1 /* Subroutines used for code generation on Vitesse IQ2000 processors
2 Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008
3 Free Software Foundation, Inc.
5 This file is part of GCC.
7 GCC is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3, or (at your option)
12 GCC is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING3. If not see
19 <http://www.gnu.org/licenses/>. */
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"
48 #include "langhooks.h"
50 /* Enumeration for all of the relational tests, so that we can build
51 arrays indexed by the test type, and not worry about the order
72 /* Structure to be filled in by compute_frame_size with register
73 save masks, and offsets for the current function. */
75 struct iq2000_frame_info
77 long total_size; /* # bytes that the entire frame takes up. */
78 long var_size; /* # bytes that variables take up. */
79 long args_size; /* # bytes that outgoing arguments take up. */
80 long extra_size; /* # bytes of extra gunk. */
81 int gp_reg_size; /* # bytes needed to store gp regs. */
82 int fp_reg_size; /* # bytes needed to store fp regs. */
83 long mask; /* Mask of saved gp registers. */
84 long gp_save_offset; /* Offset from vfp to store gp registers. */
85 long fp_save_offset; /* Offset from vfp to store fp registers. */
86 long gp_sp_offset; /* Offset from new sp to store gp registers. */
87 long fp_sp_offset; /* Offset from new sp to store fp registers. */
88 int initialized; /* != 0 if frame size already calculated. */
89 int num_gp; /* Number of gp registers saved. */
92 struct GTY(()) machine_function
94 /* Current frame information, calculated by compute_frame_size. */
95 long total_size; /* # bytes that the entire frame takes up. */
96 long var_size; /* # bytes that variables take up. */
97 long args_size; /* # bytes that outgoing arguments take up. */
98 long extra_size; /* # bytes of extra gunk. */
99 int gp_reg_size; /* # bytes needed to store gp regs. */
100 int fp_reg_size; /* # bytes needed to store fp regs. */
101 long mask; /* Mask of saved gp registers. */
102 long gp_save_offset; /* Offset from vfp to store gp registers. */
103 long fp_save_offset; /* Offset from vfp to store fp registers. */
104 long gp_sp_offset; /* Offset from new sp to store gp registers. */
105 long fp_sp_offset; /* Offset from new sp to store fp registers. */
106 int initialized; /* != 0 if frame size already calculated. */
107 int num_gp; /* Number of gp registers saved. */
110 /* Global variables for machine-dependent things. */
112 /* List of all IQ2000 punctuation characters used by print_operand. */
113 char iq2000_print_operand_punct[256];
115 /* The target cpu for optimization and scheduling. */
116 enum processor_type iq2000_tune;
118 /* Which instruction set architecture to use. */
121 /* Cached operands, and operator to compare for use in set/branch/trap
122 on condition codes. */
125 /* What type of branch to use. */
126 enum cmp_type branch_type;
128 /* Local variables. */
130 /* The next branch instruction is a branch likely, not branch normal. */
131 static int iq2000_branch_likely;
133 /* Count of delay slots and how many are filled. */
134 static int dslots_load_total;
135 static int dslots_load_filled;
136 static int dslots_jump_total;
138 /* # of nops needed by previous insn. */
139 static int dslots_number_nops;
141 /* Number of 1/2/3 word references to data items (i.e., not jal's). */
142 static int num_refs[3];
144 /* Registers to check for load delay. */
145 static rtx iq2000_load_reg;
146 static rtx iq2000_load_reg2;
147 static rtx iq2000_load_reg3;
148 static rtx iq2000_load_reg4;
150 /* Mode used for saving/restoring general purpose registers. */
151 static enum machine_mode gpr_mode;
154 /* Initialize the GCC target structure. */
155 static struct machine_function* iq2000_init_machine_status (void);
156 static bool iq2000_handle_option (size_t, const char *, int);
157 static section *iq2000_select_rtx_section (enum machine_mode, rtx,
158 unsigned HOST_WIDE_INT);
159 static void iq2000_init_builtins (void);
160 static rtx iq2000_expand_builtin (tree, rtx, rtx, enum machine_mode, int);
161 static bool iq2000_return_in_memory (const_tree, const_tree);
162 static void iq2000_setup_incoming_varargs (CUMULATIVE_ARGS *,
163 enum machine_mode, tree, int *,
165 static bool iq2000_rtx_costs (rtx, int, int, int *, bool);
166 static int iq2000_address_cost (rtx, bool);
167 static section *iq2000_select_section (tree, int, unsigned HOST_WIDE_INT);
168 static bool iq2000_pass_by_reference (CUMULATIVE_ARGS *, enum machine_mode,
170 static int iq2000_arg_partial_bytes (CUMULATIVE_ARGS *, enum machine_mode,
172 static void iq2000_va_start (tree, rtx);
174 #undef TARGET_INIT_BUILTINS
175 #define TARGET_INIT_BUILTINS iq2000_init_builtins
176 #undef TARGET_EXPAND_BUILTIN
177 #define TARGET_EXPAND_BUILTIN iq2000_expand_builtin
178 #undef TARGET_ASM_SELECT_RTX_SECTION
179 #define TARGET_ASM_SELECT_RTX_SECTION iq2000_select_rtx_section
180 #undef TARGET_HANDLE_OPTION
181 #define TARGET_HANDLE_OPTION iq2000_handle_option
182 #undef TARGET_RTX_COSTS
183 #define TARGET_RTX_COSTS iq2000_rtx_costs
184 #undef TARGET_ADDRESS_COST
185 #define TARGET_ADDRESS_COST iq2000_address_cost
186 #undef TARGET_ASM_SELECT_SECTION
187 #define TARGET_ASM_SELECT_SECTION iq2000_select_section
189 /* The assembler supports switchable .bss sections, but
190 iq2000_select_section doesn't yet make use of them. */
191 #undef TARGET_HAVE_SWITCHABLE_BSS_SECTIONS
192 #define TARGET_HAVE_SWITCHABLE_BSS_SECTIONS false
194 #undef TARGET_PROMOTE_FUNCTION_ARGS
195 #define TARGET_PROMOTE_FUNCTION_ARGS hook_bool_const_tree_true
196 #undef TARGET_PROMOTE_FUNCTION_RETURN
197 #define TARGET_PROMOTE_FUNCTION_RETURN hook_bool_const_tree_true
198 #undef TARGET_PROMOTE_PROTOTYPES
199 #define TARGET_PROMOTE_PROTOTYPES hook_bool_const_tree_true
201 #undef TARGET_RETURN_IN_MEMORY
202 #define TARGET_RETURN_IN_MEMORY iq2000_return_in_memory
203 #undef TARGET_PASS_BY_REFERENCE
204 #define TARGET_PASS_BY_REFERENCE iq2000_pass_by_reference
205 #undef TARGET_CALLEE_COPIES
206 #define TARGET_CALLEE_COPIES hook_callee_copies_named
207 #undef TARGET_ARG_PARTIAL_BYTES
208 #define TARGET_ARG_PARTIAL_BYTES iq2000_arg_partial_bytes
210 #undef TARGET_SETUP_INCOMING_VARARGS
211 #define TARGET_SETUP_INCOMING_VARARGS iq2000_setup_incoming_varargs
212 #undef TARGET_STRICT_ARGUMENT_NAMING
213 #define TARGET_STRICT_ARGUMENT_NAMING hook_bool_CUMULATIVE_ARGS_true
215 #undef TARGET_EXPAND_BUILTIN_VA_START
216 #define TARGET_EXPAND_BUILTIN_VA_START iq2000_va_start
218 struct gcc_target targetm = TARGET_INITIALIZER;
220 /* Return nonzero if we split the address into high and low parts. */
223 iq2000_check_split (rtx address, enum machine_mode mode)
225 /* This is the same check used in simple_memory_operand.
226 We use it here because LO_SUM is not offsettable. */
227 if (GET_MODE_SIZE (mode) > (unsigned) UNITS_PER_WORD)
230 if ((GET_CODE (address) == SYMBOL_REF)
231 || (GET_CODE (address) == CONST
232 && GET_CODE (XEXP (XEXP (address, 0), 0)) == SYMBOL_REF)
233 || GET_CODE (address) == LABEL_REF)
239 /* Return nonzero if REG is valid for MODE. */
242 iq2000_reg_mode_ok_for_base_p (rtx reg,
243 enum machine_mode mode ATTRIBUTE_UNUSED,
247 ? REGNO_MODE_OK_FOR_BASE_P (REGNO (reg), mode)
248 : GP_REG_OR_PSEUDO_NONSTRICT_P (REGNO (reg), mode));
251 /* Return a nonzero value if XINSN is a legitimate address for a
252 memory operand of the indicated MODE. STRICT is nonzero if this
253 function is called during reload. */
256 iq2000_legitimate_address_p (enum machine_mode mode, rtx xinsn, int strict)
258 if (TARGET_DEBUG_A_MODE)
260 GO_PRINTF2 ("\n========== GO_IF_LEGITIMATE_ADDRESS, %sstrict\n",
261 strict ? "" : "not ");
262 GO_DEBUG_RTX (xinsn);
265 /* Check for constant before stripping off SUBREG, so that we don't
266 accept (subreg (const_int)) which will fail to reload. */
267 if (CONSTANT_ADDRESS_P (xinsn)
268 && ! (iq2000_check_split (xinsn, mode))
269 && ! (GET_CODE (xinsn) == CONST_INT && ! SMALL_INT (xinsn)))
272 while (GET_CODE (xinsn) == SUBREG)
273 xinsn = SUBREG_REG (xinsn);
275 if (GET_CODE (xinsn) == REG
276 && iq2000_reg_mode_ok_for_base_p (xinsn, mode, strict))
279 if (GET_CODE (xinsn) == LO_SUM)
281 rtx xlow0 = XEXP (xinsn, 0);
282 rtx xlow1 = XEXP (xinsn, 1);
284 while (GET_CODE (xlow0) == SUBREG)
285 xlow0 = SUBREG_REG (xlow0);
286 if (GET_CODE (xlow0) == REG
287 && iq2000_reg_mode_ok_for_base_p (xlow0, mode, strict)
288 && iq2000_check_split (xlow1, mode))
292 if (GET_CODE (xinsn) == PLUS)
294 rtx xplus0 = XEXP (xinsn, 0);
295 rtx xplus1 = XEXP (xinsn, 1);
299 while (GET_CODE (xplus0) == SUBREG)
300 xplus0 = SUBREG_REG (xplus0);
301 code0 = GET_CODE (xplus0);
303 while (GET_CODE (xplus1) == SUBREG)
304 xplus1 = SUBREG_REG (xplus1);
305 code1 = GET_CODE (xplus1);
308 && iq2000_reg_mode_ok_for_base_p (xplus0, mode, strict))
310 if (code1 == CONST_INT && SMALL_INT (xplus1)
311 && SMALL_INT_UNSIGNED (xplus1) /* No negative offsets */)
316 if (TARGET_DEBUG_A_MODE)
317 GO_PRINTF ("Not a legitimate address\n");
319 /* The address was not legitimate. */
323 /* Returns an operand string for the given instruction's delay slot,
324 after updating filled delay slot statistics.
326 We assume that operands[0] is the target register that is set.
328 In order to check the next insn, most of this functionality is moved
329 to FINAL_PRESCAN_INSN, and we just set the global variables that
333 iq2000_fill_delay_slot (const char *ret, enum delay_type type, rtx operands[],
337 enum machine_mode mode;
338 rtx next_insn = cur_insn ? NEXT_INSN (cur_insn) : NULL_RTX;
341 if (type == DELAY_LOAD || type == DELAY_FCMP)
347 /* Make sure that we don't put nop's after labels. */
348 next_insn = NEXT_INSN (cur_insn);
349 while (next_insn != 0
350 && (GET_CODE (next_insn) == NOTE
351 || GET_CODE (next_insn) == CODE_LABEL))
352 next_insn = NEXT_INSN (next_insn);
354 dslots_load_total += num_nops;
355 if (TARGET_DEBUG_C_MODE
356 || type == DELAY_NONE
360 || GET_CODE (next_insn) == CODE_LABEL
361 || (set_reg = operands[0]) == 0)
363 dslots_number_nops = 0;
365 iq2000_load_reg2 = 0;
366 iq2000_load_reg3 = 0;
367 iq2000_load_reg4 = 0;
372 set_reg = operands[0];
376 while (GET_CODE (set_reg) == SUBREG)
377 set_reg = SUBREG_REG (set_reg);
379 mode = GET_MODE (set_reg);
380 dslots_number_nops = num_nops;
381 iq2000_load_reg = set_reg;
382 if (GET_MODE_SIZE (mode)
383 > (unsigned) (UNITS_PER_WORD))
384 iq2000_load_reg2 = gen_rtx_REG (SImode, REGNO (set_reg) + 1);
386 iq2000_load_reg2 = 0;
391 /* Determine whether a memory reference takes one (based off of the GP
392 pointer), two (normal), or three (label + reg) instructions, and bump the
393 appropriate counter for -mstats. */
396 iq2000_count_memory_refs (rtx op, int num)
400 rtx addr, plus0, plus1;
401 enum rtx_code code0, code1;
404 if (TARGET_DEBUG_B_MODE)
406 fprintf (stderr, "\n========== iq2000_count_memory_refs:\n");
410 /* Skip MEM if passed, otherwise handle movsi of address. */
411 addr = (GET_CODE (op) != MEM) ? op : XEXP (op, 0);
413 /* Loop, going through the address RTL. */
417 switch (GET_CODE (addr))
425 plus0 = XEXP (addr, 0);
426 plus1 = XEXP (addr, 1);
427 code0 = GET_CODE (plus0);
428 code1 = GET_CODE (plus1);
438 if (code0 == CONST_INT)
453 if (code1 == CONST_INT)
460 if (code0 == SYMBOL_REF || code0 == LABEL_REF || code0 == CONST)
467 if (code1 == SYMBOL_REF || code1 == LABEL_REF || code1 == CONST)
477 n_words = 2; /* Always 2 words. */
481 addr = XEXP (addr, 0);
486 n_words = SYMBOL_REF_FLAG (addr) ? 1 : 2;
498 n_words += additional;
502 num_refs[n_words-1] += num;
505 /* Abort after printing out a specific insn. */
508 abort_with_insn (rtx insn, const char * reason)
512 fancy_abort (__FILE__, __LINE__, __FUNCTION__);
515 /* Return the appropriate instructions to move one operand to another. */
518 iq2000_move_1word (rtx operands[], rtx insn, int unsignedp)
521 rtx op0 = operands[0];
522 rtx op1 = operands[1];
523 enum rtx_code code0 = GET_CODE (op0);
524 enum rtx_code code1 = GET_CODE (op1);
525 enum machine_mode mode = GET_MODE (op0);
526 int subreg_offset0 = 0;
527 int subreg_offset1 = 0;
528 enum delay_type delay = DELAY_NONE;
530 while (code0 == SUBREG)
532 subreg_offset0 += subreg_regno_offset (REGNO (SUBREG_REG (op0)),
533 GET_MODE (SUBREG_REG (op0)),
536 op0 = SUBREG_REG (op0);
537 code0 = GET_CODE (op0);
540 while (code1 == SUBREG)
542 subreg_offset1 += subreg_regno_offset (REGNO (SUBREG_REG (op1)),
543 GET_MODE (SUBREG_REG (op1)),
546 op1 = SUBREG_REG (op1);
547 code1 = GET_CODE (op1);
550 /* For our purposes, a condition code mode is the same as SImode. */
556 int regno0 = REGNO (op0) + subreg_offset0;
560 int regno1 = REGNO (op1) + subreg_offset1;
562 /* Do not do anything for assigning a register to itself */
563 if (regno0 == regno1)
566 else if (GP_REG_P (regno0))
568 if (GP_REG_P (regno1))
569 ret = "or\t%0,%%0,%1";
574 else if (code1 == MEM)
579 iq2000_count_memory_refs (op1, 1);
581 if (GP_REG_P (regno0))
583 /* For loads, use the mode of the memory item, instead of the
584 target, so zero/sign extend can use this code as well. */
585 switch (GET_MODE (op1))
597 ret = (unsignedp) ? "lhu\t%0,%1" : "lh\t%0,%1";
600 ret = (unsignedp) ? "lbu\t%0,%1" : "lb\t%0,%1";
606 else if (code1 == CONST_INT
607 || (code1 == CONST_DOUBLE
608 && GET_MODE (op1) == VOIDmode))
610 if (code1 == CONST_DOUBLE)
612 /* This can happen when storing constants into long long
613 bitfields. Just store the least significant word of
615 operands[1] = op1 = GEN_INT (CONST_DOUBLE_LOW (op1));
618 if (INTVAL (op1) == 0)
620 if (GP_REG_P (regno0))
621 ret = "or\t%0,%%0,%z1";
623 else if (GP_REG_P (regno0))
625 if (SMALL_INT_UNSIGNED (op1))
626 ret = "ori\t%0,%%0,%x1\t\t\t# %1";
627 else if (SMALL_INT (op1))
628 ret = "addiu\t%0,%%0,%1\t\t\t# %1";
630 ret = "lui\t%0,%X1\t\t\t# %1\n\tori\t%0,%0,%x1";
634 else if (code1 == CONST_DOUBLE && mode == SFmode)
636 if (op1 == CONST0_RTX (SFmode))
638 if (GP_REG_P (regno0))
639 ret = "or\t%0,%%0,%.";
649 else if (code1 == LABEL_REF)
652 iq2000_count_memory_refs (op1, 1);
657 else if (code1 == SYMBOL_REF || code1 == CONST)
660 iq2000_count_memory_refs (op1, 1);
665 else if (code1 == PLUS)
667 rtx add_op0 = XEXP (op1, 0);
668 rtx add_op1 = XEXP (op1, 1);
670 if (GET_CODE (XEXP (op1, 1)) == REG
671 && GET_CODE (XEXP (op1, 0)) == CONST_INT)
672 add_op0 = XEXP (op1, 1), add_op1 = XEXP (op1, 0);
674 operands[2] = add_op0;
675 operands[3] = add_op1;
676 ret = "add%:\t%0,%2,%3";
679 else if (code1 == HIGH)
681 operands[1] = XEXP (op1, 0);
682 ret = "lui\t%0,%%hi(%1)";
686 else if (code0 == MEM)
689 iq2000_count_memory_refs (op0, 1);
693 int regno1 = REGNO (op1) + subreg_offset1;
695 if (GP_REG_P (regno1))
699 case SFmode: ret = "sw\t%1,%0"; break;
700 case SImode: ret = "sw\t%1,%0"; break;
701 case HImode: ret = "sh\t%1,%0"; break;
702 case QImode: ret = "sb\t%1,%0"; break;
708 else if (code1 == CONST_INT && INTVAL (op1) == 0)
712 case SFmode: ret = "sw\t%z1,%0"; break;
713 case SImode: ret = "sw\t%z1,%0"; break;
714 case HImode: ret = "sh\t%z1,%0"; break;
715 case QImode: ret = "sb\t%z1,%0"; break;
720 else if (code1 == CONST_DOUBLE && op1 == CONST0_RTX (mode))
724 case SFmode: ret = "sw\t%.,%0"; break;
725 case SImode: ret = "sw\t%.,%0"; break;
726 case HImode: ret = "sh\t%.,%0"; break;
727 case QImode: ret = "sb\t%.,%0"; break;
735 abort_with_insn (insn, "Bad move");
739 if (delay != DELAY_NONE)
740 return iq2000_fill_delay_slot (ret, delay, operands, insn);
745 /* Provide the costs of an addressing mode that contains ADDR. */
748 iq2000_address_cost (rtx addr, bool speed)
750 switch (GET_CODE (addr))
760 rtx offset = const0_rtx;
762 addr = eliminate_constant_term (XEXP (addr, 0), & offset);
763 if (GET_CODE (addr) == LABEL_REF)
766 if (GET_CODE (addr) != SYMBOL_REF)
769 if (! SMALL_INT (offset))
776 return SYMBOL_REF_FLAG (addr) ? 1 : 2;
780 rtx plus0 = XEXP (addr, 0);
781 rtx plus1 = XEXP (addr, 1);
783 if (GET_CODE (plus0) != REG && GET_CODE (plus1) == REG)
784 plus0 = XEXP (addr, 1), plus1 = XEXP (addr, 0);
786 if (GET_CODE (plus0) != REG)
789 switch (GET_CODE (plus1))
792 return SMALL_INT (plus1) ? 1 : 2;
799 return iq2000_address_cost (plus1, speed) + 1;
813 /* Make normal rtx_code into something we can index from an array. */
815 static enum internal_test
816 map_test_to_internal_test (enum rtx_code test_code)
818 enum internal_test test = ITEST_MAX;
822 case EQ: test = ITEST_EQ; break;
823 case NE: test = ITEST_NE; break;
824 case GT: test = ITEST_GT; break;
825 case GE: test = ITEST_GE; break;
826 case LT: test = ITEST_LT; break;
827 case LE: test = ITEST_LE; break;
828 case GTU: test = ITEST_GTU; break;
829 case GEU: test = ITEST_GEU; break;
830 case LTU: test = ITEST_LTU; break;
831 case LEU: test = ITEST_LEU; break;
838 /* Generate the code to do a TEST_CODE comparison on two integer values CMP0
839 and CMP1. P_INVERT is NULL or ptr if branch needs to reverse its test.
840 The return value RESULT is:
841 (reg:SI xx) The pseudo register the comparison is in
842 0 No register, generate a simple branch. */
845 gen_int_relational (enum rtx_code test_code, rtx result, rtx cmp0, rtx cmp1,
850 enum rtx_code test_code; /* Code to use in instruction (LT vs. LTU). */
851 int const_low; /* Low bound of constant we can accept. */
852 int const_high; /* High bound of constant we can accept. */
853 int const_add; /* Constant to add (convert LE -> LT). */
854 int reverse_regs; /* Reverse registers in test. */
855 int invert_const; /* != 0 if invert value if cmp1 is constant. */
856 int invert_reg; /* != 0 if invert value if cmp1 is register. */
857 int unsignedp; /* != 0 for unsigned comparisons. */
860 static struct cmp_info info[ (int)ITEST_MAX ] =
862 { XOR, 0, 65535, 0, 0, 0, 0, 0 }, /* EQ */
863 { XOR, 0, 65535, 0, 0, 1, 1, 0 }, /* NE */
864 { LT, -32769, 32766, 1, 1, 1, 0, 0 }, /* GT */
865 { LT, -32768, 32767, 0, 0, 1, 1, 0 }, /* GE */
866 { LT, -32768, 32767, 0, 0, 0, 0, 0 }, /* LT */
867 { LT, -32769, 32766, 1, 1, 0, 1, 0 }, /* LE */
868 { LTU, -32769, 32766, 1, 1, 1, 0, 1 }, /* GTU */
869 { LTU, -32768, 32767, 0, 0, 1, 1, 1 }, /* GEU */
870 { LTU, -32768, 32767, 0, 0, 0, 0, 1 }, /* LTU */
871 { LTU, -32769, 32766, 1, 1, 0, 1, 1 }, /* LEU */
874 enum internal_test test;
875 enum machine_mode mode;
876 struct cmp_info *p_info;
883 test = map_test_to_internal_test (test_code);
884 gcc_assert (test != ITEST_MAX);
886 p_info = &info[(int) test];
887 eqne_p = (p_info->test_code == XOR);
889 mode = GET_MODE (cmp0);
890 if (mode == VOIDmode)
891 mode = GET_MODE (cmp1);
893 /* Eliminate simple branches. */
894 branch_p = (result == 0);
897 if (GET_CODE (cmp0) == REG || GET_CODE (cmp0) == SUBREG)
899 /* Comparisons against zero are simple branches. */
900 if (GET_CODE (cmp1) == CONST_INT && INTVAL (cmp1) == 0)
903 /* Test for beq/bne. */
908 /* Allocate a pseudo to calculate the value in. */
909 result = gen_reg_rtx (mode);
912 /* Make sure we can handle any constants given to us. */
913 if (GET_CODE (cmp0) == CONST_INT)
914 cmp0 = force_reg (mode, cmp0);
916 if (GET_CODE (cmp1) == CONST_INT)
918 HOST_WIDE_INT value = INTVAL (cmp1);
920 if (value < p_info->const_low
921 || value > p_info->const_high)
922 cmp1 = force_reg (mode, cmp1);
925 /* See if we need to invert the result. */
926 invert = (GET_CODE (cmp1) == CONST_INT
927 ? p_info->invert_const : p_info->invert_reg);
929 if (p_invert != (int *)0)
935 /* Comparison to constants, may involve adding 1 to change a LT into LE.
936 Comparison between two registers, may involve switching operands. */
937 if (GET_CODE (cmp1) == CONST_INT)
939 if (p_info->const_add != 0)
941 HOST_WIDE_INT new_const = INTVAL (cmp1) + p_info->const_add;
943 /* If modification of cmp1 caused overflow,
944 we would get the wrong answer if we follow the usual path;
945 thus, x > 0xffffffffU would turn into x > 0U. */
946 if ((p_info->unsignedp
947 ? (unsigned HOST_WIDE_INT) new_const >
948 (unsigned HOST_WIDE_INT) INTVAL (cmp1)
949 : new_const > INTVAL (cmp1))
950 != (p_info->const_add > 0))
952 /* This test is always true, but if INVERT is true then
953 the result of the test needs to be inverted so 0 should
954 be returned instead. */
955 emit_move_insn (result, invert ? const0_rtx : const_true_rtx);
959 cmp1 = GEN_INT (new_const);
963 else if (p_info->reverse_regs)
970 if (test == ITEST_NE && GET_CODE (cmp1) == CONST_INT && INTVAL (cmp1) == 0)
974 reg = (invert || eqne_p) ? gen_reg_rtx (mode) : result;
975 convert_move (reg, gen_rtx_fmt_ee (p_info->test_code, mode, cmp0, cmp1), 0);
978 if (test == ITEST_NE)
980 convert_move (result, gen_rtx_GTU (mode, reg, const0_rtx), 0);
981 if (p_invert != NULL)
986 else if (test == ITEST_EQ)
988 reg2 = invert ? gen_reg_rtx (mode) : result;
989 convert_move (reg2, gen_rtx_LTU (mode, reg, const1_rtx), 0);
998 convert_move (result, gen_rtx_XOR (mode, reg, one), 0);
1004 /* Emit the common code for doing conditional branches.
1005 operand[0] is the label to jump to.
1006 The comparison operands are saved away by cmp{si,di,sf,df}. */
1009 gen_conditional_branch (rtx operands[], enum rtx_code test_code)
1011 enum cmp_type type = branch_type;
1012 rtx cmp0 = branch_cmp[0];
1013 rtx cmp1 = branch_cmp[1];
1014 enum machine_mode mode;
1023 mode = type == CMP_SI ? SImode : DImode;
1025 reg = gen_int_relational (test_code, NULL_RTX, cmp0, cmp1, &invert);
1033 else if (GET_CODE (cmp1) == CONST_INT && INTVAL (cmp1) != 0)
1034 /* We don't want to build a comparison against a nonzero
1036 cmp1 = force_reg (mode, cmp1);
1042 reg = gen_reg_rtx (CCmode);
1044 /* For cmp0 != cmp1, build cmp0 == cmp1, and test for result == 0. */
1045 emit_insn (gen_rtx_SET (VOIDmode, reg,
1046 gen_rtx_fmt_ee (test_code == NE ? EQ : test_code,
1047 CCmode, cmp0, cmp1)));
1049 test_code = test_code == NE ? EQ : NE;
1057 abort_with_insn (gen_rtx_fmt_ee (test_code, VOIDmode, cmp0, cmp1),
1061 /* Generate the branch. */
1062 label1 = gen_rtx_LABEL_REF (VOIDmode, operands[0]);
1071 emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
1072 gen_rtx_IF_THEN_ELSE (VOIDmode,
1073 gen_rtx_fmt_ee (test_code,
1079 /* Initialize CUM for a function FNTYPE. */
1082 init_cumulative_args (CUMULATIVE_ARGS *cum, tree fntype,
1083 rtx libname ATTRIBUTE_UNUSED)
1085 static CUMULATIVE_ARGS zero_cum;
1089 if (TARGET_DEBUG_D_MODE)
1092 "\ninit_cumulative_args, fntype = 0x%.8lx", (long) fntype);
1095 fputc ('\n', stderr);
1099 tree ret_type = TREE_TYPE (fntype);
1101 fprintf (stderr, ", fntype code = %s, ret code = %s\n",
1102 tree_code_name[(int)TREE_CODE (fntype)],
1103 tree_code_name[(int)TREE_CODE (ret_type)]);
1109 /* Determine if this function has variable arguments. This is
1110 indicated by the last argument being 'void_type_mode' if there
1111 are no variable arguments. The standard IQ2000 calling sequence
1112 passes all arguments in the general purpose registers in this case. */
1114 for (param = fntype ? TYPE_ARG_TYPES (fntype) : 0;
1115 param != 0; param = next_param)
1117 next_param = TREE_CHAIN (param);
1118 if (next_param == 0 && TREE_VALUE (param) != void_type_node)
1119 cum->gp_reg_found = 1;
1123 /* Advance the argument of type TYPE and mode MODE to the next argument
1127 function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode, tree type,
1130 if (TARGET_DEBUG_D_MODE)
1133 "function_adv({gp reg found = %d, arg # = %2d, words = %2d}, %4s, ",
1134 cum->gp_reg_found, cum->arg_number, cum->arg_words,
1135 GET_MODE_NAME (mode));
1136 fprintf (stderr, "%p", (void *) type);
1137 fprintf (stderr, ", %d )\n\n", named);
1147 gcc_assert (GET_MODE_CLASS (mode) == MODE_COMPLEX_INT
1148 || GET_MODE_CLASS (mode) == MODE_COMPLEX_FLOAT);
1150 cum->gp_reg_found = 1;
1151 cum->arg_words += ((GET_MODE_SIZE (mode) + UNITS_PER_WORD - 1)
1156 cum->gp_reg_found = 1;
1157 cum->arg_words += ((int_size_in_bytes (type) + UNITS_PER_WORD - 1)
1163 if (! cum->gp_reg_found && cum->arg_number <= 2)
1164 cum->fp_code += 1 << ((cum->arg_number - 1) * 2);
1168 cum->arg_words += 2;
1169 if (! cum->gp_reg_found && cum->arg_number <= 2)
1170 cum->fp_code += 2 << ((cum->arg_number - 1) * 2);
1174 cum->gp_reg_found = 1;
1175 cum->arg_words += 2;
1179 cum->gp_reg_found = 1;
1180 cum->arg_words += 4;
1186 cum->gp_reg_found = 1;
1192 /* Return an RTL expression containing the register for the given mode MODE
1193 and type TYPE in CUM, or 0 if the argument is to be passed on the stack. */
1196 function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode, const_tree type,
1202 unsigned int *arg_words = &cum->arg_words;
1203 int struct_p = (type != 0
1204 && (TREE_CODE (type) == RECORD_TYPE
1205 || TREE_CODE (type) == UNION_TYPE
1206 || TREE_CODE (type) == QUAL_UNION_TYPE));
1208 if (TARGET_DEBUG_D_MODE)
1211 "function_arg( {gp reg found = %d, arg # = %2d, words = %2d}, %4s, ",
1212 cum->gp_reg_found, cum->arg_number, cum->arg_words,
1213 GET_MODE_NAME (mode));
1214 fprintf (stderr, "%p", (const void *) type);
1215 fprintf (stderr, ", %d ) = ", named);
1219 cum->last_arg_fp = 0;
1223 regbase = GP_ARG_FIRST;
1227 cum->arg_words += cum->arg_words & 1;
1229 regbase = GP_ARG_FIRST;
1233 gcc_assert (GET_MODE_CLASS (mode) == MODE_COMPLEX_INT
1234 || GET_MODE_CLASS (mode) == MODE_COMPLEX_FLOAT);
1236 /* Drops through. */
1238 if (type != NULL_TREE && TYPE_ALIGN (type) > (unsigned) BITS_PER_WORD)
1239 cum->arg_words += (cum->arg_words & 1);
1240 regbase = GP_ARG_FIRST;
1247 regbase = GP_ARG_FIRST;
1251 cum->arg_words += (cum->arg_words & 1);
1252 regbase = GP_ARG_FIRST;
1256 cum->arg_words += (cum->arg_words & 3);
1257 regbase = GP_ARG_FIRST;
1261 if (*arg_words >= (unsigned) MAX_ARGS_IN_REGISTERS)
1263 if (TARGET_DEBUG_D_MODE)
1264 fprintf (stderr, "<stack>%s\n", struct_p ? ", [struct]" : "");
1270 gcc_assert (regbase != -1);
1272 if (! type || TREE_CODE (type) != RECORD_TYPE
1273 || ! named || ! TYPE_SIZE_UNIT (type)
1274 || ! host_integerp (TYPE_SIZE_UNIT (type), 1))
1275 ret = gen_rtx_REG (mode, regbase + *arg_words + bias);
1280 for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field))
1281 if (TREE_CODE (field) == FIELD_DECL
1282 && TREE_CODE (TREE_TYPE (field)) == REAL_TYPE
1283 && TYPE_PRECISION (TREE_TYPE (field)) == BITS_PER_WORD
1284 && host_integerp (bit_position (field), 0)
1285 && int_bit_position (field) % BITS_PER_WORD == 0)
1288 /* If the whole struct fits a DFmode register,
1289 we don't need the PARALLEL. */
1290 if (! field || mode == DFmode)
1291 ret = gen_rtx_REG (mode, regbase + *arg_words + bias);
1294 unsigned int chunks;
1295 HOST_WIDE_INT bitpos;
1299 /* ??? If this is a packed structure, then the last hunk won't
1302 = tree_low_cst (TYPE_SIZE_UNIT (type), 1) / UNITS_PER_WORD;
1303 if (chunks + *arg_words + bias > (unsigned) MAX_ARGS_IN_REGISTERS)
1304 chunks = MAX_ARGS_IN_REGISTERS - *arg_words - bias;
1306 /* Assign_parms checks the mode of ENTRY_PARM, so we must
1307 use the actual mode here. */
1308 ret = gen_rtx_PARALLEL (mode, rtvec_alloc (chunks));
1311 regno = regbase + *arg_words + bias;
1312 field = TYPE_FIELDS (type);
1313 for (i = 0; i < chunks; i++)
1317 for (; field; field = TREE_CHAIN (field))
1318 if (TREE_CODE (field) == FIELD_DECL
1319 && int_bit_position (field) >= bitpos)
1323 && int_bit_position (field) == bitpos
1324 && TREE_CODE (TREE_TYPE (field)) == REAL_TYPE
1325 && TYPE_PRECISION (TREE_TYPE (field)) == BITS_PER_WORD)
1326 reg = gen_rtx_REG (DFmode, regno++);
1328 reg = gen_rtx_REG (word_mode, regno);
1331 = gen_rtx_EXPR_LIST (VOIDmode, reg,
1332 GEN_INT (bitpos / BITS_PER_UNIT));
1340 if (TARGET_DEBUG_D_MODE)
1341 fprintf (stderr, "%s%s\n", reg_names[regbase + *arg_words + bias],
1342 struct_p ? ", [struct]" : "");
1345 /* We will be called with a mode of VOIDmode after the last argument
1346 has been seen. Whatever we return will be passed to the call
1347 insn. If we need any shifts for small structures, return them in
1349 if (mode == VOIDmode)
1351 if (cum->num_adjusts > 0)
1352 ret = gen_rtx_PARALLEL ((enum machine_mode) cum->fp_code,
1353 gen_rtvec_v (cum->num_adjusts, cum->adjust));
1360 iq2000_arg_partial_bytes (CUMULATIVE_ARGS *cum, enum machine_mode mode,
1361 tree type ATTRIBUTE_UNUSED,
1362 bool named ATTRIBUTE_UNUSED)
1364 if (mode == DImode && cum->arg_words == MAX_ARGS_IN_REGISTERS - 1)
1366 if (TARGET_DEBUG_D_MODE)
1367 fprintf (stderr, "iq2000_arg_partial_bytes=%d\n", UNITS_PER_WORD);
1368 return UNITS_PER_WORD;
1374 /* Implement va_start. */
1377 iq2000_va_start (tree valist, rtx nextarg)
1380 /* Find out how many non-float named formals. */
1381 int gpr_save_area_size;
1382 /* Note UNITS_PER_WORD is 4 bytes. */
1383 int_arg_words = crtl->args.info.arg_words;
1385 if (int_arg_words < 8 )
1386 /* Adjust for the prologue's economy measure. */
1387 gpr_save_area_size = (8 - int_arg_words) * UNITS_PER_WORD;
1389 gpr_save_area_size = 0;
1391 /* Everything is in the GPR save area, or in the overflow
1392 area which is contiguous with it. */
1393 nextarg = plus_constant (nextarg, - gpr_save_area_size);
1394 std_expand_builtin_va_start (valist, nextarg);
1397 /* Allocate a chunk of memory for per-function machine-dependent data. */
1399 static struct machine_function *
1400 iq2000_init_machine_status (void)
1402 struct machine_function *f;
1404 f = GGC_CNEW (struct machine_function);
1409 /* Implement TARGET_HANDLE_OPTION. */
1412 iq2000_handle_option (size_t code, const char *arg, int value ATTRIBUTE_UNUSED)
1417 if (strcmp (arg, "iq10") == 0)
1418 iq2000_tune = PROCESSOR_IQ10;
1419 else if (strcmp (arg, "iq2000") == 0)
1420 iq2000_tune = PROCESSOR_IQ2000;
1426 /* This option has no effect at the moment. */
1427 return (strcmp (arg, "default") == 0
1428 || strcmp (arg, "DEFAULT") == 0
1429 || strcmp (arg, "iq2000") == 0);
1436 /* Detect any conflicts in the switches. */
1439 override_options (void)
1441 target_flags &= ~MASK_GPOPT;
1443 iq2000_isa = IQ2000_ISA_DEFAULT;
1445 /* Identify the processor type. */
1447 iq2000_print_operand_punct['?'] = 1;
1448 iq2000_print_operand_punct['#'] = 1;
1449 iq2000_print_operand_punct['&'] = 1;
1450 iq2000_print_operand_punct['!'] = 1;
1451 iq2000_print_operand_punct['*'] = 1;
1452 iq2000_print_operand_punct['@'] = 1;
1453 iq2000_print_operand_punct['.'] = 1;
1454 iq2000_print_operand_punct['('] = 1;
1455 iq2000_print_operand_punct[')'] = 1;
1456 iq2000_print_operand_punct['['] = 1;
1457 iq2000_print_operand_punct[']'] = 1;
1458 iq2000_print_operand_punct['<'] = 1;
1459 iq2000_print_operand_punct['>'] = 1;
1460 iq2000_print_operand_punct['{'] = 1;
1461 iq2000_print_operand_punct['}'] = 1;
1462 iq2000_print_operand_punct['^'] = 1;
1463 iq2000_print_operand_punct['$'] = 1;
1464 iq2000_print_operand_punct['+'] = 1;
1465 iq2000_print_operand_punct['~'] = 1;
1467 /* Save GPR registers in word_mode sized hunks. word_mode hasn't been
1468 initialized yet, so we can't use that here. */
1471 /* Function to allocate machine-dependent function status. */
1472 init_machine_status = iq2000_init_machine_status;
1475 /* The arg pointer (which is eliminated) points to the virtual frame pointer,
1476 while the frame pointer (which may be eliminated) points to the stack
1477 pointer after the initial adjustments. */
1480 iq2000_debugger_offset (rtx addr, HOST_WIDE_INT offset)
1482 rtx offset2 = const0_rtx;
1483 rtx reg = eliminate_constant_term (addr, & offset2);
1486 offset = INTVAL (offset2);
1488 if (reg == stack_pointer_rtx || reg == frame_pointer_rtx
1489 || reg == hard_frame_pointer_rtx)
1491 HOST_WIDE_INT frame_size = (!cfun->machine->initialized)
1492 ? compute_frame_size (get_frame_size ())
1493 : cfun->machine->total_size;
1495 offset = offset - frame_size;
1501 /* If defined, a C statement to be executed just prior to the output of
1502 assembler code for INSN, to modify the extracted operands so they will be
1505 Here the argument OPVEC is the vector containing the operands extracted
1506 from INSN, and NOPERANDS is the number of elements of the vector which
1507 contain meaningful data for this insn. The contents of this vector are
1508 what will be used to convert the insn template into assembler code, so you
1509 can change the assembler output by changing the contents of the vector.
1511 We use it to check if the current insn needs a nop in front of it because
1512 of load delays, and also to update the delay slot statistics. */
1515 final_prescan_insn (rtx insn, rtx opvec[] ATTRIBUTE_UNUSED,
1516 int noperands ATTRIBUTE_UNUSED)
1518 if (dslots_number_nops > 0)
1520 rtx pattern = PATTERN (insn);
1521 int length = get_attr_length (insn);
1523 /* Do we need to emit a NOP? */
1525 || (iq2000_load_reg != 0 && reg_mentioned_p (iq2000_load_reg, pattern))
1526 || (iq2000_load_reg2 != 0 && reg_mentioned_p (iq2000_load_reg2, pattern))
1527 || (iq2000_load_reg3 != 0 && reg_mentioned_p (iq2000_load_reg3, pattern))
1528 || (iq2000_load_reg4 != 0
1529 && reg_mentioned_p (iq2000_load_reg4, pattern)))
1530 fputs ("\tnop\n", asm_out_file);
1533 dslots_load_filled ++;
1535 while (--dslots_number_nops > 0)
1536 fputs ("\tnop\n", asm_out_file);
1538 iq2000_load_reg = 0;
1539 iq2000_load_reg2 = 0;
1540 iq2000_load_reg3 = 0;
1541 iq2000_load_reg4 = 0;
1544 if ( (GET_CODE (insn) == JUMP_INSN
1545 || GET_CODE (insn) == CALL_INSN
1546 || (GET_CODE (PATTERN (insn)) == RETURN))
1547 && NEXT_INSN (PREV_INSN (insn)) == insn)
1549 rtx nop_insn = emit_insn_after (gen_nop (), insn);
1551 INSN_ADDRESSES_NEW (nop_insn, -1);
1555 && (GET_CODE (insn) == JUMP_INSN || GET_CODE (insn) == CALL_INSN))
1556 dslots_jump_total ++;
1559 /* Return the bytes needed to compute the frame pointer from the current
1560 stack pointer where SIZE is the # of var. bytes allocated.
1562 IQ2000 stack frames look like:
1564 Before call After call
1565 +-----------------------+ +-----------------------+
1568 | caller's temps. | | caller's temps. |
1570 +-----------------------+ +-----------------------+
1572 | arguments on stack. | | arguments on stack. |
1574 +-----------------------+ +-----------------------+
1575 | 4 words to save | | 4 words to save |
1576 | arguments passed | | arguments passed |
1577 | in registers, even | | in registers, even |
1578 SP->| if not passed. | VFP->| if not passed. |
1579 +-----------------------+ +-----------------------+
1581 | fp register save |
1583 +-----------------------+
1585 | gp register save |
1587 +-----------------------+
1591 +-----------------------+
1593 | alloca allocations |
1595 +-----------------------+
1597 | GP save for V.4 abi |
1599 +-----------------------+
1601 | arguments on stack |
1603 +-----------------------+
1605 | arguments passed |
1606 | in registers, even |
1607 low SP->| if not passed. |
1608 memory +-----------------------+ */
1611 compute_frame_size (HOST_WIDE_INT size)
1614 HOST_WIDE_INT total_size; /* # bytes that the entire frame takes up. */
1615 HOST_WIDE_INT var_size; /* # bytes that variables take up. */
1616 HOST_WIDE_INT args_size; /* # bytes that outgoing arguments take up. */
1617 HOST_WIDE_INT extra_size; /* # extra bytes. */
1618 HOST_WIDE_INT gp_reg_rounded; /* # bytes needed to store gp after rounding. */
1619 HOST_WIDE_INT gp_reg_size; /* # bytes needed to store gp regs. */
1620 HOST_WIDE_INT fp_reg_size; /* # bytes needed to store fp regs. */
1621 long mask; /* mask of saved gp registers. */
1622 int fp_inc; /* 1 or 2 depending on the size of fp regs. */
1623 long fp_bits; /* bitmask to use for each fp register. */
1628 extra_size = IQ2000_STACK_ALIGN ((0));
1629 var_size = IQ2000_STACK_ALIGN (size);
1630 args_size = IQ2000_STACK_ALIGN (crtl->outgoing_args_size);
1632 /* If a function dynamically allocates the stack and
1633 has 0 for STACK_DYNAMIC_OFFSET then allocate some stack space. */
1634 if (args_size == 0 && cfun->calls_alloca)
1635 args_size = 4 * UNITS_PER_WORD;
1637 total_size = var_size + args_size + extra_size;
1639 /* Calculate space needed for gp registers. */
1640 for (regno = GP_REG_FIRST; regno <= GP_REG_LAST; regno++)
1642 if (MUST_SAVE_REGISTER (regno))
1644 gp_reg_size += GET_MODE_SIZE (gpr_mode);
1645 mask |= 1L << (regno - GP_REG_FIRST);
1649 /* We need to restore these for the handler. */
1650 if (crtl->calls_eh_return)
1656 regno = EH_RETURN_DATA_REGNO (i);
1657 if (regno == (int) INVALID_REGNUM)
1659 gp_reg_size += GET_MODE_SIZE (gpr_mode);
1660 mask |= 1L << (regno - GP_REG_FIRST);
1666 gp_reg_rounded = IQ2000_STACK_ALIGN (gp_reg_size);
1667 total_size += gp_reg_rounded + IQ2000_STACK_ALIGN (fp_reg_size);
1669 /* The gp reg is caller saved, so there is no need for leaf routines
1670 (total_size == extra_size) to save the gp reg. */
1671 if (total_size == extra_size
1673 total_size = extra_size = 0;
1675 total_size += IQ2000_STACK_ALIGN (crtl->args.pretend_args_size);
1677 /* Save other computed information. */
1678 cfun->machine->total_size = total_size;
1679 cfun->machine->var_size = var_size;
1680 cfun->machine->args_size = args_size;
1681 cfun->machine->extra_size = extra_size;
1682 cfun->machine->gp_reg_size = gp_reg_size;
1683 cfun->machine->fp_reg_size = fp_reg_size;
1684 cfun->machine->mask = mask;
1685 cfun->machine->initialized = reload_completed;
1686 cfun->machine->num_gp = gp_reg_size / UNITS_PER_WORD;
1690 unsigned long offset;
1692 offset = (args_size + extra_size + var_size
1693 + gp_reg_size - GET_MODE_SIZE (gpr_mode));
1695 cfun->machine->gp_sp_offset = offset;
1696 cfun->machine->gp_save_offset = offset - total_size;
1700 cfun->machine->gp_sp_offset = 0;
1701 cfun->machine->gp_save_offset = 0;
1704 cfun->machine->fp_sp_offset = 0;
1705 cfun->machine->fp_save_offset = 0;
1707 /* Ok, we're done. */
1711 /* Implement INITIAL_ELIMINATION_OFFSET. FROM is either the frame
1712 pointer, argument pointer, or return address pointer. TO is either
1713 the stack pointer or hard frame pointer. */
1716 iq2000_initial_elimination_offset (int from, int to ATTRIBUTE_UNUSED)
1720 compute_frame_size (get_frame_size ());
1721 if ((from) == FRAME_POINTER_REGNUM)
1723 else if ((from) == ARG_POINTER_REGNUM)
1724 (offset) = (cfun->machine->total_size);
1725 else if ((from) == RETURN_ADDRESS_POINTER_REGNUM)
1727 if (leaf_function_p ())
1729 else (offset) = cfun->machine->gp_sp_offset
1730 + ((UNITS_PER_WORD - (POINTER_SIZE / BITS_PER_UNIT))
1731 * (BYTES_BIG_ENDIAN != 0));
1737 /* Common code to emit the insns (or to write the instructions to a file)
1738 to save/restore registers.
1739 Other parts of the code assume that IQ2000_TEMP1_REGNUM (aka large_reg)
1740 is not modified within save_restore_insns. */
1742 #define BITSET_P(VALUE,BIT) (((VALUE) & (1L << (BIT))) != 0)
1744 /* Emit instructions to load the value (SP + OFFSET) into IQ2000_TEMP2_REGNUM
1745 and return an rtl expression for the register. Write the assembly
1746 instructions directly to FILE if it is not null, otherwise emit them as
1749 This function is a subroutine of save_restore_insns. It is used when
1750 OFFSET is too large to add in a single instruction. */
1753 iq2000_add_large_offset_to_sp (HOST_WIDE_INT offset)
1755 rtx reg = gen_rtx_REG (Pmode, IQ2000_TEMP2_REGNUM);
1756 rtx offset_rtx = GEN_INT (offset);
1758 emit_move_insn (reg, offset_rtx);
1759 emit_insn (gen_addsi3 (reg, reg, stack_pointer_rtx));
1763 /* Make INSN frame related and note that it performs the frame-related
1764 operation DWARF_PATTERN. */
1767 iq2000_annotate_frame_insn (rtx insn, rtx dwarf_pattern)
1769 RTX_FRAME_RELATED_P (insn) = 1;
1770 REG_NOTES (insn) = alloc_EXPR_LIST (REG_FRAME_RELATED_EXPR,
1775 /* Emit a move instruction that stores REG in MEM. Make the instruction
1776 frame related and note that it stores REG at (SP + OFFSET). */
1779 iq2000_emit_frame_related_store (rtx mem, rtx reg, HOST_WIDE_INT offset)
1781 rtx dwarf_address = plus_constant (stack_pointer_rtx, offset);
1782 rtx dwarf_mem = gen_rtx_MEM (GET_MODE (reg), dwarf_address);
1784 iq2000_annotate_frame_insn (emit_move_insn (mem, reg),
1785 gen_rtx_SET (GET_MODE (reg), dwarf_mem, reg));
1788 /* Emit instructions to save/restore registers, as determined by STORE_P. */
1791 save_restore_insns (int store_p)
1793 long mask = cfun->machine->mask;
1796 HOST_WIDE_INT base_offset;
1797 HOST_WIDE_INT gp_offset;
1798 HOST_WIDE_INT end_offset;
1800 gcc_assert (!frame_pointer_needed
1801 || BITSET_P (mask, HARD_FRAME_POINTER_REGNUM - GP_REG_FIRST));
1805 base_reg_rtx = 0, base_offset = 0;
1809 /* Save registers starting from high to low. The debuggers prefer at least
1810 the return register be stored at func+4, and also it allows us not to
1811 need a nop in the epilog if at least one register is reloaded in
1812 addition to return address. */
1814 /* Save GP registers if needed. */
1815 /* Pick which pointer to use as a base register. For small frames, just
1816 use the stack pointer. Otherwise, use a temporary register. Save 2
1817 cycles if the save area is near the end of a large frame, by reusing
1818 the constant created in the prologue/epilogue to adjust the stack
1821 gp_offset = cfun->machine->gp_sp_offset;
1823 = gp_offset - (cfun->machine->gp_reg_size
1824 - GET_MODE_SIZE (gpr_mode));
1826 if (gp_offset < 0 || end_offset < 0)
1828 ("gp_offset (%ld) or end_offset (%ld) is less than zero",
1829 (long) gp_offset, (long) end_offset);
1831 else if (gp_offset < 32768)
1832 base_reg_rtx = stack_pointer_rtx, base_offset = 0;
1836 int reg_save_count = 0;
1838 for (regno = GP_REG_LAST; regno >= GP_REG_FIRST; regno--)
1839 if (BITSET_P (mask, regno - GP_REG_FIRST)) reg_save_count += 1;
1840 base_offset = gp_offset - ((reg_save_count - 1) * 4);
1841 base_reg_rtx = iq2000_add_large_offset_to_sp (base_offset);
1844 for (regno = GP_REG_LAST; regno >= GP_REG_FIRST; regno--)
1846 if (BITSET_P (mask, regno - GP_REG_FIRST))
1850 = gen_rtx_MEM (gpr_mode,
1851 gen_rtx_PLUS (Pmode, base_reg_rtx,
1852 GEN_INT (gp_offset - base_offset)));
1854 reg_rtx = gen_rtx_REG (gpr_mode, regno);
1857 iq2000_emit_frame_related_store (mem_rtx, reg_rtx, gp_offset);
1860 emit_move_insn (reg_rtx, mem_rtx);
1862 gp_offset -= GET_MODE_SIZE (gpr_mode);
1867 /* Expand the prologue into a bunch of separate insns. */
1870 iq2000_expand_prologue (void)
1873 HOST_WIDE_INT tsize;
1874 int last_arg_is_vararg_marker = 0;
1875 tree fndecl = current_function_decl;
1876 tree fntype = TREE_TYPE (fndecl);
1877 tree fnargs = DECL_ARGUMENTS (fndecl);
1882 CUMULATIVE_ARGS args_so_far;
1883 int store_args_on_stack = (iq2000_can_use_return_insn ());
1885 /* If struct value address is treated as the first argument. */
1886 if (aggregate_value_p (DECL_RESULT (fndecl), fndecl)
1887 && !cfun->returns_pcc_struct
1888 && targetm.calls.struct_value_rtx (TREE_TYPE (fndecl), 1) == 0)
1890 tree type = build_pointer_type (fntype);
1891 tree function_result_decl = build_decl (PARM_DECL, NULL_TREE, type);
1893 DECL_ARG_TYPE (function_result_decl) = type;
1894 TREE_CHAIN (function_result_decl) = fnargs;
1895 fnargs = function_result_decl;
1898 /* For arguments passed in registers, find the register number
1899 of the first argument in the variable part of the argument list,
1900 otherwise GP_ARG_LAST+1. Note also if the last argument is
1901 the varargs special argument, and treat it as part of the
1904 This is only needed if store_args_on_stack is true. */
1905 INIT_CUMULATIVE_ARGS (args_so_far, fntype, NULL_RTX, 0, 0);
1906 regno = GP_ARG_FIRST;
1908 for (cur_arg = fnargs; cur_arg != 0; cur_arg = next_arg)
1910 tree passed_type = DECL_ARG_TYPE (cur_arg);
1911 enum machine_mode passed_mode = TYPE_MODE (passed_type);
1914 if (TREE_ADDRESSABLE (passed_type))
1916 passed_type = build_pointer_type (passed_type);
1917 passed_mode = Pmode;
1920 entry_parm = FUNCTION_ARG (args_so_far, passed_mode, passed_type, 1);
1922 FUNCTION_ARG_ADVANCE (args_so_far, passed_mode, passed_type, 1);
1923 next_arg = TREE_CHAIN (cur_arg);
1925 if (entry_parm && store_args_on_stack)
1928 && DECL_NAME (cur_arg)
1929 && ((0 == strcmp (IDENTIFIER_POINTER (DECL_NAME (cur_arg)),
1930 "__builtin_va_alist"))
1931 || (0 == strcmp (IDENTIFIER_POINTER (DECL_NAME (cur_arg)),
1934 last_arg_is_vararg_marker = 1;
1941 gcc_assert (GET_CODE (entry_parm) == REG);
1943 /* Passed in a register, so will get homed automatically. */
1944 if (GET_MODE (entry_parm) == BLKmode)
1945 words = (int_size_in_bytes (passed_type) + 3) / 4;
1947 words = (GET_MODE_SIZE (GET_MODE (entry_parm)) + 3) / 4;
1949 regno = REGNO (entry_parm) + words - 1;
1954 regno = GP_ARG_LAST+1;
1959 /* In order to pass small structures by value in registers we need to
1960 shift the value into the high part of the register.
1961 Function_arg has encoded a PARALLEL rtx, holding a vector of
1962 adjustments to be made as the next_arg_reg variable, so we split up the
1963 insns, and emit them separately. */
1964 next_arg_reg = FUNCTION_ARG (args_so_far, VOIDmode, void_type_node, 1);
1965 if (next_arg_reg != 0 && GET_CODE (next_arg_reg) == PARALLEL)
1967 rtvec adjust = XVEC (next_arg_reg, 0);
1968 int num = GET_NUM_ELEM (adjust);
1970 for (i = 0; i < num; i++)
1974 pattern = RTVEC_ELT (adjust, i);
1975 if (GET_CODE (pattern) != SET
1976 || GET_CODE (SET_SRC (pattern)) != ASHIFT)
1977 abort_with_insn (pattern, "Insn is not a shift");
1978 PUT_CODE (SET_SRC (pattern), ASHIFTRT);
1980 insn = emit_insn (pattern);
1984 tsize = compute_frame_size (get_frame_size ());
1986 /* If this function is a varargs function, store any registers that
1987 would normally hold arguments ($4 - $7) on the stack. */
1988 if (store_args_on_stack
1989 && ((TYPE_ARG_TYPES (fntype) != 0
1990 && (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
1992 || last_arg_is_vararg_marker))
1994 int offset = (regno - GP_ARG_FIRST) * UNITS_PER_WORD;
1995 rtx ptr = stack_pointer_rtx;
1997 for (; regno <= GP_ARG_LAST; regno++)
2000 ptr = gen_rtx_PLUS (Pmode, stack_pointer_rtx, GEN_INT (offset));
2001 emit_move_insn (gen_rtx_MEM (gpr_mode, ptr),
2002 gen_rtx_REG (gpr_mode, regno));
2004 offset += GET_MODE_SIZE (gpr_mode);
2010 rtx tsize_rtx = GEN_INT (tsize);
2011 rtx adjustment_rtx, insn, dwarf_pattern;
2015 adjustment_rtx = gen_rtx_REG (Pmode, IQ2000_TEMP1_REGNUM);
2016 emit_move_insn (adjustment_rtx, tsize_rtx);
2019 adjustment_rtx = tsize_rtx;
2021 insn = emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
2024 dwarf_pattern = gen_rtx_SET (Pmode, stack_pointer_rtx,
2025 plus_constant (stack_pointer_rtx, -tsize));
2027 iq2000_annotate_frame_insn (insn, dwarf_pattern);
2029 save_restore_insns (1);
2031 if (frame_pointer_needed)
2035 insn = emit_insn (gen_movsi (hard_frame_pointer_rtx,
2036 stack_pointer_rtx));
2039 RTX_FRAME_RELATED_P (insn) = 1;
2043 emit_insn (gen_blockage ());
2046 /* Expand the epilogue into a bunch of separate insns. */
2049 iq2000_expand_epilogue (void)
2051 HOST_WIDE_INT tsize = cfun->machine->total_size;
2052 rtx tsize_rtx = GEN_INT (tsize);
2053 rtx tmp_rtx = (rtx)0;
2055 if (iq2000_can_use_return_insn ())
2057 emit_jump_insn (gen_return ());
2063 tmp_rtx = gen_rtx_REG (Pmode, IQ2000_TEMP1_REGNUM);
2064 emit_move_insn (tmp_rtx, tsize_rtx);
2065 tsize_rtx = tmp_rtx;
2070 if (frame_pointer_needed)
2072 emit_insn (gen_blockage ());
2074 emit_insn (gen_movsi (stack_pointer_rtx, hard_frame_pointer_rtx));
2077 save_restore_insns (0);
2079 if (crtl->calls_eh_return)
2081 rtx eh_ofs = EH_RETURN_STACKADJ_RTX;
2082 emit_insn (gen_addsi3 (eh_ofs, eh_ofs, tsize_rtx));
2086 emit_insn (gen_blockage ());
2088 if (tsize != 0 || crtl->calls_eh_return)
2090 emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx,
2095 if (crtl->calls_eh_return)
2097 /* Perform the additional bump for __throw. */
2098 emit_move_insn (gen_rtx_REG (Pmode, HARD_FRAME_POINTER_REGNUM),
2100 emit_use (gen_rtx_REG (Pmode, HARD_FRAME_POINTER_REGNUM));
2101 emit_jump_insn (gen_eh_return_internal ());
2104 emit_jump_insn (gen_return_internal (gen_rtx_REG (Pmode,
2105 GP_REG_FIRST + 31)));
2109 iq2000_expand_eh_return (rtx address)
2111 HOST_WIDE_INT gp_offset = cfun->machine->gp_sp_offset;
2114 scratch = plus_constant (stack_pointer_rtx, gp_offset);
2115 emit_move_insn (gen_rtx_MEM (GET_MODE (address), scratch), address);
2118 /* Return nonzero if this function is known to have a null epilogue.
2119 This allows the optimizer to omit jumps to jumps if no stack
2123 iq2000_can_use_return_insn (void)
2125 if (! reload_completed)
2128 if (df_regs_ever_live_p (31) || profile_flag)
2131 if (cfun->machine->initialized)
2132 return cfun->machine->total_size == 0;
2134 return compute_frame_size (get_frame_size ()) == 0;
2137 /* Returns nonzero if X contains a SYMBOL_REF. */
2140 symbolic_expression_p (rtx x)
2142 if (GET_CODE (x) == SYMBOL_REF)
2145 if (GET_CODE (x) == CONST)
2146 return symbolic_expression_p (XEXP (x, 0));
2149 return symbolic_expression_p (XEXP (x, 0));
2151 if (ARITHMETIC_P (x))
2152 return (symbolic_expression_p (XEXP (x, 0))
2153 || symbolic_expression_p (XEXP (x, 1)));
2158 /* Choose the section to use for the constant rtx expression X that has
2162 iq2000_select_rtx_section (enum machine_mode mode, rtx x ATTRIBUTE_UNUSED,
2163 unsigned HOST_WIDE_INT align)
2165 /* For embedded applications, always put constants in read-only data,
2166 in order to reduce RAM usage. */
2167 return mergeable_constant_section (mode, align, 0);
2170 /* Choose the section to use for DECL. RELOC is true if its value contains
2171 any relocatable expression.
2173 Some of the logic used here needs to be replicated in
2174 ENCODE_SECTION_INFO in iq2000.h so that references to these symbols
2175 are done correctly. */
2178 iq2000_select_section (tree decl, int reloc ATTRIBUTE_UNUSED,
2179 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED)
2181 if (TARGET_EMBEDDED_DATA)
2183 /* For embedded applications, always put an object in read-only data
2184 if possible, in order to reduce RAM usage. */
2185 if ((TREE_CODE (decl) == VAR_DECL
2186 && TREE_READONLY (decl) && !TREE_SIDE_EFFECTS (decl)
2187 && DECL_INITIAL (decl)
2188 && (DECL_INITIAL (decl) == error_mark_node
2189 || TREE_CONSTANT (DECL_INITIAL (decl))))
2190 /* Deal with calls from output_constant_def_contents. */
2191 || TREE_CODE (decl) != VAR_DECL)
2192 return readonly_data_section;
2194 return data_section;
2198 /* For hosted applications, always put an object in small data if
2199 possible, as this gives the best performance. */
2200 if ((TREE_CODE (decl) == VAR_DECL
2201 && TREE_READONLY (decl) && !TREE_SIDE_EFFECTS (decl)
2202 && DECL_INITIAL (decl)
2203 && (DECL_INITIAL (decl) == error_mark_node
2204 || TREE_CONSTANT (DECL_INITIAL (decl))))
2205 /* Deal with calls from output_constant_def_contents. */
2206 || TREE_CODE (decl) != VAR_DECL)
2207 return readonly_data_section;
2209 return data_section;
2212 /* Return register to use for a function return value with VALTYPE for function
2216 iq2000_function_value (const_tree valtype, const_tree func ATTRIBUTE_UNUSED)
2218 int reg = GP_RETURN;
2219 enum machine_mode mode = TYPE_MODE (valtype);
2220 int unsignedp = TYPE_UNSIGNED (valtype);
2222 /* Since we define TARGET_PROMOTE_FUNCTION_RETURN that returns true,
2223 we must promote the mode just as PROMOTE_MODE does. */
2224 mode = promote_mode (valtype, mode, &unsignedp, 1);
2226 return gen_rtx_REG (mode, reg);
2229 /* Return true when an argument must be passed by reference. */
2232 iq2000_pass_by_reference (CUMULATIVE_ARGS *cum, enum machine_mode mode,
2233 const_tree type, bool named ATTRIBUTE_UNUSED)
2237 /* We must pass by reference if we would be both passing in registers
2238 and the stack. This is because any subsequent partial arg would be
2239 handled incorrectly in this case. */
2240 if (cum && targetm.calls.must_pass_in_stack (mode, type))
2242 /* Don't pass the actual CUM to FUNCTION_ARG, because we would
2243 get double copies of any offsets generated for small structs
2244 passed in registers. */
2245 CUMULATIVE_ARGS temp;
2248 if (FUNCTION_ARG (temp, mode, type, named) != 0)
2252 if (type == NULL_TREE || mode == DImode || mode == DFmode)
2255 size = int_size_in_bytes (type);
2256 return size == -1 || size > UNITS_PER_WORD;
2259 /* Return the length of INSN. LENGTH is the initial length computed by
2260 attributes in the machine-description file. */
2263 iq2000_adjust_insn_length (rtx insn, int length)
2265 /* A unconditional jump has an unfilled delay slot if it is not part
2266 of a sequence. A conditional jump normally has a delay slot. */
2267 if (simplejump_p (insn)
2268 || ( (GET_CODE (insn) == JUMP_INSN
2269 || GET_CODE (insn) == CALL_INSN)))
2275 /* Output assembly instructions to perform a conditional branch.
2277 INSN is the branch instruction. OPERANDS[0] is the condition.
2278 OPERANDS[1] is the target of the branch. OPERANDS[2] is the target
2279 of the first operand to the condition. If TWO_OPERANDS_P is
2280 nonzero the comparison takes two operands; OPERANDS[3] will be the
2283 If INVERTED_P is nonzero we are to branch if the condition does
2284 not hold. If FLOAT_P is nonzero this is a floating-point comparison.
2286 LENGTH is the length (in bytes) of the sequence we are to generate.
2287 That tells us whether to generate a simple conditional branch, or a
2288 reversed conditional branch around a `jr' instruction. */
2291 iq2000_output_conditional_branch (rtx insn, rtx * operands, int two_operands_p,
2292 int float_p, int inverted_p, int length)
2294 static char buffer[200];
2295 /* The kind of comparison we are doing. */
2296 enum rtx_code code = GET_CODE (operands[0]);
2297 /* Nonzero if the opcode for the comparison needs a `z' indicating
2298 that it is a comparison against zero. */
2300 /* A string to use in the assembly output to represent the first
2302 const char *op1 = "%z2";
2303 /* A string to use in the assembly output to represent the second
2304 operand. Use the hard-wired zero register if there's no second
2306 const char *op2 = (two_operands_p ? ",%z3" : ",%.");
2307 /* The operand-printing string for the comparison. */
2308 const char *comp = (float_p ? "%F0" : "%C0");
2309 /* The operand-printing string for the inverted comparison. */
2310 const char *inverted_comp = (float_p ? "%W0" : "%N0");
2312 /* Likely variants of each branch instruction annul the instruction
2313 in the delay slot if the branch is not taken. */
2314 iq2000_branch_likely = (final_sequence && INSN_ANNULLED_BRANCH_P (insn));
2316 if (!two_operands_p)
2318 /* To compute whether than A > B, for example, we normally
2319 subtract B from A and then look at the sign bit. But, if we
2320 are doing an unsigned comparison, and B is zero, we don't
2321 have to do the subtraction. Instead, we can just check to
2322 see if A is nonzero. Thus, we change the CODE here to
2323 reflect the simpler comparison operation. */
2335 /* A condition which will always be true. */
2341 /* A condition which will always be false. */
2347 /* Not a special case. */
2352 /* Relative comparisons are always done against zero. But
2353 equality comparisons are done between two operands, and therefore
2354 do not require a `z' in the assembly language output. */
2355 need_z_p = (!float_p && code != EQ && code != NE);
2356 /* For comparisons against zero, the zero is not provided
2361 /* Begin by terminating the buffer. That way we can always use
2362 strcat to add to it. */
2369 /* Just a simple conditional branch. */
2371 sprintf (buffer, "b%s%%?\t%%Z2%%1",
2372 inverted_p ? inverted_comp : comp);
2374 sprintf (buffer, "b%s%s%%?\t%s%s,%%1",
2375 inverted_p ? inverted_comp : comp,
2376 need_z_p ? "z" : "",
2384 /* Generate a reversed conditional branch around ` j'
2396 Because we have to jump four bytes *past* the following
2397 instruction if this branch was annulled, we can't just use
2398 a label, as in the picture above; there's no way to put the
2399 label after the next instruction, as the assembler does not
2400 accept `.L+4' as the target of a branch. (We can't just
2401 wait until the next instruction is output; it might be a
2402 macro and take up more than four bytes. Once again, we see
2403 why we want to eliminate macros.)
2405 If the branch is annulled, we jump four more bytes that we
2406 would otherwise; that way we skip the annulled instruction
2407 in the delay slot. */
2410 = ((iq2000_branch_likely || length == 16) ? ".+16" : ".+12");
2413 c = strchr (buffer, '\0');
2414 /* Generate the reversed comparison. This takes four
2417 sprintf (c, "b%s\t%%Z2%s",
2418 inverted_p ? comp : inverted_comp,
2421 sprintf (c, "b%s%s\t%s%s,%s",
2422 inverted_p ? comp : inverted_comp,
2423 need_z_p ? "z" : "",
2427 strcat (c, "\n\tnop\n\tj\t%1");
2429 /* The delay slot was unfilled. Since we're inside
2430 .noreorder, the assembler will not fill in the NOP for
2431 us, so we must do it ourselves. */
2432 strcat (buffer, "\n\tnop");
2444 #define def_builtin(NAME, TYPE, CODE) \
2445 add_builtin_function ((NAME), (TYPE), (CODE), BUILT_IN_MD, \
2449 iq2000_init_builtins (void)
2451 tree endlink = void_list_node;
2452 tree void_ftype, void_ftype_int, void_ftype_int_int;
2453 tree void_ftype_int_int_int;
2454 tree int_ftype_int, int_ftype_int_int, int_ftype_int_int_int;
2455 tree int_ftype_int_int_int_int;
2459 = build_function_type (void_type_node,
2460 tree_cons (NULL_TREE, void_type_node, endlink));
2464 = build_function_type (void_type_node,
2465 tree_cons (NULL_TREE, integer_type_node, endlink));
2467 /* void func (int, int) */
2469 = build_function_type (void_type_node,
2470 tree_cons (NULL_TREE, integer_type_node,
2471 tree_cons (NULL_TREE, integer_type_node,
2474 /* int func (int) */
2476 = build_function_type (integer_type_node,
2477 tree_cons (NULL_TREE, integer_type_node, endlink));
2479 /* int func (int, int) */
2481 = build_function_type (integer_type_node,
2482 tree_cons (NULL_TREE, integer_type_node,
2483 tree_cons (NULL_TREE, integer_type_node,
2486 /* void func (int, int, int) */
2487 void_ftype_int_int_int
2488 = build_function_type
2490 tree_cons (NULL_TREE, integer_type_node,
2491 tree_cons (NULL_TREE, integer_type_node,
2492 tree_cons (NULL_TREE,
2496 /* int func (int, int, int, int) */
2497 int_ftype_int_int_int_int
2498 = build_function_type
2500 tree_cons (NULL_TREE, integer_type_node,
2501 tree_cons (NULL_TREE, integer_type_node,
2502 tree_cons (NULL_TREE,
2504 tree_cons (NULL_TREE,
2508 /* int func (int, int, int) */
2509 int_ftype_int_int_int
2510 = build_function_type
2512 tree_cons (NULL_TREE, integer_type_node,
2513 tree_cons (NULL_TREE, integer_type_node,
2514 tree_cons (NULL_TREE,
2518 /* int func (int, int, int, int) */
2519 int_ftype_int_int_int_int
2520 = build_function_type
2522 tree_cons (NULL_TREE, integer_type_node,
2523 tree_cons (NULL_TREE, integer_type_node,
2524 tree_cons (NULL_TREE,
2526 tree_cons (NULL_TREE,
2530 def_builtin ("__builtin_ado16", int_ftype_int_int, IQ2000_BUILTIN_ADO16);
2531 def_builtin ("__builtin_ram", int_ftype_int_int_int_int, IQ2000_BUILTIN_RAM);
2532 def_builtin ("__builtin_chkhdr", void_ftype_int_int, IQ2000_BUILTIN_CHKHDR);
2533 def_builtin ("__builtin_pkrl", void_ftype_int_int, IQ2000_BUILTIN_PKRL);
2534 def_builtin ("__builtin_cfc0", int_ftype_int, IQ2000_BUILTIN_CFC0);
2535 def_builtin ("__builtin_cfc1", int_ftype_int, IQ2000_BUILTIN_CFC1);
2536 def_builtin ("__builtin_cfc2", int_ftype_int, IQ2000_BUILTIN_CFC2);
2537 def_builtin ("__builtin_cfc3", int_ftype_int, IQ2000_BUILTIN_CFC3);
2538 def_builtin ("__builtin_ctc0", void_ftype_int_int, IQ2000_BUILTIN_CTC0);
2539 def_builtin ("__builtin_ctc1", void_ftype_int_int, IQ2000_BUILTIN_CTC1);
2540 def_builtin ("__builtin_ctc2", void_ftype_int_int, IQ2000_BUILTIN_CTC2);
2541 def_builtin ("__builtin_ctc3", void_ftype_int_int, IQ2000_BUILTIN_CTC3);
2542 def_builtin ("__builtin_mfc0", int_ftype_int, IQ2000_BUILTIN_MFC0);
2543 def_builtin ("__builtin_mfc1", int_ftype_int, IQ2000_BUILTIN_MFC1);
2544 def_builtin ("__builtin_mfc2", int_ftype_int, IQ2000_BUILTIN_MFC2);
2545 def_builtin ("__builtin_mfc3", int_ftype_int, IQ2000_BUILTIN_MFC3);
2546 def_builtin ("__builtin_mtc0", void_ftype_int_int, IQ2000_BUILTIN_MTC0);
2547 def_builtin ("__builtin_mtc1", void_ftype_int_int, IQ2000_BUILTIN_MTC1);
2548 def_builtin ("__builtin_mtc2", void_ftype_int_int, IQ2000_BUILTIN_MTC2);
2549 def_builtin ("__builtin_mtc3", void_ftype_int_int, IQ2000_BUILTIN_MTC3);
2550 def_builtin ("__builtin_lur", void_ftype_int_int, IQ2000_BUILTIN_LUR);
2551 def_builtin ("__builtin_rb", void_ftype_int_int, IQ2000_BUILTIN_RB);
2552 def_builtin ("__builtin_rx", void_ftype_int_int, IQ2000_BUILTIN_RX);
2553 def_builtin ("__builtin_srrd", void_ftype_int, IQ2000_BUILTIN_SRRD);
2554 def_builtin ("__builtin_srwr", void_ftype_int_int, IQ2000_BUILTIN_SRWR);
2555 def_builtin ("__builtin_wb", void_ftype_int_int, IQ2000_BUILTIN_WB);
2556 def_builtin ("__builtin_wx", void_ftype_int_int, IQ2000_BUILTIN_WX);
2557 def_builtin ("__builtin_luc32l", void_ftype_int_int, IQ2000_BUILTIN_LUC32L);
2558 def_builtin ("__builtin_luc64", void_ftype_int_int, IQ2000_BUILTIN_LUC64);
2559 def_builtin ("__builtin_luc64l", void_ftype_int_int, IQ2000_BUILTIN_LUC64L);
2560 def_builtin ("__builtin_luk", void_ftype_int_int, IQ2000_BUILTIN_LUK);
2561 def_builtin ("__builtin_lulck", void_ftype_int, IQ2000_BUILTIN_LULCK);
2562 def_builtin ("__builtin_lum32", void_ftype_int_int, IQ2000_BUILTIN_LUM32);
2563 def_builtin ("__builtin_lum32l", void_ftype_int_int, IQ2000_BUILTIN_LUM32L);
2564 def_builtin ("__builtin_lum64", void_ftype_int_int, IQ2000_BUILTIN_LUM64);
2565 def_builtin ("__builtin_lum64l", void_ftype_int_int, IQ2000_BUILTIN_LUM64L);
2566 def_builtin ("__builtin_lurl", void_ftype_int_int, IQ2000_BUILTIN_LURL);
2567 def_builtin ("__builtin_mrgb", int_ftype_int_int_int, IQ2000_BUILTIN_MRGB);
2568 def_builtin ("__builtin_srrdl", void_ftype_int, IQ2000_BUILTIN_SRRDL);
2569 def_builtin ("__builtin_srulck", void_ftype_int, IQ2000_BUILTIN_SRULCK);
2570 def_builtin ("__builtin_srwru", void_ftype_int_int, IQ2000_BUILTIN_SRWRU);
2571 def_builtin ("__builtin_trapqfl", void_ftype, IQ2000_BUILTIN_TRAPQFL);
2572 def_builtin ("__builtin_trapqne", void_ftype, IQ2000_BUILTIN_TRAPQNE);
2573 def_builtin ("__builtin_traprel", void_ftype_int, IQ2000_BUILTIN_TRAPREL);
2574 def_builtin ("__builtin_wbu", void_ftype_int_int_int, IQ2000_BUILTIN_WBU);
2575 def_builtin ("__builtin_syscall", void_ftype, IQ2000_BUILTIN_SYSCALL);
2578 /* Builtin for ICODE having ARGCOUNT args in EXP where each arg
2582 expand_one_builtin (enum insn_code icode, rtx target, tree exp,
2583 enum rtx_code *code, int argcount)
2588 enum machine_mode mode [5];
2591 mode[0] = insn_data[icode].operand[0].mode;
2592 for (i = 0; i < argcount; i++)
2594 arg[i] = CALL_EXPR_ARG (exp, i);
2595 op[i] = expand_expr (arg[i], NULL_RTX, VOIDmode, 0);
2596 mode[i] = insn_data[icode].operand[i].mode;
2597 if (code[i] == CONST_INT && GET_CODE (op[i]) != CONST_INT)
2598 error ("argument %qd is not a constant", i + 1);
2600 && ! (*insn_data[icode].operand[i].predicate) (op[i], mode[i]))
2601 op[i] = copy_to_mode_reg (mode[i], op[i]);
2604 if (insn_data[icode].operand[0].constraint[0] == '=')
2607 || GET_MODE (target) != mode[0]
2608 || ! (*insn_data[icode].operand[0].predicate) (target, mode[0]))
2609 target = gen_reg_rtx (mode[0]);
2617 pat = GEN_FCN (icode) (target);
2620 pat = GEN_FCN (icode) (target, op[0]);
2622 pat = GEN_FCN (icode) (op[0]);
2626 pat = GEN_FCN (icode) (target, op[0], op[1]);
2628 pat = GEN_FCN (icode) (op[0], op[1]);
2632 pat = GEN_FCN (icode) (target, op[0], op[1], op[2]);
2634 pat = GEN_FCN (icode) (op[0], op[1], op[2]);
2638 pat = GEN_FCN (icode) (target, op[0], op[1], op[2], op[3]);
2640 pat = GEN_FCN (icode) (op[0], op[1], op[2], op[3]);
2652 /* Expand an expression EXP that calls a built-in function,
2653 with result going to TARGET if that's convenient
2654 (and in mode MODE if that's convenient).
2655 SUBTARGET may be used as the target for computing one of EXP's operands.
2656 IGNORE is nonzero if the value is to be ignored. */
2659 iq2000_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED,
2660 enum machine_mode mode ATTRIBUTE_UNUSED,
2661 int ignore ATTRIBUTE_UNUSED)
2663 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
2664 int fcode = DECL_FUNCTION_CODE (fndecl);
2665 enum rtx_code code [5];
2677 case IQ2000_BUILTIN_ADO16:
2678 return expand_one_builtin (CODE_FOR_ado16, target, exp, code, 2);
2680 case IQ2000_BUILTIN_RAM:
2681 code[1] = CONST_INT;
2682 code[2] = CONST_INT;
2683 code[3] = CONST_INT;
2684 return expand_one_builtin (CODE_FOR_ram, target, exp, code, 4);
2686 case IQ2000_BUILTIN_CHKHDR:
2687 return expand_one_builtin (CODE_FOR_chkhdr, target, exp, code, 2);
2689 case IQ2000_BUILTIN_PKRL:
2690 return expand_one_builtin (CODE_FOR_pkrl, target, exp, code, 2);
2692 case IQ2000_BUILTIN_CFC0:
2693 code[0] = CONST_INT;
2694 return expand_one_builtin (CODE_FOR_cfc0, target, exp, code, 1);
2696 case IQ2000_BUILTIN_CFC1:
2697 code[0] = CONST_INT;
2698 return expand_one_builtin (CODE_FOR_cfc1, target, exp, code, 1);
2700 case IQ2000_BUILTIN_CFC2:
2701 code[0] = CONST_INT;
2702 return expand_one_builtin (CODE_FOR_cfc2, target, exp, code, 1);
2704 case IQ2000_BUILTIN_CFC3:
2705 code[0] = CONST_INT;
2706 return expand_one_builtin (CODE_FOR_cfc3, target, exp, code, 1);
2708 case IQ2000_BUILTIN_CTC0:
2709 code[1] = CONST_INT;
2710 return expand_one_builtin (CODE_FOR_ctc0, target, exp, code, 2);
2712 case IQ2000_BUILTIN_CTC1:
2713 code[1] = CONST_INT;
2714 return expand_one_builtin (CODE_FOR_ctc1, target, exp, code, 2);
2716 case IQ2000_BUILTIN_CTC2:
2717 code[1] = CONST_INT;
2718 return expand_one_builtin (CODE_FOR_ctc2, target, exp, code, 2);
2720 case IQ2000_BUILTIN_CTC3:
2721 code[1] = CONST_INT;
2722 return expand_one_builtin (CODE_FOR_ctc3, target, exp, code, 2);
2724 case IQ2000_BUILTIN_MFC0:
2725 code[0] = CONST_INT;
2726 return expand_one_builtin (CODE_FOR_mfc0, target, exp, code, 1);
2728 case IQ2000_BUILTIN_MFC1:
2729 code[0] = CONST_INT;
2730 return expand_one_builtin (CODE_FOR_mfc1, target, exp, code, 1);
2732 case IQ2000_BUILTIN_MFC2:
2733 code[0] = CONST_INT;
2734 return expand_one_builtin (CODE_FOR_mfc2, target, exp, code, 1);
2736 case IQ2000_BUILTIN_MFC3:
2737 code[0] = CONST_INT;
2738 return expand_one_builtin (CODE_FOR_mfc3, target, exp, code, 1);
2740 case IQ2000_BUILTIN_MTC0:
2741 code[1] = CONST_INT;
2742 return expand_one_builtin (CODE_FOR_mtc0, target, exp, code, 2);
2744 case IQ2000_BUILTIN_MTC1:
2745 code[1] = CONST_INT;
2746 return expand_one_builtin (CODE_FOR_mtc1, target, exp, code, 2);
2748 case IQ2000_BUILTIN_MTC2:
2749 code[1] = CONST_INT;
2750 return expand_one_builtin (CODE_FOR_mtc2, target, exp, code, 2);
2752 case IQ2000_BUILTIN_MTC3:
2753 code[1] = CONST_INT;
2754 return expand_one_builtin (CODE_FOR_mtc3, target, exp, code, 2);
2756 case IQ2000_BUILTIN_LUR:
2757 return expand_one_builtin (CODE_FOR_lur, target, exp, code, 2);
2759 case IQ2000_BUILTIN_RB:
2760 return expand_one_builtin (CODE_FOR_rb, target, exp, code, 2);
2762 case IQ2000_BUILTIN_RX:
2763 return expand_one_builtin (CODE_FOR_rx, target, exp, code, 2);
2765 case IQ2000_BUILTIN_SRRD:
2766 return expand_one_builtin (CODE_FOR_srrd, target, exp, code, 1);
2768 case IQ2000_BUILTIN_SRWR:
2769 return expand_one_builtin (CODE_FOR_srwr, target, exp, code, 2);
2771 case IQ2000_BUILTIN_WB:
2772 return expand_one_builtin (CODE_FOR_wb, target, exp, code, 2);
2774 case IQ2000_BUILTIN_WX:
2775 return expand_one_builtin (CODE_FOR_wx, target, exp, code, 2);
2777 case IQ2000_BUILTIN_LUC32L:
2778 return expand_one_builtin (CODE_FOR_luc32l, target, exp, code, 2);
2780 case IQ2000_BUILTIN_LUC64:
2781 return expand_one_builtin (CODE_FOR_luc64, target, exp, code, 2);
2783 case IQ2000_BUILTIN_LUC64L:
2784 return expand_one_builtin (CODE_FOR_luc64l, target, exp, code, 2);
2786 case IQ2000_BUILTIN_LUK:
2787 return expand_one_builtin (CODE_FOR_luk, target, exp, code, 2);
2789 case IQ2000_BUILTIN_LULCK:
2790 return expand_one_builtin (CODE_FOR_lulck, target, exp, code, 1);
2792 case IQ2000_BUILTIN_LUM32:
2793 return expand_one_builtin (CODE_FOR_lum32, target, exp, code, 2);
2795 case IQ2000_BUILTIN_LUM32L:
2796 return expand_one_builtin (CODE_FOR_lum32l, target, exp, code, 2);
2798 case IQ2000_BUILTIN_LUM64:
2799 return expand_one_builtin (CODE_FOR_lum64, target, exp, code, 2);
2801 case IQ2000_BUILTIN_LUM64L:
2802 return expand_one_builtin (CODE_FOR_lum64l, target, exp, code, 2);
2804 case IQ2000_BUILTIN_LURL:
2805 return expand_one_builtin (CODE_FOR_lurl, target, exp, code, 2);
2807 case IQ2000_BUILTIN_MRGB:
2808 code[2] = CONST_INT;
2809 return expand_one_builtin (CODE_FOR_mrgb, target, exp, code, 3);
2811 case IQ2000_BUILTIN_SRRDL:
2812 return expand_one_builtin (CODE_FOR_srrdl, target, exp, code, 1);
2814 case IQ2000_BUILTIN_SRULCK:
2815 return expand_one_builtin (CODE_FOR_srulck, target, exp, code, 1);
2817 case IQ2000_BUILTIN_SRWRU:
2818 return expand_one_builtin (CODE_FOR_srwru, target, exp, code, 2);
2820 case IQ2000_BUILTIN_TRAPQFL:
2821 return expand_one_builtin (CODE_FOR_trapqfl, target, exp, code, 0);
2823 case IQ2000_BUILTIN_TRAPQNE:
2824 return expand_one_builtin (CODE_FOR_trapqne, target, exp, code, 0);
2826 case IQ2000_BUILTIN_TRAPREL:
2827 return expand_one_builtin (CODE_FOR_traprel, target, exp, code, 1);
2829 case IQ2000_BUILTIN_WBU:
2830 return expand_one_builtin (CODE_FOR_wbu, target, exp, code, 3);
2832 case IQ2000_BUILTIN_SYSCALL:
2833 return expand_one_builtin (CODE_FOR_syscall, target, exp, code, 0);
2839 /* Worker function for TARGET_RETURN_IN_MEMORY. */
2842 iq2000_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED)
2844 return ((int_size_in_bytes (type) > (2 * UNITS_PER_WORD))
2845 || (int_size_in_bytes (type) == -1));
2848 /* Worker function for TARGET_SETUP_INCOMING_VARARGS. */
2851 iq2000_setup_incoming_varargs (CUMULATIVE_ARGS *cum,
2852 enum machine_mode mode ATTRIBUTE_UNUSED,
2853 tree type ATTRIBUTE_UNUSED, int * pretend_size,
2856 unsigned int iq2000_off = ! cum->last_arg_fp;
2857 unsigned int iq2000_fp_off = cum->last_arg_fp;
2859 if ((cum->arg_words < MAX_ARGS_IN_REGISTERS - iq2000_off))
2861 int iq2000_save_gp_regs
2862 = MAX_ARGS_IN_REGISTERS - cum->arg_words - iq2000_off;
2863 int iq2000_save_fp_regs
2864 = (MAX_ARGS_IN_REGISTERS - cum->fp_arg_words - iq2000_fp_off);
2866 if (iq2000_save_gp_regs < 0)
2867 iq2000_save_gp_regs = 0;
2868 if (iq2000_save_fp_regs < 0)
2869 iq2000_save_fp_regs = 0;
2871 *pretend_size = ((iq2000_save_gp_regs * UNITS_PER_WORD)
2872 + (iq2000_save_fp_regs * UNITS_PER_FPREG));
2876 if (cum->arg_words < MAX_ARGS_IN_REGISTERS - iq2000_off)
2879 ptr = plus_constant (virtual_incoming_args_rtx,
2880 - (iq2000_save_gp_regs
2882 mem = gen_rtx_MEM (BLKmode, ptr);
2884 (cum->arg_words + GP_ARG_FIRST + iq2000_off,
2886 iq2000_save_gp_regs);
2892 /* A C compound statement to output to stdio stream STREAM the
2893 assembler syntax for an instruction operand that is a memory
2894 reference whose address is ADDR. ADDR is an RTL expression. */
2897 print_operand_address (FILE * file, rtx addr)
2900 error ("PRINT_OPERAND_ADDRESS, null pointer");
2903 switch (GET_CODE (addr))
2906 if (REGNO (addr) == ARG_POINTER_REGNUM)
2907 abort_with_insn (addr, "Arg pointer not eliminated.");
2909 fprintf (file, "0(%s)", reg_names [REGNO (addr)]);
2914 rtx arg0 = XEXP (addr, 0);
2915 rtx arg1 = XEXP (addr, 1);
2917 if (GET_CODE (arg0) != REG)
2918 abort_with_insn (addr,
2919 "PRINT_OPERAND_ADDRESS, LO_SUM with #1 not REG.");
2921 fprintf (file, "%%lo(");
2922 print_operand_address (file, arg1);
2923 fprintf (file, ")(%s)", reg_names [REGNO (arg0)]);
2931 rtx arg0 = XEXP (addr, 0);
2932 rtx arg1 = XEXP (addr, 1);
2934 if (GET_CODE (arg0) == REG)
2938 if (GET_CODE (offset) == REG)
2939 abort_with_insn (addr, "PRINT_OPERAND_ADDRESS, 2 regs");
2942 else if (GET_CODE (arg1) == REG)
2943 reg = arg1, offset = arg0;
2944 else if (CONSTANT_P (arg0) && CONSTANT_P (arg1))
2946 output_addr_const (file, addr);
2950 abort_with_insn (addr, "PRINT_OPERAND_ADDRESS, no regs");
2952 if (! CONSTANT_P (offset))
2953 abort_with_insn (addr, "PRINT_OPERAND_ADDRESS, invalid insn #2");
2955 if (REGNO (reg) == ARG_POINTER_REGNUM)
2956 abort_with_insn (addr, "Arg pointer not eliminated.");
2958 output_addr_const (file, offset);
2959 fprintf (file, "(%s)", reg_names [REGNO (reg)]);
2967 output_addr_const (file, addr);
2968 if (GET_CODE (addr) == CONST_INT)
2969 fprintf (file, "(%s)", reg_names [0]);
2973 abort_with_insn (addr, "PRINT_OPERAND_ADDRESS, invalid insn #1");
2978 /* A C compound statement to output to stdio stream FILE the
2979 assembler syntax for an instruction operand OP.
2981 LETTER is a value that can be used to specify one of several ways
2982 of printing the operand. It is used when identical operands
2983 must be printed differently depending on the context. LETTER
2984 comes from the `%' specification that was used to request
2985 printing of the operand. If the specification was just `%DIGIT'
2986 then LETTER is 0; if the specification was `%LTR DIGIT' then LETTER
2987 is the ASCII code for LTR.
2989 If OP is a register, this macro should print the register's name.
2990 The names can be found in an array `reg_names' whose type is
2991 `char *[]'. `reg_names' is initialized from `REGISTER_NAMES'.
2993 When the machine description has a specification `%PUNCT' (a `%'
2994 followed by a punctuation character), this macro is called with
2995 a null pointer for X and the punctuation character for LETTER.
2997 The IQ2000 specific codes are:
2999 'X' X is CONST_INT, prints upper 16 bits in hexadecimal format = "0x%04x",
3000 'x' X is CONST_INT, prints lower 16 bits in hexadecimal format = "0x%04x",
3001 'd' output integer constant in decimal,
3002 'z' if the operand is 0, use $0 instead of normal operand.
3003 'D' print second part of double-word register or memory operand.
3004 'L' print low-order register of double-word register operand.
3005 'M' print high-order register of double-word register operand.
3006 'C' print part of opcode for a branch condition.
3007 'F' print part of opcode for a floating-point branch condition.
3008 'N' print part of opcode for a branch condition, inverted.
3009 'W' print part of opcode for a floating-point branch condition, inverted.
3010 'A' Print part of opcode for a bit test condition.
3011 'P' Print label for a bit test.
3012 'p' Print log for a bit test.
3013 'B' print 'z' for EQ, 'n' for NE
3014 'b' print 'n' for EQ, 'z' for NE
3015 'T' print 'f' for EQ, 't' for NE
3016 't' print 't' for EQ, 'f' for NE
3017 'Z' print register and a comma, but print nothing for $fcc0
3018 '?' Print 'l' if we are to use a branch likely instead of normal branch.
3019 '@' Print the name of the assembler temporary register (at or $1).
3020 '.' Print the name of the register with a hard-wired zero (zero or $0).
3021 '$' Print the name of the stack pointer register (sp or $29).
3022 '+' Print the name of the gp register (gp or $28). */
3025 print_operand (FILE *file, rtx op, int letter)
3029 if (PRINT_OPERAND_PUNCT_VALID_P (letter))
3034 if (iq2000_branch_likely)
3039 fputs (reg_names [GP_REG_FIRST + 1], file);
3043 fputs (reg_names [GP_REG_FIRST + 0], file);
3047 fputs (reg_names[STACK_POINTER_REGNUM], file);
3051 fputs (reg_names[GP_REG_FIRST + 28], file);
3055 error ("PRINT_OPERAND: Unknown punctuation '%c'", letter);
3064 error ("PRINT_OPERAND null pointer");
3068 code = GET_CODE (op);
3070 if (code == SIGN_EXTEND)
3071 op = XEXP (op, 0), code = GET_CODE (op);
3076 case EQ: fputs ("eq", file); break;
3077 case NE: fputs ("ne", file); break;
3078 case GT: fputs ("gt", file); break;
3079 case GE: fputs ("ge", file); break;
3080 case LT: fputs ("lt", file); break;
3081 case LE: fputs ("le", file); break;
3082 case GTU: fputs ("ne", file); break;
3083 case GEU: fputs ("geu", file); break;
3084 case LTU: fputs ("ltu", file); break;
3085 case LEU: fputs ("eq", file); break;
3087 abort_with_insn (op, "PRINT_OPERAND, invalid insn for %%C");
3090 else if (letter == 'N')
3093 case EQ: fputs ("ne", file); break;
3094 case NE: fputs ("eq", file); break;
3095 case GT: fputs ("le", file); break;
3096 case GE: fputs ("lt", file); break;
3097 case LT: fputs ("ge", file); break;
3098 case LE: fputs ("gt", file); break;
3099 case GTU: fputs ("leu", file); break;
3100 case GEU: fputs ("ltu", file); break;
3101 case LTU: fputs ("geu", file); break;
3102 case LEU: fputs ("gtu", file); break;
3104 abort_with_insn (op, "PRINT_OPERAND, invalid insn for %%N");
3107 else if (letter == 'F')
3110 case EQ: fputs ("c1f", file); break;
3111 case NE: fputs ("c1t", file); break;
3113 abort_with_insn (op, "PRINT_OPERAND, invalid insn for %%F");
3116 else if (letter == 'W')
3119 case EQ: fputs ("c1t", file); break;
3120 case NE: fputs ("c1f", file); break;
3122 abort_with_insn (op, "PRINT_OPERAND, invalid insn for %%W");
3125 else if (letter == 'A')
3126 fputs (code == LABEL_REF ? "i" : "in", file);
3128 else if (letter == 'P')
3130 if (code == LABEL_REF)
3131 output_addr_const (file, op);
3132 else if (code != PC)
3133 output_operand_lossage ("invalid %%P operand");
3136 else if (letter == 'p')
3139 if (code != CONST_INT
3140 || (value = exact_log2 (INTVAL (op))) < 0)
3141 output_operand_lossage ("invalid %%p value");
3142 fprintf (file, "%d", value);
3145 else if (letter == 'Z')
3150 else if (code == REG || code == SUBREG)
3155 regnum = REGNO (op);
3157 regnum = true_regnum (op);
3159 if ((letter == 'M' && ! WORDS_BIG_ENDIAN)
3160 || (letter == 'L' && WORDS_BIG_ENDIAN)
3164 fprintf (file, "%s", reg_names[regnum]);
3167 else if (code == MEM)
3170 output_address (plus_constant (XEXP (op, 0), 4));
3172 output_address (XEXP (op, 0));
3175 else if (code == CONST_DOUBLE
3176 && GET_MODE_CLASS (GET_MODE (op)) == MODE_FLOAT)
3180 real_to_decimal (s, CONST_DOUBLE_REAL_VALUE (op), sizeof (s), 0, 1);
3184 else if (letter == 'x' && GET_CODE (op) == CONST_INT)
3185 fprintf (file, HOST_WIDE_INT_PRINT_HEX, 0xffff & INTVAL(op));
3187 else if (letter == 'X' && GET_CODE(op) == CONST_INT)
3188 fprintf (file, HOST_WIDE_INT_PRINT_HEX, 0xffff & (INTVAL (op) >> 16));
3190 else if (letter == 'd' && GET_CODE(op) == CONST_INT)
3191 fprintf (file, HOST_WIDE_INT_PRINT_DEC, (INTVAL(op)));
3193 else if (letter == 'z' && GET_CODE (op) == CONST_INT && INTVAL (op) == 0)
3194 fputs (reg_names[GP_REG_FIRST], file);
3196 else if (letter == 'd' || letter == 'x' || letter == 'X')
3197 output_operand_lossage ("invalid use of %%d, %%x, or %%X");
3199 else if (letter == 'B')
3200 fputs (code == EQ ? "z" : "n", file);
3201 else if (letter == 'b')
3202 fputs (code == EQ ? "n" : "z", file);
3203 else if (letter == 'T')
3204 fputs (code == EQ ? "f" : "t", file);
3205 else if (letter == 't')
3206 fputs (code == EQ ? "t" : "f", file);
3208 else if (code == CONST && GET_CODE (XEXP (op, 0)) == REG)
3210 print_operand (file, XEXP (op, 0), letter);
3214 output_addr_const (file, op);
3218 iq2000_rtx_costs (rtx x, int code, int outer_code ATTRIBUTE_UNUSED, int * total,
3219 bool speed ATTRIBUTE_UNUSED)
3221 enum machine_mode mode = GET_MODE (x);
3227 int num_words = (GET_MODE_SIZE (mode) > UNITS_PER_WORD) ? 2 : 1;
3229 if (simple_memory_operand (x, mode))
3230 return COSTS_N_INSNS (num_words);
3232 * total = COSTS_N_INSNS (2 * num_words);
3237 * total = COSTS_N_INSNS (6);
3244 * total = COSTS_N_INSNS (mode == DImode ? 2 : 1);
3251 * total = COSTS_N_INSNS ((GET_CODE (XEXP (x, 1)) == CONST_INT) ? 4 : 12);
3253 * total = COSTS_N_INSNS (1);
3257 if (mode == SFmode || mode == DFmode)
3258 * total = COSTS_N_INSNS (1);
3260 * total = COSTS_N_INSNS (4);
3265 if (mode == SFmode || mode == DFmode)
3266 * total = COSTS_N_INSNS (6);
3267 else if (mode == DImode)
3268 * total = COSTS_N_INSNS (4);
3270 * total = COSTS_N_INSNS (1);
3274 * total = (mode == DImode) ? 4 : 1;
3279 * total = COSTS_N_INSNS (7);
3280 else if (mode == DFmode)
3281 * total = COSTS_N_INSNS (8);
3283 * total = COSTS_N_INSNS (10);
3289 * total = COSTS_N_INSNS (23);
3290 else if (mode == DFmode)
3291 * total = COSTS_N_INSNS (36);
3293 * total = COSTS_N_INSNS (69);
3298 * total = COSTS_N_INSNS (69);
3302 * total = COSTS_N_INSNS (2);
3306 * total = COSTS_N_INSNS (1);
3314 * total = COSTS_N_INSNS (2);
3319 rtx offset = const0_rtx;
3320 rtx symref = eliminate_constant_term (XEXP (x, 0), & offset);
3322 if (GET_CODE (symref) == LABEL_REF)
3323 * total = COSTS_N_INSNS (2);
3324 else if (GET_CODE (symref) != SYMBOL_REF)
3325 * total = COSTS_N_INSNS (4);
3326 /* Let's be paranoid.... */
3327 else if (INTVAL (offset) < -32768 || INTVAL (offset) > 32767)
3328 * total = COSTS_N_INSNS (2);
3330 * total = COSTS_N_INSNS (SYMBOL_REF_FLAG (symref) ? 1 : 2);
3335 * total = COSTS_N_INSNS (SYMBOL_REF_FLAG (x) ? 1 : 2);
3342 split_double (x, & high, & low);
3344 * total = COSTS_N_INSNS ( (high == CONST0_RTX (GET_MODE (high))
3345 || low == CONST0_RTX (GET_MODE (low)))
3356 #include "gt-iq2000.h"