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
*,
152 enum machine_mode
, tree
, int *,
154 static bool iq2000_rtx_costs (rtx
, 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
*, enum machine_mode
,
160 static int iq2000_arg_partial_bytes (CUMULATIVE_ARGS
*, enum machine_mode
,
162 static rtx
iq2000_function_arg (CUMULATIVE_ARGS
*,
163 enum machine_mode
, const_tree
, bool);
164 static void iq2000_function_arg_advance (CUMULATIVE_ARGS
*,
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
*cum
, enum machine_mode mode
,
1133 const_tree type
, bool named
)
1135 if (TARGET_DEBUG_D_MODE
)
1138 "function_adv({gp reg found = %d, arg # = %2d, words = %2d}, %4s, ",
1139 cum
->gp_reg_found
, cum
->arg_number
, cum
->arg_words
,
1140 GET_MODE_NAME (mode
));
1141 fprintf (stderr
, "%p", CONST_CAST2 (void *, const_tree
, type
));
1142 fprintf (stderr
, ", %d )\n\n", named
);
1152 gcc_assert (GET_MODE_CLASS (mode
) == MODE_COMPLEX_INT
1153 || GET_MODE_CLASS (mode
) == MODE_COMPLEX_FLOAT
);
1155 cum
->gp_reg_found
= 1;
1156 cum
->arg_words
+= ((GET_MODE_SIZE (mode
) + UNITS_PER_WORD
- 1)
1161 cum
->gp_reg_found
= 1;
1162 cum
->arg_words
+= ((int_size_in_bytes (type
) + UNITS_PER_WORD
- 1)
1168 if (! cum
->gp_reg_found
&& cum
->arg_number
<= 2)
1169 cum
->fp_code
+= 1 << ((cum
->arg_number
- 1) * 2);
1173 cum
->arg_words
+= 2;
1174 if (! cum
->gp_reg_found
&& cum
->arg_number
<= 2)
1175 cum
->fp_code
+= 2 << ((cum
->arg_number
- 1) * 2);
1179 cum
->gp_reg_found
= 1;
1180 cum
->arg_words
+= 2;
1184 cum
->gp_reg_found
= 1;
1185 cum
->arg_words
+= 4;
1191 cum
->gp_reg_found
= 1;
1197 /* Return an RTL expression containing the register for the given mode MODE
1198 and type TYPE in CUM, or 0 if the argument is to be passed on the stack. */
1201 iq2000_function_arg (CUMULATIVE_ARGS
*cum
, enum machine_mode mode
,
1202 const_tree type
, bool named
)
1207 unsigned int *arg_words
= &cum
->arg_words
;
1208 int struct_p
= (type
!= 0
1209 && (TREE_CODE (type
) == RECORD_TYPE
1210 || TREE_CODE (type
) == UNION_TYPE
1211 || TREE_CODE (type
) == QUAL_UNION_TYPE
));
1213 if (TARGET_DEBUG_D_MODE
)
1216 "function_arg( {gp reg found = %d, arg # = %2d, words = %2d}, %4s, ",
1217 cum
->gp_reg_found
, cum
->arg_number
, cum
->arg_words
,
1218 GET_MODE_NAME (mode
));
1219 fprintf (stderr
, "%p", (const void *) type
);
1220 fprintf (stderr
, ", %d ) = ", named
);
1224 cum
->last_arg_fp
= 0;
1228 regbase
= GP_ARG_FIRST
;
1232 cum
->arg_words
+= cum
->arg_words
& 1;
1234 regbase
= GP_ARG_FIRST
;
1238 gcc_assert (GET_MODE_CLASS (mode
) == MODE_COMPLEX_INT
1239 || GET_MODE_CLASS (mode
) == MODE_COMPLEX_FLOAT
);
1241 /* Drops through. */
1243 if (type
!= NULL_TREE
&& TYPE_ALIGN (type
) > (unsigned) BITS_PER_WORD
)
1244 cum
->arg_words
+= (cum
->arg_words
& 1);
1245 regbase
= GP_ARG_FIRST
;
1252 regbase
= GP_ARG_FIRST
;
1256 cum
->arg_words
+= (cum
->arg_words
& 1);
1257 regbase
= GP_ARG_FIRST
;
1261 cum
->arg_words
+= (cum
->arg_words
& 3);
1262 regbase
= GP_ARG_FIRST
;
1266 if (*arg_words
>= (unsigned) MAX_ARGS_IN_REGISTERS
)
1268 if (TARGET_DEBUG_D_MODE
)
1269 fprintf (stderr
, "<stack>%s\n", struct_p
? ", [struct]" : "");
1275 gcc_assert (regbase
!= -1);
1277 if (! type
|| TREE_CODE (type
) != RECORD_TYPE
1278 || ! named
|| ! TYPE_SIZE_UNIT (type
)
1279 || ! host_integerp (TYPE_SIZE_UNIT (type
), 1))
1280 ret
= gen_rtx_REG (mode
, regbase
+ *arg_words
+ bias
);
1285 for (field
= TYPE_FIELDS (type
); field
; field
= DECL_CHAIN (field
))
1286 if (TREE_CODE (field
) == FIELD_DECL
1287 && TREE_CODE (TREE_TYPE (field
)) == REAL_TYPE
1288 && TYPE_PRECISION (TREE_TYPE (field
)) == BITS_PER_WORD
1289 && host_integerp (bit_position (field
), 0)
1290 && int_bit_position (field
) % BITS_PER_WORD
== 0)
1293 /* If the whole struct fits a DFmode register,
1294 we don't need the PARALLEL. */
1295 if (! field
|| mode
== DFmode
)
1296 ret
= gen_rtx_REG (mode
, regbase
+ *arg_words
+ bias
);
1299 unsigned int chunks
;
1300 HOST_WIDE_INT bitpos
;
1304 /* ??? If this is a packed structure, then the last hunk won't
1307 = tree_low_cst (TYPE_SIZE_UNIT (type
), 1) / UNITS_PER_WORD
;
1308 if (chunks
+ *arg_words
+ bias
> (unsigned) MAX_ARGS_IN_REGISTERS
)
1309 chunks
= MAX_ARGS_IN_REGISTERS
- *arg_words
- bias
;
1311 /* Assign_parms checks the mode of ENTRY_PARM, so we must
1312 use the actual mode here. */
1313 ret
= gen_rtx_PARALLEL (mode
, rtvec_alloc (chunks
));
1316 regno
= regbase
+ *arg_words
+ bias
;
1317 field
= TYPE_FIELDS (type
);
1318 for (i
= 0; i
< chunks
; i
++)
1322 for (; field
; field
= DECL_CHAIN (field
))
1323 if (TREE_CODE (field
) == FIELD_DECL
1324 && int_bit_position (field
) >= bitpos
)
1328 && int_bit_position (field
) == bitpos
1329 && TREE_CODE (TREE_TYPE (field
)) == REAL_TYPE
1330 && TYPE_PRECISION (TREE_TYPE (field
)) == BITS_PER_WORD
)
1331 reg
= gen_rtx_REG (DFmode
, regno
++);
1333 reg
= gen_rtx_REG (word_mode
, regno
);
1336 = gen_rtx_EXPR_LIST (VOIDmode
, reg
,
1337 GEN_INT (bitpos
/ BITS_PER_UNIT
));
1345 if (TARGET_DEBUG_D_MODE
)
1346 fprintf (stderr
, "%s%s\n", reg_names
[regbase
+ *arg_words
+ bias
],
1347 struct_p
? ", [struct]" : "");
1350 /* We will be called with a mode of VOIDmode after the last argument
1351 has been seen. Whatever we return will be passed to the call
1352 insn. If we need any shifts for small structures, return them in
1354 if (mode
== VOIDmode
)
1356 if (cum
->num_adjusts
> 0)
1357 ret
= gen_rtx_PARALLEL ((enum machine_mode
) cum
->fp_code
,
1358 gen_rtvec_v (cum
->num_adjusts
, cum
->adjust
));
1365 iq2000_function_arg_boundary (enum machine_mode mode
, const_tree type
)
1367 return (type
!= NULL_TREE
1368 ? (TYPE_ALIGN (type
) <= PARM_BOUNDARY
1370 : TYPE_ALIGN (type
))
1371 : (GET_MODE_ALIGNMENT (mode
) <= PARM_BOUNDARY
1373 : GET_MODE_ALIGNMENT (mode
)));
1377 iq2000_arg_partial_bytes (CUMULATIVE_ARGS
*cum
, enum machine_mode mode
,
1378 tree type ATTRIBUTE_UNUSED
,
1379 bool named ATTRIBUTE_UNUSED
)
1381 if (mode
== DImode
&& cum
->arg_words
== MAX_ARGS_IN_REGISTERS
- 1)
1383 if (TARGET_DEBUG_D_MODE
)
1384 fprintf (stderr
, "iq2000_arg_partial_bytes=%d\n", UNITS_PER_WORD
);
1385 return UNITS_PER_WORD
;
1391 /* Implement va_start. */
1394 iq2000_va_start (tree valist
, rtx nextarg
)
1397 /* Find out how many non-float named formals. */
1398 int gpr_save_area_size
;
1399 /* Note UNITS_PER_WORD is 4 bytes. */
1400 int_arg_words
= crtl
->args
.info
.arg_words
;
1402 if (int_arg_words
< 8 )
1403 /* Adjust for the prologue's economy measure. */
1404 gpr_save_area_size
= (8 - int_arg_words
) * UNITS_PER_WORD
;
1406 gpr_save_area_size
= 0;
1408 /* Everything is in the GPR save area, or in the overflow
1409 area which is contiguous with it. */
1410 nextarg
= plus_constant (nextarg
, - gpr_save_area_size
);
1411 std_expand_builtin_va_start (valist
, nextarg
);
1414 /* Allocate a chunk of memory for per-function machine-dependent data. */
1416 static struct machine_function
*
1417 iq2000_init_machine_status (void)
1419 return ggc_alloc_cleared_machine_function ();
1422 /* Detect any conflicts in the switches. */
1425 iq2000_option_override (void)
1427 target_flags
&= ~MASK_GPOPT
;
1429 iq2000_isa
= IQ2000_ISA_DEFAULT
;
1431 /* Identify the processor type. */
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;
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;
1453 /* Save GPR registers in word_mode sized hunks. word_mode hasn't been
1454 initialized yet, so we can't use that here. */
1457 /* Function to allocate machine-dependent function status. */
1458 init_machine_status
= iq2000_init_machine_status
;
1461 /* The arg pointer (which is eliminated) points to the virtual frame pointer,
1462 while the frame pointer (which may be eliminated) points to the stack
1463 pointer after the initial adjustments. */
1466 iq2000_debugger_offset (rtx addr
, HOST_WIDE_INT offset
)
1468 rtx offset2
= const0_rtx
;
1469 rtx reg
= eliminate_constant_term (addr
, & offset2
);
1472 offset
= INTVAL (offset2
);
1474 if (reg
== stack_pointer_rtx
|| reg
== frame_pointer_rtx
1475 || reg
== hard_frame_pointer_rtx
)
1477 HOST_WIDE_INT frame_size
= (!cfun
->machine
->initialized
)
1478 ? compute_frame_size (get_frame_size ())
1479 : cfun
->machine
->total_size
;
1481 offset
= offset
- frame_size
;
1487 /* If defined, a C statement to be executed just prior to the output of
1488 assembler code for INSN, to modify the extracted operands so they will be
1491 Here the argument OPVEC is the vector containing the operands extracted
1492 from INSN, and NOPERANDS is the number of elements of the vector which
1493 contain meaningful data for this insn. The contents of this vector are
1494 what will be used to convert the insn template into assembler code, so you
1495 can change the assembler output by changing the contents of the vector.
1497 We use it to check if the current insn needs a nop in front of it because
1498 of load delays, and also to update the delay slot statistics. */
1501 final_prescan_insn (rtx insn
, rtx opvec
[] ATTRIBUTE_UNUSED
,
1502 int noperands ATTRIBUTE_UNUSED
)
1504 if (dslots_number_nops
> 0)
1506 rtx pattern
= PATTERN (insn
);
1507 int length
= get_attr_length (insn
);
1509 /* Do we need to emit a NOP? */
1511 || (iq2000_load_reg
!= 0 && reg_mentioned_p (iq2000_load_reg
, pattern
))
1512 || (iq2000_load_reg2
!= 0 && reg_mentioned_p (iq2000_load_reg2
, pattern
))
1513 || (iq2000_load_reg3
!= 0 && reg_mentioned_p (iq2000_load_reg3
, pattern
))
1514 || (iq2000_load_reg4
!= 0
1515 && reg_mentioned_p (iq2000_load_reg4
, pattern
)))
1516 fputs ("\tnop\n", asm_out_file
);
1519 dslots_load_filled
++;
1521 while (--dslots_number_nops
> 0)
1522 fputs ("\tnop\n", asm_out_file
);
1524 iq2000_load_reg
= 0;
1525 iq2000_load_reg2
= 0;
1526 iq2000_load_reg3
= 0;
1527 iq2000_load_reg4
= 0;
1530 if ( (GET_CODE (insn
) == JUMP_INSN
1531 || GET_CODE (insn
) == CALL_INSN
1532 || (GET_CODE (PATTERN (insn
)) == RETURN
))
1533 && NEXT_INSN (PREV_INSN (insn
)) == insn
)
1535 rtx nop_insn
= emit_insn_after (gen_nop (), insn
);
1537 INSN_ADDRESSES_NEW (nop_insn
, -1);
1541 && (GET_CODE (insn
) == JUMP_INSN
|| GET_CODE (insn
) == CALL_INSN
))
1542 dslots_jump_total
++;
1545 /* Return the bytes needed to compute the frame pointer from the current
1546 stack pointer where SIZE is the # of var. bytes allocated.
1548 IQ2000 stack frames look like:
1550 Before call After call
1551 +-----------------------+ +-----------------------+
1554 | caller's temps. | | caller's temps. |
1556 +-----------------------+ +-----------------------+
1558 | arguments on stack. | | arguments on stack. |
1560 +-----------------------+ +-----------------------+
1561 | 4 words to save | | 4 words to save |
1562 | arguments passed | | arguments passed |
1563 | in registers, even | | in registers, even |
1564 SP->| if not passed. | VFP->| if not passed. |
1565 +-----------------------+ +-----------------------+
1567 | fp register save |
1569 +-----------------------+
1571 | gp register save |
1573 +-----------------------+
1577 +-----------------------+
1579 | alloca allocations |
1581 +-----------------------+
1583 | GP save for V.4 abi |
1585 +-----------------------+
1587 | arguments on stack |
1589 +-----------------------+
1591 | arguments passed |
1592 | in registers, even |
1593 low SP->| if not passed. |
1594 memory +-----------------------+ */
1597 compute_frame_size (HOST_WIDE_INT size
)
1600 HOST_WIDE_INT total_size
; /* # bytes that the entire frame takes up. */
1601 HOST_WIDE_INT var_size
; /* # bytes that variables take up. */
1602 HOST_WIDE_INT args_size
; /* # bytes that outgoing arguments take up. */
1603 HOST_WIDE_INT extra_size
; /* # extra bytes. */
1604 HOST_WIDE_INT gp_reg_rounded
; /* # bytes needed to store gp after rounding. */
1605 HOST_WIDE_INT gp_reg_size
; /* # bytes needed to store gp regs. */
1606 HOST_WIDE_INT fp_reg_size
; /* # bytes needed to store fp regs. */
1607 long mask
; /* mask of saved gp registers. */
1612 extra_size
= IQ2000_STACK_ALIGN ((0));
1613 var_size
= IQ2000_STACK_ALIGN (size
);
1614 args_size
= IQ2000_STACK_ALIGN (crtl
->outgoing_args_size
);
1616 /* If a function dynamically allocates the stack and
1617 has 0 for STACK_DYNAMIC_OFFSET then allocate some stack space. */
1618 if (args_size
== 0 && cfun
->calls_alloca
)
1619 args_size
= 4 * UNITS_PER_WORD
;
1621 total_size
= var_size
+ args_size
+ extra_size
;
1623 /* Calculate space needed for gp registers. */
1624 for (regno
= GP_REG_FIRST
; regno
<= GP_REG_LAST
; regno
++)
1626 if (MUST_SAVE_REGISTER (regno
))
1628 gp_reg_size
+= GET_MODE_SIZE (gpr_mode
);
1629 mask
|= 1L << (regno
- GP_REG_FIRST
);
1633 /* We need to restore these for the handler. */
1634 if (crtl
->calls_eh_return
)
1640 regno
= EH_RETURN_DATA_REGNO (i
);
1641 if (regno
== (int) INVALID_REGNUM
)
1643 gp_reg_size
+= GET_MODE_SIZE (gpr_mode
);
1644 mask
|= 1L << (regno
- GP_REG_FIRST
);
1648 gp_reg_rounded
= IQ2000_STACK_ALIGN (gp_reg_size
);
1649 total_size
+= gp_reg_rounded
+ IQ2000_STACK_ALIGN (fp_reg_size
);
1651 /* The gp reg is caller saved, so there is no need for leaf routines
1652 (total_size == extra_size) to save the gp reg. */
1653 if (total_size
== extra_size
1655 total_size
= extra_size
= 0;
1657 total_size
+= IQ2000_STACK_ALIGN (crtl
->args
.pretend_args_size
);
1659 /* Save other computed information. */
1660 cfun
->machine
->total_size
= total_size
;
1661 cfun
->machine
->var_size
= var_size
;
1662 cfun
->machine
->args_size
= args_size
;
1663 cfun
->machine
->extra_size
= extra_size
;
1664 cfun
->machine
->gp_reg_size
= gp_reg_size
;
1665 cfun
->machine
->fp_reg_size
= fp_reg_size
;
1666 cfun
->machine
->mask
= mask
;
1667 cfun
->machine
->initialized
= reload_completed
;
1668 cfun
->machine
->num_gp
= gp_reg_size
/ UNITS_PER_WORD
;
1672 unsigned long offset
;
1674 offset
= (args_size
+ extra_size
+ var_size
1675 + gp_reg_size
- GET_MODE_SIZE (gpr_mode
));
1677 cfun
->machine
->gp_sp_offset
= offset
;
1678 cfun
->machine
->gp_save_offset
= offset
- total_size
;
1682 cfun
->machine
->gp_sp_offset
= 0;
1683 cfun
->machine
->gp_save_offset
= 0;
1686 cfun
->machine
->fp_sp_offset
= 0;
1687 cfun
->machine
->fp_save_offset
= 0;
1689 /* Ok, we're done. */
1694 /* We can always eliminate to the frame pointer. We can eliminate to the
1695 stack pointer unless a frame pointer is needed. */
1698 iq2000_can_eliminate (const int from
, const int to
)
1700 return (from
== RETURN_ADDRESS_POINTER_REGNUM
1701 && (! leaf_function_p ()
1702 || (to
== GP_REG_FIRST
+ 31 && leaf_function_p ())))
1703 || (from
!= RETURN_ADDRESS_POINTER_REGNUM
1704 && (to
== HARD_FRAME_POINTER_REGNUM
1705 || (to
== STACK_POINTER_REGNUM
1706 && ! frame_pointer_needed
)));
1709 /* Implement INITIAL_ELIMINATION_OFFSET. FROM is either the frame
1710 pointer, argument pointer, or return address pointer. TO is either
1711 the stack pointer or hard frame pointer. */
1714 iq2000_initial_elimination_offset (int from
, int to ATTRIBUTE_UNUSED
)
1718 compute_frame_size (get_frame_size ());
1719 if ((from
) == FRAME_POINTER_REGNUM
)
1721 else if ((from
) == ARG_POINTER_REGNUM
)
1722 (offset
) = (cfun
->machine
->total_size
);
1723 else if ((from
) == RETURN_ADDRESS_POINTER_REGNUM
)
1725 if (leaf_function_p ())
1727 else (offset
) = cfun
->machine
->gp_sp_offset
1728 + ((UNITS_PER_WORD
- (POINTER_SIZE
/ BITS_PER_UNIT
))
1729 * (BYTES_BIG_ENDIAN
!= 0));
1737 /* Common code to emit the insns (or to write the instructions to a file)
1738 to save/restore registers.
1739 Other parts of the code assume that IQ2000_TEMP1_REGNUM (aka large_reg)
1740 is not modified within save_restore_insns. */
1742 #define BITSET_P(VALUE,BIT) (((VALUE) & (1L << (BIT))) != 0)
1744 /* Emit instructions to load the value (SP + OFFSET) into IQ2000_TEMP2_REGNUM
1745 and return an rtl expression for the register. Write the assembly
1746 instructions directly to FILE if it is not null, otherwise emit them as
1749 This function is a subroutine of save_restore_insns. It is used when
1750 OFFSET is too large to add in a single instruction. */
1753 iq2000_add_large_offset_to_sp (HOST_WIDE_INT offset
)
1755 rtx reg
= gen_rtx_REG (Pmode
, IQ2000_TEMP2_REGNUM
);
1756 rtx offset_rtx
= GEN_INT (offset
);
1758 emit_move_insn (reg
, offset_rtx
);
1759 emit_insn (gen_addsi3 (reg
, reg
, stack_pointer_rtx
));
1763 /* Make INSN frame related and note that it performs the frame-related
1764 operation DWARF_PATTERN. */
1767 iq2000_annotate_frame_insn (rtx insn
, rtx dwarf_pattern
)
1769 RTX_FRAME_RELATED_P (insn
) = 1;
1770 REG_NOTES (insn
) = alloc_EXPR_LIST (REG_FRAME_RELATED_EXPR
,
1775 /* Emit a move instruction that stores REG in MEM. Make the instruction
1776 frame related and note that it stores REG at (SP + OFFSET). */
1779 iq2000_emit_frame_related_store (rtx mem
, rtx reg
, HOST_WIDE_INT offset
)
1781 rtx dwarf_address
= plus_constant (stack_pointer_rtx
, offset
);
1782 rtx dwarf_mem
= gen_rtx_MEM (GET_MODE (reg
), dwarf_address
);
1784 iq2000_annotate_frame_insn (emit_move_insn (mem
, reg
),
1785 gen_rtx_SET (GET_MODE (reg
), dwarf_mem
, reg
));
1788 /* Emit instructions to save/restore registers, as determined by STORE_P. */
1791 save_restore_insns (int store_p
)
1793 long mask
= cfun
->machine
->mask
;
1796 HOST_WIDE_INT base_offset
;
1797 HOST_WIDE_INT gp_offset
;
1798 HOST_WIDE_INT end_offset
;
1800 gcc_assert (!frame_pointer_needed
1801 || BITSET_P (mask
, HARD_FRAME_POINTER_REGNUM
- GP_REG_FIRST
));
1805 base_reg_rtx
= 0, base_offset
= 0;
1809 /* Save registers starting from high to low. The debuggers prefer at least
1810 the return register be stored at func+4, and also it allows us not to
1811 need a nop in the epilog if at least one register is reloaded in
1812 addition to return address. */
1814 /* Save GP registers if needed. */
1815 /* Pick which pointer to use as a base register. For small frames, just
1816 use the stack pointer. Otherwise, use a temporary register. Save 2
1817 cycles if the save area is near the end of a large frame, by reusing
1818 the constant created in the prologue/epilogue to adjust the stack
1821 gp_offset
= cfun
->machine
->gp_sp_offset
;
1823 = gp_offset
- (cfun
->machine
->gp_reg_size
1824 - GET_MODE_SIZE (gpr_mode
));
1826 if (gp_offset
< 0 || end_offset
< 0)
1828 ("gp_offset (%ld) or end_offset (%ld) is less than zero",
1829 (long) gp_offset
, (long) end_offset
);
1831 else if (gp_offset
< 32768)
1832 base_reg_rtx
= stack_pointer_rtx
, base_offset
= 0;
1836 int reg_save_count
= 0;
1838 for (regno
= GP_REG_LAST
; regno
>= GP_REG_FIRST
; regno
--)
1839 if (BITSET_P (mask
, regno
- GP_REG_FIRST
)) reg_save_count
+= 1;
1840 base_offset
= gp_offset
- ((reg_save_count
- 1) * 4);
1841 base_reg_rtx
= iq2000_add_large_offset_to_sp (base_offset
);
1844 for (regno
= GP_REG_LAST
; regno
>= GP_REG_FIRST
; regno
--)
1846 if (BITSET_P (mask
, regno
- GP_REG_FIRST
))
1850 = gen_rtx_MEM (gpr_mode
,
1851 gen_rtx_PLUS (Pmode
, base_reg_rtx
,
1852 GEN_INT (gp_offset
- base_offset
)));
1854 reg_rtx
= gen_rtx_REG (gpr_mode
, regno
);
1857 iq2000_emit_frame_related_store (mem_rtx
, reg_rtx
, gp_offset
);
1860 emit_move_insn (reg_rtx
, mem_rtx
);
1862 gp_offset
-= GET_MODE_SIZE (gpr_mode
);
1867 /* Expand the prologue into a bunch of separate insns. */
1870 iq2000_expand_prologue (void)
1873 HOST_WIDE_INT tsize
;
1874 int last_arg_is_vararg_marker
= 0;
1875 tree fndecl
= current_function_decl
;
1876 tree fntype
= TREE_TYPE (fndecl
);
1877 tree fnargs
= DECL_ARGUMENTS (fndecl
);
1882 CUMULATIVE_ARGS args_so_far
;
1883 int store_args_on_stack
= (iq2000_can_use_return_insn ());
1885 /* If struct value address is treated as the first argument. */
1886 if (aggregate_value_p (DECL_RESULT (fndecl
), fndecl
)
1887 && !cfun
->returns_pcc_struct
1888 && targetm
.calls
.struct_value_rtx (TREE_TYPE (fndecl
), 1) == 0)
1890 tree type
= build_pointer_type (fntype
);
1891 tree function_result_decl
= build_decl (BUILTINS_LOCATION
,
1892 PARM_DECL
, NULL_TREE
, type
);
1894 DECL_ARG_TYPE (function_result_decl
) = type
;
1895 DECL_CHAIN (function_result_decl
) = fnargs
;
1896 fnargs
= function_result_decl
;
1899 /* For arguments passed in registers, find the register number
1900 of the first argument in the variable part of the argument list,
1901 otherwise GP_ARG_LAST+1. Note also if the last argument is
1902 the varargs special argument, and treat it as part of the
1905 This is only needed if store_args_on_stack is true. */
1906 INIT_CUMULATIVE_ARGS (args_so_far
, fntype
, NULL_RTX
, 0, 0);
1907 regno
= GP_ARG_FIRST
;
1909 for (cur_arg
= fnargs
; cur_arg
!= 0; cur_arg
= next_arg
)
1911 tree passed_type
= DECL_ARG_TYPE (cur_arg
);
1912 enum machine_mode passed_mode
= TYPE_MODE (passed_type
);
1915 if (TREE_ADDRESSABLE (passed_type
))
1917 passed_type
= build_pointer_type (passed_type
);
1918 passed_mode
= Pmode
;
1921 entry_parm
= iq2000_function_arg (&args_so_far
, passed_mode
,
1924 iq2000_function_arg_advance (&args_so_far
, passed_mode
,
1926 next_arg
= DECL_CHAIN (cur_arg
);
1928 if (entry_parm
&& store_args_on_stack
)
1931 && DECL_NAME (cur_arg
)
1932 && ((0 == strcmp (IDENTIFIER_POINTER (DECL_NAME (cur_arg
)),
1933 "__builtin_va_alist"))
1934 || (0 == strcmp (IDENTIFIER_POINTER (DECL_NAME (cur_arg
)),
1937 last_arg_is_vararg_marker
= 1;
1944 gcc_assert (GET_CODE (entry_parm
) == REG
);
1946 /* Passed in a register, so will get homed automatically. */
1947 if (GET_MODE (entry_parm
) == BLKmode
)
1948 words
= (int_size_in_bytes (passed_type
) + 3) / 4;
1950 words
= (GET_MODE_SIZE (GET_MODE (entry_parm
)) + 3) / 4;
1952 regno
= REGNO (entry_parm
) + words
- 1;
1957 regno
= GP_ARG_LAST
+1;
1962 /* In order to pass small structures by value in registers we need to
1963 shift the value into the high part of the register.
1964 iq2000_unction_arg has encoded a PARALLEL rtx, holding a vector of
1965 adjustments to be made as the next_arg_reg variable, so we split up
1966 the insns, and emit them separately. */
1967 next_arg_reg
= iq2000_function_arg (&args_so_far
, VOIDmode
,
1968 void_type_node
, true);
1969 if (next_arg_reg
!= 0 && GET_CODE (next_arg_reg
) == PARALLEL
)
1971 rtvec adjust
= XVEC (next_arg_reg
, 0);
1972 int num
= GET_NUM_ELEM (adjust
);
1974 for (i
= 0; i
< num
; i
++)
1978 pattern
= RTVEC_ELT (adjust
, i
);
1979 if (GET_CODE (pattern
) != SET
1980 || GET_CODE (SET_SRC (pattern
)) != ASHIFT
)
1981 abort_with_insn (pattern
, "Insn is not a shift");
1982 PUT_CODE (SET_SRC (pattern
), ASHIFTRT
);
1984 emit_insn (pattern
);
1988 tsize
= compute_frame_size (get_frame_size ());
1990 /* If this function is a varargs function, store any registers that
1991 would normally hold arguments ($4 - $7) on the stack. */
1992 if (store_args_on_stack
1993 && (stdarg_p (fntype
)
1994 || last_arg_is_vararg_marker
))
1996 int offset
= (regno
- GP_ARG_FIRST
) * UNITS_PER_WORD
;
1997 rtx ptr
= stack_pointer_rtx
;
1999 for (; regno
<= GP_ARG_LAST
; regno
++)
2002 ptr
= gen_rtx_PLUS (Pmode
, stack_pointer_rtx
, GEN_INT (offset
));
2003 emit_move_insn (gen_rtx_MEM (gpr_mode
, ptr
),
2004 gen_rtx_REG (gpr_mode
, regno
));
2006 offset
+= GET_MODE_SIZE (gpr_mode
);
2012 rtx tsize_rtx
= GEN_INT (tsize
);
2013 rtx adjustment_rtx
, insn
, dwarf_pattern
;
2017 adjustment_rtx
= gen_rtx_REG (Pmode
, IQ2000_TEMP1_REGNUM
);
2018 emit_move_insn (adjustment_rtx
, tsize_rtx
);
2021 adjustment_rtx
= tsize_rtx
;
2023 insn
= emit_insn (gen_subsi3 (stack_pointer_rtx
, stack_pointer_rtx
,
2026 dwarf_pattern
= gen_rtx_SET (Pmode
, stack_pointer_rtx
,
2027 plus_constant (stack_pointer_rtx
, -tsize
));
2029 iq2000_annotate_frame_insn (insn
, dwarf_pattern
);
2031 save_restore_insns (1);
2033 if (frame_pointer_needed
)
2037 insn
= emit_insn (gen_movsi (hard_frame_pointer_rtx
,
2038 stack_pointer_rtx
));
2041 RTX_FRAME_RELATED_P (insn
) = 1;
2045 emit_insn (gen_blockage ());
2048 /* Expand the epilogue into a bunch of separate insns. */
2051 iq2000_expand_epilogue (void)
2053 HOST_WIDE_INT tsize
= cfun
->machine
->total_size
;
2054 rtx tsize_rtx
= GEN_INT (tsize
);
2055 rtx tmp_rtx
= (rtx
)0;
2057 if (iq2000_can_use_return_insn ())
2059 emit_jump_insn (gen_return ());
2065 tmp_rtx
= gen_rtx_REG (Pmode
, IQ2000_TEMP1_REGNUM
);
2066 emit_move_insn (tmp_rtx
, tsize_rtx
);
2067 tsize_rtx
= tmp_rtx
;
2072 if (frame_pointer_needed
)
2074 emit_insn (gen_blockage ());
2076 emit_insn (gen_movsi (stack_pointer_rtx
, hard_frame_pointer_rtx
));
2079 save_restore_insns (0);
2081 if (crtl
->calls_eh_return
)
2083 rtx eh_ofs
= EH_RETURN_STACKADJ_RTX
;
2084 emit_insn (gen_addsi3 (eh_ofs
, eh_ofs
, tsize_rtx
));
2088 emit_insn (gen_blockage ());
2090 if (tsize
!= 0 || crtl
->calls_eh_return
)
2092 emit_insn (gen_addsi3 (stack_pointer_rtx
, stack_pointer_rtx
,
2097 if (crtl
->calls_eh_return
)
2099 /* Perform the additional bump for __throw. */
2100 emit_move_insn (gen_rtx_REG (Pmode
, HARD_FRAME_POINTER_REGNUM
),
2102 emit_use (gen_rtx_REG (Pmode
, HARD_FRAME_POINTER_REGNUM
));
2103 emit_jump_insn (gen_eh_return_internal ());
2106 emit_jump_insn (gen_return_internal (gen_rtx_REG (Pmode
,
2107 GP_REG_FIRST
+ 31)));
2111 iq2000_expand_eh_return (rtx address
)
2113 HOST_WIDE_INT gp_offset
= cfun
->machine
->gp_sp_offset
;
2116 scratch
= plus_constant (stack_pointer_rtx
, gp_offset
);
2117 emit_move_insn (gen_rtx_MEM (GET_MODE (address
), scratch
), address
);
2120 /* Return nonzero if this function is known to have a null epilogue.
2121 This allows the optimizer to omit jumps to jumps if no stack
2125 iq2000_can_use_return_insn (void)
2127 if (! reload_completed
)
2130 if (df_regs_ever_live_p (31) || profile_flag
)
2133 if (cfun
->machine
->initialized
)
2134 return cfun
->machine
->total_size
== 0;
2136 return compute_frame_size (get_frame_size ()) == 0;
2139 /* Choose the section to use for the constant rtx expression X that has
2143 iq2000_select_rtx_section (enum machine_mode mode
, rtx x ATTRIBUTE_UNUSED
,
2144 unsigned HOST_WIDE_INT align
)
2146 /* For embedded applications, always put constants in read-only data,
2147 in order to reduce RAM usage. */
2148 return mergeable_constant_section (mode
, align
, 0);
2151 /* Choose the section to use for DECL. RELOC is true if its value contains
2152 any relocatable expression.
2154 Some of the logic used here needs to be replicated in
2155 ENCODE_SECTION_INFO in iq2000.h so that references to these symbols
2156 are done correctly. */
2159 iq2000_select_section (tree decl
, int reloc ATTRIBUTE_UNUSED
,
2160 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED
)
2162 if (TARGET_EMBEDDED_DATA
)
2164 /* For embedded applications, always put an object in read-only data
2165 if possible, in order to reduce RAM usage. */
2166 if ((TREE_CODE (decl
) == VAR_DECL
2167 && TREE_READONLY (decl
) && !TREE_SIDE_EFFECTS (decl
)
2168 && DECL_INITIAL (decl
)
2169 && (DECL_INITIAL (decl
) == error_mark_node
2170 || TREE_CONSTANT (DECL_INITIAL (decl
))))
2171 /* Deal with calls from output_constant_def_contents. */
2172 || TREE_CODE (decl
) != VAR_DECL
)
2173 return readonly_data_section
;
2175 return data_section
;
2179 /* For hosted applications, always put an object in small data if
2180 possible, as this gives the best performance. */
2181 if ((TREE_CODE (decl
) == VAR_DECL
2182 && TREE_READONLY (decl
) && !TREE_SIDE_EFFECTS (decl
)
2183 && DECL_INITIAL (decl
)
2184 && (DECL_INITIAL (decl
) == error_mark_node
2185 || TREE_CONSTANT (DECL_INITIAL (decl
))))
2186 /* Deal with calls from output_constant_def_contents. */
2187 || TREE_CODE (decl
) != VAR_DECL
)
2188 return readonly_data_section
;
2190 return data_section
;
2193 /* Return register to use for a function return value with VALTYPE for function
2197 iq2000_function_value (const_tree valtype
,
2198 const_tree fn_decl_or_type
,
2199 bool outgoing ATTRIBUTE_UNUSED
)
2201 int reg
= GP_RETURN
;
2202 enum machine_mode mode
= TYPE_MODE (valtype
);
2203 int unsignedp
= TYPE_UNSIGNED (valtype
);
2204 const_tree func
= fn_decl_or_type
;
2207 && !DECL_P (fn_decl_or_type
))
2208 fn_decl_or_type
= NULL
;
2210 /* Since we promote return types, we must promote the mode here too. */
2211 mode
= promote_function_mode (valtype
, mode
, &unsignedp
, func
, 1);
2213 return gen_rtx_REG (mode
, reg
);
2216 /* Worker function for TARGET_LIBCALL_VALUE. */
2219 iq2000_libcall_value (enum machine_mode mode
, const_rtx fun ATTRIBUTE_UNUSED
)
2221 return gen_rtx_REG (((GET_MODE_CLASS (mode
) != MODE_INT
2222 || GET_MODE_SIZE (mode
) >= 4)
2227 /* Worker function for FUNCTION_VALUE_REGNO_P.
2229 On the IQ2000, R2 and R3 are the only register thus used. */
2232 iq2000_function_value_regno_p (const unsigned int regno
)
2234 return (regno
== GP_RETURN
);
2238 /* Return true when an argument must be passed by reference. */
2241 iq2000_pass_by_reference (CUMULATIVE_ARGS
*cum
, enum machine_mode mode
,
2242 const_tree type
, bool named ATTRIBUTE_UNUSED
)
2246 /* We must pass by reference if we would be both passing in registers
2247 and the stack. This is because any subsequent partial arg would be
2248 handled incorrectly in this case. */
2249 if (cum
&& targetm
.calls
.must_pass_in_stack (mode
, type
))
2251 /* Don't pass the actual CUM to FUNCTION_ARG, because we would
2252 get double copies of any offsets generated for small structs
2253 passed in registers. */
2254 CUMULATIVE_ARGS temp
;
2257 if (iq2000_function_arg (&temp
, mode
, type
, named
) != 0)
2261 if (type
== NULL_TREE
|| mode
== DImode
|| mode
== DFmode
)
2264 size
= int_size_in_bytes (type
);
2265 return size
== -1 || size
> UNITS_PER_WORD
;
2268 /* Return the length of INSN. LENGTH is the initial length computed by
2269 attributes in the machine-description file. */
2272 iq2000_adjust_insn_length (rtx insn
, int length
)
2274 /* A unconditional jump has an unfilled delay slot if it is not part
2275 of a sequence. A conditional jump normally has a delay slot. */
2276 if (simplejump_p (insn
)
2277 || ( (GET_CODE (insn
) == JUMP_INSN
2278 || GET_CODE (insn
) == CALL_INSN
)))
2284 /* Output assembly instructions to perform a conditional branch.
2286 INSN is the branch instruction. OPERANDS[0] is the condition.
2287 OPERANDS[1] is the target of the branch. OPERANDS[2] is the target
2288 of the first operand to the condition. If TWO_OPERANDS_P is
2289 nonzero the comparison takes two operands; OPERANDS[3] will be the
2292 If INVERTED_P is nonzero we are to branch if the condition does
2293 not hold. If FLOAT_P is nonzero this is a floating-point comparison.
2295 LENGTH is the length (in bytes) of the sequence we are to generate.
2296 That tells us whether to generate a simple conditional branch, or a
2297 reversed conditional branch around a `jr' instruction. */
2300 iq2000_output_conditional_branch (rtx insn
, rtx
* operands
, int two_operands_p
,
2301 int float_p
, int inverted_p
, int length
)
2303 static char buffer
[200];
2304 /* The kind of comparison we are doing. */
2305 enum rtx_code code
= GET_CODE (operands
[0]);
2306 /* Nonzero if the opcode for the comparison needs a `z' indicating
2307 that it is a comparison against zero. */
2309 /* A string to use in the assembly output to represent the first
2311 const char *op1
= "%z2";
2312 /* A string to use in the assembly output to represent the second
2313 operand. Use the hard-wired zero register if there's no second
2315 const char *op2
= (two_operands_p
? ",%z3" : ",%.");
2316 /* The operand-printing string for the comparison. */
2317 const char *comp
= (float_p
? "%F0" : "%C0");
2318 /* The operand-printing string for the inverted comparison. */
2319 const char *inverted_comp
= (float_p
? "%W0" : "%N0");
2321 /* Likely variants of each branch instruction annul the instruction
2322 in the delay slot if the branch is not taken. */
2323 iq2000_branch_likely
= (final_sequence
&& INSN_ANNULLED_BRANCH_P (insn
));
2325 if (!two_operands_p
)
2327 /* To compute whether than A > B, for example, we normally
2328 subtract B from A and then look at the sign bit. But, if we
2329 are doing an unsigned comparison, and B is zero, we don't
2330 have to do the subtraction. Instead, we can just check to
2331 see if A is nonzero. Thus, we change the CODE here to
2332 reflect the simpler comparison operation. */
2344 /* A condition which will always be true. */
2350 /* A condition which will always be false. */
2356 /* Not a special case. */
2361 /* Relative comparisons are always done against zero. But
2362 equality comparisons are done between two operands, and therefore
2363 do not require a `z' in the assembly language output. */
2364 need_z_p
= (!float_p
&& code
!= EQ
&& code
!= NE
);
2365 /* For comparisons against zero, the zero is not provided
2370 /* Begin by terminating the buffer. That way we can always use
2371 strcat to add to it. */
2378 /* Just a simple conditional branch. */
2380 sprintf (buffer
, "b%s%%?\t%%Z2%%1",
2381 inverted_p
? inverted_comp
: comp
);
2383 sprintf (buffer
, "b%s%s%%?\t%s%s,%%1",
2384 inverted_p
? inverted_comp
: comp
,
2385 need_z_p
? "z" : "",
2393 /* Generate a reversed conditional branch around ` j'
2405 Because we have to jump four bytes *past* the following
2406 instruction if this branch was annulled, we can't just use
2407 a label, as in the picture above; there's no way to put the
2408 label after the next instruction, as the assembler does not
2409 accept `.L+4' as the target of a branch. (We can't just
2410 wait until the next instruction is output; it might be a
2411 macro and take up more than four bytes. Once again, we see
2412 why we want to eliminate macros.)
2414 If the branch is annulled, we jump four more bytes that we
2415 would otherwise; that way we skip the annulled instruction
2416 in the delay slot. */
2419 = ((iq2000_branch_likely
|| length
== 16) ? ".+16" : ".+12");
2422 c
= strchr (buffer
, '\0');
2423 /* Generate the reversed comparison. This takes four
2426 sprintf (c
, "b%s\t%%Z2%s",
2427 inverted_p
? comp
: inverted_comp
,
2430 sprintf (c
, "b%s%s\t%s%s,%s",
2431 inverted_p
? comp
: inverted_comp
,
2432 need_z_p
? "z" : "",
2436 strcat (c
, "\n\tnop\n\tj\t%1");
2438 /* The delay slot was unfilled. Since we're inside
2439 .noreorder, the assembler will not fill in the NOP for
2440 us, so we must do it ourselves. */
2441 strcat (buffer
, "\n\tnop");
2453 #define def_builtin(NAME, TYPE, CODE) \
2454 add_builtin_function ((NAME), (TYPE), (CODE), BUILT_IN_MD, \
2458 iq2000_init_builtins (void)
2460 tree void_ftype
, void_ftype_int
, void_ftype_int_int
;
2461 tree void_ftype_int_int_int
;
2462 tree int_ftype_int
, int_ftype_int_int
, int_ftype_int_int_int
;
2463 tree int_ftype_int_int_int_int
;
2467 = build_function_type_list (void_type_node
, NULL_TREE
);
2471 = build_function_type_list (void_type_node
, integer_type_node
, NULL_TREE
);
2473 /* void func (int, int) */
2475 = build_function_type_list (void_type_node
,
2480 /* int func (int) */
2482 = build_function_type_list (integer_type_node
,
2483 integer_type_node
, NULL_TREE
);
2485 /* int func (int, int) */
2487 = build_function_type_list (integer_type_node
,
2492 /* void func (int, int, int) */
2493 void_ftype_int_int_int
2494 = build_function_type_list (void_type_node
,
2500 /* int func (int, int, int) */
2501 int_ftype_int_int_int
2502 = build_function_type_list (integer_type_node
,
2508 /* int func (int, int, int, int) */
2509 int_ftype_int_int_int_int
2510 = build_function_type_list (integer_type_node
,
2517 def_builtin ("__builtin_ado16", int_ftype_int_int
, IQ2000_BUILTIN_ADO16
);
2518 def_builtin ("__builtin_ram", int_ftype_int_int_int_int
, IQ2000_BUILTIN_RAM
);
2519 def_builtin ("__builtin_chkhdr", void_ftype_int_int
, IQ2000_BUILTIN_CHKHDR
);
2520 def_builtin ("__builtin_pkrl", void_ftype_int_int
, IQ2000_BUILTIN_PKRL
);
2521 def_builtin ("__builtin_cfc0", int_ftype_int
, IQ2000_BUILTIN_CFC0
);
2522 def_builtin ("__builtin_cfc1", int_ftype_int
, IQ2000_BUILTIN_CFC1
);
2523 def_builtin ("__builtin_cfc2", int_ftype_int
, IQ2000_BUILTIN_CFC2
);
2524 def_builtin ("__builtin_cfc3", int_ftype_int
, IQ2000_BUILTIN_CFC3
);
2525 def_builtin ("__builtin_ctc0", void_ftype_int_int
, IQ2000_BUILTIN_CTC0
);
2526 def_builtin ("__builtin_ctc1", void_ftype_int_int
, IQ2000_BUILTIN_CTC1
);
2527 def_builtin ("__builtin_ctc2", void_ftype_int_int
, IQ2000_BUILTIN_CTC2
);
2528 def_builtin ("__builtin_ctc3", void_ftype_int_int
, IQ2000_BUILTIN_CTC3
);
2529 def_builtin ("__builtin_mfc0", int_ftype_int
, IQ2000_BUILTIN_MFC0
);
2530 def_builtin ("__builtin_mfc1", int_ftype_int
, IQ2000_BUILTIN_MFC1
);
2531 def_builtin ("__builtin_mfc2", int_ftype_int
, IQ2000_BUILTIN_MFC2
);
2532 def_builtin ("__builtin_mfc3", int_ftype_int
, IQ2000_BUILTIN_MFC3
);
2533 def_builtin ("__builtin_mtc0", void_ftype_int_int
, IQ2000_BUILTIN_MTC0
);
2534 def_builtin ("__builtin_mtc1", void_ftype_int_int
, IQ2000_BUILTIN_MTC1
);
2535 def_builtin ("__builtin_mtc2", void_ftype_int_int
, IQ2000_BUILTIN_MTC2
);
2536 def_builtin ("__builtin_mtc3", void_ftype_int_int
, IQ2000_BUILTIN_MTC3
);
2537 def_builtin ("__builtin_lur", void_ftype_int_int
, IQ2000_BUILTIN_LUR
);
2538 def_builtin ("__builtin_rb", void_ftype_int_int
, IQ2000_BUILTIN_RB
);
2539 def_builtin ("__builtin_rx", void_ftype_int_int
, IQ2000_BUILTIN_RX
);
2540 def_builtin ("__builtin_srrd", void_ftype_int
, IQ2000_BUILTIN_SRRD
);
2541 def_builtin ("__builtin_srwr", void_ftype_int_int
, IQ2000_BUILTIN_SRWR
);
2542 def_builtin ("__builtin_wb", void_ftype_int_int
, IQ2000_BUILTIN_WB
);
2543 def_builtin ("__builtin_wx", void_ftype_int_int
, IQ2000_BUILTIN_WX
);
2544 def_builtin ("__builtin_luc32l", void_ftype_int_int
, IQ2000_BUILTIN_LUC32L
);
2545 def_builtin ("__builtin_luc64", void_ftype_int_int
, IQ2000_BUILTIN_LUC64
);
2546 def_builtin ("__builtin_luc64l", void_ftype_int_int
, IQ2000_BUILTIN_LUC64L
);
2547 def_builtin ("__builtin_luk", void_ftype_int_int
, IQ2000_BUILTIN_LUK
);
2548 def_builtin ("__builtin_lulck", void_ftype_int
, IQ2000_BUILTIN_LULCK
);
2549 def_builtin ("__builtin_lum32", void_ftype_int_int
, IQ2000_BUILTIN_LUM32
);
2550 def_builtin ("__builtin_lum32l", void_ftype_int_int
, IQ2000_BUILTIN_LUM32L
);
2551 def_builtin ("__builtin_lum64", void_ftype_int_int
, IQ2000_BUILTIN_LUM64
);
2552 def_builtin ("__builtin_lum64l", void_ftype_int_int
, IQ2000_BUILTIN_LUM64L
);
2553 def_builtin ("__builtin_lurl", void_ftype_int_int
, IQ2000_BUILTIN_LURL
);
2554 def_builtin ("__builtin_mrgb", int_ftype_int_int_int
, IQ2000_BUILTIN_MRGB
);
2555 def_builtin ("__builtin_srrdl", void_ftype_int
, IQ2000_BUILTIN_SRRDL
);
2556 def_builtin ("__builtin_srulck", void_ftype_int
, IQ2000_BUILTIN_SRULCK
);
2557 def_builtin ("__builtin_srwru", void_ftype_int_int
, IQ2000_BUILTIN_SRWRU
);
2558 def_builtin ("__builtin_trapqfl", void_ftype
, IQ2000_BUILTIN_TRAPQFL
);
2559 def_builtin ("__builtin_trapqne", void_ftype
, IQ2000_BUILTIN_TRAPQNE
);
2560 def_builtin ("__builtin_traprel", void_ftype_int
, IQ2000_BUILTIN_TRAPREL
);
2561 def_builtin ("__builtin_wbu", void_ftype_int_int_int
, IQ2000_BUILTIN_WBU
);
2562 def_builtin ("__builtin_syscall", void_ftype
, IQ2000_BUILTIN_SYSCALL
);
2565 /* Builtin for ICODE having ARGCOUNT args in EXP where each arg
2569 expand_one_builtin (enum insn_code icode
, rtx target
, tree exp
,
2570 enum rtx_code
*code
, int argcount
)
2575 enum machine_mode mode
[5];
2578 mode
[0] = insn_data
[icode
].operand
[0].mode
;
2579 for (i
= 0; i
< argcount
; i
++)
2581 arg
[i
] = CALL_EXPR_ARG (exp
, i
);
2582 op
[i
] = expand_normal (arg
[i
]);
2583 mode
[i
] = insn_data
[icode
].operand
[i
].mode
;
2584 if (code
[i
] == CONST_INT
&& GET_CODE (op
[i
]) != CONST_INT
)
2585 error ("argument %qd is not a constant", i
+ 1);
2587 && ! (*insn_data
[icode
].operand
[i
].predicate
) (op
[i
], mode
[i
]))
2588 op
[i
] = copy_to_mode_reg (mode
[i
], op
[i
]);
2591 if (insn_data
[icode
].operand
[0].constraint
[0] == '=')
2594 || GET_MODE (target
) != mode
[0]
2595 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, mode
[0]))
2596 target
= gen_reg_rtx (mode
[0]);
2604 pat
= GEN_FCN (icode
) (target
);
2607 pat
= GEN_FCN (icode
) (target
, op
[0]);
2609 pat
= GEN_FCN (icode
) (op
[0]);
2613 pat
= GEN_FCN (icode
) (target
, op
[0], op
[1]);
2615 pat
= GEN_FCN (icode
) (op
[0], op
[1]);
2619 pat
= GEN_FCN (icode
) (target
, op
[0], op
[1], op
[2]);
2621 pat
= GEN_FCN (icode
) (op
[0], op
[1], op
[2]);
2625 pat
= GEN_FCN (icode
) (target
, op
[0], op
[1], op
[2], op
[3]);
2627 pat
= GEN_FCN (icode
) (op
[0], op
[1], op
[2], op
[3]);
2639 /* Expand an expression EXP that calls a built-in function,
2640 with result going to TARGET if that's convenient
2641 (and in mode MODE if that's convenient).
2642 SUBTARGET may be used as the target for computing one of EXP's operands.
2643 IGNORE is nonzero if the value is to be ignored. */
2646 iq2000_expand_builtin (tree exp
, rtx target
, rtx subtarget ATTRIBUTE_UNUSED
,
2647 enum machine_mode mode ATTRIBUTE_UNUSED
,
2648 int ignore ATTRIBUTE_UNUSED
)
2650 tree fndecl
= TREE_OPERAND (CALL_EXPR_FN (exp
), 0);
2651 int fcode
= DECL_FUNCTION_CODE (fndecl
);
2652 enum rtx_code code
[5];
2664 case IQ2000_BUILTIN_ADO16
:
2665 return expand_one_builtin (CODE_FOR_ado16
, target
, exp
, code
, 2);
2667 case IQ2000_BUILTIN_RAM
:
2668 code
[1] = CONST_INT
;
2669 code
[2] = CONST_INT
;
2670 code
[3] = CONST_INT
;
2671 return expand_one_builtin (CODE_FOR_ram
, target
, exp
, code
, 4);
2673 case IQ2000_BUILTIN_CHKHDR
:
2674 return expand_one_builtin (CODE_FOR_chkhdr
, target
, exp
, code
, 2);
2676 case IQ2000_BUILTIN_PKRL
:
2677 return expand_one_builtin (CODE_FOR_pkrl
, target
, exp
, code
, 2);
2679 case IQ2000_BUILTIN_CFC0
:
2680 code
[0] = CONST_INT
;
2681 return expand_one_builtin (CODE_FOR_cfc0
, target
, exp
, code
, 1);
2683 case IQ2000_BUILTIN_CFC1
:
2684 code
[0] = CONST_INT
;
2685 return expand_one_builtin (CODE_FOR_cfc1
, target
, exp
, code
, 1);
2687 case IQ2000_BUILTIN_CFC2
:
2688 code
[0] = CONST_INT
;
2689 return expand_one_builtin (CODE_FOR_cfc2
, target
, exp
, code
, 1);
2691 case IQ2000_BUILTIN_CFC3
:
2692 code
[0] = CONST_INT
;
2693 return expand_one_builtin (CODE_FOR_cfc3
, target
, exp
, code
, 1);
2695 case IQ2000_BUILTIN_CTC0
:
2696 code
[1] = CONST_INT
;
2697 return expand_one_builtin (CODE_FOR_ctc0
, target
, exp
, code
, 2);
2699 case IQ2000_BUILTIN_CTC1
:
2700 code
[1] = CONST_INT
;
2701 return expand_one_builtin (CODE_FOR_ctc1
, target
, exp
, code
, 2);
2703 case IQ2000_BUILTIN_CTC2
:
2704 code
[1] = CONST_INT
;
2705 return expand_one_builtin (CODE_FOR_ctc2
, target
, exp
, code
, 2);
2707 case IQ2000_BUILTIN_CTC3
:
2708 code
[1] = CONST_INT
;
2709 return expand_one_builtin (CODE_FOR_ctc3
, target
, exp
, code
, 2);
2711 case IQ2000_BUILTIN_MFC0
:
2712 code
[0] = CONST_INT
;
2713 return expand_one_builtin (CODE_FOR_mfc0
, target
, exp
, code
, 1);
2715 case IQ2000_BUILTIN_MFC1
:
2716 code
[0] = CONST_INT
;
2717 return expand_one_builtin (CODE_FOR_mfc1
, target
, exp
, code
, 1);
2719 case IQ2000_BUILTIN_MFC2
:
2720 code
[0] = CONST_INT
;
2721 return expand_one_builtin (CODE_FOR_mfc2
, target
, exp
, code
, 1);
2723 case IQ2000_BUILTIN_MFC3
:
2724 code
[0] = CONST_INT
;
2725 return expand_one_builtin (CODE_FOR_mfc3
, target
, exp
, code
, 1);
2727 case IQ2000_BUILTIN_MTC0
:
2728 code
[1] = CONST_INT
;
2729 return expand_one_builtin (CODE_FOR_mtc0
, target
, exp
, code
, 2);
2731 case IQ2000_BUILTIN_MTC1
:
2732 code
[1] = CONST_INT
;
2733 return expand_one_builtin (CODE_FOR_mtc1
, target
, exp
, code
, 2);
2735 case IQ2000_BUILTIN_MTC2
:
2736 code
[1] = CONST_INT
;
2737 return expand_one_builtin (CODE_FOR_mtc2
, target
, exp
, code
, 2);
2739 case IQ2000_BUILTIN_MTC3
:
2740 code
[1] = CONST_INT
;
2741 return expand_one_builtin (CODE_FOR_mtc3
, target
, exp
, code
, 2);
2743 case IQ2000_BUILTIN_LUR
:
2744 return expand_one_builtin (CODE_FOR_lur
, target
, exp
, code
, 2);
2746 case IQ2000_BUILTIN_RB
:
2747 return expand_one_builtin (CODE_FOR_rb
, target
, exp
, code
, 2);
2749 case IQ2000_BUILTIN_RX
:
2750 return expand_one_builtin (CODE_FOR_rx
, target
, exp
, code
, 2);
2752 case IQ2000_BUILTIN_SRRD
:
2753 return expand_one_builtin (CODE_FOR_srrd
, target
, exp
, code
, 1);
2755 case IQ2000_BUILTIN_SRWR
:
2756 return expand_one_builtin (CODE_FOR_srwr
, target
, exp
, code
, 2);
2758 case IQ2000_BUILTIN_WB
:
2759 return expand_one_builtin (CODE_FOR_wb
, target
, exp
, code
, 2);
2761 case IQ2000_BUILTIN_WX
:
2762 return expand_one_builtin (CODE_FOR_wx
, target
, exp
, code
, 2);
2764 case IQ2000_BUILTIN_LUC32L
:
2765 return expand_one_builtin (CODE_FOR_luc32l
, target
, exp
, code
, 2);
2767 case IQ2000_BUILTIN_LUC64
:
2768 return expand_one_builtin (CODE_FOR_luc64
, target
, exp
, code
, 2);
2770 case IQ2000_BUILTIN_LUC64L
:
2771 return expand_one_builtin (CODE_FOR_luc64l
, target
, exp
, code
, 2);
2773 case IQ2000_BUILTIN_LUK
:
2774 return expand_one_builtin (CODE_FOR_luk
, target
, exp
, code
, 2);
2776 case IQ2000_BUILTIN_LULCK
:
2777 return expand_one_builtin (CODE_FOR_lulck
, target
, exp
, code
, 1);
2779 case IQ2000_BUILTIN_LUM32
:
2780 return expand_one_builtin (CODE_FOR_lum32
, target
, exp
, code
, 2);
2782 case IQ2000_BUILTIN_LUM32L
:
2783 return expand_one_builtin (CODE_FOR_lum32l
, target
, exp
, code
, 2);
2785 case IQ2000_BUILTIN_LUM64
:
2786 return expand_one_builtin (CODE_FOR_lum64
, target
, exp
, code
, 2);
2788 case IQ2000_BUILTIN_LUM64L
:
2789 return expand_one_builtin (CODE_FOR_lum64l
, target
, exp
, code
, 2);
2791 case IQ2000_BUILTIN_LURL
:
2792 return expand_one_builtin (CODE_FOR_lurl
, target
, exp
, code
, 2);
2794 case IQ2000_BUILTIN_MRGB
:
2795 code
[2] = CONST_INT
;
2796 return expand_one_builtin (CODE_FOR_mrgb
, target
, exp
, code
, 3);
2798 case IQ2000_BUILTIN_SRRDL
:
2799 return expand_one_builtin (CODE_FOR_srrdl
, target
, exp
, code
, 1);
2801 case IQ2000_BUILTIN_SRULCK
:
2802 return expand_one_builtin (CODE_FOR_srulck
, target
, exp
, code
, 1);
2804 case IQ2000_BUILTIN_SRWRU
:
2805 return expand_one_builtin (CODE_FOR_srwru
, target
, exp
, code
, 2);
2807 case IQ2000_BUILTIN_TRAPQFL
:
2808 return expand_one_builtin (CODE_FOR_trapqfl
, target
, exp
, code
, 0);
2810 case IQ2000_BUILTIN_TRAPQNE
:
2811 return expand_one_builtin (CODE_FOR_trapqne
, target
, exp
, code
, 0);
2813 case IQ2000_BUILTIN_TRAPREL
:
2814 return expand_one_builtin (CODE_FOR_traprel
, target
, exp
, code
, 1);
2816 case IQ2000_BUILTIN_WBU
:
2817 return expand_one_builtin (CODE_FOR_wbu
, target
, exp
, code
, 3);
2819 case IQ2000_BUILTIN_SYSCALL
:
2820 return expand_one_builtin (CODE_FOR_syscall
, target
, exp
, code
, 0);
2826 /* Worker function for TARGET_RETURN_IN_MEMORY. */
2829 iq2000_return_in_memory (const_tree type
, const_tree fntype ATTRIBUTE_UNUSED
)
2831 return ((int_size_in_bytes (type
) > (2 * UNITS_PER_WORD
))
2832 || (int_size_in_bytes (type
) == -1));
2835 /* Worker function for TARGET_SETUP_INCOMING_VARARGS. */
2838 iq2000_setup_incoming_varargs (CUMULATIVE_ARGS
*cum
,
2839 enum machine_mode mode ATTRIBUTE_UNUSED
,
2840 tree type ATTRIBUTE_UNUSED
, int * pretend_size
,
2843 unsigned int iq2000_off
= ! cum
->last_arg_fp
;
2844 unsigned int iq2000_fp_off
= cum
->last_arg_fp
;
2846 if ((cum
->arg_words
< MAX_ARGS_IN_REGISTERS
- iq2000_off
))
2848 int iq2000_save_gp_regs
2849 = MAX_ARGS_IN_REGISTERS
- cum
->arg_words
- iq2000_off
;
2850 int iq2000_save_fp_regs
2851 = (MAX_ARGS_IN_REGISTERS
- cum
->fp_arg_words
- iq2000_fp_off
);
2853 if (iq2000_save_gp_regs
< 0)
2854 iq2000_save_gp_regs
= 0;
2855 if (iq2000_save_fp_regs
< 0)
2856 iq2000_save_fp_regs
= 0;
2858 *pretend_size
= ((iq2000_save_gp_regs
* UNITS_PER_WORD
)
2859 + (iq2000_save_fp_regs
* UNITS_PER_FPREG
));
2863 if (cum
->arg_words
< MAX_ARGS_IN_REGISTERS
- iq2000_off
)
2866 ptr
= plus_constant (virtual_incoming_args_rtx
,
2867 - (iq2000_save_gp_regs
2869 mem
= gen_rtx_MEM (BLKmode
, ptr
);
2871 (cum
->arg_words
+ GP_ARG_FIRST
+ iq2000_off
,
2873 iq2000_save_gp_regs
);
2879 /* A C compound statement to output to stdio stream STREAM the
2880 assembler syntax for an instruction operand that is a memory
2881 reference whose address is ADDR. ADDR is an RTL expression. */
2884 iq2000_print_operand_address (FILE * file
, rtx addr
)
2887 error ("PRINT_OPERAND_ADDRESS, null pointer");
2890 switch (GET_CODE (addr
))
2893 if (REGNO (addr
) == ARG_POINTER_REGNUM
)
2894 abort_with_insn (addr
, "Arg pointer not eliminated.");
2896 fprintf (file
, "0(%s)", reg_names
[REGNO (addr
)]);
2901 rtx arg0
= XEXP (addr
, 0);
2902 rtx arg1
= XEXP (addr
, 1);
2904 if (GET_CODE (arg0
) != REG
)
2905 abort_with_insn (addr
,
2906 "PRINT_OPERAND_ADDRESS, LO_SUM with #1 not REG.");
2908 fprintf (file
, "%%lo(");
2909 iq2000_print_operand_address (file
, arg1
);
2910 fprintf (file
, ")(%s)", reg_names
[REGNO (arg0
)]);
2918 rtx arg0
= XEXP (addr
, 0);
2919 rtx arg1
= XEXP (addr
, 1);
2921 if (GET_CODE (arg0
) == REG
)
2925 if (GET_CODE (offset
) == REG
)
2926 abort_with_insn (addr
, "PRINT_OPERAND_ADDRESS, 2 regs");
2929 else if (GET_CODE (arg1
) == REG
)
2930 reg
= arg1
, offset
= arg0
;
2931 else if (CONSTANT_P (arg0
) && CONSTANT_P (arg1
))
2933 output_addr_const (file
, addr
);
2937 abort_with_insn (addr
, "PRINT_OPERAND_ADDRESS, no regs");
2939 if (! CONSTANT_P (offset
))
2940 abort_with_insn (addr
, "PRINT_OPERAND_ADDRESS, invalid insn #2");
2942 if (REGNO (reg
) == ARG_POINTER_REGNUM
)
2943 abort_with_insn (addr
, "Arg pointer not eliminated.");
2945 output_addr_const (file
, offset
);
2946 fprintf (file
, "(%s)", reg_names
[REGNO (reg
)]);
2954 output_addr_const (file
, addr
);
2955 if (GET_CODE (addr
) == CONST_INT
)
2956 fprintf (file
, "(%s)", reg_names
[0]);
2960 abort_with_insn (addr
, "PRINT_OPERAND_ADDRESS, invalid insn #1");
2965 /* A C compound statement to output to stdio stream FILE the
2966 assembler syntax for an instruction operand OP.
2968 LETTER is a value that can be used to specify one of several ways
2969 of printing the operand. It is used when identical operands
2970 must be printed differently depending on the context. LETTER
2971 comes from the `%' specification that was used to request
2972 printing of the operand. If the specification was just `%DIGIT'
2973 then LETTER is 0; if the specification was `%LTR DIGIT' then LETTER
2974 is the ASCII code for LTR.
2976 If OP is a register, this macro should print the register's name.
2977 The names can be found in an array `reg_names' whose type is
2978 `char *[]'. `reg_names' is initialized from `REGISTER_NAMES'.
2980 When the machine description has a specification `%PUNCT' (a `%'
2981 followed by a punctuation character), this macro is called with
2982 a null pointer for X and the punctuation character for LETTER.
2984 The IQ2000 specific codes are:
2986 'X' X is CONST_INT, prints upper 16 bits in hexadecimal format = "0x%04x",
2987 'x' X is CONST_INT, prints lower 16 bits in hexadecimal format = "0x%04x",
2988 'd' output integer constant in decimal,
2989 'z' if the operand is 0, use $0 instead of normal operand.
2990 'D' print second part of double-word register or memory operand.
2991 'L' print low-order register of double-word register operand.
2992 'M' print high-order register of double-word register operand.
2993 'C' print part of opcode for a branch condition.
2994 'F' print part of opcode for a floating-point branch condition.
2995 'N' print part of opcode for a branch condition, inverted.
2996 'W' print part of opcode for a floating-point branch condition, inverted.
2997 'A' Print part of opcode for a bit test condition.
2998 'P' Print label for a bit test.
2999 'p' Print log for a bit test.
3000 'B' print 'z' for EQ, 'n' for NE
3001 'b' print 'n' for EQ, 'z' for NE
3002 'T' print 'f' for EQ, 't' for NE
3003 't' print 't' for EQ, 'f' for NE
3004 'Z' print register and a comma, but print nothing for $fcc0
3005 '?' Print 'l' if we are to use a branch likely instead of normal branch.
3006 '@' Print the name of the assembler temporary register (at or $1).
3007 '.' Print the name of the register with a hard-wired zero (zero or $0).
3008 '$' Print the name of the stack pointer register (sp or $29).
3009 '+' Print the name of the gp register (gp or $28). */
3012 iq2000_print_operand (FILE *file
, rtx op
, int letter
)
3016 if (iq2000_print_operand_punct_valid_p (letter
))
3021 if (iq2000_branch_likely
)
3026 fputs (reg_names
[GP_REG_FIRST
+ 1], file
);
3030 fputs (reg_names
[GP_REG_FIRST
+ 0], file
);
3034 fputs (reg_names
[STACK_POINTER_REGNUM
], file
);
3038 fputs (reg_names
[GP_REG_FIRST
+ 28], file
);
3042 error ("PRINT_OPERAND: Unknown punctuation '%c'", letter
);
3051 error ("PRINT_OPERAND null pointer");
3055 code
= GET_CODE (op
);
3057 if (code
== SIGN_EXTEND
)
3058 op
= XEXP (op
, 0), code
= GET_CODE (op
);
3063 case EQ
: fputs ("eq", file
); break;
3064 case NE
: fputs ("ne", file
); break;
3065 case GT
: fputs ("gt", file
); break;
3066 case GE
: fputs ("ge", file
); break;
3067 case LT
: fputs ("lt", file
); break;
3068 case LE
: fputs ("le", file
); break;
3069 case GTU
: fputs ("ne", file
); break;
3070 case GEU
: fputs ("geu", file
); break;
3071 case LTU
: fputs ("ltu", file
); break;
3072 case LEU
: fputs ("eq", file
); break;
3074 abort_with_insn (op
, "PRINT_OPERAND, invalid insn for %%C");
3077 else if (letter
== 'N')
3080 case EQ
: fputs ("ne", file
); break;
3081 case NE
: fputs ("eq", file
); break;
3082 case GT
: fputs ("le", file
); break;
3083 case GE
: fputs ("lt", file
); break;
3084 case LT
: fputs ("ge", file
); break;
3085 case LE
: fputs ("gt", file
); break;
3086 case GTU
: fputs ("leu", file
); break;
3087 case GEU
: fputs ("ltu", file
); break;
3088 case LTU
: fputs ("geu", file
); break;
3089 case LEU
: fputs ("gtu", file
); break;
3091 abort_with_insn (op
, "PRINT_OPERAND, invalid insn for %%N");
3094 else if (letter
== 'F')
3097 case EQ
: fputs ("c1f", file
); break;
3098 case NE
: fputs ("c1t", file
); break;
3100 abort_with_insn (op
, "PRINT_OPERAND, invalid insn for %%F");
3103 else if (letter
== 'W')
3106 case EQ
: fputs ("c1t", file
); break;
3107 case NE
: fputs ("c1f", file
); break;
3109 abort_with_insn (op
, "PRINT_OPERAND, invalid insn for %%W");
3112 else if (letter
== 'A')
3113 fputs (code
== LABEL_REF
? "i" : "in", file
);
3115 else if (letter
== 'P')
3117 if (code
== LABEL_REF
)
3118 output_addr_const (file
, op
);
3119 else if (code
!= PC
)
3120 output_operand_lossage ("invalid %%P operand");
3123 else if (letter
== 'p')
3126 if (code
!= CONST_INT
3127 || (value
= exact_log2 (INTVAL (op
))) < 0)
3128 output_operand_lossage ("invalid %%p value");
3130 fprintf (file
, "%d", value
);
3133 else if (letter
== 'Z')
3138 else if (code
== REG
|| code
== SUBREG
)
3143 regnum
= REGNO (op
);
3145 regnum
= true_regnum (op
);
3147 if ((letter
== 'M' && ! WORDS_BIG_ENDIAN
)
3148 || (letter
== 'L' && WORDS_BIG_ENDIAN
)
3152 fprintf (file
, "%s", reg_names
[regnum
]);
3155 else if (code
== MEM
)
3158 output_address (plus_constant (XEXP (op
, 0), 4));
3160 output_address (XEXP (op
, 0));
3163 else if (code
== CONST_DOUBLE
3164 && GET_MODE_CLASS (GET_MODE (op
)) == MODE_FLOAT
)
3168 real_to_decimal (s
, CONST_DOUBLE_REAL_VALUE (op
), sizeof (s
), 0, 1);
3172 else if (letter
== 'x' && GET_CODE (op
) == CONST_INT
)
3173 fprintf (file
, HOST_WIDE_INT_PRINT_HEX
, 0xffff & INTVAL(op
));
3175 else if (letter
== 'X' && GET_CODE(op
) == CONST_INT
)
3176 fprintf (file
, HOST_WIDE_INT_PRINT_HEX
, 0xffff & (INTVAL (op
) >> 16));
3178 else if (letter
== 'd' && GET_CODE(op
) == CONST_INT
)
3179 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, (INTVAL(op
)));
3181 else if (letter
== 'z' && GET_CODE (op
) == CONST_INT
&& INTVAL (op
) == 0)
3182 fputs (reg_names
[GP_REG_FIRST
], file
);
3184 else if (letter
== 'd' || letter
== 'x' || letter
== 'X')
3185 output_operand_lossage ("invalid use of %%d, %%x, or %%X");
3187 else if (letter
== 'B')
3188 fputs (code
== EQ
? "z" : "n", file
);
3189 else if (letter
== 'b')
3190 fputs (code
== EQ
? "n" : "z", file
);
3191 else if (letter
== 'T')
3192 fputs (code
== EQ
? "f" : "t", file
);
3193 else if (letter
== 't')
3194 fputs (code
== EQ
? "t" : "f", file
);
3196 else if (code
== CONST
&& GET_CODE (XEXP (op
, 0)) == REG
)
3198 iq2000_print_operand (file
, XEXP (op
, 0), letter
);
3202 output_addr_const (file
, op
);
3206 iq2000_print_operand_punct_valid_p (unsigned char code
)
3208 return iq2000_print_operand_punct
[code
];
3211 /* For the IQ2000, transform:
3213 memory(X + <large int>)
3215 Y = <large int> & ~0x7fff;
3217 memory (Z + (<large int> & 0x7fff));
3221 iq2000_legitimize_address (rtx xinsn
, rtx old_x ATTRIBUTE_UNUSED
,
3222 enum machine_mode mode
)
3224 if (TARGET_DEBUG_B_MODE
)
3226 GO_PRINTF ("\n========== LEGITIMIZE_ADDRESS\n");
3227 GO_DEBUG_RTX (xinsn
);
3230 if (iq2000_check_split (xinsn
, mode
))
3232 return gen_rtx_LO_SUM (Pmode
,
3233 copy_to_mode_reg (Pmode
,
3234 gen_rtx_HIGH (Pmode
, xinsn
)),
3238 if (GET_CODE (xinsn
) == PLUS
)
3240 rtx xplus0
= XEXP (xinsn
, 0);
3241 rtx xplus1
= XEXP (xinsn
, 1);
3242 enum rtx_code code0
= GET_CODE (xplus0
);
3243 enum rtx_code code1
= GET_CODE (xplus1
);
3245 if (code0
!= REG
&& code1
== REG
)
3247 xplus0
= XEXP (xinsn
, 1);
3248 xplus1
= XEXP (xinsn
, 0);
3249 code0
= GET_CODE (xplus0
);
3250 code1
= GET_CODE (xplus1
);
3253 if (code0
== REG
&& REG_MODE_OK_FOR_BASE_P (xplus0
, mode
)
3254 && code1
== CONST_INT
&& !SMALL_INT (xplus1
))
3256 rtx int_reg
= gen_reg_rtx (Pmode
);
3257 rtx ptr_reg
= gen_reg_rtx (Pmode
);
3259 emit_move_insn (int_reg
,
3260 GEN_INT (INTVAL (xplus1
) & ~ 0x7fff));
3262 emit_insn (gen_rtx_SET (VOIDmode
,
3264 gen_rtx_PLUS (Pmode
, xplus0
, int_reg
)));
3266 return plus_constant (ptr_reg
, INTVAL (xplus1
) & 0x7fff);
3270 if (TARGET_DEBUG_B_MODE
)
3271 GO_PRINTF ("LEGITIMIZE_ADDRESS could not fix.\n");
3278 iq2000_rtx_costs (rtx x
, int code
, int outer_code ATTRIBUTE_UNUSED
, int * total
,
3279 bool speed ATTRIBUTE_UNUSED
)
3281 enum machine_mode mode
= GET_MODE (x
);
3287 int num_words
= (GET_MODE_SIZE (mode
) > UNITS_PER_WORD
) ? 2 : 1;
3289 if (simple_memory_operand (x
, mode
))
3290 return COSTS_N_INSNS (num_words
);
3292 * total
= COSTS_N_INSNS (2 * num_words
);
3297 * total
= COSTS_N_INSNS (6);
3304 * total
= COSTS_N_INSNS (mode
== DImode
? 2 : 1);
3311 * total
= COSTS_N_INSNS ((GET_CODE (XEXP (x
, 1)) == CONST_INT
) ? 4 : 12);
3313 * total
= COSTS_N_INSNS (1);
3317 if (mode
== SFmode
|| mode
== DFmode
)
3318 * total
= COSTS_N_INSNS (1);
3320 * total
= COSTS_N_INSNS (4);
3325 if (mode
== SFmode
|| mode
== DFmode
)
3326 * total
= COSTS_N_INSNS (6);
3327 else if (mode
== DImode
)
3328 * total
= COSTS_N_INSNS (4);
3330 * total
= COSTS_N_INSNS (1);
3334 * total
= (mode
== DImode
) ? 4 : 1;
3339 * total
= COSTS_N_INSNS (7);
3340 else if (mode
== DFmode
)
3341 * total
= COSTS_N_INSNS (8);
3343 * total
= COSTS_N_INSNS (10);
3349 * total
= COSTS_N_INSNS (23);
3350 else if (mode
== DFmode
)
3351 * total
= COSTS_N_INSNS (36);
3353 * total
= COSTS_N_INSNS (69);
3358 * total
= COSTS_N_INSNS (69);
3362 * total
= COSTS_N_INSNS (2);
3366 * total
= COSTS_N_INSNS (1);
3374 * total
= COSTS_N_INSNS (2);
3379 rtx offset
= const0_rtx
;
3380 rtx symref
= eliminate_constant_term (XEXP (x
, 0), & offset
);
3382 if (GET_CODE (symref
) == LABEL_REF
)
3383 * total
= COSTS_N_INSNS (2);
3384 else if (GET_CODE (symref
) != SYMBOL_REF
)
3385 * total
= COSTS_N_INSNS (4);
3386 /* Let's be paranoid.... */
3387 else if (INTVAL (offset
) < -32768 || INTVAL (offset
) > 32767)
3388 * total
= COSTS_N_INSNS (2);
3390 * total
= COSTS_N_INSNS (SYMBOL_REF_FLAG (symref
) ? 1 : 2);
3395 * total
= COSTS_N_INSNS (SYMBOL_REF_FLAG (x
) ? 1 : 2);
3402 split_double (x
, & high
, & low
);
3404 * total
= COSTS_N_INSNS ( (high
== CONST0_RTX (GET_MODE (high
))
3405 || low
== CONST0_RTX (GET_MODE (low
)))
3416 /* Worker for TARGET_ASM_TRAMPOLINE_TEMPLATE. */
3419 iq2000_asm_trampoline_template (FILE *f
)
3421 fprintf (f
, "\t.word\t0x03e00821\t\t# move $1,$31\n");
3422 fprintf (f
, "\t.word\t0x04110001\t\t# bgezal $0,.+8\n");
3423 fprintf (f
, "\t.word\t0x00000000\t\t# nop\n");
3424 if (Pmode
== DImode
)
3426 fprintf (f
, "\t.word\t0xdfe30014\t\t# ld $3,20($31)\n");
3427 fprintf (f
, "\t.word\t0xdfe2001c\t\t# ld $2,28($31)\n");
3431 fprintf (f
, "\t.word\t0x8fe30014\t\t# lw $3,20($31)\n");
3432 fprintf (f
, "\t.word\t0x8fe20018\t\t# lw $2,24($31)\n");
3434 fprintf (f
, "\t.word\t0x0060c821\t\t# move $25,$3 (abicalls)\n");
3435 fprintf (f
, "\t.word\t0x00600008\t\t# jr $3\n");
3436 fprintf (f
, "\t.word\t0x0020f821\t\t# move $31,$1\n");
3437 fprintf (f
, "\t.word\t0x00000000\t\t# <function address>\n");
3438 fprintf (f
, "\t.word\t0x00000000\t\t# <static chain value>\n");
3441 /* Worker for TARGET_TRAMPOLINE_INIT. */
3444 iq2000_trampoline_init (rtx m_tramp
, tree fndecl
, rtx chain_value
)
3446 rtx fnaddr
= XEXP (DECL_RTL (fndecl
), 0);
3449 emit_block_move (m_tramp
, assemble_trampoline_template (),
3450 GEN_INT (TRAMPOLINE_CODE_SIZE
), BLOCK_OP_NORMAL
);
3452 mem
= adjust_address (m_tramp
, Pmode
, TRAMPOLINE_CODE_SIZE
);
3453 emit_move_insn (mem
, fnaddr
);
3454 mem
= adjust_address (m_tramp
, Pmode
,
3455 TRAMPOLINE_CODE_SIZE
+ GET_MODE_SIZE (Pmode
));
3456 emit_move_insn (mem
, chain_value
);
3459 #include "gt-iq2000.h"