1 /* Subroutines used for code generation on Vitesse IQ2000 processors
2 Copyright (C) 2003 Free Software Foundation, Inc.
4 This file is part of GCC.
6 GCC 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)
11 GCC 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 GCC; see the file COPYING. If not, write to
18 the Free Software Foundation, 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA. */
23 #include "coretypes.h"
29 #include "hard-reg-set.h"
31 #include "insn-config.h"
32 #include "conditions.h"
34 #include "insn-attr.h"
47 #include "target-def.h"
49 /* Enumeration for all of the relational tests, so that we can build
50 arrays indexed by the test type, and not worry about the order
69 static void iq2000_count_memory_refs (rtx, int);
70 static enum internal_test map_test_to_internal_test (enum rtx_code);
71 static rtx iq2000_add_large_offset_to_sp (HOST_WIDE_INT);
72 static void iq2000_annotate_frame_insn (rtx, rtx);
73 static void iq2000_emit_frame_related_store (rtx, rtx,
75 static struct machine_function * iq2000_init_machine_status (void);
76 static void save_restore_insns (int);
77 static void abort_with_insn (rtx, const char *)
79 static int symbolic_expression_p (rtx);
80 static enum processor_type iq2000_parse_cpu (const char *);
81 static void iq2000_select_rtx_section (enum machine_mode, rtx,
82 unsigned HOST_WIDE_INT);
83 static void iq2000_select_section (tree, int, unsigned HOST_WIDE_INT);
84 static rtx expand_one_builtin (enum insn_code, rtx, tree, enum rtx_code*,
87 /* Structure to be filled in by compute_frame_size with register
88 save masks, and offsets for the current function. */
90 struct iq2000_frame_info
92 long total_size; /* # bytes that the entire frame takes up */
93 long var_size; /* # bytes that variables take up */
94 long args_size; /* # bytes that outgoing arguments take up */
95 long extra_size; /* # bytes of extra gunk */
96 int gp_reg_size; /* # bytes needed to store gp regs */
97 int fp_reg_size; /* # bytes needed to store fp regs */
98 long mask; /* mask of saved gp registers */
99 long gp_save_offset; /* offset from vfp to store gp registers */
100 long fp_save_offset; /* offset from vfp to store fp registers */
101 long gp_sp_offset; /* offset from new sp to store gp registers */
102 long fp_sp_offset; /* offset from new sp to store fp registers */
103 int initialized; /* != 0 if frame size already calculated */
104 int num_gp; /* number of gp registers saved */
107 struct machine_function
109 /* Current frame information, calculated by compute_frame_size. */
110 struct iq2000_frame_info frame;
113 /* Global variables for machine-dependent things. */
115 /* Count the number of .file directives, so that .loc is up to date. */
116 int num_source_filenames = 0;
118 /* Files to separate the text and the data output, so that all of the data
119 can be emitted before the text, which will mean that the assembler will
120 generate smaller code, based on the global pointer. */
121 FILE *asm_out_data_file;
122 FILE *asm_out_text_file;
124 /* The next branch instruction is a branch likely, not branch normal. */
125 int iq2000_branch_likely;
127 /* Count of delay slots and how many are filled. */
128 int dslots_load_total;
129 int dslots_load_filled;
130 int dslots_jump_total;
131 int dslots_jump_filled;
133 /* # of nops needed by previous insn */
134 int dslots_number_nops;
136 /* Number of 1/2/3 word references to data items (ie, not jal's). */
139 /* registers to check for load delay */
140 rtx iq2000_load_reg, iq2000_load_reg2, iq2000_load_reg3, iq2000_load_reg4;
142 /* Cached operands, and operator to compare for use in set/branch/trap
143 on condition codes. */
146 /* what type of branch to use */
147 enum cmp_type branch_type;
149 /* The target cpu for code generation. */
150 enum processor_type iq2000_arch;
152 /* The target cpu for optimization and scheduling. */
153 enum processor_type iq2000_tune;
155 /* which instruction set architecture to use. */
158 /* Strings to hold which cpu and instruction set architecture to use. */
159 const char *iq2000_cpu_string; /* for -mcpu=<xxx> */
160 const char *iq2000_arch_string; /* for -march=<xxx> */
162 /* Mode used for saving/restoring general purpose registers. */
163 static enum machine_mode gpr_mode;
165 /* List of all IQ2000 punctuation characters used by print_operand. */
166 char iq2000_print_operand_punct[256];
168 /* Initialize the GCC target structure. */
169 #undef TARGET_INIT_BUILTINS
170 #define TARGET_INIT_BUILTINS iq2000_init_builtins
172 #undef TARGET_EXPAND_BUILTIN
173 #define TARGET_EXPAND_BUILTIN iq2000_expand_builtin
175 #undef TARGET_ASM_SELECT_RTX_SECTION
176 #define TARGET_ASM_SELECT_RTX_SECTION iq2000_select_rtx_section
178 struct gcc_target targetm = TARGET_INITIALIZER;
180 /* Return 1 if OP can be used as an operand where a register or 16 bit unsigned
181 integer is needed. */
184 uns_arith_operand (rtx op, enum machine_mode mode)
186 if (GET_CODE (op) == CONST_INT && SMALL_INT_UNSIGNED (op))
189 return register_operand (op, mode);
192 /* Return 1 if OP can be used as an operand where a 16 bit integer is needed. */
195 arith_operand (rtx op, enum machine_mode mode)
197 if (GET_CODE (op) == CONST_INT && SMALL_INT (op))
200 return register_operand (op, mode);
203 /* Return 1 if OP is a integer which fits in 16 bits */
206 small_int (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
208 return (GET_CODE (op) == CONST_INT && SMALL_INT (op));
211 /* Return 1 if OP is a 32 bit integer which is too big to be loaded with one
215 large_int (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
219 if (GET_CODE (op) != CONST_INT)
224 /* ior reg,$r0,value */
225 if ((value & ~ ((HOST_WIDE_INT) 0x0000ffff)) == 0)
228 /* subu reg,$r0,value */
229 if (((unsigned HOST_WIDE_INT) (value + 32768)) <= 32767)
232 /* lui reg,value>>16 */
233 if ((value & 0x0000ffff) == 0)
239 /* Return 1 if OP is a register or the constant 0. */
242 reg_or_0_operand (rtx op, enum machine_mode mode)
244 switch (GET_CODE (op))
247 return INTVAL (op) == 0;
250 return op == CONST0_RTX (mode);
254 return register_operand (op, mode);
263 /* Return 1 if OP is a memory operand that fits in a single instruction
264 (ie, register + small offset). */
267 simple_memory_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
269 rtx addr, plus0, plus1;
271 /* Eliminate non-memory operations */
272 if (GET_CODE (op) != MEM)
275 /* dword operations really put out 2 instructions, so eliminate them. */
276 if (GET_MODE_SIZE (GET_MODE (op)) > (unsigned) UNITS_PER_WORD)
279 /* Decode the address now. */
281 switch (GET_CODE (addr))
288 return SMALL_INT (addr);
291 plus0 = XEXP (addr, 0);
292 plus1 = XEXP (addr, 1);
293 if (GET_CODE (plus0) == REG
294 && GET_CODE (plus1) == CONST_INT && SMALL_INT (plus1)
295 && SMALL_INT_UNSIGNED (plus1) /* No negative offsets */)
298 else if (GET_CODE (plus1) == REG
299 && GET_CODE (plus0) == CONST_INT && SMALL_INT (plus0)
300 && SMALL_INT_UNSIGNED (plus1) /* No negative offsets */)
316 /* Return nonzero if the code of this rtx pattern is EQ or NE. */
319 equality_op (rtx op, enum machine_mode mode)
321 if (mode != GET_MODE (op))
324 return GET_CODE (op) == EQ || GET_CODE (op) == NE;
327 /* Return nonzero if the code is a relational operations (EQ, LE, etc.) */
330 cmp_op (rtx op, enum machine_mode mode)
332 if (mode != GET_MODE (op))
335 return GET_RTX_CLASS (GET_CODE (op)) == '<';
338 /* Return nonzero if the operand is either the PC or a label_ref. */
341 pc_or_label_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
346 if (GET_CODE (op) == LABEL_REF)
352 /* Return nonzero if OP is a valid operand for a call instruction. */
355 call_insn_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
357 return (CONSTANT_ADDRESS_P (op)
358 || (GET_CODE (op) == REG && op != arg_pointer_rtx
359 && ! (REGNO (op) >= FIRST_PSEUDO_REGISTER
360 && REGNO (op) <= LAST_VIRTUAL_REGISTER)));
363 /* Return nonzero if OP is valid as a source operand for a move instruction. */
366 move_operand (rtx op, enum machine_mode mode)
368 /* Accept any general operand after reload has started; doing so
369 avoids losing if reload does an in-place replacement of a register
370 with a SYMBOL_REF or CONST. */
371 return (general_operand (op, mode)
372 && (! (iq2000_check_split (op, mode))
373 || reload_in_progress || reload_completed));
376 /* Return nonzero if OP is a constant power of 2. */
379 power_of_2_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
383 if (GET_CODE (op) != CONST_INT)
386 intval = INTVAL (op);
388 return ((intval & ((unsigned)(intval) - 1)) == 0);
391 /* Return nonzero if we split the address into high and low parts. */
394 iq2000_check_split (rtx address, enum machine_mode mode)
396 /* This is the same check used in simple_memory_operand.
397 We use it here because LO_SUM is not offsettable. */
398 if (GET_MODE_SIZE (mode) > (unsigned) UNITS_PER_WORD)
401 if ((GET_CODE (address) == SYMBOL_REF)
402 || (GET_CODE (address) == CONST
403 && GET_CODE (XEXP (XEXP (address, 0), 0)) == SYMBOL_REF)
404 || GET_CODE (address) == LABEL_REF)
410 /* Return nonzero if REG is valid for MODE. */
413 iq2000_reg_mode_ok_for_base_p (rtx reg,
414 enum machine_mode mode ATTRIBUTE_UNUSED,
418 ? REGNO_MODE_OK_FOR_BASE_P (REGNO (reg), mode)
419 : GP_REG_OR_PSEUDO_NONSTRICT_P (REGNO (reg), mode));
422 /* Return a nonzero value if XINSN is a legitimate address for a
423 memory operand of the indicated MODE. STRICT is nonzero if this
424 function is called during reload. */
427 iq2000_legitimate_address_p (enum machine_mode mode, rtx xinsn, int strict)
429 if (TARGET_DEBUG_A_MODE)
431 GO_PRINTF2 ("\n========== GO_IF_LEGITIMATE_ADDRESS, %sstrict\n",
432 strict ? "" : "not ");
433 GO_DEBUG_RTX (xinsn);
436 /* Check for constant before stripping off SUBREG, so that we don't
437 accept (subreg (const_int)) which will fail to reload. */
438 if (CONSTANT_ADDRESS_P (xinsn)
439 && ! (iq2000_check_split (xinsn, mode))
440 && ! (GET_CODE (xinsn) == CONST_INT && ! SMALL_INT (xinsn)))
443 while (GET_CODE (xinsn) == SUBREG)
444 xinsn = SUBREG_REG (xinsn);
446 if (GET_CODE (xinsn) == REG
447 && iq2000_reg_mode_ok_for_base_p (xinsn, mode, strict))
450 if (GET_CODE (xinsn) == LO_SUM)
452 register rtx xlow0 = XEXP (xinsn, 0);
453 register rtx xlow1 = XEXP (xinsn, 1);
455 while (GET_CODE (xlow0) == SUBREG)
456 xlow0 = SUBREG_REG (xlow0);
457 if (GET_CODE (xlow0) == REG
458 && iq2000_reg_mode_ok_for_base_p (xlow0, mode, strict)
459 && iq2000_check_split (xlow1, mode))
463 if (GET_CODE (xinsn) == PLUS)
465 register rtx xplus0 = XEXP (xinsn, 0);
466 register rtx xplus1 = XEXP (xinsn, 1);
467 register enum rtx_code code0;
468 register enum rtx_code code1;
470 while (GET_CODE (xplus0) == SUBREG)
471 xplus0 = SUBREG_REG (xplus0);
472 code0 = GET_CODE (xplus0);
474 while (GET_CODE (xplus1) == SUBREG)
475 xplus1 = SUBREG_REG (xplus1);
476 code1 = GET_CODE (xplus1);
479 && iq2000_reg_mode_ok_for_base_p (xplus0, mode, strict))
481 if (code1 == CONST_INT && SMALL_INT (xplus1)
482 && SMALL_INT_UNSIGNED (xplus1) /* No negative offsets */)
487 if (TARGET_DEBUG_A_MODE)
488 GO_PRINTF ("Not a legitimate address\n");
490 /* The address was not legitimate. */
494 /* Returns an operand string for the given instruction's delay slot,
495 after updating filled delay slot statistics.
497 We assume that operands[0] is the target register that is set.
499 In order to check the next insn, most of this functionality is moved
500 to FINAL_PRESCAN_INSN, and we just set the global variables that
504 iq2000_fill_delay_slot (const char *ret, enum delay_type type, rtx operands[],
507 register rtx set_reg;
508 register enum machine_mode mode;
509 register rtx next_insn = cur_insn ? NEXT_INSN (cur_insn) : NULL_RTX;
510 register int num_nops;
512 if (type == DELAY_LOAD || type == DELAY_FCMP)
518 /* Make sure that we don't put nop's after labels. */
519 next_insn = NEXT_INSN (cur_insn);
520 while (next_insn != 0
521 && (GET_CODE (next_insn) == NOTE
522 || GET_CODE (next_insn) == CODE_LABEL))
523 next_insn = NEXT_INSN (next_insn);
525 dslots_load_total += num_nops;
526 if (TARGET_DEBUG_C_MODE
527 || type == DELAY_NONE
531 || GET_CODE (next_insn) == CODE_LABEL
532 || (set_reg = operands[0]) == 0)
534 dslots_number_nops = 0;
536 iq2000_load_reg2 = 0;
537 iq2000_load_reg3 = 0;
538 iq2000_load_reg4 = 0;
542 set_reg = operands[0];
546 while (GET_CODE (set_reg) == SUBREG)
547 set_reg = SUBREG_REG (set_reg);
549 mode = GET_MODE (set_reg);
550 dslots_number_nops = num_nops;
551 iq2000_load_reg = set_reg;
552 if (GET_MODE_SIZE (mode)
553 > (unsigned) (UNITS_PER_WORD))
554 iq2000_load_reg2 = gen_rtx_REG (SImode, REGNO (set_reg) + 1);
556 iq2000_load_reg2 = 0;
561 /* Determine whether a memory reference takes one (based off of the GP
562 pointer), two (normal), or three (label + reg) instructions, and bump the
563 appropriate counter for -mstats. */
566 iq2000_count_memory_refs (rtx op, int num)
570 rtx addr, plus0, plus1;
571 enum rtx_code code0, code1;
574 if (TARGET_DEBUG_B_MODE)
576 fprintf (stderr, "\n========== iq2000_count_memory_refs:\n");
580 /* Skip MEM if passed, otherwise handle movsi of address. */
581 addr = (GET_CODE (op) != MEM) ? op : XEXP (op, 0);
583 /* Loop, going through the address RTL. */
587 switch (GET_CODE (addr))
595 plus0 = XEXP (addr, 0);
596 plus1 = XEXP (addr, 1);
597 code0 = GET_CODE (plus0);
598 code1 = GET_CODE (plus1);
608 if (code0 == CONST_INT)
623 if (code1 == CONST_INT)
630 if (code0 == SYMBOL_REF || code0 == LABEL_REF || code0 == CONST)
637 if (code1 == SYMBOL_REF || code1 == LABEL_REF || code1 == CONST)
647 n_words = 2; /* always 2 words */
651 addr = XEXP (addr, 0);
656 n_words = SYMBOL_REF_FLAG (addr) ? 1 : 2;
668 n_words += additional;
672 num_refs[n_words-1] += num;
675 /* Return the appropriate instructions to move one operand to another. */
678 iq2000_move_1word (rtx operands[], rtx insn, int unsignedp)
681 rtx op0 = operands[0];
682 rtx op1 = operands[1];
683 enum rtx_code code0 = GET_CODE (op0);
684 enum rtx_code code1 = GET_CODE (op1);
685 enum machine_mode mode = GET_MODE (op0);
686 int subreg_offset0 = 0;
687 int subreg_offset1 = 0;
688 enum delay_type delay = DELAY_NONE;
690 while (code0 == SUBREG)
692 subreg_offset0 += subreg_regno_offset (REGNO (SUBREG_REG (op0)),
693 GET_MODE (SUBREG_REG (op0)),
696 op0 = SUBREG_REG (op0);
697 code0 = GET_CODE (op0);
700 while (code1 == SUBREG)
702 subreg_offset1 += subreg_regno_offset (REGNO (SUBREG_REG (op1)),
703 GET_MODE (SUBREG_REG (op1)),
706 op1 = SUBREG_REG (op1);
707 code1 = GET_CODE (op1);
710 /* For our purposes, a condition code mode is the same as SImode. */
716 int regno0 = REGNO (op0) + subreg_offset0;
720 int regno1 = REGNO (op1) + subreg_offset1;
722 /* Do not do anything for assigning a register to itself */
723 if (regno0 == regno1)
726 else if (GP_REG_P (regno0))
728 if (GP_REG_P (regno1))
729 ret = "or\t%0,%%0,%1";
734 else if (code1 == MEM)
739 iq2000_count_memory_refs (op1, 1);
741 if (GP_REG_P (regno0))
743 /* For loads, use the mode of the memory item, instead of the
744 target, so zero/sign extend can use this code as well. */
745 switch (GET_MODE (op1))
757 ret = (unsignedp) ? "lhu\t%0,%1" : "lh\t%0,%1";
760 ret = (unsignedp) ? "lbu\t%0,%1" : "lb\t%0,%1";
766 else if (code1 == CONST_INT
767 || (code1 == CONST_DOUBLE
768 && GET_MODE (op1) == VOIDmode))
770 if (code1 == CONST_DOUBLE)
772 /* This can happen when storing constants into long long
773 bitfields. Just store the least significant word of
775 operands[1] = op1 = GEN_INT (CONST_DOUBLE_LOW (op1));
778 if (INTVAL (op1) == 0)
780 if (GP_REG_P (regno0))
781 ret = "or\t%0,%%0,%z1";
783 else if (GP_REG_P (regno0))
785 if (SMALL_INT_UNSIGNED (op1))
786 ret = "ori\t%0,%%0,%x1\t\t\t# %1";
787 else if (SMALL_INT (op1))
788 ret = "addiu\t%0,%%0,%1\t\t\t# %1";
790 ret = "lui\t%0,%X1\t\t\t# %1\n\tori\t%0,%0,%x1";
794 else if (code1 == CONST_DOUBLE && mode == SFmode)
796 if (op1 == CONST0_RTX (SFmode))
798 if (GP_REG_P (regno0))
799 ret = "or\t%0,%%0,%.";
809 else if (code1 == LABEL_REF)
812 iq2000_count_memory_refs (op1, 1);
817 else if (code1 == SYMBOL_REF || code1 == CONST)
820 iq2000_count_memory_refs (op1, 1);
825 else if (code1 == PLUS)
827 rtx add_op0 = XEXP (op1, 0);
828 rtx add_op1 = XEXP (op1, 1);
830 if (GET_CODE (XEXP (op1, 1)) == REG
831 && GET_CODE (XEXP (op1, 0)) == CONST_INT)
832 add_op0 = XEXP (op1, 1), add_op1 = XEXP (op1, 0);
834 operands[2] = add_op0;
835 operands[3] = add_op1;
836 ret = "add%:\t%0,%2,%3";
839 else if (code1 == HIGH)
841 operands[1] = XEXP (op1, 0);
842 ret = "lui\t%0,%%hi(%1)";
846 else if (code0 == MEM)
849 iq2000_count_memory_refs (op0, 1);
853 int regno1 = REGNO (op1) + subreg_offset1;
855 if (GP_REG_P (regno1))
859 case SFmode: ret = "sw\t%1,%0"; break;
860 case SImode: ret = "sw\t%1,%0"; break;
861 case HImode: ret = "sh\t%1,%0"; break;
862 case QImode: ret = "sb\t%1,%0"; break;
868 else if (code1 == CONST_INT && INTVAL (op1) == 0)
872 case SFmode: ret = "sw\t%z1,%0"; break;
873 case SImode: ret = "sw\t%z1,%0"; break;
874 case HImode: ret = "sh\t%z1,%0"; break;
875 case QImode: ret = "sb\t%z1,%0"; break;
880 else if (code1 == CONST_DOUBLE && op1 == CONST0_RTX (mode))
884 case SFmode: ret = "sw\t%.,%0"; break;
885 case SImode: ret = "sw\t%.,%0"; break;
886 case HImode: ret = "sh\t%.,%0"; break;
887 case QImode: ret = "sb\t%.,%0"; break;
895 abort_with_insn (insn, "Bad move");
899 if (delay != DELAY_NONE)
900 return iq2000_fill_delay_slot (ret, delay, operands, insn);
905 /* Provide the costs of an addressing mode that contains ADDR. */
908 iq2000_address_cost (rtx addr)
910 switch (GET_CODE (addr))
920 rtx offset = const0_rtx;
921 addr = eliminate_constant_term (XEXP (addr, 0), &offset);
922 if (GET_CODE (addr) == LABEL_REF)
925 if (GET_CODE (addr) != SYMBOL_REF)
928 if (! SMALL_INT (offset))
932 /* ... fall through ... */
935 return SYMBOL_REF_FLAG (addr) ? 1 : 2;
939 register rtx plus0 = XEXP (addr, 0);
940 register rtx plus1 = XEXP (addr, 1);
942 if (GET_CODE (plus0) != REG && GET_CODE (plus1) == REG)
943 plus0 = XEXP (addr, 1), plus1 = XEXP (addr, 0);
945 if (GET_CODE (plus0) != REG)
948 switch (GET_CODE (plus1))
951 return SMALL_INT (plus1) ? 1 : 2;
958 return iq2000_address_cost (plus1) + 1;
972 /* Make normal rtx_code into something we can index from an array. */
974 static enum internal_test
975 map_test_to_internal_test (enum rtx_code test_code)
977 enum internal_test test = ITEST_MAX;
981 case EQ: test = ITEST_EQ; break;
982 case NE: test = ITEST_NE; break;
983 case GT: test = ITEST_GT; break;
984 case GE: test = ITEST_GE; break;
985 case LT: test = ITEST_LT; break;
986 case LE: test = ITEST_LE; break;
987 case GTU: test = ITEST_GTU; break;
988 case GEU: test = ITEST_GEU; break;
989 case LTU: test = ITEST_LTU; break;
990 case LEU: test = ITEST_LEU; break;
997 /* Generate the code to compare two integer values. The return value is:
998 (reg:SI xx) The pseudo register the comparison is in
999 0 No register, generate a simple branch.
1001 TEST_CODE: relational test (EQ, etc).
1002 RESULT: result to store comp. or 0 if branch.
1003 CMP0: first operand to compare
1004 CMP1: second operand to compare
1005 *P_INVERT: NULL or ptr to hold whether branch needs to reverse its test. */
1008 gen_int_relational (enum rtx_code test_code, rtx result, rtx cmp0, rtx cmp1,
1013 enum rtx_code test_code; /* code to use in instruction (LT vs. LTU) */
1014 int const_low; /* low bound of constant we can accept */
1015 int const_high; /* high bound of constant we can accept */
1016 int const_add; /* constant to add (convert LE -> LT) */
1017 int reverse_regs; /* reverse registers in test */
1018 int invert_const; /* != 0 if invert value if cmp1 is constant */
1019 int invert_reg; /* != 0 if invert value if cmp1 is register */
1020 int unsignedp; /* != 0 for unsigned comparisons. */
1023 static struct cmp_info info[ (int)ITEST_MAX ] = {
1025 { XOR, 0, 65535, 0, 0, 0, 0, 0 }, /* EQ */
1026 { XOR, 0, 65535, 0, 0, 1, 1, 0 }, /* NE */
1027 { LT, -32769, 32766, 1, 1, 1, 0, 0 }, /* GT */
1028 { LT, -32768, 32767, 0, 0, 1, 1, 0 }, /* GE */
1029 { LT, -32768, 32767, 0, 0, 0, 0, 0 }, /* LT */
1030 { LT, -32769, 32766, 1, 1, 0, 1, 0 }, /* LE */
1031 { LTU, -32769, 32766, 1, 1, 1, 0, 1 }, /* GTU */
1032 { LTU, -32768, 32767, 0, 0, 1, 1, 1 }, /* GEU */
1033 { LTU, -32768, 32767, 0, 0, 0, 0, 1 }, /* LTU */
1034 { LTU, -32769, 32766, 1, 1, 0, 1, 1 }, /* LEU */
1037 enum internal_test test;
1038 enum machine_mode mode;
1039 struct cmp_info *p_info;
1046 test = map_test_to_internal_test (test_code);
1047 if (test == ITEST_MAX)
1050 p_info = &info[(int) test];
1051 eqne_p = (p_info->test_code == XOR);
1053 mode = GET_MODE (cmp0);
1054 if (mode == VOIDmode)
1055 mode = GET_MODE (cmp1);
1057 /* Eliminate simple branches */
1058 branch_p = (result == 0);
1061 if (GET_CODE (cmp0) == REG || GET_CODE (cmp0) == SUBREG)
1063 /* Comparisons against zero are simple branches */
1064 if (GET_CODE (cmp1) == CONST_INT && INTVAL (cmp1) == 0)
1067 /* Test for beq/bne. */
1072 /* allocate a pseudo to calculate the value in. */
1073 result = gen_reg_rtx (mode);
1076 /* Make sure we can handle any constants given to us. */
1077 if (GET_CODE (cmp0) == CONST_INT)
1078 cmp0 = force_reg (mode, cmp0);
1080 if (GET_CODE (cmp1) == CONST_INT)
1082 HOST_WIDE_INT value = INTVAL (cmp1);
1084 if (value < p_info->const_low
1085 || value > p_info->const_high)
1086 cmp1 = force_reg (mode, cmp1);
1089 /* See if we need to invert the result. */
1090 invert = (GET_CODE (cmp1) == CONST_INT
1091 ? p_info->invert_const : p_info->invert_reg);
1093 if (p_invert != (int *)0)
1099 /* Comparison to constants, may involve adding 1 to change a LT into LE.
1100 Comparison between two registers, may involve switching operands. */
1101 if (GET_CODE (cmp1) == CONST_INT)
1103 if (p_info->const_add != 0)
1105 HOST_WIDE_INT new = INTVAL (cmp1) + p_info->const_add;
1107 /* If modification of cmp1 caused overflow,
1108 we would get the wrong answer if we follow the usual path;
1109 thus, x > 0xffffffffU would turn into x > 0U. */
1110 if ((p_info->unsignedp
1111 ? (unsigned HOST_WIDE_INT) new >
1112 (unsigned HOST_WIDE_INT) INTVAL (cmp1)
1113 : new > INTVAL (cmp1))
1114 != (p_info->const_add > 0))
1116 /* This test is always true, but if INVERT is true then
1117 the result of the test needs to be inverted so 0 should
1118 be returned instead. */
1119 emit_move_insn (result, invert ? const0_rtx : const_true_rtx);
1123 cmp1 = GEN_INT (new);
1127 else if (p_info->reverse_regs)
1134 if (test == ITEST_NE && GET_CODE (cmp1) == CONST_INT && INTVAL (cmp1) == 0)
1138 reg = (invert || eqne_p) ? gen_reg_rtx (mode) : result;
1139 convert_move (reg, gen_rtx (p_info->test_code, mode, cmp0, cmp1), 0);
1142 if (test == ITEST_NE)
1144 convert_move (result, gen_rtx (GTU, mode, reg, const0_rtx), 0);
1145 if (p_invert != NULL)
1150 else if (test == ITEST_EQ)
1152 reg2 = invert ? gen_reg_rtx (mode) : result;
1153 convert_move (reg2, gen_rtx_LTU (mode, reg, const1_rtx), 0);
1162 convert_move (result, gen_rtx (XOR, mode, reg, one), 0);
1168 /* Emit the common code for doing conditional branches.
1169 operand[0] is the label to jump to.
1170 The comparison operands are saved away by cmp{si,di,sf,df}. */
1173 gen_conditional_branch (rtx operands[], enum rtx_code test_code)
1175 enum cmp_type type = branch_type;
1176 rtx cmp0 = branch_cmp[0];
1177 rtx cmp1 = branch_cmp[1];
1178 enum machine_mode mode;
1187 mode = type == CMP_SI ? SImode : DImode;
1189 reg = gen_int_relational (test_code, NULL_RTX, cmp0, cmp1, &invert);
1197 else if (GET_CODE (cmp1) == CONST_INT && INTVAL (cmp1) != 0)
1198 /* We don't want to build a comparison against a nonzero
1200 cmp1 = force_reg (mode, cmp1);
1206 reg = gen_reg_rtx (CCmode);
1208 /* For cmp0 != cmp1, build cmp0 == cmp1, and test for result == 0 */
1209 emit_insn (gen_rtx_SET (VOIDmode, reg,
1210 gen_rtx (test_code == NE ? EQ : test_code,
1211 CCmode, cmp0, cmp1)));
1213 test_code = test_code == NE ? EQ : NE;
1221 abort_with_insn (gen_rtx (test_code, VOIDmode, cmp0, cmp1), "bad test");
1224 /* Generate the branch. */
1226 label1 = gen_rtx_LABEL_REF (VOIDmode, operands[0]);
1235 emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
1236 gen_rtx_IF_THEN_ELSE (VOIDmode,
1237 gen_rtx (test_code, mode,
1242 /* Initialize CUMULATIVE_ARGS for a function. */
1245 init_cumulative_args (CUMULATIVE_ARGS *cum, tree fntype,
1246 rtx libname ATTRIBUTE_UNUSED)
1248 static CUMULATIVE_ARGS zero_cum;
1249 tree param, next_param;
1251 if (TARGET_DEBUG_D_MODE)
1254 "\ninit_cumulative_args, fntype = 0x%.8lx", (long)fntype);
1257 fputc ('\n', stderr);
1261 tree ret_type = TREE_TYPE (fntype);
1262 fprintf (stderr, ", fntype code = %s, ret code = %s\n",
1263 tree_code_name[(int)TREE_CODE (fntype)],
1264 tree_code_name[(int)TREE_CODE (ret_type)]);
1270 /* Determine if this function has variable arguments. This is
1271 indicated by the last argument being 'void_type_mode' if there
1272 are no variable arguments. The standard IQ2000 calling sequence
1273 passes all arguments in the general purpose registers in this case. */
1275 for (param = fntype ? TYPE_ARG_TYPES (fntype) : 0;
1276 param != 0; param = next_param)
1278 next_param = TREE_CHAIN (param);
1279 if (next_param == 0 && TREE_VALUE (param) != void_type_node)
1280 cum->gp_reg_found = 1;
1284 /* Advance the argument to the next argument position. */
1287 function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode, tree type,
1290 if (TARGET_DEBUG_D_MODE)
1293 "function_adv({gp reg found = %d, arg # = %2d, words = %2d}, %4s, ",
1294 cum->gp_reg_found, cum->arg_number, cum->arg_words,
1295 GET_MODE_NAME (mode));
1296 fprintf (stderr, HOST_PTR_PRINTF, (const PTR) type);
1297 fprintf (stderr, ", %d )\n\n", named);
1307 if (GET_MODE_CLASS (mode) != MODE_COMPLEX_INT
1308 && GET_MODE_CLASS (mode) != MODE_COMPLEX_FLOAT)
1311 cum->gp_reg_found = 1;
1312 cum->arg_words += ((GET_MODE_SIZE (mode) + UNITS_PER_WORD - 1)
1317 cum->gp_reg_found = 1;
1318 cum->arg_words += ((int_size_in_bytes (type) + UNITS_PER_WORD - 1)
1324 if (! cum->gp_reg_found && cum->arg_number <= 2)
1325 cum->fp_code += 1 << ((cum->arg_number - 1) * 2);
1329 cum->arg_words += 2;
1330 if (! cum->gp_reg_found && cum->arg_number <= 2)
1331 cum->fp_code += 2 << ((cum->arg_number - 1) * 2);
1335 cum->gp_reg_found = 1;
1336 cum->arg_words += 2;
1342 cum->gp_reg_found = 1;
1348 /* Return an RTL expression containing the register for the given mode,
1349 or 0 if the argument is to be passed on the stack. */
1352 function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode, tree type,
1358 unsigned int *arg_words = &cum->arg_words;
1359 int struct_p = (type != 0
1360 && (TREE_CODE (type) == RECORD_TYPE
1361 || TREE_CODE (type) == UNION_TYPE
1362 || TREE_CODE (type) == QUAL_UNION_TYPE));
1364 if (TARGET_DEBUG_D_MODE)
1367 "function_arg( {gp reg found = %d, arg # = %2d, words = %2d}, %4s, ",
1368 cum->gp_reg_found, cum->arg_number, cum->arg_words,
1369 GET_MODE_NAME (mode));
1370 fprintf (stderr, HOST_PTR_PRINTF, (const PTR) type);
1371 fprintf (stderr, ", %d ) = ", named);
1375 cum->last_arg_fp = 0;
1379 regbase = GP_ARG_FIRST;
1383 cum->arg_words += cum->arg_words & 1;
1385 regbase = GP_ARG_FIRST;
1389 if (GET_MODE_CLASS (mode) != MODE_COMPLEX_INT
1390 && GET_MODE_CLASS (mode) != MODE_COMPLEX_FLOAT)
1393 /* Drops through. */
1395 if (type != NULL_TREE && TYPE_ALIGN (type) > (unsigned) BITS_PER_WORD)
1396 cum->arg_words += (cum->arg_words & 1);
1397 regbase = GP_ARG_FIRST;
1404 regbase = GP_ARG_FIRST;
1408 cum->arg_words += (cum->arg_words & 1);
1409 regbase = GP_ARG_FIRST;
1412 if (*arg_words >= (unsigned) MAX_ARGS_IN_REGISTERS)
1414 if (TARGET_DEBUG_D_MODE)
1415 fprintf (stderr, "<stack>%s\n", struct_p ? ", [struct]" : "");
1424 if (! type || TREE_CODE (type) != RECORD_TYPE
1425 || ! named || ! TYPE_SIZE_UNIT (type)
1426 || ! host_integerp (TYPE_SIZE_UNIT (type), 1))
1427 ret = gen_rtx_REG (mode, regbase + *arg_words + bias);
1432 for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field))
1433 if (TREE_CODE (field) == FIELD_DECL
1434 && TREE_CODE (TREE_TYPE (field)) == REAL_TYPE
1435 && TYPE_PRECISION (TREE_TYPE (field)) == BITS_PER_WORD
1436 && host_integerp (bit_position (field), 0)
1437 && int_bit_position (field) % BITS_PER_WORD == 0)
1440 /* If the whole struct fits a DFmode register,
1441 we don't need the PARALLEL. */
1442 if (! field || mode == DFmode)
1443 ret = gen_rtx_REG (mode, regbase + *arg_words + bias);
1446 unsigned int chunks;
1447 HOST_WIDE_INT bitpos;
1451 /* ??? If this is a packed structure, then the last hunk won't
1455 = tree_low_cst (TYPE_SIZE_UNIT (type), 1) / UNITS_PER_WORD;
1456 if (chunks + *arg_words + bias > (unsigned) MAX_ARGS_IN_REGISTERS)
1457 chunks = MAX_ARGS_IN_REGISTERS - *arg_words - bias;
1459 /* assign_parms checks the mode of ENTRY_PARM, so we must
1460 use the actual mode here. */
1461 ret = gen_rtx_PARALLEL (mode, rtvec_alloc (chunks));
1464 regno = regbase + *arg_words + bias;
1465 field = TYPE_FIELDS (type);
1466 for (i = 0; i < chunks; i++)
1470 for (; field; field = TREE_CHAIN (field))
1471 if (TREE_CODE (field) == FIELD_DECL
1472 && int_bit_position (field) >= bitpos)
1476 && int_bit_position (field) == bitpos
1477 && TREE_CODE (TREE_TYPE (field)) == REAL_TYPE
1478 && TYPE_PRECISION (TREE_TYPE (field)) == BITS_PER_WORD)
1479 reg = gen_rtx_REG (DFmode, regno++);
1481 reg = gen_rtx_REG (word_mode, regno);
1484 = gen_rtx_EXPR_LIST (VOIDmode, reg,
1485 GEN_INT (bitpos / BITS_PER_UNIT));
1493 if (TARGET_DEBUG_D_MODE)
1494 fprintf (stderr, "%s%s\n", reg_names[regbase + *arg_words + bias],
1495 struct_p ? ", [struct]" : "");
1498 /* We will be called with a mode of VOIDmode after the last argument
1499 has been seen. Whatever we return will be passed to the call
1500 insn. If we need any shifts for small structures, return them in
1502 if (mode == VOIDmode)
1504 if (cum->num_adjusts > 0)
1505 ret = gen_rtx (PARALLEL, (enum machine_mode) cum->fp_code,
1506 gen_rtvec_v (cum->num_adjusts, cum->adjust));
1513 function_arg_partial_nregs (CUMULATIVE_ARGS *cum, enum machine_mode mode,
1514 tree type ATTRIBUTE_UNUSED,
1515 int named ATTRIBUTE_UNUSED)
1518 && cum->arg_words == MAX_ARGS_IN_REGISTERS - (unsigned)1)
1520 if (TARGET_DEBUG_D_MODE)
1521 fprintf (stderr, "function_arg_partial_nregs = 1\n");
1529 /* Implement va_start. */
1532 iq2000_va_start (tree valist, rtx nextarg)
1536 /* Find out how many non-float named formals */
1537 int gpr_save_area_size;
1538 /* Note UNITS_PER_WORD is 4 bytes */
1539 int_arg_words = current_function_args_info.arg_words;
1540 if (int_arg_words < 8 )
1541 /* Adjust for the prologue's economy measure */
1542 gpr_save_area_size = (8 - int_arg_words) * UNITS_PER_WORD;
1544 gpr_save_area_size = 0;
1546 /* Everything is in the GPR save area, or in the overflow
1547 area which is contiguous with it. */
1549 nextarg = plus_constant (nextarg, -gpr_save_area_size);
1550 std_expand_builtin_va_start (valist, nextarg);
1553 /* Implement va_arg. */
1556 iq2000_va_arg (tree valist, tree type)
1558 HOST_WIDE_INT size, rsize;
1563 rtx r, lab_over = NULL_RTX, lab_false;
1564 tree f_ovfl, f_gtop, f_ftop, f_goff, f_foff;
1565 tree ovfl, gtop, ftop, goff, foff;
1567 size = int_size_in_bytes (type);
1568 rsize = (size + UNITS_PER_WORD - 1) & -UNITS_PER_WORD;
1570 = function_arg_pass_by_reference (NULL, TYPE_MODE (type), type, 0);
1573 size = POINTER_SIZE / BITS_PER_UNIT;
1574 rsize = UNITS_PER_WORD;
1577 addr_rtx = gen_reg_rtx (Pmode);
1580 /* Case of all args in a merged stack. No need to check bounds,
1581 just advance valist along the stack. */
1585 && TYPE_ALIGN (type) > (unsigned) BITS_PER_WORD)
1587 t = build (PLUS_EXPR, TREE_TYPE (gpr), gpr,
1588 build_int_2 (2*UNITS_PER_WORD - 1, 0));
1589 t = build (BIT_AND_EXPR, TREE_TYPE (t), t,
1590 build_int_2 (-2*UNITS_PER_WORD, -1));
1591 t = build (MODIFY_EXPR, TREE_TYPE (gpr), gpr, t);
1592 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
1595 t = build (POSTINCREMENT_EXPR, TREE_TYPE (gpr), gpr,
1597 r = expand_expr (t, addr_rtx, Pmode, EXPAND_NORMAL);
1599 emit_move_insn (addr_rtx, r);
1601 /* flush the POSTINCREMENT */
1606 r = gen_rtx_MEM (Pmode, addr_rtx);
1607 set_mem_alias_set (r, get_varargs_alias_set ());
1608 emit_move_insn (addr_rtx, r);
1612 if (BYTES_BIG_ENDIAN && rsize != size)
1613 addr_rtx = plus_constant (addr_rtx, rsize - size);
1618 /* Not a simple merged stack. Need ptrs and indexes left by va_start. */
1620 f_ovfl = TYPE_FIELDS (va_list_type_node);
1621 f_gtop = TREE_CHAIN (f_ovfl);
1622 f_ftop = TREE_CHAIN (f_gtop);
1623 f_goff = TREE_CHAIN (f_ftop);
1624 f_foff = TREE_CHAIN (f_goff);
1626 ovfl = build (COMPONENT_REF, TREE_TYPE (f_ovfl), valist, f_ovfl);
1627 gtop = build (COMPONENT_REF, TREE_TYPE (f_gtop), valist, f_gtop);
1628 ftop = build (COMPONENT_REF, TREE_TYPE (f_ftop), valist, f_ftop);
1629 goff = build (COMPONENT_REF, TREE_TYPE (f_goff), valist, f_goff);
1630 foff = build (COMPONENT_REF, TREE_TYPE (f_foff), valist, f_foff);
1632 lab_false = gen_label_rtx ();
1633 lab_over = gen_label_rtx ();
1635 if (TREE_CODE (type) == REAL_TYPE)
1638 /* Emit code to branch if foff == 0. */
1639 r = expand_expr (foff, NULL_RTX, TYPE_MODE (TREE_TYPE (foff)),
1641 emit_cmp_and_jump_insns (r, const0_rtx, EQ,
1642 const1_rtx, GET_MODE (r), 1, lab_false);
1644 /* Emit code for addr_rtx = ftop - foff */
1645 t = build (MINUS_EXPR, TREE_TYPE (ftop), ftop, foff );
1646 r = expand_expr (t, addr_rtx, Pmode, EXPAND_NORMAL);
1648 emit_move_insn (addr_rtx, r);
1650 /* Emit code for foff-=8.
1651 Advances the offset up FPR save area by one double */
1652 t = build (MINUS_EXPR, TREE_TYPE (foff), foff, build_int_2 (8, 0));
1653 t = build (MODIFY_EXPR, TREE_TYPE (foff), foff, t);
1654 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
1657 emit_jump (lab_over);
1659 emit_label (lab_false);
1661 /* If a 4-byte int is followed by an 8-byte float, then
1662 natural alignment causes a 4 byte gap.
1663 So, dynamically adjust ovfl up to a multiple of 8. */
1664 t = build (BIT_AND_EXPR, TREE_TYPE (ovfl), ovfl,
1665 build_int_2 (7, 0));
1666 t = build (PLUS_EXPR, TREE_TYPE (ovfl), ovfl, t);
1667 t = build (MODIFY_EXPR, TREE_TYPE (ovfl), ovfl, t);
1668 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
1670 /* Emit code for addr_rtx = the ovfl pointer into overflow area.
1671 Postincrement the ovfl pointer by 8. */
1672 t = build (POSTINCREMENT_EXPR, TREE_TYPE(ovfl), ovfl,
1674 r = expand_expr (t, addr_rtx, Pmode, EXPAND_NORMAL);
1676 emit_move_insn (addr_rtx, r);
1679 emit_label (lab_over);
1687 if (TREE_CODE (type) == INTEGER_TYPE
1688 && TYPE_PRECISION (type) == 64)
1690 /* int takes 32 bits of the GPR save area, but
1691 longlong takes an aligned 64 bits. So, emit code
1692 to zero the low order bits of goff, thus aligning
1693 the later calculation of (gtop-goff) upwards. */
1694 t = build (BIT_AND_EXPR, TREE_TYPE (goff), goff,
1695 build_int_2 (-8, -1));
1696 t = build (MODIFY_EXPR, TREE_TYPE (goff), goff, t);
1697 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
1700 /* Emit code to branch if goff == 0. */
1701 r = expand_expr (goff, NULL_RTX, TYPE_MODE (TREE_TYPE (goff)),
1703 emit_cmp_and_jump_insns (r, const0_rtx, EQ,
1704 const1_rtx, GET_MODE (r), 1, lab_false);
1706 /* Emit code for addr_rtx = gtop - goff. */
1707 t = build (MINUS_EXPR, TREE_TYPE (gtop), gtop, goff);
1708 r = expand_expr (t, addr_rtx, Pmode, EXPAND_NORMAL);
1710 emit_move_insn (addr_rtx, r);
1712 if (TYPE_PRECISION (type) == 64)
1715 step_size = UNITS_PER_WORD;
1717 /* Emit code for goff = goff - step_size.
1718 Advances the offset up GPR save area over the item. */
1719 t = build (MINUS_EXPR, TREE_TYPE (goff), goff,
1720 build_int_2 (step_size, 0));
1721 t = build (MODIFY_EXPR, TREE_TYPE (goff), goff, t);
1722 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
1725 emit_jump (lab_over);
1727 emit_label (lab_false);
1729 /* Emit code for addr_rtx -> overflow area, postinc by step_size */
1730 t = build (POSTINCREMENT_EXPR, TREE_TYPE(ovfl), ovfl,
1731 size_int (step_size));
1732 r = expand_expr (t, addr_rtx, Pmode, EXPAND_NORMAL);
1734 emit_move_insn (addr_rtx, r);
1737 emit_label (lab_over);
1741 r = gen_rtx_MEM (Pmode, addr_rtx);
1742 set_mem_alias_set (r, get_varargs_alias_set ());
1743 emit_move_insn (addr_rtx, r);
1747 if (BYTES_BIG_ENDIAN && rsize != size)
1748 addr_rtx = plus_constant (addr_rtx, rsize - size);
1754 /* Abort after printing out a specific insn. */
1757 abort_with_insn (rtx insn, const char *reason)
1764 /* Detect any conflicts in the switches. */
1767 override_options (void)
1769 register enum processor_type iq2000_cpu;
1771 target_flags &= ~MASK_GPOPT;
1773 iq2000_isa = IQ2000_ISA_DEFAULT;
1775 /* Identify the processor type. */
1777 if (iq2000_cpu_string != 0)
1779 iq2000_cpu = iq2000_parse_cpu (iq2000_cpu_string);
1780 if (iq2000_cpu == PROCESSOR_DEFAULT)
1782 error ("bad value (%s) for -mcpu= switch", iq2000_arch_string);
1783 iq2000_cpu_string = "default";
1785 iq2000_arch = iq2000_cpu;
1786 iq2000_tune = iq2000_cpu;
1789 if (iq2000_arch_string == 0
1790 || ! strcmp (iq2000_arch_string, "default")
1791 || ! strcmp (iq2000_arch_string, "DEFAULT"))
1796 iq2000_arch_string = "iq2000";
1797 iq2000_arch = PROCESSOR_IQ2000;
1803 iq2000_arch = iq2000_parse_cpu (iq2000_arch_string);
1804 if (iq2000_arch == PROCESSOR_DEFAULT)
1806 error ("bad value (%s) for -march= switch", iq2000_arch_string);
1807 iq2000_arch_string = "default";
1809 if (iq2000_arch == PROCESSOR_IQ10)
1811 error ("The compiler does not support -march=%s.", iq2000_arch_string);
1812 iq2000_arch_string = "default";
1816 iq2000_print_operand_punct['?'] = 1;
1817 iq2000_print_operand_punct['#'] = 1;
1818 iq2000_print_operand_punct['&'] = 1;
1819 iq2000_print_operand_punct['!'] = 1;
1820 iq2000_print_operand_punct['*'] = 1;
1821 iq2000_print_operand_punct['@'] = 1;
1822 iq2000_print_operand_punct['.'] = 1;
1823 iq2000_print_operand_punct['('] = 1;
1824 iq2000_print_operand_punct[')'] = 1;
1825 iq2000_print_operand_punct['['] = 1;
1826 iq2000_print_operand_punct[']'] = 1;
1827 iq2000_print_operand_punct['<'] = 1;
1828 iq2000_print_operand_punct['>'] = 1;
1829 iq2000_print_operand_punct['{'] = 1;
1830 iq2000_print_operand_punct['}'] = 1;
1831 iq2000_print_operand_punct['^'] = 1;
1832 iq2000_print_operand_punct['$'] = 1;
1833 iq2000_print_operand_punct['+'] = 1;
1834 iq2000_print_operand_punct['~'] = 1;
1836 /* Save GPR registers in word_mode sized hunks. word_mode hasn't been
1837 initialized yet, so we can't use that here. */
1840 /* Function to allocate machine-dependent function status. */
1841 init_machine_status = &iq2000_init_machine_status;
1844 /* Allocate a chunk of memory for per-function machine-dependent data. */
1846 static struct machine_function *
1847 iq2000_init_machine_status (void)
1849 return ((struct machine_function *)
1850 ggc_alloc_cleared (sizeof (struct machine_function)));
1853 /* The arg pointer (which is eliminated) points to the virtual frame pointer,
1854 while the frame pointer (which may be eliminated) points to the stack
1855 pointer after the initial adjustments. */
1858 iq2000_debugger_offset (rtx addr, HOST_WIDE_INT offset)
1860 rtx offset2 = const0_rtx;
1861 rtx reg = eliminate_constant_term (addr, &offset2);
1864 offset = INTVAL (offset2);
1866 if (reg == stack_pointer_rtx || reg == frame_pointer_rtx
1867 || reg == hard_frame_pointer_rtx)
1869 HOST_WIDE_INT frame_size = (!cfun->machine->frame.initialized)
1870 ? compute_frame_size (get_frame_size ())
1871 : cfun->machine->frame.total_size;
1873 offset = offset - frame_size;
1879 /* If defined, a C statement to be executed just prior to the output of
1880 assembler code for INSN, to modify the extracted operands so they will be
1883 Here the argument OPVEC is the vector containing the operands extracted
1884 from INSN, and NOPERANDS is the number of elements of the vector which
1885 contain meaningful data for this insn. The contents of this vector are
1886 what will be used to convert the insn template into assembler code, so you
1887 can change the assembler output by changing the contents of the vector.
1889 We use it to check if the current insn needs a nop in front of it because
1890 of load delays, and also to update the delay slot statistics. */
1893 final_prescan_insn (rtx insn, rtx opvec[] ATTRIBUTE_UNUSED,
1894 int noperands ATTRIBUTE_UNUSED)
1896 if (dslots_number_nops > 0)
1898 rtx pattern = PATTERN (insn);
1899 int length = get_attr_length (insn);
1901 /* Do we need to emit a NOP? */
1903 || (iq2000_load_reg != 0 && reg_mentioned_p (iq2000_load_reg, pattern))
1904 || (iq2000_load_reg2 != 0 && reg_mentioned_p (iq2000_load_reg2, pattern))
1905 || (iq2000_load_reg3 != 0 && reg_mentioned_p (iq2000_load_reg3, pattern))
1906 || (iq2000_load_reg4 != 0
1907 && reg_mentioned_p (iq2000_load_reg4, pattern)))
1908 fputs ("\tnop\n", asm_out_file);
1911 dslots_load_filled++;
1913 while (--dslots_number_nops > 0)
1914 fputs ("\tnop\n", asm_out_file);
1916 iq2000_load_reg = 0;
1917 iq2000_load_reg2 = 0;
1918 iq2000_load_reg3 = 0;
1919 iq2000_load_reg4 = 0;
1922 if ((GET_CODE (insn) == JUMP_INSN
1923 || GET_CODE (insn) == CALL_INSN
1924 || (GET_CODE (PATTERN (insn)) == RETURN))
1925 && NEXT_INSN (PREV_INSN (insn)) == insn)
1927 rtx nop_insn = emit_insn_after (gen_nop (), insn);
1928 INSN_ADDRESSES_NEW (nop_insn, -1);
1932 && (GET_CODE (insn) == JUMP_INSN || GET_CODE (insn) == CALL_INSN))
1933 dslots_jump_total++;
1936 /* Return the bytes needed to compute the frame pointer from the current
1939 IQ2000 stack frames look like:
1941 Before call After call
1942 +-----------------------+ +-----------------------+
1945 | caller's temps. | | caller's temps. |
1947 +-----------------------+ +-----------------------+
1949 | arguments on stack. | | arguments on stack. |
1951 +-----------------------+ +-----------------------+
1952 | 4 words to save | | 4 words to save |
1953 | arguments passed | | arguments passed |
1954 | in registers, even | | in registers, even |
1955 SP->| if not passed. | VFP->| if not passed. |
1956 +-----------------------+ +-----------------------+
1958 | fp register save |
1960 +-----------------------+
1962 | gp register save |
1964 +-----------------------+
1968 +-----------------------+
1970 | alloca allocations |
1972 +-----------------------+
1974 | GP save for V.4 abi |
1976 +-----------------------+
1978 | arguments on stack |
1980 +-----------------------+
1982 | arguments passed |
1983 | in registers, even |
1984 low SP->| if not passed. |
1985 memory +-----------------------+
1990 compute_frame_size (HOST_WIDE_INT size)
1993 HOST_WIDE_INT total_size; /* # bytes that the entire frame takes up */
1994 HOST_WIDE_INT var_size; /* # bytes that variables take up */
1995 HOST_WIDE_INT args_size; /* # bytes that outgoing arguments take up */
1996 HOST_WIDE_INT extra_size; /* # extra bytes */
1997 HOST_WIDE_INT gp_reg_rounded; /* # bytes needed to store gp after rounding */
1998 HOST_WIDE_INT gp_reg_size; /* # bytes needed to store gp regs */
1999 HOST_WIDE_INT fp_reg_size; /* # bytes needed to store fp regs */
2000 long mask; /* mask of saved gp registers */
2001 int fp_inc; /* 1 or 2 depending on the size of fp regs */
2002 long fp_bits; /* bitmask to use for each fp register */
2007 extra_size = IQ2000_STACK_ALIGN ((0));
2008 var_size = IQ2000_STACK_ALIGN (size);
2009 args_size = IQ2000_STACK_ALIGN (current_function_outgoing_args_size);
2011 /* If a function dynamically allocates the stack and
2012 has 0 for STACK_DYNAMIC_OFFSET then allocate some stack space */
2014 if (args_size == 0 && current_function_calls_alloca)
2015 args_size = 4 * UNITS_PER_WORD;
2017 total_size = var_size + args_size + extra_size;
2019 /* Calculate space needed for gp registers. */
2020 for (regno = GP_REG_FIRST; regno <= GP_REG_LAST; regno++)
2022 if (MUST_SAVE_REGISTER (regno))
2024 gp_reg_size += GET_MODE_SIZE (gpr_mode);
2025 mask |= 1L << (regno - GP_REG_FIRST);
2029 /* We need to restore these for the handler. */
2030 if (current_function_calls_eh_return)
2035 regno = EH_RETURN_DATA_REGNO (i);
2036 if (regno == (signed int) INVALID_REGNUM)
2038 gp_reg_size += GET_MODE_SIZE (gpr_mode);
2039 mask |= 1L << (regno - GP_REG_FIRST);
2045 gp_reg_rounded = IQ2000_STACK_ALIGN (gp_reg_size);
2046 total_size += gp_reg_rounded + IQ2000_STACK_ALIGN (fp_reg_size);
2048 /* The gp reg is caller saved, so there is no need for leaf routines
2049 (total_size == extra_size) to save the gp reg. */
2050 if (total_size == extra_size
2052 total_size = extra_size = 0;
2054 total_size += IQ2000_STACK_ALIGN (current_function_pretend_args_size);
2056 /* Save other computed information. */
2057 cfun->machine->frame.total_size = total_size;
2058 cfun->machine->frame.var_size = var_size;
2059 cfun->machine->frame.args_size = args_size;
2060 cfun->machine->frame.extra_size = extra_size;
2061 cfun->machine->frame.gp_reg_size = gp_reg_size;
2062 cfun->machine->frame.fp_reg_size = fp_reg_size;
2063 cfun->machine->frame.mask = mask;
2064 cfun->machine->frame.initialized = reload_completed;
2065 cfun->machine->frame.num_gp = gp_reg_size / UNITS_PER_WORD;
2069 unsigned long offset;
2071 offset = (args_size + extra_size + var_size
2072 + gp_reg_size - GET_MODE_SIZE (gpr_mode));
2074 cfun->machine->frame.gp_sp_offset = offset;
2075 cfun->machine->frame.gp_save_offset = offset - total_size;
2079 cfun->machine->frame.gp_sp_offset = 0;
2080 cfun->machine->frame.gp_save_offset = 0;
2083 cfun->machine->frame.fp_sp_offset = 0;
2084 cfun->machine->frame.fp_save_offset = 0;
2086 /* Ok, we're done. */
2090 /* Implement INITIAL_ELIMINATION_OFFSET. FROM is either the frame
2091 pointer, argument pointer, or return address pointer. TO is either
2092 the stack pointer or hard frame pointer. */
2095 iq2000_initial_elimination_offset (int from, int to ATTRIBUTE_UNUSED)
2099 compute_frame_size (get_frame_size ());
2100 if ((from) == FRAME_POINTER_REGNUM)
2102 else if ((from) == ARG_POINTER_REGNUM)
2103 (offset) = (cfun->machine->frame.total_size);
2104 else if ((from) == RETURN_ADDRESS_POINTER_REGNUM)
2106 if (leaf_function_p ())
2108 else (offset) = cfun->machine->frame.gp_sp_offset
2109 + ((UNITS_PER_WORD - (POINTER_SIZE / BITS_PER_UNIT))
2110 * (BYTES_BIG_ENDIAN != 0));
2116 /* Common code to emit the insns (or to write the instructions to a file)
2117 to save/restore registers.
2118 Other parts of the code assume that IQ2000_TEMP1_REGNUM (aka large_reg)
2119 is not modified within save_restore_insns. */
2121 #define BITSET_P(VALUE,BIT) (((VALUE) & (1L << (BIT))) != 0)
2123 /* Emit instructions to load the value (SP + OFFSET) into IQ2000_TEMP2_REGNUM
2124 and return an rtl expression for the register. Write the assembly
2125 instructions directly to FILE if it is not null, otherwise emit them as
2128 This function is a subroutine of save_restore_insns. It is used when
2129 OFFSET is too large to add in a single instruction. */
2132 iq2000_add_large_offset_to_sp (HOST_WIDE_INT offset)
2134 rtx reg = gen_rtx_REG (Pmode, IQ2000_TEMP2_REGNUM);
2135 rtx offset_rtx = GEN_INT (offset);
2137 emit_move_insn (reg, offset_rtx);
2138 emit_insn (gen_addsi3 (reg, reg, stack_pointer_rtx));
2142 /* Make INSN frame related and note that it performs the frame-related
2143 operation DWARF_PATTERN. */
2146 iq2000_annotate_frame_insn (rtx insn, rtx dwarf_pattern)
2148 RTX_FRAME_RELATED_P (insn) = 1;
2149 REG_NOTES (insn) = alloc_EXPR_LIST (REG_FRAME_RELATED_EXPR,
2154 /* Emit a move instruction that stores REG in MEM. Make the instruction
2155 frame related and note that it stores REG at (SP + OFFSET). */
2158 iq2000_emit_frame_related_store (rtx mem, rtx reg, HOST_WIDE_INT offset)
2160 rtx dwarf_address = plus_constant (stack_pointer_rtx, offset);
2161 rtx dwarf_mem = gen_rtx_MEM (GET_MODE (reg), dwarf_address);
2163 iq2000_annotate_frame_insn (emit_move_insn (mem, reg),
2164 gen_rtx_SET (GET_MODE (reg), dwarf_mem, reg));
2168 save_restore_insns (int store_p)
2170 long mask = cfun->machine->frame.mask;
2173 HOST_WIDE_INT base_offset;
2174 HOST_WIDE_INT gp_offset;
2175 HOST_WIDE_INT end_offset;
2177 if (frame_pointer_needed
2178 && ! BITSET_P (mask, HARD_FRAME_POINTER_REGNUM - GP_REG_FIRST))
2183 base_reg_rtx = 0, base_offset = 0;
2187 /* Save registers starting from high to low. The debuggers prefer at least
2188 the return register be stored at func+4, and also it allows us not to
2189 need a nop in the epilog if at least one register is reloaded in
2190 addition to return address. */
2192 /* Save GP registers if needed. */
2193 /* Pick which pointer to use as a base register. For small frames, just
2194 use the stack pointer. Otherwise, use a temporary register. Save 2
2195 cycles if the save area is near the end of a large frame, by reusing
2196 the constant created in the prologue/epilogue to adjust the stack
2199 gp_offset = cfun->machine->frame.gp_sp_offset;
2201 = gp_offset - (cfun->machine->frame.gp_reg_size
2202 - GET_MODE_SIZE (gpr_mode));
2204 if (gp_offset < 0 || end_offset < 0)
2206 ("gp_offset (%ld) or end_offset (%ld) is less than zero.",
2207 (long) gp_offset, (long) end_offset);
2209 else if (gp_offset < 32768)
2210 base_reg_rtx = stack_pointer_rtx, base_offset = 0;
2214 int reg_save_count = 0;
2215 for (regno = GP_REG_LAST; regno >= GP_REG_FIRST; regno--)
2216 if (BITSET_P (mask, regno - GP_REG_FIRST)) reg_save_count += 1;
2217 base_offset = gp_offset - ((reg_save_count - 1) * 4);
2218 base_reg_rtx = iq2000_add_large_offset_to_sp (base_offset);
2221 for (regno = GP_REG_LAST; regno >= GP_REG_FIRST; regno--)
2223 if (BITSET_P (mask, regno - GP_REG_FIRST))
2227 = gen_rtx (MEM, gpr_mode,
2228 gen_rtx (PLUS, Pmode, base_reg_rtx,
2229 GEN_INT (gp_offset - base_offset)));
2231 if (! current_function_calls_eh_return)
2232 RTX_UNCHANGING_P (mem_rtx) = 1;
2234 reg_rtx = gen_rtx (REG, gpr_mode, regno);
2237 iq2000_emit_frame_related_store (mem_rtx, reg_rtx, gp_offset);
2240 emit_move_insn (reg_rtx, mem_rtx);
2242 gp_offset -= GET_MODE_SIZE (gpr_mode);
2247 /* Expand the prologue into a bunch of separate insns. */
2250 iq2000_expand_prologue (void)
2253 HOST_WIDE_INT tsize;
2254 int last_arg_is_vararg_marker = 0;
2255 tree fndecl = current_function_decl;
2256 tree fntype = TREE_TYPE (fndecl);
2257 tree fnargs = DECL_ARGUMENTS (fndecl);
2262 CUMULATIVE_ARGS args_so_far;
2263 int store_args_on_stack = (iq2000_can_use_return_insn ());
2265 /* If struct value address is treated as the first argument. */
2266 if (aggregate_value_p (DECL_RESULT (fndecl))
2267 && ! current_function_returns_pcc_struct
2268 && struct_value_incoming_rtx == 0)
2270 tree type = build_pointer_type (fntype);
2271 tree function_result_decl = build_decl (PARM_DECL, NULL_TREE, type);
2273 DECL_ARG_TYPE (function_result_decl) = type;
2274 TREE_CHAIN (function_result_decl) = fnargs;
2275 fnargs = function_result_decl;
2278 /* For arguments passed in registers, find the register number
2279 of the first argument in the variable part of the argument list,
2280 otherwise GP_ARG_LAST+1. Note also if the last argument is
2281 the varargs special argument, and treat it as part of the
2284 This is only needed if store_args_on_stack is true. */
2286 INIT_CUMULATIVE_ARGS (args_so_far, fntype, NULL_RTX, 0);
2287 regno = GP_ARG_FIRST;
2289 for (cur_arg = fnargs; cur_arg != 0; cur_arg = next_arg)
2291 tree passed_type = DECL_ARG_TYPE (cur_arg);
2292 enum machine_mode passed_mode = TYPE_MODE (passed_type);
2295 if (TREE_ADDRESSABLE (passed_type))
2297 passed_type = build_pointer_type (passed_type);
2298 passed_mode = Pmode;
2301 entry_parm = FUNCTION_ARG (args_so_far, passed_mode, passed_type, 1);
2303 FUNCTION_ARG_ADVANCE (args_so_far, passed_mode, passed_type, 1);
2304 next_arg = TREE_CHAIN (cur_arg);
2306 if (entry_parm && store_args_on_stack)
2309 && DECL_NAME (cur_arg)
2310 && ((0 == strcmp (IDENTIFIER_POINTER (DECL_NAME (cur_arg)),
2311 "__builtin_va_alist"))
2312 || (0 == strcmp (IDENTIFIER_POINTER (DECL_NAME (cur_arg)),
2315 last_arg_is_vararg_marker = 1;
2322 if (GET_CODE (entry_parm) != REG)
2325 /* passed in a register, so will get homed automatically */
2326 if (GET_MODE (entry_parm) == BLKmode)
2327 words = (int_size_in_bytes (passed_type) + 3) / 4;
2329 words = (GET_MODE_SIZE (GET_MODE (entry_parm)) + 3) / 4;
2331 regno = REGNO (entry_parm) + words - 1;
2336 regno = GP_ARG_LAST+1;
2341 /* In order to pass small structures by value in registers we need to
2342 shift the value into the high part of the register.
2343 Function_arg has encoded a PARALLEL rtx, holding a vector of
2344 adjustments to be made as the next_arg_reg variable, so we split up the
2345 insns, and emit them separately. */
2347 next_arg_reg = FUNCTION_ARG (args_so_far, VOIDmode, void_type_node, 1);
2348 if (next_arg_reg != 0 && GET_CODE (next_arg_reg) == PARALLEL)
2350 rtvec adjust = XVEC (next_arg_reg, 0);
2351 int num = GET_NUM_ELEM (adjust);
2353 for (i = 0; i < num; i++)
2357 pattern = RTVEC_ELT (adjust, i);
2358 if (GET_CODE (pattern) != SET
2359 || GET_CODE (SET_SRC (pattern)) != ASHIFT)
2360 abort_with_insn (pattern, "Insn is not a shift");
2361 PUT_CODE (SET_SRC (pattern), ASHIFTRT);
2363 insn = emit_insn (pattern);
2365 /* Global life information isn't valid at this point, so we
2366 can't check whether these shifts are actually used. Mark
2367 them MAYBE_DEAD so that flow2 will remove them, and not
2368 complain about dead code in the prologue. */
2369 REG_NOTES(insn) = gen_rtx_EXPR_LIST (REG_MAYBE_DEAD, NULL_RTX,
2374 tsize = compute_frame_size (get_frame_size ());
2376 /* If this function is a varargs function, store any registers that
2377 would normally hold arguments ($4 - $7) on the stack. */
2378 if (store_args_on_stack
2379 && ((TYPE_ARG_TYPES (fntype) != 0
2380 && (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
2382 || last_arg_is_vararg_marker))
2384 int offset = (regno - GP_ARG_FIRST) * UNITS_PER_WORD;
2385 rtx ptr = stack_pointer_rtx;
2387 for (; regno <= GP_ARG_LAST; regno++)
2390 ptr = gen_rtx (PLUS, Pmode, stack_pointer_rtx, GEN_INT (offset));
2391 emit_move_insn (gen_rtx (MEM, gpr_mode, ptr),
2392 gen_rtx (REG, gpr_mode, regno));
2394 offset += GET_MODE_SIZE (gpr_mode);
2400 rtx tsize_rtx = GEN_INT (tsize);
2401 rtx adjustment_rtx, insn, dwarf_pattern;
2405 adjustment_rtx = gen_rtx (REG, Pmode, IQ2000_TEMP1_REGNUM);
2406 emit_move_insn (adjustment_rtx, tsize_rtx);
2409 adjustment_rtx = tsize_rtx;
2411 insn = emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
2414 dwarf_pattern = gen_rtx_SET (Pmode, stack_pointer_rtx,
2415 plus_constant (stack_pointer_rtx, -tsize));
2417 iq2000_annotate_frame_insn (insn, dwarf_pattern);
2419 save_restore_insns (1);
2421 if (frame_pointer_needed)
2425 insn = emit_insn (gen_movsi (hard_frame_pointer_rtx,
2426 stack_pointer_rtx));
2429 RTX_FRAME_RELATED_P (insn) = 1;
2433 emit_insn (gen_blockage ());
2436 /* Expand the epilogue into a bunch of separate insns. */
2439 iq2000_expand_epilogue (void)
2441 HOST_WIDE_INT tsize = cfun->machine->frame.total_size;
2442 rtx tsize_rtx = GEN_INT (tsize);
2443 rtx tmp_rtx = (rtx)0;
2445 if (iq2000_can_use_return_insn ())
2447 emit_insn (gen_return ());
2453 tmp_rtx = gen_rtx_REG (Pmode, IQ2000_TEMP1_REGNUM);
2454 emit_move_insn (tmp_rtx, tsize_rtx);
2455 tsize_rtx = tmp_rtx;
2460 if (frame_pointer_needed)
2462 emit_insn (gen_blockage ());
2464 emit_insn (gen_movsi (stack_pointer_rtx, hard_frame_pointer_rtx));
2467 save_restore_insns (0);
2469 if (current_function_calls_eh_return)
2471 rtx eh_ofs = EH_RETURN_STACKADJ_RTX;
2472 emit_insn (gen_addsi3 (eh_ofs, eh_ofs, tsize_rtx));
2476 emit_insn (gen_blockage ());
2478 if (tsize != 0 || current_function_calls_eh_return)
2480 emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx,
2485 if (current_function_calls_eh_return)
2487 /* Perform the additional bump for __throw. */
2488 emit_move_insn (gen_rtx (REG, Pmode, HARD_FRAME_POINTER_REGNUM),
2490 emit_insn (gen_rtx (USE, VOIDmode, gen_rtx (REG, Pmode,
2491 HARD_FRAME_POINTER_REGNUM)));
2492 emit_jump_insn (gen_eh_return_internal ());
2495 emit_jump_insn (gen_return_internal (gen_rtx (REG, Pmode,
2496 GP_REG_FIRST + 31)));
2500 iq2000_expand_eh_return (rtx address)
2502 HOST_WIDE_INT gp_offset = cfun->machine->frame.gp_sp_offset;
2505 scratch = plus_constant (stack_pointer_rtx, gp_offset);
2506 emit_move_insn (gen_rtx_MEM (GET_MODE (address), scratch), address);
2509 /* Return nonzero if this function is known to have a null epilogue.
2510 This allows the optimizer to omit jumps to jumps if no stack
2514 iq2000_can_use_return_insn (void)
2516 if (! reload_completed)
2519 if (regs_ever_live[31] || profile_flag)
2522 if (cfun->machine->frame.initialized)
2523 return cfun->machine->frame.total_size == 0;
2525 return compute_frame_size (get_frame_size ()) == 0;
2528 /* Returns nonzero if X contains a SYMBOL_REF. */
2531 symbolic_expression_p (rtx x)
2533 if (GET_CODE (x) == SYMBOL_REF)
2536 if (GET_CODE (x) == CONST)
2537 return symbolic_expression_p (XEXP (x, 0));
2539 if (GET_RTX_CLASS (GET_CODE (x)) == '1')
2540 return symbolic_expression_p (XEXP (x, 0));
2542 if (GET_RTX_CLASS (GET_CODE (x)) == 'c'
2543 || GET_RTX_CLASS (GET_CODE (x)) == '2')
2544 return (symbolic_expression_p (XEXP (x, 0))
2545 || symbolic_expression_p (XEXP (x, 1)));
2550 /* Choose the section to use for the constant rtx expression X that has
2554 iq2000_select_rtx_section (enum machine_mode mode, rtx x ATTRIBUTE_UNUSED,
2555 unsigned HOST_WIDE_INT align)
2557 /* For embedded applications, always put constants in read-only data,
2558 in order to reduce RAM usage. */
2559 /* For embedded applications, always put constants in read-only data,
2560 in order to reduce RAM usage. */
2561 mergeable_constant_section (mode, align, 0);
2564 /* Choose the section to use for DECL. RELOC is true if its value contains
2565 any relocatable expression.
2567 Some of the logic used here needs to be replicated in
2568 ENCODE_SECTION_INFO in iq2000.h so that references to these symbols
2569 are done correctly. */
2572 iq2000_select_section (tree decl, int reloc ATTRIBUTE_UNUSED,
2573 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED)
2575 if (TARGET_EMBEDDED_DATA)
2577 /* For embedded applications, always put an object in read-only data
2578 if possible, in order to reduce RAM usage. */
2580 if (((TREE_CODE (decl) == VAR_DECL
2581 && TREE_READONLY (decl) && !TREE_SIDE_EFFECTS (decl)
2582 && DECL_INITIAL (decl)
2583 && (DECL_INITIAL (decl) == error_mark_node
2584 || TREE_CONSTANT (DECL_INITIAL (decl))))
2585 /* Deal with calls from output_constant_def_contents. */
2586 || (TREE_CODE (decl) != VAR_DECL
2587 && (TREE_CODE (decl) != STRING_CST
2588 || !flag_writable_strings))))
2589 readonly_data_section ();
2595 /* For hosted applications, always put an object in small data if
2596 possible, as this gives the best performance. */
2598 if (((TREE_CODE (decl) == VAR_DECL
2599 && TREE_READONLY (decl) && !TREE_SIDE_EFFECTS (decl)
2600 && DECL_INITIAL (decl)
2601 && (DECL_INITIAL (decl) == error_mark_node
2602 || TREE_CONSTANT (DECL_INITIAL (decl))))
2603 /* Deal with calls from output_constant_def_contents. */
2604 || (TREE_CODE (decl) != VAR_DECL
2605 && (TREE_CODE (decl) != STRING_CST
2606 || !flag_writable_strings))))
2607 readonly_data_section ();
2612 /* Return register to use for a function return value with VALTYPE for function
2616 iq2000_function_value (tree valtype, tree func ATTRIBUTE_UNUSED)
2618 int reg = GP_RETURN;
2619 enum machine_mode mode = TYPE_MODE (valtype);
2620 int unsignedp = TREE_UNSIGNED (valtype);
2622 /* Since we define PROMOTE_FUNCTION_RETURN, we must promote the mode
2623 just as PROMOTE_MODE does. */
2624 mode = promote_mode (valtype, mode, &unsignedp, 1);
2626 return gen_rtx_REG (mode, reg);
2629 /* The implementation of FUNCTION_ARG_PASS_BY_REFERENCE. Return
2630 nonzero when an argument must be passed by reference. */
2633 function_arg_pass_by_reference (CUMULATIVE_ARGS *cum ATTRIBUTE_UNUSED,
2634 enum machine_mode mode, tree type,
2635 int named ATTRIBUTE_UNUSED)
2639 /* We must pass by reference if we would be both passing in registers
2640 and the stack. This is because any subsequent partial arg would be
2641 handled incorrectly in this case. */
2643 if (cum && MUST_PASS_IN_STACK (mode, type))
2645 /* Don't pass the actual CUM to FUNCTION_ARG, because we would
2646 get double copies of any offsets generated for small structs
2647 passed in registers. */
2648 CUMULATIVE_ARGS temp;
2650 if (FUNCTION_ARG (temp, mode, type, named) != 0)
2654 if (type == NULL_TREE || mode == DImode || mode == DFmode)
2657 size = int_size_in_bytes (type);
2658 return size == -1 || size > UNITS_PER_WORD;
2661 /* Return the length of INSN. LENGTH is the initial length computed by
2662 attributes in the machine-description file. */
2665 iq2000_adjust_insn_length (rtx insn, int length)
2667 /* A unconditional jump has an unfilled delay slot if it is not part
2668 of a sequence. A conditional jump normally has a delay slot */
2669 if (simplejump_p (insn)
2670 || ((GET_CODE (insn) == JUMP_INSN
2671 || GET_CODE (insn) == CALL_INSN)))
2677 /* Output assembly instructions to perform a conditional branch.
2679 INSN is the branch instruction. OPERANDS[0] is the condition.
2680 OPERANDS[1] is the target of the branch. OPERANDS[2] is the target
2681 of the first operand to the condition. If TWO_OPERANDS_P is
2682 nonzero the comparison takes two operands; OPERANDS[3] will be the
2685 If INVERTED_P is nonzero we are to branch if the condition does
2686 not hold. If FLOAT_P is nonzero this is a floating-point comparison.
2688 LENGTH is the length (in bytes) of the sequence we are to generate.
2689 That tells us whether to generate a simple conditional branch, or a
2690 reversed conditional branch around a `jr' instruction. */
2693 iq2000_output_conditional_branch (rtx insn, rtx *operands, int two_operands_p,
2694 int float_p, int inverted_p, int length)
2696 static char buffer[200];
2697 /* The kind of comparison we are doing. */
2698 enum rtx_code code = GET_CODE (operands[0]);
2699 /* Nonzero if the opcode for the comparison needs a `z' indicating
2700 that it is a comparision against zero. */
2702 /* A string to use in the assembly output to represent the first
2704 const char *op1 = "%z2";
2705 /* A string to use in the assembly output to represent the second
2706 operand. Use the hard-wired zero register if there's no second
2708 const char *op2 = (two_operands_p ? ",%z3" : ",%.");
2709 /* The operand-printing string for the comparison. */
2710 const char *comp = (float_p ? "%F0" : "%C0");
2711 /* The operand-printing string for the inverted comparison. */
2712 const char *inverted_comp = (float_p ? "%W0" : "%N0");
2714 /* likely variants of each branch instruction annul the instruction
2715 in the delay slot if the branch is not taken. */
2716 iq2000_branch_likely = (final_sequence && INSN_ANNULLED_BRANCH_P (insn));
2718 if (!two_operands_p)
2720 /* To compute whether than A > B, for example, we normally
2721 subtract B from A and then look at the sign bit. But, if we
2722 are doing an unsigned comparison, and B is zero, we don't
2723 have to do the subtraction. Instead, we can just check to
2724 see if A is nonzero. Thus, we change the CODE here to
2725 reflect the simpler comparison operation. */
2737 /* A condition which will always be true. */
2743 /* A condition which will always be false. */
2749 /* Not a special case. */
2754 /* Relative comparisons are always done against zero. But
2755 equality comparisons are done between two operands, and therefore
2756 do not require a `z' in the assembly language output. */
2757 need_z_p = (!float_p && code != EQ && code != NE);
2758 /* For comparisons against zero, the zero is not provided
2763 /* Begin by terminating the buffer. That way we can always use
2764 strcat to add to it. */
2771 /* Just a simple conditional branch. */
2773 sprintf (buffer, "b%s%%?\t%%Z2%%1",
2774 inverted_p ? inverted_comp : comp);
2776 sprintf (buffer, "b%s%s%%?\t%s%s,%%1",
2777 inverted_p ? inverted_comp : comp,
2778 need_z_p ? "z" : "",
2786 /* Generate a reversed conditional branch around ` j'
2798 Because we have to jump four bytes *past* the following
2799 instruction if this branch was annulled, we can't just use
2800 a label, as in the picture above; there's no way to put the
2801 label after the next instruction, as the assembler does not
2802 accept `.L+4' as the target of a branch. (We can't just
2803 wait until the next instruction is output; it might be a
2804 macro and take up more than four bytes. Once again, we see
2805 why we want to eliminate macros.)
2807 If the branch is annulled, we jump four more bytes that we
2808 would otherwise; that way we skip the annulled instruction
2809 in the delay slot. */
2812 = ((iq2000_branch_likely || length == 16) ? ".+16" : ".+12");
2815 c = strchr (buffer, '\0');
2816 /* Generate the reversed comparision. This takes four
2819 sprintf (c, "b%s\t%%Z2%s",
2820 inverted_p ? comp : inverted_comp,
2823 sprintf (c, "b%s%s\t%s%s,%s",
2824 inverted_p ? comp : inverted_comp,
2825 need_z_p ? "z" : "",
2829 strcat (c, "\n\tnop\n\tj\t%1");
2831 /* The delay slot was unfilled. Since we're inside
2832 .noreorder, the assembler will not fill in the NOP for
2833 us, so we must do it ourselves. */
2834 strcat (buffer, "\n\tnop");
2846 static enum processor_type
2847 iq2000_parse_cpu (const char *cpu_string)
2849 const char *p = cpu_string;
2850 enum processor_type cpu;
2852 cpu = PROCESSOR_DEFAULT;
2856 if (!strcmp (p, "iq10"))
2857 cpu = PROCESSOR_IQ10;
2860 if (!strcmp (p, "iq2000"))
2861 cpu = PROCESSOR_IQ2000;
2868 #define def_builtin(NAME, TYPE, CODE) \
2869 builtin_function ((NAME), (TYPE), (CODE), BUILT_IN_MD, NULL, NULL_TREE)
2872 iq2000_init_builtins (void)
2874 tree endlink = void_list_node;
2875 tree void_ftype, void_ftype_int, void_ftype_int_int;
2876 tree void_ftype_int_int_int;
2877 tree int_ftype_int, int_ftype_int_int, int_ftype_int_int_int;
2878 tree int_ftype_int_int_int_int;
2882 = build_function_type (void_type_node,
2883 tree_cons (NULL_TREE, void_type_node, endlink));
2887 = build_function_type (void_type_node,
2888 tree_cons (NULL_TREE, integer_type_node, endlink));
2890 /* void func (int, int) */
2892 = build_function_type (void_type_node,
2893 tree_cons (NULL_TREE, integer_type_node,
2894 tree_cons (NULL_TREE, integer_type_node,
2897 /* int func (int) */
2899 = build_function_type (integer_type_node,
2900 tree_cons (NULL_TREE, integer_type_node, endlink));
2902 /* int func (int, int) */
2904 = build_function_type (integer_type_node,
2905 tree_cons (NULL_TREE, integer_type_node,
2906 tree_cons (NULL_TREE, integer_type_node,
2909 /* void func (int, int, int) */
2910 void_ftype_int_int_int
2911 = build_function_type
2913 tree_cons (NULL_TREE, integer_type_node,
2914 tree_cons (NULL_TREE, integer_type_node,
2915 tree_cons (NULL_TREE,
2919 /* int func (int, int, int, int) */
2920 int_ftype_int_int_int_int
2921 = build_function_type
2923 tree_cons (NULL_TREE, integer_type_node,
2924 tree_cons (NULL_TREE, integer_type_node,
2925 tree_cons (NULL_TREE,
2927 tree_cons (NULL_TREE,
2931 /* int func (int, int, int) */
2932 int_ftype_int_int_int
2933 = build_function_type
2935 tree_cons (NULL_TREE, integer_type_node,
2936 tree_cons (NULL_TREE, integer_type_node,
2937 tree_cons (NULL_TREE,
2941 /* int func (int, int, int, int) */
2942 int_ftype_int_int_int_int
2943 = build_function_type
2945 tree_cons (NULL_TREE, integer_type_node,
2946 tree_cons (NULL_TREE, integer_type_node,
2947 tree_cons (NULL_TREE,
2949 tree_cons (NULL_TREE,
2953 def_builtin ("__builtin_ado16", int_ftype_int_int, IQ2000_BUILTIN_ADO16);
2954 def_builtin ("__builtin_ram", int_ftype_int_int_int_int, IQ2000_BUILTIN_RAM);
2955 def_builtin ("__builtin_chkhdr", void_ftype_int_int, IQ2000_BUILTIN_CHKHDR);
2956 def_builtin ("__builtin_pkrl", void_ftype_int_int, IQ2000_BUILTIN_PKRL);
2957 def_builtin ("__builtin_cfc0", int_ftype_int, IQ2000_BUILTIN_CFC0);
2958 def_builtin ("__builtin_cfc1", int_ftype_int, IQ2000_BUILTIN_CFC1);
2959 def_builtin ("__builtin_cfc2", int_ftype_int, IQ2000_BUILTIN_CFC2);
2960 def_builtin ("__builtin_cfc3", int_ftype_int, IQ2000_BUILTIN_CFC3);
2961 def_builtin ("__builtin_ctc0", void_ftype_int_int, IQ2000_BUILTIN_CTC0);
2962 def_builtin ("__builtin_ctc1", void_ftype_int_int, IQ2000_BUILTIN_CTC1);
2963 def_builtin ("__builtin_ctc2", void_ftype_int_int, IQ2000_BUILTIN_CTC2);
2964 def_builtin ("__builtin_ctc3", void_ftype_int_int, IQ2000_BUILTIN_CTC3);
2965 def_builtin ("__builtin_mfc0", int_ftype_int, IQ2000_BUILTIN_MFC0);
2966 def_builtin ("__builtin_mfc1", int_ftype_int, IQ2000_BUILTIN_MFC1);
2967 def_builtin ("__builtin_mfc2", int_ftype_int, IQ2000_BUILTIN_MFC2);
2968 def_builtin ("__builtin_mfc3", int_ftype_int, IQ2000_BUILTIN_MFC3);
2969 def_builtin ("__builtin_mtc0", void_ftype_int_int, IQ2000_BUILTIN_MTC0);
2970 def_builtin ("__builtin_mtc1", void_ftype_int_int, IQ2000_BUILTIN_MTC1);
2971 def_builtin ("__builtin_mtc2", void_ftype_int_int, IQ2000_BUILTIN_MTC2);
2972 def_builtin ("__builtin_mtc3", void_ftype_int_int, IQ2000_BUILTIN_MTC3);
2973 def_builtin ("__builtin_lur", void_ftype_int_int, IQ2000_BUILTIN_LUR);
2974 def_builtin ("__builtin_rb", void_ftype_int_int, IQ2000_BUILTIN_RB);
2975 def_builtin ("__builtin_rx", void_ftype_int_int, IQ2000_BUILTIN_RX);
2976 def_builtin ("__builtin_srrd", void_ftype_int, IQ2000_BUILTIN_SRRD);
2977 def_builtin ("__builtin_srwr", void_ftype_int_int, IQ2000_BUILTIN_SRWR);
2978 def_builtin ("__builtin_wb", void_ftype_int_int, IQ2000_BUILTIN_WB);
2979 def_builtin ("__builtin_wx", void_ftype_int_int, IQ2000_BUILTIN_WX);
2980 def_builtin ("__builtin_luc32l", void_ftype_int_int, IQ2000_BUILTIN_LUC32L);
2981 def_builtin ("__builtin_luc64", void_ftype_int_int, IQ2000_BUILTIN_LUC64);
2982 def_builtin ("__builtin_luc64l", void_ftype_int_int, IQ2000_BUILTIN_LUC64L);
2983 def_builtin ("__builtin_luk", void_ftype_int_int, IQ2000_BUILTIN_LUK);
2984 def_builtin ("__builtin_lulck", void_ftype_int, IQ2000_BUILTIN_LULCK);
2985 def_builtin ("__builtin_lum32", void_ftype_int_int, IQ2000_BUILTIN_LUM32);
2986 def_builtin ("__builtin_lum32l", void_ftype_int_int, IQ2000_BUILTIN_LUM32L);
2987 def_builtin ("__builtin_lum64", void_ftype_int_int, IQ2000_BUILTIN_LUM64);
2988 def_builtin ("__builtin_lum64l", void_ftype_int_int, IQ2000_BUILTIN_LUM64L);
2989 def_builtin ("__builtin_lurl", void_ftype_int_int, IQ2000_BUILTIN_LURL);
2990 def_builtin ("__builtin_mrgb", int_ftype_int_int_int, IQ2000_BUILTIN_MRGB);
2991 def_builtin ("__builtin_srrdl", void_ftype_int, IQ2000_BUILTIN_SRRDL);
2992 def_builtin ("__builtin_srulck", void_ftype_int, IQ2000_BUILTIN_SRULCK);
2993 def_builtin ("__builtin_srwru", void_ftype_int_int, IQ2000_BUILTIN_SRWRU);
2994 def_builtin ("__builtin_trapqfl", void_ftype, IQ2000_BUILTIN_TRAPQFL);
2995 def_builtin ("__builtin_trapqne", void_ftype, IQ2000_BUILTIN_TRAPQNE);
2996 def_builtin ("__builtin_traprel", void_ftype_int, IQ2000_BUILTIN_TRAPREL);
2997 def_builtin ("__builtin_wbu", void_ftype_int_int_int, IQ2000_BUILTIN_WBU);
2998 def_builtin ("__builtin_syscall", void_ftype, IQ2000_BUILTIN_SYSCALL);
3001 /* Builtin for ICODE having ARGCOUNT args in ARGLIST where each arg
3005 expand_one_builtin (enum insn_code icode, rtx target, tree arglist,
3006 enum rtx_code *code, int argcount)
3011 enum machine_mode mode [5];
3014 mode[0] = insn_data[icode].operand[0].mode;
3015 for (i = 0; i < argcount; i++)
3017 arg[i] = TREE_VALUE (arglist);
3018 arglist = TREE_CHAIN (arglist);
3019 op[i] = expand_expr (arg[i], NULL_RTX, VOIDmode, 0);
3020 mode[i] = insn_data[icode].operand[i].mode;
3021 if (code[i] == CONST_INT && GET_CODE (op[i]) != CONST_INT)
3022 error ("argument `%d' is not a constant", i + 1);
3024 && ! (*insn_data[icode].operand[i].predicate) (op[i], mode[i]))
3025 op[i] = copy_to_mode_reg (mode[i], op[i]);
3028 if (insn_data[icode].operand[0].constraint[0] == '=')
3031 || GET_MODE (target) != mode[0]
3032 || ! (*insn_data[icode].operand[0].predicate) (target, mode[0]))
3033 target = gen_reg_rtx (mode[0]);
3041 pat = GEN_FCN (icode) (target);
3044 pat = GEN_FCN (icode) (target, op[0]);
3046 pat = GEN_FCN (icode) (op[0]);
3050 pat = GEN_FCN (icode) (target, op[0], op[1]);
3052 pat = GEN_FCN (icode) (op[0], op[1]);
3056 pat = GEN_FCN (icode) (target, op[0], op[1], op[2]);
3058 pat = GEN_FCN (icode) (op[0], op[1], op[2]);
3062 pat = GEN_FCN (icode) (target, op[0], op[1], op[2], op[3]);
3064 pat = GEN_FCN (icode) (op[0], op[1], op[2], op[3]);
3076 /* Expand an expression EXP that calls a built-in function,
3077 with result going to TARGET if that's convenient
3078 (and in mode MODE if that's convenient).
3079 SUBTARGET may be used as the target for computing one of EXP's operands.
3080 IGNORE is nonzero if the value is to be ignored. */
3083 iq2000_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED,
3084 enum machine_mode mode ATTRIBUTE_UNUSED,
3085 int ignore ATTRIBUTE_UNUSED)
3087 tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
3088 tree arglist = TREE_OPERAND (exp, 1);
3089 int fcode = DECL_FUNCTION_CODE (fndecl);
3090 enum rtx_code code [5];
3102 case IQ2000_BUILTIN_ADO16:
3103 return expand_one_builtin (CODE_FOR_ado16, target, arglist, code, 2);
3105 case IQ2000_BUILTIN_RAM:
3106 code[1] = CONST_INT;
3107 code[2] = CONST_INT;
3108 code[3] = CONST_INT;
3109 return expand_one_builtin (CODE_FOR_ram, target, arglist, code, 4);
3111 case IQ2000_BUILTIN_CHKHDR:
3112 return expand_one_builtin (CODE_FOR_chkhdr, target, arglist, code, 2);
3114 case IQ2000_BUILTIN_PKRL:
3115 return expand_one_builtin (CODE_FOR_pkrl, target, arglist, code, 2);
3117 case IQ2000_BUILTIN_CFC0:
3118 code[0] = CONST_INT;
3119 return expand_one_builtin (CODE_FOR_cfc0, target, arglist, code, 1);
3121 case IQ2000_BUILTIN_CFC1:
3122 code[0] = CONST_INT;
3123 return expand_one_builtin (CODE_FOR_cfc1, target, arglist, code, 1);
3125 case IQ2000_BUILTIN_CFC2:
3126 code[0] = CONST_INT;
3127 return expand_one_builtin (CODE_FOR_cfc2, target, arglist, code, 1);
3129 case IQ2000_BUILTIN_CFC3:
3130 code[0] = CONST_INT;
3131 return expand_one_builtin (CODE_FOR_cfc3, target, arglist, code, 1);
3133 case IQ2000_BUILTIN_CTC0:
3134 code[1] = CONST_INT;
3135 return expand_one_builtin (CODE_FOR_ctc0, target, arglist, code, 2);
3137 case IQ2000_BUILTIN_CTC1:
3138 code[1] = CONST_INT;
3139 return expand_one_builtin (CODE_FOR_ctc1, target, arglist, code, 2);
3141 case IQ2000_BUILTIN_CTC2:
3142 code[1] = CONST_INT;
3143 return expand_one_builtin (CODE_FOR_ctc2, target, arglist, code, 2);
3145 case IQ2000_BUILTIN_CTC3:
3146 code[1] = CONST_INT;
3147 return expand_one_builtin (CODE_FOR_ctc3, target, arglist, code, 2);
3149 case IQ2000_BUILTIN_MFC0:
3150 code[0] = CONST_INT;
3151 return expand_one_builtin (CODE_FOR_mfc0, target, arglist, code, 1);
3153 case IQ2000_BUILTIN_MFC1:
3154 code[0] = CONST_INT;
3155 return expand_one_builtin (CODE_FOR_mfc1, target, arglist, code, 1);
3157 case IQ2000_BUILTIN_MFC2:
3158 code[0] = CONST_INT;
3159 return expand_one_builtin (CODE_FOR_mfc2, target, arglist, code, 1);
3161 case IQ2000_BUILTIN_MFC3:
3162 code[0] = CONST_INT;
3163 return expand_one_builtin (CODE_FOR_mfc3, target, arglist, code, 1);
3165 case IQ2000_BUILTIN_MTC0:
3166 code[1] = CONST_INT;
3167 return expand_one_builtin (CODE_FOR_mtc0, target, arglist, code, 2);
3169 case IQ2000_BUILTIN_MTC1:
3170 code[1] = CONST_INT;
3171 return expand_one_builtin (CODE_FOR_mtc1, target, arglist, code, 2);
3173 case IQ2000_BUILTIN_MTC2:
3174 code[1] = CONST_INT;
3175 return expand_one_builtin (CODE_FOR_mtc2, target, arglist, code, 2);
3177 case IQ2000_BUILTIN_MTC3:
3178 code[1] = CONST_INT;
3179 return expand_one_builtin (CODE_FOR_mtc3, target, arglist, code, 2);
3181 case IQ2000_BUILTIN_LUR:
3182 return expand_one_builtin (CODE_FOR_lur, target, arglist, code, 2);
3184 case IQ2000_BUILTIN_RB:
3185 return expand_one_builtin (CODE_FOR_rb, target, arglist, code, 2);
3187 case IQ2000_BUILTIN_RX:
3188 return expand_one_builtin (CODE_FOR_rx, target, arglist, code, 2);
3190 case IQ2000_BUILTIN_SRRD:
3191 return expand_one_builtin (CODE_FOR_srrd, target, arglist, code, 1);
3193 case IQ2000_BUILTIN_SRWR:
3194 return expand_one_builtin (CODE_FOR_srwr, target, arglist, code, 2);
3196 case IQ2000_BUILTIN_WB:
3197 return expand_one_builtin (CODE_FOR_wb, target, arglist, code, 2);
3199 case IQ2000_BUILTIN_WX:
3200 return expand_one_builtin (CODE_FOR_wx, target, arglist, code, 2);
3202 case IQ2000_BUILTIN_LUC32L:
3203 return expand_one_builtin (CODE_FOR_luc32l, target, arglist, code, 2);
3205 case IQ2000_BUILTIN_LUC64:
3206 return expand_one_builtin (CODE_FOR_luc64, target, arglist, code, 2);
3208 case IQ2000_BUILTIN_LUC64L:
3209 return expand_one_builtin (CODE_FOR_luc64l, target, arglist, code, 2);
3211 case IQ2000_BUILTIN_LUK:
3212 return expand_one_builtin (CODE_FOR_luk, target, arglist, code, 2);
3214 case IQ2000_BUILTIN_LULCK:
3215 return expand_one_builtin (CODE_FOR_lulck, target, arglist, code, 1);
3217 case IQ2000_BUILTIN_LUM32:
3218 return expand_one_builtin (CODE_FOR_lum32, target, arglist, code, 2);
3220 case IQ2000_BUILTIN_LUM32L:
3221 return expand_one_builtin (CODE_FOR_lum32l, target, arglist, code, 2);
3223 case IQ2000_BUILTIN_LUM64:
3224 return expand_one_builtin (CODE_FOR_lum64, target, arglist, code, 2);
3226 case IQ2000_BUILTIN_LUM64L:
3227 return expand_one_builtin (CODE_FOR_lum64l, target, arglist, code, 2);
3229 case IQ2000_BUILTIN_LURL:
3230 return expand_one_builtin (CODE_FOR_lurl, target, arglist, code, 2);
3232 case IQ2000_BUILTIN_MRGB:
3233 code[2] = CONST_INT;
3234 return expand_one_builtin (CODE_FOR_mrgb, target, arglist, code, 3);
3236 case IQ2000_BUILTIN_SRRDL:
3237 return expand_one_builtin (CODE_FOR_srrdl, target, arglist, code, 1);
3239 case IQ2000_BUILTIN_SRULCK:
3240 return expand_one_builtin (CODE_FOR_srulck, target, arglist, code, 1);
3242 case IQ2000_BUILTIN_SRWRU:
3243 return expand_one_builtin (CODE_FOR_srwru, target, arglist, code, 2);
3245 case IQ2000_BUILTIN_TRAPQFL:
3246 return expand_one_builtin (CODE_FOR_trapqfl, target, arglist, code, 0);
3248 case IQ2000_BUILTIN_TRAPQNE:
3249 return expand_one_builtin (CODE_FOR_trapqne, target, arglist, code, 0);
3251 case IQ2000_BUILTIN_TRAPREL:
3252 return expand_one_builtin (CODE_FOR_traprel, target, arglist, code, 1);
3254 case IQ2000_BUILTIN_WBU:
3255 return expand_one_builtin (CODE_FOR_wbu, target, arglist, code, 3);
3257 case IQ2000_BUILTIN_SYSCALL:
3258 return expand_one_builtin (CODE_FOR_syscall, target, arglist, code, 0);
3265 iq2000_setup_incoming_varargs (CUMULATIVE_ARGS cum, int mode ATTRIBUTE_UNUSED,
3266 tree type ATTRIBUTE_UNUSED, int *pretend_size,
3269 unsigned int iq2000_off = (! (cum).last_arg_fp);
3270 unsigned int iq2000_fp_off = ((cum).last_arg_fp);
3271 if (((cum).arg_words < MAX_ARGS_IN_REGISTERS - iq2000_off))
3273 int iq2000_save_gp_regs
3274 = MAX_ARGS_IN_REGISTERS - (cum).arg_words - iq2000_off;
3275 int iq2000_save_fp_regs
3276 = (MAX_ARGS_IN_REGISTERS - (cum).fp_arg_words - iq2000_fp_off);
3278 if (iq2000_save_gp_regs < 0)
3279 iq2000_save_gp_regs = 0;
3280 if (iq2000_save_fp_regs < 0)
3281 iq2000_save_fp_regs = 0;
3283 *pretend_size = ((iq2000_save_gp_regs * UNITS_PER_WORD)
3284 + (iq2000_save_fp_regs * UNITS_PER_FPREG));
3288 if ((cum).arg_words < MAX_ARGS_IN_REGISTERS - iq2000_off)
3291 ptr = plus_constant (virtual_incoming_args_rtx,
3292 - (iq2000_save_gp_regs
3294 mem = gen_rtx_MEM (BLKmode, ptr);
3296 ((cum).arg_words + GP_ARG_FIRST + iq2000_off,
3298 iq2000_save_gp_regs);
3304 /* A C compound statement to output to stdio stream STREAM the
3305 assembler syntax for an instruction operand that is a memory
3306 reference whose address is ADDR. ADDR is an RTL expression.
3310 print_operand_address (FILE *file, rtx addr)
3313 error ("PRINT_OPERAND_ADDRESS, null pointer");
3316 switch (GET_CODE (addr))
3319 if (REGNO (addr) == ARG_POINTER_REGNUM)
3320 abort_with_insn (addr, "Arg pointer not eliminated.");
3322 fprintf (file, "0(%s)", reg_names [REGNO (addr)]);
3327 register rtx arg0 = XEXP (addr, 0);
3328 register rtx arg1 = XEXP (addr, 1);
3330 if (GET_CODE (arg0) != REG)
3331 abort_with_insn (addr,
3332 "PRINT_OPERAND_ADDRESS, LO_SUM with #1 not REG.");
3334 fprintf (file, "%%lo(");
3335 print_operand_address (file, arg1);
3336 fprintf (file, ")(%s)", reg_names [REGNO (arg0)]);
3342 register rtx reg = 0;
3343 register rtx offset = 0;
3344 register rtx arg0 = XEXP (addr, 0);
3345 register rtx arg1 = XEXP (addr, 1);
3347 if (GET_CODE (arg0) == REG)
3351 if (GET_CODE (offset) == REG)
3352 abort_with_insn (addr, "PRINT_OPERAND_ADDRESS, 2 regs");
3355 else if (GET_CODE (arg1) == REG)
3356 reg = arg1, offset = arg0;
3357 else if (CONSTANT_P (arg0) && CONSTANT_P (arg1))
3359 output_addr_const (file, addr);
3363 abort_with_insn (addr, "PRINT_OPERAND_ADDRESS, no regs");
3365 if (! CONSTANT_P (offset))
3366 abort_with_insn (addr, "PRINT_OPERAND_ADDRESS, invalid insn #2");
3368 if (REGNO (reg) == ARG_POINTER_REGNUM)
3369 abort_with_insn (addr, "Arg pointer not eliminated.");
3371 output_addr_const (file, offset);
3372 fprintf (file, "(%s)", reg_names [REGNO (reg)]);
3380 output_addr_const (file, addr);
3381 if (GET_CODE (addr) == CONST_INT)
3382 fprintf (file, "(%s)", reg_names [0]);
3386 abort_with_insn (addr, "PRINT_OPERAND_ADDRESS, invalid insn #1");
3391 /* A C compound statement to output to stdio stream STREAM the
3392 assembler syntax for an instruction operand X. X is an RTL
3395 CODE is a value that can be used to specify one of several ways
3396 of printing the operand. It is used when identical operands
3397 must be printed differently depending on the context. CODE
3398 comes from the `%' specification that was used to request
3399 printing of the operand. If the specification was just `%DIGIT'
3400 then CODE is 0; if the specification was `%LTR DIGIT' then CODE
3401 is the ASCII code for LTR.
3403 If X is a register, this macro should print the register's name.
3404 The names can be found in an array `reg_names' whose type is
3405 `char *[]'. `reg_names' is initialized from `REGISTER_NAMES'.
3407 When the machine description has a specification `%PUNCT' (a `%'
3408 followed by a punctuation character), this macro is called with
3409 a null pointer for X and the punctuation character for CODE.
3411 The IQ2000 specific codes are:
3413 'X' X is CONST_INT, prints upper 16 bits in hexadecimal format = "0x%04x",
3414 'x' X is CONST_INT, prints lower 16 bits in hexadecimal format = "0x%04x",
3415 'd' output integer constant in decimal,
3416 'z' if the operand is 0, use $0 instead of normal operand.
3417 'D' print second part of double-word register or memory operand.
3418 'L' print low-order register of double-word register operand.
3419 'M' print high-order register of double-word register operand.
3420 'C' print part of opcode for a branch condition.
3421 'F' print part of opcode for a floating-point branch condition.
3422 'N' print part of opcode for a branch condition, inverted.
3423 'W' print part of opcode for a floating-point branch condition, inverted.
3424 'A' Print part of opcode for a bit test condition.
3425 'P' Print label for a bit test.
3426 'p' Print log for a bit test.
3427 'B' print 'z' for EQ, 'n' for NE
3428 'b' print 'n' for EQ, 'z' for NE
3429 'T' print 'f' for EQ, 't' for NE
3430 't' print 't' for EQ, 'f' for NE
3431 'Z' print register and a comma, but print nothing for $fcc0
3432 '?' Print 'l' if we are to use a branch likely instead of normal branch.
3433 '@' Print the name of the assembler temporary register (at or $1).
3434 '.' Print the name of the register with a hard-wired zero (zero or $0).
3435 '$' Print the name of the stack pointer register (sp or $29).
3436 '+' Print the name of the gp register (gp or $28). */
3439 print_operand (FILE *file, rtx op, int letter)
3441 register enum rtx_code code;
3443 if (PRINT_OPERAND_PUNCT_VALID_P (letter))
3448 if (iq2000_branch_likely)
3453 fputs (reg_names [GP_REG_FIRST + 1], file);
3457 fputs (reg_names [GP_REG_FIRST + 0], file);
3461 fputs (reg_names[STACK_POINTER_REGNUM], file);
3465 fputs (reg_names[GP_REG_FIRST + 28], file);
3469 error ("PRINT_OPERAND: Unknown punctuation '%c'", letter);
3478 error ("PRINT_OPERAND null pointer");
3482 code = GET_CODE (op);
3484 if (code == SIGN_EXTEND)
3485 op = XEXP (op, 0), code = GET_CODE (op);
3490 case EQ: fputs ("eq", file); break;
3491 case NE: fputs ("ne", file); break;
3492 case GT: fputs ("gt", file); break;
3493 case GE: fputs ("ge", file); break;
3494 case LT: fputs ("lt", file); break;
3495 case LE: fputs ("le", file); break;
3496 case GTU: fputs ("ne", file); break;
3497 case GEU: fputs ("geu", file); break;
3498 case LTU: fputs ("ltu", file); break;
3499 case LEU: fputs ("eq", file); break;
3501 abort_with_insn (op, "PRINT_OPERAND, invalid insn for %%C");
3504 else if (letter == 'N')
3507 case EQ: fputs ("ne", file); break;
3508 case NE: fputs ("eq", file); break;
3509 case GT: fputs ("le", file); break;
3510 case GE: fputs ("lt", file); break;
3511 case LT: fputs ("ge", file); break;
3512 case LE: fputs ("gt", file); break;
3513 case GTU: fputs ("leu", file); break;
3514 case GEU: fputs ("ltu", file); break;
3515 case LTU: fputs ("geu", file); break;
3516 case LEU: fputs ("gtu", file); break;
3518 abort_with_insn (op, "PRINT_OPERAND, invalid insn for %%N");
3521 else if (letter == 'F')
3524 case EQ: fputs ("c1f", file); break;
3525 case NE: fputs ("c1t", file); break;
3527 abort_with_insn (op, "PRINT_OPERAND, invalid insn for %%F");
3530 else if (letter == 'W')
3533 case EQ: fputs ("c1t", file); break;
3534 case NE: fputs ("c1f", file); break;
3536 abort_with_insn (op, "PRINT_OPERAND, invalid insn for %%W");
3539 else if (letter == 'A')
3540 fputs (code == LABEL_REF ? "i" : "in", file);
3542 else if (letter == 'P')
3544 if (code == LABEL_REF)
3545 output_addr_const (file, op);
3546 else if (code != PC)
3547 output_operand_lossage ("invalid %%P operand");
3550 else if (letter == 'p')
3553 if (code != CONST_INT
3554 || (value = exact_log2 (INTVAL (op))) < 0)
3555 output_operand_lossage ("invalid %%p value");
3556 fprintf (file, "%d", value);
3559 else if (letter == 'Z')
3561 register int regnum;
3566 regnum = REGNO (op);
3569 fprintf (file, "%s,", reg_names[regnum]);
3572 else if (code == REG || code == SUBREG)
3574 register int regnum;
3577 regnum = REGNO (op);
3579 regnum = true_regnum (op);
3581 if ((letter == 'M' && ! WORDS_BIG_ENDIAN)
3582 || (letter == 'L' && WORDS_BIG_ENDIAN)
3586 fprintf (file, "%s", reg_names[regnum]);
3589 else if (code == MEM)
3592 output_address (plus_constant (XEXP (op, 0), 4));
3594 output_address (XEXP (op, 0));
3597 else if (code == CONST_DOUBLE
3598 && GET_MODE_CLASS (GET_MODE (op)) == MODE_FLOAT)
3602 real_to_decimal (s, CONST_DOUBLE_REAL_VALUE (op), sizeof (s), 0, 1);
3606 else if (letter == 'x' && GET_CODE (op) == CONST_INT)
3607 fprintf (file, HOST_WIDE_INT_PRINT_HEX, 0xffff & INTVAL(op));
3609 else if (letter == 'X' && GET_CODE(op) == CONST_INT)
3610 fprintf (file, HOST_WIDE_INT_PRINT_HEX, 0xffff & (INTVAL (op) >> 16));
3612 else if (letter == 'd' && GET_CODE(op) == CONST_INT)
3613 fprintf (file, HOST_WIDE_INT_PRINT_DEC, (INTVAL(op)));
3615 else if (letter == 'z' && GET_CODE (op) == CONST_INT && INTVAL (op) == 0)
3616 fputs (reg_names[GP_REG_FIRST], file);
3618 else if (letter == 'd' || letter == 'x' || letter == 'X')
3619 output_operand_lossage ("invalid use of %%d, %%x, or %%X");
3621 else if (letter == 'B')
3622 fputs (code == EQ ? "z" : "n", file);
3623 else if (letter == 'b')
3624 fputs (code == EQ ? "n" : "z", file);
3625 else if (letter == 'T')
3626 fputs (code == EQ ? "f" : "t", file);
3627 else if (letter == 't')
3628 fputs (code == EQ ? "t" : "f", file);
3630 else if (code == CONST && GET_CODE (XEXP (op, 0)) == REG)
3632 print_operand (file, XEXP (op, 0), letter);
3636 output_addr_const (file, op);