1 /* Subroutines used for code generation on Vitesse IQ2000 processors
2 Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
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"
28 #include "hard-reg-set.h"
29 #include "insn-config.h"
30 #include "conditions.h"
32 #include "insn-attr.h"
39 #include "diagnostic-core.h"
45 #include "target-def.h"
46 #include "langhooks.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
71 /* Structure to be filled in by compute_frame_size with register
72 save masks, and offsets for the current function. */
74 struct iq2000_frame_info
76 long total_size; /* # bytes that the entire frame takes up. */
77 long var_size; /* # bytes that variables take up. */
78 long args_size; /* # bytes that outgoing arguments take up. */
79 long extra_size; /* # bytes of extra gunk. */
80 int gp_reg_size; /* # bytes needed to store gp regs. */
81 int fp_reg_size; /* # bytes needed to store fp regs. */
82 long mask; /* Mask of saved gp registers. */
83 long gp_save_offset; /* Offset from vfp to store gp registers. */
84 long fp_save_offset; /* Offset from vfp to store fp registers. */
85 long gp_sp_offset; /* Offset from new sp to store gp registers. */
86 long fp_sp_offset; /* Offset from new sp to store fp registers. */
87 int initialized; /* != 0 if frame size already calculated. */
88 int num_gp; /* Number of gp registers saved. */
91 struct GTY(()) machine_function
93 /* Current frame information, calculated by compute_frame_size. */
94 long total_size; /* # bytes that the entire frame takes up. */
95 long var_size; /* # bytes that variables take up. */
96 long args_size; /* # bytes that outgoing arguments take up. */
97 long extra_size; /* # bytes of extra gunk. */
98 int gp_reg_size; /* # bytes needed to store gp regs. */
99 int fp_reg_size; /* # bytes needed to store fp regs. */
100 long mask; /* Mask of saved gp registers. */
101 long gp_save_offset; /* Offset from vfp to store gp registers. */
102 long fp_save_offset; /* Offset from vfp to store fp registers. */
103 long gp_sp_offset; /* Offset from new sp to store gp registers. */
104 long fp_sp_offset; /* Offset from new sp to store fp registers. */
105 int initialized; /* != 0 if frame size already calculated. */
106 int num_gp; /* Number of gp registers saved. */
109 /* Global variables for machine-dependent things. */
111 /* List of all IQ2000 punctuation characters used by iq2000_print_operand. */
112 static char iq2000_print_operand_punct[256];
114 /* The target cpu for optimization and scheduling. */
115 enum processor_type iq2000_tune;
117 /* Which instruction set architecture to use. */
120 /* Local variables. */
122 /* The next branch instruction is a branch likely, not branch normal. */
123 static int iq2000_branch_likely;
125 /* Count of delay slots and how many are filled. */
126 static int dslots_load_total;
127 static int dslots_load_filled;
128 static int dslots_jump_total;
130 /* # of nops needed by previous insn. */
131 static int dslots_number_nops;
133 /* Number of 1/2/3 word references to data items (i.e., not jal's). */
134 static int num_refs[3];
136 /* Registers to check for load delay. */
137 static rtx iq2000_load_reg;
138 static rtx iq2000_load_reg2;
139 static rtx iq2000_load_reg3;
140 static rtx iq2000_load_reg4;
142 /* Mode used for saving/restoring general purpose registers. */
143 static enum machine_mode gpr_mode;
146 /* Initialize the GCC target structure. */
147 static struct machine_function* iq2000_init_machine_status (void);
148 static bool iq2000_handle_option (size_t, const char *, int);
149 static void iq2000_option_override (void);
150 static section *iq2000_select_rtx_section (enum machine_mode, rtx,
151 unsigned HOST_WIDE_INT);
152 static void iq2000_init_builtins (void);
153 static rtx iq2000_expand_builtin (tree, rtx, rtx, enum machine_mode, int);
154 static bool iq2000_return_in_memory (const_tree, const_tree);
155 static void iq2000_setup_incoming_varargs (CUMULATIVE_ARGS *,
156 enum machine_mode, tree, int *,
158 static bool iq2000_rtx_costs (rtx, int, int, int *, bool);
159 static int iq2000_address_cost (rtx, bool);
160 static section *iq2000_select_section (tree, int, unsigned HOST_WIDE_INT);
161 static rtx iq2000_legitimize_address (rtx, rtx, enum machine_mode);
162 static bool iq2000_pass_by_reference (CUMULATIVE_ARGS *, enum machine_mode,
164 static int iq2000_arg_partial_bytes (CUMULATIVE_ARGS *, enum machine_mode,
166 static rtx iq2000_function_arg (CUMULATIVE_ARGS *,
167 enum machine_mode, const_tree, bool);
168 static void iq2000_function_arg_advance (CUMULATIVE_ARGS *,
169 enum machine_mode, const_tree, bool);
170 static unsigned int iq2000_function_arg_boundary (enum machine_mode,
172 static void iq2000_va_start (tree, rtx);
173 static bool iq2000_legitimate_address_p (enum machine_mode, rtx, bool);
174 static bool iq2000_can_eliminate (const int, const int);
175 static void iq2000_asm_trampoline_template (FILE *);
176 static void iq2000_trampoline_init (rtx, tree, rtx);
177 static rtx iq2000_function_value (const_tree, const_tree, bool);
178 static rtx iq2000_libcall_value (enum machine_mode, const_rtx);
179 static void iq2000_print_operand (FILE *, rtx, int);
180 static void iq2000_print_operand_address (FILE *, rtx);
181 static bool iq2000_print_operand_punct_valid_p (unsigned char code);
183 /* Implement TARGET_OPTION_OPTIMIZATION_TABLE. */
184 static const struct default_options iq2000_option_optimization_table[] =
186 { OPT_LEVELS_1_PLUS, OPT_fomit_frame_pointer, NULL, 1 },
187 { OPT_LEVELS_NONE, 0, NULL, 0 }
190 #undef TARGET_INIT_BUILTINS
191 #define TARGET_INIT_BUILTINS iq2000_init_builtins
192 #undef TARGET_EXPAND_BUILTIN
193 #define TARGET_EXPAND_BUILTIN iq2000_expand_builtin
194 #undef TARGET_ASM_SELECT_RTX_SECTION
195 #define TARGET_ASM_SELECT_RTX_SECTION iq2000_select_rtx_section
196 #undef TARGET_HANDLE_OPTION
197 #define TARGET_HANDLE_OPTION iq2000_handle_option
198 #undef TARGET_OPTION_OVERRIDE
199 #define TARGET_OPTION_OVERRIDE iq2000_option_override
200 #undef TARGET_OPTION_OPTIMIZATION_TABLE
201 #define TARGET_OPTION_OPTIMIZATION_TABLE iq2000_option_optimization_table
202 #undef TARGET_RTX_COSTS
203 #define TARGET_RTX_COSTS iq2000_rtx_costs
204 #undef TARGET_ADDRESS_COST
205 #define TARGET_ADDRESS_COST iq2000_address_cost
206 #undef TARGET_ASM_SELECT_SECTION
207 #define TARGET_ASM_SELECT_SECTION iq2000_select_section
209 #undef TARGET_LEGITIMIZE_ADDRESS
210 #define TARGET_LEGITIMIZE_ADDRESS iq2000_legitimize_address
212 /* The assembler supports switchable .bss sections, but
213 iq2000_select_section doesn't yet make use of them. */
214 #undef TARGET_HAVE_SWITCHABLE_BSS_SECTIONS
215 #define TARGET_HAVE_SWITCHABLE_BSS_SECTIONS false
217 #undef TARGET_PRINT_OPERAND
218 #define TARGET_PRINT_OPERAND iq2000_print_operand
219 #undef TARGET_PRINT_OPERAND_ADDRESS
220 #define TARGET_PRINT_OPERAND_ADDRESS iq2000_print_operand_address
221 #undef TARGET_PRINT_OPERAND_PUNCT_VALID_P
222 #define TARGET_PRINT_OPERAND_PUNCT_VALID_P iq2000_print_operand_punct_valid_p
224 #undef TARGET_PROMOTE_FUNCTION_MODE
225 #define TARGET_PROMOTE_FUNCTION_MODE default_promote_function_mode_always_promote
226 #undef TARGET_PROMOTE_PROTOTYPES
227 #define TARGET_PROMOTE_PROTOTYPES hook_bool_const_tree_true
229 #undef TARGET_FUNCTION_VALUE
230 #define TARGET_FUNCTION_VALUE iq2000_function_value
231 #undef TARGET_LIBCALL_VALUE
232 #define TARGET_LIBCALL_VALUE iq2000_libcall_value
233 #undef TARGET_RETURN_IN_MEMORY
234 #define TARGET_RETURN_IN_MEMORY iq2000_return_in_memory
235 #undef TARGET_PASS_BY_REFERENCE
236 #define TARGET_PASS_BY_REFERENCE iq2000_pass_by_reference
237 #undef TARGET_CALLEE_COPIES
238 #define TARGET_CALLEE_COPIES hook_callee_copies_named
239 #undef TARGET_ARG_PARTIAL_BYTES
240 #define TARGET_ARG_PARTIAL_BYTES iq2000_arg_partial_bytes
241 #undef TARGET_FUNCTION_ARG
242 #define TARGET_FUNCTION_ARG iq2000_function_arg
243 #undef TARGET_FUNCTION_ARG_ADVANCE
244 #define TARGET_FUNCTION_ARG_ADVANCE iq2000_function_arg_advance
245 #undef TARGET_FUNCTION_ARG_BOUNDARY
246 #define TARGET_FUNCTION_ARG_BOUNDARY iq2000_function_arg_boundary
248 #undef TARGET_SETUP_INCOMING_VARARGS
249 #define TARGET_SETUP_INCOMING_VARARGS iq2000_setup_incoming_varargs
250 #undef TARGET_STRICT_ARGUMENT_NAMING
251 #define TARGET_STRICT_ARGUMENT_NAMING hook_bool_CUMULATIVE_ARGS_true
253 #undef TARGET_EXPAND_BUILTIN_VA_START
254 #define TARGET_EXPAND_BUILTIN_VA_START iq2000_va_start
256 #undef TARGET_LEGITIMATE_ADDRESS_P
257 #define TARGET_LEGITIMATE_ADDRESS_P iq2000_legitimate_address_p
259 #undef TARGET_CAN_ELIMINATE
260 #define TARGET_CAN_ELIMINATE iq2000_can_eliminate
262 #undef TARGET_ASM_TRAMPOLINE_TEMPLATE
263 #define TARGET_ASM_TRAMPOLINE_TEMPLATE iq2000_asm_trampoline_template
264 #undef TARGET_TRAMPOLINE_INIT
265 #define TARGET_TRAMPOLINE_INIT iq2000_trampoline_init
267 struct gcc_target targetm = TARGET_INITIALIZER;
269 /* Return nonzero if we split the address into high and low parts. */
272 iq2000_check_split (rtx address, enum machine_mode mode)
274 /* This is the same check used in simple_memory_operand.
275 We use it here because LO_SUM is not offsettable. */
276 if (GET_MODE_SIZE (mode) > (unsigned) UNITS_PER_WORD)
279 if ((GET_CODE (address) == SYMBOL_REF)
280 || (GET_CODE (address) == CONST
281 && GET_CODE (XEXP (XEXP (address, 0), 0)) == SYMBOL_REF)
282 || GET_CODE (address) == LABEL_REF)
288 /* Return nonzero if REG is valid for MODE. */
291 iq2000_reg_mode_ok_for_base_p (rtx reg,
292 enum machine_mode mode ATTRIBUTE_UNUSED,
296 ? REGNO_MODE_OK_FOR_BASE_P (REGNO (reg), mode)
297 : GP_REG_OR_PSEUDO_NONSTRICT_P (REGNO (reg), mode));
300 /* Return a nonzero value if XINSN is a legitimate address for a
301 memory operand of the indicated MODE. STRICT is nonzero if this
302 function is called during reload. */
305 iq2000_legitimate_address_p (enum machine_mode mode, rtx xinsn, bool strict)
307 if (TARGET_DEBUG_A_MODE)
309 GO_PRINTF2 ("\n========== legitimate_address_p, %sstrict\n",
310 strict ? "" : "not ");
311 GO_DEBUG_RTX (xinsn);
314 /* Check for constant before stripping off SUBREG, so that we don't
315 accept (subreg (const_int)) which will fail to reload. */
316 if (CONSTANT_ADDRESS_P (xinsn)
317 && ! (iq2000_check_split (xinsn, mode))
318 && ! (GET_CODE (xinsn) == CONST_INT && ! SMALL_INT (xinsn)))
321 while (GET_CODE (xinsn) == SUBREG)
322 xinsn = SUBREG_REG (xinsn);
324 if (GET_CODE (xinsn) == REG
325 && iq2000_reg_mode_ok_for_base_p (xinsn, mode, strict))
328 if (GET_CODE (xinsn) == LO_SUM)
330 rtx xlow0 = XEXP (xinsn, 0);
331 rtx xlow1 = XEXP (xinsn, 1);
333 while (GET_CODE (xlow0) == SUBREG)
334 xlow0 = SUBREG_REG (xlow0);
335 if (GET_CODE (xlow0) == REG
336 && iq2000_reg_mode_ok_for_base_p (xlow0, mode, strict)
337 && iq2000_check_split (xlow1, mode))
341 if (GET_CODE (xinsn) == PLUS)
343 rtx xplus0 = XEXP (xinsn, 0);
344 rtx xplus1 = XEXP (xinsn, 1);
348 while (GET_CODE (xplus0) == SUBREG)
349 xplus0 = SUBREG_REG (xplus0);
350 code0 = GET_CODE (xplus0);
352 while (GET_CODE (xplus1) == SUBREG)
353 xplus1 = SUBREG_REG (xplus1);
354 code1 = GET_CODE (xplus1);
357 && iq2000_reg_mode_ok_for_base_p (xplus0, mode, strict))
359 if (code1 == CONST_INT && SMALL_INT (xplus1)
360 && SMALL_INT_UNSIGNED (xplus1) /* No negative offsets */)
365 if (TARGET_DEBUG_A_MODE)
366 GO_PRINTF ("Not a enum machine_mode mode, legitimate address\n");
368 /* The address was not legitimate. */
372 /* Returns an operand string for the given instruction's delay slot,
373 after updating filled delay slot statistics.
375 We assume that operands[0] is the target register that is set.
377 In order to check the next insn, most of this functionality is moved
378 to FINAL_PRESCAN_INSN, and we just set the global variables that
382 iq2000_fill_delay_slot (const char *ret, enum delay_type type, rtx operands[],
386 enum machine_mode mode;
387 rtx next_insn = cur_insn ? NEXT_INSN (cur_insn) : NULL_RTX;
390 if (type == DELAY_LOAD || type == DELAY_FCMP)
396 /* Make sure that we don't put nop's after labels. */
397 next_insn = NEXT_INSN (cur_insn);
398 while (next_insn != 0
399 && (GET_CODE (next_insn) == NOTE
400 || GET_CODE (next_insn) == CODE_LABEL))
401 next_insn = NEXT_INSN (next_insn);
403 dslots_load_total += num_nops;
404 if (TARGET_DEBUG_C_MODE
405 || type == DELAY_NONE
409 || GET_CODE (next_insn) == CODE_LABEL
410 || (set_reg = operands[0]) == 0)
412 dslots_number_nops = 0;
414 iq2000_load_reg2 = 0;
415 iq2000_load_reg3 = 0;
416 iq2000_load_reg4 = 0;
421 set_reg = operands[0];
425 while (GET_CODE (set_reg) == SUBREG)
426 set_reg = SUBREG_REG (set_reg);
428 mode = GET_MODE (set_reg);
429 dslots_number_nops = num_nops;
430 iq2000_load_reg = set_reg;
431 if (GET_MODE_SIZE (mode)
432 > (unsigned) (UNITS_PER_WORD))
433 iq2000_load_reg2 = gen_rtx_REG (SImode, REGNO (set_reg) + 1);
435 iq2000_load_reg2 = 0;
440 /* Determine whether a memory reference takes one (based off of the GP
441 pointer), two (normal), or three (label + reg) instructions, and bump the
442 appropriate counter for -mstats. */
445 iq2000_count_memory_refs (rtx op, int num)
449 rtx addr, plus0, plus1;
450 enum rtx_code code0, code1;
453 if (TARGET_DEBUG_B_MODE)
455 fprintf (stderr, "\n========== iq2000_count_memory_refs:\n");
459 /* Skip MEM if passed, otherwise handle movsi of address. */
460 addr = (GET_CODE (op) != MEM) ? op : XEXP (op, 0);
462 /* Loop, going through the address RTL. */
466 switch (GET_CODE (addr))
474 plus0 = XEXP (addr, 0);
475 plus1 = XEXP (addr, 1);
476 code0 = GET_CODE (plus0);
477 code1 = GET_CODE (plus1);
487 if (code0 == CONST_INT)
502 if (code1 == CONST_INT)
509 if (code0 == SYMBOL_REF || code0 == LABEL_REF || code0 == CONST)
516 if (code1 == SYMBOL_REF || code1 == LABEL_REF || code1 == CONST)
526 n_words = 2; /* Always 2 words. */
530 addr = XEXP (addr, 0);
535 n_words = SYMBOL_REF_FLAG (addr) ? 1 : 2;
547 n_words += additional;
551 num_refs[n_words-1] += num;
554 /* Abort after printing out a specific insn. */
557 abort_with_insn (rtx insn, const char * reason)
561 fancy_abort (__FILE__, __LINE__, __FUNCTION__);
564 /* Return the appropriate instructions to move one operand to another. */
567 iq2000_move_1word (rtx operands[], rtx insn, int unsignedp)
570 rtx op0 = operands[0];
571 rtx op1 = operands[1];
572 enum rtx_code code0 = GET_CODE (op0);
573 enum rtx_code code1 = GET_CODE (op1);
574 enum machine_mode mode = GET_MODE (op0);
575 int subreg_offset0 = 0;
576 int subreg_offset1 = 0;
577 enum delay_type delay = DELAY_NONE;
579 while (code0 == SUBREG)
581 subreg_offset0 += subreg_regno_offset (REGNO (SUBREG_REG (op0)),
582 GET_MODE (SUBREG_REG (op0)),
585 op0 = SUBREG_REG (op0);
586 code0 = GET_CODE (op0);
589 while (code1 == SUBREG)
591 subreg_offset1 += subreg_regno_offset (REGNO (SUBREG_REG (op1)),
592 GET_MODE (SUBREG_REG (op1)),
595 op1 = SUBREG_REG (op1);
596 code1 = GET_CODE (op1);
599 /* For our purposes, a condition code mode is the same as SImode. */
605 int regno0 = REGNO (op0) + subreg_offset0;
609 int regno1 = REGNO (op1) + subreg_offset1;
611 /* Do not do anything for assigning a register to itself */
612 if (regno0 == regno1)
615 else if (GP_REG_P (regno0))
617 if (GP_REG_P (regno1))
618 ret = "or\t%0,%%0,%1";
623 else if (code1 == MEM)
628 iq2000_count_memory_refs (op1, 1);
630 if (GP_REG_P (regno0))
632 /* For loads, use the mode of the memory item, instead of the
633 target, so zero/sign extend can use this code as well. */
634 switch (GET_MODE (op1))
646 ret = (unsignedp) ? "lhu\t%0,%1" : "lh\t%0,%1";
649 ret = (unsignedp) ? "lbu\t%0,%1" : "lb\t%0,%1";
655 else if (code1 == CONST_INT
656 || (code1 == CONST_DOUBLE
657 && GET_MODE (op1) == VOIDmode))
659 if (code1 == CONST_DOUBLE)
661 /* This can happen when storing constants into long long
662 bitfields. Just store the least significant word of
664 operands[1] = op1 = GEN_INT (CONST_DOUBLE_LOW (op1));
667 if (INTVAL (op1) == 0)
669 if (GP_REG_P (regno0))
670 ret = "or\t%0,%%0,%z1";
672 else if (GP_REG_P (regno0))
674 if (SMALL_INT_UNSIGNED (op1))
675 ret = "ori\t%0,%%0,%x1\t\t\t# %1";
676 else if (SMALL_INT (op1))
677 ret = "addiu\t%0,%%0,%1\t\t\t# %1";
679 ret = "lui\t%0,%X1\t\t\t# %1\n\tori\t%0,%0,%x1";
683 else if (code1 == CONST_DOUBLE && mode == SFmode)
685 if (op1 == CONST0_RTX (SFmode))
687 if (GP_REG_P (regno0))
688 ret = "or\t%0,%%0,%.";
698 else if (code1 == LABEL_REF)
701 iq2000_count_memory_refs (op1, 1);
706 else if (code1 == SYMBOL_REF || code1 == CONST)
709 iq2000_count_memory_refs (op1, 1);
714 else if (code1 == PLUS)
716 rtx add_op0 = XEXP (op1, 0);
717 rtx add_op1 = XEXP (op1, 1);
719 if (GET_CODE (XEXP (op1, 1)) == REG
720 && GET_CODE (XEXP (op1, 0)) == CONST_INT)
721 add_op0 = XEXP (op1, 1), add_op1 = XEXP (op1, 0);
723 operands[2] = add_op0;
724 operands[3] = add_op1;
725 ret = "add%:\t%0,%2,%3";
728 else if (code1 == HIGH)
730 operands[1] = XEXP (op1, 0);
731 ret = "lui\t%0,%%hi(%1)";
735 else if (code0 == MEM)
738 iq2000_count_memory_refs (op0, 1);
742 int regno1 = REGNO (op1) + subreg_offset1;
744 if (GP_REG_P (regno1))
748 case SFmode: ret = "sw\t%1,%0"; break;
749 case SImode: ret = "sw\t%1,%0"; break;
750 case HImode: ret = "sh\t%1,%0"; break;
751 case QImode: ret = "sb\t%1,%0"; break;
757 else if (code1 == CONST_INT && INTVAL (op1) == 0)
761 case SFmode: ret = "sw\t%z1,%0"; break;
762 case SImode: ret = "sw\t%z1,%0"; break;
763 case HImode: ret = "sh\t%z1,%0"; break;
764 case QImode: ret = "sb\t%z1,%0"; break;
769 else if (code1 == CONST_DOUBLE && op1 == CONST0_RTX (mode))
773 case SFmode: ret = "sw\t%.,%0"; break;
774 case SImode: ret = "sw\t%.,%0"; break;
775 case HImode: ret = "sh\t%.,%0"; break;
776 case QImode: ret = "sb\t%.,%0"; break;
784 abort_with_insn (insn, "Bad move");
788 if (delay != DELAY_NONE)
789 return iq2000_fill_delay_slot (ret, delay, operands, insn);
794 /* Provide the costs of an addressing mode that contains ADDR. */
797 iq2000_address_cost (rtx addr, bool speed)
799 switch (GET_CODE (addr))
809 rtx offset = const0_rtx;
811 addr = eliminate_constant_term (XEXP (addr, 0), & offset);
812 if (GET_CODE (addr) == LABEL_REF)
815 if (GET_CODE (addr) != SYMBOL_REF)
818 if (! SMALL_INT (offset))
825 return SYMBOL_REF_FLAG (addr) ? 1 : 2;
829 rtx plus0 = XEXP (addr, 0);
830 rtx plus1 = XEXP (addr, 1);
832 if (GET_CODE (plus0) != REG && GET_CODE (plus1) == REG)
833 plus0 = XEXP (addr, 1), plus1 = XEXP (addr, 0);
835 if (GET_CODE (plus0) != REG)
838 switch (GET_CODE (plus1))
841 return SMALL_INT (plus1) ? 1 : 2;
848 return iq2000_address_cost (plus1, speed) + 1;
862 /* Make normal rtx_code into something we can index from an array. */
864 static enum internal_test
865 map_test_to_internal_test (enum rtx_code test_code)
867 enum internal_test test = ITEST_MAX;
871 case EQ: test = ITEST_EQ; break;
872 case NE: test = ITEST_NE; break;
873 case GT: test = ITEST_GT; break;
874 case GE: test = ITEST_GE; break;
875 case LT: test = ITEST_LT; break;
876 case LE: test = ITEST_LE; break;
877 case GTU: test = ITEST_GTU; break;
878 case GEU: test = ITEST_GEU; break;
879 case LTU: test = ITEST_LTU; break;
880 case LEU: test = ITEST_LEU; break;
887 /* Generate the code to do a TEST_CODE comparison on two integer values CMP0
888 and CMP1. P_INVERT is NULL or ptr if branch needs to reverse its test.
889 The return value RESULT is:
890 (reg:SI xx) The pseudo register the comparison is in
891 0 No register, generate a simple branch. */
894 gen_int_relational (enum rtx_code test_code, rtx result, rtx cmp0, rtx cmp1,
899 enum rtx_code test_code; /* Code to use in instruction (LT vs. LTU). */
900 int const_low; /* Low bound of constant we can accept. */
901 int const_high; /* High bound of constant we can accept. */
902 int const_add; /* Constant to add (convert LE -> LT). */
903 int reverse_regs; /* Reverse registers in test. */
904 int invert_const; /* != 0 if invert value if cmp1 is constant. */
905 int invert_reg; /* != 0 if invert value if cmp1 is register. */
906 int unsignedp; /* != 0 for unsigned comparisons. */
909 static struct cmp_info info[ (int)ITEST_MAX ] =
911 { XOR, 0, 65535, 0, 0, 0, 0, 0 }, /* EQ */
912 { XOR, 0, 65535, 0, 0, 1, 1, 0 }, /* NE */
913 { LT, -32769, 32766, 1, 1, 1, 0, 0 }, /* GT */
914 { LT, -32768, 32767, 0, 0, 1, 1, 0 }, /* GE */
915 { LT, -32768, 32767, 0, 0, 0, 0, 0 }, /* LT */
916 { LT, -32769, 32766, 1, 1, 0, 1, 0 }, /* LE */
917 { LTU, -32769, 32766, 1, 1, 1, 0, 1 }, /* GTU */
918 { LTU, -32768, 32767, 0, 0, 1, 1, 1 }, /* GEU */
919 { LTU, -32768, 32767, 0, 0, 0, 0, 1 }, /* LTU */
920 { LTU, -32769, 32766, 1, 1, 0, 1, 1 }, /* LEU */
923 enum internal_test test;
924 enum machine_mode mode;
925 struct cmp_info *p_info;
932 test = map_test_to_internal_test (test_code);
933 gcc_assert (test != ITEST_MAX);
935 p_info = &info[(int) test];
936 eqne_p = (p_info->test_code == XOR);
938 mode = GET_MODE (cmp0);
939 if (mode == VOIDmode)
940 mode = GET_MODE (cmp1);
942 /* Eliminate simple branches. */
943 branch_p = (result == 0);
946 if (GET_CODE (cmp0) == REG || GET_CODE (cmp0) == SUBREG)
948 /* Comparisons against zero are simple branches. */
949 if (GET_CODE (cmp1) == CONST_INT && INTVAL (cmp1) == 0)
952 /* Test for beq/bne. */
957 /* Allocate a pseudo to calculate the value in. */
958 result = gen_reg_rtx (mode);
961 /* Make sure we can handle any constants given to us. */
962 if (GET_CODE (cmp0) == CONST_INT)
963 cmp0 = force_reg (mode, cmp0);
965 if (GET_CODE (cmp1) == CONST_INT)
967 HOST_WIDE_INT value = INTVAL (cmp1);
969 if (value < p_info->const_low
970 || value > p_info->const_high)
971 cmp1 = force_reg (mode, cmp1);
974 /* See if we need to invert the result. */
975 invert = (GET_CODE (cmp1) == CONST_INT
976 ? p_info->invert_const : p_info->invert_reg);
978 if (p_invert != (int *)0)
984 /* Comparison to constants, may involve adding 1 to change a LT into LE.
985 Comparison between two registers, may involve switching operands. */
986 if (GET_CODE (cmp1) == CONST_INT)
988 if (p_info->const_add != 0)
990 HOST_WIDE_INT new_const = INTVAL (cmp1) + p_info->const_add;
992 /* If modification of cmp1 caused overflow,
993 we would get the wrong answer if we follow the usual path;
994 thus, x > 0xffffffffU would turn into x > 0U. */
995 if ((p_info->unsignedp
996 ? (unsigned HOST_WIDE_INT) new_const >
997 (unsigned HOST_WIDE_INT) INTVAL (cmp1)
998 : new_const > INTVAL (cmp1))
999 != (p_info->const_add > 0))
1001 /* This test is always true, but if INVERT is true then
1002 the result of the test needs to be inverted so 0 should
1003 be returned instead. */
1004 emit_move_insn (result, invert ? const0_rtx : const_true_rtx);
1008 cmp1 = GEN_INT (new_const);
1012 else if (p_info->reverse_regs)
1019 if (test == ITEST_NE && GET_CODE (cmp1) == CONST_INT && INTVAL (cmp1) == 0)
1023 reg = (invert || eqne_p) ? gen_reg_rtx (mode) : result;
1024 convert_move (reg, gen_rtx_fmt_ee (p_info->test_code, mode, cmp0, cmp1), 0);
1027 if (test == ITEST_NE)
1029 convert_move (result, gen_rtx_GTU (mode, reg, const0_rtx), 0);
1030 if (p_invert != NULL)
1035 else if (test == ITEST_EQ)
1037 reg2 = invert ? gen_reg_rtx (mode) : result;
1038 convert_move (reg2, gen_rtx_LTU (mode, reg, const1_rtx), 0);
1047 convert_move (result, gen_rtx_XOR (mode, reg, one), 0);
1053 /* Emit the common code for doing conditional branches.
1054 operand[0] is the label to jump to.
1055 The comparison operands are saved away by cmp{si,di,sf,df}. */
1058 gen_conditional_branch (rtx operands[], enum machine_mode mode)
1060 enum rtx_code test_code = GET_CODE (operands[0]);
1061 rtx cmp0 = operands[1];
1062 rtx cmp1 = operands[2];
1068 reg = gen_int_relational (test_code, NULL_RTX, cmp0, cmp1, &invert);
1076 else if (GET_CODE (cmp1) == CONST_INT && INTVAL (cmp1) != 0)
1077 /* We don't want to build a comparison against a nonzero
1079 cmp1 = force_reg (mode, cmp1);
1081 /* Generate the branch. */
1082 label1 = gen_rtx_LABEL_REF (VOIDmode, operands[3]);
1091 emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
1092 gen_rtx_IF_THEN_ELSE (VOIDmode,
1093 gen_rtx_fmt_ee (test_code,
1099 /* Initialize CUM for a function FNTYPE. */
1102 init_cumulative_args (CUMULATIVE_ARGS *cum, tree fntype,
1103 rtx libname ATTRIBUTE_UNUSED)
1105 static CUMULATIVE_ARGS zero_cum;
1109 if (TARGET_DEBUG_D_MODE)
1112 "\ninit_cumulative_args, fntype = 0x%.8lx", (long) fntype);
1115 fputc ('\n', stderr);
1119 tree ret_type = TREE_TYPE (fntype);
1121 fprintf (stderr, ", fntype code = %s, ret code = %s\n",
1122 tree_code_name[(int)TREE_CODE (fntype)],
1123 tree_code_name[(int)TREE_CODE (ret_type)]);
1129 /* Determine if this function has variable arguments. This is
1130 indicated by the last argument being 'void_type_mode' if there
1131 are no variable arguments. The standard IQ2000 calling sequence
1132 passes all arguments in the general purpose registers in this case. */
1134 for (param = fntype ? TYPE_ARG_TYPES (fntype) : 0;
1135 param != 0; param = next_param)
1137 next_param = TREE_CHAIN (param);
1138 if (next_param == 0 && TREE_VALUE (param) != void_type_node)
1139 cum->gp_reg_found = 1;
1143 /* Advance the argument of type TYPE and mode MODE to the next argument
1147 iq2000_function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode,
1148 const_tree type, bool named)
1150 if (TARGET_DEBUG_D_MODE)
1153 "function_adv({gp reg found = %d, arg # = %2d, words = %2d}, %4s, ",
1154 cum->gp_reg_found, cum->arg_number, cum->arg_words,
1155 GET_MODE_NAME (mode));
1156 fprintf (stderr, "%p", CONST_CAST2 (void *, const_tree, type));
1157 fprintf (stderr, ", %d )\n\n", named);
1167 gcc_assert (GET_MODE_CLASS (mode) == MODE_COMPLEX_INT
1168 || GET_MODE_CLASS (mode) == MODE_COMPLEX_FLOAT);
1170 cum->gp_reg_found = 1;
1171 cum->arg_words += ((GET_MODE_SIZE (mode) + UNITS_PER_WORD - 1)
1176 cum->gp_reg_found = 1;
1177 cum->arg_words += ((int_size_in_bytes (type) + UNITS_PER_WORD - 1)
1183 if (! cum->gp_reg_found && cum->arg_number <= 2)
1184 cum->fp_code += 1 << ((cum->arg_number - 1) * 2);
1188 cum->arg_words += 2;
1189 if (! cum->gp_reg_found && cum->arg_number <= 2)
1190 cum->fp_code += 2 << ((cum->arg_number - 1) * 2);
1194 cum->gp_reg_found = 1;
1195 cum->arg_words += 2;
1199 cum->gp_reg_found = 1;
1200 cum->arg_words += 4;
1206 cum->gp_reg_found = 1;
1212 /* Return an RTL expression containing the register for the given mode MODE
1213 and type TYPE in CUM, or 0 if the argument is to be passed on the stack. */
1216 iq2000_function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode,
1217 const_tree type, bool named)
1222 unsigned int *arg_words = &cum->arg_words;
1223 int struct_p = (type != 0
1224 && (TREE_CODE (type) == RECORD_TYPE
1225 || TREE_CODE (type) == UNION_TYPE
1226 || TREE_CODE (type) == QUAL_UNION_TYPE));
1228 if (TARGET_DEBUG_D_MODE)
1231 "function_arg( {gp reg found = %d, arg # = %2d, words = %2d}, %4s, ",
1232 cum->gp_reg_found, cum->arg_number, cum->arg_words,
1233 GET_MODE_NAME (mode));
1234 fprintf (stderr, "%p", (const void *) type);
1235 fprintf (stderr, ", %d ) = ", named);
1239 cum->last_arg_fp = 0;
1243 regbase = GP_ARG_FIRST;
1247 cum->arg_words += cum->arg_words & 1;
1249 regbase = GP_ARG_FIRST;
1253 gcc_assert (GET_MODE_CLASS (mode) == MODE_COMPLEX_INT
1254 || GET_MODE_CLASS (mode) == MODE_COMPLEX_FLOAT);
1256 /* Drops through. */
1258 if (type != NULL_TREE && TYPE_ALIGN (type) > (unsigned) BITS_PER_WORD)
1259 cum->arg_words += (cum->arg_words & 1);
1260 regbase = GP_ARG_FIRST;
1267 regbase = GP_ARG_FIRST;
1271 cum->arg_words += (cum->arg_words & 1);
1272 regbase = GP_ARG_FIRST;
1276 cum->arg_words += (cum->arg_words & 3);
1277 regbase = GP_ARG_FIRST;
1281 if (*arg_words >= (unsigned) MAX_ARGS_IN_REGISTERS)
1283 if (TARGET_DEBUG_D_MODE)
1284 fprintf (stderr, "<stack>%s\n", struct_p ? ", [struct]" : "");
1290 gcc_assert (regbase != -1);
1292 if (! type || TREE_CODE (type) != RECORD_TYPE
1293 || ! named || ! TYPE_SIZE_UNIT (type)
1294 || ! host_integerp (TYPE_SIZE_UNIT (type), 1))
1295 ret = gen_rtx_REG (mode, regbase + *arg_words + bias);
1300 for (field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
1301 if (TREE_CODE (field) == FIELD_DECL
1302 && TREE_CODE (TREE_TYPE (field)) == REAL_TYPE
1303 && TYPE_PRECISION (TREE_TYPE (field)) == BITS_PER_WORD
1304 && host_integerp (bit_position (field), 0)
1305 && int_bit_position (field) % BITS_PER_WORD == 0)
1308 /* If the whole struct fits a DFmode register,
1309 we don't need the PARALLEL. */
1310 if (! field || mode == DFmode)
1311 ret = gen_rtx_REG (mode, regbase + *arg_words + bias);
1314 unsigned int chunks;
1315 HOST_WIDE_INT bitpos;
1319 /* ??? If this is a packed structure, then the last hunk won't
1322 = tree_low_cst (TYPE_SIZE_UNIT (type), 1) / UNITS_PER_WORD;
1323 if (chunks + *arg_words + bias > (unsigned) MAX_ARGS_IN_REGISTERS)
1324 chunks = MAX_ARGS_IN_REGISTERS - *arg_words - bias;
1326 /* Assign_parms checks the mode of ENTRY_PARM, so we must
1327 use the actual mode here. */
1328 ret = gen_rtx_PARALLEL (mode, rtvec_alloc (chunks));
1331 regno = regbase + *arg_words + bias;
1332 field = TYPE_FIELDS (type);
1333 for (i = 0; i < chunks; i++)
1337 for (; field; field = DECL_CHAIN (field))
1338 if (TREE_CODE (field) == FIELD_DECL
1339 && int_bit_position (field) >= bitpos)
1343 && int_bit_position (field) == bitpos
1344 && TREE_CODE (TREE_TYPE (field)) == REAL_TYPE
1345 && TYPE_PRECISION (TREE_TYPE (field)) == BITS_PER_WORD)
1346 reg = gen_rtx_REG (DFmode, regno++);
1348 reg = gen_rtx_REG (word_mode, regno);
1351 = gen_rtx_EXPR_LIST (VOIDmode, reg,
1352 GEN_INT (bitpos / BITS_PER_UNIT));
1360 if (TARGET_DEBUG_D_MODE)
1361 fprintf (stderr, "%s%s\n", reg_names[regbase + *arg_words + bias],
1362 struct_p ? ", [struct]" : "");
1365 /* We will be called with a mode of VOIDmode after the last argument
1366 has been seen. Whatever we return will be passed to the call
1367 insn. If we need any shifts for small structures, return them in
1369 if (mode == VOIDmode)
1371 if (cum->num_adjusts > 0)
1372 ret = gen_rtx_PARALLEL ((enum machine_mode) cum->fp_code,
1373 gen_rtvec_v (cum->num_adjusts, cum->adjust));
1380 iq2000_function_arg_boundary (enum machine_mode mode, const_tree type)
1382 return (type != NULL_TREE
1383 ? (TYPE_ALIGN (type) <= PARM_BOUNDARY
1385 : TYPE_ALIGN (type))
1386 : (GET_MODE_ALIGNMENT (mode) <= PARM_BOUNDARY
1388 : GET_MODE_ALIGNMENT (mode)));
1392 iq2000_arg_partial_bytes (CUMULATIVE_ARGS *cum, enum machine_mode mode,
1393 tree type ATTRIBUTE_UNUSED,
1394 bool named ATTRIBUTE_UNUSED)
1396 if (mode == DImode && cum->arg_words == MAX_ARGS_IN_REGISTERS - 1)
1398 if (TARGET_DEBUG_D_MODE)
1399 fprintf (stderr, "iq2000_arg_partial_bytes=%d\n", UNITS_PER_WORD);
1400 return UNITS_PER_WORD;
1406 /* Implement va_start. */
1409 iq2000_va_start (tree valist, rtx nextarg)
1412 /* Find out how many non-float named formals. */
1413 int gpr_save_area_size;
1414 /* Note UNITS_PER_WORD is 4 bytes. */
1415 int_arg_words = crtl->args.info.arg_words;
1417 if (int_arg_words < 8 )
1418 /* Adjust for the prologue's economy measure. */
1419 gpr_save_area_size = (8 - int_arg_words) * UNITS_PER_WORD;
1421 gpr_save_area_size = 0;
1423 /* Everything is in the GPR save area, or in the overflow
1424 area which is contiguous with it. */
1425 nextarg = plus_constant (nextarg, - gpr_save_area_size);
1426 std_expand_builtin_va_start (valist, nextarg);
1429 /* Allocate a chunk of memory for per-function machine-dependent data. */
1431 static struct machine_function *
1432 iq2000_init_machine_status (void)
1434 return ggc_alloc_cleared_machine_function ();
1437 /* Implement TARGET_HANDLE_OPTION. */
1440 iq2000_handle_option (size_t code, const char *arg, int value ATTRIBUTE_UNUSED)
1445 if (strcmp (arg, "iq10") == 0)
1446 iq2000_tune = PROCESSOR_IQ10;
1447 else if (strcmp (arg, "iq2000") == 0)
1448 iq2000_tune = PROCESSOR_IQ2000;
1454 /* This option has no effect at the moment. */
1455 return (strcmp (arg, "default") == 0
1456 || strcmp (arg, "DEFAULT") == 0
1457 || strcmp (arg, "iq2000") == 0);
1464 /* Detect any conflicts in the switches. */
1467 iq2000_option_override (void)
1469 target_flags &= ~MASK_GPOPT;
1471 iq2000_isa = IQ2000_ISA_DEFAULT;
1473 /* Identify the processor type. */
1475 iq2000_print_operand_punct['?'] = 1;
1476 iq2000_print_operand_punct['#'] = 1;
1477 iq2000_print_operand_punct['&'] = 1;
1478 iq2000_print_operand_punct['!'] = 1;
1479 iq2000_print_operand_punct['*'] = 1;
1480 iq2000_print_operand_punct['@'] = 1;
1481 iq2000_print_operand_punct['.'] = 1;
1482 iq2000_print_operand_punct['('] = 1;
1483 iq2000_print_operand_punct[')'] = 1;
1484 iq2000_print_operand_punct['['] = 1;
1485 iq2000_print_operand_punct[']'] = 1;
1486 iq2000_print_operand_punct['<'] = 1;
1487 iq2000_print_operand_punct['>'] = 1;
1488 iq2000_print_operand_punct['{'] = 1;
1489 iq2000_print_operand_punct['}'] = 1;
1490 iq2000_print_operand_punct['^'] = 1;
1491 iq2000_print_operand_punct['$'] = 1;
1492 iq2000_print_operand_punct['+'] = 1;
1493 iq2000_print_operand_punct['~'] = 1;
1495 /* Save GPR registers in word_mode sized hunks. word_mode hasn't been
1496 initialized yet, so we can't use that here. */
1499 /* Function to allocate machine-dependent function status. */
1500 init_machine_status = iq2000_init_machine_status;
1503 /* The arg pointer (which is eliminated) points to the virtual frame pointer,
1504 while the frame pointer (which may be eliminated) points to the stack
1505 pointer after the initial adjustments. */
1508 iq2000_debugger_offset (rtx addr, HOST_WIDE_INT offset)
1510 rtx offset2 = const0_rtx;
1511 rtx reg = eliminate_constant_term (addr, & offset2);
1514 offset = INTVAL (offset2);
1516 if (reg == stack_pointer_rtx || reg == frame_pointer_rtx
1517 || reg == hard_frame_pointer_rtx)
1519 HOST_WIDE_INT frame_size = (!cfun->machine->initialized)
1520 ? compute_frame_size (get_frame_size ())
1521 : cfun->machine->total_size;
1523 offset = offset - frame_size;
1529 /* If defined, a C statement to be executed just prior to the output of
1530 assembler code for INSN, to modify the extracted operands so they will be
1533 Here the argument OPVEC is the vector containing the operands extracted
1534 from INSN, and NOPERANDS is the number of elements of the vector which
1535 contain meaningful data for this insn. The contents of this vector are
1536 what will be used to convert the insn template into assembler code, so you
1537 can change the assembler output by changing the contents of the vector.
1539 We use it to check if the current insn needs a nop in front of it because
1540 of load delays, and also to update the delay slot statistics. */
1543 final_prescan_insn (rtx insn, rtx opvec[] ATTRIBUTE_UNUSED,
1544 int noperands ATTRIBUTE_UNUSED)
1546 if (dslots_number_nops > 0)
1548 rtx pattern = PATTERN (insn);
1549 int length = get_attr_length (insn);
1551 /* Do we need to emit a NOP? */
1553 || (iq2000_load_reg != 0 && reg_mentioned_p (iq2000_load_reg, pattern))
1554 || (iq2000_load_reg2 != 0 && reg_mentioned_p (iq2000_load_reg2, pattern))
1555 || (iq2000_load_reg3 != 0 && reg_mentioned_p (iq2000_load_reg3, pattern))
1556 || (iq2000_load_reg4 != 0
1557 && reg_mentioned_p (iq2000_load_reg4, pattern)))
1558 fputs ("\tnop\n", asm_out_file);
1561 dslots_load_filled ++;
1563 while (--dslots_number_nops > 0)
1564 fputs ("\tnop\n", asm_out_file);
1566 iq2000_load_reg = 0;
1567 iq2000_load_reg2 = 0;
1568 iq2000_load_reg3 = 0;
1569 iq2000_load_reg4 = 0;
1572 if ( (GET_CODE (insn) == JUMP_INSN
1573 || GET_CODE (insn) == CALL_INSN
1574 || (GET_CODE (PATTERN (insn)) == RETURN))
1575 && NEXT_INSN (PREV_INSN (insn)) == insn)
1577 rtx nop_insn = emit_insn_after (gen_nop (), insn);
1579 INSN_ADDRESSES_NEW (nop_insn, -1);
1583 && (GET_CODE (insn) == JUMP_INSN || GET_CODE (insn) == CALL_INSN))
1584 dslots_jump_total ++;
1587 /* Return the bytes needed to compute the frame pointer from the current
1588 stack pointer where SIZE is the # of var. bytes allocated.
1590 IQ2000 stack frames look like:
1592 Before call After call
1593 +-----------------------+ +-----------------------+
1596 | caller's temps. | | caller's temps. |
1598 +-----------------------+ +-----------------------+
1600 | arguments on stack. | | arguments on stack. |
1602 +-----------------------+ +-----------------------+
1603 | 4 words to save | | 4 words to save |
1604 | arguments passed | | arguments passed |
1605 | in registers, even | | in registers, even |
1606 SP->| if not passed. | VFP->| if not passed. |
1607 +-----------------------+ +-----------------------+
1609 | fp register save |
1611 +-----------------------+
1613 | gp register save |
1615 +-----------------------+
1619 +-----------------------+
1621 | alloca allocations |
1623 +-----------------------+
1625 | GP save for V.4 abi |
1627 +-----------------------+
1629 | arguments on stack |
1631 +-----------------------+
1633 | arguments passed |
1634 | in registers, even |
1635 low SP->| if not passed. |
1636 memory +-----------------------+ */
1639 compute_frame_size (HOST_WIDE_INT size)
1642 HOST_WIDE_INT total_size; /* # bytes that the entire frame takes up. */
1643 HOST_WIDE_INT var_size; /* # bytes that variables take up. */
1644 HOST_WIDE_INT args_size; /* # bytes that outgoing arguments take up. */
1645 HOST_WIDE_INT extra_size; /* # extra bytes. */
1646 HOST_WIDE_INT gp_reg_rounded; /* # bytes needed to store gp after rounding. */
1647 HOST_WIDE_INT gp_reg_size; /* # bytes needed to store gp regs. */
1648 HOST_WIDE_INT fp_reg_size; /* # bytes needed to store fp regs. */
1649 long mask; /* mask of saved gp registers. */
1654 extra_size = IQ2000_STACK_ALIGN ((0));
1655 var_size = IQ2000_STACK_ALIGN (size);
1656 args_size = IQ2000_STACK_ALIGN (crtl->outgoing_args_size);
1658 /* If a function dynamically allocates the stack and
1659 has 0 for STACK_DYNAMIC_OFFSET then allocate some stack space. */
1660 if (args_size == 0 && cfun->calls_alloca)
1661 args_size = 4 * UNITS_PER_WORD;
1663 total_size = var_size + args_size + extra_size;
1665 /* Calculate space needed for gp registers. */
1666 for (regno = GP_REG_FIRST; regno <= GP_REG_LAST; regno++)
1668 if (MUST_SAVE_REGISTER (regno))
1670 gp_reg_size += GET_MODE_SIZE (gpr_mode);
1671 mask |= 1L << (regno - GP_REG_FIRST);
1675 /* We need to restore these for the handler. */
1676 if (crtl->calls_eh_return)
1682 regno = EH_RETURN_DATA_REGNO (i);
1683 if (regno == (int) INVALID_REGNUM)
1685 gp_reg_size += GET_MODE_SIZE (gpr_mode);
1686 mask |= 1L << (regno - GP_REG_FIRST);
1690 gp_reg_rounded = IQ2000_STACK_ALIGN (gp_reg_size);
1691 total_size += gp_reg_rounded + IQ2000_STACK_ALIGN (fp_reg_size);
1693 /* The gp reg is caller saved, so there is no need for leaf routines
1694 (total_size == extra_size) to save the gp reg. */
1695 if (total_size == extra_size
1697 total_size = extra_size = 0;
1699 total_size += IQ2000_STACK_ALIGN (crtl->args.pretend_args_size);
1701 /* Save other computed information. */
1702 cfun->machine->total_size = total_size;
1703 cfun->machine->var_size = var_size;
1704 cfun->machine->args_size = args_size;
1705 cfun->machine->extra_size = extra_size;
1706 cfun->machine->gp_reg_size = gp_reg_size;
1707 cfun->machine->fp_reg_size = fp_reg_size;
1708 cfun->machine->mask = mask;
1709 cfun->machine->initialized = reload_completed;
1710 cfun->machine->num_gp = gp_reg_size / UNITS_PER_WORD;
1714 unsigned long offset;
1716 offset = (args_size + extra_size + var_size
1717 + gp_reg_size - GET_MODE_SIZE (gpr_mode));
1719 cfun->machine->gp_sp_offset = offset;
1720 cfun->machine->gp_save_offset = offset - total_size;
1724 cfun->machine->gp_sp_offset = 0;
1725 cfun->machine->gp_save_offset = 0;
1728 cfun->machine->fp_sp_offset = 0;
1729 cfun->machine->fp_save_offset = 0;
1731 /* Ok, we're done. */
1736 /* We can always eliminate to the frame pointer. We can eliminate to the
1737 stack pointer unless a frame pointer is needed. */
1740 iq2000_can_eliminate (const int from, const int to)
1742 return (from == RETURN_ADDRESS_POINTER_REGNUM
1743 && (! leaf_function_p ()
1744 || (to == GP_REG_FIRST + 31 && leaf_function_p ())))
1745 || (from != RETURN_ADDRESS_POINTER_REGNUM
1746 && (to == HARD_FRAME_POINTER_REGNUM
1747 || (to == STACK_POINTER_REGNUM
1748 && ! frame_pointer_needed)));
1751 /* Implement INITIAL_ELIMINATION_OFFSET. FROM is either the frame
1752 pointer, argument pointer, or return address pointer. TO is either
1753 the stack pointer or hard frame pointer. */
1756 iq2000_initial_elimination_offset (int from, int to ATTRIBUTE_UNUSED)
1760 compute_frame_size (get_frame_size ());
1761 if ((from) == FRAME_POINTER_REGNUM)
1763 else if ((from) == ARG_POINTER_REGNUM)
1764 (offset) = (cfun->machine->total_size);
1765 else if ((from) == RETURN_ADDRESS_POINTER_REGNUM)
1767 if (leaf_function_p ())
1769 else (offset) = cfun->machine->gp_sp_offset
1770 + ((UNITS_PER_WORD - (POINTER_SIZE / BITS_PER_UNIT))
1771 * (BYTES_BIG_ENDIAN != 0));
1779 /* Common code to emit the insns (or to write the instructions to a file)
1780 to save/restore registers.
1781 Other parts of the code assume that IQ2000_TEMP1_REGNUM (aka large_reg)
1782 is not modified within save_restore_insns. */
1784 #define BITSET_P(VALUE,BIT) (((VALUE) & (1L << (BIT))) != 0)
1786 /* Emit instructions to load the value (SP + OFFSET) into IQ2000_TEMP2_REGNUM
1787 and return an rtl expression for the register. Write the assembly
1788 instructions directly to FILE if it is not null, otherwise emit them as
1791 This function is a subroutine of save_restore_insns. It is used when
1792 OFFSET is too large to add in a single instruction. */
1795 iq2000_add_large_offset_to_sp (HOST_WIDE_INT offset)
1797 rtx reg = gen_rtx_REG (Pmode, IQ2000_TEMP2_REGNUM);
1798 rtx offset_rtx = GEN_INT (offset);
1800 emit_move_insn (reg, offset_rtx);
1801 emit_insn (gen_addsi3 (reg, reg, stack_pointer_rtx));
1805 /* Make INSN frame related and note that it performs the frame-related
1806 operation DWARF_PATTERN. */
1809 iq2000_annotate_frame_insn (rtx insn, rtx dwarf_pattern)
1811 RTX_FRAME_RELATED_P (insn) = 1;
1812 REG_NOTES (insn) = alloc_EXPR_LIST (REG_FRAME_RELATED_EXPR,
1817 /* Emit a move instruction that stores REG in MEM. Make the instruction
1818 frame related and note that it stores REG at (SP + OFFSET). */
1821 iq2000_emit_frame_related_store (rtx mem, rtx reg, HOST_WIDE_INT offset)
1823 rtx dwarf_address = plus_constant (stack_pointer_rtx, offset);
1824 rtx dwarf_mem = gen_rtx_MEM (GET_MODE (reg), dwarf_address);
1826 iq2000_annotate_frame_insn (emit_move_insn (mem, reg),
1827 gen_rtx_SET (GET_MODE (reg), dwarf_mem, reg));
1830 /* Emit instructions to save/restore registers, as determined by STORE_P. */
1833 save_restore_insns (int store_p)
1835 long mask = cfun->machine->mask;
1838 HOST_WIDE_INT base_offset;
1839 HOST_WIDE_INT gp_offset;
1840 HOST_WIDE_INT end_offset;
1842 gcc_assert (!frame_pointer_needed
1843 || BITSET_P (mask, HARD_FRAME_POINTER_REGNUM - GP_REG_FIRST));
1847 base_reg_rtx = 0, base_offset = 0;
1851 /* Save registers starting from high to low. The debuggers prefer at least
1852 the return register be stored at func+4, and also it allows us not to
1853 need a nop in the epilog if at least one register is reloaded in
1854 addition to return address. */
1856 /* Save GP registers if needed. */
1857 /* Pick which pointer to use as a base register. For small frames, just
1858 use the stack pointer. Otherwise, use a temporary register. Save 2
1859 cycles if the save area is near the end of a large frame, by reusing
1860 the constant created in the prologue/epilogue to adjust the stack
1863 gp_offset = cfun->machine->gp_sp_offset;
1865 = gp_offset - (cfun->machine->gp_reg_size
1866 - GET_MODE_SIZE (gpr_mode));
1868 if (gp_offset < 0 || end_offset < 0)
1870 ("gp_offset (%ld) or end_offset (%ld) is less than zero",
1871 (long) gp_offset, (long) end_offset);
1873 else if (gp_offset < 32768)
1874 base_reg_rtx = stack_pointer_rtx, base_offset = 0;
1878 int reg_save_count = 0;
1880 for (regno = GP_REG_LAST; regno >= GP_REG_FIRST; regno--)
1881 if (BITSET_P (mask, regno - GP_REG_FIRST)) reg_save_count += 1;
1882 base_offset = gp_offset - ((reg_save_count - 1) * 4);
1883 base_reg_rtx = iq2000_add_large_offset_to_sp (base_offset);
1886 for (regno = GP_REG_LAST; regno >= GP_REG_FIRST; regno--)
1888 if (BITSET_P (mask, regno - GP_REG_FIRST))
1892 = gen_rtx_MEM (gpr_mode,
1893 gen_rtx_PLUS (Pmode, base_reg_rtx,
1894 GEN_INT (gp_offset - base_offset)));
1896 reg_rtx = gen_rtx_REG (gpr_mode, regno);
1899 iq2000_emit_frame_related_store (mem_rtx, reg_rtx, gp_offset);
1902 emit_move_insn (reg_rtx, mem_rtx);
1904 gp_offset -= GET_MODE_SIZE (gpr_mode);
1909 /* Expand the prologue into a bunch of separate insns. */
1912 iq2000_expand_prologue (void)
1915 HOST_WIDE_INT tsize;
1916 int last_arg_is_vararg_marker = 0;
1917 tree fndecl = current_function_decl;
1918 tree fntype = TREE_TYPE (fndecl);
1919 tree fnargs = DECL_ARGUMENTS (fndecl);
1924 CUMULATIVE_ARGS args_so_far;
1925 int store_args_on_stack = (iq2000_can_use_return_insn ());
1927 /* If struct value address is treated as the first argument. */
1928 if (aggregate_value_p (DECL_RESULT (fndecl), fndecl)
1929 && !cfun->returns_pcc_struct
1930 && targetm.calls.struct_value_rtx (TREE_TYPE (fndecl), 1) == 0)
1932 tree type = build_pointer_type (fntype);
1933 tree function_result_decl = build_decl (BUILTINS_LOCATION,
1934 PARM_DECL, NULL_TREE, type);
1936 DECL_ARG_TYPE (function_result_decl) = type;
1937 DECL_CHAIN (function_result_decl) = fnargs;
1938 fnargs = function_result_decl;
1941 /* For arguments passed in registers, find the register number
1942 of the first argument in the variable part of the argument list,
1943 otherwise GP_ARG_LAST+1. Note also if the last argument is
1944 the varargs special argument, and treat it as part of the
1947 This is only needed if store_args_on_stack is true. */
1948 INIT_CUMULATIVE_ARGS (args_so_far, fntype, NULL_RTX, 0, 0);
1949 regno = GP_ARG_FIRST;
1951 for (cur_arg = fnargs; cur_arg != 0; cur_arg = next_arg)
1953 tree passed_type = DECL_ARG_TYPE (cur_arg);
1954 enum machine_mode passed_mode = TYPE_MODE (passed_type);
1957 if (TREE_ADDRESSABLE (passed_type))
1959 passed_type = build_pointer_type (passed_type);
1960 passed_mode = Pmode;
1963 entry_parm = iq2000_function_arg (&args_so_far, passed_mode,
1966 iq2000_function_arg_advance (&args_so_far, passed_mode,
1968 next_arg = DECL_CHAIN (cur_arg);
1970 if (entry_parm && store_args_on_stack)
1973 && DECL_NAME (cur_arg)
1974 && ((0 == strcmp (IDENTIFIER_POINTER (DECL_NAME (cur_arg)),
1975 "__builtin_va_alist"))
1976 || (0 == strcmp (IDENTIFIER_POINTER (DECL_NAME (cur_arg)),
1979 last_arg_is_vararg_marker = 1;
1986 gcc_assert (GET_CODE (entry_parm) == REG);
1988 /* Passed in a register, so will get homed automatically. */
1989 if (GET_MODE (entry_parm) == BLKmode)
1990 words = (int_size_in_bytes (passed_type) + 3) / 4;
1992 words = (GET_MODE_SIZE (GET_MODE (entry_parm)) + 3) / 4;
1994 regno = REGNO (entry_parm) + words - 1;
1999 regno = GP_ARG_LAST+1;
2004 /* In order to pass small structures by value in registers we need to
2005 shift the value into the high part of the register.
2006 iq2000_unction_arg has encoded a PARALLEL rtx, holding a vector of
2007 adjustments to be made as the next_arg_reg variable, so we split up
2008 the insns, and emit them separately. */
2009 next_arg_reg = iq2000_function_arg (&args_so_far, VOIDmode,
2010 void_type_node, true);
2011 if (next_arg_reg != 0 && GET_CODE (next_arg_reg) == PARALLEL)
2013 rtvec adjust = XVEC (next_arg_reg, 0);
2014 int num = GET_NUM_ELEM (adjust);
2016 for (i = 0; i < num; i++)
2020 pattern = RTVEC_ELT (adjust, i);
2021 if (GET_CODE (pattern) != SET
2022 || GET_CODE (SET_SRC (pattern)) != ASHIFT)
2023 abort_with_insn (pattern, "Insn is not a shift");
2024 PUT_CODE (SET_SRC (pattern), ASHIFTRT);
2026 emit_insn (pattern);
2030 tsize = compute_frame_size (get_frame_size ());
2032 /* If this function is a varargs function, store any registers that
2033 would normally hold arguments ($4 - $7) on the stack. */
2034 if (store_args_on_stack
2035 && (stdarg_p (fntype)
2036 || last_arg_is_vararg_marker))
2038 int offset = (regno - GP_ARG_FIRST) * UNITS_PER_WORD;
2039 rtx ptr = stack_pointer_rtx;
2041 for (; regno <= GP_ARG_LAST; regno++)
2044 ptr = gen_rtx_PLUS (Pmode, stack_pointer_rtx, GEN_INT (offset));
2045 emit_move_insn (gen_rtx_MEM (gpr_mode, ptr),
2046 gen_rtx_REG (gpr_mode, regno));
2048 offset += GET_MODE_SIZE (gpr_mode);
2054 rtx tsize_rtx = GEN_INT (tsize);
2055 rtx adjustment_rtx, insn, dwarf_pattern;
2059 adjustment_rtx = gen_rtx_REG (Pmode, IQ2000_TEMP1_REGNUM);
2060 emit_move_insn (adjustment_rtx, tsize_rtx);
2063 adjustment_rtx = tsize_rtx;
2065 insn = emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
2068 dwarf_pattern = gen_rtx_SET (Pmode, stack_pointer_rtx,
2069 plus_constant (stack_pointer_rtx, -tsize));
2071 iq2000_annotate_frame_insn (insn, dwarf_pattern);
2073 save_restore_insns (1);
2075 if (frame_pointer_needed)
2079 insn = emit_insn (gen_movsi (hard_frame_pointer_rtx,
2080 stack_pointer_rtx));
2083 RTX_FRAME_RELATED_P (insn) = 1;
2087 emit_insn (gen_blockage ());
2090 /* Expand the epilogue into a bunch of separate insns. */
2093 iq2000_expand_epilogue (void)
2095 HOST_WIDE_INT tsize = cfun->machine->total_size;
2096 rtx tsize_rtx = GEN_INT (tsize);
2097 rtx tmp_rtx = (rtx)0;
2099 if (iq2000_can_use_return_insn ())
2101 emit_jump_insn (gen_return ());
2107 tmp_rtx = gen_rtx_REG (Pmode, IQ2000_TEMP1_REGNUM);
2108 emit_move_insn (tmp_rtx, tsize_rtx);
2109 tsize_rtx = tmp_rtx;
2114 if (frame_pointer_needed)
2116 emit_insn (gen_blockage ());
2118 emit_insn (gen_movsi (stack_pointer_rtx, hard_frame_pointer_rtx));
2121 save_restore_insns (0);
2123 if (crtl->calls_eh_return)
2125 rtx eh_ofs = EH_RETURN_STACKADJ_RTX;
2126 emit_insn (gen_addsi3 (eh_ofs, eh_ofs, tsize_rtx));
2130 emit_insn (gen_blockage ());
2132 if (tsize != 0 || crtl->calls_eh_return)
2134 emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx,
2139 if (crtl->calls_eh_return)
2141 /* Perform the additional bump for __throw. */
2142 emit_move_insn (gen_rtx_REG (Pmode, HARD_FRAME_POINTER_REGNUM),
2144 emit_use (gen_rtx_REG (Pmode, HARD_FRAME_POINTER_REGNUM));
2145 emit_jump_insn (gen_eh_return_internal ());
2148 emit_jump_insn (gen_return_internal (gen_rtx_REG (Pmode,
2149 GP_REG_FIRST + 31)));
2153 iq2000_expand_eh_return (rtx address)
2155 HOST_WIDE_INT gp_offset = cfun->machine->gp_sp_offset;
2158 scratch = plus_constant (stack_pointer_rtx, gp_offset);
2159 emit_move_insn (gen_rtx_MEM (GET_MODE (address), scratch), address);
2162 /* Return nonzero if this function is known to have a null epilogue.
2163 This allows the optimizer to omit jumps to jumps if no stack
2167 iq2000_can_use_return_insn (void)
2169 if (! reload_completed)
2172 if (df_regs_ever_live_p (31) || profile_flag)
2175 if (cfun->machine->initialized)
2176 return cfun->machine->total_size == 0;
2178 return compute_frame_size (get_frame_size ()) == 0;
2181 /* Choose the section to use for the constant rtx expression X that has
2185 iq2000_select_rtx_section (enum machine_mode mode, rtx x ATTRIBUTE_UNUSED,
2186 unsigned HOST_WIDE_INT align)
2188 /* For embedded applications, always put constants in read-only data,
2189 in order to reduce RAM usage. */
2190 return mergeable_constant_section (mode, align, 0);
2193 /* Choose the section to use for DECL. RELOC is true if its value contains
2194 any relocatable expression.
2196 Some of the logic used here needs to be replicated in
2197 ENCODE_SECTION_INFO in iq2000.h so that references to these symbols
2198 are done correctly. */
2201 iq2000_select_section (tree decl, int reloc ATTRIBUTE_UNUSED,
2202 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED)
2204 if (TARGET_EMBEDDED_DATA)
2206 /* For embedded applications, always put an object in read-only data
2207 if possible, in order to reduce RAM usage. */
2208 if ((TREE_CODE (decl) == VAR_DECL
2209 && TREE_READONLY (decl) && !TREE_SIDE_EFFECTS (decl)
2210 && DECL_INITIAL (decl)
2211 && (DECL_INITIAL (decl) == error_mark_node
2212 || TREE_CONSTANT (DECL_INITIAL (decl))))
2213 /* Deal with calls from output_constant_def_contents. */
2214 || TREE_CODE (decl) != VAR_DECL)
2215 return readonly_data_section;
2217 return data_section;
2221 /* For hosted applications, always put an object in small data if
2222 possible, as this gives the best performance. */
2223 if ((TREE_CODE (decl) == VAR_DECL
2224 && TREE_READONLY (decl) && !TREE_SIDE_EFFECTS (decl)
2225 && DECL_INITIAL (decl)
2226 && (DECL_INITIAL (decl) == error_mark_node
2227 || TREE_CONSTANT (DECL_INITIAL (decl))))
2228 /* Deal with calls from output_constant_def_contents. */
2229 || TREE_CODE (decl) != VAR_DECL)
2230 return readonly_data_section;
2232 return data_section;
2235 /* Return register to use for a function return value with VALTYPE for function
2239 iq2000_function_value (const_tree valtype,
2240 const_tree fn_decl_or_type,
2241 bool outgoing ATTRIBUTE_UNUSED)
2243 int reg = GP_RETURN;
2244 enum machine_mode mode = TYPE_MODE (valtype);
2245 int unsignedp = TYPE_UNSIGNED (valtype);
2246 const_tree func = fn_decl_or_type;
2249 && !DECL_P (fn_decl_or_type))
2250 fn_decl_or_type = NULL;
2252 /* Since we promote return types, we must promote the mode here too. */
2253 mode = promote_function_mode (valtype, mode, &unsignedp, func, 1);
2255 return gen_rtx_REG (mode, reg);
2258 /* Worker function for TARGET_LIBCALL_VALUE. */
2261 iq2000_libcall_value (enum machine_mode mode, const_rtx fun ATTRIBUTE_UNUSED)
2263 return gen_rtx_REG (((GET_MODE_CLASS (mode) != MODE_INT
2264 || GET_MODE_SIZE (mode) >= 4)
2269 /* Worker function for FUNCTION_VALUE_REGNO_P.
2271 On the IQ2000, R2 and R3 are the only register thus used. */
2274 iq2000_function_value_regno_p (const unsigned int regno)
2276 return (regno == GP_RETURN);
2280 /* Return true when an argument must be passed by reference. */
2283 iq2000_pass_by_reference (CUMULATIVE_ARGS *cum, enum machine_mode mode,
2284 const_tree type, bool named ATTRIBUTE_UNUSED)
2288 /* We must pass by reference if we would be both passing in registers
2289 and the stack. This is because any subsequent partial arg would be
2290 handled incorrectly in this case. */
2291 if (cum && targetm.calls.must_pass_in_stack (mode, type))
2293 /* Don't pass the actual CUM to FUNCTION_ARG, because we would
2294 get double copies of any offsets generated for small structs
2295 passed in registers. */
2296 CUMULATIVE_ARGS temp;
2299 if (iq2000_function_arg (&temp, mode, type, named) != 0)
2303 if (type == NULL_TREE || mode == DImode || mode == DFmode)
2306 size = int_size_in_bytes (type);
2307 return size == -1 || size > UNITS_PER_WORD;
2310 /* Return the length of INSN. LENGTH is the initial length computed by
2311 attributes in the machine-description file. */
2314 iq2000_adjust_insn_length (rtx insn, int length)
2316 /* A unconditional jump has an unfilled delay slot if it is not part
2317 of a sequence. A conditional jump normally has a delay slot. */
2318 if (simplejump_p (insn)
2319 || ( (GET_CODE (insn) == JUMP_INSN
2320 || GET_CODE (insn) == CALL_INSN)))
2326 /* Output assembly instructions to perform a conditional branch.
2328 INSN is the branch instruction. OPERANDS[0] is the condition.
2329 OPERANDS[1] is the target of the branch. OPERANDS[2] is the target
2330 of the first operand to the condition. If TWO_OPERANDS_P is
2331 nonzero the comparison takes two operands; OPERANDS[3] will be the
2334 If INVERTED_P is nonzero we are to branch if the condition does
2335 not hold. If FLOAT_P is nonzero this is a floating-point comparison.
2337 LENGTH is the length (in bytes) of the sequence we are to generate.
2338 That tells us whether to generate a simple conditional branch, or a
2339 reversed conditional branch around a `jr' instruction. */
2342 iq2000_output_conditional_branch (rtx insn, rtx * operands, int two_operands_p,
2343 int float_p, int inverted_p, int length)
2345 static char buffer[200];
2346 /* The kind of comparison we are doing. */
2347 enum rtx_code code = GET_CODE (operands[0]);
2348 /* Nonzero if the opcode for the comparison needs a `z' indicating
2349 that it is a comparison against zero. */
2351 /* A string to use in the assembly output to represent the first
2353 const char *op1 = "%z2";
2354 /* A string to use in the assembly output to represent the second
2355 operand. Use the hard-wired zero register if there's no second
2357 const char *op2 = (two_operands_p ? ",%z3" : ",%.");
2358 /* The operand-printing string for the comparison. */
2359 const char *comp = (float_p ? "%F0" : "%C0");
2360 /* The operand-printing string for the inverted comparison. */
2361 const char *inverted_comp = (float_p ? "%W0" : "%N0");
2363 /* Likely variants of each branch instruction annul the instruction
2364 in the delay slot if the branch is not taken. */
2365 iq2000_branch_likely = (final_sequence && INSN_ANNULLED_BRANCH_P (insn));
2367 if (!two_operands_p)
2369 /* To compute whether than A > B, for example, we normally
2370 subtract B from A and then look at the sign bit. But, if we
2371 are doing an unsigned comparison, and B is zero, we don't
2372 have to do the subtraction. Instead, we can just check to
2373 see if A is nonzero. Thus, we change the CODE here to
2374 reflect the simpler comparison operation. */
2386 /* A condition which will always be true. */
2392 /* A condition which will always be false. */
2398 /* Not a special case. */
2403 /* Relative comparisons are always done against zero. But
2404 equality comparisons are done between two operands, and therefore
2405 do not require a `z' in the assembly language output. */
2406 need_z_p = (!float_p && code != EQ && code != NE);
2407 /* For comparisons against zero, the zero is not provided
2412 /* Begin by terminating the buffer. That way we can always use
2413 strcat to add to it. */
2420 /* Just a simple conditional branch. */
2422 sprintf (buffer, "b%s%%?\t%%Z2%%1",
2423 inverted_p ? inverted_comp : comp);
2425 sprintf (buffer, "b%s%s%%?\t%s%s,%%1",
2426 inverted_p ? inverted_comp : comp,
2427 need_z_p ? "z" : "",
2435 /* Generate a reversed conditional branch around ` j'
2447 Because we have to jump four bytes *past* the following
2448 instruction if this branch was annulled, we can't just use
2449 a label, as in the picture above; there's no way to put the
2450 label after the next instruction, as the assembler does not
2451 accept `.L+4' as the target of a branch. (We can't just
2452 wait until the next instruction is output; it might be a
2453 macro and take up more than four bytes. Once again, we see
2454 why we want to eliminate macros.)
2456 If the branch is annulled, we jump four more bytes that we
2457 would otherwise; that way we skip the annulled instruction
2458 in the delay slot. */
2461 = ((iq2000_branch_likely || length == 16) ? ".+16" : ".+12");
2464 c = strchr (buffer, '\0');
2465 /* Generate the reversed comparison. This takes four
2468 sprintf (c, "b%s\t%%Z2%s",
2469 inverted_p ? comp : inverted_comp,
2472 sprintf (c, "b%s%s\t%s%s,%s",
2473 inverted_p ? comp : inverted_comp,
2474 need_z_p ? "z" : "",
2478 strcat (c, "\n\tnop\n\tj\t%1");
2480 /* The delay slot was unfilled. Since we're inside
2481 .noreorder, the assembler will not fill in the NOP for
2482 us, so we must do it ourselves. */
2483 strcat (buffer, "\n\tnop");
2495 #define def_builtin(NAME, TYPE, CODE) \
2496 add_builtin_function ((NAME), (TYPE), (CODE), BUILT_IN_MD, \
2500 iq2000_init_builtins (void)
2502 tree endlink = void_list_node;
2503 tree void_ftype, void_ftype_int, void_ftype_int_int;
2504 tree void_ftype_int_int_int;
2505 tree int_ftype_int, int_ftype_int_int, int_ftype_int_int_int;
2506 tree int_ftype_int_int_int_int;
2510 = build_function_type (void_type_node,
2511 tree_cons (NULL_TREE, void_type_node, endlink));
2515 = build_function_type (void_type_node,
2516 tree_cons (NULL_TREE, integer_type_node, endlink));
2518 /* void func (int, int) */
2520 = build_function_type (void_type_node,
2521 tree_cons (NULL_TREE, integer_type_node,
2522 tree_cons (NULL_TREE, integer_type_node,
2525 /* int func (int) */
2527 = build_function_type (integer_type_node,
2528 tree_cons (NULL_TREE, integer_type_node, endlink));
2530 /* int func (int, int) */
2532 = build_function_type (integer_type_node,
2533 tree_cons (NULL_TREE, integer_type_node,
2534 tree_cons (NULL_TREE, integer_type_node,
2537 /* void func (int, int, int) */
2538 void_ftype_int_int_int
2539 = build_function_type
2541 tree_cons (NULL_TREE, integer_type_node,
2542 tree_cons (NULL_TREE, integer_type_node,
2543 tree_cons (NULL_TREE,
2547 /* int func (int, int, int, int) */
2548 int_ftype_int_int_int_int
2549 = build_function_type
2551 tree_cons (NULL_TREE, integer_type_node,
2552 tree_cons (NULL_TREE, integer_type_node,
2553 tree_cons (NULL_TREE,
2555 tree_cons (NULL_TREE,
2559 /* int func (int, int, int) */
2560 int_ftype_int_int_int
2561 = build_function_type
2563 tree_cons (NULL_TREE, integer_type_node,
2564 tree_cons (NULL_TREE, integer_type_node,
2565 tree_cons (NULL_TREE,
2569 /* int func (int, int, int, int) */
2570 int_ftype_int_int_int_int
2571 = build_function_type
2573 tree_cons (NULL_TREE, integer_type_node,
2574 tree_cons (NULL_TREE, integer_type_node,
2575 tree_cons (NULL_TREE,
2577 tree_cons (NULL_TREE,
2581 def_builtin ("__builtin_ado16", int_ftype_int_int, IQ2000_BUILTIN_ADO16);
2582 def_builtin ("__builtin_ram", int_ftype_int_int_int_int, IQ2000_BUILTIN_RAM);
2583 def_builtin ("__builtin_chkhdr", void_ftype_int_int, IQ2000_BUILTIN_CHKHDR);
2584 def_builtin ("__builtin_pkrl", void_ftype_int_int, IQ2000_BUILTIN_PKRL);
2585 def_builtin ("__builtin_cfc0", int_ftype_int, IQ2000_BUILTIN_CFC0);
2586 def_builtin ("__builtin_cfc1", int_ftype_int, IQ2000_BUILTIN_CFC1);
2587 def_builtin ("__builtin_cfc2", int_ftype_int, IQ2000_BUILTIN_CFC2);
2588 def_builtin ("__builtin_cfc3", int_ftype_int, IQ2000_BUILTIN_CFC3);
2589 def_builtin ("__builtin_ctc0", void_ftype_int_int, IQ2000_BUILTIN_CTC0);
2590 def_builtin ("__builtin_ctc1", void_ftype_int_int, IQ2000_BUILTIN_CTC1);
2591 def_builtin ("__builtin_ctc2", void_ftype_int_int, IQ2000_BUILTIN_CTC2);
2592 def_builtin ("__builtin_ctc3", void_ftype_int_int, IQ2000_BUILTIN_CTC3);
2593 def_builtin ("__builtin_mfc0", int_ftype_int, IQ2000_BUILTIN_MFC0);
2594 def_builtin ("__builtin_mfc1", int_ftype_int, IQ2000_BUILTIN_MFC1);
2595 def_builtin ("__builtin_mfc2", int_ftype_int, IQ2000_BUILTIN_MFC2);
2596 def_builtin ("__builtin_mfc3", int_ftype_int, IQ2000_BUILTIN_MFC3);
2597 def_builtin ("__builtin_mtc0", void_ftype_int_int, IQ2000_BUILTIN_MTC0);
2598 def_builtin ("__builtin_mtc1", void_ftype_int_int, IQ2000_BUILTIN_MTC1);
2599 def_builtin ("__builtin_mtc2", void_ftype_int_int, IQ2000_BUILTIN_MTC2);
2600 def_builtin ("__builtin_mtc3", void_ftype_int_int, IQ2000_BUILTIN_MTC3);
2601 def_builtin ("__builtin_lur", void_ftype_int_int, IQ2000_BUILTIN_LUR);
2602 def_builtin ("__builtin_rb", void_ftype_int_int, IQ2000_BUILTIN_RB);
2603 def_builtin ("__builtin_rx", void_ftype_int_int, IQ2000_BUILTIN_RX);
2604 def_builtin ("__builtin_srrd", void_ftype_int, IQ2000_BUILTIN_SRRD);
2605 def_builtin ("__builtin_srwr", void_ftype_int_int, IQ2000_BUILTIN_SRWR);
2606 def_builtin ("__builtin_wb", void_ftype_int_int, IQ2000_BUILTIN_WB);
2607 def_builtin ("__builtin_wx", void_ftype_int_int, IQ2000_BUILTIN_WX);
2608 def_builtin ("__builtin_luc32l", void_ftype_int_int, IQ2000_BUILTIN_LUC32L);
2609 def_builtin ("__builtin_luc64", void_ftype_int_int, IQ2000_BUILTIN_LUC64);
2610 def_builtin ("__builtin_luc64l", void_ftype_int_int, IQ2000_BUILTIN_LUC64L);
2611 def_builtin ("__builtin_luk", void_ftype_int_int, IQ2000_BUILTIN_LUK);
2612 def_builtin ("__builtin_lulck", void_ftype_int, IQ2000_BUILTIN_LULCK);
2613 def_builtin ("__builtin_lum32", void_ftype_int_int, IQ2000_BUILTIN_LUM32);
2614 def_builtin ("__builtin_lum32l", void_ftype_int_int, IQ2000_BUILTIN_LUM32L);
2615 def_builtin ("__builtin_lum64", void_ftype_int_int, IQ2000_BUILTIN_LUM64);
2616 def_builtin ("__builtin_lum64l", void_ftype_int_int, IQ2000_BUILTIN_LUM64L);
2617 def_builtin ("__builtin_lurl", void_ftype_int_int, IQ2000_BUILTIN_LURL);
2618 def_builtin ("__builtin_mrgb", int_ftype_int_int_int, IQ2000_BUILTIN_MRGB);
2619 def_builtin ("__builtin_srrdl", void_ftype_int, IQ2000_BUILTIN_SRRDL);
2620 def_builtin ("__builtin_srulck", void_ftype_int, IQ2000_BUILTIN_SRULCK);
2621 def_builtin ("__builtin_srwru", void_ftype_int_int, IQ2000_BUILTIN_SRWRU);
2622 def_builtin ("__builtin_trapqfl", void_ftype, IQ2000_BUILTIN_TRAPQFL);
2623 def_builtin ("__builtin_trapqne", void_ftype, IQ2000_BUILTIN_TRAPQNE);
2624 def_builtin ("__builtin_traprel", void_ftype_int, IQ2000_BUILTIN_TRAPREL);
2625 def_builtin ("__builtin_wbu", void_ftype_int_int_int, IQ2000_BUILTIN_WBU);
2626 def_builtin ("__builtin_syscall", void_ftype, IQ2000_BUILTIN_SYSCALL);
2629 /* Builtin for ICODE having ARGCOUNT args in EXP where each arg
2633 expand_one_builtin (enum insn_code icode, rtx target, tree exp,
2634 enum rtx_code *code, int argcount)
2639 enum machine_mode mode [5];
2642 mode[0] = insn_data[icode].operand[0].mode;
2643 for (i = 0; i < argcount; i++)
2645 arg[i] = CALL_EXPR_ARG (exp, i);
2646 op[i] = expand_normal (arg[i]);
2647 mode[i] = insn_data[icode].operand[i].mode;
2648 if (code[i] == CONST_INT && GET_CODE (op[i]) != CONST_INT)
2649 error ("argument %qd is not a constant", i + 1);
2651 && ! (*insn_data[icode].operand[i].predicate) (op[i], mode[i]))
2652 op[i] = copy_to_mode_reg (mode[i], op[i]);
2655 if (insn_data[icode].operand[0].constraint[0] == '=')
2658 || GET_MODE (target) != mode[0]
2659 || ! (*insn_data[icode].operand[0].predicate) (target, mode[0]))
2660 target = gen_reg_rtx (mode[0]);
2668 pat = GEN_FCN (icode) (target);
2671 pat = GEN_FCN (icode) (target, op[0]);
2673 pat = GEN_FCN (icode) (op[0]);
2677 pat = GEN_FCN (icode) (target, op[0], op[1]);
2679 pat = GEN_FCN (icode) (op[0], op[1]);
2683 pat = GEN_FCN (icode) (target, op[0], op[1], op[2]);
2685 pat = GEN_FCN (icode) (op[0], op[1], op[2]);
2689 pat = GEN_FCN (icode) (target, op[0], op[1], op[2], op[3]);
2691 pat = GEN_FCN (icode) (op[0], op[1], op[2], op[3]);
2703 /* Expand an expression EXP that calls a built-in function,
2704 with result going to TARGET if that's convenient
2705 (and in mode MODE if that's convenient).
2706 SUBTARGET may be used as the target for computing one of EXP's operands.
2707 IGNORE is nonzero if the value is to be ignored. */
2710 iq2000_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED,
2711 enum machine_mode mode ATTRIBUTE_UNUSED,
2712 int ignore ATTRIBUTE_UNUSED)
2714 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
2715 int fcode = DECL_FUNCTION_CODE (fndecl);
2716 enum rtx_code code [5];
2728 case IQ2000_BUILTIN_ADO16:
2729 return expand_one_builtin (CODE_FOR_ado16, target, exp, code, 2);
2731 case IQ2000_BUILTIN_RAM:
2732 code[1] = CONST_INT;
2733 code[2] = CONST_INT;
2734 code[3] = CONST_INT;
2735 return expand_one_builtin (CODE_FOR_ram, target, exp, code, 4);
2737 case IQ2000_BUILTIN_CHKHDR:
2738 return expand_one_builtin (CODE_FOR_chkhdr, target, exp, code, 2);
2740 case IQ2000_BUILTIN_PKRL:
2741 return expand_one_builtin (CODE_FOR_pkrl, target, exp, code, 2);
2743 case IQ2000_BUILTIN_CFC0:
2744 code[0] = CONST_INT;
2745 return expand_one_builtin (CODE_FOR_cfc0, target, exp, code, 1);
2747 case IQ2000_BUILTIN_CFC1:
2748 code[0] = CONST_INT;
2749 return expand_one_builtin (CODE_FOR_cfc1, target, exp, code, 1);
2751 case IQ2000_BUILTIN_CFC2:
2752 code[0] = CONST_INT;
2753 return expand_one_builtin (CODE_FOR_cfc2, target, exp, code, 1);
2755 case IQ2000_BUILTIN_CFC3:
2756 code[0] = CONST_INT;
2757 return expand_one_builtin (CODE_FOR_cfc3, target, exp, code, 1);
2759 case IQ2000_BUILTIN_CTC0:
2760 code[1] = CONST_INT;
2761 return expand_one_builtin (CODE_FOR_ctc0, target, exp, code, 2);
2763 case IQ2000_BUILTIN_CTC1:
2764 code[1] = CONST_INT;
2765 return expand_one_builtin (CODE_FOR_ctc1, target, exp, code, 2);
2767 case IQ2000_BUILTIN_CTC2:
2768 code[1] = CONST_INT;
2769 return expand_one_builtin (CODE_FOR_ctc2, target, exp, code, 2);
2771 case IQ2000_BUILTIN_CTC3:
2772 code[1] = CONST_INT;
2773 return expand_one_builtin (CODE_FOR_ctc3, target, exp, code, 2);
2775 case IQ2000_BUILTIN_MFC0:
2776 code[0] = CONST_INT;
2777 return expand_one_builtin (CODE_FOR_mfc0, target, exp, code, 1);
2779 case IQ2000_BUILTIN_MFC1:
2780 code[0] = CONST_INT;
2781 return expand_one_builtin (CODE_FOR_mfc1, target, exp, code, 1);
2783 case IQ2000_BUILTIN_MFC2:
2784 code[0] = CONST_INT;
2785 return expand_one_builtin (CODE_FOR_mfc2, target, exp, code, 1);
2787 case IQ2000_BUILTIN_MFC3:
2788 code[0] = CONST_INT;
2789 return expand_one_builtin (CODE_FOR_mfc3, target, exp, code, 1);
2791 case IQ2000_BUILTIN_MTC0:
2792 code[1] = CONST_INT;
2793 return expand_one_builtin (CODE_FOR_mtc0, target, exp, code, 2);
2795 case IQ2000_BUILTIN_MTC1:
2796 code[1] = CONST_INT;
2797 return expand_one_builtin (CODE_FOR_mtc1, target, exp, code, 2);
2799 case IQ2000_BUILTIN_MTC2:
2800 code[1] = CONST_INT;
2801 return expand_one_builtin (CODE_FOR_mtc2, target, exp, code, 2);
2803 case IQ2000_BUILTIN_MTC3:
2804 code[1] = CONST_INT;
2805 return expand_one_builtin (CODE_FOR_mtc3, target, exp, code, 2);
2807 case IQ2000_BUILTIN_LUR:
2808 return expand_one_builtin (CODE_FOR_lur, target, exp, code, 2);
2810 case IQ2000_BUILTIN_RB:
2811 return expand_one_builtin (CODE_FOR_rb, target, exp, code, 2);
2813 case IQ2000_BUILTIN_RX:
2814 return expand_one_builtin (CODE_FOR_rx, target, exp, code, 2);
2816 case IQ2000_BUILTIN_SRRD:
2817 return expand_one_builtin (CODE_FOR_srrd, target, exp, code, 1);
2819 case IQ2000_BUILTIN_SRWR:
2820 return expand_one_builtin (CODE_FOR_srwr, target, exp, code, 2);
2822 case IQ2000_BUILTIN_WB:
2823 return expand_one_builtin (CODE_FOR_wb, target, exp, code, 2);
2825 case IQ2000_BUILTIN_WX:
2826 return expand_one_builtin (CODE_FOR_wx, target, exp, code, 2);
2828 case IQ2000_BUILTIN_LUC32L:
2829 return expand_one_builtin (CODE_FOR_luc32l, target, exp, code, 2);
2831 case IQ2000_BUILTIN_LUC64:
2832 return expand_one_builtin (CODE_FOR_luc64, target, exp, code, 2);
2834 case IQ2000_BUILTIN_LUC64L:
2835 return expand_one_builtin (CODE_FOR_luc64l, target, exp, code, 2);
2837 case IQ2000_BUILTIN_LUK:
2838 return expand_one_builtin (CODE_FOR_luk, target, exp, code, 2);
2840 case IQ2000_BUILTIN_LULCK:
2841 return expand_one_builtin (CODE_FOR_lulck, target, exp, code, 1);
2843 case IQ2000_BUILTIN_LUM32:
2844 return expand_one_builtin (CODE_FOR_lum32, target, exp, code, 2);
2846 case IQ2000_BUILTIN_LUM32L:
2847 return expand_one_builtin (CODE_FOR_lum32l, target, exp, code, 2);
2849 case IQ2000_BUILTIN_LUM64:
2850 return expand_one_builtin (CODE_FOR_lum64, target, exp, code, 2);
2852 case IQ2000_BUILTIN_LUM64L:
2853 return expand_one_builtin (CODE_FOR_lum64l, target, exp, code, 2);
2855 case IQ2000_BUILTIN_LURL:
2856 return expand_one_builtin (CODE_FOR_lurl, target, exp, code, 2);
2858 case IQ2000_BUILTIN_MRGB:
2859 code[2] = CONST_INT;
2860 return expand_one_builtin (CODE_FOR_mrgb, target, exp, code, 3);
2862 case IQ2000_BUILTIN_SRRDL:
2863 return expand_one_builtin (CODE_FOR_srrdl, target, exp, code, 1);
2865 case IQ2000_BUILTIN_SRULCK:
2866 return expand_one_builtin (CODE_FOR_srulck, target, exp, code, 1);
2868 case IQ2000_BUILTIN_SRWRU:
2869 return expand_one_builtin (CODE_FOR_srwru, target, exp, code, 2);
2871 case IQ2000_BUILTIN_TRAPQFL:
2872 return expand_one_builtin (CODE_FOR_trapqfl, target, exp, code, 0);
2874 case IQ2000_BUILTIN_TRAPQNE:
2875 return expand_one_builtin (CODE_FOR_trapqne, target, exp, code, 0);
2877 case IQ2000_BUILTIN_TRAPREL:
2878 return expand_one_builtin (CODE_FOR_traprel, target, exp, code, 1);
2880 case IQ2000_BUILTIN_WBU:
2881 return expand_one_builtin (CODE_FOR_wbu, target, exp, code, 3);
2883 case IQ2000_BUILTIN_SYSCALL:
2884 return expand_one_builtin (CODE_FOR_syscall, target, exp, code, 0);
2890 /* Worker function for TARGET_RETURN_IN_MEMORY. */
2893 iq2000_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED)
2895 return ((int_size_in_bytes (type) > (2 * UNITS_PER_WORD))
2896 || (int_size_in_bytes (type) == -1));
2899 /* Worker function for TARGET_SETUP_INCOMING_VARARGS. */
2902 iq2000_setup_incoming_varargs (CUMULATIVE_ARGS *cum,
2903 enum machine_mode mode ATTRIBUTE_UNUSED,
2904 tree type ATTRIBUTE_UNUSED, int * pretend_size,
2907 unsigned int iq2000_off = ! cum->last_arg_fp;
2908 unsigned int iq2000_fp_off = cum->last_arg_fp;
2910 if ((cum->arg_words < MAX_ARGS_IN_REGISTERS - iq2000_off))
2912 int iq2000_save_gp_regs
2913 = MAX_ARGS_IN_REGISTERS - cum->arg_words - iq2000_off;
2914 int iq2000_save_fp_regs
2915 = (MAX_ARGS_IN_REGISTERS - cum->fp_arg_words - iq2000_fp_off);
2917 if (iq2000_save_gp_regs < 0)
2918 iq2000_save_gp_regs = 0;
2919 if (iq2000_save_fp_regs < 0)
2920 iq2000_save_fp_regs = 0;
2922 *pretend_size = ((iq2000_save_gp_regs * UNITS_PER_WORD)
2923 + (iq2000_save_fp_regs * UNITS_PER_FPREG));
2927 if (cum->arg_words < MAX_ARGS_IN_REGISTERS - iq2000_off)
2930 ptr = plus_constant (virtual_incoming_args_rtx,
2931 - (iq2000_save_gp_regs
2933 mem = gen_rtx_MEM (BLKmode, ptr);
2935 (cum->arg_words + GP_ARG_FIRST + iq2000_off,
2937 iq2000_save_gp_regs);
2943 /* A C compound statement to output to stdio stream STREAM the
2944 assembler syntax for an instruction operand that is a memory
2945 reference whose address is ADDR. ADDR is an RTL expression. */
2948 iq2000_print_operand_address (FILE * file, rtx addr)
2951 error ("PRINT_OPERAND_ADDRESS, null pointer");
2954 switch (GET_CODE (addr))
2957 if (REGNO (addr) == ARG_POINTER_REGNUM)
2958 abort_with_insn (addr, "Arg pointer not eliminated.");
2960 fprintf (file, "0(%s)", reg_names [REGNO (addr)]);
2965 rtx arg0 = XEXP (addr, 0);
2966 rtx arg1 = XEXP (addr, 1);
2968 if (GET_CODE (arg0) != REG)
2969 abort_with_insn (addr,
2970 "PRINT_OPERAND_ADDRESS, LO_SUM with #1 not REG.");
2972 fprintf (file, "%%lo(");
2973 iq2000_print_operand_address (file, arg1);
2974 fprintf (file, ")(%s)", reg_names [REGNO (arg0)]);
2982 rtx arg0 = XEXP (addr, 0);
2983 rtx arg1 = XEXP (addr, 1);
2985 if (GET_CODE (arg0) == REG)
2989 if (GET_CODE (offset) == REG)
2990 abort_with_insn (addr, "PRINT_OPERAND_ADDRESS, 2 regs");
2993 else if (GET_CODE (arg1) == REG)
2994 reg = arg1, offset = arg0;
2995 else if (CONSTANT_P (arg0) && CONSTANT_P (arg1))
2997 output_addr_const (file, addr);
3001 abort_with_insn (addr, "PRINT_OPERAND_ADDRESS, no regs");
3003 if (! CONSTANT_P (offset))
3004 abort_with_insn (addr, "PRINT_OPERAND_ADDRESS, invalid insn #2");
3006 if (REGNO (reg) == ARG_POINTER_REGNUM)
3007 abort_with_insn (addr, "Arg pointer not eliminated.");
3009 output_addr_const (file, offset);
3010 fprintf (file, "(%s)", reg_names [REGNO (reg)]);
3018 output_addr_const (file, addr);
3019 if (GET_CODE (addr) == CONST_INT)
3020 fprintf (file, "(%s)", reg_names [0]);
3024 abort_with_insn (addr, "PRINT_OPERAND_ADDRESS, invalid insn #1");
3029 /* A C compound statement to output to stdio stream FILE the
3030 assembler syntax for an instruction operand OP.
3032 LETTER is a value that can be used to specify one of several ways
3033 of printing the operand. It is used when identical operands
3034 must be printed differently depending on the context. LETTER
3035 comes from the `%' specification that was used to request
3036 printing of the operand. If the specification was just `%DIGIT'
3037 then LETTER is 0; if the specification was `%LTR DIGIT' then LETTER
3038 is the ASCII code for LTR.
3040 If OP is a register, this macro should print the register's name.
3041 The names can be found in an array `reg_names' whose type is
3042 `char *[]'. `reg_names' is initialized from `REGISTER_NAMES'.
3044 When the machine description has a specification `%PUNCT' (a `%'
3045 followed by a punctuation character), this macro is called with
3046 a null pointer for X and the punctuation character for LETTER.
3048 The IQ2000 specific codes are:
3050 'X' X is CONST_INT, prints upper 16 bits in hexadecimal format = "0x%04x",
3051 'x' X is CONST_INT, prints lower 16 bits in hexadecimal format = "0x%04x",
3052 'd' output integer constant in decimal,
3053 'z' if the operand is 0, use $0 instead of normal operand.
3054 'D' print second part of double-word register or memory operand.
3055 'L' print low-order register of double-word register operand.
3056 'M' print high-order register of double-word register operand.
3057 'C' print part of opcode for a branch condition.
3058 'F' print part of opcode for a floating-point branch condition.
3059 'N' print part of opcode for a branch condition, inverted.
3060 'W' print part of opcode for a floating-point branch condition, inverted.
3061 'A' Print part of opcode for a bit test condition.
3062 'P' Print label for a bit test.
3063 'p' Print log for a bit test.
3064 'B' print 'z' for EQ, 'n' for NE
3065 'b' print 'n' for EQ, 'z' for NE
3066 'T' print 'f' for EQ, 't' for NE
3067 't' print 't' for EQ, 'f' for NE
3068 'Z' print register and a comma, but print nothing for $fcc0
3069 '?' Print 'l' if we are to use a branch likely instead of normal branch.
3070 '@' Print the name of the assembler temporary register (at or $1).
3071 '.' Print the name of the register with a hard-wired zero (zero or $0).
3072 '$' Print the name of the stack pointer register (sp or $29).
3073 '+' Print the name of the gp register (gp or $28). */
3076 iq2000_print_operand (FILE *file, rtx op, int letter)
3080 if (iq2000_print_operand_punct_valid_p (letter))
3085 if (iq2000_branch_likely)
3090 fputs (reg_names [GP_REG_FIRST + 1], file);
3094 fputs (reg_names [GP_REG_FIRST + 0], file);
3098 fputs (reg_names[STACK_POINTER_REGNUM], file);
3102 fputs (reg_names[GP_REG_FIRST + 28], file);
3106 error ("PRINT_OPERAND: Unknown punctuation '%c'", letter);
3115 error ("PRINT_OPERAND null pointer");
3119 code = GET_CODE (op);
3121 if (code == SIGN_EXTEND)
3122 op = XEXP (op, 0), code = GET_CODE (op);
3127 case EQ: fputs ("eq", file); break;
3128 case NE: fputs ("ne", file); break;
3129 case GT: fputs ("gt", file); break;
3130 case GE: fputs ("ge", file); break;
3131 case LT: fputs ("lt", file); break;
3132 case LE: fputs ("le", file); break;
3133 case GTU: fputs ("ne", file); break;
3134 case GEU: fputs ("geu", file); break;
3135 case LTU: fputs ("ltu", file); break;
3136 case LEU: fputs ("eq", file); break;
3138 abort_with_insn (op, "PRINT_OPERAND, invalid insn for %%C");
3141 else if (letter == 'N')
3144 case EQ: fputs ("ne", file); break;
3145 case NE: fputs ("eq", file); break;
3146 case GT: fputs ("le", file); break;
3147 case GE: fputs ("lt", file); break;
3148 case LT: fputs ("ge", file); break;
3149 case LE: fputs ("gt", file); break;
3150 case GTU: fputs ("leu", file); break;
3151 case GEU: fputs ("ltu", file); break;
3152 case LTU: fputs ("geu", file); break;
3153 case LEU: fputs ("gtu", file); break;
3155 abort_with_insn (op, "PRINT_OPERAND, invalid insn for %%N");
3158 else if (letter == 'F')
3161 case EQ: fputs ("c1f", file); break;
3162 case NE: fputs ("c1t", file); break;
3164 abort_with_insn (op, "PRINT_OPERAND, invalid insn for %%F");
3167 else if (letter == 'W')
3170 case EQ: fputs ("c1t", file); break;
3171 case NE: fputs ("c1f", file); break;
3173 abort_with_insn (op, "PRINT_OPERAND, invalid insn for %%W");
3176 else if (letter == 'A')
3177 fputs (code == LABEL_REF ? "i" : "in", file);
3179 else if (letter == 'P')
3181 if (code == LABEL_REF)
3182 output_addr_const (file, op);
3183 else if (code != PC)
3184 output_operand_lossage ("invalid %%P operand");
3187 else if (letter == 'p')
3190 if (code != CONST_INT
3191 || (value = exact_log2 (INTVAL (op))) < 0)
3192 output_operand_lossage ("invalid %%p value");
3194 fprintf (file, "%d", value);
3197 else if (letter == 'Z')
3202 else if (code == REG || code == SUBREG)
3207 regnum = REGNO (op);
3209 regnum = true_regnum (op);
3211 if ((letter == 'M' && ! WORDS_BIG_ENDIAN)
3212 || (letter == 'L' && WORDS_BIG_ENDIAN)
3216 fprintf (file, "%s", reg_names[regnum]);
3219 else if (code == MEM)
3222 output_address (plus_constant (XEXP (op, 0), 4));
3224 output_address (XEXP (op, 0));
3227 else if (code == CONST_DOUBLE
3228 && GET_MODE_CLASS (GET_MODE (op)) == MODE_FLOAT)
3232 real_to_decimal (s, CONST_DOUBLE_REAL_VALUE (op), sizeof (s), 0, 1);
3236 else if (letter == 'x' && GET_CODE (op) == CONST_INT)
3237 fprintf (file, HOST_WIDE_INT_PRINT_HEX, 0xffff & INTVAL(op));
3239 else if (letter == 'X' && GET_CODE(op) == CONST_INT)
3240 fprintf (file, HOST_WIDE_INT_PRINT_HEX, 0xffff & (INTVAL (op) >> 16));
3242 else if (letter == 'd' && GET_CODE(op) == CONST_INT)
3243 fprintf (file, HOST_WIDE_INT_PRINT_DEC, (INTVAL(op)));
3245 else if (letter == 'z' && GET_CODE (op) == CONST_INT && INTVAL (op) == 0)
3246 fputs (reg_names[GP_REG_FIRST], file);
3248 else if (letter == 'd' || letter == 'x' || letter == 'X')
3249 output_operand_lossage ("invalid use of %%d, %%x, or %%X");
3251 else if (letter == 'B')
3252 fputs (code == EQ ? "z" : "n", file);
3253 else if (letter == 'b')
3254 fputs (code == EQ ? "n" : "z", file);
3255 else if (letter == 'T')
3256 fputs (code == EQ ? "f" : "t", file);
3257 else if (letter == 't')
3258 fputs (code == EQ ? "t" : "f", file);
3260 else if (code == CONST && GET_CODE (XEXP (op, 0)) == REG)
3262 iq2000_print_operand (file, XEXP (op, 0), letter);
3266 output_addr_const (file, op);
3270 iq2000_print_operand_punct_valid_p (unsigned char code)
3272 return iq2000_print_operand_punct[code];
3275 /* For the IQ2000, transform:
3277 memory(X + <large int>)
3279 Y = <large int> & ~0x7fff;
3281 memory (Z + (<large int> & 0x7fff));
3285 iq2000_legitimize_address (rtx xinsn, rtx old_x ATTRIBUTE_UNUSED,
3286 enum machine_mode mode)
3288 if (TARGET_DEBUG_B_MODE)
3290 GO_PRINTF ("\n========== LEGITIMIZE_ADDRESS\n");
3291 GO_DEBUG_RTX (xinsn);
3294 if (iq2000_check_split (xinsn, mode))
3296 return gen_rtx_LO_SUM (Pmode,
3297 copy_to_mode_reg (Pmode,
3298 gen_rtx_HIGH (Pmode, xinsn)),
3302 if (GET_CODE (xinsn) == PLUS)
3304 rtx xplus0 = XEXP (xinsn, 0);
3305 rtx xplus1 = XEXP (xinsn, 1);
3306 enum rtx_code code0 = GET_CODE (xplus0);
3307 enum rtx_code code1 = GET_CODE (xplus1);
3309 if (code0 != REG && code1 == REG)
3311 xplus0 = XEXP (xinsn, 1);
3312 xplus1 = XEXP (xinsn, 0);
3313 code0 = GET_CODE (xplus0);
3314 code1 = GET_CODE (xplus1);
3317 if (code0 == REG && REG_MODE_OK_FOR_BASE_P (xplus0, mode)
3318 && code1 == CONST_INT && !SMALL_INT (xplus1))
3320 rtx int_reg = gen_reg_rtx (Pmode);
3321 rtx ptr_reg = gen_reg_rtx (Pmode);
3323 emit_move_insn (int_reg,
3324 GEN_INT (INTVAL (xplus1) & ~ 0x7fff));
3326 emit_insn (gen_rtx_SET (VOIDmode,
3328 gen_rtx_PLUS (Pmode, xplus0, int_reg)));
3330 return plus_constant (ptr_reg, INTVAL (xplus1) & 0x7fff);
3334 if (TARGET_DEBUG_B_MODE)
3335 GO_PRINTF ("LEGITIMIZE_ADDRESS could not fix.\n");
3342 iq2000_rtx_costs (rtx x, int code, int outer_code ATTRIBUTE_UNUSED, int * total,
3343 bool speed ATTRIBUTE_UNUSED)
3345 enum machine_mode mode = GET_MODE (x);
3351 int num_words = (GET_MODE_SIZE (mode) > UNITS_PER_WORD) ? 2 : 1;
3353 if (simple_memory_operand (x, mode))
3354 return COSTS_N_INSNS (num_words);
3356 * total = COSTS_N_INSNS (2 * num_words);
3361 * total = COSTS_N_INSNS (6);
3368 * total = COSTS_N_INSNS (mode == DImode ? 2 : 1);
3375 * total = COSTS_N_INSNS ((GET_CODE (XEXP (x, 1)) == CONST_INT) ? 4 : 12);
3377 * total = COSTS_N_INSNS (1);
3381 if (mode == SFmode || mode == DFmode)
3382 * total = COSTS_N_INSNS (1);
3384 * total = COSTS_N_INSNS (4);
3389 if (mode == SFmode || mode == DFmode)
3390 * total = COSTS_N_INSNS (6);
3391 else if (mode == DImode)
3392 * total = COSTS_N_INSNS (4);
3394 * total = COSTS_N_INSNS (1);
3398 * total = (mode == DImode) ? 4 : 1;
3403 * total = COSTS_N_INSNS (7);
3404 else if (mode == DFmode)
3405 * total = COSTS_N_INSNS (8);
3407 * total = COSTS_N_INSNS (10);
3413 * total = COSTS_N_INSNS (23);
3414 else if (mode == DFmode)
3415 * total = COSTS_N_INSNS (36);
3417 * total = COSTS_N_INSNS (69);
3422 * total = COSTS_N_INSNS (69);
3426 * total = COSTS_N_INSNS (2);
3430 * total = COSTS_N_INSNS (1);
3438 * total = COSTS_N_INSNS (2);
3443 rtx offset = const0_rtx;
3444 rtx symref = eliminate_constant_term (XEXP (x, 0), & offset);
3446 if (GET_CODE (symref) == LABEL_REF)
3447 * total = COSTS_N_INSNS (2);
3448 else if (GET_CODE (symref) != SYMBOL_REF)
3449 * total = COSTS_N_INSNS (4);
3450 /* Let's be paranoid.... */
3451 else if (INTVAL (offset) < -32768 || INTVAL (offset) > 32767)
3452 * total = COSTS_N_INSNS (2);
3454 * total = COSTS_N_INSNS (SYMBOL_REF_FLAG (symref) ? 1 : 2);
3459 * total = COSTS_N_INSNS (SYMBOL_REF_FLAG (x) ? 1 : 2);
3466 split_double (x, & high, & low);
3468 * total = COSTS_N_INSNS ( (high == CONST0_RTX (GET_MODE (high))
3469 || low == CONST0_RTX (GET_MODE (low)))
3480 /* Worker for TARGET_ASM_TRAMPOLINE_TEMPLATE. */
3483 iq2000_asm_trampoline_template (FILE *f)
3485 fprintf (f, "\t.word\t0x03e00821\t\t# move $1,$31\n");
3486 fprintf (f, "\t.word\t0x04110001\t\t# bgezal $0,.+8\n");
3487 fprintf (f, "\t.word\t0x00000000\t\t# nop\n");
3488 if (Pmode == DImode)
3490 fprintf (f, "\t.word\t0xdfe30014\t\t# ld $3,20($31)\n");
3491 fprintf (f, "\t.word\t0xdfe2001c\t\t# ld $2,28($31)\n");
3495 fprintf (f, "\t.word\t0x8fe30014\t\t# lw $3,20($31)\n");
3496 fprintf (f, "\t.word\t0x8fe20018\t\t# lw $2,24($31)\n");
3498 fprintf (f, "\t.word\t0x0060c821\t\t# move $25,$3 (abicalls)\n");
3499 fprintf (f, "\t.word\t0x00600008\t\t# jr $3\n");
3500 fprintf (f, "\t.word\t0x0020f821\t\t# move $31,$1\n");
3501 fprintf (f, "\t.word\t0x00000000\t\t# <function address>\n");
3502 fprintf (f, "\t.word\t0x00000000\t\t# <static chain value>\n");
3505 /* Worker for TARGET_TRAMPOLINE_INIT. */
3508 iq2000_trampoline_init (rtx m_tramp, tree fndecl, rtx chain_value)
3510 rtx fnaddr = XEXP (DECL_RTL (fndecl), 0);
3513 emit_block_move (m_tramp, assemble_trampoline_template (),
3514 GEN_INT (TRAMPOLINE_CODE_SIZE), BLOCK_OP_NORMAL);
3516 mem = adjust_address (m_tramp, Pmode, TRAMPOLINE_CODE_SIZE);
3517 emit_move_insn (mem, fnaddr);
3518 mem = adjust_address (m_tramp, Pmode,
3519 TRAMPOLINE_CODE_SIZE + GET_MODE_SIZE (Pmode));
3520 emit_move_insn (mem, chain_value);
3523 #include "gt-iq2000.h"