OSDN Git Service

* 1750a.h (EXTRA_SECTION_FUNCTIONS): Add prototype.
[pf3gnuchains/gcc-fork.git] / gcc / config / pj / pj.c
1 /* Output routines for GCC for picoJava II
2    Copyright (C) 2000, 2001 Free Software Foundation, Inc.
3
4 This file is part of GNU CC.
5
6 GNU CC is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
10
11 GNU CC is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with GNU CC; see the file COPYING.  If not, write to
18 the Free Software Foundation, 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA.  */
20
21 /* Contributed by Steve Chamberlain (sac@pobox.com), of Transmeta.  */
22
23 /* The picoJava architecture doesn't have general registers, it has an
24    operand stack.  Any of the first 256 words on the operand stack between
25    the locations indicated by the vars register and the optop register
26    are accessible with one instruction, almost as if they were registers.
27    The opstack isn't aliased into memory, so deferecencing address of
28    something on the opstack is impossible.
29
30    Small scalar incoming arguments to a function arrive on the operand
31    stack, large scalars and aggregates arrive in the `aggregate'
32    stack.  The aggregate stack lives in normal memory.
33
34
35    just before a call       after the call insn and frame setup.
36
37    vars->   ....
38    
39            arg-5            vars->arg-5
40            arg-4                  arg-4
41            arg-3                  arg-3
42            arg-2                  arg-2
43            arg-1                  arg-1
44            arg-0                  arg-0
45            target-addr            old-vars
46            #arg words             old-pc
47    optop->                        saved globals
48                                   local-0
49                                   local-1
50                                   ....
51                             optop->
52
53    This port generates code for a machine with 32 general purpose
54    registers, and on output changes the references to the fake registers
55    into offsets from the vars register.  Because the opstack grows
56    downwards and all indexes are negated, some care has to be taken here
57    to deal with endian problems; for example after a call on a little endian
58    machine, an incoming DImode argument of value 0x1122334455667788 in
59    `register 0', would live on the opstack like this:
60
61      vars - 0   0x11223344
62      vars - 4   0x55667788
63      vars - 8   old-vars
64      vars - 12  old-pc
65
66    The picoJava instructon to read and put that onto the opstack as a
67    DImode value is `lload 0', yet the least significant word lives at
68    vars - 4, for which the instruction is `iload 1'.  The incoming
69    argument code remembers which arguments arrive swapped in the
70    CUMULATIVE_ARGS structure.  The information is used to fill in
71    pj_si_vars_offset_vec and pj_di_vars_offset_vec during the prologue
72    printing.
73
74    Outgoing arguments are collected in fake `outgoing' registers, or
75    in the aggregate stack.  The emitted code to write into an outgoing
76    register does nothing, which leaves the expression to be written on
77    the top of the opstack.  GCC always evaluates arguments in the right
78    order, so nothing more needs to be done.  */
79
80
81 #include "config.h"
82 #include "system.h"
83 #include "rtl.h"
84 #include "tree.h"
85 #include "tm_p.h"
86 #include "regs.h"
87 #include "hard-reg-set.h"
88 #include "real.h"
89 #include "insn-config.h"
90 #include "conditions.h"
91 #include "output.h"
92 #include "insn-attr.h"
93 #include "flags.h"
94 #include "except.h"
95 #include "function.h"
96 #include "recog.h"
97 #include "expr.h"
98 #include "optabs.h"
99 #include "toplev.h"
100 #include "basic-block.h"
101 #include "ggc.h"
102 #include "target.h"
103 #include "target-def.h"
104
105 /* Compare insns in pj.md store the information needed to generate
106    branch instructions here.  */
107 rtx pj_cmp_op0;
108 rtx pj_cmp_op1;
109 enum machine_mode pj_cmp_mode;
110
111 static void pj_output_rval PARAMS ((rtx, enum machine_mode, rtx));
112 static void pj_output_store_into_lval PARAMS ((enum machine_mode mode, rtx op));
113 static void pj_output_push_int PARAMS ((int));
114 static void pj_output_load PARAMS ((enum machine_mode, int));
115 static void pj_output_inc PARAMS ((rtx, int));
116 static void pj_output_cnv_op PARAMS ((enum insn_code, rtx));
117 static char mode_to_char PARAMS ((enum machine_mode));
118 static void pj_output_varidx PARAMS ((enum machine_mode, int, int));
119 static void pj_print_cond PARAMS ((enum rtx_code));
120 static rtx *unique_src_operand PARAMS ((rtx *, rtx));
121
122 /* These vectors turn a register number into an offset from the vars
123    pointer register.  */
124 short pj_si_vars_offset_vec[FIRST_PSEUDO_REGISTER];
125 short pj_di_vars_offset_vec[FIRST_PSEUDO_REGISTER];
126 short pj_debugreg_renumber_vec[FIRST_PSEUDO_REGISTER];
127
128 /* Number of fake registers in the frame, used by prologue and epilogue
129    code.  */
130 static int nfakes;
131
132 /* Whether anything has been printed to the current assembly output
133    line. */
134 int pj_stuff_on_line;
135 \f
136 /* Initialize the GCC target structure.  */
137
138 struct gcc_target targetm = TARGET_INITIALIZER;
139 \f
140 /* printf to the asm_out_file, with special format control characters
141    for decoding operands.  
142
143  %*              - start of opcode
144  %d,%x,%c,%s     - as printf
145  %X              - address constant.
146  %<alpha><digit> - operand <digit> passed to pj_print_operand with code <alpha>.  */
147
148 static void
149 pj_printf VPARAMS ((const char *template, ...))
150 {
151   register int c;
152   int ops_read = 0;
153   rtx operands[10];
154
155   VA_OPEN (argptr, template);
156   VA_FIXEDARG (argptr, const char *, template);
157
158   while ((c = *template++))
159     {
160       int was_stuff_on_line = pj_stuff_on_line;
161       pj_stuff_on_line = 1;
162       switch (c)
163         {
164         case '\n':
165           putc (c, asm_out_file);
166           pj_stuff_on_line = 0;
167           break;
168         default:
169           putc (c, asm_out_file);
170           break;
171         case '%':
172           {
173             switch (*template)
174               {
175               case '%':
176                 putc ('%', asm_out_file);
177                 template++;
178                 pj_stuff_on_line = 1;
179                 break;
180               case '*':
181                 /* Marks start of opcode, tab out.  */
182                 if (was_stuff_on_line)
183                   fprintf (asm_out_file, "; ");
184                 template++;
185                 break;
186               case 'd':
187                 template++;
188                 fprintf (asm_out_file, "%d", va_arg (argptr, int));
189                 break;
190               case 'x':
191                 template++;
192                 fprintf (asm_out_file, "%x", va_arg (argptr, int));
193                 break;
194               case 'c':
195                 template++;
196                 fprintf (asm_out_file, "%c", va_arg (argptr, int));
197                 break;
198               case 's':
199                 template++;
200                 fputs (va_arg (argptr, const char *), asm_out_file);
201                 break;
202               case 'X':
203                 template++;
204                 output_addr_const (asm_out_file, va_arg (argptr, rtx));
205                 break;
206               default:
207                 {
208                   int code = 0;
209                   rtx send;
210
211                   if (ISALPHA (*template))
212                     code = *template++;
213                   if (ISDIGIT (*template))
214                     {
215                       int num = atoi (template);
216                       template++;
217                       while (ops_read <= num)
218                         operands[ops_read++] = va_arg (argptr, rtx);
219                       send = operands[num];
220                     }
221                   else
222                     send = va_arg (argptr, rtx);
223
224                   /* A null means leave the word on the stack, so there's
225                      no need to do anything for that.  */
226
227                   if (send)
228                     pj_print_operand (asm_out_file, send, code);
229                 }
230               }
231           }
232         }
233     }
234   VA_CLOSE (argptr);
235 }
236
237 /* Output code to efficiently push a single word integer constant onto
238    the opstack.  */
239
240 static void
241 pj_output_push_int (val)
242      int val;
243 {
244   int low = ((val & 0x8000) ? ~0xffff : 0) | (val & 0xffff);
245
246   if (low == -1)
247     pj_printf ("%*iconst_m1");
248   else if (low >= 0 && low <= 5)
249     pj_printf ("%*iconst_%d", low);
250   else if (low >= -128 && low < 128)
251     pj_printf ("%*bipush %d", low);
252   else
253     pj_printf ("%*sipush %d", low);
254
255   if ((low & 0xffff0000) != (val & 0xffff0000))
256     pj_printf ("%*sethi 0x%x", (val >> 16) & 0xffff);
257 }
258
259 /* Output code to add a constant to the value on the top of the
260    opstack.  */
261
262 static void
263 pj_output_print_add_k (int size)
264 {
265   if (size >= 0)
266     {
267       pj_output_push_int (size);
268       pj_printf ("%*iadd");
269     }
270   else
271     {
272       pj_output_push_int (-size);
273       pj_printf ("%*isub");
274     }
275 }
276
277 /* Output code to load the value pointed to by the top of stack onto
278    the stack.  */
279
280 static void
281 pj_output_load (mode, uns)
282      enum machine_mode mode;
283      int uns;
284 {
285   int i;
286   switch (GET_MODE_SIZE (mode))
287     {
288     case 1:
289       pj_printf (uns ? "%*load_ubyte" : "%*load_byte");
290       break;
291     case 2:
292       pj_printf (uns ? "%*load_char" : "%*load_short");
293       break;
294     case 8:
295       if (TARGET_TM_EXTENSIONS)
296         {
297           pj_printf ("%*tm_load_long");
298           break;
299         }
300       /* Fall through.  */
301     default:
302       for (i = GET_MODE_SIZE (mode); i > 4; i -= 4)
303         {
304           pj_printf ("%*dup");
305           pj_output_print_add_k (i - 4);
306           pj_printf ("%*load_word");
307           pj_printf ("%*swap");
308         }
309       pj_printf ("%*load_word");
310     }
311 }
312
313 /*  Output code to increment the provided lval operand.  */
314
315 static void
316 pj_output_inc (op, size)
317      rtx op;
318      int size;
319 {
320   if (STACK_REG_RTX_P (op))
321     pj_printf ("%*iinc %d,%d", pj_si_vars_offset_vec[REGNO (op)], size);
322   else
323     {
324       pj_output_rval (op, SImode, 0);
325       pj_output_push_int (size);
326       pj_printf ("%*iadd");
327       pj_output_store_into_lval (SImode, op);
328     }
329 }
330
331 /* Output the text for a conversion operator.  */
332
333 static void
334 pj_output_cnv_op (e, op)
335      enum insn_code e;
336      rtx op;
337 {
338   pj_printf ((const char *) insn_data[(int) e].output, 0, XEXP (op, 0));
339 }
340
341 /* Turn a machine_mode into an opcode modifier chararacter.  */
342
343 static char
344 mode_to_char (mode)
345      enum machine_mode mode;
346 {
347   switch (mode)
348     {
349     case QImode:
350     case HImode:
351     case SImode:
352       return 'i';
353       break;
354     case DImode:
355       return 'l';
356       break;
357     case DFmode:
358       return 'd';
359       break;
360     case SFmode:
361       return 'f';
362       break;
363     default:
364       abort ();
365     }
366 }
367
368 /* Output an index off the var register. If we're moving an 8 byte
369    value then reduce the index, since the picoJava instruction loading
370    the value uses the index of the highest part of the register as
371    it's name.  */
372
373 static void
374 pj_output_varidx (mode, do_store, idx)
375      enum machine_mode mode;
376      int do_store;
377      int idx;
378 {
379   pj_printf ("%*%c%s%c%d",
380              mode_to_char (mode),
381              do_store ? "store" : "load",
382              (GET_MODE_SIZE (mode) == 4 || GET_MODE_SIZE (mode) == 8)
383              && idx <= 3 ? '_' : ' ', idx);
384 }
385
386 /* Output an rvalue expression.  */
387
388 static void
389 pj_output_rval (op, mode, outer_op)
390      rtx op;
391      enum machine_mode mode;
392      rtx outer_op;
393 {
394   enum rtx_code code = GET_CODE (op);
395
396   optab tab;
397
398   if (code == DIV && GET_MODE_CLASS (mode) == MODE_INT)
399     tab = sdiv_optab;
400   else
401     tab = code_to_optab[code];
402
403   if (code == PLUS)
404     {
405       pj_output_rval (XEXP (op, 0), mode, op);
406       pj_output_rval (XEXP (op, 1), mode, op);
407       pj_printf ("%*%cadd", mode_to_char (mode));
408     }
409   else if (tab && tab->handlers[mode].insn_code != CODE_FOR_nothing)
410     {
411       const char *const template =
412         (const char *) insn_data[tab->handlers[mode].insn_code].output;
413       if (code == NEG)
414         pj_printf (template, 0, XEXP (op, 0));
415       else
416         pj_printf (template, 0, XEXP (op, 0), XEXP (op, 1));
417     }
418   else
419     switch (GET_CODE (op))
420       {
421       case PC:
422         fprintf (asm_out_file, " pc ");
423         break;
424
425       case CONST:
426         pj_output_rval (XEXP (op, 0), mode, op);
427         break;
428
429       case MEM:
430         pj_output_rval (XEXP (op, 0), Pmode, op);
431         pj_output_load (mode, 0);
432         break;
433
434       case SYMBOL_REF:
435         pj_printf ("%*ipush %X", op);
436         break;
437
438       case REG:
439         switch (mode)
440           {
441           case SImode:
442           case SFmode:
443           case HImode:
444           case QImode:
445             if (pj_si_vars_offset_vec[REGNO (op)] >= 0)
446               pj_output_varidx (mode, 0, pj_si_vars_offset_vec[REGNO (op)]);
447             else
448               pj_printf ("%*read_%s", reg_names[REGNO (op)]);
449             break;
450           case DImode:
451           case DFmode:
452             if (pj_di_vars_offset_vec[REGNO (op)] >= 0)
453               pj_output_varidx (mode, 0, pj_di_vars_offset_vec[REGNO (op)]);
454             else
455               switch (REGNO (op))
456                 {
457                 case G1_REG:
458                   pj_printf ("%*read_global2");
459                   pj_printf ("%*read_global1");
460                   break;
461
462                   /* A 64 bit read of global0 gives global0 and
463                      optop.  */
464                 case G0_REG:
465                   pj_printf ("%*read_optop");
466                   pj_printf ("%*read_global0");
467                   break;
468
469                 default:
470                   abort ();
471                 }
472             break;
473           default:
474             abort ();
475           }
476         break;
477
478       case CONST_DOUBLE:
479         pj_printf (pj_standard_float_constant (op));
480         break;
481
482       case CONST_INT:
483         if (mode == SImode || mode == HImode || mode == QImode)
484           pj_output_push_int (INTVAL (op));
485         else if (mode == DImode)
486           {
487             int v = INTVAL (op);
488             if (v == 1)
489               pj_printf ("%*lconst_1", 0);
490             else if (v == 0)
491               pj_printf ("%*lconst_0", 0);
492             else
493               {
494                 rtx hi = GEN_INT (v < 0 ? -1 : 0);
495                 rtx lo = op;
496                 pj_output_rval (TARGET_LITTLE_ENDIAN ? hi : lo, SImode, op);
497                 pj_output_rval (TARGET_LITTLE_ENDIAN ? lo : hi, SImode, op);
498               }
499           }
500         else
501           abort ();
502         break;
503
504       case FLOAT_TRUNCATE:
505         pj_printf ("%S0%*d2f", XEXP (op, 0));
506         break;
507       case LABEL_REF:
508         pj_printf ("%*ipush %X", XEXP (op, 0));
509         break;
510
511       case SUBREG:
512         pj_output_rval (alter_subreg (op), mode, outer_op);
513         break;
514
515       case POST_INC:
516         pj_output_rval (XEXP (op, 0), mode, op);
517         pj_output_inc (XEXP (op, 0), GET_MODE_SIZE (GET_MODE (outer_op)));
518         break;
519
520       case POST_DEC:
521         pj_output_rval (XEXP (op, 0), mode, op);
522         pj_output_inc (XEXP (op, 0), -GET_MODE_SIZE (GET_MODE (outer_op)));
523         break;
524
525       case PRE_INC:
526         pj_output_inc (XEXP (op, 0), GET_MODE_SIZE (GET_MODE (outer_op)));
527         pj_output_rval (XEXP (op, 0), mode, op);
528         break;
529
530       case PRE_DEC:
531         if (OPTOP_REG_RTX_P (XEXP (op, 0)))
532           pj_output_rval (XEXP (op, 0), mode, op);
533         else if (STACK_REG_RTX_P (XEXP (op, 0)))
534           {
535             pj_output_inc (XEXP (op, 0),
536                            -GET_MODE_SIZE (GET_MODE (outer_op)));
537             pj_output_rval (XEXP (op, 0), mode, op);
538           }
539         else
540           {
541             pj_printf ("%S0", XEXP (op, 0));
542             pj_output_print_add_k (-GET_MODE_SIZE (GET_MODE (outer_op)));
543             pj_printf ("%*dup%R0", XEXP (op, 0));
544           }
545         break;
546
547       case FIX:
548         pj_output_cnv_op (fixtrunctab[GET_MODE (XEXP (op, 0))][mode][0], op);
549         break;
550
551       case FLOAT:
552         if (mode == DFmode && GET_CODE (XEXP (op, 0)) == CONST_INT)
553           pj_output_cnv_op (floattab[mode][SImode][0], op);
554         else
555           pj_output_cnv_op (floattab[mode][GET_MODE (XEXP (op, 0))][0], op);
556         break;
557
558       case FLOAT_EXTEND:
559       case SIGN_EXTEND:
560         /* Sign extending from a memop to register is automatic.  */
561         if (mode == SImode && GET_CODE (XEXP (op, 0)) == MEM)
562           pj_output_rval (XEXP (op, 0), GET_MODE (XEXP (op, 0)), op);
563         else
564           pj_output_cnv_op (extendtab[mode][GET_MODE (XEXP (op, 0))][0], op);
565         break;
566
567       case ZERO_EXTEND:
568         pj_output_cnv_op (extendtab[mode][GET_MODE (XEXP (op, 0))][1], op);
569         break;
570
571       default:
572         abort ();
573         break;
574       }
575 }
576
577 /* Store the top of stack into the lval operand OP.  */
578
579 static void
580 pj_output_store_into_lval (mode, op)
581      enum machine_mode mode;
582      rtx op;
583 {
584   if (GET_CODE (op) == REG)
585     {
586       int rn = REGNO (op);
587
588       /* Outgoing values are left on the stack and not written
589          anywhere.  */
590       if (!OUTGOING_REG_RTX_P (op))
591         {
592           switch (GET_MODE (op))
593             {
594             case SImode:
595             case QImode:
596             case HImode:
597             case SFmode:
598               if (pj_si_vars_offset_vec[rn] >= 0)
599                 pj_output_varidx (mode, 1, pj_si_vars_offset_vec[rn]);
600               else
601                 pj_printf ("%*write_%s", reg_names[rn]);
602               break;
603             case DImode:
604             case DFmode:
605               if (pj_di_vars_offset_vec[rn] >= 0)
606                 pj_output_varidx (mode, 1, pj_di_vars_offset_vec[rn]);
607               else
608                 switch (rn)
609                   {
610                   case G1_REG:
611                     pj_printf ("%*write_global1");
612                     pj_printf ("%*write_global2");
613                     break;
614                   default:
615                     abort ();
616                   }
617               break;
618             default:
619               abort ();
620             }
621         }
622     }
623   else
624     {
625       pj_output_rval (XEXP (op, 0), Pmode, op);
626
627       switch (GET_MODE_SIZE (mode))
628         {
629         case 1:
630           pj_printf ("%*store_byte", 0);
631           break;
632         case 2:
633           pj_printf ("%*store_short", 0);
634           break;
635         case 8:
636           if (TARGET_TM_EXTENSIONS)
637             {
638               pj_printf ("%*tm_store_long");
639               break;
640             }
641           /* Fall through.  */
642         default:
643           {
644             int i;
645             for (i = GET_MODE_SIZE (mode); i > 4; i -= 4)
646               {
647                 pj_printf ("%*dup_x1", 0);
648                 pj_printf ("%*store_word", 0);
649                 pj_printf ("%*iconst_4", 0);
650                 pj_printf ("%*iadd", 0);
651               }
652           }
653           pj_printf ("%*store_word", 0);
654           break;
655         }
656     }
657 }
658
659 /* Print a condition, unsigned and signed have the same text because
660    the unsigned operands have been run through icmp first.  */
661
662 static void
663 pj_print_cond (code)
664      enum rtx_code code;
665 {
666   switch (code)
667     {
668     case EQ:
669       fputs ("eq", asm_out_file);
670       break;
671     case NE:
672       fputs ("ne", asm_out_file);
673       break;
674     case GT:
675     case GTU:
676       fputs ("gt", asm_out_file);
677       break;
678     case GE:
679     case GEU:
680       fputs ("ge", asm_out_file);
681       break;
682     case LT:
683     case LTU:
684       fputs ("lt", asm_out_file);
685       break;
686     case LE:
687     case LEU:
688       fputs ("le", asm_out_file);
689       break;
690     default:
691       abort ();
692     }
693 }
694 /* Print operand X (an rtx) in assembler syntax to file STREAM
695    according to modifier CODE.
696
697    C  emit the first part of a Check_call pseudop. 
698    D  emit operand, if no mode, assume DImode.
699    E  emit the second part of a check_call pseudop. 
700    I  print the XEXP (X, 0) Inside of the operand.
701    J  print Just the integer or register part of an operand, for iinc.
702    P  emit source is SI padded to DI with 0, used for unsigned mod and divide.
703    R  emit the operand as an lval Result.
704    S  emit Source operand, if no mode, assume SImode.
705    X  nan choice suffix for floating point comparision.
706    Y  condition name from op.
707    Z  Y, reversed.
708    *  marks start of opcode.  */
709
710 void
711 pj_print_operand (stream, x, code)
712      FILE *stream;
713      rtx x;
714      int code;
715 {
716   static int last_call_known;
717   switch (code)
718     {
719     case 'C':
720       if (GET_CODE (x) == SYMBOL_REF)
721         {
722           last_call_known = 1;
723           pj_printf ("%*.check_call %0", x);
724         }
725       else
726         last_call_known = 0;
727       break;
728
729     case 'D':
730       pj_output_rval (x,
731                       GET_MODE (x) == VOIDmode ? DImode : GET_MODE (x),
732                       NULL_RTX);
733       break;
734
735     case 'E':
736       if (last_call_known)
737         pj_printf (",%d", INTVAL (x));
738       break;
739
740     case 'I':
741       pj_output_rval (XEXP (x, 0), GET_MODE (XEXP (x, 0)), NULL_RTX);
742       break;
743
744     case 'J':
745       if (GET_CODE (x) == CONST_INT)
746         pj_printf ("%d", INTVAL (x));
747       else if (GET_CODE (x) == REG)
748         pj_printf ("%d", pj_si_vars_offset_vec[REGNO (x)]);
749       else
750         abort ();
751       break;
752
753     case 'P':
754       if (TARGET_LITTLE_ENDIAN)
755         pj_printf ("%*iconst_0", 0);
756       pj_output_rval (x,
757                       GET_MODE (x) == VOIDmode ? SImode : GET_MODE (x),
758                       NULL_RTX);
759       if (!TARGET_LITTLE_ENDIAN)
760         pj_printf ("%*iconst_0", 0);
761       break;
762
763     case 'R':
764       pj_output_store_into_lval (GET_MODE (x), x);
765       break;
766
767     case 'S':
768       pj_output_rval (x,
769                       GET_MODE (x) == VOIDmode ? SImode : GET_MODE (x),
770                       NULL_RTX);
771       break;
772
773     case 'X':
774       fputc (GET_CODE (x) == LT || GET_CODE (x) == LE ? 'g' : 'l', stream);
775       break;
776
777     case 'Y':
778       pj_print_cond (GET_CODE (x));
779       break;
780
781     case 'Z':
782       pj_print_cond (reverse_condition (GET_CODE (x)));
783       break;
784
785     case '*':
786       pj_printf ("%*");
787       break;
788
789     default:
790       output_addr_const (stream, x);
791       break;
792     }
793 }
794 \f
795 /* Return in an rtx the number of words pushed onto the optop to be
796    used as the word count in a call insn.  (NEXT_ARG_REG is NULL when
797    called from expand_builtin_apply).  */
798
799 rtx
800 pj_workout_arg_words (stack_size, next_arg_reg)
801      rtx stack_size ATTRIBUTE_UNUSED;
802      rtx next_arg_reg;
803 {
804   return GEN_INT ((next_arg_reg ? REGNO (next_arg_reg) - O0_REG : 0) + 2);
805 }
806
807 /* Handle the INCOMING_FUNCTION_ARG macro.
808    Determine where to put an argument to a function.
809    Value is zero to push the argument on the stack,
810    or a hard register in which to store the argument.
811
812    CUM is a variable of type CUMULATIVE_ARGS which gives info about
813     the preceding args and about the function being called.
814    MODE is the argument's machine mode.
815    TYPE is the data type of the argument (as a tree).
816     This is null for libcalls where that information may
817     not be available.
818    NAMED is nonzero if this argument is a named parameter
819     (otherwise it is an extra parameter matching an ellipsis). */
820
821 rtx
822 pj_function_incoming_arg (cum, mode, passed_type, named_arg)
823      CUMULATIVE_ARGS *cum;
824      enum machine_mode mode;
825      tree passed_type ATTRIBUTE_UNUSED;
826      int named_arg ATTRIBUTE_UNUSED;
827 {
828   int arg_words = PJ_ARG_WORDS (mode);
829
830   /* If the whole argument will fit into registers, return the first
831      register needed.  Also fill in the arg_adjust information so that
832      we can work out the right offset to use when looking at the
833      insides of a DI or DF value.  */
834
835   if (cum->total_words + arg_words <= ARGS_IN_REGS)
836     {
837       int i;
838       if (mode == DImode || mode == DFmode)
839         {
840           cum->arg_adjust[cum->total_words + 0] = 1;
841           cum->arg_adjust[cum->total_words + 1] = -1;
842         }
843       else
844         for (i = 0; i < arg_words; i++)
845           cum->arg_adjust[cum->total_words + i] = 0;
846
847       return gen_rtx (REG, mode, I0_REG + cum->total_words);
848     }
849   return NULL_RTX;
850 }
851
852 /* Output code to add two SImode values.  Deals carefully with the the common
853    case of moving the optop.  */
854
855 const char *
856 pj_output_addsi3 (operands)
857      rtx *operands;
858 {
859   if (OPTOP_REG_RTX_P (operands[0]) && OPTOP_REG_RTX_P (operands[1])
860       && GET_CODE (operands[2]) == CONST_INT
861       && INTVAL (operands[2]) >= -32 && INTVAL (operands[2]) <= 32)
862     {
863       static struct
864       {
865         const char *two;
866         const char *one;
867       }
868       name[2] =
869       {
870         { "pop2", "pop"},
871         { "lconst_0", "iconst_0"}
872       };
873       int size = INTVAL (operands[2]);
874       int d = 0;
875
876       if (size < 0)
877         {
878           d = 1;
879           size = -size;
880         }
881
882       for (; size >= 8; size -= 8)
883         output_asm_insn (name[d].two, 0);
884
885
886       if (size > 0)
887         output_asm_insn (name[d].one, 0);
888
889       return "";
890     }
891
892   if (STACK_REG_RTX_P (operands[0])
893       && rtx_equal_p (operands[0], operands[1])
894       && GET_CODE (operands[2]) == CONST_INT
895       && INTVAL (operands[2]) >= -128 && INTVAL (operands[2]) <= 127)
896     {
897       return "iinc %J0,%J2";
898     }
899
900   return "%S1%S2%*iadd%R0";
901 }
902 \f
903 /* Generate rtl for the prologue of the current function.  */
904
905 void
906 pj_expand_prologue ()
907 {
908   int i;
909   int off = 0;
910   int arg_words = current_function_args_info.named_words;
911
912   memset (pj_si_vars_offset_vec, -1, sizeof (pj_si_vars_offset_vec));
913   memset (pj_di_vars_offset_vec, -1, sizeof (pj_di_vars_offset_vec));
914
915   /* Work out the register numbers of the named arguments.  */
916   for (i = 0; i < current_function_args_info.named_words; i++)
917     {
918       pj_debugreg_renumber_vec[I0_REG + i]
919         = off + R0_REG + current_function_args_info.arg_adjust[i];
920       pj_si_vars_offset_vec[I0_REG + i]
921         = off + current_function_args_info.arg_adjust[i];
922       pj_di_vars_offset_vec[I0_REG + i] = off;
923       off++;
924     }
925
926   if (current_function_varargs || current_function_stdarg)
927     {
928       /* If the function is varadic we need to call the vhelper
929          function.  vhelper pops off the unnamed argument words from
930          the opstack and puts them onto the the aggregate stack.  The
931          unnamed words are replacedwith two extra arguments, a pointer
932          to the aggreagate stack for the first vararg and the original
933          global0 value.  */
934
935       emit_insn (gen_varargs (GEN_INT (arg_words * 4)));
936       pj_si_vars_offset_vec[VA_REG] = off++;
937       off++;
938       arg_words += 2;
939     }
940
941   /* Skip over the return pc and old vars in the frame.  */
942   off += 2;
943
944   /* Work out the register numbers and offsets from the var pointer
945      for the normal registers.  */
946   nfakes = 0;
947
948   for (i = LAST_I_REG; i >= R0_REG; i--)
949     if (regs_ever_live[i] && pj_si_vars_offset_vec[i] == -1)
950       {
951         nfakes++;
952         pj_si_vars_offset_vec[i] = off;
953         pj_di_vars_offset_vec[i] = off - 1;
954         pj_debugreg_renumber_vec[i] = off + R0_REG;
955         off++;
956       }
957
958   if (TARGET_TEST)
959     {
960       fprintf (asm_out_file, "\n\t! args %d, size %d, fakes %d\n", 
961                arg_words,
962                get_frame_size () / 4,
963                nfakes);
964
965       for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
966         if (pj_si_vars_offset_vec[i] >= 0)
967           fprintf (asm_out_file, "\t!vars - %d %d: %s\n",
968                    pj_si_vars_offset_vec[i],
969                    pj_di_vars_offset_vec[i], 
970                    reg_names[i]);
971     }
972
973   /* Make room on the opstack for the fake registers.  */
974   if (TARGET_TM_EXTENSIONS)
975     RTX_FRAME_RELATED_P (emit_insn (gen_tm_frame (GEN_INT (arg_words),
976                                                   GEN_INT (nfakes)))) = 1;
977   else
978     RTX_FRAME_RELATED_P (emit_insn
979                          (gen_addsi3
980                           (gen_rtx_REG (SImode, OPTOP_REG),
981                            gen_rtx_REG (SImode, OPTOP_REG),
982                            GEN_INT (-nfakes * 4)))) = 1;
983
984
985   if (frame_pointer_needed)
986       emit_move_insn (frame_pointer_rtx, stack_pointer_rtx);
987
988   if (get_frame_size ())
989     RTX_FRAME_RELATED_P (emit_insn (gen_addsi3 (stack_pointer_rtx,
990                                                 stack_pointer_rtx,
991                                                 GEN_INT
992                                                 (-get_frame_size ())))) = 1;
993
994   emit_insn (gen_rtx_USE (VOIDmode, gen_rtx_REG (SImode, OPTOP_REG)));
995 }
996
997 /* Generate rtl for the epilogue of the current function.  */
998
999 void
1000 pj_expand_epilogue ()
1001 {
1002   if (frame_pointer_needed)
1003     emit_move_insn (stack_pointer_rtx, frame_pointer_rtx);
1004   else if (get_frame_size ())
1005     emit_insn (gen_addsi3 (stack_pointer_rtx,
1006                            stack_pointer_rtx, GEN_INT (get_frame_size ())));
1007   if (nfakes)
1008     emit_insn (gen_addsi3 (gen_rtx_REG (SImode, OPTOP_REG),
1009                            gen_rtx_REG (SImode, OPTOP_REG),
1010                            GEN_INT (nfakes * 4)));
1011
1012
1013   /* If this is a varargs function, then global0 is stashed away on
1014      the top of the optop stack as the last secret argument by the
1015      __vhelper.  Pop off the va pointer provided too.  */
1016
1017   if (current_function_varargs || current_function_stdarg)
1018     emit_insn (gen_varargs_finish
1019                (GEN_INT (current_function_args_info.named_words + 1)));
1020
1021   emit_insn (gen_rtx_USE (VOIDmode, gen_rtx_REG (SImode, OPTOP_REG)));
1022 }
1023
1024 /* Return the opcode name for an instruction to load a standard
1025    floating point constant, or NULL.  */
1026
1027 const char *
1028 pj_standard_float_constant (op)
1029      rtx op;
1030 {
1031   REAL_VALUE_TYPE r;
1032   enum machine_mode mode = GET_MODE (op);
1033
1034   if (GET_CODE (op) != CONST_DOUBLE || (mode != DFmode && mode != SFmode))
1035     return NULL;
1036
1037   REAL_VALUE_FROM_CONST_DOUBLE (r, op);
1038
1039   if (REAL_VALUES_EQUAL (r, dconst0) && !REAL_VALUE_MINUS_ZERO (r))
1040     return mode == DFmode ? "%*dconst_0" : "%*fconst_0";
1041
1042   if (REAL_VALUES_EQUAL (r, dconst1))
1043     return mode == DFmode ? "%*dconst_1" : "%*fconst_1";
1044
1045   if (REAL_VALUES_EQUAL (r, dconst2))
1046     return mode == DFmode ? 0 : "%*fconst_2";
1047
1048   return NULL;
1049 }
1050
1051 /* Read the value at the current address, and decrement by the size.
1052    The function is interesting because we're reading from high memory to low memory
1053    and have to adjust the addresses of reads of 8 byte values
1054    accordingly.  */
1055
1056 rtx
1057 pj_expand_builtin_va_arg (valist, type)
1058      tree valist;
1059      tree type;
1060 {
1061   tree addr_tree, t;
1062   HOST_WIDE_INT align;
1063   HOST_WIDE_INT rounded_size;
1064   rtx addr;
1065
1066   /* Compute the rounded size of the type.  */
1067   align = PARM_BOUNDARY / BITS_PER_UNIT;
1068   rounded_size = (((int_size_in_bytes (type) + align - 1) / align) * align);
1069
1070   /* Get AP.  */
1071   addr_tree = valist;
1072   addr = expand_expr (addr_tree, NULL_RTX, Pmode, EXPAND_NORMAL);
1073   addr = copy_to_reg (addr);
1074
1075   /* Aggregates and large scalars are passed by reference.  */
1076   if (AGGREGATE_TYPE_P (type) || rounded_size > 8)
1077     {
1078       addr = gen_rtx_MEM (Pmode, addr);
1079       rounded_size = 4;
1080     }
1081
1082   /* adjust address to cope with double word sizes */
1083   if (rounded_size > 4)
1084     addr = gen_rtx_PLUS (Pmode, addr, GEN_INT (-4));
1085
1086   /* Compute new value for AP; AP = AP - SIZE */
1087   t = build (MODIFY_EXPR, TREE_TYPE (valist), valist,
1088              build (MINUS_EXPR, TREE_TYPE (valist), valist,
1089                     build_int_2 (rounded_size, 0)));
1090
1091   TREE_SIDE_EFFECTS (t) = 1;
1092
1093   expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
1094
1095   return addr;
1096 }
1097 \f
1098 /* Return nonzero if the operand is valid as a source operand; it's
1099    general and it's not an outgoing argument register.  */
1100
1101 int
1102 pj_source_operand (op, mode)
1103      rtx op;
1104      enum machine_mode mode;
1105 {
1106   return !OUTGOING_REG_RTX_P (op) && general_operand (op, mode);
1107 }
1108
1109 /* Return nonzero if the operator is a signed compare.  */
1110
1111 int
1112 pj_signed_comparison_operator (op, mode)
1113      rtx op;
1114      enum machine_mode mode;
1115 {
1116   if (mode != GET_MODE (op))
1117     return 0;
1118
1119   switch (GET_CODE (op))
1120     {
1121     case EQ:
1122     case NE:
1123     case LE:
1124     case LT:
1125     case GE:
1126     case GT:
1127       return 1;
1128     default:
1129       return 0;
1130     }
1131 }
1132
1133 /* Return nonzero if the operator is an unsigned compare.  */
1134
1135 int
1136 pj_unsigned_comparison_operator (op, mode)
1137      rtx op;
1138      enum machine_mode mode ATTRIBUTE_UNUSED;
1139 {
1140   if (mode != GET_MODE (op))
1141     return 0;
1142
1143   switch (GET_CODE (op))
1144     {
1145     case GTU:
1146     case GEU:
1147     case LTU:
1148     case LEU:
1149       return 1;
1150     default:
1151       return 0;
1152     }
1153 }
1154 \f
1155 /* Helper function for pj_machine_dependent_reorg.  Find the one
1156    instance of register OP in the source part of PAT.  If there are no
1157    copies return NULL, if there are more than one, return NOT_UNIQUE.  */
1158
1159 #define NOT_UNIQUE (&const0_rtx)
1160
1161 static rtx *
1162 unique_src_operand (pat, reg)
1163      rtx *pat;
1164      rtx reg;
1165 {
1166   register rtx *result = 0;
1167   register const char *fmt;
1168   register int i;
1169   register int j;
1170
1171   if (GET_CODE (*pat) == SET)
1172     {
1173       if (GET_CODE (XEXP (*pat, 0)) == MEM)
1174         result = unique_src_operand (&XEXP (SET_DEST (*pat), 0), reg);
1175       pat = &SET_SRC (*pat);
1176     }
1177
1178   if (GET_CODE (*pat) == REG && REGNO (*pat) == REGNO (reg))
1179     return pat;
1180
1181   fmt = GET_RTX_FORMAT (GET_CODE (*pat));
1182   for (i = GET_RTX_LENGTH (GET_CODE (*pat)) - 1; i >= 0; i--)
1183     {
1184       if (fmt[i] == 'e')
1185         {
1186           rtx *new_result = unique_src_operand (&XEXP (*pat, i), reg);
1187
1188           if (new_result)
1189             {
1190               if (result)
1191                 return NOT_UNIQUE;
1192               result = new_result;
1193             }
1194         }
1195       else if (fmt[i] == 'E')
1196         {
1197           for (j = XVECLEN (*pat, i) - 1; j >= 0; j--)
1198             {
1199               rtx *new_result =
1200                 unique_src_operand (&XVECEXP (*pat, i, j), reg);
1201
1202               if (new_result)
1203                 {
1204                   if (result)
1205                     return NOT_UNIQUE;
1206                   result = new_result;
1207                 }
1208             }
1209         }
1210     }
1211   return result;
1212 }
1213
1214 /* Clean up the instructions to remove unneeded loads and stores.
1215
1216    For example, rewrite
1217
1218    iload a; iload b; iadd; istore z
1219    iload z; iload c; iadd; istore z
1220
1221    as
1222
1223    iload a; iload b; iadd ; iload c; iadd; istore z
1224
1225    This function moves a cursor over each instruction, inspecting the
1226    LOG_LINKS.  Each of the cursor's LOG_LINK incoming instructions are
1227    inspected, any which have a simple register destination which is
1228    also used as a source in the cursor instruction, and aren't used
1229    again between the the incoming instruction and the cursor, and
1230    which become dead or set after the cursor get their sources
1231    substituted into the position of the source register in the cursor
1232    instruction.  */
1233
1234 void
1235 pj_machine_dependent_reorg (insns)
1236      rtx insns;
1237 {
1238   rtx cursor;
1239
1240   if (!optimize || !TARGET_REORG)
1241     return;
1242
1243   for (cursor = insns; cursor; cursor = NEXT_INSN (cursor))
1244     {
1245       rtx links;
1246       rtx cursor_pat;
1247
1248       /* We only care about INSNs, JUMP_INSNs. Ignore any special USE insns.  */
1249
1250       if ((GET_CODE (cursor) != INSN && GET_CODE (cursor) != JUMP_INSN)
1251           || GET_CODE (cursor_pat = PATTERN (cursor)) == USE
1252           || GET_CODE (cursor_pat) == CLOBBER
1253           || GET_CODE (cursor_pat) == ADDR_VEC
1254           || GET_CODE (cursor_pat) == ADDR_DIFF_VEC)
1255         continue;
1256
1257       for (links = LOG_LINKS (cursor); links; links = XEXP (links, 1))
1258         {
1259           rtx prev = XEXP (links, 0);
1260           rtx prev_pat;
1261           rtx prev_dest;
1262           rtx prev_src;
1263           rtx *dst_place;
1264
1265           if (GET_CODE (prev) == INSN
1266               && GET_CODE (prev_pat = PATTERN (prev)) == SET
1267               && GET_CODE (prev_dest = SET_DEST (prev_pat)) == REG
1268               && dead_or_set_p (cursor, prev_dest)
1269               && !reg_used_between_p (prev_dest, prev, cursor)
1270               && no_labels_between_p (prev, cursor)
1271               && no_jumps_between_p (prev, cursor)
1272               && !modified_between_p ((prev_src = SET_SRC (prev_pat)), prev,
1273                                       cursor)
1274               && (dst_place = unique_src_operand (&cursor_pat, prev_dest))
1275               && dst_place != NOT_UNIQUE
1276               && REGNO (prev_dest) != OPTOP_REG
1277               && GET_MODE (prev_dest) != XFmode
1278               && GET_MODE (*dst_place) == GET_MODE (SET_DEST (prev_pat)))
1279             {
1280               *dst_place = SET_SRC (prev_pat);
1281               PUT_CODE (prev, NOTE);
1282               NOTE_LINE_NUMBER (prev) = NOTE_INSN_DELETED;
1283             }
1284         }
1285     }
1286 }