1 /* Subroutines used for code generation on Vitesse IQ2000 processors
2 Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009
3 Free Software Foundation, Inc.
5 This file is part of GCC.
7 GCC is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3, or (at your option)
12 GCC is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING3. If not see
19 <http://www.gnu.org/licenses/>. */
23 #include "coretypes.h"
29 #include "hard-reg-set.h"
31 #include "insn-config.h"
32 #include "conditions.h"
34 #include "insn-attr.h"
47 #include "target-def.h"
48 #include "langhooks.h"
50 /* Enumeration for all of the relational tests, so that we can build
51 arrays indexed by the test type, and not worry about the order
72 /* Structure to be filled in by compute_frame_size with register
73 save masks, and offsets for the current function. */
75 struct iq2000_frame_info
77 long total_size; /* # bytes that the entire frame takes up. */
78 long var_size; /* # bytes that variables take up. */
79 long args_size; /* # bytes that outgoing arguments take up. */
80 long extra_size; /* # bytes of extra gunk. */
81 int gp_reg_size; /* # bytes needed to store gp regs. */
82 int fp_reg_size; /* # bytes needed to store fp regs. */
83 long mask; /* Mask of saved gp registers. */
84 long gp_save_offset; /* Offset from vfp to store gp registers. */
85 long fp_save_offset; /* Offset from vfp to store fp registers. */
86 long gp_sp_offset; /* Offset from new sp to store gp registers. */
87 long fp_sp_offset; /* Offset from new sp to store fp registers. */
88 int initialized; /* != 0 if frame size already calculated. */
89 int num_gp; /* Number of gp registers saved. */
92 struct GTY(()) machine_function
94 /* Current frame information, calculated by compute_frame_size. */
95 long total_size; /* # bytes that the entire frame takes up. */
96 long var_size; /* # bytes that variables take up. */
97 long args_size; /* # bytes that outgoing arguments take up. */
98 long extra_size; /* # bytes of extra gunk. */
99 int gp_reg_size; /* # bytes needed to store gp regs. */
100 int fp_reg_size; /* # bytes needed to store fp regs. */
101 long mask; /* Mask of saved gp registers. */
102 long gp_save_offset; /* Offset from vfp to store gp registers. */
103 long fp_save_offset; /* Offset from vfp to store fp registers. */
104 long gp_sp_offset; /* Offset from new sp to store gp registers. */
105 long fp_sp_offset; /* Offset from new sp to store fp registers. */
106 int initialized; /* != 0 if frame size already calculated. */
107 int num_gp; /* Number of gp registers saved. */
110 /* Global variables for machine-dependent things. */
112 /* List of all IQ2000 punctuation characters used by print_operand. */
113 char iq2000_print_operand_punct[256];
115 /* The target cpu for optimization and scheduling. */
116 enum processor_type iq2000_tune;
118 /* Which instruction set architecture to use. */
121 /* Local variables. */
123 /* The next branch instruction is a branch likely, not branch normal. */
124 static int iq2000_branch_likely;
126 /* Count of delay slots and how many are filled. */
127 static int dslots_load_total;
128 static int dslots_load_filled;
129 static int dslots_jump_total;
131 /* # of nops needed by previous insn. */
132 static int dslots_number_nops;
134 /* Number of 1/2/3 word references to data items (i.e., not jal's). */
135 static int num_refs[3];
137 /* Registers to check for load delay. */
138 static rtx iq2000_load_reg;
139 static rtx iq2000_load_reg2;
140 static rtx iq2000_load_reg3;
141 static rtx iq2000_load_reg4;
143 /* Mode used for saving/restoring general purpose registers. */
144 static enum machine_mode gpr_mode;
147 /* Initialize the GCC target structure. */
148 static struct machine_function* iq2000_init_machine_status (void);
149 static bool iq2000_handle_option (size_t, const char *, int);
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 void iq2000_va_start (tree, rtx);
167 static bool iq2000_legitimate_address_p (enum machine_mode, rtx, bool);
168 static bool iq2000_can_eliminate (const int, const int);
169 static void iq2000_asm_trampoline_template (FILE *);
170 static void iq2000_trampoline_init (rtx, tree, rtx);
172 #undef TARGET_INIT_BUILTINS
173 #define TARGET_INIT_BUILTINS iq2000_init_builtins
174 #undef TARGET_EXPAND_BUILTIN
175 #define TARGET_EXPAND_BUILTIN iq2000_expand_builtin
176 #undef TARGET_ASM_SELECT_RTX_SECTION
177 #define TARGET_ASM_SELECT_RTX_SECTION iq2000_select_rtx_section
178 #undef TARGET_HANDLE_OPTION
179 #define TARGET_HANDLE_OPTION iq2000_handle_option
180 #undef TARGET_RTX_COSTS
181 #define TARGET_RTX_COSTS iq2000_rtx_costs
182 #undef TARGET_ADDRESS_COST
183 #define TARGET_ADDRESS_COST iq2000_address_cost
184 #undef TARGET_ASM_SELECT_SECTION
185 #define TARGET_ASM_SELECT_SECTION iq2000_select_section
187 #undef TARGET_LEGITIMIZE_ADDRESS
188 #define TARGET_LEGITIMIZE_ADDRESS iq2000_legitimize_address
190 /* The assembler supports switchable .bss sections, but
191 iq2000_select_section doesn't yet make use of them. */
192 #undef TARGET_HAVE_SWITCHABLE_BSS_SECTIONS
193 #define TARGET_HAVE_SWITCHABLE_BSS_SECTIONS false
195 #undef TARGET_PROMOTE_FUNCTION_MODE
196 #define TARGET_PROMOTE_FUNCTION_MODE default_promote_function_mode_always_promote
197 #undef TARGET_PROMOTE_PROTOTYPES
198 #define TARGET_PROMOTE_PROTOTYPES hook_bool_const_tree_true
200 #undef TARGET_RETURN_IN_MEMORY
201 #define TARGET_RETURN_IN_MEMORY iq2000_return_in_memory
202 #undef TARGET_PASS_BY_REFERENCE
203 #define TARGET_PASS_BY_REFERENCE iq2000_pass_by_reference
204 #undef TARGET_CALLEE_COPIES
205 #define TARGET_CALLEE_COPIES hook_callee_copies_named
206 #undef TARGET_ARG_PARTIAL_BYTES
207 #define TARGET_ARG_PARTIAL_BYTES iq2000_arg_partial_bytes
209 #undef TARGET_SETUP_INCOMING_VARARGS
210 #define TARGET_SETUP_INCOMING_VARARGS iq2000_setup_incoming_varargs
211 #undef TARGET_STRICT_ARGUMENT_NAMING
212 #define TARGET_STRICT_ARGUMENT_NAMING hook_bool_CUMULATIVE_ARGS_true
214 #undef TARGET_EXPAND_BUILTIN_VA_START
215 #define TARGET_EXPAND_BUILTIN_VA_START iq2000_va_start
217 #undef TARGET_LEGITIMATE_ADDRESS_P
218 #define TARGET_LEGITIMATE_ADDRESS_P iq2000_legitimate_address_p
220 #undef TARGET_CAN_ELIMINATE
221 #define TARGET_CAN_ELIMINATE iq2000_can_eliminate
223 #undef TARGET_ASM_TRAMPOLINE_TEMPLATE
224 #define TARGET_ASM_TRAMPOLINE_TEMPLATE iq2000_asm_trampoline_template
225 #undef TARGET_TRAMPOLINE_INIT
226 #define TARGET_TRAMPOLINE_INIT iq2000_trampoline_init
228 struct gcc_target targetm = TARGET_INITIALIZER;
230 /* Return nonzero if we split the address into high and low parts. */
233 iq2000_check_split (rtx address, enum machine_mode mode)
235 /* This is the same check used in simple_memory_operand.
236 We use it here because LO_SUM is not offsettable. */
237 if (GET_MODE_SIZE (mode) > (unsigned) UNITS_PER_WORD)
240 if ((GET_CODE (address) == SYMBOL_REF)
241 || (GET_CODE (address) == CONST
242 && GET_CODE (XEXP (XEXP (address, 0), 0)) == SYMBOL_REF)
243 || GET_CODE (address) == LABEL_REF)
249 /* Return nonzero if REG is valid for MODE. */
252 iq2000_reg_mode_ok_for_base_p (rtx reg,
253 enum machine_mode mode ATTRIBUTE_UNUSED,
257 ? REGNO_MODE_OK_FOR_BASE_P (REGNO (reg), mode)
258 : GP_REG_OR_PSEUDO_NONSTRICT_P (REGNO (reg), mode));
261 /* Return a nonzero value if XINSN is a legitimate address for a
262 memory operand of the indicated MODE. STRICT is nonzero if this
263 function is called during reload. */
266 iq2000_legitimate_address_p (enum machine_mode mode, rtx xinsn, bool strict)
268 if (TARGET_DEBUG_A_MODE)
270 GO_PRINTF2 ("\n========== legitimate_address_p, %sstrict\n",
271 strict ? "" : "not ");
272 GO_DEBUG_RTX (xinsn);
275 /* Check for constant before stripping off SUBREG, so that we don't
276 accept (subreg (const_int)) which will fail to reload. */
277 if (CONSTANT_ADDRESS_P (xinsn)
278 && ! (iq2000_check_split (xinsn, mode))
279 && ! (GET_CODE (xinsn) == CONST_INT && ! SMALL_INT (xinsn)))
282 while (GET_CODE (xinsn) == SUBREG)
283 xinsn = SUBREG_REG (xinsn);
285 if (GET_CODE (xinsn) == REG
286 && iq2000_reg_mode_ok_for_base_p (xinsn, mode, strict))
289 if (GET_CODE (xinsn) == LO_SUM)
291 rtx xlow0 = XEXP (xinsn, 0);
292 rtx xlow1 = XEXP (xinsn, 1);
294 while (GET_CODE (xlow0) == SUBREG)
295 xlow0 = SUBREG_REG (xlow0);
296 if (GET_CODE (xlow0) == REG
297 && iq2000_reg_mode_ok_for_base_p (xlow0, mode, strict)
298 && iq2000_check_split (xlow1, mode))
302 if (GET_CODE (xinsn) == PLUS)
304 rtx xplus0 = XEXP (xinsn, 0);
305 rtx xplus1 = XEXP (xinsn, 1);
309 while (GET_CODE (xplus0) == SUBREG)
310 xplus0 = SUBREG_REG (xplus0);
311 code0 = GET_CODE (xplus0);
313 while (GET_CODE (xplus1) == SUBREG)
314 xplus1 = SUBREG_REG (xplus1);
315 code1 = GET_CODE (xplus1);
318 && iq2000_reg_mode_ok_for_base_p (xplus0, mode, strict))
320 if (code1 == CONST_INT && SMALL_INT (xplus1)
321 && SMALL_INT_UNSIGNED (xplus1) /* No negative offsets */)
326 if (TARGET_DEBUG_A_MODE)
327 GO_PRINTF ("Not a enum machine_mode mode, legitimate address\n");
329 /* The address was not legitimate. */
333 /* Returns an operand string for the given instruction's delay slot,
334 after updating filled delay slot statistics.
336 We assume that operands[0] is the target register that is set.
338 In order to check the next insn, most of this functionality is moved
339 to FINAL_PRESCAN_INSN, and we just set the global variables that
343 iq2000_fill_delay_slot (const char *ret, enum delay_type type, rtx operands[],
347 enum machine_mode mode;
348 rtx next_insn = cur_insn ? NEXT_INSN (cur_insn) : NULL_RTX;
351 if (type == DELAY_LOAD || type == DELAY_FCMP)
357 /* Make sure that we don't put nop's after labels. */
358 next_insn = NEXT_INSN (cur_insn);
359 while (next_insn != 0
360 && (GET_CODE (next_insn) == NOTE
361 || GET_CODE (next_insn) == CODE_LABEL))
362 next_insn = NEXT_INSN (next_insn);
364 dslots_load_total += num_nops;
365 if (TARGET_DEBUG_C_MODE
366 || type == DELAY_NONE
370 || GET_CODE (next_insn) == CODE_LABEL
371 || (set_reg = operands[0]) == 0)
373 dslots_number_nops = 0;
375 iq2000_load_reg2 = 0;
376 iq2000_load_reg3 = 0;
377 iq2000_load_reg4 = 0;
382 set_reg = operands[0];
386 while (GET_CODE (set_reg) == SUBREG)
387 set_reg = SUBREG_REG (set_reg);
389 mode = GET_MODE (set_reg);
390 dslots_number_nops = num_nops;
391 iq2000_load_reg = set_reg;
392 if (GET_MODE_SIZE (mode)
393 > (unsigned) (UNITS_PER_WORD))
394 iq2000_load_reg2 = gen_rtx_REG (SImode, REGNO (set_reg) + 1);
396 iq2000_load_reg2 = 0;
401 /* Determine whether a memory reference takes one (based off of the GP
402 pointer), two (normal), or three (label + reg) instructions, and bump the
403 appropriate counter for -mstats. */
406 iq2000_count_memory_refs (rtx op, int num)
410 rtx addr, plus0, plus1;
411 enum rtx_code code0, code1;
414 if (TARGET_DEBUG_B_MODE)
416 fprintf (stderr, "\n========== iq2000_count_memory_refs:\n");
420 /* Skip MEM if passed, otherwise handle movsi of address. */
421 addr = (GET_CODE (op) != MEM) ? op : XEXP (op, 0);
423 /* Loop, going through the address RTL. */
427 switch (GET_CODE (addr))
435 plus0 = XEXP (addr, 0);
436 plus1 = XEXP (addr, 1);
437 code0 = GET_CODE (plus0);
438 code1 = GET_CODE (plus1);
448 if (code0 == CONST_INT)
463 if (code1 == CONST_INT)
470 if (code0 == SYMBOL_REF || code0 == LABEL_REF || code0 == CONST)
477 if (code1 == SYMBOL_REF || code1 == LABEL_REF || code1 == CONST)
487 n_words = 2; /* Always 2 words. */
491 addr = XEXP (addr, 0);
496 n_words = SYMBOL_REF_FLAG (addr) ? 1 : 2;
508 n_words += additional;
512 num_refs[n_words-1] += num;
515 /* Abort after printing out a specific insn. */
518 abort_with_insn (rtx insn, const char * reason)
522 fancy_abort (__FILE__, __LINE__, __FUNCTION__);
525 /* Return the appropriate instructions to move one operand to another. */
528 iq2000_move_1word (rtx operands[], rtx insn, int unsignedp)
531 rtx op0 = operands[0];
532 rtx op1 = operands[1];
533 enum rtx_code code0 = GET_CODE (op0);
534 enum rtx_code code1 = GET_CODE (op1);
535 enum machine_mode mode = GET_MODE (op0);
536 int subreg_offset0 = 0;
537 int subreg_offset1 = 0;
538 enum delay_type delay = DELAY_NONE;
540 while (code0 == SUBREG)
542 subreg_offset0 += subreg_regno_offset (REGNO (SUBREG_REG (op0)),
543 GET_MODE (SUBREG_REG (op0)),
546 op0 = SUBREG_REG (op0);
547 code0 = GET_CODE (op0);
550 while (code1 == SUBREG)
552 subreg_offset1 += subreg_regno_offset (REGNO (SUBREG_REG (op1)),
553 GET_MODE (SUBREG_REG (op1)),
556 op1 = SUBREG_REG (op1);
557 code1 = GET_CODE (op1);
560 /* For our purposes, a condition code mode is the same as SImode. */
566 int regno0 = REGNO (op0) + subreg_offset0;
570 int regno1 = REGNO (op1) + subreg_offset1;
572 /* Do not do anything for assigning a register to itself */
573 if (regno0 == regno1)
576 else if (GP_REG_P (regno0))
578 if (GP_REG_P (regno1))
579 ret = "or\t%0,%%0,%1";
584 else if (code1 == MEM)
589 iq2000_count_memory_refs (op1, 1);
591 if (GP_REG_P (regno0))
593 /* For loads, use the mode of the memory item, instead of the
594 target, so zero/sign extend can use this code as well. */
595 switch (GET_MODE (op1))
607 ret = (unsignedp) ? "lhu\t%0,%1" : "lh\t%0,%1";
610 ret = (unsignedp) ? "lbu\t%0,%1" : "lb\t%0,%1";
616 else if (code1 == CONST_INT
617 || (code1 == CONST_DOUBLE
618 && GET_MODE (op1) == VOIDmode))
620 if (code1 == CONST_DOUBLE)
622 /* This can happen when storing constants into long long
623 bitfields. Just store the least significant word of
625 operands[1] = op1 = GEN_INT (CONST_DOUBLE_LOW (op1));
628 if (INTVAL (op1) == 0)
630 if (GP_REG_P (regno0))
631 ret = "or\t%0,%%0,%z1";
633 else if (GP_REG_P (regno0))
635 if (SMALL_INT_UNSIGNED (op1))
636 ret = "ori\t%0,%%0,%x1\t\t\t# %1";
637 else if (SMALL_INT (op1))
638 ret = "addiu\t%0,%%0,%1\t\t\t# %1";
640 ret = "lui\t%0,%X1\t\t\t# %1\n\tori\t%0,%0,%x1";
644 else if (code1 == CONST_DOUBLE && mode == SFmode)
646 if (op1 == CONST0_RTX (SFmode))
648 if (GP_REG_P (regno0))
649 ret = "or\t%0,%%0,%.";
659 else if (code1 == LABEL_REF)
662 iq2000_count_memory_refs (op1, 1);
667 else if (code1 == SYMBOL_REF || code1 == CONST)
670 iq2000_count_memory_refs (op1, 1);
675 else if (code1 == PLUS)
677 rtx add_op0 = XEXP (op1, 0);
678 rtx add_op1 = XEXP (op1, 1);
680 if (GET_CODE (XEXP (op1, 1)) == REG
681 && GET_CODE (XEXP (op1, 0)) == CONST_INT)
682 add_op0 = XEXP (op1, 1), add_op1 = XEXP (op1, 0);
684 operands[2] = add_op0;
685 operands[3] = add_op1;
686 ret = "add%:\t%0,%2,%3";
689 else if (code1 == HIGH)
691 operands[1] = XEXP (op1, 0);
692 ret = "lui\t%0,%%hi(%1)";
696 else if (code0 == MEM)
699 iq2000_count_memory_refs (op0, 1);
703 int regno1 = REGNO (op1) + subreg_offset1;
705 if (GP_REG_P (regno1))
709 case SFmode: ret = "sw\t%1,%0"; break;
710 case SImode: ret = "sw\t%1,%0"; break;
711 case HImode: ret = "sh\t%1,%0"; break;
712 case QImode: ret = "sb\t%1,%0"; break;
718 else if (code1 == CONST_INT && INTVAL (op1) == 0)
722 case SFmode: ret = "sw\t%z1,%0"; break;
723 case SImode: ret = "sw\t%z1,%0"; break;
724 case HImode: ret = "sh\t%z1,%0"; break;
725 case QImode: ret = "sb\t%z1,%0"; break;
730 else if (code1 == CONST_DOUBLE && op1 == CONST0_RTX (mode))
734 case SFmode: ret = "sw\t%.,%0"; break;
735 case SImode: ret = "sw\t%.,%0"; break;
736 case HImode: ret = "sh\t%.,%0"; break;
737 case QImode: ret = "sb\t%.,%0"; break;
745 abort_with_insn (insn, "Bad move");
749 if (delay != DELAY_NONE)
750 return iq2000_fill_delay_slot (ret, delay, operands, insn);
755 /* Provide the costs of an addressing mode that contains ADDR. */
758 iq2000_address_cost (rtx addr, bool speed)
760 switch (GET_CODE (addr))
770 rtx offset = const0_rtx;
772 addr = eliminate_constant_term (XEXP (addr, 0), & offset);
773 if (GET_CODE (addr) == LABEL_REF)
776 if (GET_CODE (addr) != SYMBOL_REF)
779 if (! SMALL_INT (offset))
786 return SYMBOL_REF_FLAG (addr) ? 1 : 2;
790 rtx plus0 = XEXP (addr, 0);
791 rtx plus1 = XEXP (addr, 1);
793 if (GET_CODE (plus0) != REG && GET_CODE (plus1) == REG)
794 plus0 = XEXP (addr, 1), plus1 = XEXP (addr, 0);
796 if (GET_CODE (plus0) != REG)
799 switch (GET_CODE (plus1))
802 return SMALL_INT (plus1) ? 1 : 2;
809 return iq2000_address_cost (plus1, speed) + 1;
823 /* Make normal rtx_code into something we can index from an array. */
825 static enum internal_test
826 map_test_to_internal_test (enum rtx_code test_code)
828 enum internal_test test = ITEST_MAX;
832 case EQ: test = ITEST_EQ; break;
833 case NE: test = ITEST_NE; break;
834 case GT: test = ITEST_GT; break;
835 case GE: test = ITEST_GE; break;
836 case LT: test = ITEST_LT; break;
837 case LE: test = ITEST_LE; break;
838 case GTU: test = ITEST_GTU; break;
839 case GEU: test = ITEST_GEU; break;
840 case LTU: test = ITEST_LTU; break;
841 case LEU: test = ITEST_LEU; break;
848 /* Generate the code to do a TEST_CODE comparison on two integer values CMP0
849 and CMP1. P_INVERT is NULL or ptr if branch needs to reverse its test.
850 The return value RESULT is:
851 (reg:SI xx) The pseudo register the comparison is in
852 0 No register, generate a simple branch. */
855 gen_int_relational (enum rtx_code test_code, rtx result, rtx cmp0, rtx cmp1,
860 enum rtx_code test_code; /* Code to use in instruction (LT vs. LTU). */
861 int const_low; /* Low bound of constant we can accept. */
862 int const_high; /* High bound of constant we can accept. */
863 int const_add; /* Constant to add (convert LE -> LT). */
864 int reverse_regs; /* Reverse registers in test. */
865 int invert_const; /* != 0 if invert value if cmp1 is constant. */
866 int invert_reg; /* != 0 if invert value if cmp1 is register. */
867 int unsignedp; /* != 0 for unsigned comparisons. */
870 static struct cmp_info info[ (int)ITEST_MAX ] =
872 { XOR, 0, 65535, 0, 0, 0, 0, 0 }, /* EQ */
873 { XOR, 0, 65535, 0, 0, 1, 1, 0 }, /* NE */
874 { LT, -32769, 32766, 1, 1, 1, 0, 0 }, /* GT */
875 { LT, -32768, 32767, 0, 0, 1, 1, 0 }, /* GE */
876 { LT, -32768, 32767, 0, 0, 0, 0, 0 }, /* LT */
877 { LT, -32769, 32766, 1, 1, 0, 1, 0 }, /* LE */
878 { LTU, -32769, 32766, 1, 1, 1, 0, 1 }, /* GTU */
879 { LTU, -32768, 32767, 0, 0, 1, 1, 1 }, /* GEU */
880 { LTU, -32768, 32767, 0, 0, 0, 0, 1 }, /* LTU */
881 { LTU, -32769, 32766, 1, 1, 0, 1, 1 }, /* LEU */
884 enum internal_test test;
885 enum machine_mode mode;
886 struct cmp_info *p_info;
893 test = map_test_to_internal_test (test_code);
894 gcc_assert (test != ITEST_MAX);
896 p_info = &info[(int) test];
897 eqne_p = (p_info->test_code == XOR);
899 mode = GET_MODE (cmp0);
900 if (mode == VOIDmode)
901 mode = GET_MODE (cmp1);
903 /* Eliminate simple branches. */
904 branch_p = (result == 0);
907 if (GET_CODE (cmp0) == REG || GET_CODE (cmp0) == SUBREG)
909 /* Comparisons against zero are simple branches. */
910 if (GET_CODE (cmp1) == CONST_INT && INTVAL (cmp1) == 0)
913 /* Test for beq/bne. */
918 /* Allocate a pseudo to calculate the value in. */
919 result = gen_reg_rtx (mode);
922 /* Make sure we can handle any constants given to us. */
923 if (GET_CODE (cmp0) == CONST_INT)
924 cmp0 = force_reg (mode, cmp0);
926 if (GET_CODE (cmp1) == CONST_INT)
928 HOST_WIDE_INT value = INTVAL (cmp1);
930 if (value < p_info->const_low
931 || value > p_info->const_high)
932 cmp1 = force_reg (mode, cmp1);
935 /* See if we need to invert the result. */
936 invert = (GET_CODE (cmp1) == CONST_INT
937 ? p_info->invert_const : p_info->invert_reg);
939 if (p_invert != (int *)0)
945 /* Comparison to constants, may involve adding 1 to change a LT into LE.
946 Comparison between two registers, may involve switching operands. */
947 if (GET_CODE (cmp1) == CONST_INT)
949 if (p_info->const_add != 0)
951 HOST_WIDE_INT new_const = INTVAL (cmp1) + p_info->const_add;
953 /* If modification of cmp1 caused overflow,
954 we would get the wrong answer if we follow the usual path;
955 thus, x > 0xffffffffU would turn into x > 0U. */
956 if ((p_info->unsignedp
957 ? (unsigned HOST_WIDE_INT) new_const >
958 (unsigned HOST_WIDE_INT) INTVAL (cmp1)
959 : new_const > INTVAL (cmp1))
960 != (p_info->const_add > 0))
962 /* This test is always true, but if INVERT is true then
963 the result of the test needs to be inverted so 0 should
964 be returned instead. */
965 emit_move_insn (result, invert ? const0_rtx : const_true_rtx);
969 cmp1 = GEN_INT (new_const);
973 else if (p_info->reverse_regs)
980 if (test == ITEST_NE && GET_CODE (cmp1) == CONST_INT && INTVAL (cmp1) == 0)
984 reg = (invert || eqne_p) ? gen_reg_rtx (mode) : result;
985 convert_move (reg, gen_rtx_fmt_ee (p_info->test_code, mode, cmp0, cmp1), 0);
988 if (test == ITEST_NE)
990 convert_move (result, gen_rtx_GTU (mode, reg, const0_rtx), 0);
991 if (p_invert != NULL)
996 else if (test == ITEST_EQ)
998 reg2 = invert ? gen_reg_rtx (mode) : result;
999 convert_move (reg2, gen_rtx_LTU (mode, reg, const1_rtx), 0);
1008 convert_move (result, gen_rtx_XOR (mode, reg, one), 0);
1014 /* Emit the common code for doing conditional branches.
1015 operand[0] is the label to jump to.
1016 The comparison operands are saved away by cmp{si,di,sf,df}. */
1019 gen_conditional_branch (rtx operands[], enum machine_mode mode)
1021 enum rtx_code test_code = GET_CODE (operands[0]);
1022 rtx cmp0 = operands[1];
1023 rtx cmp1 = operands[2];
1029 reg = gen_int_relational (test_code, NULL_RTX, cmp0, cmp1, &invert);
1037 else if (GET_CODE (cmp1) == CONST_INT && INTVAL (cmp1) != 0)
1038 /* We don't want to build a comparison against a nonzero
1040 cmp1 = force_reg (mode, cmp1);
1042 /* Generate the branch. */
1043 label1 = gen_rtx_LABEL_REF (VOIDmode, operands[3]);
1052 emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
1053 gen_rtx_IF_THEN_ELSE (VOIDmode,
1054 gen_rtx_fmt_ee (test_code,
1060 /* Initialize CUM for a function FNTYPE. */
1063 init_cumulative_args (CUMULATIVE_ARGS *cum, tree fntype,
1064 rtx libname ATTRIBUTE_UNUSED)
1066 static CUMULATIVE_ARGS zero_cum;
1070 if (TARGET_DEBUG_D_MODE)
1073 "\ninit_cumulative_args, fntype = 0x%.8lx", (long) fntype);
1076 fputc ('\n', stderr);
1080 tree ret_type = TREE_TYPE (fntype);
1082 fprintf (stderr, ", fntype code = %s, ret code = %s\n",
1083 tree_code_name[(int)TREE_CODE (fntype)],
1084 tree_code_name[(int)TREE_CODE (ret_type)]);
1090 /* Determine if this function has variable arguments. This is
1091 indicated by the last argument being 'void_type_mode' if there
1092 are no variable arguments. The standard IQ2000 calling sequence
1093 passes all arguments in the general purpose registers in this case. */
1095 for (param = fntype ? TYPE_ARG_TYPES (fntype) : 0;
1096 param != 0; param = next_param)
1098 next_param = TREE_CHAIN (param);
1099 if (next_param == 0 && TREE_VALUE (param) != void_type_node)
1100 cum->gp_reg_found = 1;
1104 /* Advance the argument of type TYPE and mode MODE to the next argument
1108 function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode, tree type,
1111 if (TARGET_DEBUG_D_MODE)
1114 "function_adv({gp reg found = %d, arg # = %2d, words = %2d}, %4s, ",
1115 cum->gp_reg_found, cum->arg_number, cum->arg_words,
1116 GET_MODE_NAME (mode));
1117 fprintf (stderr, "%p", (void *) type);
1118 fprintf (stderr, ", %d )\n\n", named);
1128 gcc_assert (GET_MODE_CLASS (mode) == MODE_COMPLEX_INT
1129 || GET_MODE_CLASS (mode) == MODE_COMPLEX_FLOAT);
1131 cum->gp_reg_found = 1;
1132 cum->arg_words += ((GET_MODE_SIZE (mode) + UNITS_PER_WORD - 1)
1137 cum->gp_reg_found = 1;
1138 cum->arg_words += ((int_size_in_bytes (type) + UNITS_PER_WORD - 1)
1144 if (! cum->gp_reg_found && cum->arg_number <= 2)
1145 cum->fp_code += 1 << ((cum->arg_number - 1) * 2);
1149 cum->arg_words += 2;
1150 if (! cum->gp_reg_found && cum->arg_number <= 2)
1151 cum->fp_code += 2 << ((cum->arg_number - 1) * 2);
1155 cum->gp_reg_found = 1;
1156 cum->arg_words += 2;
1160 cum->gp_reg_found = 1;
1161 cum->arg_words += 4;
1167 cum->gp_reg_found = 1;
1173 /* Return an RTL expression containing the register for the given mode MODE
1174 and type TYPE in CUM, or 0 if the argument is to be passed on the stack. */
1177 function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode, const_tree type,
1183 unsigned int *arg_words = &cum->arg_words;
1184 int struct_p = (type != 0
1185 && (TREE_CODE (type) == RECORD_TYPE
1186 || TREE_CODE (type) == UNION_TYPE
1187 || TREE_CODE (type) == QUAL_UNION_TYPE));
1189 if (TARGET_DEBUG_D_MODE)
1192 "function_arg( {gp reg found = %d, arg # = %2d, words = %2d}, %4s, ",
1193 cum->gp_reg_found, cum->arg_number, cum->arg_words,
1194 GET_MODE_NAME (mode));
1195 fprintf (stderr, "%p", (const void *) type);
1196 fprintf (stderr, ", %d ) = ", named);
1200 cum->last_arg_fp = 0;
1204 regbase = GP_ARG_FIRST;
1208 cum->arg_words += cum->arg_words & 1;
1210 regbase = GP_ARG_FIRST;
1214 gcc_assert (GET_MODE_CLASS (mode) == MODE_COMPLEX_INT
1215 || GET_MODE_CLASS (mode) == MODE_COMPLEX_FLOAT);
1217 /* Drops through. */
1219 if (type != NULL_TREE && TYPE_ALIGN (type) > (unsigned) BITS_PER_WORD)
1220 cum->arg_words += (cum->arg_words & 1);
1221 regbase = GP_ARG_FIRST;
1228 regbase = GP_ARG_FIRST;
1232 cum->arg_words += (cum->arg_words & 1);
1233 regbase = GP_ARG_FIRST;
1237 cum->arg_words += (cum->arg_words & 3);
1238 regbase = GP_ARG_FIRST;
1242 if (*arg_words >= (unsigned) MAX_ARGS_IN_REGISTERS)
1244 if (TARGET_DEBUG_D_MODE)
1245 fprintf (stderr, "<stack>%s\n", struct_p ? ", [struct]" : "");
1251 gcc_assert (regbase != -1);
1253 if (! type || TREE_CODE (type) != RECORD_TYPE
1254 || ! named || ! TYPE_SIZE_UNIT (type)
1255 || ! host_integerp (TYPE_SIZE_UNIT (type), 1))
1256 ret = gen_rtx_REG (mode, regbase + *arg_words + bias);
1261 for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field))
1262 if (TREE_CODE (field) == FIELD_DECL
1263 && TREE_CODE (TREE_TYPE (field)) == REAL_TYPE
1264 && TYPE_PRECISION (TREE_TYPE (field)) == BITS_PER_WORD
1265 && host_integerp (bit_position (field), 0)
1266 && int_bit_position (field) % BITS_PER_WORD == 0)
1269 /* If the whole struct fits a DFmode register,
1270 we don't need the PARALLEL. */
1271 if (! field || mode == DFmode)
1272 ret = gen_rtx_REG (mode, regbase + *arg_words + bias);
1275 unsigned int chunks;
1276 HOST_WIDE_INT bitpos;
1280 /* ??? If this is a packed structure, then the last hunk won't
1283 = tree_low_cst (TYPE_SIZE_UNIT (type), 1) / UNITS_PER_WORD;
1284 if (chunks + *arg_words + bias > (unsigned) MAX_ARGS_IN_REGISTERS)
1285 chunks = MAX_ARGS_IN_REGISTERS - *arg_words - bias;
1287 /* Assign_parms checks the mode of ENTRY_PARM, so we must
1288 use the actual mode here. */
1289 ret = gen_rtx_PARALLEL (mode, rtvec_alloc (chunks));
1292 regno = regbase + *arg_words + bias;
1293 field = TYPE_FIELDS (type);
1294 for (i = 0; i < chunks; i++)
1298 for (; field; field = TREE_CHAIN (field))
1299 if (TREE_CODE (field) == FIELD_DECL
1300 && int_bit_position (field) >= bitpos)
1304 && int_bit_position (field) == bitpos
1305 && TREE_CODE (TREE_TYPE (field)) == REAL_TYPE
1306 && TYPE_PRECISION (TREE_TYPE (field)) == BITS_PER_WORD)
1307 reg = gen_rtx_REG (DFmode, regno++);
1309 reg = gen_rtx_REG (word_mode, regno);
1312 = gen_rtx_EXPR_LIST (VOIDmode, reg,
1313 GEN_INT (bitpos / BITS_PER_UNIT));
1321 if (TARGET_DEBUG_D_MODE)
1322 fprintf (stderr, "%s%s\n", reg_names[regbase + *arg_words + bias],
1323 struct_p ? ", [struct]" : "");
1326 /* We will be called with a mode of VOIDmode after the last argument
1327 has been seen. Whatever we return will be passed to the call
1328 insn. If we need any shifts for small structures, return them in
1330 if (mode == VOIDmode)
1332 if (cum->num_adjusts > 0)
1333 ret = gen_rtx_PARALLEL ((enum machine_mode) cum->fp_code,
1334 gen_rtvec_v (cum->num_adjusts, cum->adjust));
1341 iq2000_arg_partial_bytes (CUMULATIVE_ARGS *cum, enum machine_mode mode,
1342 tree type ATTRIBUTE_UNUSED,
1343 bool named ATTRIBUTE_UNUSED)
1345 if (mode == DImode && cum->arg_words == MAX_ARGS_IN_REGISTERS - 1)
1347 if (TARGET_DEBUG_D_MODE)
1348 fprintf (stderr, "iq2000_arg_partial_bytes=%d\n", UNITS_PER_WORD);
1349 return UNITS_PER_WORD;
1355 /* Implement va_start. */
1358 iq2000_va_start (tree valist, rtx nextarg)
1361 /* Find out how many non-float named formals. */
1362 int gpr_save_area_size;
1363 /* Note UNITS_PER_WORD is 4 bytes. */
1364 int_arg_words = crtl->args.info.arg_words;
1366 if (int_arg_words < 8 )
1367 /* Adjust for the prologue's economy measure. */
1368 gpr_save_area_size = (8 - int_arg_words) * UNITS_PER_WORD;
1370 gpr_save_area_size = 0;
1372 /* Everything is in the GPR save area, or in the overflow
1373 area which is contiguous with it. */
1374 nextarg = plus_constant (nextarg, - gpr_save_area_size);
1375 std_expand_builtin_va_start (valist, nextarg);
1378 /* Allocate a chunk of memory for per-function machine-dependent data. */
1380 static struct machine_function *
1381 iq2000_init_machine_status (void)
1383 struct machine_function *f;
1385 f = GGC_CNEW (struct machine_function);
1390 /* Implement TARGET_HANDLE_OPTION. */
1393 iq2000_handle_option (size_t code, const char *arg, int value ATTRIBUTE_UNUSED)
1398 if (strcmp (arg, "iq10") == 0)
1399 iq2000_tune = PROCESSOR_IQ10;
1400 else if (strcmp (arg, "iq2000") == 0)
1401 iq2000_tune = PROCESSOR_IQ2000;
1407 /* This option has no effect at the moment. */
1408 return (strcmp (arg, "default") == 0
1409 || strcmp (arg, "DEFAULT") == 0
1410 || strcmp (arg, "iq2000") == 0);
1417 /* Detect any conflicts in the switches. */
1420 override_options (void)
1422 target_flags &= ~MASK_GPOPT;
1424 iq2000_isa = IQ2000_ISA_DEFAULT;
1426 /* Identify the processor type. */
1428 iq2000_print_operand_punct['?'] = 1;
1429 iq2000_print_operand_punct['#'] = 1;
1430 iq2000_print_operand_punct['&'] = 1;
1431 iq2000_print_operand_punct['!'] = 1;
1432 iq2000_print_operand_punct['*'] = 1;
1433 iq2000_print_operand_punct['@'] = 1;
1434 iq2000_print_operand_punct['.'] = 1;
1435 iq2000_print_operand_punct['('] = 1;
1436 iq2000_print_operand_punct[')'] = 1;
1437 iq2000_print_operand_punct['['] = 1;
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;
1448 /* Save GPR registers in word_mode sized hunks. word_mode hasn't been
1449 initialized yet, so we can't use that here. */
1452 /* Function to allocate machine-dependent function status. */
1453 init_machine_status = iq2000_init_machine_status;
1456 /* The arg pointer (which is eliminated) points to the virtual frame pointer,
1457 while the frame pointer (which may be eliminated) points to the stack
1458 pointer after the initial adjustments. */
1461 iq2000_debugger_offset (rtx addr, HOST_WIDE_INT offset)
1463 rtx offset2 = const0_rtx;
1464 rtx reg = eliminate_constant_term (addr, & offset2);
1467 offset = INTVAL (offset2);
1469 if (reg == stack_pointer_rtx || reg == frame_pointer_rtx
1470 || reg == hard_frame_pointer_rtx)
1472 HOST_WIDE_INT frame_size = (!cfun->machine->initialized)
1473 ? compute_frame_size (get_frame_size ())
1474 : cfun->machine->total_size;
1476 offset = offset - frame_size;
1482 /* If defined, a C statement to be executed just prior to the output of
1483 assembler code for INSN, to modify the extracted operands so they will be
1486 Here the argument OPVEC is the vector containing the operands extracted
1487 from INSN, and NOPERANDS is the number of elements of the vector which
1488 contain meaningful data for this insn. The contents of this vector are
1489 what will be used to convert the insn template into assembler code, so you
1490 can change the assembler output by changing the contents of the vector.
1492 We use it to check if the current insn needs a nop in front of it because
1493 of load delays, and also to update the delay slot statistics. */
1496 final_prescan_insn (rtx insn, rtx opvec[] ATTRIBUTE_UNUSED,
1497 int noperands ATTRIBUTE_UNUSED)
1499 if (dslots_number_nops > 0)
1501 rtx pattern = PATTERN (insn);
1502 int length = get_attr_length (insn);
1504 /* Do we need to emit a NOP? */
1506 || (iq2000_load_reg != 0 && reg_mentioned_p (iq2000_load_reg, pattern))
1507 || (iq2000_load_reg2 != 0 && reg_mentioned_p (iq2000_load_reg2, pattern))
1508 || (iq2000_load_reg3 != 0 && reg_mentioned_p (iq2000_load_reg3, pattern))
1509 || (iq2000_load_reg4 != 0
1510 && reg_mentioned_p (iq2000_load_reg4, pattern)))
1511 fputs ("\tnop\n", asm_out_file);
1514 dslots_load_filled ++;
1516 while (--dslots_number_nops > 0)
1517 fputs ("\tnop\n", asm_out_file);
1519 iq2000_load_reg = 0;
1520 iq2000_load_reg2 = 0;
1521 iq2000_load_reg3 = 0;
1522 iq2000_load_reg4 = 0;
1525 if ( (GET_CODE (insn) == JUMP_INSN
1526 || GET_CODE (insn) == CALL_INSN
1527 || (GET_CODE (PATTERN (insn)) == RETURN))
1528 && NEXT_INSN (PREV_INSN (insn)) == insn)
1530 rtx nop_insn = emit_insn_after (gen_nop (), insn);
1532 INSN_ADDRESSES_NEW (nop_insn, -1);
1536 && (GET_CODE (insn) == JUMP_INSN || GET_CODE (insn) == CALL_INSN))
1537 dslots_jump_total ++;
1540 /* Return the bytes needed to compute the frame pointer from the current
1541 stack pointer where SIZE is the # of var. bytes allocated.
1543 IQ2000 stack frames look like:
1545 Before call After call
1546 +-----------------------+ +-----------------------+
1549 | caller's temps. | | caller's temps. |
1551 +-----------------------+ +-----------------------+
1553 | arguments on stack. | | arguments on stack. |
1555 +-----------------------+ +-----------------------+
1556 | 4 words to save | | 4 words to save |
1557 | arguments passed | | arguments passed |
1558 | in registers, even | | in registers, even |
1559 SP->| if not passed. | VFP->| if not passed. |
1560 +-----------------------+ +-----------------------+
1562 | fp register save |
1564 +-----------------------+
1566 | gp register save |
1568 +-----------------------+
1572 +-----------------------+
1574 | alloca allocations |
1576 +-----------------------+
1578 | GP save for V.4 abi |
1580 +-----------------------+
1582 | arguments on stack |
1584 +-----------------------+
1586 | arguments passed |
1587 | in registers, even |
1588 low SP->| if not passed. |
1589 memory +-----------------------+ */
1592 compute_frame_size (HOST_WIDE_INT size)
1595 HOST_WIDE_INT total_size; /* # bytes that the entire frame takes up. */
1596 HOST_WIDE_INT var_size; /* # bytes that variables take up. */
1597 HOST_WIDE_INT args_size; /* # bytes that outgoing arguments take up. */
1598 HOST_WIDE_INT extra_size; /* # extra bytes. */
1599 HOST_WIDE_INT gp_reg_rounded; /* # bytes needed to store gp after rounding. */
1600 HOST_WIDE_INT gp_reg_size; /* # bytes needed to store gp regs. */
1601 HOST_WIDE_INT fp_reg_size; /* # bytes needed to store fp regs. */
1602 long mask; /* mask of saved gp registers. */
1603 int fp_inc; /* 1 or 2 depending on the size of fp regs. */
1604 long fp_bits; /* bitmask to use for each fp register. */
1609 extra_size = IQ2000_STACK_ALIGN ((0));
1610 var_size = IQ2000_STACK_ALIGN (size);
1611 args_size = IQ2000_STACK_ALIGN (crtl->outgoing_args_size);
1613 /* If a function dynamically allocates the stack and
1614 has 0 for STACK_DYNAMIC_OFFSET then allocate some stack space. */
1615 if (args_size == 0 && cfun->calls_alloca)
1616 args_size = 4 * UNITS_PER_WORD;
1618 total_size = var_size + args_size + extra_size;
1620 /* Calculate space needed for gp registers. */
1621 for (regno = GP_REG_FIRST; regno <= GP_REG_LAST; regno++)
1623 if (MUST_SAVE_REGISTER (regno))
1625 gp_reg_size += GET_MODE_SIZE (gpr_mode);
1626 mask |= 1L << (regno - GP_REG_FIRST);
1630 /* We need to restore these for the handler. */
1631 if (crtl->calls_eh_return)
1637 regno = EH_RETURN_DATA_REGNO (i);
1638 if (regno == (int) INVALID_REGNUM)
1640 gp_reg_size += GET_MODE_SIZE (gpr_mode);
1641 mask |= 1L << (regno - GP_REG_FIRST);
1647 gp_reg_rounded = IQ2000_STACK_ALIGN (gp_reg_size);
1648 total_size += gp_reg_rounded + IQ2000_STACK_ALIGN (fp_reg_size);
1650 /* The gp reg is caller saved, so there is no need for leaf routines
1651 (total_size == extra_size) to save the gp reg. */
1652 if (total_size == extra_size
1654 total_size = extra_size = 0;
1656 total_size += IQ2000_STACK_ALIGN (crtl->args.pretend_args_size);
1658 /* Save other computed information. */
1659 cfun->machine->total_size = total_size;
1660 cfun->machine->var_size = var_size;
1661 cfun->machine->args_size = args_size;
1662 cfun->machine->extra_size = extra_size;
1663 cfun->machine->gp_reg_size = gp_reg_size;
1664 cfun->machine->fp_reg_size = fp_reg_size;
1665 cfun->machine->mask = mask;
1666 cfun->machine->initialized = reload_completed;
1667 cfun->machine->num_gp = gp_reg_size / UNITS_PER_WORD;
1671 unsigned long offset;
1673 offset = (args_size + extra_size + var_size
1674 + gp_reg_size - GET_MODE_SIZE (gpr_mode));
1676 cfun->machine->gp_sp_offset = offset;
1677 cfun->machine->gp_save_offset = offset - total_size;
1681 cfun->machine->gp_sp_offset = 0;
1682 cfun->machine->gp_save_offset = 0;
1685 cfun->machine->fp_sp_offset = 0;
1686 cfun->machine->fp_save_offset = 0;
1688 /* Ok, we're done. */
1693 /* We can always eliminate to the frame pointer. We can eliminate to the
1694 stack pointer unless a frame pointer is needed. */
1697 iq2000_can_eliminate (const int from, const int to)
1699 return (from == RETURN_ADDRESS_POINTER_REGNUM
1700 && (! leaf_function_p ()
1701 || (to == GP_REG_FIRST + 31 && leaf_function_p)))
1702 || (from != RETURN_ADDRESS_POINTER_REGNUM
1703 && (to == HARD_FRAME_POINTER_REGNUM
1704 || (to == STACK_POINTER_REGNUM
1705 && ! frame_pointer_needed)));
1708 /* Implement INITIAL_ELIMINATION_OFFSET. FROM is either the frame
1709 pointer, argument pointer, or return address pointer. TO is either
1710 the stack pointer or hard frame pointer. */
1713 iq2000_initial_elimination_offset (int from, int to ATTRIBUTE_UNUSED)
1717 compute_frame_size (get_frame_size ());
1718 if ((from) == FRAME_POINTER_REGNUM)
1720 else if ((from) == ARG_POINTER_REGNUM)
1721 (offset) = (cfun->machine->total_size);
1722 else if ((from) == RETURN_ADDRESS_POINTER_REGNUM)
1724 if (leaf_function_p ())
1726 else (offset) = cfun->machine->gp_sp_offset
1727 + ((UNITS_PER_WORD - (POINTER_SIZE / BITS_PER_UNIT))
1728 * (BYTES_BIG_ENDIAN != 0));
1734 /* Common code to emit the insns (or to write the instructions to a file)
1735 to save/restore registers.
1736 Other parts of the code assume that IQ2000_TEMP1_REGNUM (aka large_reg)
1737 is not modified within save_restore_insns. */
1739 #define BITSET_P(VALUE,BIT) (((VALUE) & (1L << (BIT))) != 0)
1741 /* Emit instructions to load the value (SP + OFFSET) into IQ2000_TEMP2_REGNUM
1742 and return an rtl expression for the register. Write the assembly
1743 instructions directly to FILE if it is not null, otherwise emit them as
1746 This function is a subroutine of save_restore_insns. It is used when
1747 OFFSET is too large to add in a single instruction. */
1750 iq2000_add_large_offset_to_sp (HOST_WIDE_INT offset)
1752 rtx reg = gen_rtx_REG (Pmode, IQ2000_TEMP2_REGNUM);
1753 rtx offset_rtx = GEN_INT (offset);
1755 emit_move_insn (reg, offset_rtx);
1756 emit_insn (gen_addsi3 (reg, reg, stack_pointer_rtx));
1760 /* Make INSN frame related and note that it performs the frame-related
1761 operation DWARF_PATTERN. */
1764 iq2000_annotate_frame_insn (rtx insn, rtx dwarf_pattern)
1766 RTX_FRAME_RELATED_P (insn) = 1;
1767 REG_NOTES (insn) = alloc_EXPR_LIST (REG_FRAME_RELATED_EXPR,
1772 /* Emit a move instruction that stores REG in MEM. Make the instruction
1773 frame related and note that it stores REG at (SP + OFFSET). */
1776 iq2000_emit_frame_related_store (rtx mem, rtx reg, HOST_WIDE_INT offset)
1778 rtx dwarf_address = plus_constant (stack_pointer_rtx, offset);
1779 rtx dwarf_mem = gen_rtx_MEM (GET_MODE (reg), dwarf_address);
1781 iq2000_annotate_frame_insn (emit_move_insn (mem, reg),
1782 gen_rtx_SET (GET_MODE (reg), dwarf_mem, reg));
1785 /* Emit instructions to save/restore registers, as determined by STORE_P. */
1788 save_restore_insns (int store_p)
1790 long mask = cfun->machine->mask;
1793 HOST_WIDE_INT base_offset;
1794 HOST_WIDE_INT gp_offset;
1795 HOST_WIDE_INT end_offset;
1797 gcc_assert (!frame_pointer_needed
1798 || BITSET_P (mask, HARD_FRAME_POINTER_REGNUM - GP_REG_FIRST));
1802 base_reg_rtx = 0, base_offset = 0;
1806 /* Save registers starting from high to low. The debuggers prefer at least
1807 the return register be stored at func+4, and also it allows us not to
1808 need a nop in the epilog if at least one register is reloaded in
1809 addition to return address. */
1811 /* Save GP registers if needed. */
1812 /* Pick which pointer to use as a base register. For small frames, just
1813 use the stack pointer. Otherwise, use a temporary register. Save 2
1814 cycles if the save area is near the end of a large frame, by reusing
1815 the constant created in the prologue/epilogue to adjust the stack
1818 gp_offset = cfun->machine->gp_sp_offset;
1820 = gp_offset - (cfun->machine->gp_reg_size
1821 - GET_MODE_SIZE (gpr_mode));
1823 if (gp_offset < 0 || end_offset < 0)
1825 ("gp_offset (%ld) or end_offset (%ld) is less than zero",
1826 (long) gp_offset, (long) end_offset);
1828 else if (gp_offset < 32768)
1829 base_reg_rtx = stack_pointer_rtx, base_offset = 0;
1833 int reg_save_count = 0;
1835 for (regno = GP_REG_LAST; regno >= GP_REG_FIRST; regno--)
1836 if (BITSET_P (mask, regno - GP_REG_FIRST)) reg_save_count += 1;
1837 base_offset = gp_offset - ((reg_save_count - 1) * 4);
1838 base_reg_rtx = iq2000_add_large_offset_to_sp (base_offset);
1841 for (regno = GP_REG_LAST; regno >= GP_REG_FIRST; regno--)
1843 if (BITSET_P (mask, regno - GP_REG_FIRST))
1847 = gen_rtx_MEM (gpr_mode,
1848 gen_rtx_PLUS (Pmode, base_reg_rtx,
1849 GEN_INT (gp_offset - base_offset)));
1851 reg_rtx = gen_rtx_REG (gpr_mode, regno);
1854 iq2000_emit_frame_related_store (mem_rtx, reg_rtx, gp_offset);
1857 emit_move_insn (reg_rtx, mem_rtx);
1859 gp_offset -= GET_MODE_SIZE (gpr_mode);
1864 /* Expand the prologue into a bunch of separate insns. */
1867 iq2000_expand_prologue (void)
1870 HOST_WIDE_INT tsize;
1871 int last_arg_is_vararg_marker = 0;
1872 tree fndecl = current_function_decl;
1873 tree fntype = TREE_TYPE (fndecl);
1874 tree fnargs = DECL_ARGUMENTS (fndecl);
1879 CUMULATIVE_ARGS args_so_far;
1880 int store_args_on_stack = (iq2000_can_use_return_insn ());
1882 /* If struct value address is treated as the first argument. */
1883 if (aggregate_value_p (DECL_RESULT (fndecl), fndecl)
1884 && !cfun->returns_pcc_struct
1885 && targetm.calls.struct_value_rtx (TREE_TYPE (fndecl), 1) == 0)
1887 tree type = build_pointer_type (fntype);
1888 tree function_result_decl = build_decl (BUILTINS_LOCATION,
1889 PARM_DECL, NULL_TREE, type);
1891 DECL_ARG_TYPE (function_result_decl) = type;
1892 TREE_CHAIN (function_result_decl) = fnargs;
1893 fnargs = function_result_decl;
1896 /* For arguments passed in registers, find the register number
1897 of the first argument in the variable part of the argument list,
1898 otherwise GP_ARG_LAST+1. Note also if the last argument is
1899 the varargs special argument, and treat it as part of the
1902 This is only needed if store_args_on_stack is true. */
1903 INIT_CUMULATIVE_ARGS (args_so_far, fntype, NULL_RTX, 0, 0);
1904 regno = GP_ARG_FIRST;
1906 for (cur_arg = fnargs; cur_arg != 0; cur_arg = next_arg)
1908 tree passed_type = DECL_ARG_TYPE (cur_arg);
1909 enum machine_mode passed_mode = TYPE_MODE (passed_type);
1912 if (TREE_ADDRESSABLE (passed_type))
1914 passed_type = build_pointer_type (passed_type);
1915 passed_mode = Pmode;
1918 entry_parm = FUNCTION_ARG (args_so_far, passed_mode, passed_type, 1);
1920 FUNCTION_ARG_ADVANCE (args_so_far, passed_mode, passed_type, 1);
1921 next_arg = TREE_CHAIN (cur_arg);
1923 if (entry_parm && store_args_on_stack)
1926 && DECL_NAME (cur_arg)
1927 && ((0 == strcmp (IDENTIFIER_POINTER (DECL_NAME (cur_arg)),
1928 "__builtin_va_alist"))
1929 || (0 == strcmp (IDENTIFIER_POINTER (DECL_NAME (cur_arg)),
1932 last_arg_is_vararg_marker = 1;
1939 gcc_assert (GET_CODE (entry_parm) == REG);
1941 /* Passed in a register, so will get homed automatically. */
1942 if (GET_MODE (entry_parm) == BLKmode)
1943 words = (int_size_in_bytes (passed_type) + 3) / 4;
1945 words = (GET_MODE_SIZE (GET_MODE (entry_parm)) + 3) / 4;
1947 regno = REGNO (entry_parm) + words - 1;
1952 regno = GP_ARG_LAST+1;
1957 /* In order to pass small structures by value in registers we need to
1958 shift the value into the high part of the register.
1959 Function_arg has encoded a PARALLEL rtx, holding a vector of
1960 adjustments to be made as the next_arg_reg variable, so we split up the
1961 insns, and emit them separately. */
1962 next_arg_reg = FUNCTION_ARG (args_so_far, VOIDmode, void_type_node, 1);
1963 if (next_arg_reg != 0 && GET_CODE (next_arg_reg) == PARALLEL)
1965 rtvec adjust = XVEC (next_arg_reg, 0);
1966 int num = GET_NUM_ELEM (adjust);
1968 for (i = 0; i < num; i++)
1972 pattern = RTVEC_ELT (adjust, i);
1973 if (GET_CODE (pattern) != SET
1974 || GET_CODE (SET_SRC (pattern)) != ASHIFT)
1975 abort_with_insn (pattern, "Insn is not a shift");
1976 PUT_CODE (SET_SRC (pattern), ASHIFTRT);
1978 insn = emit_insn (pattern);
1982 tsize = compute_frame_size (get_frame_size ());
1984 /* If this function is a varargs function, store any registers that
1985 would normally hold arguments ($4 - $7) on the stack. */
1986 if (store_args_on_stack
1987 && ((TYPE_ARG_TYPES (fntype) != 0
1988 && (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
1990 || last_arg_is_vararg_marker))
1992 int offset = (regno - GP_ARG_FIRST) * UNITS_PER_WORD;
1993 rtx ptr = stack_pointer_rtx;
1995 for (; regno <= GP_ARG_LAST; regno++)
1998 ptr = gen_rtx_PLUS (Pmode, stack_pointer_rtx, GEN_INT (offset));
1999 emit_move_insn (gen_rtx_MEM (gpr_mode, ptr),
2000 gen_rtx_REG (gpr_mode, regno));
2002 offset += GET_MODE_SIZE (gpr_mode);
2008 rtx tsize_rtx = GEN_INT (tsize);
2009 rtx adjustment_rtx, insn, dwarf_pattern;
2013 adjustment_rtx = gen_rtx_REG (Pmode, IQ2000_TEMP1_REGNUM);
2014 emit_move_insn (adjustment_rtx, tsize_rtx);
2017 adjustment_rtx = tsize_rtx;
2019 insn = emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
2022 dwarf_pattern = gen_rtx_SET (Pmode, stack_pointer_rtx,
2023 plus_constant (stack_pointer_rtx, -tsize));
2025 iq2000_annotate_frame_insn (insn, dwarf_pattern);
2027 save_restore_insns (1);
2029 if (frame_pointer_needed)
2033 insn = emit_insn (gen_movsi (hard_frame_pointer_rtx,
2034 stack_pointer_rtx));
2037 RTX_FRAME_RELATED_P (insn) = 1;
2041 emit_insn (gen_blockage ());
2044 /* Expand the epilogue into a bunch of separate insns. */
2047 iq2000_expand_epilogue (void)
2049 HOST_WIDE_INT tsize = cfun->machine->total_size;
2050 rtx tsize_rtx = GEN_INT (tsize);
2051 rtx tmp_rtx = (rtx)0;
2053 if (iq2000_can_use_return_insn ())
2055 emit_jump_insn (gen_return ());
2061 tmp_rtx = gen_rtx_REG (Pmode, IQ2000_TEMP1_REGNUM);
2062 emit_move_insn (tmp_rtx, tsize_rtx);
2063 tsize_rtx = tmp_rtx;
2068 if (frame_pointer_needed)
2070 emit_insn (gen_blockage ());
2072 emit_insn (gen_movsi (stack_pointer_rtx, hard_frame_pointer_rtx));
2075 save_restore_insns (0);
2077 if (crtl->calls_eh_return)
2079 rtx eh_ofs = EH_RETURN_STACKADJ_RTX;
2080 emit_insn (gen_addsi3 (eh_ofs, eh_ofs, tsize_rtx));
2084 emit_insn (gen_blockage ());
2086 if (tsize != 0 || crtl->calls_eh_return)
2088 emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx,
2093 if (crtl->calls_eh_return)
2095 /* Perform the additional bump for __throw. */
2096 emit_move_insn (gen_rtx_REG (Pmode, HARD_FRAME_POINTER_REGNUM),
2098 emit_use (gen_rtx_REG (Pmode, HARD_FRAME_POINTER_REGNUM));
2099 emit_jump_insn (gen_eh_return_internal ());
2102 emit_jump_insn (gen_return_internal (gen_rtx_REG (Pmode,
2103 GP_REG_FIRST + 31)));
2107 iq2000_expand_eh_return (rtx address)
2109 HOST_WIDE_INT gp_offset = cfun->machine->gp_sp_offset;
2112 scratch = plus_constant (stack_pointer_rtx, gp_offset);
2113 emit_move_insn (gen_rtx_MEM (GET_MODE (address), scratch), address);
2116 /* Return nonzero if this function is known to have a null epilogue.
2117 This allows the optimizer to omit jumps to jumps if no stack
2121 iq2000_can_use_return_insn (void)
2123 if (! reload_completed)
2126 if (df_regs_ever_live_p (31) || profile_flag)
2129 if (cfun->machine->initialized)
2130 return cfun->machine->total_size == 0;
2132 return compute_frame_size (get_frame_size ()) == 0;
2135 /* Returns nonzero if X contains a SYMBOL_REF. */
2138 symbolic_expression_p (rtx x)
2140 if (GET_CODE (x) == SYMBOL_REF)
2143 if (GET_CODE (x) == CONST)
2144 return symbolic_expression_p (XEXP (x, 0));
2147 return symbolic_expression_p (XEXP (x, 0));
2149 if (ARITHMETIC_P (x))
2150 return (symbolic_expression_p (XEXP (x, 0))
2151 || symbolic_expression_p (XEXP (x, 1)));
2156 /* Choose the section to use for the constant rtx expression X that has
2160 iq2000_select_rtx_section (enum machine_mode mode, rtx x ATTRIBUTE_UNUSED,
2161 unsigned HOST_WIDE_INT align)
2163 /* For embedded applications, always put constants in read-only data,
2164 in order to reduce RAM usage. */
2165 return mergeable_constant_section (mode, align, 0);
2168 /* Choose the section to use for DECL. RELOC is true if its value contains
2169 any relocatable expression.
2171 Some of the logic used here needs to be replicated in
2172 ENCODE_SECTION_INFO in iq2000.h so that references to these symbols
2173 are done correctly. */
2176 iq2000_select_section (tree decl, int reloc ATTRIBUTE_UNUSED,
2177 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED)
2179 if (TARGET_EMBEDDED_DATA)
2181 /* For embedded applications, always put an object in read-only data
2182 if possible, in order to reduce RAM usage. */
2183 if ((TREE_CODE (decl) == VAR_DECL
2184 && TREE_READONLY (decl) && !TREE_SIDE_EFFECTS (decl)
2185 && DECL_INITIAL (decl)
2186 && (DECL_INITIAL (decl) == error_mark_node
2187 || TREE_CONSTANT (DECL_INITIAL (decl))))
2188 /* Deal with calls from output_constant_def_contents. */
2189 || TREE_CODE (decl) != VAR_DECL)
2190 return readonly_data_section;
2192 return data_section;
2196 /* For hosted applications, always put an object in small data if
2197 possible, as this gives the best performance. */
2198 if ((TREE_CODE (decl) == VAR_DECL
2199 && TREE_READONLY (decl) && !TREE_SIDE_EFFECTS (decl)
2200 && DECL_INITIAL (decl)
2201 && (DECL_INITIAL (decl) == error_mark_node
2202 || TREE_CONSTANT (DECL_INITIAL (decl))))
2203 /* Deal with calls from output_constant_def_contents. */
2204 || TREE_CODE (decl) != VAR_DECL)
2205 return readonly_data_section;
2207 return data_section;
2210 /* Return register to use for a function return value with VALTYPE for function
2214 iq2000_function_value (const_tree valtype, const_tree func)
2216 int reg = GP_RETURN;
2217 enum machine_mode mode = TYPE_MODE (valtype);
2218 int unsignedp = TYPE_UNSIGNED (valtype);
2220 /* Since we promote return types, we must promote the mode here too. */
2221 mode = promote_function_mode (valtype, mode, &unsignedp, func, 1);
2223 return gen_rtx_REG (mode, reg);
2226 /* Return true when an argument must be passed by reference. */
2229 iq2000_pass_by_reference (CUMULATIVE_ARGS *cum, enum machine_mode mode,
2230 const_tree type, bool named ATTRIBUTE_UNUSED)
2234 /* We must pass by reference if we would be both passing in registers
2235 and the stack. This is because any subsequent partial arg would be
2236 handled incorrectly in this case. */
2237 if (cum && targetm.calls.must_pass_in_stack (mode, type))
2239 /* Don't pass the actual CUM to FUNCTION_ARG, because we would
2240 get double copies of any offsets generated for small structs
2241 passed in registers. */
2242 CUMULATIVE_ARGS temp;
2245 if (FUNCTION_ARG (temp, mode, type, named) != 0)
2249 if (type == NULL_TREE || mode == DImode || mode == DFmode)
2252 size = int_size_in_bytes (type);
2253 return size == -1 || size > UNITS_PER_WORD;
2256 /* Return the length of INSN. LENGTH is the initial length computed by
2257 attributes in the machine-description file. */
2260 iq2000_adjust_insn_length (rtx insn, int length)
2262 /* A unconditional jump has an unfilled delay slot if it is not part
2263 of a sequence. A conditional jump normally has a delay slot. */
2264 if (simplejump_p (insn)
2265 || ( (GET_CODE (insn) == JUMP_INSN
2266 || GET_CODE (insn) == CALL_INSN)))
2272 /* Output assembly instructions to perform a conditional branch.
2274 INSN is the branch instruction. OPERANDS[0] is the condition.
2275 OPERANDS[1] is the target of the branch. OPERANDS[2] is the target
2276 of the first operand to the condition. If TWO_OPERANDS_P is
2277 nonzero the comparison takes two operands; OPERANDS[3] will be the
2280 If INVERTED_P is nonzero we are to branch if the condition does
2281 not hold. If FLOAT_P is nonzero this is a floating-point comparison.
2283 LENGTH is the length (in bytes) of the sequence we are to generate.
2284 That tells us whether to generate a simple conditional branch, or a
2285 reversed conditional branch around a `jr' instruction. */
2288 iq2000_output_conditional_branch (rtx insn, rtx * operands, int two_operands_p,
2289 int float_p, int inverted_p, int length)
2291 static char buffer[200];
2292 /* The kind of comparison we are doing. */
2293 enum rtx_code code = GET_CODE (operands[0]);
2294 /* Nonzero if the opcode for the comparison needs a `z' indicating
2295 that it is a comparison against zero. */
2297 /* A string to use in the assembly output to represent the first
2299 const char *op1 = "%z2";
2300 /* A string to use in the assembly output to represent the second
2301 operand. Use the hard-wired zero register if there's no second
2303 const char *op2 = (two_operands_p ? ",%z3" : ",%.");
2304 /* The operand-printing string for the comparison. */
2305 const char *comp = (float_p ? "%F0" : "%C0");
2306 /* The operand-printing string for the inverted comparison. */
2307 const char *inverted_comp = (float_p ? "%W0" : "%N0");
2309 /* Likely variants of each branch instruction annul the instruction
2310 in the delay slot if the branch is not taken. */
2311 iq2000_branch_likely = (final_sequence && INSN_ANNULLED_BRANCH_P (insn));
2313 if (!two_operands_p)
2315 /* To compute whether than A > B, for example, we normally
2316 subtract B from A and then look at the sign bit. But, if we
2317 are doing an unsigned comparison, and B is zero, we don't
2318 have to do the subtraction. Instead, we can just check to
2319 see if A is nonzero. Thus, we change the CODE here to
2320 reflect the simpler comparison operation. */
2332 /* A condition which will always be true. */
2338 /* A condition which will always be false. */
2344 /* Not a special case. */
2349 /* Relative comparisons are always done against zero. But
2350 equality comparisons are done between two operands, and therefore
2351 do not require a `z' in the assembly language output. */
2352 need_z_p = (!float_p && code != EQ && code != NE);
2353 /* For comparisons against zero, the zero is not provided
2358 /* Begin by terminating the buffer. That way we can always use
2359 strcat to add to it. */
2366 /* Just a simple conditional branch. */
2368 sprintf (buffer, "b%s%%?\t%%Z2%%1",
2369 inverted_p ? inverted_comp : comp);
2371 sprintf (buffer, "b%s%s%%?\t%s%s,%%1",
2372 inverted_p ? inverted_comp : comp,
2373 need_z_p ? "z" : "",
2381 /* Generate a reversed conditional branch around ` j'
2393 Because we have to jump four bytes *past* the following
2394 instruction if this branch was annulled, we can't just use
2395 a label, as in the picture above; there's no way to put the
2396 label after the next instruction, as the assembler does not
2397 accept `.L+4' as the target of a branch. (We can't just
2398 wait until the next instruction is output; it might be a
2399 macro and take up more than four bytes. Once again, we see
2400 why we want to eliminate macros.)
2402 If the branch is annulled, we jump four more bytes that we
2403 would otherwise; that way we skip the annulled instruction
2404 in the delay slot. */
2407 = ((iq2000_branch_likely || length == 16) ? ".+16" : ".+12");
2410 c = strchr (buffer, '\0');
2411 /* Generate the reversed comparison. This takes four
2414 sprintf (c, "b%s\t%%Z2%s",
2415 inverted_p ? comp : inverted_comp,
2418 sprintf (c, "b%s%s\t%s%s,%s",
2419 inverted_p ? comp : inverted_comp,
2420 need_z_p ? "z" : "",
2424 strcat (c, "\n\tnop\n\tj\t%1");
2426 /* The delay slot was unfilled. Since we're inside
2427 .noreorder, the assembler will not fill in the NOP for
2428 us, so we must do it ourselves. */
2429 strcat (buffer, "\n\tnop");
2441 #define def_builtin(NAME, TYPE, CODE) \
2442 add_builtin_function ((NAME), (TYPE), (CODE), BUILT_IN_MD, \
2446 iq2000_init_builtins (void)
2448 tree endlink = void_list_node;
2449 tree void_ftype, void_ftype_int, void_ftype_int_int;
2450 tree void_ftype_int_int_int;
2451 tree int_ftype_int, int_ftype_int_int, int_ftype_int_int_int;
2452 tree int_ftype_int_int_int_int;
2456 = build_function_type (void_type_node,
2457 tree_cons (NULL_TREE, void_type_node, endlink));
2461 = build_function_type (void_type_node,
2462 tree_cons (NULL_TREE, integer_type_node, endlink));
2464 /* void func (int, int) */
2466 = build_function_type (void_type_node,
2467 tree_cons (NULL_TREE, integer_type_node,
2468 tree_cons (NULL_TREE, integer_type_node,
2471 /* int func (int) */
2473 = build_function_type (integer_type_node,
2474 tree_cons (NULL_TREE, integer_type_node, endlink));
2476 /* int func (int, int) */
2478 = build_function_type (integer_type_node,
2479 tree_cons (NULL_TREE, integer_type_node,
2480 tree_cons (NULL_TREE, integer_type_node,
2483 /* void func (int, int, int) */
2484 void_ftype_int_int_int
2485 = build_function_type
2487 tree_cons (NULL_TREE, integer_type_node,
2488 tree_cons (NULL_TREE, integer_type_node,
2489 tree_cons (NULL_TREE,
2493 /* int func (int, int, int, int) */
2494 int_ftype_int_int_int_int
2495 = build_function_type
2497 tree_cons (NULL_TREE, integer_type_node,
2498 tree_cons (NULL_TREE, integer_type_node,
2499 tree_cons (NULL_TREE,
2501 tree_cons (NULL_TREE,
2505 /* int func (int, int, int) */
2506 int_ftype_int_int_int
2507 = build_function_type
2509 tree_cons (NULL_TREE, integer_type_node,
2510 tree_cons (NULL_TREE, integer_type_node,
2511 tree_cons (NULL_TREE,
2515 /* int func (int, int, int, int) */
2516 int_ftype_int_int_int_int
2517 = build_function_type
2519 tree_cons (NULL_TREE, integer_type_node,
2520 tree_cons (NULL_TREE, integer_type_node,
2521 tree_cons (NULL_TREE,
2523 tree_cons (NULL_TREE,
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_expr (arg[i], NULL_RTX, VOIDmode, 0);
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 *cum,
2849 enum machine_mode mode ATTRIBUTE_UNUSED,
2850 tree type ATTRIBUTE_UNUSED, int * pretend_size,
2853 unsigned int iq2000_off = ! cum->last_arg_fp;
2854 unsigned int iq2000_fp_off = cum->last_arg_fp;
2856 if ((cum->arg_words < MAX_ARGS_IN_REGISTERS - iq2000_off))
2858 int iq2000_save_gp_regs
2859 = MAX_ARGS_IN_REGISTERS - cum->arg_words - iq2000_off;
2860 int iq2000_save_fp_regs
2861 = (MAX_ARGS_IN_REGISTERS - cum->fp_arg_words - iq2000_fp_off);
2863 if (iq2000_save_gp_regs < 0)
2864 iq2000_save_gp_regs = 0;
2865 if (iq2000_save_fp_regs < 0)
2866 iq2000_save_fp_regs = 0;
2868 *pretend_size = ((iq2000_save_gp_regs * UNITS_PER_WORD)
2869 + (iq2000_save_fp_regs * UNITS_PER_FPREG));
2873 if (cum->arg_words < MAX_ARGS_IN_REGISTERS - iq2000_off)
2876 ptr = plus_constant (virtual_incoming_args_rtx,
2877 - (iq2000_save_gp_regs
2879 mem = gen_rtx_MEM (BLKmode, ptr);
2881 (cum->arg_words + GP_ARG_FIRST + iq2000_off,
2883 iq2000_save_gp_regs);
2889 /* A C compound statement to output to stdio stream STREAM the
2890 assembler syntax for an instruction operand that is a memory
2891 reference whose address is ADDR. ADDR is an RTL expression. */
2894 print_operand_address (FILE * file, rtx addr)
2897 error ("PRINT_OPERAND_ADDRESS, null pointer");
2900 switch (GET_CODE (addr))
2903 if (REGNO (addr) == ARG_POINTER_REGNUM)
2904 abort_with_insn (addr, "Arg pointer not eliminated.");
2906 fprintf (file, "0(%s)", reg_names [REGNO (addr)]);
2911 rtx arg0 = XEXP (addr, 0);
2912 rtx arg1 = XEXP (addr, 1);
2914 if (GET_CODE (arg0) != REG)
2915 abort_with_insn (addr,
2916 "PRINT_OPERAND_ADDRESS, LO_SUM with #1 not REG.");
2918 fprintf (file, "%%lo(");
2919 print_operand_address (file, arg1);
2920 fprintf (file, ")(%s)", reg_names [REGNO (arg0)]);
2928 rtx arg0 = XEXP (addr, 0);
2929 rtx arg1 = XEXP (addr, 1);
2931 if (GET_CODE (arg0) == REG)
2935 if (GET_CODE (offset) == REG)
2936 abort_with_insn (addr, "PRINT_OPERAND_ADDRESS, 2 regs");
2939 else if (GET_CODE (arg1) == REG)
2940 reg = arg1, offset = arg0;
2941 else if (CONSTANT_P (arg0) && CONSTANT_P (arg1))
2943 output_addr_const (file, addr);
2947 abort_with_insn (addr, "PRINT_OPERAND_ADDRESS, no regs");
2949 if (! CONSTANT_P (offset))
2950 abort_with_insn (addr, "PRINT_OPERAND_ADDRESS, invalid insn #2");
2952 if (REGNO (reg) == ARG_POINTER_REGNUM)
2953 abort_with_insn (addr, "Arg pointer not eliminated.");
2955 output_addr_const (file, offset);
2956 fprintf (file, "(%s)", reg_names [REGNO (reg)]);
2964 output_addr_const (file, addr);
2965 if (GET_CODE (addr) == CONST_INT)
2966 fprintf (file, "(%s)", reg_names [0]);
2970 abort_with_insn (addr, "PRINT_OPERAND_ADDRESS, invalid insn #1");
2975 /* A C compound statement to output to stdio stream FILE the
2976 assembler syntax for an instruction operand OP.
2978 LETTER is a value that can be used to specify one of several ways
2979 of printing the operand. It is used when identical operands
2980 must be printed differently depending on the context. LETTER
2981 comes from the `%' specification that was used to request
2982 printing of the operand. If the specification was just `%DIGIT'
2983 then LETTER is 0; if the specification was `%LTR DIGIT' then LETTER
2984 is the ASCII code for LTR.
2986 If OP is a register, this macro should print the register's name.
2987 The names can be found in an array `reg_names' whose type is
2988 `char *[]'. `reg_names' is initialized from `REGISTER_NAMES'.
2990 When the machine description has a specification `%PUNCT' (a `%'
2991 followed by a punctuation character), this macro is called with
2992 a null pointer for X and the punctuation character for LETTER.
2994 The IQ2000 specific codes are:
2996 'X' X is CONST_INT, prints upper 16 bits in hexadecimal format = "0x%04x",
2997 'x' X is CONST_INT, prints lower 16 bits in hexadecimal format = "0x%04x",
2998 'd' output integer constant in decimal,
2999 'z' if the operand is 0, use $0 instead of normal operand.
3000 'D' print second part of double-word register or memory operand.
3001 'L' print low-order register of double-word register operand.
3002 'M' print high-order register of double-word register operand.
3003 'C' print part of opcode for a branch condition.
3004 'F' print part of opcode for a floating-point branch condition.
3005 'N' print part of opcode for a branch condition, inverted.
3006 'W' print part of opcode for a floating-point branch condition, inverted.
3007 'A' Print part of opcode for a bit test condition.
3008 'P' Print label for a bit test.
3009 'p' Print log for a bit test.
3010 'B' print 'z' for EQ, 'n' for NE
3011 'b' print 'n' for EQ, 'z' for NE
3012 'T' print 'f' for EQ, 't' for NE
3013 't' print 't' for EQ, 'f' for NE
3014 'Z' print register and a comma, but print nothing for $fcc0
3015 '?' Print 'l' if we are to use a branch likely instead of normal branch.
3016 '@' Print the name of the assembler temporary register (at or $1).
3017 '.' Print the name of the register with a hard-wired zero (zero or $0).
3018 '$' Print the name of the stack pointer register (sp or $29).
3019 '+' Print the name of the gp register (gp or $28). */
3022 print_operand (FILE *file, rtx op, int letter)
3026 if (PRINT_OPERAND_PUNCT_VALID_P (letter))
3031 if (iq2000_branch_likely)
3036 fputs (reg_names [GP_REG_FIRST + 1], file);
3040 fputs (reg_names [GP_REG_FIRST + 0], file);
3044 fputs (reg_names[STACK_POINTER_REGNUM], file);
3048 fputs (reg_names[GP_REG_FIRST + 28], file);
3052 error ("PRINT_OPERAND: Unknown punctuation '%c'", letter);
3061 error ("PRINT_OPERAND null pointer");
3065 code = GET_CODE (op);
3067 if (code == SIGN_EXTEND)
3068 op = XEXP (op, 0), code = GET_CODE (op);
3073 case EQ: fputs ("eq", file); break;
3074 case NE: fputs ("ne", file); break;
3075 case GT: fputs ("gt", file); break;
3076 case GE: fputs ("ge", file); break;
3077 case LT: fputs ("lt", file); break;
3078 case LE: fputs ("le", file); break;
3079 case GTU: fputs ("ne", file); break;
3080 case GEU: fputs ("geu", file); break;
3081 case LTU: fputs ("ltu", file); break;
3082 case LEU: fputs ("eq", file); break;
3084 abort_with_insn (op, "PRINT_OPERAND, invalid insn for %%C");
3087 else if (letter == 'N')
3090 case EQ: fputs ("ne", file); break;
3091 case NE: fputs ("eq", file); break;
3092 case GT: fputs ("le", file); break;
3093 case GE: fputs ("lt", file); break;
3094 case LT: fputs ("ge", file); break;
3095 case LE: fputs ("gt", file); break;
3096 case GTU: fputs ("leu", file); break;
3097 case GEU: fputs ("ltu", file); break;
3098 case LTU: fputs ("geu", file); break;
3099 case LEU: fputs ("gtu", file); break;
3101 abort_with_insn (op, "PRINT_OPERAND, invalid insn for %%N");
3104 else if (letter == 'F')
3107 case EQ: fputs ("c1f", file); break;
3108 case NE: fputs ("c1t", file); break;
3110 abort_with_insn (op, "PRINT_OPERAND, invalid insn for %%F");
3113 else if (letter == 'W')
3116 case EQ: fputs ("c1t", file); break;
3117 case NE: fputs ("c1f", file); break;
3119 abort_with_insn (op, "PRINT_OPERAND, invalid insn for %%W");
3122 else if (letter == 'A')
3123 fputs (code == LABEL_REF ? "i" : "in", file);
3125 else if (letter == 'P')
3127 if (code == LABEL_REF)
3128 output_addr_const (file, op);
3129 else if (code != PC)
3130 output_operand_lossage ("invalid %%P operand");
3133 else if (letter == 'p')
3136 if (code != CONST_INT
3137 || (value = exact_log2 (INTVAL (op))) < 0)
3138 output_operand_lossage ("invalid %%p value");
3139 fprintf (file, "%d", value);
3142 else if (letter == 'Z')
3147 else if (code == REG || code == SUBREG)
3152 regnum = REGNO (op);
3154 regnum = true_regnum (op);
3156 if ((letter == 'M' && ! WORDS_BIG_ENDIAN)
3157 || (letter == 'L' && WORDS_BIG_ENDIAN)
3161 fprintf (file, "%s", reg_names[regnum]);
3164 else if (code == MEM)
3167 output_address (plus_constant (XEXP (op, 0), 4));
3169 output_address (XEXP (op, 0));
3172 else if (code == CONST_DOUBLE
3173 && GET_MODE_CLASS (GET_MODE (op)) == MODE_FLOAT)
3177 real_to_decimal (s, CONST_DOUBLE_REAL_VALUE (op), sizeof (s), 0, 1);
3181 else if (letter == 'x' && GET_CODE (op) == CONST_INT)
3182 fprintf (file, HOST_WIDE_INT_PRINT_HEX, 0xffff & INTVAL(op));
3184 else if (letter == 'X' && GET_CODE(op) == CONST_INT)
3185 fprintf (file, HOST_WIDE_INT_PRINT_HEX, 0xffff & (INTVAL (op) >> 16));
3187 else if (letter == 'd' && GET_CODE(op) == CONST_INT)
3188 fprintf (file, HOST_WIDE_INT_PRINT_DEC, (INTVAL(op)));
3190 else if (letter == 'z' && GET_CODE (op) == CONST_INT && INTVAL (op) == 0)
3191 fputs (reg_names[GP_REG_FIRST], file);
3193 else if (letter == 'd' || letter == 'x' || letter == 'X')
3194 output_operand_lossage ("invalid use of %%d, %%x, or %%X");
3196 else if (letter == 'B')
3197 fputs (code == EQ ? "z" : "n", file);
3198 else if (letter == 'b')
3199 fputs (code == EQ ? "n" : "z", file);
3200 else if (letter == 'T')
3201 fputs (code == EQ ? "f" : "t", file);
3202 else if (letter == 't')
3203 fputs (code == EQ ? "t" : "f", file);
3205 else if (code == CONST && GET_CODE (XEXP (op, 0)) == REG)
3207 print_operand (file, XEXP (op, 0), letter);
3211 output_addr_const (file, op);
3215 /* For the IQ2000, transform:
3217 memory(X + <large int>)
3219 Y = <large int> & ~0x7fff;
3221 memory (Z + (<large int> & 0x7fff));
3225 iq2000_legitimize_address (rtx xinsn, rtx old_x ATTRIBUTE_UNUSED,
3226 enum machine_mode mode)
3228 if (TARGET_DEBUG_B_MODE)
3230 GO_PRINTF ("\n========== LEGITIMIZE_ADDRESS\n");
3231 GO_DEBUG_RTX (xinsn);
3234 if (iq2000_check_split (xinsn, mode))
3236 return gen_rtx_LO_SUM (Pmode,
3237 copy_to_mode_reg (Pmode,
3238 gen_rtx_HIGH (Pmode, xinsn)),
3242 if (GET_CODE (xinsn) == PLUS)
3244 rtx xplus0 = XEXP (xinsn, 0);
3245 rtx xplus1 = XEXP (xinsn, 1);
3246 enum rtx_code code0 = GET_CODE (xplus0);
3247 enum rtx_code code1 = GET_CODE (xplus1);
3249 if (code0 != REG && code1 == REG)
3251 xplus0 = XEXP (xinsn, 1);
3252 xplus1 = XEXP (xinsn, 0);
3253 code0 = GET_CODE (xplus0);
3254 code1 = GET_CODE (xplus1);
3257 if (code0 == REG && REG_MODE_OK_FOR_BASE_P (xplus0, mode)
3258 && code1 == CONST_INT && !SMALL_INT (xplus1))
3260 rtx int_reg = gen_reg_rtx (Pmode);
3261 rtx ptr_reg = gen_reg_rtx (Pmode);
3263 emit_move_insn (int_reg,
3264 GEN_INT (INTVAL (xplus1) & ~ 0x7fff));
3266 emit_insn (gen_rtx_SET (VOIDmode,
3268 gen_rtx_PLUS (Pmode, xplus0, int_reg)));
3270 return plus_constant (ptr_reg, INTVAL (xplus1) & 0x7fff);
3274 if (TARGET_DEBUG_B_MODE)
3275 GO_PRINTF ("LEGITIMIZE_ADDRESS could not fix.\n");
3282 iq2000_rtx_costs (rtx x, int code, int outer_code ATTRIBUTE_UNUSED, int * total,
3283 bool speed ATTRIBUTE_UNUSED)
3285 enum machine_mode mode = GET_MODE (x);
3291 int num_words = (GET_MODE_SIZE (mode) > UNITS_PER_WORD) ? 2 : 1;
3293 if (simple_memory_operand (x, mode))
3294 return COSTS_N_INSNS (num_words);
3296 * total = COSTS_N_INSNS (2 * num_words);
3301 * total = COSTS_N_INSNS (6);
3308 * total = COSTS_N_INSNS (mode == DImode ? 2 : 1);
3315 * total = COSTS_N_INSNS ((GET_CODE (XEXP (x, 1)) == CONST_INT) ? 4 : 12);
3317 * total = COSTS_N_INSNS (1);
3321 if (mode == SFmode || mode == DFmode)
3322 * total = COSTS_N_INSNS (1);
3324 * total = COSTS_N_INSNS (4);
3329 if (mode == SFmode || mode == DFmode)
3330 * total = COSTS_N_INSNS (6);
3331 else if (mode == DImode)
3332 * total = COSTS_N_INSNS (4);
3334 * total = COSTS_N_INSNS (1);
3338 * total = (mode == DImode) ? 4 : 1;
3343 * total = COSTS_N_INSNS (7);
3344 else if (mode == DFmode)
3345 * total = COSTS_N_INSNS (8);
3347 * total = COSTS_N_INSNS (10);
3353 * total = COSTS_N_INSNS (23);
3354 else if (mode == DFmode)
3355 * total = COSTS_N_INSNS (36);
3357 * total = COSTS_N_INSNS (69);
3362 * total = COSTS_N_INSNS (69);
3366 * total = COSTS_N_INSNS (2);
3370 * total = COSTS_N_INSNS (1);
3378 * total = COSTS_N_INSNS (2);
3383 rtx offset = const0_rtx;
3384 rtx symref = eliminate_constant_term (XEXP (x, 0), & offset);
3386 if (GET_CODE (symref) == LABEL_REF)
3387 * total = COSTS_N_INSNS (2);
3388 else if (GET_CODE (symref) != SYMBOL_REF)
3389 * total = COSTS_N_INSNS (4);
3390 /* Let's be paranoid.... */
3391 else if (INTVAL (offset) < -32768 || INTVAL (offset) > 32767)
3392 * total = COSTS_N_INSNS (2);
3394 * total = COSTS_N_INSNS (SYMBOL_REF_FLAG (symref) ? 1 : 2);
3399 * total = COSTS_N_INSNS (SYMBOL_REF_FLAG (x) ? 1 : 2);
3406 split_double (x, & high, & low);
3408 * total = COSTS_N_INSNS ( (high == CONST0_RTX (GET_MODE (high))
3409 || low == CONST0_RTX (GET_MODE (low)))
3420 /* Worker for TARGET_ASM_TRAMPOLINE_TEMPLATE. */
3423 iq2000_asm_trampoline_template (FILE *f)
3425 fprintf (f, "\t.word\t0x03e00821\t\t# move $1,$31\n");
3426 fprintf (f, "\t.word\t0x04110001\t\t# bgezal $0,.+8\n");
3427 fprintf (f, "\t.word\t0x00000000\t\t# nop\n");
3428 if (Pmode == DImode)
3430 fprintf (f, "\t.word\t0xdfe30014\t\t# ld $3,20($31)\n");
3431 fprintf (f, "\t.word\t0xdfe2001c\t\t# ld $2,28($31)\n");
3435 fprintf (f, "\t.word\t0x8fe30014\t\t# lw $3,20($31)\n");
3436 fprintf (f, "\t.word\t0x8fe20018\t\t# lw $2,24($31)\n");
3438 fprintf (f, "\t.word\t0x0060c821\t\t# move $25,$3 (abicalls)\n");
3439 fprintf (f, "\t.word\t0x00600008\t\t# jr $3\n");
3440 fprintf (f, "\t.word\t0x0020f821\t\t# move $31,$1\n");
3441 fprintf (f, "\t.word\t0x00000000\t\t# <function address>\n");
3442 fprintf (f, "\t.word\t0x00000000\t\t# <static chain value>\n");
3445 /* Worker for TARGET_TRAMPOLINE_INIT. */
3448 iq2000_trampoline_init (rtx m_tramp, tree fndecl, rtx chain_value)
3450 rtx fnaddr = XEXP (DECL_RTL (fndecl), 0);
3453 emit_block_move (m_tramp, assemble_trampoline_template (),
3454 GEN_INT (TRAMPOLINE_CODE_SIZE), BLOCK_OP_NORMAL);
3456 mem = adjust_address (m_tramp, Pmode, TRAMPOLINE_CODE_SIZE);
3457 emit_move_insn (mem, fnaddr);
3458 mem = adjust_address (m_tramp, Pmode,
3459 TRAMPOLINE_CODE_SIZE + GET_MODE_SIZE (Pmode));
3460 emit_move_insn (mem, chain_value);
3463 #include "gt-iq2000.h"