1 /* Subroutines used for code generation on Vitesse IQ2000 processors
2 Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011
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 /* Which instruction set architecture to use. */
117 /* Local variables. */
119 /* The next branch instruction is a branch likely, not branch normal. */
120 static int iq2000_branch_likely;
122 /* Count of delay slots and how many are filled. */
123 static int dslots_load_total;
124 static int dslots_load_filled;
125 static int dslots_jump_total;
127 /* # of nops needed by previous insn. */
128 static int dslots_number_nops;
130 /* Number of 1/2/3 word references to data items (i.e., not jal's). */
131 static int num_refs[3];
133 /* Registers to check for load delay. */
134 static rtx iq2000_load_reg;
135 static rtx iq2000_load_reg2;
136 static rtx iq2000_load_reg3;
137 static rtx iq2000_load_reg4;
139 /* Mode used for saving/restoring general purpose registers. */
140 static enum machine_mode gpr_mode;
143 /* Initialize the GCC target structure. */
144 static struct machine_function* iq2000_init_machine_status (void);
145 static void iq2000_option_override (void);
146 static section *iq2000_select_rtx_section (enum machine_mode, rtx,
147 unsigned HOST_WIDE_INT);
148 static void iq2000_init_builtins (void);
149 static rtx iq2000_expand_builtin (tree, rtx, rtx, enum machine_mode, int);
150 static bool iq2000_return_in_memory (const_tree, const_tree);
151 static void iq2000_setup_incoming_varargs (cumulative_args_t,
152 enum machine_mode, tree, int *,
154 static bool iq2000_rtx_costs (rtx, int, int, int, int *, bool);
155 static int iq2000_address_cost (rtx, bool);
156 static section *iq2000_select_section (tree, int, unsigned HOST_WIDE_INT);
157 static rtx iq2000_legitimize_address (rtx, rtx, enum machine_mode);
158 static bool iq2000_pass_by_reference (cumulative_args_t, enum machine_mode,
160 static int iq2000_arg_partial_bytes (cumulative_args_t, enum machine_mode,
162 static rtx iq2000_function_arg (cumulative_args_t,
163 enum machine_mode, const_tree, bool);
164 static void iq2000_function_arg_advance (cumulative_args_t,
165 enum machine_mode, const_tree, bool);
166 static unsigned int iq2000_function_arg_boundary (enum machine_mode,
168 static void iq2000_va_start (tree, rtx);
169 static bool iq2000_legitimate_address_p (enum machine_mode, rtx, bool);
170 static bool iq2000_can_eliminate (const int, const int);
171 static void iq2000_asm_trampoline_template (FILE *);
172 static void iq2000_trampoline_init (rtx, tree, rtx);
173 static rtx iq2000_function_value (const_tree, const_tree, bool);
174 static rtx iq2000_libcall_value (enum machine_mode, const_rtx);
175 static void iq2000_print_operand (FILE *, rtx, int);
176 static void iq2000_print_operand_address (FILE *, rtx);
177 static bool iq2000_print_operand_punct_valid_p (unsigned char code);
179 #undef TARGET_INIT_BUILTINS
180 #define TARGET_INIT_BUILTINS iq2000_init_builtins
181 #undef TARGET_EXPAND_BUILTIN
182 #define TARGET_EXPAND_BUILTIN iq2000_expand_builtin
183 #undef TARGET_ASM_SELECT_RTX_SECTION
184 #define TARGET_ASM_SELECT_RTX_SECTION iq2000_select_rtx_section
185 #undef TARGET_OPTION_OVERRIDE
186 #define TARGET_OPTION_OVERRIDE iq2000_option_override
187 #undef TARGET_RTX_COSTS
188 #define TARGET_RTX_COSTS iq2000_rtx_costs
189 #undef TARGET_ADDRESS_COST
190 #define TARGET_ADDRESS_COST iq2000_address_cost
191 #undef TARGET_ASM_SELECT_SECTION
192 #define TARGET_ASM_SELECT_SECTION iq2000_select_section
194 #undef TARGET_LEGITIMIZE_ADDRESS
195 #define TARGET_LEGITIMIZE_ADDRESS iq2000_legitimize_address
197 /* The assembler supports switchable .bss sections, but
198 iq2000_select_section doesn't yet make use of them. */
199 #undef TARGET_HAVE_SWITCHABLE_BSS_SECTIONS
200 #define TARGET_HAVE_SWITCHABLE_BSS_SECTIONS false
202 #undef TARGET_PRINT_OPERAND
203 #define TARGET_PRINT_OPERAND iq2000_print_operand
204 #undef TARGET_PRINT_OPERAND_ADDRESS
205 #define TARGET_PRINT_OPERAND_ADDRESS iq2000_print_operand_address
206 #undef TARGET_PRINT_OPERAND_PUNCT_VALID_P
207 #define TARGET_PRINT_OPERAND_PUNCT_VALID_P iq2000_print_operand_punct_valid_p
209 #undef TARGET_PROMOTE_FUNCTION_MODE
210 #define TARGET_PROMOTE_FUNCTION_MODE default_promote_function_mode_always_promote
211 #undef TARGET_PROMOTE_PROTOTYPES
212 #define TARGET_PROMOTE_PROTOTYPES hook_bool_const_tree_true
214 #undef TARGET_FUNCTION_VALUE
215 #define TARGET_FUNCTION_VALUE iq2000_function_value
216 #undef TARGET_LIBCALL_VALUE
217 #define TARGET_LIBCALL_VALUE iq2000_libcall_value
218 #undef TARGET_RETURN_IN_MEMORY
219 #define TARGET_RETURN_IN_MEMORY iq2000_return_in_memory
220 #undef TARGET_PASS_BY_REFERENCE
221 #define TARGET_PASS_BY_REFERENCE iq2000_pass_by_reference
222 #undef TARGET_CALLEE_COPIES
223 #define TARGET_CALLEE_COPIES hook_callee_copies_named
224 #undef TARGET_ARG_PARTIAL_BYTES
225 #define TARGET_ARG_PARTIAL_BYTES iq2000_arg_partial_bytes
226 #undef TARGET_FUNCTION_ARG
227 #define TARGET_FUNCTION_ARG iq2000_function_arg
228 #undef TARGET_FUNCTION_ARG_ADVANCE
229 #define TARGET_FUNCTION_ARG_ADVANCE iq2000_function_arg_advance
230 #undef TARGET_FUNCTION_ARG_BOUNDARY
231 #define TARGET_FUNCTION_ARG_BOUNDARY iq2000_function_arg_boundary
233 #undef TARGET_SETUP_INCOMING_VARARGS
234 #define TARGET_SETUP_INCOMING_VARARGS iq2000_setup_incoming_varargs
235 #undef TARGET_STRICT_ARGUMENT_NAMING
236 #define TARGET_STRICT_ARGUMENT_NAMING hook_bool_CUMULATIVE_ARGS_true
238 #undef TARGET_EXPAND_BUILTIN_VA_START
239 #define TARGET_EXPAND_BUILTIN_VA_START iq2000_va_start
241 #undef TARGET_LEGITIMATE_ADDRESS_P
242 #define TARGET_LEGITIMATE_ADDRESS_P iq2000_legitimate_address_p
244 #undef TARGET_CAN_ELIMINATE
245 #define TARGET_CAN_ELIMINATE iq2000_can_eliminate
247 #undef TARGET_ASM_TRAMPOLINE_TEMPLATE
248 #define TARGET_ASM_TRAMPOLINE_TEMPLATE iq2000_asm_trampoline_template
249 #undef TARGET_TRAMPOLINE_INIT
250 #define TARGET_TRAMPOLINE_INIT iq2000_trampoline_init
252 struct gcc_target targetm = TARGET_INITIALIZER;
254 /* Return nonzero if we split the address into high and low parts. */
257 iq2000_check_split (rtx address, enum machine_mode mode)
259 /* This is the same check used in simple_memory_operand.
260 We use it here because LO_SUM is not offsettable. */
261 if (GET_MODE_SIZE (mode) > (unsigned) UNITS_PER_WORD)
264 if ((GET_CODE (address) == SYMBOL_REF)
265 || (GET_CODE (address) == CONST
266 && GET_CODE (XEXP (XEXP (address, 0), 0)) == SYMBOL_REF)
267 || GET_CODE (address) == LABEL_REF)
273 /* Return nonzero if REG is valid for MODE. */
276 iq2000_reg_mode_ok_for_base_p (rtx reg,
277 enum machine_mode mode ATTRIBUTE_UNUSED,
281 ? REGNO_MODE_OK_FOR_BASE_P (REGNO (reg), mode)
282 : GP_REG_OR_PSEUDO_NONSTRICT_P (REGNO (reg), mode));
285 /* Return a nonzero value if XINSN is a legitimate address for a
286 memory operand of the indicated MODE. STRICT is nonzero if this
287 function is called during reload. */
290 iq2000_legitimate_address_p (enum machine_mode mode, rtx xinsn, bool strict)
292 if (TARGET_DEBUG_A_MODE)
294 GO_PRINTF2 ("\n========== legitimate_address_p, %sstrict\n",
295 strict ? "" : "not ");
296 GO_DEBUG_RTX (xinsn);
299 /* Check for constant before stripping off SUBREG, so that we don't
300 accept (subreg (const_int)) which will fail to reload. */
301 if (CONSTANT_ADDRESS_P (xinsn)
302 && ! (iq2000_check_split (xinsn, mode))
303 && ! (GET_CODE (xinsn) == CONST_INT && ! SMALL_INT (xinsn)))
306 while (GET_CODE (xinsn) == SUBREG)
307 xinsn = SUBREG_REG (xinsn);
309 if (GET_CODE (xinsn) == REG
310 && iq2000_reg_mode_ok_for_base_p (xinsn, mode, strict))
313 if (GET_CODE (xinsn) == LO_SUM)
315 rtx xlow0 = XEXP (xinsn, 0);
316 rtx xlow1 = XEXP (xinsn, 1);
318 while (GET_CODE (xlow0) == SUBREG)
319 xlow0 = SUBREG_REG (xlow0);
320 if (GET_CODE (xlow0) == REG
321 && iq2000_reg_mode_ok_for_base_p (xlow0, mode, strict)
322 && iq2000_check_split (xlow1, mode))
326 if (GET_CODE (xinsn) == PLUS)
328 rtx xplus0 = XEXP (xinsn, 0);
329 rtx xplus1 = XEXP (xinsn, 1);
333 while (GET_CODE (xplus0) == SUBREG)
334 xplus0 = SUBREG_REG (xplus0);
335 code0 = GET_CODE (xplus0);
337 while (GET_CODE (xplus1) == SUBREG)
338 xplus1 = SUBREG_REG (xplus1);
339 code1 = GET_CODE (xplus1);
342 && iq2000_reg_mode_ok_for_base_p (xplus0, mode, strict))
344 if (code1 == CONST_INT && SMALL_INT (xplus1)
345 && SMALL_INT_UNSIGNED (xplus1) /* No negative offsets */)
350 if (TARGET_DEBUG_A_MODE)
351 GO_PRINTF ("Not a enum machine_mode mode, legitimate address\n");
353 /* The address was not legitimate. */
357 /* Returns an operand string for the given instruction's delay slot,
358 after updating filled delay slot statistics.
360 We assume that operands[0] is the target register that is set.
362 In order to check the next insn, most of this functionality is moved
363 to FINAL_PRESCAN_INSN, and we just set the global variables that
367 iq2000_fill_delay_slot (const char *ret, enum delay_type type, rtx operands[],
371 enum machine_mode mode;
372 rtx next_insn = cur_insn ? NEXT_INSN (cur_insn) : NULL_RTX;
375 if (type == DELAY_LOAD || type == DELAY_FCMP)
381 /* Make sure that we don't put nop's after labels. */
382 next_insn = NEXT_INSN (cur_insn);
383 while (next_insn != 0
384 && (GET_CODE (next_insn) == NOTE
385 || GET_CODE (next_insn) == CODE_LABEL))
386 next_insn = NEXT_INSN (next_insn);
388 dslots_load_total += num_nops;
389 if (TARGET_DEBUG_C_MODE
390 || type == DELAY_NONE
394 || GET_CODE (next_insn) == CODE_LABEL
395 || (set_reg = operands[0]) == 0)
397 dslots_number_nops = 0;
399 iq2000_load_reg2 = 0;
400 iq2000_load_reg3 = 0;
401 iq2000_load_reg4 = 0;
406 set_reg = operands[0];
410 while (GET_CODE (set_reg) == SUBREG)
411 set_reg = SUBREG_REG (set_reg);
413 mode = GET_MODE (set_reg);
414 dslots_number_nops = num_nops;
415 iq2000_load_reg = set_reg;
416 if (GET_MODE_SIZE (mode)
417 > (unsigned) (UNITS_PER_WORD))
418 iq2000_load_reg2 = gen_rtx_REG (SImode, REGNO (set_reg) + 1);
420 iq2000_load_reg2 = 0;
425 /* Determine whether a memory reference takes one (based off of the GP
426 pointer), two (normal), or three (label + reg) instructions, and bump the
427 appropriate counter for -mstats. */
430 iq2000_count_memory_refs (rtx op, int num)
434 rtx addr, plus0, plus1;
435 enum rtx_code code0, code1;
438 if (TARGET_DEBUG_B_MODE)
440 fprintf (stderr, "\n========== iq2000_count_memory_refs:\n");
444 /* Skip MEM if passed, otherwise handle movsi of address. */
445 addr = (GET_CODE (op) != MEM) ? op : XEXP (op, 0);
447 /* Loop, going through the address RTL. */
451 switch (GET_CODE (addr))
459 plus0 = XEXP (addr, 0);
460 plus1 = XEXP (addr, 1);
461 code0 = GET_CODE (plus0);
462 code1 = GET_CODE (plus1);
472 if (code0 == CONST_INT)
487 if (code1 == CONST_INT)
494 if (code0 == SYMBOL_REF || code0 == LABEL_REF || code0 == CONST)
501 if (code1 == SYMBOL_REF || code1 == LABEL_REF || code1 == CONST)
511 n_words = 2; /* Always 2 words. */
515 addr = XEXP (addr, 0);
520 n_words = SYMBOL_REF_FLAG (addr) ? 1 : 2;
532 n_words += additional;
536 num_refs[n_words-1] += num;
539 /* Abort after printing out a specific insn. */
542 abort_with_insn (rtx insn, const char * reason)
546 fancy_abort (__FILE__, __LINE__, __FUNCTION__);
549 /* Return the appropriate instructions to move one operand to another. */
552 iq2000_move_1word (rtx operands[], rtx insn, int unsignedp)
555 rtx op0 = operands[0];
556 rtx op1 = operands[1];
557 enum rtx_code code0 = GET_CODE (op0);
558 enum rtx_code code1 = GET_CODE (op1);
559 enum machine_mode mode = GET_MODE (op0);
560 int subreg_offset0 = 0;
561 int subreg_offset1 = 0;
562 enum delay_type delay = DELAY_NONE;
564 while (code0 == SUBREG)
566 subreg_offset0 += subreg_regno_offset (REGNO (SUBREG_REG (op0)),
567 GET_MODE (SUBREG_REG (op0)),
570 op0 = SUBREG_REG (op0);
571 code0 = GET_CODE (op0);
574 while (code1 == SUBREG)
576 subreg_offset1 += subreg_regno_offset (REGNO (SUBREG_REG (op1)),
577 GET_MODE (SUBREG_REG (op1)),
580 op1 = SUBREG_REG (op1);
581 code1 = GET_CODE (op1);
584 /* For our purposes, a condition code mode is the same as SImode. */
590 int regno0 = REGNO (op0) + subreg_offset0;
594 int regno1 = REGNO (op1) + subreg_offset1;
596 /* Do not do anything for assigning a register to itself */
597 if (regno0 == regno1)
600 else if (GP_REG_P (regno0))
602 if (GP_REG_P (regno1))
603 ret = "or\t%0,%%0,%1";
608 else if (code1 == MEM)
613 iq2000_count_memory_refs (op1, 1);
615 if (GP_REG_P (regno0))
617 /* For loads, use the mode of the memory item, instead of the
618 target, so zero/sign extend can use this code as well. */
619 switch (GET_MODE (op1))
631 ret = (unsignedp) ? "lhu\t%0,%1" : "lh\t%0,%1";
634 ret = (unsignedp) ? "lbu\t%0,%1" : "lb\t%0,%1";
640 else if (code1 == CONST_INT
641 || (code1 == CONST_DOUBLE
642 && GET_MODE (op1) == VOIDmode))
644 if (code1 == CONST_DOUBLE)
646 /* This can happen when storing constants into long long
647 bitfields. Just store the least significant word of
649 operands[1] = op1 = GEN_INT (CONST_DOUBLE_LOW (op1));
652 if (INTVAL (op1) == 0)
654 if (GP_REG_P (regno0))
655 ret = "or\t%0,%%0,%z1";
657 else if (GP_REG_P (regno0))
659 if (SMALL_INT_UNSIGNED (op1))
660 ret = "ori\t%0,%%0,%x1\t\t\t# %1";
661 else if (SMALL_INT (op1))
662 ret = "addiu\t%0,%%0,%1\t\t\t# %1";
664 ret = "lui\t%0,%X1\t\t\t# %1\n\tori\t%0,%0,%x1";
668 else if (code1 == CONST_DOUBLE && mode == SFmode)
670 if (op1 == CONST0_RTX (SFmode))
672 if (GP_REG_P (regno0))
673 ret = "or\t%0,%%0,%.";
683 else if (code1 == LABEL_REF)
686 iq2000_count_memory_refs (op1, 1);
691 else if (code1 == SYMBOL_REF || code1 == CONST)
694 iq2000_count_memory_refs (op1, 1);
699 else if (code1 == PLUS)
701 rtx add_op0 = XEXP (op1, 0);
702 rtx add_op1 = XEXP (op1, 1);
704 if (GET_CODE (XEXP (op1, 1)) == REG
705 && GET_CODE (XEXP (op1, 0)) == CONST_INT)
706 add_op0 = XEXP (op1, 1), add_op1 = XEXP (op1, 0);
708 operands[2] = add_op0;
709 operands[3] = add_op1;
710 ret = "add%:\t%0,%2,%3";
713 else if (code1 == HIGH)
715 operands[1] = XEXP (op1, 0);
716 ret = "lui\t%0,%%hi(%1)";
720 else if (code0 == MEM)
723 iq2000_count_memory_refs (op0, 1);
727 int regno1 = REGNO (op1) + subreg_offset1;
729 if (GP_REG_P (regno1))
733 case SFmode: ret = "sw\t%1,%0"; break;
734 case SImode: ret = "sw\t%1,%0"; break;
735 case HImode: ret = "sh\t%1,%0"; break;
736 case QImode: ret = "sb\t%1,%0"; break;
742 else if (code1 == CONST_INT && INTVAL (op1) == 0)
746 case SFmode: ret = "sw\t%z1,%0"; break;
747 case SImode: ret = "sw\t%z1,%0"; break;
748 case HImode: ret = "sh\t%z1,%0"; break;
749 case QImode: ret = "sb\t%z1,%0"; break;
754 else if (code1 == CONST_DOUBLE && op1 == CONST0_RTX (mode))
758 case SFmode: ret = "sw\t%.,%0"; break;
759 case SImode: ret = "sw\t%.,%0"; break;
760 case HImode: ret = "sh\t%.,%0"; break;
761 case QImode: ret = "sb\t%.,%0"; break;
769 abort_with_insn (insn, "Bad move");
773 if (delay != DELAY_NONE)
774 return iq2000_fill_delay_slot (ret, delay, operands, insn);
779 /* Provide the costs of an addressing mode that contains ADDR. */
782 iq2000_address_cost (rtx addr, bool speed)
784 switch (GET_CODE (addr))
794 rtx offset = const0_rtx;
796 addr = eliminate_constant_term (XEXP (addr, 0), & offset);
797 if (GET_CODE (addr) == LABEL_REF)
800 if (GET_CODE (addr) != SYMBOL_REF)
803 if (! SMALL_INT (offset))
810 return SYMBOL_REF_FLAG (addr) ? 1 : 2;
814 rtx plus0 = XEXP (addr, 0);
815 rtx plus1 = XEXP (addr, 1);
817 if (GET_CODE (plus0) != REG && GET_CODE (plus1) == REG)
818 plus0 = XEXP (addr, 1), plus1 = XEXP (addr, 0);
820 if (GET_CODE (plus0) != REG)
823 switch (GET_CODE (plus1))
826 return SMALL_INT (plus1) ? 1 : 2;
833 return iq2000_address_cost (plus1, speed) + 1;
847 /* Make normal rtx_code into something we can index from an array. */
849 static enum internal_test
850 map_test_to_internal_test (enum rtx_code test_code)
852 enum internal_test test = ITEST_MAX;
856 case EQ: test = ITEST_EQ; break;
857 case NE: test = ITEST_NE; break;
858 case GT: test = ITEST_GT; break;
859 case GE: test = ITEST_GE; break;
860 case LT: test = ITEST_LT; break;
861 case LE: test = ITEST_LE; break;
862 case GTU: test = ITEST_GTU; break;
863 case GEU: test = ITEST_GEU; break;
864 case LTU: test = ITEST_LTU; break;
865 case LEU: test = ITEST_LEU; break;
872 /* Generate the code to do a TEST_CODE comparison on two integer values CMP0
873 and CMP1. P_INVERT is NULL or ptr if branch needs to reverse its test.
874 The return value RESULT is:
875 (reg:SI xx) The pseudo register the comparison is in
876 0 No register, generate a simple branch. */
879 gen_int_relational (enum rtx_code test_code, rtx result, rtx cmp0, rtx cmp1,
884 enum rtx_code test_code; /* Code to use in instruction (LT vs. LTU). */
885 int const_low; /* Low bound of constant we can accept. */
886 int const_high; /* High bound of constant we can accept. */
887 int const_add; /* Constant to add (convert LE -> LT). */
888 int reverse_regs; /* Reverse registers in test. */
889 int invert_const; /* != 0 if invert value if cmp1 is constant. */
890 int invert_reg; /* != 0 if invert value if cmp1 is register. */
891 int unsignedp; /* != 0 for unsigned comparisons. */
894 static struct cmp_info info[ (int)ITEST_MAX ] =
896 { XOR, 0, 65535, 0, 0, 0, 0, 0 }, /* EQ */
897 { XOR, 0, 65535, 0, 0, 1, 1, 0 }, /* NE */
898 { LT, -32769, 32766, 1, 1, 1, 0, 0 }, /* GT */
899 { LT, -32768, 32767, 0, 0, 1, 1, 0 }, /* GE */
900 { LT, -32768, 32767, 0, 0, 0, 0, 0 }, /* LT */
901 { LT, -32769, 32766, 1, 1, 0, 1, 0 }, /* LE */
902 { LTU, -32769, 32766, 1, 1, 1, 0, 1 }, /* GTU */
903 { LTU, -32768, 32767, 0, 0, 1, 1, 1 }, /* GEU */
904 { LTU, -32768, 32767, 0, 0, 0, 0, 1 }, /* LTU */
905 { LTU, -32769, 32766, 1, 1, 0, 1, 1 }, /* LEU */
908 enum internal_test test;
909 enum machine_mode mode;
910 struct cmp_info *p_info;
917 test = map_test_to_internal_test (test_code);
918 gcc_assert (test != ITEST_MAX);
920 p_info = &info[(int) test];
921 eqne_p = (p_info->test_code == XOR);
923 mode = GET_MODE (cmp0);
924 if (mode == VOIDmode)
925 mode = GET_MODE (cmp1);
927 /* Eliminate simple branches. */
928 branch_p = (result == 0);
931 if (GET_CODE (cmp0) == REG || GET_CODE (cmp0) == SUBREG)
933 /* Comparisons against zero are simple branches. */
934 if (GET_CODE (cmp1) == CONST_INT && INTVAL (cmp1) == 0)
937 /* Test for beq/bne. */
942 /* Allocate a pseudo to calculate the value in. */
943 result = gen_reg_rtx (mode);
946 /* Make sure we can handle any constants given to us. */
947 if (GET_CODE (cmp0) == CONST_INT)
948 cmp0 = force_reg (mode, cmp0);
950 if (GET_CODE (cmp1) == CONST_INT)
952 HOST_WIDE_INT value = INTVAL (cmp1);
954 if (value < p_info->const_low
955 || value > p_info->const_high)
956 cmp1 = force_reg (mode, cmp1);
959 /* See if we need to invert the result. */
960 invert = (GET_CODE (cmp1) == CONST_INT
961 ? p_info->invert_const : p_info->invert_reg);
963 if (p_invert != (int *)0)
969 /* Comparison to constants, may involve adding 1 to change a LT into LE.
970 Comparison between two registers, may involve switching operands. */
971 if (GET_CODE (cmp1) == CONST_INT)
973 if (p_info->const_add != 0)
975 HOST_WIDE_INT new_const = INTVAL (cmp1) + p_info->const_add;
977 /* If modification of cmp1 caused overflow,
978 we would get the wrong answer if we follow the usual path;
979 thus, x > 0xffffffffU would turn into x > 0U. */
980 if ((p_info->unsignedp
981 ? (unsigned HOST_WIDE_INT) new_const >
982 (unsigned HOST_WIDE_INT) INTVAL (cmp1)
983 : new_const > INTVAL (cmp1))
984 != (p_info->const_add > 0))
986 /* This test is always true, but if INVERT is true then
987 the result of the test needs to be inverted so 0 should
988 be returned instead. */
989 emit_move_insn (result, invert ? const0_rtx : const_true_rtx);
993 cmp1 = GEN_INT (new_const);
997 else if (p_info->reverse_regs)
1004 if (test == ITEST_NE && GET_CODE (cmp1) == CONST_INT && INTVAL (cmp1) == 0)
1008 reg = (invert || eqne_p) ? gen_reg_rtx (mode) : result;
1009 convert_move (reg, gen_rtx_fmt_ee (p_info->test_code, mode, cmp0, cmp1), 0);
1012 if (test == ITEST_NE)
1014 convert_move (result, gen_rtx_GTU (mode, reg, const0_rtx), 0);
1015 if (p_invert != NULL)
1020 else if (test == ITEST_EQ)
1022 reg2 = invert ? gen_reg_rtx (mode) : result;
1023 convert_move (reg2, gen_rtx_LTU (mode, reg, const1_rtx), 0);
1032 convert_move (result, gen_rtx_XOR (mode, reg, one), 0);
1038 /* Emit the common code for doing conditional branches.
1039 operand[0] is the label to jump to.
1040 The comparison operands are saved away by cmp{si,di,sf,df}. */
1043 gen_conditional_branch (rtx operands[], enum machine_mode mode)
1045 enum rtx_code test_code = GET_CODE (operands[0]);
1046 rtx cmp0 = operands[1];
1047 rtx cmp1 = operands[2];
1053 reg = gen_int_relational (test_code, NULL_RTX, cmp0, cmp1, &invert);
1061 else if (GET_CODE (cmp1) == CONST_INT && INTVAL (cmp1) != 0)
1062 /* We don't want to build a comparison against a nonzero
1064 cmp1 = force_reg (mode, cmp1);
1066 /* Generate the branch. */
1067 label1 = gen_rtx_LABEL_REF (VOIDmode, operands[3]);
1076 emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
1077 gen_rtx_IF_THEN_ELSE (VOIDmode,
1078 gen_rtx_fmt_ee (test_code,
1084 /* Initialize CUM for a function FNTYPE. */
1087 init_cumulative_args (CUMULATIVE_ARGS *cum, tree fntype,
1088 rtx libname ATTRIBUTE_UNUSED)
1090 static CUMULATIVE_ARGS zero_cum;
1094 if (TARGET_DEBUG_D_MODE)
1097 "\ninit_cumulative_args, fntype = 0x%.8lx", (long) fntype);
1100 fputc ('\n', stderr);
1104 tree ret_type = TREE_TYPE (fntype);
1106 fprintf (stderr, ", fntype code = %s, ret code = %s\n",
1107 tree_code_name[(int)TREE_CODE (fntype)],
1108 tree_code_name[(int)TREE_CODE (ret_type)]);
1114 /* Determine if this function has variable arguments. This is
1115 indicated by the last argument being 'void_type_mode' if there
1116 are no variable arguments. The standard IQ2000 calling sequence
1117 passes all arguments in the general purpose registers in this case. */
1119 for (param = fntype ? TYPE_ARG_TYPES (fntype) : 0;
1120 param != 0; param = next_param)
1122 next_param = TREE_CHAIN (param);
1123 if (next_param == 0 && TREE_VALUE (param) != void_type_node)
1124 cum->gp_reg_found = 1;
1128 /* Advance the argument of type TYPE and mode MODE to the next argument
1132 iq2000_function_arg_advance (cumulative_args_t cum_v, enum machine_mode mode,
1133 const_tree type, bool named)
1135 CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
1137 if (TARGET_DEBUG_D_MODE)
1140 "function_adv({gp reg found = %d, arg # = %2d, words = %2d}, %4s, ",
1141 cum->gp_reg_found, cum->arg_number, cum->arg_words,
1142 GET_MODE_NAME (mode));
1143 fprintf (stderr, "%p", type);
1144 fprintf (stderr, ", %d )\n\n", named);
1154 gcc_assert (GET_MODE_CLASS (mode) == MODE_COMPLEX_INT
1155 || GET_MODE_CLASS (mode) == MODE_COMPLEX_FLOAT);
1157 cum->gp_reg_found = 1;
1158 cum->arg_words += ((GET_MODE_SIZE (mode) + UNITS_PER_WORD - 1)
1163 cum->gp_reg_found = 1;
1164 cum->arg_words += ((int_size_in_bytes (type) + UNITS_PER_WORD - 1)
1170 if (! cum->gp_reg_found && cum->arg_number <= 2)
1171 cum->fp_code += 1 << ((cum->arg_number - 1) * 2);
1175 cum->arg_words += 2;
1176 if (! cum->gp_reg_found && cum->arg_number <= 2)
1177 cum->fp_code += 2 << ((cum->arg_number - 1) * 2);
1181 cum->gp_reg_found = 1;
1182 cum->arg_words += 2;
1186 cum->gp_reg_found = 1;
1187 cum->arg_words += 4;
1193 cum->gp_reg_found = 1;
1199 /* Return an RTL expression containing the register for the given mode MODE
1200 and type TYPE in CUM, or 0 if the argument is to be passed on the stack. */
1203 iq2000_function_arg (cumulative_args_t cum_v, enum machine_mode mode,
1204 const_tree type, bool named)
1206 CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
1210 unsigned int *arg_words = &cum->arg_words;
1211 int struct_p = (type != 0
1212 && (TREE_CODE (type) == RECORD_TYPE
1213 || TREE_CODE (type) == UNION_TYPE
1214 || TREE_CODE (type) == QUAL_UNION_TYPE));
1216 if (TARGET_DEBUG_D_MODE)
1219 "function_arg( {gp reg found = %d, arg # = %2d, words = %2d}, %4s, ",
1220 cum->gp_reg_found, cum->arg_number, cum->arg_words,
1221 GET_MODE_NAME (mode));
1222 fprintf (stderr, "%p", (const void *) type);
1223 fprintf (stderr, ", %d ) = ", named);
1227 cum->last_arg_fp = 0;
1231 regbase = GP_ARG_FIRST;
1235 cum->arg_words += cum->arg_words & 1;
1237 regbase = GP_ARG_FIRST;
1241 gcc_assert (GET_MODE_CLASS (mode) == MODE_COMPLEX_INT
1242 || GET_MODE_CLASS (mode) == MODE_COMPLEX_FLOAT);
1244 /* Drops through. */
1246 if (type != NULL_TREE && TYPE_ALIGN (type) > (unsigned) BITS_PER_WORD)
1247 cum->arg_words += (cum->arg_words & 1);
1248 regbase = GP_ARG_FIRST;
1255 regbase = GP_ARG_FIRST;
1259 cum->arg_words += (cum->arg_words & 1);
1260 regbase = GP_ARG_FIRST;
1264 cum->arg_words += (cum->arg_words & 3);
1265 regbase = GP_ARG_FIRST;
1269 if (*arg_words >= (unsigned) MAX_ARGS_IN_REGISTERS)
1271 if (TARGET_DEBUG_D_MODE)
1272 fprintf (stderr, "<stack>%s\n", struct_p ? ", [struct]" : "");
1278 gcc_assert (regbase != -1);
1280 if (! type || TREE_CODE (type) != RECORD_TYPE
1281 || ! named || ! TYPE_SIZE_UNIT (type)
1282 || ! host_integerp (TYPE_SIZE_UNIT (type), 1))
1283 ret = gen_rtx_REG (mode, regbase + *arg_words + bias);
1288 for (field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
1289 if (TREE_CODE (field) == FIELD_DECL
1290 && TREE_CODE (TREE_TYPE (field)) == REAL_TYPE
1291 && TYPE_PRECISION (TREE_TYPE (field)) == BITS_PER_WORD
1292 && host_integerp (bit_position (field), 0)
1293 && int_bit_position (field) % BITS_PER_WORD == 0)
1296 /* If the whole struct fits a DFmode register,
1297 we don't need the PARALLEL. */
1298 if (! field || mode == DFmode)
1299 ret = gen_rtx_REG (mode, regbase + *arg_words + bias);
1302 unsigned int chunks;
1303 HOST_WIDE_INT bitpos;
1307 /* ??? If this is a packed structure, then the last hunk won't
1310 = tree_low_cst (TYPE_SIZE_UNIT (type), 1) / UNITS_PER_WORD;
1311 if (chunks + *arg_words + bias > (unsigned) MAX_ARGS_IN_REGISTERS)
1312 chunks = MAX_ARGS_IN_REGISTERS - *arg_words - bias;
1314 /* Assign_parms checks the mode of ENTRY_PARM, so we must
1315 use the actual mode here. */
1316 ret = gen_rtx_PARALLEL (mode, rtvec_alloc (chunks));
1319 regno = regbase + *arg_words + bias;
1320 field = TYPE_FIELDS (type);
1321 for (i = 0; i < chunks; i++)
1325 for (; field; field = DECL_CHAIN (field))
1326 if (TREE_CODE (field) == FIELD_DECL
1327 && int_bit_position (field) >= bitpos)
1331 && int_bit_position (field) == bitpos
1332 && TREE_CODE (TREE_TYPE (field)) == REAL_TYPE
1333 && TYPE_PRECISION (TREE_TYPE (field)) == BITS_PER_WORD)
1334 reg = gen_rtx_REG (DFmode, regno++);
1336 reg = gen_rtx_REG (word_mode, regno);
1339 = gen_rtx_EXPR_LIST (VOIDmode, reg,
1340 GEN_INT (bitpos / BITS_PER_UNIT));
1348 if (TARGET_DEBUG_D_MODE)
1349 fprintf (stderr, "%s%s\n", reg_names[regbase + *arg_words + bias],
1350 struct_p ? ", [struct]" : "");
1353 /* We will be called with a mode of VOIDmode after the last argument
1354 has been seen. Whatever we return will be passed to the call
1355 insn. If we need any shifts for small structures, return them in
1357 if (mode == VOIDmode)
1359 if (cum->num_adjusts > 0)
1360 ret = gen_rtx_PARALLEL ((enum machine_mode) cum->fp_code,
1361 gen_rtvec_v (cum->num_adjusts, cum->adjust));
1368 iq2000_function_arg_boundary (enum machine_mode mode, const_tree type)
1370 return (type != NULL_TREE
1371 ? (TYPE_ALIGN (type) <= PARM_BOUNDARY
1373 : TYPE_ALIGN (type))
1374 : (GET_MODE_ALIGNMENT (mode) <= PARM_BOUNDARY
1376 : GET_MODE_ALIGNMENT (mode)));
1380 iq2000_arg_partial_bytes (cumulative_args_t cum_v, enum machine_mode mode,
1381 tree type ATTRIBUTE_UNUSED,
1382 bool named ATTRIBUTE_UNUSED)
1384 CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
1386 if (mode == DImode && cum->arg_words == MAX_ARGS_IN_REGISTERS - 1)
1388 if (TARGET_DEBUG_D_MODE)
1389 fprintf (stderr, "iq2000_arg_partial_bytes=%d\n", UNITS_PER_WORD);
1390 return UNITS_PER_WORD;
1396 /* Implement va_start. */
1399 iq2000_va_start (tree valist, rtx nextarg)
1402 /* Find out how many non-float named formals. */
1403 int gpr_save_area_size;
1404 /* Note UNITS_PER_WORD is 4 bytes. */
1405 int_arg_words = crtl->args.info.arg_words;
1407 if (int_arg_words < 8 )
1408 /* Adjust for the prologue's economy measure. */
1409 gpr_save_area_size = (8 - int_arg_words) * UNITS_PER_WORD;
1411 gpr_save_area_size = 0;
1413 /* Everything is in the GPR save area, or in the overflow
1414 area which is contiguous with it. */
1415 nextarg = plus_constant (Pmode, nextarg, - gpr_save_area_size);
1416 std_expand_builtin_va_start (valist, nextarg);
1419 /* Allocate a chunk of memory for per-function machine-dependent data. */
1421 static struct machine_function *
1422 iq2000_init_machine_status (void)
1424 return ggc_alloc_cleared_machine_function ();
1427 /* Detect any conflicts in the switches. */
1430 iq2000_option_override (void)
1432 target_flags &= ~MASK_GPOPT;
1434 iq2000_isa = IQ2000_ISA_DEFAULT;
1436 /* Identify the processor type. */
1438 iq2000_print_operand_punct['?'] = 1;
1439 iq2000_print_operand_punct['#'] = 1;
1440 iq2000_print_operand_punct['&'] = 1;
1441 iq2000_print_operand_punct['!'] = 1;
1442 iq2000_print_operand_punct['*'] = 1;
1443 iq2000_print_operand_punct['@'] = 1;
1444 iq2000_print_operand_punct['.'] = 1;
1445 iq2000_print_operand_punct['('] = 1;
1446 iq2000_print_operand_punct[')'] = 1;
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;
1458 /* Save GPR registers in word_mode sized hunks. word_mode hasn't been
1459 initialized yet, so we can't use that here. */
1462 /* Function to allocate machine-dependent function status. */
1463 init_machine_status = iq2000_init_machine_status;
1466 /* The arg pointer (which is eliminated) points to the virtual frame pointer,
1467 while the frame pointer (which may be eliminated) points to the stack
1468 pointer after the initial adjustments. */
1471 iq2000_debugger_offset (rtx addr, HOST_WIDE_INT offset)
1473 rtx offset2 = const0_rtx;
1474 rtx reg = eliminate_constant_term (addr, & offset2);
1477 offset = INTVAL (offset2);
1479 if (reg == stack_pointer_rtx || reg == frame_pointer_rtx
1480 || reg == hard_frame_pointer_rtx)
1482 HOST_WIDE_INT frame_size = (!cfun->machine->initialized)
1483 ? compute_frame_size (get_frame_size ())
1484 : cfun->machine->total_size;
1486 offset = offset - frame_size;
1492 /* If defined, a C statement to be executed just prior to the output of
1493 assembler code for INSN, to modify the extracted operands so they will be
1496 Here the argument OPVEC is the vector containing the operands extracted
1497 from INSN, and NOPERANDS is the number of elements of the vector which
1498 contain meaningful data for this insn. The contents of this vector are
1499 what will be used to convert the insn template into assembler code, so you
1500 can change the assembler output by changing the contents of the vector.
1502 We use it to check if the current insn needs a nop in front of it because
1503 of load delays, and also to update the delay slot statistics. */
1506 final_prescan_insn (rtx insn, rtx opvec[] ATTRIBUTE_UNUSED,
1507 int noperands ATTRIBUTE_UNUSED)
1509 if (dslots_number_nops > 0)
1511 rtx pattern = PATTERN (insn);
1512 int length = get_attr_length (insn);
1514 /* Do we need to emit a NOP? */
1516 || (iq2000_load_reg != 0 && reg_mentioned_p (iq2000_load_reg, pattern))
1517 || (iq2000_load_reg2 != 0 && reg_mentioned_p (iq2000_load_reg2, pattern))
1518 || (iq2000_load_reg3 != 0 && reg_mentioned_p (iq2000_load_reg3, pattern))
1519 || (iq2000_load_reg4 != 0
1520 && reg_mentioned_p (iq2000_load_reg4, pattern)))
1521 fputs ("\tnop\n", asm_out_file);
1524 dslots_load_filled ++;
1526 while (--dslots_number_nops > 0)
1527 fputs ("\tnop\n", asm_out_file);
1529 iq2000_load_reg = 0;
1530 iq2000_load_reg2 = 0;
1531 iq2000_load_reg3 = 0;
1532 iq2000_load_reg4 = 0;
1535 if ( (GET_CODE (insn) == JUMP_INSN
1536 || GET_CODE (insn) == CALL_INSN
1537 || (GET_CODE (PATTERN (insn)) == RETURN))
1538 && NEXT_INSN (PREV_INSN (insn)) == insn)
1540 rtx nop_insn = emit_insn_after (gen_nop (), insn);
1542 INSN_ADDRESSES_NEW (nop_insn, -1);
1546 && (GET_CODE (insn) == JUMP_INSN || GET_CODE (insn) == CALL_INSN))
1547 dslots_jump_total ++;
1550 /* Return the bytes needed to compute the frame pointer from the current
1551 stack pointer where SIZE is the # of var. bytes allocated.
1553 IQ2000 stack frames look like:
1555 Before call After call
1556 +-----------------------+ +-----------------------+
1559 | caller's temps. | | caller's temps. |
1561 +-----------------------+ +-----------------------+
1563 | arguments on stack. | | arguments on stack. |
1565 +-----------------------+ +-----------------------+
1566 | 4 words to save | | 4 words to save |
1567 | arguments passed | | arguments passed |
1568 | in registers, even | | in registers, even |
1569 SP->| if not passed. | VFP->| if not passed. |
1570 +-----------------------+ +-----------------------+
1572 | fp register save |
1574 +-----------------------+
1576 | gp register save |
1578 +-----------------------+
1582 +-----------------------+
1584 | alloca allocations |
1586 +-----------------------+
1588 | GP save for V.4 abi |
1590 +-----------------------+
1592 | arguments on stack |
1594 +-----------------------+
1596 | arguments passed |
1597 | in registers, even |
1598 low SP->| if not passed. |
1599 memory +-----------------------+ */
1602 compute_frame_size (HOST_WIDE_INT size)
1605 HOST_WIDE_INT total_size; /* # bytes that the entire frame takes up. */
1606 HOST_WIDE_INT var_size; /* # bytes that variables take up. */
1607 HOST_WIDE_INT args_size; /* # bytes that outgoing arguments take up. */
1608 HOST_WIDE_INT extra_size; /* # extra bytes. */
1609 HOST_WIDE_INT gp_reg_rounded; /* # bytes needed to store gp after rounding. */
1610 HOST_WIDE_INT gp_reg_size; /* # bytes needed to store gp regs. */
1611 HOST_WIDE_INT fp_reg_size; /* # bytes needed to store fp regs. */
1612 long mask; /* mask of saved gp registers. */
1617 extra_size = IQ2000_STACK_ALIGN ((0));
1618 var_size = IQ2000_STACK_ALIGN (size);
1619 args_size = IQ2000_STACK_ALIGN (crtl->outgoing_args_size);
1621 /* If a function dynamically allocates the stack and
1622 has 0 for STACK_DYNAMIC_OFFSET then allocate some stack space. */
1623 if (args_size == 0 && cfun->calls_alloca)
1624 args_size = 4 * UNITS_PER_WORD;
1626 total_size = var_size + args_size + extra_size;
1628 /* Calculate space needed for gp registers. */
1629 for (regno = GP_REG_FIRST; regno <= GP_REG_LAST; regno++)
1631 if (MUST_SAVE_REGISTER (regno))
1633 gp_reg_size += GET_MODE_SIZE (gpr_mode);
1634 mask |= 1L << (regno - GP_REG_FIRST);
1638 /* We need to restore these for the handler. */
1639 if (crtl->calls_eh_return)
1645 regno = EH_RETURN_DATA_REGNO (i);
1646 if (regno == (int) INVALID_REGNUM)
1648 gp_reg_size += GET_MODE_SIZE (gpr_mode);
1649 mask |= 1L << (regno - GP_REG_FIRST);
1653 gp_reg_rounded = IQ2000_STACK_ALIGN (gp_reg_size);
1654 total_size += gp_reg_rounded + IQ2000_STACK_ALIGN (fp_reg_size);
1656 /* The gp reg is caller saved, so there is no need for leaf routines
1657 (total_size == extra_size) to save the gp reg. */
1658 if (total_size == extra_size
1660 total_size = extra_size = 0;
1662 total_size += IQ2000_STACK_ALIGN (crtl->args.pretend_args_size);
1664 /* Save other computed information. */
1665 cfun->machine->total_size = total_size;
1666 cfun->machine->var_size = var_size;
1667 cfun->machine->args_size = args_size;
1668 cfun->machine->extra_size = extra_size;
1669 cfun->machine->gp_reg_size = gp_reg_size;
1670 cfun->machine->fp_reg_size = fp_reg_size;
1671 cfun->machine->mask = mask;
1672 cfun->machine->initialized = reload_completed;
1673 cfun->machine->num_gp = gp_reg_size / UNITS_PER_WORD;
1677 unsigned long offset;
1679 offset = (args_size + extra_size + var_size
1680 + gp_reg_size - GET_MODE_SIZE (gpr_mode));
1682 cfun->machine->gp_sp_offset = offset;
1683 cfun->machine->gp_save_offset = offset - total_size;
1687 cfun->machine->gp_sp_offset = 0;
1688 cfun->machine->gp_save_offset = 0;
1691 cfun->machine->fp_sp_offset = 0;
1692 cfun->machine->fp_save_offset = 0;
1694 /* Ok, we're done. */
1699 /* We can always eliminate to the frame pointer. We can eliminate to the
1700 stack pointer unless a frame pointer is needed. */
1703 iq2000_can_eliminate (const int from, const int to)
1705 return (from == RETURN_ADDRESS_POINTER_REGNUM
1706 && (! leaf_function_p ()
1707 || (to == GP_REG_FIRST + 31 && leaf_function_p ())))
1708 || (from != RETURN_ADDRESS_POINTER_REGNUM
1709 && (to == HARD_FRAME_POINTER_REGNUM
1710 || (to == STACK_POINTER_REGNUM
1711 && ! frame_pointer_needed)));
1714 /* Implement INITIAL_ELIMINATION_OFFSET. FROM is either the frame
1715 pointer, argument pointer, or return address pointer. TO is either
1716 the stack pointer or hard frame pointer. */
1719 iq2000_initial_elimination_offset (int from, int to ATTRIBUTE_UNUSED)
1723 compute_frame_size (get_frame_size ());
1724 if ((from) == FRAME_POINTER_REGNUM)
1726 else if ((from) == ARG_POINTER_REGNUM)
1727 (offset) = (cfun->machine->total_size);
1728 else if ((from) == RETURN_ADDRESS_POINTER_REGNUM)
1730 if (leaf_function_p ())
1732 else (offset) = cfun->machine->gp_sp_offset
1733 + ((UNITS_PER_WORD - (POINTER_SIZE / BITS_PER_UNIT))
1734 * (BYTES_BIG_ENDIAN != 0));
1742 /* Common code to emit the insns (or to write the instructions to a file)
1743 to save/restore registers.
1744 Other parts of the code assume that IQ2000_TEMP1_REGNUM (aka large_reg)
1745 is not modified within save_restore_insns. */
1747 #define BITSET_P(VALUE,BIT) (((VALUE) & (1L << (BIT))) != 0)
1749 /* Emit instructions to load the value (SP + OFFSET) into IQ2000_TEMP2_REGNUM
1750 and return an rtl expression for the register. Write the assembly
1751 instructions directly to FILE if it is not null, otherwise emit them as
1754 This function is a subroutine of save_restore_insns. It is used when
1755 OFFSET is too large to add in a single instruction. */
1758 iq2000_add_large_offset_to_sp (HOST_WIDE_INT offset)
1760 rtx reg = gen_rtx_REG (Pmode, IQ2000_TEMP2_REGNUM);
1761 rtx offset_rtx = GEN_INT (offset);
1763 emit_move_insn (reg, offset_rtx);
1764 emit_insn (gen_addsi3 (reg, reg, stack_pointer_rtx));
1768 /* Make INSN frame related and note that it performs the frame-related
1769 operation DWARF_PATTERN. */
1772 iq2000_annotate_frame_insn (rtx insn, rtx dwarf_pattern)
1774 RTX_FRAME_RELATED_P (insn) = 1;
1775 REG_NOTES (insn) = alloc_EXPR_LIST (REG_FRAME_RELATED_EXPR,
1780 /* Emit a move instruction that stores REG in MEM. Make the instruction
1781 frame related and note that it stores REG at (SP + OFFSET). */
1784 iq2000_emit_frame_related_store (rtx mem, rtx reg, HOST_WIDE_INT offset)
1786 rtx dwarf_address = plus_constant (Pmode, stack_pointer_rtx, offset);
1787 rtx dwarf_mem = gen_rtx_MEM (GET_MODE (reg), dwarf_address);
1789 iq2000_annotate_frame_insn (emit_move_insn (mem, reg),
1790 gen_rtx_SET (GET_MODE (reg), dwarf_mem, reg));
1793 /* Emit instructions to save/restore registers, as determined by STORE_P. */
1796 save_restore_insns (int store_p)
1798 long mask = cfun->machine->mask;
1801 HOST_WIDE_INT base_offset;
1802 HOST_WIDE_INT gp_offset;
1803 HOST_WIDE_INT end_offset;
1805 gcc_assert (!frame_pointer_needed
1806 || BITSET_P (mask, HARD_FRAME_POINTER_REGNUM - GP_REG_FIRST));
1810 base_reg_rtx = 0, base_offset = 0;
1814 /* Save registers starting from high to low. The debuggers prefer at least
1815 the return register be stored at func+4, and also it allows us not to
1816 need a nop in the epilog if at least one register is reloaded in
1817 addition to return address. */
1819 /* Save GP registers if needed. */
1820 /* Pick which pointer to use as a base register. For small frames, just
1821 use the stack pointer. Otherwise, use a temporary register. Save 2
1822 cycles if the save area is near the end of a large frame, by reusing
1823 the constant created in the prologue/epilogue to adjust the stack
1826 gp_offset = cfun->machine->gp_sp_offset;
1828 = gp_offset - (cfun->machine->gp_reg_size
1829 - GET_MODE_SIZE (gpr_mode));
1831 if (gp_offset < 0 || end_offset < 0)
1833 ("gp_offset (%ld) or end_offset (%ld) is less than zero",
1834 (long) gp_offset, (long) end_offset);
1836 else if (gp_offset < 32768)
1837 base_reg_rtx = stack_pointer_rtx, base_offset = 0;
1841 int reg_save_count = 0;
1843 for (regno = GP_REG_LAST; regno >= GP_REG_FIRST; regno--)
1844 if (BITSET_P (mask, regno - GP_REG_FIRST)) reg_save_count += 1;
1845 base_offset = gp_offset - ((reg_save_count - 1) * 4);
1846 base_reg_rtx = iq2000_add_large_offset_to_sp (base_offset);
1849 for (regno = GP_REG_LAST; regno >= GP_REG_FIRST; regno--)
1851 if (BITSET_P (mask, regno - GP_REG_FIRST))
1855 = gen_rtx_MEM (gpr_mode,
1856 gen_rtx_PLUS (Pmode, base_reg_rtx,
1857 GEN_INT (gp_offset - base_offset)));
1859 reg_rtx = gen_rtx_REG (gpr_mode, regno);
1862 iq2000_emit_frame_related_store (mem_rtx, reg_rtx, gp_offset);
1865 emit_move_insn (reg_rtx, mem_rtx);
1867 gp_offset -= GET_MODE_SIZE (gpr_mode);
1872 /* Expand the prologue into a bunch of separate insns. */
1875 iq2000_expand_prologue (void)
1878 HOST_WIDE_INT tsize;
1879 int last_arg_is_vararg_marker = 0;
1880 tree fndecl = current_function_decl;
1881 tree fntype = TREE_TYPE (fndecl);
1882 tree fnargs = DECL_ARGUMENTS (fndecl);
1887 CUMULATIVE_ARGS args_so_far_v;
1888 cumulative_args_t args_so_far;
1889 int store_args_on_stack = (iq2000_can_use_return_insn ());
1891 /* If struct value address is treated as the first argument. */
1892 if (aggregate_value_p (DECL_RESULT (fndecl), fndecl)
1893 && !cfun->returns_pcc_struct
1894 && targetm.calls.struct_value_rtx (TREE_TYPE (fndecl), 1) == 0)
1896 tree type = build_pointer_type (fntype);
1897 tree function_result_decl = build_decl (BUILTINS_LOCATION,
1898 PARM_DECL, NULL_TREE, type);
1900 DECL_ARG_TYPE (function_result_decl) = type;
1901 DECL_CHAIN (function_result_decl) = fnargs;
1902 fnargs = function_result_decl;
1905 /* For arguments passed in registers, find the register number
1906 of the first argument in the variable part of the argument list,
1907 otherwise GP_ARG_LAST+1. Note also if the last argument is
1908 the varargs special argument, and treat it as part of the
1911 This is only needed if store_args_on_stack is true. */
1912 INIT_CUMULATIVE_ARGS (args_so_far_v, fntype, NULL_RTX, 0, 0);
1913 args_so_far = pack_cumulative_args (&args_so_far_v);
1914 regno = GP_ARG_FIRST;
1916 for (cur_arg = fnargs; cur_arg != 0; cur_arg = next_arg)
1918 tree passed_type = DECL_ARG_TYPE (cur_arg);
1919 enum machine_mode passed_mode = TYPE_MODE (passed_type);
1922 if (TREE_ADDRESSABLE (passed_type))
1924 passed_type = build_pointer_type (passed_type);
1925 passed_mode = Pmode;
1928 entry_parm = iq2000_function_arg (args_so_far, passed_mode,
1931 iq2000_function_arg_advance (args_so_far, passed_mode,
1933 next_arg = DECL_CHAIN (cur_arg);
1935 if (entry_parm && store_args_on_stack)
1938 && DECL_NAME (cur_arg)
1939 && ((0 == strcmp (IDENTIFIER_POINTER (DECL_NAME (cur_arg)),
1940 "__builtin_va_alist"))
1941 || (0 == strcmp (IDENTIFIER_POINTER (DECL_NAME (cur_arg)),
1944 last_arg_is_vararg_marker = 1;
1951 gcc_assert (GET_CODE (entry_parm) == REG);
1953 /* Passed in a register, so will get homed automatically. */
1954 if (GET_MODE (entry_parm) == BLKmode)
1955 words = (int_size_in_bytes (passed_type) + 3) / 4;
1957 words = (GET_MODE_SIZE (GET_MODE (entry_parm)) + 3) / 4;
1959 regno = REGNO (entry_parm) + words - 1;
1964 regno = GP_ARG_LAST+1;
1969 /* In order to pass small structures by value in registers we need to
1970 shift the value into the high part of the register.
1971 iq2000_unction_arg has encoded a PARALLEL rtx, holding a vector of
1972 adjustments to be made as the next_arg_reg variable, so we split up
1973 the insns, and emit them separately. */
1974 next_arg_reg = iq2000_function_arg (args_so_far, VOIDmode,
1975 void_type_node, true);
1976 if (next_arg_reg != 0 && GET_CODE (next_arg_reg) == PARALLEL)
1978 rtvec adjust = XVEC (next_arg_reg, 0);
1979 int num = GET_NUM_ELEM (adjust);
1981 for (i = 0; i < num; i++)
1985 pattern = RTVEC_ELT (adjust, i);
1986 if (GET_CODE (pattern) != SET
1987 || GET_CODE (SET_SRC (pattern)) != ASHIFT)
1988 abort_with_insn (pattern, "Insn is not a shift");
1989 PUT_CODE (SET_SRC (pattern), ASHIFTRT);
1991 emit_insn (pattern);
1995 tsize = compute_frame_size (get_frame_size ());
1997 /* If this function is a varargs function, store any registers that
1998 would normally hold arguments ($4 - $7) on the stack. */
1999 if (store_args_on_stack
2000 && (stdarg_p (fntype)
2001 || last_arg_is_vararg_marker))
2003 int offset = (regno - GP_ARG_FIRST) * UNITS_PER_WORD;
2004 rtx ptr = stack_pointer_rtx;
2006 for (; regno <= GP_ARG_LAST; regno++)
2009 ptr = gen_rtx_PLUS (Pmode, stack_pointer_rtx, GEN_INT (offset));
2010 emit_move_insn (gen_rtx_MEM (gpr_mode, ptr),
2011 gen_rtx_REG (gpr_mode, regno));
2013 offset += GET_MODE_SIZE (gpr_mode);
2019 rtx tsize_rtx = GEN_INT (tsize);
2020 rtx adjustment_rtx, insn, dwarf_pattern;
2024 adjustment_rtx = gen_rtx_REG (Pmode, IQ2000_TEMP1_REGNUM);
2025 emit_move_insn (adjustment_rtx, tsize_rtx);
2028 adjustment_rtx = tsize_rtx;
2030 insn = emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
2033 dwarf_pattern = gen_rtx_SET (Pmode, stack_pointer_rtx,
2034 plus_constant (Pmode, stack_pointer_rtx,
2037 iq2000_annotate_frame_insn (insn, dwarf_pattern);
2039 save_restore_insns (1);
2041 if (frame_pointer_needed)
2045 insn = emit_insn (gen_movsi (hard_frame_pointer_rtx,
2046 stack_pointer_rtx));
2049 RTX_FRAME_RELATED_P (insn) = 1;
2053 emit_insn (gen_blockage ());
2056 /* Expand the epilogue into a bunch of separate insns. */
2059 iq2000_expand_epilogue (void)
2061 HOST_WIDE_INT tsize = cfun->machine->total_size;
2062 rtx tsize_rtx = GEN_INT (tsize);
2063 rtx tmp_rtx = (rtx)0;
2065 if (iq2000_can_use_return_insn ())
2067 emit_jump_insn (gen_return ());
2073 tmp_rtx = gen_rtx_REG (Pmode, IQ2000_TEMP1_REGNUM);
2074 emit_move_insn (tmp_rtx, tsize_rtx);
2075 tsize_rtx = tmp_rtx;
2080 if (frame_pointer_needed)
2082 emit_insn (gen_blockage ());
2084 emit_insn (gen_movsi (stack_pointer_rtx, hard_frame_pointer_rtx));
2087 save_restore_insns (0);
2089 if (crtl->calls_eh_return)
2091 rtx eh_ofs = EH_RETURN_STACKADJ_RTX;
2092 emit_insn (gen_addsi3 (eh_ofs, eh_ofs, tsize_rtx));
2096 emit_insn (gen_blockage ());
2098 if (tsize != 0 || crtl->calls_eh_return)
2100 emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx,
2105 if (crtl->calls_eh_return)
2107 /* Perform the additional bump for __throw. */
2108 emit_move_insn (gen_rtx_REG (Pmode, HARD_FRAME_POINTER_REGNUM),
2110 emit_use (gen_rtx_REG (Pmode, HARD_FRAME_POINTER_REGNUM));
2111 emit_jump_insn (gen_eh_return_internal ());
2114 emit_jump_insn (gen_return_internal (gen_rtx_REG (Pmode,
2115 GP_REG_FIRST + 31)));
2119 iq2000_expand_eh_return (rtx address)
2121 HOST_WIDE_INT gp_offset = cfun->machine->gp_sp_offset;
2124 scratch = plus_constant (Pmode, stack_pointer_rtx, gp_offset);
2125 emit_move_insn (gen_rtx_MEM (GET_MODE (address), scratch), address);
2128 /* Return nonzero if this function is known to have a null epilogue.
2129 This allows the optimizer to omit jumps to jumps if no stack
2133 iq2000_can_use_return_insn (void)
2135 if (! reload_completed)
2138 if (df_regs_ever_live_p (31) || profile_flag)
2141 if (cfun->machine->initialized)
2142 return cfun->machine->total_size == 0;
2144 return compute_frame_size (get_frame_size ()) == 0;
2147 /* Choose the section to use for the constant rtx expression X that has
2151 iq2000_select_rtx_section (enum machine_mode mode, rtx x ATTRIBUTE_UNUSED,
2152 unsigned HOST_WIDE_INT align)
2154 /* For embedded applications, always put constants in read-only data,
2155 in order to reduce RAM usage. */
2156 return mergeable_constant_section (mode, align, 0);
2159 /* Choose the section to use for DECL. RELOC is true if its value contains
2160 any relocatable expression.
2162 Some of the logic used here needs to be replicated in
2163 ENCODE_SECTION_INFO in iq2000.h so that references to these symbols
2164 are done correctly. */
2167 iq2000_select_section (tree decl, int reloc ATTRIBUTE_UNUSED,
2168 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED)
2170 if (TARGET_EMBEDDED_DATA)
2172 /* For embedded applications, always put an object in read-only data
2173 if possible, in order to reduce RAM usage. */
2174 if ((TREE_CODE (decl) == VAR_DECL
2175 && TREE_READONLY (decl) && !TREE_SIDE_EFFECTS (decl)
2176 && DECL_INITIAL (decl)
2177 && (DECL_INITIAL (decl) == error_mark_node
2178 || TREE_CONSTANT (DECL_INITIAL (decl))))
2179 /* Deal with calls from output_constant_def_contents. */
2180 || TREE_CODE (decl) != VAR_DECL)
2181 return readonly_data_section;
2183 return data_section;
2187 /* For hosted applications, always put an object in small data if
2188 possible, as this gives the best performance. */
2189 if ((TREE_CODE (decl) == VAR_DECL
2190 && TREE_READONLY (decl) && !TREE_SIDE_EFFECTS (decl)
2191 && DECL_INITIAL (decl)
2192 && (DECL_INITIAL (decl) == error_mark_node
2193 || TREE_CONSTANT (DECL_INITIAL (decl))))
2194 /* Deal with calls from output_constant_def_contents. */
2195 || TREE_CODE (decl) != VAR_DECL)
2196 return readonly_data_section;
2198 return data_section;
2201 /* Return register to use for a function return value with VALTYPE for function
2205 iq2000_function_value (const_tree valtype,
2206 const_tree fn_decl_or_type,
2207 bool outgoing ATTRIBUTE_UNUSED)
2209 int reg = GP_RETURN;
2210 enum machine_mode mode = TYPE_MODE (valtype);
2211 int unsignedp = TYPE_UNSIGNED (valtype);
2212 const_tree func = fn_decl_or_type;
2215 && !DECL_P (fn_decl_or_type))
2216 fn_decl_or_type = NULL;
2218 /* Since we promote return types, we must promote the mode here too. */
2219 mode = promote_function_mode (valtype, mode, &unsignedp, func, 1);
2221 return gen_rtx_REG (mode, reg);
2224 /* Worker function for TARGET_LIBCALL_VALUE. */
2227 iq2000_libcall_value (enum machine_mode mode, const_rtx fun ATTRIBUTE_UNUSED)
2229 return gen_rtx_REG (((GET_MODE_CLASS (mode) != MODE_INT
2230 || GET_MODE_SIZE (mode) >= 4)
2235 /* Worker function for FUNCTION_VALUE_REGNO_P.
2237 On the IQ2000, R2 and R3 are the only register thus used. */
2240 iq2000_function_value_regno_p (const unsigned int regno)
2242 return (regno == GP_RETURN);
2246 /* Return true when an argument must be passed by reference. */
2249 iq2000_pass_by_reference (cumulative_args_t cum_v, enum machine_mode mode,
2250 const_tree type, bool named ATTRIBUTE_UNUSED)
2252 CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
2255 /* We must pass by reference if we would be both passing in registers
2256 and the stack. This is because any subsequent partial arg would be
2257 handled incorrectly in this case. */
2258 if (cum && targetm.calls.must_pass_in_stack (mode, type))
2260 /* Don't pass the actual CUM to FUNCTION_ARG, because we would
2261 get double copies of any offsets generated for small structs
2262 passed in registers. */
2263 CUMULATIVE_ARGS temp;
2266 if (iq2000_function_arg (pack_cumulative_args (&temp), mode, type, named)
2271 if (type == NULL_TREE || mode == DImode || mode == DFmode)
2274 size = int_size_in_bytes (type);
2275 return size == -1 || size > UNITS_PER_WORD;
2278 /* Return the length of INSN. LENGTH is the initial length computed by
2279 attributes in the machine-description file. */
2282 iq2000_adjust_insn_length (rtx insn, int length)
2284 /* A unconditional jump has an unfilled delay slot if it is not part
2285 of a sequence. A conditional jump normally has a delay slot. */
2286 if (simplejump_p (insn)
2287 || ( (GET_CODE (insn) == JUMP_INSN
2288 || GET_CODE (insn) == CALL_INSN)))
2294 /* Output assembly instructions to perform a conditional branch.
2296 INSN is the branch instruction. OPERANDS[0] is the condition.
2297 OPERANDS[1] is the target of the branch. OPERANDS[2] is the target
2298 of the first operand to the condition. If TWO_OPERANDS_P is
2299 nonzero the comparison takes two operands; OPERANDS[3] will be the
2302 If INVERTED_P is nonzero we are to branch if the condition does
2303 not hold. If FLOAT_P is nonzero this is a floating-point comparison.
2305 LENGTH is the length (in bytes) of the sequence we are to generate.
2306 That tells us whether to generate a simple conditional branch, or a
2307 reversed conditional branch around a `jr' instruction. */
2310 iq2000_output_conditional_branch (rtx insn, rtx * operands, int two_operands_p,
2311 int float_p, int inverted_p, int length)
2313 static char buffer[200];
2314 /* The kind of comparison we are doing. */
2315 enum rtx_code code = GET_CODE (operands[0]);
2316 /* Nonzero if the opcode for the comparison needs a `z' indicating
2317 that it is a comparison against zero. */
2319 /* A string to use in the assembly output to represent the first
2321 const char *op1 = "%z2";
2322 /* A string to use in the assembly output to represent the second
2323 operand. Use the hard-wired zero register if there's no second
2325 const char *op2 = (two_operands_p ? ",%z3" : ",%.");
2326 /* The operand-printing string for the comparison. */
2327 const char *comp = (float_p ? "%F0" : "%C0");
2328 /* The operand-printing string for the inverted comparison. */
2329 const char *inverted_comp = (float_p ? "%W0" : "%N0");
2331 /* Likely variants of each branch instruction annul the instruction
2332 in the delay slot if the branch is not taken. */
2333 iq2000_branch_likely = (final_sequence && INSN_ANNULLED_BRANCH_P (insn));
2335 if (!two_operands_p)
2337 /* To compute whether than A > B, for example, we normally
2338 subtract B from A and then look at the sign bit. But, if we
2339 are doing an unsigned comparison, and B is zero, we don't
2340 have to do the subtraction. Instead, we can just check to
2341 see if A is nonzero. Thus, we change the CODE here to
2342 reflect the simpler comparison operation. */
2354 /* A condition which will always be true. */
2360 /* A condition which will always be false. */
2366 /* Not a special case. */
2371 /* Relative comparisons are always done against zero. But
2372 equality comparisons are done between two operands, and therefore
2373 do not require a `z' in the assembly language output. */
2374 need_z_p = (!float_p && code != EQ && code != NE);
2375 /* For comparisons against zero, the zero is not provided
2380 /* Begin by terminating the buffer. That way we can always use
2381 strcat to add to it. */
2388 /* Just a simple conditional branch. */
2390 sprintf (buffer, "b%s%%?\t%%Z2%%1",
2391 inverted_p ? inverted_comp : comp);
2393 sprintf (buffer, "b%s%s%%?\t%s%s,%%1",
2394 inverted_p ? inverted_comp : comp,
2395 need_z_p ? "z" : "",
2403 /* Generate a reversed conditional branch around ` j'
2415 Because we have to jump four bytes *past* the following
2416 instruction if this branch was annulled, we can't just use
2417 a label, as in the picture above; there's no way to put the
2418 label after the next instruction, as the assembler does not
2419 accept `.L+4' as the target of a branch. (We can't just
2420 wait until the next instruction is output; it might be a
2421 macro and take up more than four bytes. Once again, we see
2422 why we want to eliminate macros.)
2424 If the branch is annulled, we jump four more bytes that we
2425 would otherwise; that way we skip the annulled instruction
2426 in the delay slot. */
2429 = ((iq2000_branch_likely || length == 16) ? ".+16" : ".+12");
2432 c = strchr (buffer, '\0');
2433 /* Generate the reversed comparison. This takes four
2436 sprintf (c, "b%s\t%%Z2%s",
2437 inverted_p ? comp : inverted_comp,
2440 sprintf (c, "b%s%s\t%s%s,%s",
2441 inverted_p ? comp : inverted_comp,
2442 need_z_p ? "z" : "",
2446 strcat (c, "\n\tnop\n\tj\t%1");
2448 /* The delay slot was unfilled. Since we're inside
2449 .noreorder, the assembler will not fill in the NOP for
2450 us, so we must do it ourselves. */
2451 strcat (buffer, "\n\tnop");
2463 #define def_builtin(NAME, TYPE, CODE) \
2464 add_builtin_function ((NAME), (TYPE), (CODE), BUILT_IN_MD, \
2468 iq2000_init_builtins (void)
2470 tree void_ftype, void_ftype_int, void_ftype_int_int;
2471 tree void_ftype_int_int_int;
2472 tree int_ftype_int, int_ftype_int_int, int_ftype_int_int_int;
2473 tree int_ftype_int_int_int_int;
2477 = build_function_type_list (void_type_node, NULL_TREE);
2481 = build_function_type_list (void_type_node, integer_type_node, NULL_TREE);
2483 /* void func (int, int) */
2485 = build_function_type_list (void_type_node,
2490 /* int func (int) */
2492 = build_function_type_list (integer_type_node,
2493 integer_type_node, NULL_TREE);
2495 /* int func (int, int) */
2497 = build_function_type_list (integer_type_node,
2502 /* void func (int, int, int) */
2503 void_ftype_int_int_int
2504 = build_function_type_list (void_type_node,
2510 /* int func (int, int, int) */
2511 int_ftype_int_int_int
2512 = build_function_type_list (integer_type_node,
2518 /* int func (int, int, int, int) */
2519 int_ftype_int_int_int_int
2520 = build_function_type_list (integer_type_node,
2527 def_builtin ("__builtin_ado16", int_ftype_int_int, IQ2000_BUILTIN_ADO16);
2528 def_builtin ("__builtin_ram", int_ftype_int_int_int_int, IQ2000_BUILTIN_RAM);
2529 def_builtin ("__builtin_chkhdr", void_ftype_int_int, IQ2000_BUILTIN_CHKHDR);
2530 def_builtin ("__builtin_pkrl", void_ftype_int_int, IQ2000_BUILTIN_PKRL);
2531 def_builtin ("__builtin_cfc0", int_ftype_int, IQ2000_BUILTIN_CFC0);
2532 def_builtin ("__builtin_cfc1", int_ftype_int, IQ2000_BUILTIN_CFC1);
2533 def_builtin ("__builtin_cfc2", int_ftype_int, IQ2000_BUILTIN_CFC2);
2534 def_builtin ("__builtin_cfc3", int_ftype_int, IQ2000_BUILTIN_CFC3);
2535 def_builtin ("__builtin_ctc0", void_ftype_int_int, IQ2000_BUILTIN_CTC0);
2536 def_builtin ("__builtin_ctc1", void_ftype_int_int, IQ2000_BUILTIN_CTC1);
2537 def_builtin ("__builtin_ctc2", void_ftype_int_int, IQ2000_BUILTIN_CTC2);
2538 def_builtin ("__builtin_ctc3", void_ftype_int_int, IQ2000_BUILTIN_CTC3);
2539 def_builtin ("__builtin_mfc0", int_ftype_int, IQ2000_BUILTIN_MFC0);
2540 def_builtin ("__builtin_mfc1", int_ftype_int, IQ2000_BUILTIN_MFC1);
2541 def_builtin ("__builtin_mfc2", int_ftype_int, IQ2000_BUILTIN_MFC2);
2542 def_builtin ("__builtin_mfc3", int_ftype_int, IQ2000_BUILTIN_MFC3);
2543 def_builtin ("__builtin_mtc0", void_ftype_int_int, IQ2000_BUILTIN_MTC0);
2544 def_builtin ("__builtin_mtc1", void_ftype_int_int, IQ2000_BUILTIN_MTC1);
2545 def_builtin ("__builtin_mtc2", void_ftype_int_int, IQ2000_BUILTIN_MTC2);
2546 def_builtin ("__builtin_mtc3", void_ftype_int_int, IQ2000_BUILTIN_MTC3);
2547 def_builtin ("__builtin_lur", void_ftype_int_int, IQ2000_BUILTIN_LUR);
2548 def_builtin ("__builtin_rb", void_ftype_int_int, IQ2000_BUILTIN_RB);
2549 def_builtin ("__builtin_rx", void_ftype_int_int, IQ2000_BUILTIN_RX);
2550 def_builtin ("__builtin_srrd", void_ftype_int, IQ2000_BUILTIN_SRRD);
2551 def_builtin ("__builtin_srwr", void_ftype_int_int, IQ2000_BUILTIN_SRWR);
2552 def_builtin ("__builtin_wb", void_ftype_int_int, IQ2000_BUILTIN_WB);
2553 def_builtin ("__builtin_wx", void_ftype_int_int, IQ2000_BUILTIN_WX);
2554 def_builtin ("__builtin_luc32l", void_ftype_int_int, IQ2000_BUILTIN_LUC32L);
2555 def_builtin ("__builtin_luc64", void_ftype_int_int, IQ2000_BUILTIN_LUC64);
2556 def_builtin ("__builtin_luc64l", void_ftype_int_int, IQ2000_BUILTIN_LUC64L);
2557 def_builtin ("__builtin_luk", void_ftype_int_int, IQ2000_BUILTIN_LUK);
2558 def_builtin ("__builtin_lulck", void_ftype_int, IQ2000_BUILTIN_LULCK);
2559 def_builtin ("__builtin_lum32", void_ftype_int_int, IQ2000_BUILTIN_LUM32);
2560 def_builtin ("__builtin_lum32l", void_ftype_int_int, IQ2000_BUILTIN_LUM32L);
2561 def_builtin ("__builtin_lum64", void_ftype_int_int, IQ2000_BUILTIN_LUM64);
2562 def_builtin ("__builtin_lum64l", void_ftype_int_int, IQ2000_BUILTIN_LUM64L);
2563 def_builtin ("__builtin_lurl", void_ftype_int_int, IQ2000_BUILTIN_LURL);
2564 def_builtin ("__builtin_mrgb", int_ftype_int_int_int, IQ2000_BUILTIN_MRGB);
2565 def_builtin ("__builtin_srrdl", void_ftype_int, IQ2000_BUILTIN_SRRDL);
2566 def_builtin ("__builtin_srulck", void_ftype_int, IQ2000_BUILTIN_SRULCK);
2567 def_builtin ("__builtin_srwru", void_ftype_int_int, IQ2000_BUILTIN_SRWRU);
2568 def_builtin ("__builtin_trapqfl", void_ftype, IQ2000_BUILTIN_TRAPQFL);
2569 def_builtin ("__builtin_trapqne", void_ftype, IQ2000_BUILTIN_TRAPQNE);
2570 def_builtin ("__builtin_traprel", void_ftype_int, IQ2000_BUILTIN_TRAPREL);
2571 def_builtin ("__builtin_wbu", void_ftype_int_int_int, IQ2000_BUILTIN_WBU);
2572 def_builtin ("__builtin_syscall", void_ftype, IQ2000_BUILTIN_SYSCALL);
2575 /* Builtin for ICODE having ARGCOUNT args in EXP where each arg
2579 expand_one_builtin (enum insn_code icode, rtx target, tree exp,
2580 enum rtx_code *code, int argcount)
2585 enum machine_mode mode [5];
2588 mode[0] = insn_data[icode].operand[0].mode;
2589 for (i = 0; i < argcount; i++)
2591 arg[i] = CALL_EXPR_ARG (exp, i);
2592 op[i] = expand_normal (arg[i]);
2593 mode[i] = insn_data[icode].operand[i].mode;
2594 if (code[i] == CONST_INT && GET_CODE (op[i]) != CONST_INT)
2595 error ("argument %qd is not a constant", i + 1);
2597 && ! (*insn_data[icode].operand[i].predicate) (op[i], mode[i]))
2598 op[i] = copy_to_mode_reg (mode[i], op[i]);
2601 if (insn_data[icode].operand[0].constraint[0] == '=')
2604 || GET_MODE (target) != mode[0]
2605 || ! (*insn_data[icode].operand[0].predicate) (target, mode[0]))
2606 target = gen_reg_rtx (mode[0]);
2614 pat = GEN_FCN (icode) (target);
2617 pat = GEN_FCN (icode) (target, op[0]);
2619 pat = GEN_FCN (icode) (op[0]);
2623 pat = GEN_FCN (icode) (target, op[0], op[1]);
2625 pat = GEN_FCN (icode) (op[0], op[1]);
2629 pat = GEN_FCN (icode) (target, op[0], op[1], op[2]);
2631 pat = GEN_FCN (icode) (op[0], op[1], op[2]);
2635 pat = GEN_FCN (icode) (target, op[0], op[1], op[2], op[3]);
2637 pat = GEN_FCN (icode) (op[0], op[1], op[2], op[3]);
2649 /* Expand an expression EXP that calls a built-in function,
2650 with result going to TARGET if that's convenient
2651 (and in mode MODE if that's convenient).
2652 SUBTARGET may be used as the target for computing one of EXP's operands.
2653 IGNORE is nonzero if the value is to be ignored. */
2656 iq2000_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED,
2657 enum machine_mode mode ATTRIBUTE_UNUSED,
2658 int ignore ATTRIBUTE_UNUSED)
2660 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
2661 int fcode = DECL_FUNCTION_CODE (fndecl);
2662 enum rtx_code code [5];
2674 case IQ2000_BUILTIN_ADO16:
2675 return expand_one_builtin (CODE_FOR_ado16, target, exp, code, 2);
2677 case IQ2000_BUILTIN_RAM:
2678 code[1] = CONST_INT;
2679 code[2] = CONST_INT;
2680 code[3] = CONST_INT;
2681 return expand_one_builtin (CODE_FOR_ram, target, exp, code, 4);
2683 case IQ2000_BUILTIN_CHKHDR:
2684 return expand_one_builtin (CODE_FOR_chkhdr, target, exp, code, 2);
2686 case IQ2000_BUILTIN_PKRL:
2687 return expand_one_builtin (CODE_FOR_pkrl, target, exp, code, 2);
2689 case IQ2000_BUILTIN_CFC0:
2690 code[0] = CONST_INT;
2691 return expand_one_builtin (CODE_FOR_cfc0, target, exp, code, 1);
2693 case IQ2000_BUILTIN_CFC1:
2694 code[0] = CONST_INT;
2695 return expand_one_builtin (CODE_FOR_cfc1, target, exp, code, 1);
2697 case IQ2000_BUILTIN_CFC2:
2698 code[0] = CONST_INT;
2699 return expand_one_builtin (CODE_FOR_cfc2, target, exp, code, 1);
2701 case IQ2000_BUILTIN_CFC3:
2702 code[0] = CONST_INT;
2703 return expand_one_builtin (CODE_FOR_cfc3, target, exp, code, 1);
2705 case IQ2000_BUILTIN_CTC0:
2706 code[1] = CONST_INT;
2707 return expand_one_builtin (CODE_FOR_ctc0, target, exp, code, 2);
2709 case IQ2000_BUILTIN_CTC1:
2710 code[1] = CONST_INT;
2711 return expand_one_builtin (CODE_FOR_ctc1, target, exp, code, 2);
2713 case IQ2000_BUILTIN_CTC2:
2714 code[1] = CONST_INT;
2715 return expand_one_builtin (CODE_FOR_ctc2, target, exp, code, 2);
2717 case IQ2000_BUILTIN_CTC3:
2718 code[1] = CONST_INT;
2719 return expand_one_builtin (CODE_FOR_ctc3, target, exp, code, 2);
2721 case IQ2000_BUILTIN_MFC0:
2722 code[0] = CONST_INT;
2723 return expand_one_builtin (CODE_FOR_mfc0, target, exp, code, 1);
2725 case IQ2000_BUILTIN_MFC1:
2726 code[0] = CONST_INT;
2727 return expand_one_builtin (CODE_FOR_mfc1, target, exp, code, 1);
2729 case IQ2000_BUILTIN_MFC2:
2730 code[0] = CONST_INT;
2731 return expand_one_builtin (CODE_FOR_mfc2, target, exp, code, 1);
2733 case IQ2000_BUILTIN_MFC3:
2734 code[0] = CONST_INT;
2735 return expand_one_builtin (CODE_FOR_mfc3, target, exp, code, 1);
2737 case IQ2000_BUILTIN_MTC0:
2738 code[1] = CONST_INT;
2739 return expand_one_builtin (CODE_FOR_mtc0, target, exp, code, 2);
2741 case IQ2000_BUILTIN_MTC1:
2742 code[1] = CONST_INT;
2743 return expand_one_builtin (CODE_FOR_mtc1, target, exp, code, 2);
2745 case IQ2000_BUILTIN_MTC2:
2746 code[1] = CONST_INT;
2747 return expand_one_builtin (CODE_FOR_mtc2, target, exp, code, 2);
2749 case IQ2000_BUILTIN_MTC3:
2750 code[1] = CONST_INT;
2751 return expand_one_builtin (CODE_FOR_mtc3, target, exp, code, 2);
2753 case IQ2000_BUILTIN_LUR:
2754 return expand_one_builtin (CODE_FOR_lur, target, exp, code, 2);
2756 case IQ2000_BUILTIN_RB:
2757 return expand_one_builtin (CODE_FOR_rb, target, exp, code, 2);
2759 case IQ2000_BUILTIN_RX:
2760 return expand_one_builtin (CODE_FOR_rx, target, exp, code, 2);
2762 case IQ2000_BUILTIN_SRRD:
2763 return expand_one_builtin (CODE_FOR_srrd, target, exp, code, 1);
2765 case IQ2000_BUILTIN_SRWR:
2766 return expand_one_builtin (CODE_FOR_srwr, target, exp, code, 2);
2768 case IQ2000_BUILTIN_WB:
2769 return expand_one_builtin (CODE_FOR_wb, target, exp, code, 2);
2771 case IQ2000_BUILTIN_WX:
2772 return expand_one_builtin (CODE_FOR_wx, target, exp, code, 2);
2774 case IQ2000_BUILTIN_LUC32L:
2775 return expand_one_builtin (CODE_FOR_luc32l, target, exp, code, 2);
2777 case IQ2000_BUILTIN_LUC64:
2778 return expand_one_builtin (CODE_FOR_luc64, target, exp, code, 2);
2780 case IQ2000_BUILTIN_LUC64L:
2781 return expand_one_builtin (CODE_FOR_luc64l, target, exp, code, 2);
2783 case IQ2000_BUILTIN_LUK:
2784 return expand_one_builtin (CODE_FOR_luk, target, exp, code, 2);
2786 case IQ2000_BUILTIN_LULCK:
2787 return expand_one_builtin (CODE_FOR_lulck, target, exp, code, 1);
2789 case IQ2000_BUILTIN_LUM32:
2790 return expand_one_builtin (CODE_FOR_lum32, target, exp, code, 2);
2792 case IQ2000_BUILTIN_LUM32L:
2793 return expand_one_builtin (CODE_FOR_lum32l, target, exp, code, 2);
2795 case IQ2000_BUILTIN_LUM64:
2796 return expand_one_builtin (CODE_FOR_lum64, target, exp, code, 2);
2798 case IQ2000_BUILTIN_LUM64L:
2799 return expand_one_builtin (CODE_FOR_lum64l, target, exp, code, 2);
2801 case IQ2000_BUILTIN_LURL:
2802 return expand_one_builtin (CODE_FOR_lurl, target, exp, code, 2);
2804 case IQ2000_BUILTIN_MRGB:
2805 code[2] = CONST_INT;
2806 return expand_one_builtin (CODE_FOR_mrgb, target, exp, code, 3);
2808 case IQ2000_BUILTIN_SRRDL:
2809 return expand_one_builtin (CODE_FOR_srrdl, target, exp, code, 1);
2811 case IQ2000_BUILTIN_SRULCK:
2812 return expand_one_builtin (CODE_FOR_srulck, target, exp, code, 1);
2814 case IQ2000_BUILTIN_SRWRU:
2815 return expand_one_builtin (CODE_FOR_srwru, target, exp, code, 2);
2817 case IQ2000_BUILTIN_TRAPQFL:
2818 return expand_one_builtin (CODE_FOR_trapqfl, target, exp, code, 0);
2820 case IQ2000_BUILTIN_TRAPQNE:
2821 return expand_one_builtin (CODE_FOR_trapqne, target, exp, code, 0);
2823 case IQ2000_BUILTIN_TRAPREL:
2824 return expand_one_builtin (CODE_FOR_traprel, target, exp, code, 1);
2826 case IQ2000_BUILTIN_WBU:
2827 return expand_one_builtin (CODE_FOR_wbu, target, exp, code, 3);
2829 case IQ2000_BUILTIN_SYSCALL:
2830 return expand_one_builtin (CODE_FOR_syscall, target, exp, code, 0);
2836 /* Worker function for TARGET_RETURN_IN_MEMORY. */
2839 iq2000_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED)
2841 return ((int_size_in_bytes (type) > (2 * UNITS_PER_WORD))
2842 || (int_size_in_bytes (type) == -1));
2845 /* Worker function for TARGET_SETUP_INCOMING_VARARGS. */
2848 iq2000_setup_incoming_varargs (cumulative_args_t cum_v,
2849 enum machine_mode mode ATTRIBUTE_UNUSED,
2850 tree type ATTRIBUTE_UNUSED, int * pretend_size,
2853 CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
2854 unsigned int iq2000_off = ! cum->last_arg_fp;
2855 unsigned int iq2000_fp_off = cum->last_arg_fp;
2857 if ((cum->arg_words < MAX_ARGS_IN_REGISTERS - iq2000_off))
2859 int iq2000_save_gp_regs
2860 = MAX_ARGS_IN_REGISTERS - cum->arg_words - iq2000_off;
2861 int iq2000_save_fp_regs
2862 = (MAX_ARGS_IN_REGISTERS - cum->fp_arg_words - iq2000_fp_off);
2864 if (iq2000_save_gp_regs < 0)
2865 iq2000_save_gp_regs = 0;
2866 if (iq2000_save_fp_regs < 0)
2867 iq2000_save_fp_regs = 0;
2869 *pretend_size = ((iq2000_save_gp_regs * UNITS_PER_WORD)
2870 + (iq2000_save_fp_regs * UNITS_PER_FPREG));
2874 if (cum->arg_words < MAX_ARGS_IN_REGISTERS - iq2000_off)
2877 ptr = plus_constant (Pmode, virtual_incoming_args_rtx,
2878 - (iq2000_save_gp_regs
2880 mem = gen_rtx_MEM (BLKmode, ptr);
2882 (cum->arg_words + GP_ARG_FIRST + iq2000_off,
2884 iq2000_save_gp_regs);
2890 /* A C compound statement to output to stdio stream STREAM the
2891 assembler syntax for an instruction operand that is a memory
2892 reference whose address is ADDR. ADDR is an RTL expression. */
2895 iq2000_print_operand_address (FILE * file, rtx addr)
2898 error ("PRINT_OPERAND_ADDRESS, null pointer");
2901 switch (GET_CODE (addr))
2904 if (REGNO (addr) == ARG_POINTER_REGNUM)
2905 abort_with_insn (addr, "Arg pointer not eliminated.");
2907 fprintf (file, "0(%s)", reg_names [REGNO (addr)]);
2912 rtx arg0 = XEXP (addr, 0);
2913 rtx arg1 = XEXP (addr, 1);
2915 if (GET_CODE (arg0) != REG)
2916 abort_with_insn (addr,
2917 "PRINT_OPERAND_ADDRESS, LO_SUM with #1 not REG.");
2919 fprintf (file, "%%lo(");
2920 iq2000_print_operand_address (file, arg1);
2921 fprintf (file, ")(%s)", reg_names [REGNO (arg0)]);
2929 rtx arg0 = XEXP (addr, 0);
2930 rtx arg1 = XEXP (addr, 1);
2932 if (GET_CODE (arg0) == REG)
2936 if (GET_CODE (offset) == REG)
2937 abort_with_insn (addr, "PRINT_OPERAND_ADDRESS, 2 regs");
2940 else if (GET_CODE (arg1) == REG)
2941 reg = arg1, offset = arg0;
2942 else if (CONSTANT_P (arg0) && CONSTANT_P (arg1))
2944 output_addr_const (file, addr);
2948 abort_with_insn (addr, "PRINT_OPERAND_ADDRESS, no regs");
2950 if (! CONSTANT_P (offset))
2951 abort_with_insn (addr, "PRINT_OPERAND_ADDRESS, invalid insn #2");
2953 if (REGNO (reg) == ARG_POINTER_REGNUM)
2954 abort_with_insn (addr, "Arg pointer not eliminated.");
2956 output_addr_const (file, offset);
2957 fprintf (file, "(%s)", reg_names [REGNO (reg)]);
2965 output_addr_const (file, addr);
2966 if (GET_CODE (addr) == CONST_INT)
2967 fprintf (file, "(%s)", reg_names [0]);
2971 abort_with_insn (addr, "PRINT_OPERAND_ADDRESS, invalid insn #1");
2976 /* A C compound statement to output to stdio stream FILE the
2977 assembler syntax for an instruction operand OP.
2979 LETTER is a value that can be used to specify one of several ways
2980 of printing the operand. It is used when identical operands
2981 must be printed differently depending on the context. LETTER
2982 comes from the `%' specification that was used to request
2983 printing of the operand. If the specification was just `%DIGIT'
2984 then LETTER is 0; if the specification was `%LTR DIGIT' then LETTER
2985 is the ASCII code for LTR.
2987 If OP is a register, this macro should print the register's name.
2988 The names can be found in an array `reg_names' whose type is
2989 `char *[]'. `reg_names' is initialized from `REGISTER_NAMES'.
2991 When the machine description has a specification `%PUNCT' (a `%'
2992 followed by a punctuation character), this macro is called with
2993 a null pointer for X and the punctuation character for LETTER.
2995 The IQ2000 specific codes are:
2997 'X' X is CONST_INT, prints upper 16 bits in hexadecimal format = "0x%04x",
2998 'x' X is CONST_INT, prints lower 16 bits in hexadecimal format = "0x%04x",
2999 'd' output integer constant in decimal,
3000 'z' if the operand is 0, use $0 instead of normal operand.
3001 'D' print second part of double-word register or memory operand.
3002 'L' print low-order register of double-word register operand.
3003 'M' print high-order register of double-word register operand.
3004 'C' print part of opcode for a branch condition.
3005 'F' print part of opcode for a floating-point branch condition.
3006 'N' print part of opcode for a branch condition, inverted.
3007 'W' print part of opcode for a floating-point branch condition, inverted.
3008 'A' Print part of opcode for a bit test condition.
3009 'P' Print label for a bit test.
3010 'p' Print log for a bit test.
3011 'B' print 'z' for EQ, 'n' for NE
3012 'b' print 'n' for EQ, 'z' for NE
3013 'T' print 'f' for EQ, 't' for NE
3014 't' print 't' for EQ, 'f' for NE
3015 'Z' print register and a comma, but print nothing for $fcc0
3016 '?' Print 'l' if we are to use a branch likely instead of normal branch.
3017 '@' Print the name of the assembler temporary register (at or $1).
3018 '.' Print the name of the register with a hard-wired zero (zero or $0).
3019 '$' Print the name of the stack pointer register (sp or $29).
3020 '+' Print the name of the gp register (gp or $28). */
3023 iq2000_print_operand (FILE *file, rtx op, int letter)
3027 if (iq2000_print_operand_punct_valid_p (letter))
3032 if (iq2000_branch_likely)
3037 fputs (reg_names [GP_REG_FIRST + 1], file);
3041 fputs (reg_names [GP_REG_FIRST + 0], file);
3045 fputs (reg_names[STACK_POINTER_REGNUM], file);
3049 fputs (reg_names[GP_REG_FIRST + 28], file);
3053 error ("PRINT_OPERAND: Unknown punctuation '%c'", letter);
3062 error ("PRINT_OPERAND null pointer");
3066 code = GET_CODE (op);
3068 if (code == SIGN_EXTEND)
3069 op = XEXP (op, 0), code = GET_CODE (op);
3074 case EQ: fputs ("eq", file); break;
3075 case NE: fputs ("ne", file); break;
3076 case GT: fputs ("gt", file); break;
3077 case GE: fputs ("ge", file); break;
3078 case LT: fputs ("lt", file); break;
3079 case LE: fputs ("le", file); break;
3080 case GTU: fputs ("ne", file); break;
3081 case GEU: fputs ("geu", file); break;
3082 case LTU: fputs ("ltu", file); break;
3083 case LEU: fputs ("eq", file); break;
3085 abort_with_insn (op, "PRINT_OPERAND, invalid insn for %%C");
3088 else if (letter == 'N')
3091 case EQ: fputs ("ne", file); break;
3092 case NE: fputs ("eq", file); break;
3093 case GT: fputs ("le", file); break;
3094 case GE: fputs ("lt", file); break;
3095 case LT: fputs ("ge", file); break;
3096 case LE: fputs ("gt", file); break;
3097 case GTU: fputs ("leu", file); break;
3098 case GEU: fputs ("ltu", file); break;
3099 case LTU: fputs ("geu", file); break;
3100 case LEU: fputs ("gtu", file); break;
3102 abort_with_insn (op, "PRINT_OPERAND, invalid insn for %%N");
3105 else if (letter == 'F')
3108 case EQ: fputs ("c1f", file); break;
3109 case NE: fputs ("c1t", file); break;
3111 abort_with_insn (op, "PRINT_OPERAND, invalid insn for %%F");
3114 else if (letter == 'W')
3117 case EQ: fputs ("c1t", file); break;
3118 case NE: fputs ("c1f", file); break;
3120 abort_with_insn (op, "PRINT_OPERAND, invalid insn for %%W");
3123 else if (letter == 'A')
3124 fputs (code == LABEL_REF ? "i" : "in", file);
3126 else if (letter == 'P')
3128 if (code == LABEL_REF)
3129 output_addr_const (file, op);
3130 else if (code != PC)
3131 output_operand_lossage ("invalid %%P operand");
3134 else if (letter == 'p')
3137 if (code != CONST_INT
3138 || (value = exact_log2 (INTVAL (op))) < 0)
3139 output_operand_lossage ("invalid %%p value");
3141 fprintf (file, "%d", value);
3144 else if (letter == 'Z')
3149 else if (code == REG || code == SUBREG)
3154 regnum = REGNO (op);
3156 regnum = true_regnum (op);
3158 if ((letter == 'M' && ! WORDS_BIG_ENDIAN)
3159 || (letter == 'L' && WORDS_BIG_ENDIAN)
3163 fprintf (file, "%s", reg_names[regnum]);
3166 else if (code == MEM)
3169 output_address (plus_constant (Pmode, XEXP (op, 0), 4));
3171 output_address (XEXP (op, 0));
3174 else if (code == CONST_DOUBLE
3175 && GET_MODE_CLASS (GET_MODE (op)) == MODE_FLOAT)
3179 real_to_decimal (s, CONST_DOUBLE_REAL_VALUE (op), sizeof (s), 0, 1);
3183 else if (letter == 'x' && GET_CODE (op) == CONST_INT)
3184 fprintf (file, HOST_WIDE_INT_PRINT_HEX, 0xffff & INTVAL(op));
3186 else if (letter == 'X' && GET_CODE(op) == CONST_INT)
3187 fprintf (file, HOST_WIDE_INT_PRINT_HEX, 0xffff & (INTVAL (op) >> 16));
3189 else if (letter == 'd' && GET_CODE(op) == CONST_INT)
3190 fprintf (file, HOST_WIDE_INT_PRINT_DEC, (INTVAL(op)));
3192 else if (letter == 'z' && GET_CODE (op) == CONST_INT && INTVAL (op) == 0)
3193 fputs (reg_names[GP_REG_FIRST], file);
3195 else if (letter == 'd' || letter == 'x' || letter == 'X')
3196 output_operand_lossage ("invalid use of %%d, %%x, or %%X");
3198 else if (letter == 'B')
3199 fputs (code == EQ ? "z" : "n", file);
3200 else if (letter == 'b')
3201 fputs (code == EQ ? "n" : "z", file);
3202 else if (letter == 'T')
3203 fputs (code == EQ ? "f" : "t", file);
3204 else if (letter == 't')
3205 fputs (code == EQ ? "t" : "f", file);
3207 else if (code == CONST && GET_CODE (XEXP (op, 0)) == REG)
3209 iq2000_print_operand (file, XEXP (op, 0), letter);
3213 output_addr_const (file, op);
3217 iq2000_print_operand_punct_valid_p (unsigned char code)
3219 return iq2000_print_operand_punct[code];
3222 /* For the IQ2000, transform:
3224 memory(X + <large int>)
3226 Y = <large int> & ~0x7fff;
3228 memory (Z + (<large int> & 0x7fff));
3232 iq2000_legitimize_address (rtx xinsn, rtx old_x ATTRIBUTE_UNUSED,
3233 enum machine_mode mode)
3235 if (TARGET_DEBUG_B_MODE)
3237 GO_PRINTF ("\n========== LEGITIMIZE_ADDRESS\n");
3238 GO_DEBUG_RTX (xinsn);
3241 if (iq2000_check_split (xinsn, mode))
3243 return gen_rtx_LO_SUM (Pmode,
3244 copy_to_mode_reg (Pmode,
3245 gen_rtx_HIGH (Pmode, xinsn)),
3249 if (GET_CODE (xinsn) == PLUS)
3251 rtx xplus0 = XEXP (xinsn, 0);
3252 rtx xplus1 = XEXP (xinsn, 1);
3253 enum rtx_code code0 = GET_CODE (xplus0);
3254 enum rtx_code code1 = GET_CODE (xplus1);
3256 if (code0 != REG && code1 == REG)
3258 xplus0 = XEXP (xinsn, 1);
3259 xplus1 = XEXP (xinsn, 0);
3260 code0 = GET_CODE (xplus0);
3261 code1 = GET_CODE (xplus1);
3264 if (code0 == REG && REG_MODE_OK_FOR_BASE_P (xplus0, mode)
3265 && code1 == CONST_INT && !SMALL_INT (xplus1))
3267 rtx int_reg = gen_reg_rtx (Pmode);
3268 rtx ptr_reg = gen_reg_rtx (Pmode);
3270 emit_move_insn (int_reg,
3271 GEN_INT (INTVAL (xplus1) & ~ 0x7fff));
3273 emit_insn (gen_rtx_SET (VOIDmode,
3275 gen_rtx_PLUS (Pmode, xplus0, int_reg)));
3277 return plus_constant (Pmode, ptr_reg, INTVAL (xplus1) & 0x7fff);
3281 if (TARGET_DEBUG_B_MODE)
3282 GO_PRINTF ("LEGITIMIZE_ADDRESS could not fix.\n");
3289 iq2000_rtx_costs (rtx x, int code, int outer_code ATTRIBUTE_UNUSED,
3290 int opno ATTRIBUTE_UNUSED, int * total,
3291 bool speed ATTRIBUTE_UNUSED)
3293 enum machine_mode mode = GET_MODE (x);
3299 int num_words = (GET_MODE_SIZE (mode) > UNITS_PER_WORD) ? 2 : 1;
3301 if (simple_memory_operand (x, mode))
3302 return COSTS_N_INSNS (num_words);
3304 * total = COSTS_N_INSNS (2 * num_words);
3309 * total = COSTS_N_INSNS (6);
3316 * total = COSTS_N_INSNS (mode == DImode ? 2 : 1);
3323 * total = COSTS_N_INSNS ((GET_CODE (XEXP (x, 1)) == CONST_INT) ? 4 : 12);
3325 * total = COSTS_N_INSNS (1);
3329 if (mode == SFmode || mode == DFmode)
3330 * total = COSTS_N_INSNS (1);
3332 * total = COSTS_N_INSNS (4);
3337 if (mode == SFmode || mode == DFmode)
3338 * total = COSTS_N_INSNS (6);
3339 else if (mode == DImode)
3340 * total = COSTS_N_INSNS (4);
3342 * total = COSTS_N_INSNS (1);
3346 * total = (mode == DImode) ? 4 : 1;
3351 * total = COSTS_N_INSNS (7);
3352 else if (mode == DFmode)
3353 * total = COSTS_N_INSNS (8);
3355 * total = COSTS_N_INSNS (10);
3361 * total = COSTS_N_INSNS (23);
3362 else if (mode == DFmode)
3363 * total = COSTS_N_INSNS (36);
3365 * total = COSTS_N_INSNS (69);
3370 * total = COSTS_N_INSNS (69);
3374 * total = COSTS_N_INSNS (2);
3378 * total = COSTS_N_INSNS (1);
3386 * total = COSTS_N_INSNS (2);
3391 rtx offset = const0_rtx;
3392 rtx symref = eliminate_constant_term (XEXP (x, 0), & offset);
3394 if (GET_CODE (symref) == LABEL_REF)
3395 * total = COSTS_N_INSNS (2);
3396 else if (GET_CODE (symref) != SYMBOL_REF)
3397 * total = COSTS_N_INSNS (4);
3398 /* Let's be paranoid.... */
3399 else if (INTVAL (offset) < -32768 || INTVAL (offset) > 32767)
3400 * total = COSTS_N_INSNS (2);
3402 * total = COSTS_N_INSNS (SYMBOL_REF_FLAG (symref) ? 1 : 2);
3407 * total = COSTS_N_INSNS (SYMBOL_REF_FLAG (x) ? 1 : 2);
3414 split_double (x, & high, & low);
3416 * total = COSTS_N_INSNS ( (high == CONST0_RTX (GET_MODE (high))
3417 || low == CONST0_RTX (GET_MODE (low)))
3428 /* Worker for TARGET_ASM_TRAMPOLINE_TEMPLATE. */
3431 iq2000_asm_trampoline_template (FILE *f)
3433 fprintf (f, "\t.word\t0x03e00821\t\t# move $1,$31\n");
3434 fprintf (f, "\t.word\t0x04110001\t\t# bgezal $0,.+8\n");
3435 fprintf (f, "\t.word\t0x00000000\t\t# nop\n");
3436 if (Pmode == DImode)
3438 fprintf (f, "\t.word\t0xdfe30014\t\t# ld $3,20($31)\n");
3439 fprintf (f, "\t.word\t0xdfe2001c\t\t# ld $2,28($31)\n");
3443 fprintf (f, "\t.word\t0x8fe30014\t\t# lw $3,20($31)\n");
3444 fprintf (f, "\t.word\t0x8fe20018\t\t# lw $2,24($31)\n");
3446 fprintf (f, "\t.word\t0x0060c821\t\t# move $25,$3 (abicalls)\n");
3447 fprintf (f, "\t.word\t0x00600008\t\t# jr $3\n");
3448 fprintf (f, "\t.word\t0x0020f821\t\t# move $31,$1\n");
3449 fprintf (f, "\t.word\t0x00000000\t\t# <function address>\n");
3450 fprintf (f, "\t.word\t0x00000000\t\t# <static chain value>\n");
3453 /* Worker for TARGET_TRAMPOLINE_INIT. */
3456 iq2000_trampoline_init (rtx m_tramp, tree fndecl, rtx chain_value)
3458 rtx fnaddr = XEXP (DECL_RTL (fndecl), 0);
3461 emit_block_move (m_tramp, assemble_trampoline_template (),
3462 GEN_INT (TRAMPOLINE_CODE_SIZE), BLOCK_OP_NORMAL);
3464 mem = adjust_address (m_tramp, Pmode, TRAMPOLINE_CODE_SIZE);
3465 emit_move_insn (mem, fnaddr);
3466 mem = adjust_address (m_tramp, Pmode,
3467 TRAMPOLINE_CODE_SIZE + GET_MODE_SIZE (Pmode));
3468 emit_move_insn (mem, chain_value);
3471 #include "gt-iq2000.h"