Replace occurrences of #elif with #if...#endif.
[official-gcc.git] / gcc / config / pj / pj.c
blob65366270f4b36b3468253ca4b6edd0bb3e3e5ea0
1 /* Output routines for GCC for picoJava II
2 Copyright (C) 2000, 2001 Free Software Foundation, Inc.
4 This file is part of GNU CC.
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.
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.
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. */
21 /* Contributed by Steve Chamberlain (sac@pobox.com), of Transmeta. */
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.
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.
35 just before a call after the call insn and frame setup.
37 vars-> ....
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->
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:
61 vars - 0 0x11223344
62 vars - 4 0x55667788
63 vars - 8 old-vars
64 vars - 12 old-pc
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.
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. */
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"
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;
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));
114 /* These vectors turn a register number into an offset from the vars
115 pointer register. */
116 short pj_si_vars_offset_vec[FIRST_PSEUDO_REGISTER];
117 short pj_di_vars_offset_vec[FIRST_PSEUDO_REGISTER];
118 short pj_debugreg_renumber_vec[FIRST_PSEUDO_REGISTER];
120 /* Number of fake registers in the frame, used by prologue and epilogue
121 code. */
122 static int nfakes;
124 /* Whether anything has been printed to the current assembly output
125 line. */
126 int pj_stuff_on_line;
128 /* Initialize the GCC target structure. */
130 struct gcc_target targetm = TARGET_INITIALIZER;
132 /* printf to the asm_out_file, with special format control characters
133 for decoding operands.
135 %* - start of opcode
136 %d,%x,%c,%s - as printf
137 %X - address constant.
138 %<alpha><digit> - operand <digit> passed to pj_print_operand with code <alpha>. */
140 static void
141 pj_printf VPARAMS ((const char *template, ...))
143 register int c;
144 int ops_read = 0;
145 rtx operands[10];
147 VA_OPEN (argptr, template);
148 VA_FIXEDARG (argptr, const char *, template);
150 while ((c = *template++))
152 int was_stuff_on_line = pj_stuff_on_line;
153 pj_stuff_on_line = 1;
154 switch (c)
156 case '\n':
157 putc (c, asm_out_file);
158 pj_stuff_on_line = 0;
159 break;
160 default:
161 putc (c, asm_out_file);
162 break;
163 case '%':
165 switch (*template)
167 case '%':
168 putc ('%', asm_out_file);
169 template++;
170 pj_stuff_on_line = 1;
171 break;
172 case '*':
173 /* Marks start of opcode, tab out. */
174 if (was_stuff_on_line)
175 fprintf (asm_out_file, "; ");
176 template++;
177 break;
178 case 'd':
179 template++;
180 fprintf (asm_out_file, "%d", va_arg (argptr, int));
181 break;
182 case 'x':
183 template++;
184 fprintf (asm_out_file, "%x", va_arg (argptr, int));
185 break;
186 case 'c':
187 template++;
188 fprintf (asm_out_file, "%c", va_arg (argptr, int));
189 break;
190 case 's':
191 template++;
192 fputs (va_arg (argptr, const char *), asm_out_file);
193 break;
194 case 'X':
195 template++;
196 output_addr_const (asm_out_file, va_arg (argptr, rtx));
197 break;
198 default:
200 int code = 0;
201 rtx send;
203 if (ISALPHA (*template))
204 code = *template++;
205 if (ISDIGIT (*template))
207 int num = atoi (template);
208 template++;
209 while (ops_read <= num)
210 operands[ops_read++] = va_arg (argptr, rtx);
211 send = operands[num];
213 else
214 send = va_arg (argptr, rtx);
216 /* A null means leave the word on the stack, so there's
217 no need to do anything for that. */
219 if (send)
220 pj_print_operand (asm_out_file, send, code);
226 VA_CLOSE (argptr);
229 /* Output code to efficiently push a single word integer constant onto
230 the opstack. */
232 static void
233 pj_output_push_int (val)
234 int val;
236 int low = ((val & 0x8000) ? ~0xffff : 0) | (val & 0xffff);
238 if (low == -1)
239 pj_printf ("%*iconst_m1");
240 else if (low >= 0 && low <= 5)
241 pj_printf ("%*iconst_%d", low);
242 else if (low >= -128 && low < 128)
243 pj_printf ("%*bipush %d", low);
244 else
245 pj_printf ("%*sipush %d", low);
247 if ((low & 0xffff0000) != (val & 0xffff0000))
248 pj_printf ("%*sethi 0x%x", (val >> 16) & 0xffff);
251 /* Output code to add a constant to the value on the top of the
252 opstack. */
254 static void
255 pj_output_print_add_k (int size)
257 if (size >= 0)
259 pj_output_push_int (size);
260 pj_printf ("%*iadd");
262 else
264 pj_output_push_int (-size);
265 pj_printf ("%*isub");
269 /* Output code to load the value pointed to by the top of stack onto
270 the stack. */
272 static void
273 pj_output_load (mode, uns)
274 enum machine_mode mode;
275 int uns;
277 int i;
278 switch (GET_MODE_SIZE (mode))
280 case 1:
281 pj_printf (uns ? "%*load_ubyte" : "%*load_byte");
282 break;
283 case 2:
284 pj_printf (uns ? "%*load_char" : "%*load_short");
285 break;
286 case 8:
287 if (TARGET_TM_EXTENSIONS)
289 pj_printf ("%*tm_load_long");
290 break;
292 /* Fall through. */
293 default:
294 for (i = GET_MODE_SIZE (mode); i > 4; i -= 4)
296 pj_printf ("%*dup");
297 pj_output_print_add_k (i - 4);
298 pj_printf ("%*load_word");
299 pj_printf ("%*swap");
301 pj_printf ("%*load_word");
305 /* Output code to increment the provided lval operand. */
307 static void
308 pj_output_inc (op, size)
309 rtx op;
310 int size;
312 if (STACK_REG_RTX_P (op))
313 pj_printf ("%*iinc %d,%d", pj_si_vars_offset_vec[REGNO (op)], size);
314 else
316 pj_output_rval (op, SImode, 0);
317 pj_output_push_int (size);
318 pj_printf ("%*iadd");
319 pj_output_store_into_lval (SImode, op);
323 /* Output the text for a conversion operator. */
325 static void
326 pj_output_cnv_op (e, op)
327 enum insn_code e;
328 rtx op;
330 pj_printf ((const char *) insn_data[(int) e].output, 0, XEXP (op, 0));
333 /* Turn a machine_mode into an opcode modifier chararacter. */
335 static char
336 mode_to_char (mode)
337 enum machine_mode mode;
339 switch (mode)
341 case QImode:
342 case HImode:
343 case SImode:
344 return 'i';
345 break;
346 case DImode:
347 return 'l';
348 break;
349 case DFmode:
350 return 'd';
351 break;
352 case SFmode:
353 return 'f';
354 break;
355 default:
356 abort ();
360 /* Output an index off the var register. If we're moving an 8 byte
361 value then reduce the index, since the picoJava instruction loading
362 the value uses the index of the highest part of the register as
363 it's name. */
365 static void
366 pj_output_varidx (mode, do_store, idx)
367 enum machine_mode mode;
368 int do_store;
369 int idx;
371 pj_printf ("%*%c%s%c%d",
372 mode_to_char (mode),
373 do_store ? "store" : "load",
374 (GET_MODE_SIZE (mode) == 4 || GET_MODE_SIZE (mode) == 8)
375 && idx <= 3 ? '_' : ' ', idx);
378 /* Output an rvalue expression. */
380 static void
381 pj_output_rval (op, mode, outer_op)
382 rtx op;
383 enum machine_mode mode;
384 rtx outer_op;
386 enum rtx_code code = GET_CODE (op);
388 optab tab;
390 if (code == DIV && GET_MODE_CLASS (mode) == MODE_INT)
391 tab = sdiv_optab;
392 else
393 tab = code_to_optab[code];
395 if (code == PLUS)
397 pj_output_rval (XEXP (op, 0), mode, op);
398 pj_output_rval (XEXP (op, 1), mode, op);
399 pj_printf ("%*%cadd", mode_to_char (mode));
401 else if (tab && tab->handlers[mode].insn_code != CODE_FOR_nothing)
403 const char *const template =
404 (const char *) insn_data[tab->handlers[mode].insn_code].output;
405 if (code == NEG)
406 pj_printf (template, 0, XEXP (op, 0));
407 else
408 pj_printf (template, 0, XEXP (op, 0), XEXP (op, 1));
410 else
411 switch (GET_CODE (op))
413 case PC:
414 fprintf (asm_out_file, " pc ");
415 break;
417 case CONST:
418 pj_output_rval (XEXP (op, 0), mode, op);
419 break;
421 case MEM:
422 pj_output_rval (XEXP (op, 0), Pmode, op);
423 pj_output_load (mode, 0);
424 break;
426 case SYMBOL_REF:
427 pj_printf ("%*ipush %X", op);
428 break;
430 case REG:
431 switch (mode)
433 case SImode:
434 case SFmode:
435 case HImode:
436 case QImode:
437 if (pj_si_vars_offset_vec[REGNO (op)] >= 0)
438 pj_output_varidx (mode, 0, pj_si_vars_offset_vec[REGNO (op)]);
439 else
440 pj_printf ("%*read_%s", reg_names[REGNO (op)]);
441 break;
442 case DImode:
443 case DFmode:
444 if (pj_di_vars_offset_vec[REGNO (op)] >= 0)
445 pj_output_varidx (mode, 0, pj_di_vars_offset_vec[REGNO (op)]);
446 else
447 switch (REGNO (op))
449 case G1_REG:
450 pj_printf ("%*read_global2");
451 pj_printf ("%*read_global1");
452 break;
454 /* A 64 bit read of global0 gives global0 and
455 optop. */
456 case G0_REG:
457 pj_printf ("%*read_optop");
458 pj_printf ("%*read_global0");
459 break;
461 default:
462 abort ();
464 break;
465 default:
466 abort ();
468 break;
470 case CONST_DOUBLE:
471 pj_printf (pj_standard_float_constant (op));
472 break;
474 case CONST_INT:
475 if (mode == SImode || mode == HImode || mode == QImode)
476 pj_output_push_int (INTVAL (op));
477 else if (mode == DImode)
479 int v = INTVAL (op);
480 if (v == 1)
481 pj_printf ("%*lconst_1", 0);
482 else if (v == 0)
483 pj_printf ("%*lconst_0", 0);
484 else
486 rtx hi = GEN_INT (v < 0 ? -1 : 0);
487 rtx lo = op;
488 pj_output_rval (TARGET_LITTLE_ENDIAN ? hi : lo, SImode, op);
489 pj_output_rval (TARGET_LITTLE_ENDIAN ? lo : hi, SImode, op);
492 else
493 abort ();
494 break;
496 case FLOAT_TRUNCATE:
497 pj_printf ("%S0%*d2f", XEXP (op, 0));
498 break;
499 case LABEL_REF:
500 pj_printf ("%*ipush %X", XEXP (op, 0));
501 break;
503 case SUBREG:
504 pj_output_rval (alter_subreg (op), mode, outer_op);
505 break;
507 case POST_INC:
508 pj_output_rval (XEXP (op, 0), mode, op);
509 pj_output_inc (XEXP (op, 0), GET_MODE_SIZE (GET_MODE (outer_op)));
510 break;
512 case POST_DEC:
513 pj_output_rval (XEXP (op, 0), mode, op);
514 pj_output_inc (XEXP (op, 0), -GET_MODE_SIZE (GET_MODE (outer_op)));
515 break;
517 case PRE_INC:
518 pj_output_inc (XEXP (op, 0), GET_MODE_SIZE (GET_MODE (outer_op)));
519 pj_output_rval (XEXP (op, 0), mode, op);
520 break;
522 case PRE_DEC:
523 if (OPTOP_REG_RTX_P (XEXP (op, 0)))
524 pj_output_rval (XEXP (op, 0), mode, op);
525 else if (STACK_REG_RTX_P (XEXP (op, 0)))
527 pj_output_inc (XEXP (op, 0),
528 -GET_MODE_SIZE (GET_MODE (outer_op)));
529 pj_output_rval (XEXP (op, 0), mode, op);
531 else
533 pj_printf ("%S0", XEXP (op, 0));
534 pj_output_print_add_k (-GET_MODE_SIZE (GET_MODE (outer_op)));
535 pj_printf ("%*dup%R0", XEXP (op, 0));
537 break;
539 case FIX:
540 pj_output_cnv_op (fixtrunctab[GET_MODE (XEXP (op, 0))][mode][0], op);
541 break;
543 case FLOAT:
544 if (mode == DFmode && GET_CODE (XEXP (op, 0)) == CONST_INT)
545 pj_output_cnv_op (floattab[mode][SImode][0], op);
546 else
547 pj_output_cnv_op (floattab[mode][GET_MODE (XEXP (op, 0))][0], op);
548 break;
550 case FLOAT_EXTEND:
551 case SIGN_EXTEND:
552 /* Sign extending from a memop to register is automatic. */
553 if (mode == SImode && GET_CODE (XEXP (op, 0)) == MEM)
554 pj_output_rval (XEXP (op, 0), GET_MODE (XEXP (op, 0)), op);
555 else
556 pj_output_cnv_op (extendtab[mode][GET_MODE (XEXP (op, 0))][0], op);
557 break;
559 case ZERO_EXTEND:
560 pj_output_cnv_op (extendtab[mode][GET_MODE (XEXP (op, 0))][1], op);
561 break;
563 default:
564 abort ();
565 break;
569 /* Store the top of stack into the lval operand OP. */
571 void
572 pj_output_store_into_lval (mode, op)
573 enum machine_mode mode;
574 rtx op;
576 if (GET_CODE (op) == REG)
578 int rn = REGNO (op);
580 /* Outgoing values are left on the stack and not written
581 anywhere. */
582 if (!OUTGOING_REG_RTX_P (op))
584 switch (GET_MODE (op))
586 case SImode:
587 case QImode:
588 case HImode:
589 case SFmode:
590 if (pj_si_vars_offset_vec[rn] >= 0)
591 pj_output_varidx (mode, 1, pj_si_vars_offset_vec[rn]);
592 else
593 pj_printf ("%*write_%s", reg_names[rn]);
594 break;
595 case DImode:
596 case DFmode:
597 if (pj_di_vars_offset_vec[rn] >= 0)
598 pj_output_varidx (mode, 1, pj_di_vars_offset_vec[rn]);
599 else
600 switch (rn)
602 case G1_REG:
603 pj_printf ("%*write_global1");
604 pj_printf ("%*write_global2");
605 break;
606 default:
607 abort ();
609 break;
610 default:
611 abort ();
615 else
617 pj_output_rval (XEXP (op, 0), Pmode, op);
619 switch (GET_MODE_SIZE (mode))
621 case 1:
622 pj_printf ("%*store_byte", 0);
623 break;
624 case 2:
625 pj_printf ("%*store_short", 0);
626 break;
627 case 8:
628 if (TARGET_TM_EXTENSIONS)
630 pj_printf ("%*tm_store_long");
631 break;
633 /* Fall through. */
634 default:
636 int i;
637 for (i = GET_MODE_SIZE (mode); i > 4; i -= 4)
639 pj_printf ("%*dup_x1", 0);
640 pj_printf ("%*store_word", 0);
641 pj_printf ("%*iconst_4", 0);
642 pj_printf ("%*iadd", 0);
645 pj_printf ("%*store_word", 0);
646 break;
651 /* Print a condition, unsigned and signed have the same text because
652 the unsigned operands have been run through icmp first. */
654 static void
655 pj_print_cond (code)
656 enum rtx_code code;
658 switch (code)
660 case EQ:
661 fputs ("eq", asm_out_file);
662 break;
663 case NE:
664 fputs ("ne", asm_out_file);
665 break;
666 case GT:
667 case GTU:
668 fputs ("gt", asm_out_file);
669 break;
670 case GE:
671 case GEU:
672 fputs ("ge", asm_out_file);
673 break;
674 case LT:
675 case LTU:
676 fputs ("lt", asm_out_file);
677 break;
678 case LE:
679 case LEU:
680 fputs ("le", asm_out_file);
681 break;
682 default:
683 abort ();
686 /* Print operand X (an rtx) in assembler syntax to file STREAM
687 according to modifier CODE.
689 C emit the first part of a Check_call pseudop.
690 D emit operand, if no mode, assume DImode.
691 E emit the second part of a check_call pseudop.
692 I print the XEXP (X, 0) Inside of the operand.
693 J print Just the integer or register part of an operand, for iinc.
694 P emit source is SI padded to DI with 0, used for unsigned mod and divide.
695 R emit the operand as an lval Result.
696 S emit Source operand, if no mode, assume SImode.
697 X nan choice suffix for floating point comparision.
698 Y condition name from op.
699 Z Y, reversed.
700 * marks start of opcode. */
702 void
703 pj_print_operand (stream, x, code)
704 FILE *stream;
705 rtx x;
706 int code;
708 static int last_call_known;
709 switch (code)
711 case 'C':
712 if (GET_CODE (x) == SYMBOL_REF)
714 last_call_known = 1;
715 pj_printf ("%*.check_call %0", x);
717 else
718 last_call_known = 0;
719 break;
721 case 'D':
722 pj_output_rval (x,
723 GET_MODE (x) == VOIDmode ? DImode : GET_MODE (x),
724 NULL_RTX);
725 break;
727 case 'E':
728 if (last_call_known)
729 pj_printf (",%d", INTVAL (x));
730 break;
732 case 'I':
733 pj_output_rval (XEXP (x, 0), GET_MODE (XEXP (x, 0)), NULL_RTX);
734 break;
736 case 'J':
737 if (GET_CODE (x) == CONST_INT)
738 pj_printf ("%d", INTVAL (x));
739 else if (GET_CODE (x) == REG)
740 pj_printf ("%d", pj_si_vars_offset_vec[REGNO (x)]);
741 else
742 abort ();
743 break;
745 case 'P':
746 if (TARGET_LITTLE_ENDIAN)
747 pj_printf ("%*iconst_0", 0);
748 pj_output_rval (x,
749 GET_MODE (x) == VOIDmode ? SImode : GET_MODE (x),
750 NULL_RTX);
751 if (!TARGET_LITTLE_ENDIAN)
752 pj_printf ("%*iconst_0", 0);
753 break;
755 case 'R':
756 pj_output_store_into_lval (GET_MODE (x), x);
757 break;
759 case 'S':
760 pj_output_rval (x,
761 GET_MODE (x) == VOIDmode ? SImode : GET_MODE (x),
762 NULL_RTX);
763 break;
765 case 'X':
766 fputc (GET_CODE (x) == LT || GET_CODE (x) == LE ? 'g' : 'l', stream);
767 break;
769 case 'Y':
770 pj_print_cond (GET_CODE (x));
771 break;
773 case 'Z':
774 pj_print_cond (reverse_condition (GET_CODE (x)));
775 break;
777 case '*':
778 pj_printf ("%*");
779 break;
781 default:
782 output_addr_const (stream, x);
783 break;
787 /* Return in an rtx the number of words pushed onto the optop to be
788 used as the word count in a call insn. (NEXT_ARG_REG is NULL when
789 called from expand_builtin_apply). */
792 pj_workout_arg_words (stack_size, next_arg_reg)
793 rtx stack_size ATTRIBUTE_UNUSED;
794 rtx next_arg_reg;
796 return GEN_INT ((next_arg_reg ? REGNO (next_arg_reg) - O0_REG : 0) + 2);
799 /* Handle the INCOMING_FUNCTION_ARG macro.
800 Determine where to put an argument to a function.
801 Value is zero to push the argument on the stack,
802 or a hard register in which to store the argument.
804 CUM is a variable of type CUMULATIVE_ARGS which gives info about
805 the preceding args and about the function being called.
806 MODE is the argument's machine mode.
807 TYPE is the data type of the argument (as a tree).
808 This is null for libcalls where that information may
809 not be available.
810 NAMED is nonzero if this argument is a named parameter
811 (otherwise it is an extra parameter matching an ellipsis). */
814 pj_function_incoming_arg (cum, mode, passed_type, named_arg)
815 CUMULATIVE_ARGS *cum;
816 enum machine_mode mode;
817 tree passed_type ATTRIBUTE_UNUSED;
818 int named_arg ATTRIBUTE_UNUSED;
820 int arg_words = PJ_ARG_WORDS (mode);
822 /* If the whole argument will fit into registers, return the first
823 register needed. Also fill in the arg_adjust information so that
824 we can work out the right offset to use when looking at the
825 insides of a DI or DF value. */
827 if (cum->total_words + arg_words <= ARGS_IN_REGS)
829 int i;
830 if (mode == DImode || mode == DFmode)
832 cum->arg_adjust[cum->total_words + 0] = +1;
833 cum->arg_adjust[cum->total_words + 1] = -1;
835 else
836 for (i = 0; i < arg_words; i++)
837 cum->arg_adjust[cum->total_words + i] = 0;
839 return gen_rtx (REG, mode, I0_REG + cum->total_words);
841 return NULL_RTX;
844 /* Output code to add two SImode values. Deals carefully with the the common
845 case of moving the optop. */
847 char *
848 pj_output_addsi3 (operands)
849 rtx *operands;
851 if (OPTOP_REG_RTX_P (operands[0]) && OPTOP_REG_RTX_P (operands[1])
852 && GET_CODE (operands[2]) == CONST_INT
853 && INTVAL (operands[2]) >= -32 && INTVAL (operands[2]) <= 32)
855 static struct
857 const char *two;
858 const char *one;
860 name[2] =
862 { "pop2", "pop"},
863 { "lconst_0", "iconst_0"}
865 int size = INTVAL (operands[2]);
866 int d = 0;
868 if (size < 0)
870 d = 1;
871 size = -size;
874 for (; size >= 8; size -= 8)
875 output_asm_insn (name[d].two, 0);
878 if (size > 0)
879 output_asm_insn (name[d].one, 0);
881 return "";
884 if (STACK_REG_RTX_P (operands[0])
885 && rtx_equal_p (operands[0], operands[1])
886 && GET_CODE (operands[2]) == CONST_INT
887 && INTVAL (operands[2]) >= -128 && INTVAL (operands[2]) <= 127)
889 return "iinc %J0,%J2";
892 return "%S1%S2%*iadd%R0";
895 /* Generate rtl for the prologue of the current function. */
897 void
898 pj_expand_prologue ()
900 int i;
901 int off = 0;
902 int arg_words = current_function_args_info.named_words;
904 memset (pj_si_vars_offset_vec, -1, sizeof (pj_si_vars_offset_vec));
905 memset (pj_di_vars_offset_vec, -1, sizeof (pj_di_vars_offset_vec));
907 /* Work out the register numbers of the named arguments. */
908 for (i = 0; i < current_function_args_info.named_words; i++)
910 pj_debugreg_renumber_vec[I0_REG + i]
911 = off + R0_REG + current_function_args_info.arg_adjust[i];
912 pj_si_vars_offset_vec[I0_REG + i]
913 = off + current_function_args_info.arg_adjust[i];
914 pj_di_vars_offset_vec[I0_REG + i] = off;
915 off++;
918 if (current_function_varargs || current_function_stdarg)
920 /* If the function is varadic we need to call the vhelper
921 function. vhelper pops off the unnamed argument words from
922 the opstack and puts them onto the the aggregate stack. The
923 unnamed words are replacedwith two extra arguments, a pointer
924 to the aggreagate stack for the first vararg and the original
925 global0 value. */
927 emit_insn (gen_varargs (GEN_INT (arg_words * 4)));
928 pj_si_vars_offset_vec[VA_REG] = off++;
929 off++;
930 arg_words += 2;
933 /* Skip over the return pc and old vars in the frame. */
934 off += 2;
936 /* Work out the register numbers and offsets from the var pointer
937 for the normal registers. */
938 nfakes = 0;
940 for (i = LAST_I_REG; i >= R0_REG; i--)
941 if (regs_ever_live[i] && pj_si_vars_offset_vec[i] == -1)
943 nfakes++;
944 pj_si_vars_offset_vec[i] = off;
945 pj_di_vars_offset_vec[i] = off - 1;
946 pj_debugreg_renumber_vec[i] = off + R0_REG;
947 off++;
950 if (TARGET_TEST)
952 fprintf (asm_out_file, "\n\t! args %d, size %d, fakes %d\n",
953 arg_words,
954 get_frame_size () / 4,
955 nfakes);
957 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
958 if (pj_si_vars_offset_vec[i] >= 0)
959 fprintf (asm_out_file, "\t!vars - %d %d: %s\n",
960 pj_si_vars_offset_vec[i],
961 pj_di_vars_offset_vec[i],
962 reg_names[i]);
965 /* Make room on the opstack for the fake registers. */
966 if (TARGET_TM_EXTENSIONS)
967 RTX_FRAME_RELATED_P (emit_insn (gen_tm_frame (GEN_INT (arg_words),
968 GEN_INT (nfakes)))) = 1;
969 else
970 RTX_FRAME_RELATED_P (emit_insn
971 (gen_addsi3
972 (gen_rtx_REG (SImode, OPTOP_REG),
973 gen_rtx_REG (SImode, OPTOP_REG),
974 GEN_INT (-nfakes * 4)))) = 1;
977 if (frame_pointer_needed)
978 emit_move_insn (frame_pointer_rtx, stack_pointer_rtx);
980 if (get_frame_size ())
981 RTX_FRAME_RELATED_P (emit_insn (gen_addsi3 (stack_pointer_rtx,
982 stack_pointer_rtx,
983 GEN_INT
984 (-get_frame_size ())))) = 1;
986 emit_insn (gen_rtx_USE (VOIDmode, gen_rtx_REG (SImode, OPTOP_REG)));
989 /* Generate rtl for the epilogue of the current function. */
991 void
992 pj_expand_epilogue ()
994 if (frame_pointer_needed)
995 emit_move_insn (stack_pointer_rtx, frame_pointer_rtx);
996 else if (get_frame_size ())
997 emit_insn (gen_addsi3 (stack_pointer_rtx,
998 stack_pointer_rtx, GEN_INT (get_frame_size ())));
999 if (nfakes)
1000 emit_insn (gen_addsi3 (gen_rtx_REG (SImode, OPTOP_REG),
1001 gen_rtx_REG (SImode, OPTOP_REG),
1002 GEN_INT (nfakes * 4)));
1005 /* If this is a varargs function, then global0 is stashed away on
1006 the top of the optop stack as the last secret argument by the
1007 __vhelper. Pop off the va pointer provided too. */
1009 if (current_function_varargs || current_function_stdarg)
1010 emit_insn (gen_varargs_finish
1011 (GEN_INT (current_function_args_info.named_words + 1)));
1013 emit_insn (gen_rtx_USE (VOIDmode, gen_rtx_REG (SImode, OPTOP_REG)));
1016 /* Return the opcode name for an instruction to load a standard
1017 floating point constant, or NULL. */
1019 const char *
1020 pj_standard_float_constant (op)
1021 rtx op;
1023 REAL_VALUE_TYPE r;
1024 enum machine_mode mode = GET_MODE (op);
1026 if (GET_CODE (op) != CONST_DOUBLE || (mode != DFmode && mode != SFmode))
1027 return NULL;
1029 REAL_VALUE_FROM_CONST_DOUBLE (r, op);
1031 if (REAL_VALUES_EQUAL (r, dconst0) && !REAL_VALUE_MINUS_ZERO (r))
1032 return mode == DFmode ? "%*dconst_0" : "%*fconst_0";
1034 if (REAL_VALUES_EQUAL (r, dconst1))
1035 return mode == DFmode ? "%*dconst_1" : "%*fconst_1";
1037 if (REAL_VALUES_EQUAL (r, dconst2))
1038 return mode == DFmode ? 0 : "%*fconst_2";
1040 return NULL;
1043 /* Read the value at the current address, and decrement by the size.
1044 The function is interesting because we're reading from high memory to low memory
1045 and have to adjust the addresses of reads of 8 byte values
1046 accordingly. */
1049 pj_expand_builtin_va_arg (valist, type)
1050 tree valist;
1051 tree type;
1053 tree addr_tree, t;
1054 HOST_WIDE_INT align;
1055 HOST_WIDE_INT rounded_size;
1056 rtx addr;
1058 /* Compute the rounded size of the type. */
1059 align = PARM_BOUNDARY / BITS_PER_UNIT;
1060 rounded_size = (((int_size_in_bytes (type) + align - 1) / align) * align);
1062 /* Get AP. */
1063 addr_tree = valist;
1064 addr = expand_expr (addr_tree, NULL_RTX, Pmode, EXPAND_NORMAL);
1065 addr = copy_to_reg (addr);
1067 /* Aggregates and large scalars are passed by reference. */
1068 if (AGGREGATE_TYPE_P (type) || rounded_size > 8)
1070 addr = gen_rtx_MEM (Pmode, addr);
1071 rounded_size = 4;
1074 /* adjust address to cope with double word sizes */
1075 if (rounded_size > 4)
1076 addr = gen_rtx_PLUS (Pmode, addr, GEN_INT (-4));
1078 /* Compute new value for AP; AP = AP - SIZE */
1079 t = build (MODIFY_EXPR, TREE_TYPE (valist), valist,
1080 build (MINUS_EXPR, TREE_TYPE (valist), valist,
1081 build_int_2 (rounded_size, 0)));
1083 TREE_SIDE_EFFECTS (t) = 1;
1085 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
1087 return addr;
1090 /* Return nonzero if the operand is valid as a source operand; it's
1091 general and it's not an outgoing argument register. */
1094 pj_source_operand (op, mode)
1095 rtx op;
1096 enum machine_mode mode;
1098 return !OUTGOING_REG_RTX_P (op) && general_operand (op, mode);
1101 /* Return nonzero if the operator is a signed compare. */
1104 pj_signed_comparison_operator (op, mode)
1105 rtx op;
1106 enum machine_mode mode;
1108 if (mode != GET_MODE (op))
1109 return 0;
1111 switch (GET_CODE (op))
1113 case EQ:
1114 case NE:
1115 case LE:
1116 case LT:
1117 case GE:
1118 case GT:
1119 return 1;
1120 default:
1121 return 0;
1125 /* Return nonzero if the operator is an unsigned compare. */
1128 pj_unsigned_comparison_operator (op, mode)
1129 rtx op;
1130 enum machine_mode mode ATTRIBUTE_UNUSED;
1132 if (mode != GET_MODE (op))
1133 return 0;
1135 switch (GET_CODE (op))
1137 case GTU:
1138 case GEU:
1139 case LTU:
1140 case LEU:
1141 return 1;
1142 default:
1143 return 0;
1147 /* Helper function for pj_machine_dependent_reorg. Find the one
1148 instance of register OP in the source part of PAT. If there are no
1149 copies return NULL, if there are more than one, return NOT_UNIQUE. */
1151 #define NOT_UNIQUE (&const0_rtx)
1153 static rtx *
1154 unique_src_operand (pat, reg)
1155 rtx *pat;
1156 rtx reg;
1158 register rtx *result = 0;
1159 register const char *fmt;
1160 register int i;
1161 register int j;
1163 if (GET_CODE (*pat) == SET)
1165 if (GET_CODE (XEXP (*pat, 0)) == MEM)
1166 result = unique_src_operand (&XEXP (SET_DEST (*pat), 0), reg);
1167 pat = &SET_SRC (*pat);
1170 if (GET_CODE (*pat) == REG && REGNO (*pat) == REGNO (reg))
1171 return pat;
1173 fmt = GET_RTX_FORMAT (GET_CODE (*pat));
1174 for (i = GET_RTX_LENGTH (GET_CODE (*pat)) - 1; i >= 0; i--)
1176 if (fmt[i] == 'e')
1178 rtx *new_result = unique_src_operand (&XEXP (*pat, i), reg);
1180 if (new_result)
1182 if (result)
1183 return NOT_UNIQUE;
1184 result = new_result;
1187 else if (fmt[i] == 'E')
1189 for (j = XVECLEN (*pat, i) - 1; j >= 0; j--)
1191 rtx *new_result =
1192 unique_src_operand (&XVECEXP (*pat, i, j), reg);
1194 if (new_result)
1196 if (result)
1197 return NOT_UNIQUE;
1198 result = new_result;
1203 return result;
1206 /* Clean up the instructions to remove unneeded loads and stores.
1208 For example, rewrite
1210 iload a; iload b; iadd; istore z
1211 iload z; iload c; iadd; istore z
1215 iload a; iload b; iadd ; iload c; iadd; istore z
1217 This function moves a cursor over each instruction, inspecting the
1218 LOG_LINKS. Each of the cursor's LOG_LINK incoming instructions are
1219 inspected, any which have a simple register destination which is
1220 also used as a source in the cursor instruction, and aren't used
1221 again between the the incoming instruction and the cursor, and
1222 which become dead or set after the cursor get their sources
1223 substituted into the position of the source register in the cursor
1224 instruction. */
1226 void
1227 pj_machine_dependent_reorg (insns)
1228 rtx insns;
1230 rtx cursor;
1232 if (!optimize || !TARGET_REORG)
1233 return;
1235 for (cursor = insns; cursor; cursor = NEXT_INSN (cursor))
1237 rtx links;
1238 rtx cursor_pat;
1240 /* We only care about INSNs, JUMP_INSNs. Ignore any special USE insns. */
1242 if ((GET_CODE (cursor) != INSN && GET_CODE (cursor) != JUMP_INSN)
1243 || GET_CODE (cursor_pat = PATTERN (cursor)) == USE
1244 || GET_CODE (cursor_pat) == CLOBBER
1245 || GET_CODE (cursor_pat) == ADDR_VEC
1246 || GET_CODE (cursor_pat) == ADDR_DIFF_VEC)
1247 continue;
1249 for (links = LOG_LINKS (cursor); links; links = XEXP (links, 1))
1251 rtx prev = XEXP (links, 0);
1252 rtx prev_pat;
1253 rtx prev_dest;
1254 rtx prev_src;
1255 rtx *dst_place;
1257 if (GET_CODE (prev) == INSN
1258 && GET_CODE (prev_pat = PATTERN (prev)) == SET
1259 && GET_CODE (prev_dest = SET_DEST (prev_pat)) == REG
1260 && dead_or_set_p (cursor, prev_dest)
1261 && !reg_used_between_p (prev_dest, prev, cursor)
1262 && no_labels_between_p (prev, cursor)
1263 && no_jumps_between_p (prev, cursor)
1264 && !modified_between_p ((prev_src = SET_SRC (prev_pat)), prev,
1265 cursor)
1266 && (dst_place = unique_src_operand (&cursor_pat, prev_dest))
1267 && dst_place != NOT_UNIQUE
1268 && REGNO (prev_dest) != OPTOP_REG
1269 && GET_MODE (prev_dest) != XFmode
1270 && GET_MODE (*dst_place) == GET_MODE (SET_DEST (prev_pat)))
1272 *dst_place = SET_SRC (prev_pat);
1273 PUT_CODE (prev, NOTE);
1274 NOTE_LINE_NUMBER (prev) = NOTE_INSN_DELETED;