1 /* Subroutines used for code generation on Vitesse IQ2000 processors
2 Copyright (C) 2003-2017 Free Software Foundation, Inc.
4 This file is part of GCC.
6 GCC is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3, or (at your option)
11 GCC is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GCC; see the file COPYING3. If not see
18 <http://www.gnu.org/licenses/>. */
22 #include "coretypes.h"
27 #include "stringpool.h"
36 #include "diagnostic-core.h"
37 #include "stor-layout.h"
41 #include "insn-attr.h"
44 #include "langhooks.h"
47 /* This file should be included last. */
48 #include "target-def.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 iq2000_print_operand. */
113 static char iq2000_print_operand_punct
[256];
115 /* Which instruction set architecture to use. */
118 /* Local variables. */
120 /* The next branch instruction is a branch likely, not branch normal. */
121 static int iq2000_branch_likely
;
123 /* Count of delay slots and how many are filled. */
124 static int dslots_load_total
;
125 static int dslots_load_filled
;
126 static int dslots_jump_total
;
128 /* # of nops needed by previous insn. */
129 static int dslots_number_nops
;
131 /* Number of 1/2/3 word references to data items (i.e., not jal's). */
132 static int num_refs
[3];
134 /* Registers to check for load delay. */
135 static rtx iq2000_load_reg
;
136 static rtx iq2000_load_reg2
;
137 static rtx iq2000_load_reg3
;
138 static rtx iq2000_load_reg4
;
140 /* Mode used for saving/restoring general purpose registers. */
141 static machine_mode gpr_mode
;
144 /* Initialize the GCC target structure. */
145 static struct machine_function
* iq2000_init_machine_status (void);
146 static void iq2000_option_override (void);
147 static section
*iq2000_select_rtx_section (machine_mode
, rtx
,
148 unsigned HOST_WIDE_INT
);
149 static void iq2000_init_builtins (void);
150 static rtx
iq2000_expand_builtin (tree
, rtx
, rtx
, machine_mode
, int);
151 static bool iq2000_return_in_memory (const_tree
, const_tree
);
152 static void iq2000_setup_incoming_varargs (cumulative_args_t
,
153 machine_mode
, tree
, int *,
155 static bool iq2000_rtx_costs (rtx
, machine_mode
, int, int, int *, bool);
156 static int iq2000_address_cost (rtx
, machine_mode
, addr_space_t
,
158 static section
*iq2000_select_section (tree
, int, unsigned HOST_WIDE_INT
);
159 static rtx
iq2000_legitimize_address (rtx
, rtx
, machine_mode
);
160 static bool iq2000_pass_by_reference (cumulative_args_t
, machine_mode
,
162 static int iq2000_arg_partial_bytes (cumulative_args_t
, machine_mode
,
164 static rtx
iq2000_function_arg (cumulative_args_t
,
165 machine_mode
, const_tree
, bool);
166 static void iq2000_function_arg_advance (cumulative_args_t
,
167 machine_mode
, const_tree
, bool);
168 static pad_direction
iq2000_function_arg_padding (machine_mode
, const_tree
);
169 static unsigned int iq2000_function_arg_boundary (machine_mode
,
171 static void iq2000_va_start (tree
, rtx
);
172 static bool iq2000_legitimate_address_p (machine_mode
, rtx
, bool);
173 static bool iq2000_can_eliminate (const int, const int);
174 static void iq2000_asm_trampoline_template (FILE *);
175 static void iq2000_trampoline_init (rtx
, tree
, rtx
);
176 static rtx
iq2000_function_value (const_tree
, const_tree
, bool);
177 static rtx
iq2000_libcall_value (machine_mode
, const_rtx
);
178 static void iq2000_print_operand (FILE *, rtx
, int);
179 static void iq2000_print_operand_address (FILE *, machine_mode
, rtx
);
180 static bool iq2000_print_operand_punct_valid_p (unsigned char code
);
181 static bool iq2000_hard_regno_mode_ok (unsigned int, machine_mode
);
182 static bool iq2000_modes_tieable_p (machine_mode
, machine_mode
);
183 static HOST_WIDE_INT
iq2000_constant_alignment (const_tree
, HOST_WIDE_INT
);
184 static HOST_WIDE_INT
iq2000_starting_frame_offset (void);
186 #undef TARGET_INIT_BUILTINS
187 #define TARGET_INIT_BUILTINS iq2000_init_builtins
188 #undef TARGET_EXPAND_BUILTIN
189 #define TARGET_EXPAND_BUILTIN iq2000_expand_builtin
190 #undef TARGET_ASM_SELECT_RTX_SECTION
191 #define TARGET_ASM_SELECT_RTX_SECTION iq2000_select_rtx_section
192 #undef TARGET_OPTION_OVERRIDE
193 #define TARGET_OPTION_OVERRIDE iq2000_option_override
194 #undef TARGET_RTX_COSTS
195 #define TARGET_RTX_COSTS iq2000_rtx_costs
196 #undef TARGET_ADDRESS_COST
197 #define TARGET_ADDRESS_COST iq2000_address_cost
198 #undef TARGET_ASM_SELECT_SECTION
199 #define TARGET_ASM_SELECT_SECTION iq2000_select_section
201 #undef TARGET_LEGITIMIZE_ADDRESS
202 #define TARGET_LEGITIMIZE_ADDRESS iq2000_legitimize_address
204 /* The assembler supports switchable .bss sections, but
205 iq2000_select_section doesn't yet make use of them. */
206 #undef TARGET_HAVE_SWITCHABLE_BSS_SECTIONS
207 #define TARGET_HAVE_SWITCHABLE_BSS_SECTIONS false
209 #undef TARGET_PRINT_OPERAND
210 #define TARGET_PRINT_OPERAND iq2000_print_operand
211 #undef TARGET_PRINT_OPERAND_ADDRESS
212 #define TARGET_PRINT_OPERAND_ADDRESS iq2000_print_operand_address
213 #undef TARGET_PRINT_OPERAND_PUNCT_VALID_P
214 #define TARGET_PRINT_OPERAND_PUNCT_VALID_P iq2000_print_operand_punct_valid_p
216 #undef TARGET_PROMOTE_FUNCTION_MODE
217 #define TARGET_PROMOTE_FUNCTION_MODE default_promote_function_mode_always_promote
218 #undef TARGET_PROMOTE_PROTOTYPES
219 #define TARGET_PROMOTE_PROTOTYPES hook_bool_const_tree_true
221 #undef TARGET_FUNCTION_VALUE
222 #define TARGET_FUNCTION_VALUE iq2000_function_value
223 #undef TARGET_LIBCALL_VALUE
224 #define TARGET_LIBCALL_VALUE iq2000_libcall_value
225 #undef TARGET_RETURN_IN_MEMORY
226 #define TARGET_RETURN_IN_MEMORY iq2000_return_in_memory
227 #undef TARGET_PASS_BY_REFERENCE
228 #define TARGET_PASS_BY_REFERENCE iq2000_pass_by_reference
229 #undef TARGET_CALLEE_COPIES
230 #define TARGET_CALLEE_COPIES hook_callee_copies_named
231 #undef TARGET_ARG_PARTIAL_BYTES
232 #define TARGET_ARG_PARTIAL_BYTES iq2000_arg_partial_bytes
233 #undef TARGET_FUNCTION_ARG
234 #define TARGET_FUNCTION_ARG iq2000_function_arg
235 #undef TARGET_FUNCTION_ARG_ADVANCE
236 #define TARGET_FUNCTION_ARG_ADVANCE iq2000_function_arg_advance
237 #undef TARGET_FUNCTION_ARG_PADDING
238 #define TARGET_FUNCTION_ARG_PADDING iq2000_function_arg_padding
239 #undef TARGET_FUNCTION_ARG_BOUNDARY
240 #define TARGET_FUNCTION_ARG_BOUNDARY iq2000_function_arg_boundary
242 #undef TARGET_SETUP_INCOMING_VARARGS
243 #define TARGET_SETUP_INCOMING_VARARGS iq2000_setup_incoming_varargs
244 #undef TARGET_STRICT_ARGUMENT_NAMING
245 #define TARGET_STRICT_ARGUMENT_NAMING hook_bool_CUMULATIVE_ARGS_true
247 #undef TARGET_EXPAND_BUILTIN_VA_START
248 #define TARGET_EXPAND_BUILTIN_VA_START iq2000_va_start
251 #define TARGET_LRA_P hook_bool_void_false
253 #undef TARGET_LEGITIMATE_ADDRESS_P
254 #define TARGET_LEGITIMATE_ADDRESS_P iq2000_legitimate_address_p
256 #undef TARGET_CAN_ELIMINATE
257 #define TARGET_CAN_ELIMINATE iq2000_can_eliminate
259 #undef TARGET_ASM_TRAMPOLINE_TEMPLATE
260 #define TARGET_ASM_TRAMPOLINE_TEMPLATE iq2000_asm_trampoline_template
261 #undef TARGET_TRAMPOLINE_INIT
262 #define TARGET_TRAMPOLINE_INIT iq2000_trampoline_init
264 #undef TARGET_HARD_REGNO_MODE_OK
265 #define TARGET_HARD_REGNO_MODE_OK iq2000_hard_regno_mode_ok
266 #undef TARGET_MODES_TIEABLE_P
267 #define TARGET_MODES_TIEABLE_P iq2000_modes_tieable_p
269 #undef TARGET_CONSTANT_ALIGNMENT
270 #define TARGET_CONSTANT_ALIGNMENT iq2000_constant_alignment
272 #undef TARGET_STARTING_FRAME_OFFSET
273 #define TARGET_STARTING_FRAME_OFFSET iq2000_starting_frame_offset
275 struct gcc_target targetm
= TARGET_INITIALIZER
;
277 /* Return nonzero if we split the address into high and low parts. */
280 iq2000_check_split (rtx address
, machine_mode mode
)
282 /* This is the same check used in simple_memory_operand.
283 We use it here because LO_SUM is not offsettable. */
284 if (GET_MODE_SIZE (mode
) > (unsigned) UNITS_PER_WORD
)
287 if ((GET_CODE (address
) == SYMBOL_REF
)
288 || (GET_CODE (address
) == CONST
289 && GET_CODE (XEXP (XEXP (address
, 0), 0)) == SYMBOL_REF
)
290 || GET_CODE (address
) == LABEL_REF
)
296 /* Return nonzero if REG is valid for MODE. */
299 iq2000_reg_mode_ok_for_base_p (rtx reg
,
300 machine_mode mode ATTRIBUTE_UNUSED
,
304 ? REGNO_MODE_OK_FOR_BASE_P (REGNO (reg
), mode
)
305 : GP_REG_OR_PSEUDO_NONSTRICT_P (REGNO (reg
), mode
));
308 /* Return a nonzero value if XINSN is a legitimate address for a
309 memory operand of the indicated MODE. STRICT is nonzero if this
310 function is called during reload. */
313 iq2000_legitimate_address_p (machine_mode mode
, rtx xinsn
, bool strict
)
315 if (TARGET_DEBUG_A_MODE
)
317 GO_PRINTF2 ("\n========== legitimate_address_p, %sstrict\n",
318 strict
? "" : "not ");
319 GO_DEBUG_RTX (xinsn
);
322 /* Check for constant before stripping off SUBREG, so that we don't
323 accept (subreg (const_int)) which will fail to reload. */
324 if (CONSTANT_ADDRESS_P (xinsn
)
325 && ! (iq2000_check_split (xinsn
, mode
))
326 && ! (GET_CODE (xinsn
) == CONST_INT
&& ! SMALL_INT (xinsn
)))
329 while (GET_CODE (xinsn
) == SUBREG
)
330 xinsn
= SUBREG_REG (xinsn
);
332 if (GET_CODE (xinsn
) == REG
333 && iq2000_reg_mode_ok_for_base_p (xinsn
, mode
, strict
))
336 if (GET_CODE (xinsn
) == LO_SUM
)
338 rtx xlow0
= XEXP (xinsn
, 0);
339 rtx xlow1
= XEXP (xinsn
, 1);
341 while (GET_CODE (xlow0
) == SUBREG
)
342 xlow0
= SUBREG_REG (xlow0
);
343 if (GET_CODE (xlow0
) == REG
344 && iq2000_reg_mode_ok_for_base_p (xlow0
, mode
, strict
)
345 && iq2000_check_split (xlow1
, mode
))
349 if (GET_CODE (xinsn
) == PLUS
)
351 rtx xplus0
= XEXP (xinsn
, 0);
352 rtx xplus1
= XEXP (xinsn
, 1);
356 while (GET_CODE (xplus0
) == SUBREG
)
357 xplus0
= SUBREG_REG (xplus0
);
358 code0
= GET_CODE (xplus0
);
360 while (GET_CODE (xplus1
) == SUBREG
)
361 xplus1
= SUBREG_REG (xplus1
);
362 code1
= GET_CODE (xplus1
);
365 && iq2000_reg_mode_ok_for_base_p (xplus0
, mode
, strict
))
367 if (code1
== CONST_INT
&& SMALL_INT (xplus1
)
368 && SMALL_INT_UNSIGNED (xplus1
) /* No negative offsets */)
373 if (TARGET_DEBUG_A_MODE
)
374 GO_PRINTF ("Not a machine_mode mode, legitimate address\n");
376 /* The address was not legitimate. */
380 /* Returns an operand string for the given instruction's delay slot,
381 after updating filled delay slot statistics.
383 We assume that operands[0] is the target register that is set.
385 In order to check the next insn, most of this functionality is moved
386 to FINAL_PRESCAN_INSN, and we just set the global variables that
390 iq2000_fill_delay_slot (const char *ret
, enum delay_type type
, rtx operands
[],
395 rtx_insn
*next_insn
= cur_insn
? NEXT_INSN (cur_insn
) : NULL
;
398 if (type
== DELAY_LOAD
|| type
== DELAY_FCMP
)
404 /* Make sure that we don't put nop's after labels. */
405 next_insn
= NEXT_INSN (cur_insn
);
406 while (next_insn
!= 0
407 && (NOTE_P (next_insn
) || LABEL_P (next_insn
)))
408 next_insn
= NEXT_INSN (next_insn
);
410 dslots_load_total
+= num_nops
;
411 if (TARGET_DEBUG_C_MODE
412 || type
== DELAY_NONE
416 || LABEL_P (next_insn
)
417 || (set_reg
= operands
[0]) == 0)
419 dslots_number_nops
= 0;
421 iq2000_load_reg2
= 0;
422 iq2000_load_reg3
= 0;
423 iq2000_load_reg4
= 0;
428 set_reg
= operands
[0];
432 while (GET_CODE (set_reg
) == SUBREG
)
433 set_reg
= SUBREG_REG (set_reg
);
435 mode
= GET_MODE (set_reg
);
436 dslots_number_nops
= num_nops
;
437 iq2000_load_reg
= set_reg
;
438 if (GET_MODE_SIZE (mode
)
439 > (unsigned) (UNITS_PER_WORD
))
440 iq2000_load_reg2
= gen_rtx_REG (SImode
, REGNO (set_reg
) + 1);
442 iq2000_load_reg2
= 0;
447 /* Determine whether a memory reference takes one (based off of the GP
448 pointer), two (normal), or three (label + reg) instructions, and bump the
449 appropriate counter for -mstats. */
452 iq2000_count_memory_refs (rtx op
, int num
)
456 rtx addr
, plus0
, plus1
;
457 enum rtx_code code0
, code1
;
460 if (TARGET_DEBUG_B_MODE
)
462 fprintf (stderr
, "\n========== iq2000_count_memory_refs:\n");
466 /* Skip MEM if passed, otherwise handle movsi of address. */
467 addr
= (GET_CODE (op
) != MEM
) ? op
: XEXP (op
, 0);
469 /* Loop, going through the address RTL. */
473 switch (GET_CODE (addr
))
481 plus0
= XEXP (addr
, 0);
482 plus1
= XEXP (addr
, 1);
483 code0
= GET_CODE (plus0
);
484 code1
= GET_CODE (plus1
);
494 if (code0
== CONST_INT
)
509 if (code1
== CONST_INT
)
516 if (code0
== SYMBOL_REF
|| code0
== LABEL_REF
|| code0
== CONST
)
523 if (code1
== SYMBOL_REF
|| code1
== LABEL_REF
|| code1
== CONST
)
533 n_words
= 2; /* Always 2 words. */
537 addr
= XEXP (addr
, 0);
542 n_words
= SYMBOL_REF_FLAG (addr
) ? 1 : 2;
554 n_words
+= additional
;
558 num_refs
[n_words
-1] += num
;
561 /* Abort after printing out a specific insn. */
564 abort_with_insn (rtx insn
, const char * reason
)
568 fancy_abort (__FILE__
, __LINE__
, __FUNCTION__
);
571 /* Return the appropriate instructions to move one operand to another. */
574 iq2000_move_1word (rtx operands
[], rtx_insn
*insn
, int unsignedp
)
577 rtx op0
= operands
[0];
578 rtx op1
= operands
[1];
579 enum rtx_code code0
= GET_CODE (op0
);
580 enum rtx_code code1
= GET_CODE (op1
);
581 machine_mode mode
= GET_MODE (op0
);
582 int subreg_offset0
= 0;
583 int subreg_offset1
= 0;
584 enum delay_type delay
= DELAY_NONE
;
586 while (code0
== SUBREG
)
588 subreg_offset0
+= subreg_regno_offset (REGNO (SUBREG_REG (op0
)),
589 GET_MODE (SUBREG_REG (op0
)),
592 op0
= SUBREG_REG (op0
);
593 code0
= GET_CODE (op0
);
596 while (code1
== SUBREG
)
598 subreg_offset1
+= subreg_regno_offset (REGNO (SUBREG_REG (op1
)),
599 GET_MODE (SUBREG_REG (op1
)),
602 op1
= SUBREG_REG (op1
);
603 code1
= GET_CODE (op1
);
606 /* For our purposes, a condition code mode is the same as SImode. */
612 int regno0
= REGNO (op0
) + subreg_offset0
;
616 int regno1
= REGNO (op1
) + subreg_offset1
;
618 /* Do not do anything for assigning a register to itself */
619 if (regno0
== regno1
)
622 else if (GP_REG_P (regno0
))
624 if (GP_REG_P (regno1
))
625 ret
= "or\t%0,%%0,%1";
630 else if (code1
== MEM
)
635 iq2000_count_memory_refs (op1
, 1);
637 if (GP_REG_P (regno0
))
639 /* For loads, use the mode of the memory item, instead of the
640 target, so zero/sign extend can use this code as well. */
641 switch (GET_MODE (op1
))
653 ret
= (unsignedp
) ? "lhu\t%0,%1" : "lh\t%0,%1";
656 ret
= (unsignedp
) ? "lbu\t%0,%1" : "lb\t%0,%1";
662 else if (code1
== CONST_INT
663 || (code1
== CONST_DOUBLE
664 && GET_MODE (op1
) == VOIDmode
))
666 if (code1
== CONST_DOUBLE
)
668 /* This can happen when storing constants into long long
669 bitfields. Just store the least significant word of
671 operands
[1] = op1
= GEN_INT (CONST_DOUBLE_LOW (op1
));
674 if (INTVAL (op1
) == 0)
676 if (GP_REG_P (regno0
))
677 ret
= "or\t%0,%%0,%z1";
679 else if (GP_REG_P (regno0
))
681 if (SMALL_INT_UNSIGNED (op1
))
682 ret
= "ori\t%0,%%0,%x1\t\t\t# %1";
683 else if (SMALL_INT (op1
))
684 ret
= "addiu\t%0,%%0,%1\t\t\t# %1";
686 ret
= "lui\t%0,%X1\t\t\t# %1\n\tori\t%0,%0,%x1";
690 else if (code1
== CONST_DOUBLE
&& mode
== SFmode
)
692 if (op1
== CONST0_RTX (SFmode
))
694 if (GP_REG_P (regno0
))
695 ret
= "or\t%0,%%0,%.";
705 else if (code1
== LABEL_REF
)
708 iq2000_count_memory_refs (op1
, 1);
713 else if (code1
== SYMBOL_REF
|| code1
== CONST
)
716 iq2000_count_memory_refs (op1
, 1);
721 else if (code1
== PLUS
)
723 rtx add_op0
= XEXP (op1
, 0);
724 rtx add_op1
= XEXP (op1
, 1);
726 if (GET_CODE (XEXP (op1
, 1)) == REG
727 && GET_CODE (XEXP (op1
, 0)) == CONST_INT
)
728 add_op0
= XEXP (op1
, 1), add_op1
= XEXP (op1
, 0);
730 operands
[2] = add_op0
;
731 operands
[3] = add_op1
;
732 ret
= "add%:\t%0,%2,%3";
735 else if (code1
== HIGH
)
737 operands
[1] = XEXP (op1
, 0);
738 ret
= "lui\t%0,%%hi(%1)";
742 else if (code0
== MEM
)
745 iq2000_count_memory_refs (op0
, 1);
749 int regno1
= REGNO (op1
) + subreg_offset1
;
751 if (GP_REG_P (regno1
))
755 case E_SFmode
: ret
= "sw\t%1,%0"; break;
756 case E_SImode
: ret
= "sw\t%1,%0"; break;
757 case E_HImode
: ret
= "sh\t%1,%0"; break;
758 case E_QImode
: ret
= "sb\t%1,%0"; break;
764 else if (code1
== CONST_INT
&& INTVAL (op1
) == 0)
768 case E_SFmode
: ret
= "sw\t%z1,%0"; break;
769 case E_SImode
: ret
= "sw\t%z1,%0"; break;
770 case E_HImode
: ret
= "sh\t%z1,%0"; break;
771 case E_QImode
: ret
= "sb\t%z1,%0"; break;
776 else if (code1
== CONST_DOUBLE
&& op1
== CONST0_RTX (mode
))
780 case E_SFmode
: ret
= "sw\t%.,%0"; break;
781 case E_SImode
: ret
= "sw\t%.,%0"; break;
782 case E_HImode
: ret
= "sh\t%.,%0"; break;
783 case E_QImode
: ret
= "sb\t%.,%0"; break;
791 abort_with_insn (insn
, "Bad move");
795 if (delay
!= DELAY_NONE
)
796 return iq2000_fill_delay_slot (ret
, delay
, operands
, insn
);
801 /* Provide the costs of an addressing mode that contains ADDR. */
804 iq2000_address_cost (rtx addr
, machine_mode mode
, addr_space_t as
,
807 switch (GET_CODE (addr
))
817 rtx offset
= const0_rtx
;
819 addr
= eliminate_constant_term (XEXP (addr
, 0), & offset
);
820 if (GET_CODE (addr
) == LABEL_REF
)
823 if (GET_CODE (addr
) != SYMBOL_REF
)
826 if (! SMALL_INT (offset
))
833 return SYMBOL_REF_FLAG (addr
) ? 1 : 2;
837 rtx plus0
= XEXP (addr
, 0);
838 rtx plus1
= XEXP (addr
, 1);
840 if (GET_CODE (plus0
) != REG
&& GET_CODE (plus1
) == REG
)
841 plus0
= XEXP (addr
, 1), plus1
= XEXP (addr
, 0);
843 if (GET_CODE (plus0
) != REG
)
846 switch (GET_CODE (plus1
))
849 return SMALL_INT (plus1
) ? 1 : 2;
856 return iq2000_address_cost (plus1
, mode
, as
, speed
) + 1;
870 /* Make normal rtx_code into something we can index from an array. */
872 static enum internal_test
873 map_test_to_internal_test (enum rtx_code test_code
)
875 enum internal_test test
= ITEST_MAX
;
879 case EQ
: test
= ITEST_EQ
; break;
880 case NE
: test
= ITEST_NE
; break;
881 case GT
: test
= ITEST_GT
; break;
882 case GE
: test
= ITEST_GE
; break;
883 case LT
: test
= ITEST_LT
; break;
884 case LE
: test
= ITEST_LE
; break;
885 case GTU
: test
= ITEST_GTU
; break;
886 case GEU
: test
= ITEST_GEU
; break;
887 case LTU
: test
= ITEST_LTU
; break;
888 case LEU
: test
= ITEST_LEU
; break;
895 /* Generate the code to do a TEST_CODE comparison on two integer values CMP0
896 and CMP1. P_INVERT is NULL or ptr if branch needs to reverse its test.
897 The return value RESULT is:
898 (reg:SI xx) The pseudo register the comparison is in
899 0 No register, generate a simple branch. */
902 gen_int_relational (enum rtx_code test_code
, rtx result
, rtx cmp0
, rtx cmp1
,
907 enum rtx_code test_code
; /* Code to use in instruction (LT vs. LTU). */
908 int const_low
; /* Low bound of constant we can accept. */
909 int const_high
; /* High bound of constant we can accept. */
910 int const_add
; /* Constant to add (convert LE -> LT). */
911 int reverse_regs
; /* Reverse registers in test. */
912 int invert_const
; /* != 0 if invert value if cmp1 is constant. */
913 int invert_reg
; /* != 0 if invert value if cmp1 is register. */
914 int unsignedp
; /* != 0 for unsigned comparisons. */
917 static struct cmp_info info
[ (int)ITEST_MAX
] =
919 { XOR
, 0, 65535, 0, 0, 0, 0, 0 }, /* EQ */
920 { XOR
, 0, 65535, 0, 0, 1, 1, 0 }, /* NE */
921 { LT
, -32769, 32766, 1, 1, 1, 0, 0 }, /* GT */
922 { LT
, -32768, 32767, 0, 0, 1, 1, 0 }, /* GE */
923 { LT
, -32768, 32767, 0, 0, 0, 0, 0 }, /* LT */
924 { LT
, -32769, 32766, 1, 1, 0, 1, 0 }, /* LE */
925 { LTU
, -32769, 32766, 1, 1, 1, 0, 1 }, /* GTU */
926 { LTU
, -32768, 32767, 0, 0, 1, 1, 1 }, /* GEU */
927 { LTU
, -32768, 32767, 0, 0, 0, 0, 1 }, /* LTU */
928 { LTU
, -32769, 32766, 1, 1, 0, 1, 1 }, /* LEU */
931 enum internal_test test
;
933 struct cmp_info
*p_info
;
940 test
= map_test_to_internal_test (test_code
);
941 gcc_assert (test
!= ITEST_MAX
);
943 p_info
= &info
[(int) test
];
944 eqne_p
= (p_info
->test_code
== XOR
);
946 mode
= GET_MODE (cmp0
);
947 if (mode
== VOIDmode
)
948 mode
= GET_MODE (cmp1
);
950 /* Eliminate simple branches. */
951 branch_p
= (result
== 0);
954 if (GET_CODE (cmp0
) == REG
|| GET_CODE (cmp0
) == SUBREG
)
956 /* Comparisons against zero are simple branches. */
957 if (GET_CODE (cmp1
) == CONST_INT
&& INTVAL (cmp1
) == 0)
960 /* Test for beq/bne. */
965 /* Allocate a pseudo to calculate the value in. */
966 result
= gen_reg_rtx (mode
);
969 /* Make sure we can handle any constants given to us. */
970 if (GET_CODE (cmp0
) == CONST_INT
)
971 cmp0
= force_reg (mode
, cmp0
);
973 if (GET_CODE (cmp1
) == CONST_INT
)
975 HOST_WIDE_INT value
= INTVAL (cmp1
);
977 if (value
< p_info
->const_low
978 || value
> p_info
->const_high
)
979 cmp1
= force_reg (mode
, cmp1
);
982 /* See if we need to invert the result. */
983 invert
= (GET_CODE (cmp1
) == CONST_INT
984 ? p_info
->invert_const
: p_info
->invert_reg
);
986 if (p_invert
!= (int *)0)
992 /* Comparison to constants, may involve adding 1 to change a LT into LE.
993 Comparison between two registers, may involve switching operands. */
994 if (GET_CODE (cmp1
) == CONST_INT
)
996 if (p_info
->const_add
!= 0)
998 HOST_WIDE_INT new_const
= INTVAL (cmp1
) + p_info
->const_add
;
1000 /* If modification of cmp1 caused overflow,
1001 we would get the wrong answer if we follow the usual path;
1002 thus, x > 0xffffffffU would turn into x > 0U. */
1003 if ((p_info
->unsignedp
1004 ? (unsigned HOST_WIDE_INT
) new_const
>
1005 (unsigned HOST_WIDE_INT
) INTVAL (cmp1
)
1006 : new_const
> INTVAL (cmp1
))
1007 != (p_info
->const_add
> 0))
1009 /* This test is always true, but if INVERT is true then
1010 the result of the test needs to be inverted so 0 should
1011 be returned instead. */
1012 emit_move_insn (result
, invert
? const0_rtx
: const_true_rtx
);
1016 cmp1
= GEN_INT (new_const
);
1020 else if (p_info
->reverse_regs
)
1027 if (test
== ITEST_NE
&& GET_CODE (cmp1
) == CONST_INT
&& INTVAL (cmp1
) == 0)
1031 reg
= (invert
|| eqne_p
) ? gen_reg_rtx (mode
) : result
;
1032 convert_move (reg
, gen_rtx_fmt_ee (p_info
->test_code
, mode
, cmp0
, cmp1
), 0);
1035 if (test
== ITEST_NE
)
1037 convert_move (result
, gen_rtx_GTU (mode
, reg
, const0_rtx
), 0);
1038 if (p_invert
!= NULL
)
1043 else if (test
== ITEST_EQ
)
1045 reg2
= invert
? gen_reg_rtx (mode
) : result
;
1046 convert_move (reg2
, gen_rtx_LTU (mode
, reg
, const1_rtx
), 0);
1055 convert_move (result
, gen_rtx_XOR (mode
, reg
, one
), 0);
1061 /* Emit the common code for doing conditional branches.
1062 operand[0] is the label to jump to.
1063 The comparison operands are saved away by cmp{si,di,sf,df}. */
1066 gen_conditional_branch (rtx operands
[], machine_mode mode
)
1068 enum rtx_code test_code
= GET_CODE (operands
[0]);
1069 rtx cmp0
= operands
[1];
1070 rtx cmp1
= operands
[2];
1076 reg
= gen_int_relational (test_code
, NULL_RTX
, cmp0
, cmp1
, &invert
);
1084 else if (GET_CODE (cmp1
) == CONST_INT
&& INTVAL (cmp1
) != 0)
1085 /* We don't want to build a comparison against a nonzero
1087 cmp1
= force_reg (mode
, cmp1
);
1089 /* Generate the branch. */
1090 label1
= gen_rtx_LABEL_REF (VOIDmode
, operands
[3]);
1099 emit_jump_insn (gen_rtx_SET (pc_rtx
,
1100 gen_rtx_IF_THEN_ELSE (VOIDmode
,
1101 gen_rtx_fmt_ee (test_code
,
1107 /* Initialize CUM for a function FNTYPE. */
1110 init_cumulative_args (CUMULATIVE_ARGS
*cum
, tree fntype
,
1111 rtx libname ATTRIBUTE_UNUSED
)
1113 static CUMULATIVE_ARGS zero_cum
;
1117 if (TARGET_DEBUG_D_MODE
)
1120 "\ninit_cumulative_args, fntype = 0x%.8lx", (long) fntype
);
1123 fputc ('\n', stderr
);
1127 tree ret_type
= TREE_TYPE (fntype
);
1129 fprintf (stderr
, ", fntype code = %s, ret code = %s\n",
1130 get_tree_code_name (TREE_CODE (fntype
)),
1131 get_tree_code_name (TREE_CODE (ret_type
)));
1137 /* Determine if this function has variable arguments. This is
1138 indicated by the last argument being 'void_type_mode' if there
1139 are no variable arguments. The standard IQ2000 calling sequence
1140 passes all arguments in the general purpose registers in this case. */
1142 for (param
= fntype
? TYPE_ARG_TYPES (fntype
) : 0;
1143 param
!= 0; param
= next_param
)
1145 next_param
= TREE_CHAIN (param
);
1146 if (next_param
== 0 && TREE_VALUE (param
) != void_type_node
)
1147 cum
->gp_reg_found
= 1;
1151 /* Advance the argument of type TYPE and mode MODE to the next argument
1155 iq2000_function_arg_advance (cumulative_args_t cum_v
, machine_mode mode
,
1156 const_tree type
, bool named
)
1158 CUMULATIVE_ARGS
*cum
= get_cumulative_args (cum_v
);
1160 if (TARGET_DEBUG_D_MODE
)
1163 "function_adv({gp reg found = %d, arg # = %2d, words = %2d}, %4s, ",
1164 cum
->gp_reg_found
, cum
->arg_number
, cum
->arg_words
,
1165 GET_MODE_NAME (mode
));
1166 fprintf (stderr
, "%p", (const void *) type
);
1167 fprintf (stderr
, ", %d )\n\n", named
);
1177 gcc_assert (GET_MODE_CLASS (mode
) == MODE_COMPLEX_INT
1178 || GET_MODE_CLASS (mode
) == MODE_COMPLEX_FLOAT
);
1180 cum
->gp_reg_found
= 1;
1181 cum
->arg_words
+= ((GET_MODE_SIZE (mode
) + UNITS_PER_WORD
- 1)
1186 cum
->gp_reg_found
= 1;
1187 cum
->arg_words
+= ((int_size_in_bytes (type
) + UNITS_PER_WORD
- 1)
1193 if (! cum
->gp_reg_found
&& cum
->arg_number
<= 2)
1194 cum
->fp_code
+= 1 << ((cum
->arg_number
- 1) * 2);
1198 cum
->arg_words
+= 2;
1199 if (! cum
->gp_reg_found
&& cum
->arg_number
<= 2)
1200 cum
->fp_code
+= 2 << ((cum
->arg_number
- 1) * 2);
1204 cum
->gp_reg_found
= 1;
1205 cum
->arg_words
+= 2;
1209 cum
->gp_reg_found
= 1;
1210 cum
->arg_words
+= 4;
1216 cum
->gp_reg_found
= 1;
1222 /* Return an RTL expression containing the register for the given mode MODE
1223 and type TYPE in CUM, or 0 if the argument is to be passed on the stack. */
1226 iq2000_function_arg (cumulative_args_t cum_v
, machine_mode mode
,
1227 const_tree type
, bool named
)
1229 CUMULATIVE_ARGS
*cum
= get_cumulative_args (cum_v
);
1233 unsigned int *arg_words
= &cum
->arg_words
;
1234 int struct_p
= (type
!= 0
1235 && (TREE_CODE (type
) == RECORD_TYPE
1236 || TREE_CODE (type
) == UNION_TYPE
1237 || TREE_CODE (type
) == QUAL_UNION_TYPE
));
1239 if (TARGET_DEBUG_D_MODE
)
1242 "function_arg( {gp reg found = %d, arg # = %2d, words = %2d}, %4s, ",
1243 cum
->gp_reg_found
, cum
->arg_number
, cum
->arg_words
,
1244 GET_MODE_NAME (mode
));
1245 fprintf (stderr
, "%p", (const void *) type
);
1246 fprintf (stderr
, ", %d ) = ", named
);
1250 cum
->last_arg_fp
= 0;
1254 regbase
= GP_ARG_FIRST
;
1258 cum
->arg_words
+= cum
->arg_words
& 1;
1260 regbase
= GP_ARG_FIRST
;
1264 gcc_assert (GET_MODE_CLASS (mode
) == MODE_COMPLEX_INT
1265 || GET_MODE_CLASS (mode
) == MODE_COMPLEX_FLOAT
);
1269 if (type
!= NULL_TREE
&& TYPE_ALIGN (type
) > (unsigned) BITS_PER_WORD
)
1270 cum
->arg_words
+= (cum
->arg_words
& 1);
1271 regbase
= GP_ARG_FIRST
;
1278 regbase
= GP_ARG_FIRST
;
1282 cum
->arg_words
+= (cum
->arg_words
& 1);
1283 regbase
= GP_ARG_FIRST
;
1287 cum
->arg_words
+= (cum
->arg_words
& 3);
1288 regbase
= GP_ARG_FIRST
;
1292 if (*arg_words
>= (unsigned) MAX_ARGS_IN_REGISTERS
)
1294 if (TARGET_DEBUG_D_MODE
)
1295 fprintf (stderr
, "<stack>%s\n", struct_p
? ", [struct]" : "");
1301 gcc_assert (regbase
!= -1);
1303 if (! type
|| TREE_CODE (type
) != RECORD_TYPE
1304 || ! named
|| ! TYPE_SIZE_UNIT (type
)
1305 || ! tree_fits_uhwi_p (TYPE_SIZE_UNIT (type
)))
1306 ret
= gen_rtx_REG (mode
, regbase
+ *arg_words
+ bias
);
1311 for (field
= TYPE_FIELDS (type
); field
; field
= DECL_CHAIN (field
))
1312 if (TREE_CODE (field
) == FIELD_DECL
1313 && TREE_CODE (TREE_TYPE (field
)) == REAL_TYPE
1314 && TYPE_PRECISION (TREE_TYPE (field
)) == BITS_PER_WORD
1315 && tree_fits_shwi_p (bit_position (field
))
1316 && int_bit_position (field
) % BITS_PER_WORD
== 0)
1319 /* If the whole struct fits a DFmode register,
1320 we don't need the PARALLEL. */
1321 if (! field
|| mode
== DFmode
)
1322 ret
= gen_rtx_REG (mode
, regbase
+ *arg_words
+ bias
);
1325 unsigned int chunks
;
1326 HOST_WIDE_INT bitpos
;
1330 /* ??? If this is a packed structure, then the last hunk won't
1333 = tree_to_uhwi (TYPE_SIZE_UNIT (type
)) / UNITS_PER_WORD
;
1334 if (chunks
+ *arg_words
+ bias
> (unsigned) MAX_ARGS_IN_REGISTERS
)
1335 chunks
= MAX_ARGS_IN_REGISTERS
- *arg_words
- bias
;
1337 /* Assign_parms checks the mode of ENTRY_PARM, so we must
1338 use the actual mode here. */
1339 ret
= gen_rtx_PARALLEL (mode
, rtvec_alloc (chunks
));
1342 regno
= regbase
+ *arg_words
+ bias
;
1343 field
= TYPE_FIELDS (type
);
1344 for (i
= 0; i
< chunks
; i
++)
1348 for (; field
; field
= DECL_CHAIN (field
))
1349 if (TREE_CODE (field
) == FIELD_DECL
1350 && int_bit_position (field
) >= bitpos
)
1354 && int_bit_position (field
) == bitpos
1355 && TREE_CODE (TREE_TYPE (field
)) == REAL_TYPE
1356 && TYPE_PRECISION (TREE_TYPE (field
)) == BITS_PER_WORD
)
1357 reg
= gen_rtx_REG (DFmode
, regno
++);
1359 reg
= gen_rtx_REG (word_mode
, regno
);
1362 = gen_rtx_EXPR_LIST (VOIDmode
, reg
,
1363 GEN_INT (bitpos
/ BITS_PER_UNIT
));
1371 if (TARGET_DEBUG_D_MODE
)
1372 fprintf (stderr
, "%s%s\n", reg_names
[regbase
+ *arg_words
+ bias
],
1373 struct_p
? ", [struct]" : "");
1376 /* We will be called with a mode of VOIDmode after the last argument
1377 has been seen. Whatever we return will be passed to the call
1378 insn. If we need any shifts for small structures, return them in
1380 if (mode
== VOIDmode
)
1382 if (cum
->num_adjusts
> 0)
1383 ret
= gen_rtx_PARALLEL ((machine_mode
) cum
->fp_code
,
1384 gen_rtvec_v (cum
->num_adjusts
, cum
->adjust
));
1390 /* Implement TARGET_FUNCTION_ARG_PADDING. */
1392 static pad_direction
1393 iq2000_function_arg_padding (machine_mode mode
, const_tree type
)
1395 return (! BYTES_BIG_ENDIAN
1399 && TREE_CODE (TYPE_SIZE (type
)) == INTEGER_CST
1400 && int_size_in_bytes (type
) < (PARM_BOUNDARY
/ BITS_PER_UNIT
))
1401 : (GET_MODE_BITSIZE (mode
) < PARM_BOUNDARY
1402 && GET_MODE_CLASS (mode
) == MODE_INT
))
1403 ? PAD_DOWNWARD
: PAD_UPWARD
));
1407 iq2000_function_arg_boundary (machine_mode mode
, const_tree type
)
1409 return (type
!= NULL_TREE
1410 ? (TYPE_ALIGN (type
) <= PARM_BOUNDARY
1412 : TYPE_ALIGN (type
))
1413 : (GET_MODE_ALIGNMENT (mode
) <= PARM_BOUNDARY
1415 : GET_MODE_ALIGNMENT (mode
)));
1419 iq2000_arg_partial_bytes (cumulative_args_t cum_v
, machine_mode mode
,
1420 tree type ATTRIBUTE_UNUSED
,
1421 bool named ATTRIBUTE_UNUSED
)
1423 CUMULATIVE_ARGS
*cum
= get_cumulative_args (cum_v
);
1425 if (mode
== DImode
&& cum
->arg_words
== MAX_ARGS_IN_REGISTERS
- 1)
1427 if (TARGET_DEBUG_D_MODE
)
1428 fprintf (stderr
, "iq2000_arg_partial_bytes=%d\n", UNITS_PER_WORD
);
1429 return UNITS_PER_WORD
;
1435 /* Implement va_start. */
1438 iq2000_va_start (tree valist
, rtx nextarg
)
1441 /* Find out how many non-float named formals. */
1442 int gpr_save_area_size
;
1443 /* Note UNITS_PER_WORD is 4 bytes. */
1444 int_arg_words
= crtl
->args
.info
.arg_words
;
1446 if (int_arg_words
< 8 )
1447 /* Adjust for the prologue's economy measure. */
1448 gpr_save_area_size
= (8 - int_arg_words
) * UNITS_PER_WORD
;
1450 gpr_save_area_size
= 0;
1452 /* Everything is in the GPR save area, or in the overflow
1453 area which is contiguous with it. */
1454 nextarg
= plus_constant (Pmode
, nextarg
, - gpr_save_area_size
);
1455 std_expand_builtin_va_start (valist
, nextarg
);
1458 /* Allocate a chunk of memory for per-function machine-dependent data. */
1460 static struct machine_function
*
1461 iq2000_init_machine_status (void)
1463 return ggc_cleared_alloc
<machine_function
> ();
1466 /* Detect any conflicts in the switches. */
1469 iq2000_option_override (void)
1471 target_flags
&= ~MASK_GPOPT
;
1473 iq2000_isa
= IQ2000_ISA_DEFAULT
;
1475 /* Identify the processor type. */
1477 iq2000_print_operand_punct
['?'] = 1;
1478 iq2000_print_operand_punct
['#'] = 1;
1479 iq2000_print_operand_punct
['&'] = 1;
1480 iq2000_print_operand_punct
['!'] = 1;
1481 iq2000_print_operand_punct
['*'] = 1;
1482 iq2000_print_operand_punct
['@'] = 1;
1483 iq2000_print_operand_punct
['.'] = 1;
1484 iq2000_print_operand_punct
['('] = 1;
1485 iq2000_print_operand_punct
[')'] = 1;
1486 iq2000_print_operand_punct
['['] = 1;
1487 iq2000_print_operand_punct
[']'] = 1;
1488 iq2000_print_operand_punct
['<'] = 1;
1489 iq2000_print_operand_punct
['>'] = 1;
1490 iq2000_print_operand_punct
['{'] = 1;
1491 iq2000_print_operand_punct
['}'] = 1;
1492 iq2000_print_operand_punct
['^'] = 1;
1493 iq2000_print_operand_punct
['$'] = 1;
1494 iq2000_print_operand_punct
['+'] = 1;
1495 iq2000_print_operand_punct
['~'] = 1;
1497 /* Save GPR registers in word_mode sized hunks. word_mode hasn't been
1498 initialized yet, so we can't use that here. */
1501 /* Function to allocate machine-dependent function status. */
1502 init_machine_status
= iq2000_init_machine_status
;
1505 /* The arg pointer (which is eliminated) points to the virtual frame pointer,
1506 while the frame pointer (which may be eliminated) points to the stack
1507 pointer after the initial adjustments. */
1510 iq2000_debugger_offset (rtx addr
, HOST_WIDE_INT offset
)
1512 rtx offset2
= const0_rtx
;
1513 rtx reg
= eliminate_constant_term (addr
, & offset2
);
1516 offset
= INTVAL (offset2
);
1518 if (reg
== stack_pointer_rtx
|| reg
== frame_pointer_rtx
1519 || reg
== hard_frame_pointer_rtx
)
1521 HOST_WIDE_INT frame_size
= (!cfun
->machine
->initialized
)
1522 ? compute_frame_size (get_frame_size ())
1523 : cfun
->machine
->total_size
;
1525 offset
= offset
- frame_size
;
1531 /* If defined, a C statement to be executed just prior to the output of
1532 assembler code for INSN, to modify the extracted operands so they will be
1535 Here the argument OPVEC is the vector containing the operands extracted
1536 from INSN, and NOPERANDS is the number of elements of the vector which
1537 contain meaningful data for this insn. The contents of this vector are
1538 what will be used to convert the insn template into assembler code, so you
1539 can change the assembler output by changing the contents of the vector.
1541 We use it to check if the current insn needs a nop in front of it because
1542 of load delays, and also to update the delay slot statistics. */
1545 final_prescan_insn (rtx_insn
*insn
, rtx opvec
[] ATTRIBUTE_UNUSED
,
1546 int noperands ATTRIBUTE_UNUSED
)
1548 if (dslots_number_nops
> 0)
1550 rtx pattern
= PATTERN (insn
);
1551 int length
= get_attr_length (insn
);
1553 /* Do we need to emit a NOP? */
1555 || (iq2000_load_reg
!= 0 && reg_mentioned_p (iq2000_load_reg
, pattern
))
1556 || (iq2000_load_reg2
!= 0 && reg_mentioned_p (iq2000_load_reg2
, pattern
))
1557 || (iq2000_load_reg3
!= 0 && reg_mentioned_p (iq2000_load_reg3
, pattern
))
1558 || (iq2000_load_reg4
!= 0
1559 && reg_mentioned_p (iq2000_load_reg4
, pattern
)))
1560 fputs ("\tnop\n", asm_out_file
);
1563 dslots_load_filled
++;
1565 while (--dslots_number_nops
> 0)
1566 fputs ("\tnop\n", asm_out_file
);
1568 iq2000_load_reg
= 0;
1569 iq2000_load_reg2
= 0;
1570 iq2000_load_reg3
= 0;
1571 iq2000_load_reg4
= 0;
1576 || (GET_CODE (PATTERN (insn
)) == RETURN
))
1577 && NEXT_INSN (PREV_INSN (insn
)) == insn
)
1579 rtx_insn
*tmp
= insn
;
1580 while (NEXT_INSN (tmp
)
1581 && NOTE_P (NEXT_INSN (tmp
))
1582 && NOTE_KIND (NEXT_INSN (tmp
)) == NOTE_INSN_CALL_ARG_LOCATION
)
1583 tmp
= NEXT_INSN (tmp
);
1585 rtx_insn
*nop_insn
= emit_insn_after (gen_nop (), tmp
);
1586 INSN_ADDRESSES_NEW (nop_insn
, -1);
1590 && (JUMP_P (insn
) || CALL_P (insn
)))
1591 dslots_jump_total
++;
1594 /* Return the bytes needed to compute the frame pointer from the current
1595 stack pointer where SIZE is the # of var. bytes allocated.
1597 IQ2000 stack frames look like:
1599 Before call After call
1600 +-----------------------+ +-----------------------+
1603 | caller's temps. | | caller's temps. |
1605 +-----------------------+ +-----------------------+
1607 | arguments on stack. | | arguments on stack. |
1609 +-----------------------+ +-----------------------+
1610 | 4 words to save | | 4 words to save |
1611 | arguments passed | | arguments passed |
1612 | in registers, even | | in registers, even |
1613 SP->| if not passed. | VFP->| if not passed. |
1614 +-----------------------+ +-----------------------+
1616 | fp register save |
1618 +-----------------------+
1620 | gp register save |
1622 +-----------------------+
1626 +-----------------------+
1628 | alloca allocations |
1630 +-----------------------+
1632 | GP save for V.4 abi |
1634 +-----------------------+
1636 | arguments on stack |
1638 +-----------------------+
1640 | arguments passed |
1641 | in registers, even |
1642 low SP->| if not passed. |
1643 memory +-----------------------+ */
1646 compute_frame_size (HOST_WIDE_INT size
)
1649 HOST_WIDE_INT total_size
; /* # bytes that the entire frame takes up. */
1650 HOST_WIDE_INT var_size
; /* # bytes that variables take up. */
1651 HOST_WIDE_INT args_size
; /* # bytes that outgoing arguments take up. */
1652 HOST_WIDE_INT extra_size
; /* # extra bytes. */
1653 HOST_WIDE_INT gp_reg_rounded
; /* # bytes needed to store gp after rounding. */
1654 HOST_WIDE_INT gp_reg_size
; /* # bytes needed to store gp regs. */
1655 HOST_WIDE_INT fp_reg_size
; /* # bytes needed to store fp regs. */
1656 long mask
; /* mask of saved gp registers. */
1661 extra_size
= IQ2000_STACK_ALIGN ((0));
1662 var_size
= IQ2000_STACK_ALIGN (size
);
1663 args_size
= IQ2000_STACK_ALIGN (crtl
->outgoing_args_size
);
1665 /* If a function dynamically allocates the stack and
1666 has 0 for STACK_DYNAMIC_OFFSET then allocate some stack space. */
1667 if (args_size
== 0 && cfun
->calls_alloca
)
1668 args_size
= 4 * UNITS_PER_WORD
;
1670 total_size
= var_size
+ args_size
+ extra_size
;
1672 /* Calculate space needed for gp registers. */
1673 for (regno
= GP_REG_FIRST
; regno
<= GP_REG_LAST
; regno
++)
1675 if (MUST_SAVE_REGISTER (regno
))
1677 gp_reg_size
+= GET_MODE_SIZE (gpr_mode
);
1678 mask
|= 1L << (regno
- GP_REG_FIRST
);
1682 /* We need to restore these for the handler. */
1683 if (crtl
->calls_eh_return
)
1689 regno
= EH_RETURN_DATA_REGNO (i
);
1690 if (regno
== (int) INVALID_REGNUM
)
1692 gp_reg_size
+= GET_MODE_SIZE (gpr_mode
);
1693 mask
|= 1L << (regno
- GP_REG_FIRST
);
1697 gp_reg_rounded
= IQ2000_STACK_ALIGN (gp_reg_size
);
1698 total_size
+= gp_reg_rounded
+ IQ2000_STACK_ALIGN (fp_reg_size
);
1700 /* The gp reg is caller saved, so there is no need for leaf routines
1701 (total_size == extra_size) to save the gp reg. */
1702 if (total_size
== extra_size
1704 total_size
= extra_size
= 0;
1706 total_size
+= IQ2000_STACK_ALIGN (crtl
->args
.pretend_args_size
);
1708 /* Save other computed information. */
1709 cfun
->machine
->total_size
= total_size
;
1710 cfun
->machine
->var_size
= var_size
;
1711 cfun
->machine
->args_size
= args_size
;
1712 cfun
->machine
->extra_size
= extra_size
;
1713 cfun
->machine
->gp_reg_size
= gp_reg_size
;
1714 cfun
->machine
->fp_reg_size
= fp_reg_size
;
1715 cfun
->machine
->mask
= mask
;
1716 cfun
->machine
->initialized
= reload_completed
;
1717 cfun
->machine
->num_gp
= gp_reg_size
/ UNITS_PER_WORD
;
1721 unsigned long offset
;
1723 offset
= (args_size
+ extra_size
+ var_size
1724 + gp_reg_size
- GET_MODE_SIZE (gpr_mode
));
1726 cfun
->machine
->gp_sp_offset
= offset
;
1727 cfun
->machine
->gp_save_offset
= offset
- total_size
;
1731 cfun
->machine
->gp_sp_offset
= 0;
1732 cfun
->machine
->gp_save_offset
= 0;
1735 cfun
->machine
->fp_sp_offset
= 0;
1736 cfun
->machine
->fp_save_offset
= 0;
1738 /* Ok, we're done. */
1743 /* We can always eliminate to the frame pointer. We can eliminate to the
1744 stack pointer unless a frame pointer is needed. */
1747 iq2000_can_eliminate (const int from
, const int to
)
1749 return (from
== RETURN_ADDRESS_POINTER_REGNUM
1750 && (! leaf_function_p ()
1751 || (to
== GP_REG_FIRST
+ 31 && leaf_function_p ())))
1752 || (from
!= RETURN_ADDRESS_POINTER_REGNUM
1753 && (to
== HARD_FRAME_POINTER_REGNUM
1754 || (to
== STACK_POINTER_REGNUM
1755 && ! frame_pointer_needed
)));
1758 /* Implement INITIAL_ELIMINATION_OFFSET. FROM is either the frame
1759 pointer, argument pointer, or return address pointer. TO is either
1760 the stack pointer or hard frame pointer. */
1763 iq2000_initial_elimination_offset (int from
, int to ATTRIBUTE_UNUSED
)
1767 compute_frame_size (get_frame_size ());
1768 if ((from
) == FRAME_POINTER_REGNUM
)
1770 else if ((from
) == ARG_POINTER_REGNUM
)
1771 (offset
) = (cfun
->machine
->total_size
);
1772 else if ((from
) == RETURN_ADDRESS_POINTER_REGNUM
)
1774 if (leaf_function_p ())
1776 else (offset
) = cfun
->machine
->gp_sp_offset
1777 + ((UNITS_PER_WORD
- (POINTER_SIZE
/ BITS_PER_UNIT
))
1778 * (BYTES_BIG_ENDIAN
!= 0));
1786 /* Common code to emit the insns (or to write the instructions to a file)
1787 to save/restore registers.
1788 Other parts of the code assume that IQ2000_TEMP1_REGNUM (aka large_reg)
1789 is not modified within save_restore_insns. */
1791 #define BITSET_P(VALUE,BIT) (((VALUE) & (1L << (BIT))) != 0)
1793 /* Emit instructions to load the value (SP + OFFSET) into IQ2000_TEMP2_REGNUM
1794 and return an rtl expression for the register. Write the assembly
1795 instructions directly to FILE if it is not null, otherwise emit them as
1798 This function is a subroutine of save_restore_insns. It is used when
1799 OFFSET is too large to add in a single instruction. */
1802 iq2000_add_large_offset_to_sp (HOST_WIDE_INT offset
)
1804 rtx reg
= gen_rtx_REG (Pmode
, IQ2000_TEMP2_REGNUM
);
1805 rtx offset_rtx
= GEN_INT (offset
);
1807 emit_move_insn (reg
, offset_rtx
);
1808 emit_insn (gen_addsi3 (reg
, reg
, stack_pointer_rtx
));
1812 /* Make INSN frame related and note that it performs the frame-related
1813 operation DWARF_PATTERN. */
1816 iq2000_annotate_frame_insn (rtx_insn
*insn
, rtx dwarf_pattern
)
1818 RTX_FRAME_RELATED_P (insn
) = 1;
1819 REG_NOTES (insn
) = alloc_EXPR_LIST (REG_FRAME_RELATED_EXPR
,
1824 /* Emit a move instruction that stores REG in MEM. Make the instruction
1825 frame related and note that it stores REG at (SP + OFFSET). */
1828 iq2000_emit_frame_related_store (rtx mem
, rtx reg
, HOST_WIDE_INT offset
)
1830 rtx dwarf_address
= plus_constant (Pmode
, stack_pointer_rtx
, offset
);
1831 rtx dwarf_mem
= gen_rtx_MEM (GET_MODE (reg
), dwarf_address
);
1833 iq2000_annotate_frame_insn (emit_move_insn (mem
, reg
),
1834 gen_rtx_SET (dwarf_mem
, reg
));
1837 /* Emit instructions to save/restore registers, as determined by STORE_P. */
1840 save_restore_insns (int store_p
)
1842 long mask
= cfun
->machine
->mask
;
1845 HOST_WIDE_INT base_offset
;
1846 HOST_WIDE_INT gp_offset
;
1847 HOST_WIDE_INT end_offset
;
1849 gcc_assert (!frame_pointer_needed
1850 || BITSET_P (mask
, HARD_FRAME_POINTER_REGNUM
- GP_REG_FIRST
));
1854 base_reg_rtx
= 0, base_offset
= 0;
1858 /* Save registers starting from high to low. The debuggers prefer at least
1859 the return register be stored at func+4, and also it allows us not to
1860 need a nop in the epilog if at least one register is reloaded in
1861 addition to return address. */
1863 /* Save GP registers if needed. */
1864 /* Pick which pointer to use as a base register. For small frames, just
1865 use the stack pointer. Otherwise, use a temporary register. Save 2
1866 cycles if the save area is near the end of a large frame, by reusing
1867 the constant created in the prologue/epilogue to adjust the stack
1870 gp_offset
= cfun
->machine
->gp_sp_offset
;
1872 = gp_offset
- (cfun
->machine
->gp_reg_size
1873 - GET_MODE_SIZE (gpr_mode
));
1875 if (gp_offset
< 0 || end_offset
< 0)
1877 ("gp_offset (%ld) or end_offset (%ld) is less than zero",
1878 (long) gp_offset
, (long) end_offset
);
1880 else if (gp_offset
< 32768)
1881 base_reg_rtx
= stack_pointer_rtx
, base_offset
= 0;
1885 int reg_save_count
= 0;
1887 for (regno
= GP_REG_LAST
; regno
>= GP_REG_FIRST
; regno
--)
1888 if (BITSET_P (mask
, regno
- GP_REG_FIRST
)) reg_save_count
+= 1;
1889 base_offset
= gp_offset
- ((reg_save_count
- 1) * 4);
1890 base_reg_rtx
= iq2000_add_large_offset_to_sp (base_offset
);
1893 for (regno
= GP_REG_LAST
; regno
>= GP_REG_FIRST
; regno
--)
1895 if (BITSET_P (mask
, regno
- GP_REG_FIRST
))
1899 = gen_rtx_MEM (gpr_mode
,
1900 gen_rtx_PLUS (Pmode
, base_reg_rtx
,
1901 GEN_INT (gp_offset
- base_offset
)));
1903 reg_rtx
= gen_rtx_REG (gpr_mode
, regno
);
1906 iq2000_emit_frame_related_store (mem_rtx
, reg_rtx
, gp_offset
);
1909 emit_move_insn (reg_rtx
, mem_rtx
);
1911 gp_offset
-= GET_MODE_SIZE (gpr_mode
);
1916 /* Expand the prologue into a bunch of separate insns. */
1919 iq2000_expand_prologue (void)
1922 HOST_WIDE_INT tsize
;
1923 int last_arg_is_vararg_marker
= 0;
1924 tree fndecl
= current_function_decl
;
1925 tree fntype
= TREE_TYPE (fndecl
);
1926 tree fnargs
= DECL_ARGUMENTS (fndecl
);
1931 CUMULATIVE_ARGS args_so_far_v
;
1932 cumulative_args_t args_so_far
;
1933 int store_args_on_stack
= (iq2000_can_use_return_insn ());
1935 /* If struct value address is treated as the first argument. */
1936 if (aggregate_value_p (DECL_RESULT (fndecl
), fndecl
)
1937 && !cfun
->returns_pcc_struct
1938 && targetm
.calls
.struct_value_rtx (TREE_TYPE (fndecl
), 1) == 0)
1940 tree type
= build_pointer_type (fntype
);
1941 tree function_result_decl
= build_decl (BUILTINS_LOCATION
,
1942 PARM_DECL
, NULL_TREE
, type
);
1944 DECL_ARG_TYPE (function_result_decl
) = type
;
1945 DECL_CHAIN (function_result_decl
) = fnargs
;
1946 fnargs
= function_result_decl
;
1949 /* For arguments passed in registers, find the register number
1950 of the first argument in the variable part of the argument list,
1951 otherwise GP_ARG_LAST+1. Note also if the last argument is
1952 the varargs special argument, and treat it as part of the
1955 This is only needed if store_args_on_stack is true. */
1956 INIT_CUMULATIVE_ARGS (args_so_far_v
, fntype
, NULL_RTX
, 0, 0);
1957 args_so_far
= pack_cumulative_args (&args_so_far_v
);
1958 regno
= GP_ARG_FIRST
;
1960 for (cur_arg
= fnargs
; cur_arg
!= 0; cur_arg
= next_arg
)
1962 tree passed_type
= DECL_ARG_TYPE (cur_arg
);
1963 machine_mode passed_mode
= TYPE_MODE (passed_type
);
1966 if (TREE_ADDRESSABLE (passed_type
))
1968 passed_type
= build_pointer_type (passed_type
);
1969 passed_mode
= Pmode
;
1972 entry_parm
= iq2000_function_arg (args_so_far
, passed_mode
,
1975 iq2000_function_arg_advance (args_so_far
, passed_mode
,
1977 next_arg
= DECL_CHAIN (cur_arg
);
1979 if (entry_parm
&& store_args_on_stack
)
1982 && DECL_NAME (cur_arg
)
1983 && ((0 == strcmp (IDENTIFIER_POINTER (DECL_NAME (cur_arg
)),
1984 "__builtin_va_alist"))
1985 || (0 == strcmp (IDENTIFIER_POINTER (DECL_NAME (cur_arg
)),
1988 last_arg_is_vararg_marker
= 1;
1995 gcc_assert (GET_CODE (entry_parm
) == REG
);
1997 /* Passed in a register, so will get homed automatically. */
1998 if (GET_MODE (entry_parm
) == BLKmode
)
1999 words
= (int_size_in_bytes (passed_type
) + 3) / 4;
2001 words
= (GET_MODE_SIZE (GET_MODE (entry_parm
)) + 3) / 4;
2003 regno
= REGNO (entry_parm
) + words
- 1;
2008 regno
= GP_ARG_LAST
+1;
2013 /* In order to pass small structures by value in registers we need to
2014 shift the value into the high part of the register.
2015 iq2000_unction_arg has encoded a PARALLEL rtx, holding a vector of
2016 adjustments to be made as the next_arg_reg variable, so we split up
2017 the insns, and emit them separately. */
2018 next_arg_reg
= iq2000_function_arg (args_so_far
, VOIDmode
,
2019 void_type_node
, true);
2020 if (next_arg_reg
!= 0 && GET_CODE (next_arg_reg
) == PARALLEL
)
2022 rtvec adjust
= XVEC (next_arg_reg
, 0);
2023 int num
= GET_NUM_ELEM (adjust
);
2025 for (i
= 0; i
< num
; i
++)
2029 pattern
= RTVEC_ELT (adjust
, i
);
2030 if (GET_CODE (pattern
) != SET
2031 || GET_CODE (SET_SRC (pattern
)) != ASHIFT
)
2032 abort_with_insn (pattern
, "Insn is not a shift");
2033 PUT_CODE (SET_SRC (pattern
), ASHIFTRT
);
2035 emit_insn (pattern
);
2039 tsize
= compute_frame_size (get_frame_size ());
2041 /* If this function is a varargs function, store any registers that
2042 would normally hold arguments ($4 - $7) on the stack. */
2043 if (store_args_on_stack
2044 && (stdarg_p (fntype
)
2045 || last_arg_is_vararg_marker
))
2047 int offset
= (regno
- GP_ARG_FIRST
) * UNITS_PER_WORD
;
2048 rtx ptr
= stack_pointer_rtx
;
2050 for (; regno
<= GP_ARG_LAST
; regno
++)
2053 ptr
= gen_rtx_PLUS (Pmode
, stack_pointer_rtx
, GEN_INT (offset
));
2054 emit_move_insn (gen_rtx_MEM (gpr_mode
, ptr
),
2055 gen_rtx_REG (gpr_mode
, regno
));
2057 offset
+= GET_MODE_SIZE (gpr_mode
);
2063 rtx tsize_rtx
= GEN_INT (tsize
);
2064 rtx adjustment_rtx
, dwarf_pattern
;
2069 adjustment_rtx
= gen_rtx_REG (Pmode
, IQ2000_TEMP1_REGNUM
);
2070 emit_move_insn (adjustment_rtx
, tsize_rtx
);
2073 adjustment_rtx
= tsize_rtx
;
2075 insn
= emit_insn (gen_subsi3 (stack_pointer_rtx
, stack_pointer_rtx
,
2078 dwarf_pattern
= gen_rtx_SET (stack_pointer_rtx
,
2079 plus_constant (Pmode
, stack_pointer_rtx
,
2082 iq2000_annotate_frame_insn (insn
, dwarf_pattern
);
2084 save_restore_insns (1);
2086 if (frame_pointer_needed
)
2090 insn
= emit_insn (gen_movsi (hard_frame_pointer_rtx
,
2091 stack_pointer_rtx
));
2094 RTX_FRAME_RELATED_P (insn
) = 1;
2098 if (flag_stack_usage_info
)
2099 current_function_static_stack_size
= cfun
->machine
->total_size
;
2101 emit_insn (gen_blockage ());
2104 /* Expand the epilogue into a bunch of separate insns. */
2107 iq2000_expand_epilogue (void)
2109 HOST_WIDE_INT tsize
= cfun
->machine
->total_size
;
2110 rtx tsize_rtx
= GEN_INT (tsize
);
2111 rtx tmp_rtx
= (rtx
)0;
2113 if (iq2000_can_use_return_insn ())
2115 emit_jump_insn (gen_return ());
2121 tmp_rtx
= gen_rtx_REG (Pmode
, IQ2000_TEMP1_REGNUM
);
2122 emit_move_insn (tmp_rtx
, tsize_rtx
);
2123 tsize_rtx
= tmp_rtx
;
2128 if (frame_pointer_needed
)
2130 emit_insn (gen_blockage ());
2132 emit_insn (gen_movsi (stack_pointer_rtx
, hard_frame_pointer_rtx
));
2135 save_restore_insns (0);
2137 if (crtl
->calls_eh_return
)
2139 rtx eh_ofs
= EH_RETURN_STACKADJ_RTX
;
2140 emit_insn (gen_addsi3 (eh_ofs
, eh_ofs
, tsize_rtx
));
2144 emit_insn (gen_blockage ());
2146 if (tsize
!= 0 || crtl
->calls_eh_return
)
2148 emit_insn (gen_addsi3 (stack_pointer_rtx
, stack_pointer_rtx
,
2153 if (crtl
->calls_eh_return
)
2155 /* Perform the additional bump for __throw. */
2156 emit_move_insn (gen_rtx_REG (Pmode
, HARD_FRAME_POINTER_REGNUM
),
2158 emit_use (gen_rtx_REG (Pmode
, HARD_FRAME_POINTER_REGNUM
));
2159 emit_jump_insn (gen_eh_return_internal ());
2162 emit_jump_insn (gen_return_internal (gen_rtx_REG (Pmode
,
2163 GP_REG_FIRST
+ 31)));
2167 iq2000_expand_eh_return (rtx address
)
2169 HOST_WIDE_INT gp_offset
= cfun
->machine
->gp_sp_offset
;
2172 scratch
= plus_constant (Pmode
, stack_pointer_rtx
, gp_offset
);
2173 emit_move_insn (gen_rtx_MEM (GET_MODE (address
), scratch
), address
);
2176 /* Return nonzero if this function is known to have a null epilogue.
2177 This allows the optimizer to omit jumps to jumps if no stack
2181 iq2000_can_use_return_insn (void)
2183 if (! reload_completed
)
2186 if (df_regs_ever_live_p (31) || profile_flag
)
2189 if (cfun
->machine
->initialized
)
2190 return cfun
->machine
->total_size
== 0;
2192 return compute_frame_size (get_frame_size ()) == 0;
2195 /* Choose the section to use for the constant rtx expression X that has
2199 iq2000_select_rtx_section (machine_mode mode
, rtx x ATTRIBUTE_UNUSED
,
2200 unsigned HOST_WIDE_INT align
)
2202 /* For embedded applications, always put constants in read-only data,
2203 in order to reduce RAM usage. */
2204 return mergeable_constant_section (mode
, align
, 0);
2207 /* Choose the section to use for DECL. RELOC is true if its value contains
2208 any relocatable expression.
2210 Some of the logic used here needs to be replicated in
2211 ENCODE_SECTION_INFO in iq2000.h so that references to these symbols
2212 are done correctly. */
2215 iq2000_select_section (tree decl
, int reloc ATTRIBUTE_UNUSED
,
2216 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED
)
2218 if (TARGET_EMBEDDED_DATA
)
2220 /* For embedded applications, always put an object in read-only data
2221 if possible, in order to reduce RAM usage. */
2222 if ((TREE_CODE (decl
) == VAR_DECL
2223 && TREE_READONLY (decl
) && !TREE_SIDE_EFFECTS (decl
)
2224 && DECL_INITIAL (decl
)
2225 && (DECL_INITIAL (decl
) == error_mark_node
2226 || TREE_CONSTANT (DECL_INITIAL (decl
))))
2227 /* Deal with calls from output_constant_def_contents. */
2228 || TREE_CODE (decl
) != VAR_DECL
)
2229 return readonly_data_section
;
2231 return data_section
;
2235 /* For hosted applications, always put an object in small data if
2236 possible, as this gives the best performance. */
2237 if ((TREE_CODE (decl
) == VAR_DECL
2238 && TREE_READONLY (decl
) && !TREE_SIDE_EFFECTS (decl
)
2239 && DECL_INITIAL (decl
)
2240 && (DECL_INITIAL (decl
) == error_mark_node
2241 || TREE_CONSTANT (DECL_INITIAL (decl
))))
2242 /* Deal with calls from output_constant_def_contents. */
2243 || TREE_CODE (decl
) != VAR_DECL
)
2244 return readonly_data_section
;
2246 return data_section
;
2249 /* Return register to use for a function return value with VALTYPE for function
2253 iq2000_function_value (const_tree valtype
,
2254 const_tree fn_decl_or_type
,
2255 bool outgoing ATTRIBUTE_UNUSED
)
2257 int reg
= GP_RETURN
;
2258 machine_mode mode
= TYPE_MODE (valtype
);
2259 int unsignedp
= TYPE_UNSIGNED (valtype
);
2260 const_tree func
= fn_decl_or_type
;
2263 && !DECL_P (fn_decl_or_type
))
2264 fn_decl_or_type
= NULL
;
2266 /* Since we promote return types, we must promote the mode here too. */
2267 mode
= promote_function_mode (valtype
, mode
, &unsignedp
, func
, 1);
2269 return gen_rtx_REG (mode
, reg
);
2272 /* Worker function for TARGET_LIBCALL_VALUE. */
2275 iq2000_libcall_value (machine_mode mode
, const_rtx fun ATTRIBUTE_UNUSED
)
2277 return gen_rtx_REG (((GET_MODE_CLASS (mode
) != MODE_INT
2278 || GET_MODE_SIZE (mode
) >= 4)
2283 /* Worker function for FUNCTION_VALUE_REGNO_P.
2285 On the IQ2000, R2 and R3 are the only register thus used. */
2288 iq2000_function_value_regno_p (const unsigned int regno
)
2290 return (regno
== GP_RETURN
);
2294 /* Return true when an argument must be passed by reference. */
2297 iq2000_pass_by_reference (cumulative_args_t cum_v
, machine_mode mode
,
2298 const_tree type
, bool named ATTRIBUTE_UNUSED
)
2300 CUMULATIVE_ARGS
*cum
= get_cumulative_args (cum_v
);
2303 /* We must pass by reference if we would be both passing in registers
2304 and the stack. This is because any subsequent partial arg would be
2305 handled incorrectly in this case. */
2306 if (cum
&& targetm
.calls
.must_pass_in_stack (mode
, type
))
2308 /* Don't pass the actual CUM to FUNCTION_ARG, because we would
2309 get double copies of any offsets generated for small structs
2310 passed in registers. */
2311 CUMULATIVE_ARGS temp
;
2314 if (iq2000_function_arg (pack_cumulative_args (&temp
), mode
, type
, named
)
2319 if (type
== NULL_TREE
|| mode
== DImode
|| mode
== DFmode
)
2322 size
= int_size_in_bytes (type
);
2323 return size
== -1 || size
> UNITS_PER_WORD
;
2326 /* Return the length of INSN. LENGTH is the initial length computed by
2327 attributes in the machine-description file. */
2330 iq2000_adjust_insn_length (rtx_insn
*insn
, int length
)
2332 /* A unconditional jump has an unfilled delay slot if it is not part
2333 of a sequence. A conditional jump normally has a delay slot. */
2334 if (simplejump_p (insn
)
2342 /* Output assembly instructions to perform a conditional branch.
2344 INSN is the branch instruction. OPERANDS[0] is the condition.
2345 OPERANDS[1] is the target of the branch. OPERANDS[2] is the target
2346 of the first operand to the condition. If TWO_OPERANDS_P is
2347 nonzero the comparison takes two operands; OPERANDS[3] will be the
2350 If INVERTED_P is nonzero we are to branch if the condition does
2351 not hold. If FLOAT_P is nonzero this is a floating-point comparison.
2353 LENGTH is the length (in bytes) of the sequence we are to generate.
2354 That tells us whether to generate a simple conditional branch, or a
2355 reversed conditional branch around a `jr' instruction. */
2358 iq2000_output_conditional_branch (rtx_insn
*insn
, rtx
* operands
,
2359 int two_operands_p
, int float_p
,
2360 int inverted_p
, int length
)
2362 static char buffer
[200];
2363 /* The kind of comparison we are doing. */
2364 enum rtx_code code
= GET_CODE (operands
[0]);
2365 /* Nonzero if the opcode for the comparison needs a `z' indicating
2366 that it is a comparison against zero. */
2368 /* A string to use in the assembly output to represent the first
2370 const char *op1
= "%z2";
2371 /* A string to use in the assembly output to represent the second
2372 operand. Use the hard-wired zero register if there's no second
2374 const char *op2
= (two_operands_p
? ",%z3" : ",%.");
2375 /* The operand-printing string for the comparison. */
2376 const char *comp
= (float_p
? "%F0" : "%C0");
2377 /* The operand-printing string for the inverted comparison. */
2378 const char *inverted_comp
= (float_p
? "%W0" : "%N0");
2380 /* Likely variants of each branch instruction annul the instruction
2381 in the delay slot if the branch is not taken. */
2382 iq2000_branch_likely
= (final_sequence
&& INSN_ANNULLED_BRANCH_P (insn
));
2384 if (!two_operands_p
)
2386 /* To compute whether than A > B, for example, we normally
2387 subtract B from A and then look at the sign bit. But, if we
2388 are doing an unsigned comparison, and B is zero, we don't
2389 have to do the subtraction. Instead, we can just check to
2390 see if A is nonzero. Thus, we change the CODE here to
2391 reflect the simpler comparison operation. */
2403 /* A condition which will always be true. */
2409 /* A condition which will always be false. */
2415 /* Not a special case. */
2420 /* Relative comparisons are always done against zero. But
2421 equality comparisons are done between two operands, and therefore
2422 do not require a `z' in the assembly language output. */
2423 need_z_p
= (!float_p
&& code
!= EQ
&& code
!= NE
);
2424 /* For comparisons against zero, the zero is not provided
2429 /* Begin by terminating the buffer. That way we can always use
2430 strcat to add to it. */
2437 /* Just a simple conditional branch. */
2439 sprintf (buffer
, "b%s%%?\t%%Z2%%1",
2440 inverted_p
? inverted_comp
: comp
);
2442 sprintf (buffer
, "b%s%s%%?\t%s%s,%%1",
2443 inverted_p
? inverted_comp
: comp
,
2444 need_z_p
? "z" : "",
2452 /* Generate a reversed conditional branch around ` j'
2464 Because we have to jump four bytes *past* the following
2465 instruction if this branch was annulled, we can't just use
2466 a label, as in the picture above; there's no way to put the
2467 label after the next instruction, as the assembler does not
2468 accept `.L+4' as the target of a branch. (We can't just
2469 wait until the next instruction is output; it might be a
2470 macro and take up more than four bytes. Once again, we see
2471 why we want to eliminate macros.)
2473 If the branch is annulled, we jump four more bytes that we
2474 would otherwise; that way we skip the annulled instruction
2475 in the delay slot. */
2478 = ((iq2000_branch_likely
|| length
== 16) ? ".+16" : ".+12");
2481 c
= strchr (buffer
, '\0');
2482 /* Generate the reversed comparison. This takes four
2485 sprintf (c
, "b%s\t%%Z2%s",
2486 inverted_p
? comp
: inverted_comp
,
2489 sprintf (c
, "b%s%s\t%s%s,%s",
2490 inverted_p
? comp
: inverted_comp
,
2491 need_z_p
? "z" : "",
2495 strcat (c
, "\n\tnop\n\tj\t%1");
2497 /* The delay slot was unfilled. Since we're inside
2498 .noreorder, the assembler will not fill in the NOP for
2499 us, so we must do it ourselves. */
2500 strcat (buffer
, "\n\tnop");
2512 #define def_builtin(NAME, TYPE, CODE) \
2513 add_builtin_function ((NAME), (TYPE), (CODE), BUILT_IN_MD, \
2517 iq2000_init_builtins (void)
2519 tree void_ftype
, void_ftype_int
, void_ftype_int_int
;
2520 tree void_ftype_int_int_int
;
2521 tree int_ftype_int
, int_ftype_int_int
, int_ftype_int_int_int
;
2522 tree int_ftype_int_int_int_int
;
2526 = build_function_type_list (void_type_node
, NULL_TREE
);
2530 = build_function_type_list (void_type_node
, integer_type_node
, NULL_TREE
);
2532 /* void func (int, int) */
2534 = build_function_type_list (void_type_node
,
2539 /* int func (int) */
2541 = build_function_type_list (integer_type_node
,
2542 integer_type_node
, NULL_TREE
);
2544 /* int func (int, int) */
2546 = build_function_type_list (integer_type_node
,
2551 /* void func (int, int, int) */
2552 void_ftype_int_int_int
2553 = build_function_type_list (void_type_node
,
2559 /* int func (int, int, int) */
2560 int_ftype_int_int_int
2561 = build_function_type_list (integer_type_node
,
2567 /* int func (int, int, int, int) */
2568 int_ftype_int_int_int_int
2569 = build_function_type_list (integer_type_node
,
2576 def_builtin ("__builtin_ado16", int_ftype_int_int
, IQ2000_BUILTIN_ADO16
);
2577 def_builtin ("__builtin_ram", int_ftype_int_int_int_int
, IQ2000_BUILTIN_RAM
);
2578 def_builtin ("__builtin_chkhdr", void_ftype_int_int
, IQ2000_BUILTIN_CHKHDR
);
2579 def_builtin ("__builtin_pkrl", void_ftype_int_int
, IQ2000_BUILTIN_PKRL
);
2580 def_builtin ("__builtin_cfc0", int_ftype_int
, IQ2000_BUILTIN_CFC0
);
2581 def_builtin ("__builtin_cfc1", int_ftype_int
, IQ2000_BUILTIN_CFC1
);
2582 def_builtin ("__builtin_cfc2", int_ftype_int
, IQ2000_BUILTIN_CFC2
);
2583 def_builtin ("__builtin_cfc3", int_ftype_int
, IQ2000_BUILTIN_CFC3
);
2584 def_builtin ("__builtin_ctc0", void_ftype_int_int
, IQ2000_BUILTIN_CTC0
);
2585 def_builtin ("__builtin_ctc1", void_ftype_int_int
, IQ2000_BUILTIN_CTC1
);
2586 def_builtin ("__builtin_ctc2", void_ftype_int_int
, IQ2000_BUILTIN_CTC2
);
2587 def_builtin ("__builtin_ctc3", void_ftype_int_int
, IQ2000_BUILTIN_CTC3
);
2588 def_builtin ("__builtin_mfc0", int_ftype_int
, IQ2000_BUILTIN_MFC0
);
2589 def_builtin ("__builtin_mfc1", int_ftype_int
, IQ2000_BUILTIN_MFC1
);
2590 def_builtin ("__builtin_mfc2", int_ftype_int
, IQ2000_BUILTIN_MFC2
);
2591 def_builtin ("__builtin_mfc3", int_ftype_int
, IQ2000_BUILTIN_MFC3
);
2592 def_builtin ("__builtin_mtc0", void_ftype_int_int
, IQ2000_BUILTIN_MTC0
);
2593 def_builtin ("__builtin_mtc1", void_ftype_int_int
, IQ2000_BUILTIN_MTC1
);
2594 def_builtin ("__builtin_mtc2", void_ftype_int_int
, IQ2000_BUILTIN_MTC2
);
2595 def_builtin ("__builtin_mtc3", void_ftype_int_int
, IQ2000_BUILTIN_MTC3
);
2596 def_builtin ("__builtin_lur", void_ftype_int_int
, IQ2000_BUILTIN_LUR
);
2597 def_builtin ("__builtin_rb", void_ftype_int_int
, IQ2000_BUILTIN_RB
);
2598 def_builtin ("__builtin_rx", void_ftype_int_int
, IQ2000_BUILTIN_RX
);
2599 def_builtin ("__builtin_srrd", void_ftype_int
, IQ2000_BUILTIN_SRRD
);
2600 def_builtin ("__builtin_srwr", void_ftype_int_int
, IQ2000_BUILTIN_SRWR
);
2601 def_builtin ("__builtin_wb", void_ftype_int_int
, IQ2000_BUILTIN_WB
);
2602 def_builtin ("__builtin_wx", void_ftype_int_int
, IQ2000_BUILTIN_WX
);
2603 def_builtin ("__builtin_luc32l", void_ftype_int_int
, IQ2000_BUILTIN_LUC32L
);
2604 def_builtin ("__builtin_luc64", void_ftype_int_int
, IQ2000_BUILTIN_LUC64
);
2605 def_builtin ("__builtin_luc64l", void_ftype_int_int
, IQ2000_BUILTIN_LUC64L
);
2606 def_builtin ("__builtin_luk", void_ftype_int_int
, IQ2000_BUILTIN_LUK
);
2607 def_builtin ("__builtin_lulck", void_ftype_int
, IQ2000_BUILTIN_LULCK
);
2608 def_builtin ("__builtin_lum32", void_ftype_int_int
, IQ2000_BUILTIN_LUM32
);
2609 def_builtin ("__builtin_lum32l", void_ftype_int_int
, IQ2000_BUILTIN_LUM32L
);
2610 def_builtin ("__builtin_lum64", void_ftype_int_int
, IQ2000_BUILTIN_LUM64
);
2611 def_builtin ("__builtin_lum64l", void_ftype_int_int
, IQ2000_BUILTIN_LUM64L
);
2612 def_builtin ("__builtin_lurl", void_ftype_int_int
, IQ2000_BUILTIN_LURL
);
2613 def_builtin ("__builtin_mrgb", int_ftype_int_int_int
, IQ2000_BUILTIN_MRGB
);
2614 def_builtin ("__builtin_srrdl", void_ftype_int
, IQ2000_BUILTIN_SRRDL
);
2615 def_builtin ("__builtin_srulck", void_ftype_int
, IQ2000_BUILTIN_SRULCK
);
2616 def_builtin ("__builtin_srwru", void_ftype_int_int
, IQ2000_BUILTIN_SRWRU
);
2617 def_builtin ("__builtin_trapqfl", void_ftype
, IQ2000_BUILTIN_TRAPQFL
);
2618 def_builtin ("__builtin_trapqne", void_ftype
, IQ2000_BUILTIN_TRAPQNE
);
2619 def_builtin ("__builtin_traprel", void_ftype_int
, IQ2000_BUILTIN_TRAPREL
);
2620 def_builtin ("__builtin_wbu", void_ftype_int_int_int
, IQ2000_BUILTIN_WBU
);
2621 def_builtin ("__builtin_syscall", void_ftype
, IQ2000_BUILTIN_SYSCALL
);
2624 /* Builtin for ICODE having ARGCOUNT args in EXP where each arg
2628 expand_one_builtin (enum insn_code icode
, rtx target
, tree exp
,
2629 enum rtx_code
*code
, int argcount
)
2634 machine_mode mode
[5];
2637 mode
[0] = insn_data
[icode
].operand
[0].mode
;
2638 for (i
= 0; i
< argcount
; i
++)
2640 arg
[i
] = CALL_EXPR_ARG (exp
, i
);
2641 op
[i
] = expand_normal (arg
[i
]);
2642 mode
[i
] = insn_data
[icode
].operand
[i
].mode
;
2643 if (code
[i
] == CONST_INT
&& GET_CODE (op
[i
]) != CONST_INT
)
2644 error ("argument %qd is not a constant", i
+ 1);
2646 && ! (*insn_data
[icode
].operand
[i
].predicate
) (op
[i
], mode
[i
]))
2647 op
[i
] = copy_to_mode_reg (mode
[i
], op
[i
]);
2650 if (insn_data
[icode
].operand
[0].constraint
[0] == '=')
2653 || GET_MODE (target
) != mode
[0]
2654 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, mode
[0]))
2655 target
= gen_reg_rtx (mode
[0]);
2663 pat
= GEN_FCN (icode
) (target
);
2667 pat
= GEN_FCN (icode
) (target
, op
[0]);
2669 pat
= GEN_FCN (icode
) (op
[0]);
2673 pat
= GEN_FCN (icode
) (target
, op
[0], op
[1]);
2675 pat
= GEN_FCN (icode
) (op
[0], op
[1]);
2679 pat
= GEN_FCN (icode
) (target
, op
[0], op
[1], op
[2]);
2681 pat
= GEN_FCN (icode
) (op
[0], op
[1], op
[2]);
2685 pat
= GEN_FCN (icode
) (target
, op
[0], op
[1], op
[2], op
[3]);
2687 pat
= GEN_FCN (icode
) (op
[0], op
[1], op
[2], op
[3]);
2699 /* Expand an expression EXP that calls a built-in function,
2700 with result going to TARGET if that's convenient
2701 (and in mode MODE if that's convenient).
2702 SUBTARGET may be used as the target for computing one of EXP's operands.
2703 IGNORE is nonzero if the value is to be ignored. */
2706 iq2000_expand_builtin (tree exp
, rtx target
, rtx subtarget ATTRIBUTE_UNUSED
,
2707 machine_mode mode ATTRIBUTE_UNUSED
,
2708 int ignore ATTRIBUTE_UNUSED
)
2710 tree fndecl
= TREE_OPERAND (CALL_EXPR_FN (exp
), 0);
2711 int fcode
= DECL_FUNCTION_CODE (fndecl
);
2712 enum rtx_code code
[5];
2724 case IQ2000_BUILTIN_ADO16
:
2725 return expand_one_builtin (CODE_FOR_ado16
, target
, exp
, code
, 2);
2727 case IQ2000_BUILTIN_RAM
:
2728 code
[1] = CONST_INT
;
2729 code
[2] = CONST_INT
;
2730 code
[3] = CONST_INT
;
2731 return expand_one_builtin (CODE_FOR_ram
, target
, exp
, code
, 4);
2733 case IQ2000_BUILTIN_CHKHDR
:
2734 return expand_one_builtin (CODE_FOR_chkhdr
, target
, exp
, code
, 2);
2736 case IQ2000_BUILTIN_PKRL
:
2737 return expand_one_builtin (CODE_FOR_pkrl
, target
, exp
, code
, 2);
2739 case IQ2000_BUILTIN_CFC0
:
2740 code
[0] = CONST_INT
;
2741 return expand_one_builtin (CODE_FOR_cfc0
, target
, exp
, code
, 1);
2743 case IQ2000_BUILTIN_CFC1
:
2744 code
[0] = CONST_INT
;
2745 return expand_one_builtin (CODE_FOR_cfc1
, target
, exp
, code
, 1);
2747 case IQ2000_BUILTIN_CFC2
:
2748 code
[0] = CONST_INT
;
2749 return expand_one_builtin (CODE_FOR_cfc2
, target
, exp
, code
, 1);
2751 case IQ2000_BUILTIN_CFC3
:
2752 code
[0] = CONST_INT
;
2753 return expand_one_builtin (CODE_FOR_cfc3
, target
, exp
, code
, 1);
2755 case IQ2000_BUILTIN_CTC0
:
2756 code
[1] = CONST_INT
;
2757 return expand_one_builtin (CODE_FOR_ctc0
, target
, exp
, code
, 2);
2759 case IQ2000_BUILTIN_CTC1
:
2760 code
[1] = CONST_INT
;
2761 return expand_one_builtin (CODE_FOR_ctc1
, target
, exp
, code
, 2);
2763 case IQ2000_BUILTIN_CTC2
:
2764 code
[1] = CONST_INT
;
2765 return expand_one_builtin (CODE_FOR_ctc2
, target
, exp
, code
, 2);
2767 case IQ2000_BUILTIN_CTC3
:
2768 code
[1] = CONST_INT
;
2769 return expand_one_builtin (CODE_FOR_ctc3
, target
, exp
, code
, 2);
2771 case IQ2000_BUILTIN_MFC0
:
2772 code
[0] = CONST_INT
;
2773 return expand_one_builtin (CODE_FOR_mfc0
, target
, exp
, code
, 1);
2775 case IQ2000_BUILTIN_MFC1
:
2776 code
[0] = CONST_INT
;
2777 return expand_one_builtin (CODE_FOR_mfc1
, target
, exp
, code
, 1);
2779 case IQ2000_BUILTIN_MFC2
:
2780 code
[0] = CONST_INT
;
2781 return expand_one_builtin (CODE_FOR_mfc2
, target
, exp
, code
, 1);
2783 case IQ2000_BUILTIN_MFC3
:
2784 code
[0] = CONST_INT
;
2785 return expand_one_builtin (CODE_FOR_mfc3
, target
, exp
, code
, 1);
2787 case IQ2000_BUILTIN_MTC0
:
2788 code
[1] = CONST_INT
;
2789 return expand_one_builtin (CODE_FOR_mtc0
, target
, exp
, code
, 2);
2791 case IQ2000_BUILTIN_MTC1
:
2792 code
[1] = CONST_INT
;
2793 return expand_one_builtin (CODE_FOR_mtc1
, target
, exp
, code
, 2);
2795 case IQ2000_BUILTIN_MTC2
:
2796 code
[1] = CONST_INT
;
2797 return expand_one_builtin (CODE_FOR_mtc2
, target
, exp
, code
, 2);
2799 case IQ2000_BUILTIN_MTC3
:
2800 code
[1] = CONST_INT
;
2801 return expand_one_builtin (CODE_FOR_mtc3
, target
, exp
, code
, 2);
2803 case IQ2000_BUILTIN_LUR
:
2804 return expand_one_builtin (CODE_FOR_lur
, target
, exp
, code
, 2);
2806 case IQ2000_BUILTIN_RB
:
2807 return expand_one_builtin (CODE_FOR_rb
, target
, exp
, code
, 2);
2809 case IQ2000_BUILTIN_RX
:
2810 return expand_one_builtin (CODE_FOR_rx
, target
, exp
, code
, 2);
2812 case IQ2000_BUILTIN_SRRD
:
2813 return expand_one_builtin (CODE_FOR_srrd
, target
, exp
, code
, 1);
2815 case IQ2000_BUILTIN_SRWR
:
2816 return expand_one_builtin (CODE_FOR_srwr
, target
, exp
, code
, 2);
2818 case IQ2000_BUILTIN_WB
:
2819 return expand_one_builtin (CODE_FOR_wb
, target
, exp
, code
, 2);
2821 case IQ2000_BUILTIN_WX
:
2822 return expand_one_builtin (CODE_FOR_wx
, target
, exp
, code
, 2);
2824 case IQ2000_BUILTIN_LUC32L
:
2825 return expand_one_builtin (CODE_FOR_luc32l
, target
, exp
, code
, 2);
2827 case IQ2000_BUILTIN_LUC64
:
2828 return expand_one_builtin (CODE_FOR_luc64
, target
, exp
, code
, 2);
2830 case IQ2000_BUILTIN_LUC64L
:
2831 return expand_one_builtin (CODE_FOR_luc64l
, target
, exp
, code
, 2);
2833 case IQ2000_BUILTIN_LUK
:
2834 return expand_one_builtin (CODE_FOR_luk
, target
, exp
, code
, 2);
2836 case IQ2000_BUILTIN_LULCK
:
2837 return expand_one_builtin (CODE_FOR_lulck
, target
, exp
, code
, 1);
2839 case IQ2000_BUILTIN_LUM32
:
2840 return expand_one_builtin (CODE_FOR_lum32
, target
, exp
, code
, 2);
2842 case IQ2000_BUILTIN_LUM32L
:
2843 return expand_one_builtin (CODE_FOR_lum32l
, target
, exp
, code
, 2);
2845 case IQ2000_BUILTIN_LUM64
:
2846 return expand_one_builtin (CODE_FOR_lum64
, target
, exp
, code
, 2);
2848 case IQ2000_BUILTIN_LUM64L
:
2849 return expand_one_builtin (CODE_FOR_lum64l
, target
, exp
, code
, 2);
2851 case IQ2000_BUILTIN_LURL
:
2852 return expand_one_builtin (CODE_FOR_lurl
, target
, exp
, code
, 2);
2854 case IQ2000_BUILTIN_MRGB
:
2855 code
[2] = CONST_INT
;
2856 return expand_one_builtin (CODE_FOR_mrgb
, target
, exp
, code
, 3);
2858 case IQ2000_BUILTIN_SRRDL
:
2859 return expand_one_builtin (CODE_FOR_srrdl
, target
, exp
, code
, 1);
2861 case IQ2000_BUILTIN_SRULCK
:
2862 return expand_one_builtin (CODE_FOR_srulck
, target
, exp
, code
, 1);
2864 case IQ2000_BUILTIN_SRWRU
:
2865 return expand_one_builtin (CODE_FOR_srwru
, target
, exp
, code
, 2);
2867 case IQ2000_BUILTIN_TRAPQFL
:
2868 return expand_one_builtin (CODE_FOR_trapqfl
, target
, exp
, code
, 0);
2870 case IQ2000_BUILTIN_TRAPQNE
:
2871 return expand_one_builtin (CODE_FOR_trapqne
, target
, exp
, code
, 0);
2873 case IQ2000_BUILTIN_TRAPREL
:
2874 return expand_one_builtin (CODE_FOR_traprel
, target
, exp
, code
, 1);
2876 case IQ2000_BUILTIN_WBU
:
2877 return expand_one_builtin (CODE_FOR_wbu
, target
, exp
, code
, 3);
2879 case IQ2000_BUILTIN_SYSCALL
:
2880 return expand_one_builtin (CODE_FOR_syscall
, target
, exp
, code
, 0);
2886 /* Worker function for TARGET_RETURN_IN_MEMORY. */
2889 iq2000_return_in_memory (const_tree type
, const_tree fntype ATTRIBUTE_UNUSED
)
2891 return ((int_size_in_bytes (type
) > (2 * UNITS_PER_WORD
))
2892 || (int_size_in_bytes (type
) == -1));
2895 /* Worker function for TARGET_SETUP_INCOMING_VARARGS. */
2898 iq2000_setup_incoming_varargs (cumulative_args_t cum_v
,
2899 machine_mode mode ATTRIBUTE_UNUSED
,
2900 tree type ATTRIBUTE_UNUSED
, int * pretend_size
,
2903 CUMULATIVE_ARGS
*cum
= get_cumulative_args (cum_v
);
2904 unsigned int iq2000_off
= ! cum
->last_arg_fp
;
2905 unsigned int iq2000_fp_off
= cum
->last_arg_fp
;
2907 if ((cum
->arg_words
< MAX_ARGS_IN_REGISTERS
- iq2000_off
))
2909 int iq2000_save_gp_regs
2910 = MAX_ARGS_IN_REGISTERS
- cum
->arg_words
- iq2000_off
;
2911 int iq2000_save_fp_regs
2912 = (MAX_ARGS_IN_REGISTERS
- cum
->fp_arg_words
- iq2000_fp_off
);
2914 if (iq2000_save_gp_regs
< 0)
2915 iq2000_save_gp_regs
= 0;
2916 if (iq2000_save_fp_regs
< 0)
2917 iq2000_save_fp_regs
= 0;
2919 *pretend_size
= ((iq2000_save_gp_regs
* UNITS_PER_WORD
)
2920 + (iq2000_save_fp_regs
* UNITS_PER_FPREG
));
2924 if (cum
->arg_words
< MAX_ARGS_IN_REGISTERS
- iq2000_off
)
2927 ptr
= plus_constant (Pmode
, virtual_incoming_args_rtx
,
2928 - (iq2000_save_gp_regs
2930 mem
= gen_rtx_MEM (BLKmode
, ptr
);
2932 (cum
->arg_words
+ GP_ARG_FIRST
+ iq2000_off
,
2934 iq2000_save_gp_regs
);
2940 /* A C compound statement to output to stdio stream STREAM the
2941 assembler syntax for an instruction operand that is a memory
2942 reference whose address is ADDR. ADDR is an RTL expression. */
2945 iq2000_print_operand_address (FILE * file
, machine_mode mode
, rtx addr
)
2948 error ("PRINT_OPERAND_ADDRESS, null pointer");
2951 switch (GET_CODE (addr
))
2954 if (REGNO (addr
) == ARG_POINTER_REGNUM
)
2955 abort_with_insn (addr
, "Arg pointer not eliminated.");
2957 fprintf (file
, "0(%s)", reg_names
[REGNO (addr
)]);
2962 rtx arg0
= XEXP (addr
, 0);
2963 rtx arg1
= XEXP (addr
, 1);
2965 if (GET_CODE (arg0
) != REG
)
2966 abort_with_insn (addr
,
2967 "PRINT_OPERAND_ADDRESS, LO_SUM with #1 not REG.");
2969 fprintf (file
, "%%lo(");
2970 iq2000_print_operand_address (file
, mode
, arg1
);
2971 fprintf (file
, ")(%s)", reg_names
[REGNO (arg0
)]);
2979 rtx arg0
= XEXP (addr
, 0);
2980 rtx arg1
= XEXP (addr
, 1);
2982 if (GET_CODE (arg0
) == REG
)
2986 if (GET_CODE (offset
) == REG
)
2987 abort_with_insn (addr
, "PRINT_OPERAND_ADDRESS, 2 regs");
2990 else if (GET_CODE (arg1
) == REG
)
2991 reg
= arg1
, offset
= arg0
;
2992 else if (CONSTANT_P (arg0
) && CONSTANT_P (arg1
))
2994 output_addr_const (file
, addr
);
2998 abort_with_insn (addr
, "PRINT_OPERAND_ADDRESS, no regs");
3000 if (! CONSTANT_P (offset
))
3001 abort_with_insn (addr
, "PRINT_OPERAND_ADDRESS, invalid insn #2");
3003 if (REGNO (reg
) == ARG_POINTER_REGNUM
)
3004 abort_with_insn (addr
, "Arg pointer not eliminated.");
3006 output_addr_const (file
, offset
);
3007 fprintf (file
, "(%s)", reg_names
[REGNO (reg
)]);
3015 output_addr_const (file
, addr
);
3016 if (GET_CODE (addr
) == CONST_INT
)
3017 fprintf (file
, "(%s)", reg_names
[0]);
3021 abort_with_insn (addr
, "PRINT_OPERAND_ADDRESS, invalid insn #1");
3026 /* A C compound statement to output to stdio stream FILE the
3027 assembler syntax for an instruction operand OP.
3029 LETTER is a value that can be used to specify one of several ways
3030 of printing the operand. It is used when identical operands
3031 must be printed differently depending on the context. LETTER
3032 comes from the `%' specification that was used to request
3033 printing of the operand. If the specification was just `%DIGIT'
3034 then LETTER is 0; if the specification was `%LTR DIGIT' then LETTER
3035 is the ASCII code for LTR.
3037 If OP is a register, this macro should print the register's name.
3038 The names can be found in an array `reg_names' whose type is
3039 `char *[]'. `reg_names' is initialized from `REGISTER_NAMES'.
3041 When the machine description has a specification `%PUNCT' (a `%'
3042 followed by a punctuation character), this macro is called with
3043 a null pointer for X and the punctuation character for LETTER.
3045 The IQ2000 specific codes are:
3047 'X' X is CONST_INT, prints upper 16 bits in hexadecimal format = "0x%04x",
3048 'x' X is CONST_INT, prints lower 16 bits in hexadecimal format = "0x%04x",
3049 'd' output integer constant in decimal,
3050 'z' if the operand is 0, use $0 instead of normal operand.
3051 'D' print second part of double-word register or memory operand.
3052 'L' print low-order register of double-word register operand.
3053 'M' print high-order register of double-word register operand.
3054 'C' print part of opcode for a branch condition.
3055 'F' print part of opcode for a floating-point branch condition.
3056 'N' print part of opcode for a branch condition, inverted.
3057 'W' print part of opcode for a floating-point branch condition, inverted.
3058 'A' Print part of opcode for a bit test condition.
3059 'P' Print label for a bit test.
3060 'p' Print log for a bit test.
3061 'B' print 'z' for EQ, 'n' for NE
3062 'b' print 'n' for EQ, 'z' for NE
3063 'T' print 'f' for EQ, 't' for NE
3064 't' print 't' for EQ, 'f' for NE
3065 'Z' print register and a comma, but print nothing for $fcc0
3066 '?' Print 'l' if we are to use a branch likely instead of normal branch.
3067 '@' Print the name of the assembler temporary register (at or $1).
3068 '.' Print the name of the register with a hard-wired zero (zero or $0).
3069 '$' Print the name of the stack pointer register (sp or $29).
3070 '+' Print the name of the gp register (gp or $28). */
3073 iq2000_print_operand (FILE *file
, rtx op
, int letter
)
3077 if (iq2000_print_operand_punct_valid_p (letter
))
3082 if (iq2000_branch_likely
)
3087 fputs (reg_names
[GP_REG_FIRST
+ 1], file
);
3091 fputs (reg_names
[GP_REG_FIRST
+ 0], file
);
3095 fputs (reg_names
[STACK_POINTER_REGNUM
], file
);
3099 fputs (reg_names
[GP_REG_FIRST
+ 28], file
);
3103 error ("PRINT_OPERAND: Unknown punctuation '%c'", letter
);
3112 error ("PRINT_OPERAND null pointer");
3116 code
= GET_CODE (op
);
3118 if (code
== SIGN_EXTEND
)
3119 op
= XEXP (op
, 0), code
= GET_CODE (op
);
3124 case EQ
: fputs ("eq", file
); break;
3125 case NE
: fputs ("ne", file
); break;
3126 case GT
: fputs ("gt", file
); break;
3127 case GE
: fputs ("ge", file
); break;
3128 case LT
: fputs ("lt", file
); break;
3129 case LE
: fputs ("le", file
); break;
3130 case GTU
: fputs ("ne", file
); break;
3131 case GEU
: fputs ("geu", file
); break;
3132 case LTU
: fputs ("ltu", file
); break;
3133 case LEU
: fputs ("eq", file
); break;
3135 abort_with_insn (op
, "PRINT_OPERAND, invalid insn for %%C");
3138 else if (letter
== 'N')
3141 case EQ
: fputs ("ne", file
); break;
3142 case NE
: fputs ("eq", file
); break;
3143 case GT
: fputs ("le", file
); break;
3144 case GE
: fputs ("lt", file
); break;
3145 case LT
: fputs ("ge", file
); break;
3146 case LE
: fputs ("gt", file
); break;
3147 case GTU
: fputs ("leu", file
); break;
3148 case GEU
: fputs ("ltu", file
); break;
3149 case LTU
: fputs ("geu", file
); break;
3150 case LEU
: fputs ("gtu", file
); break;
3152 abort_with_insn (op
, "PRINT_OPERAND, invalid insn for %%N");
3155 else if (letter
== 'F')
3158 case EQ
: fputs ("c1f", file
); break;
3159 case NE
: fputs ("c1t", file
); break;
3161 abort_with_insn (op
, "PRINT_OPERAND, invalid insn for %%F");
3164 else if (letter
== 'W')
3167 case EQ
: fputs ("c1t", file
); break;
3168 case NE
: fputs ("c1f", file
); break;
3170 abort_with_insn (op
, "PRINT_OPERAND, invalid insn for %%W");
3173 else if (letter
== 'A')
3174 fputs (code
== LABEL_REF
? "i" : "in", file
);
3176 else if (letter
== 'P')
3178 if (code
== LABEL_REF
)
3179 output_addr_const (file
, op
);
3180 else if (code
!= PC
)
3181 output_operand_lossage ("invalid %%P operand");
3184 else if (letter
== 'p')
3187 if (code
!= CONST_INT
3188 || (value
= exact_log2 (INTVAL (op
))) < 0)
3189 output_operand_lossage ("invalid %%p value");
3191 fprintf (file
, "%d", value
);
3194 else if (letter
== 'Z')
3199 else if (code
== REG
|| code
== SUBREG
)
3204 regnum
= REGNO (op
);
3206 regnum
= true_regnum (op
);
3208 if ((letter
== 'M' && ! WORDS_BIG_ENDIAN
)
3209 || (letter
== 'L' && WORDS_BIG_ENDIAN
)
3213 fprintf (file
, "%s", reg_names
[regnum
]);
3216 else if (code
== MEM
)
3218 machine_mode mode
= GET_MODE (op
);
3221 output_address (mode
, plus_constant (Pmode
, XEXP (op
, 0), 4));
3223 output_address (mode
, XEXP (op
, 0));
3226 else if (code
== CONST_DOUBLE
3227 && GET_MODE_CLASS (GET_MODE (op
)) == MODE_FLOAT
)
3231 real_to_decimal (s
, CONST_DOUBLE_REAL_VALUE (op
), sizeof (s
), 0, 1);
3235 else if (letter
== 'x' && GET_CODE (op
) == CONST_INT
)
3236 fprintf (file
, HOST_WIDE_INT_PRINT_HEX
, 0xffff & INTVAL(op
));
3238 else if (letter
== 'X' && GET_CODE(op
) == CONST_INT
)
3239 fprintf (file
, HOST_WIDE_INT_PRINT_HEX
, 0xffff & (INTVAL (op
) >> 16));
3241 else if (letter
== 'd' && GET_CODE(op
) == CONST_INT
)
3242 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, (INTVAL(op
)));
3244 else if (letter
== 'z' && GET_CODE (op
) == CONST_INT
&& INTVAL (op
) == 0)
3245 fputs (reg_names
[GP_REG_FIRST
], file
);
3247 else if (letter
== 'd' || letter
== 'x' || letter
== 'X')
3248 output_operand_lossage ("invalid use of %%d, %%x, or %%X");
3250 else if (letter
== 'B')
3251 fputs (code
== EQ
? "z" : "n", file
);
3252 else if (letter
== 'b')
3253 fputs (code
== EQ
? "n" : "z", file
);
3254 else if (letter
== 'T')
3255 fputs (code
== EQ
? "f" : "t", file
);
3256 else if (letter
== 't')
3257 fputs (code
== EQ
? "t" : "f", file
);
3259 else if (code
== CONST
&& GET_CODE (XEXP (op
, 0)) == REG
)
3261 iq2000_print_operand (file
, XEXP (op
, 0), letter
);
3265 output_addr_const (file
, op
);
3269 iq2000_print_operand_punct_valid_p (unsigned char code
)
3271 return iq2000_print_operand_punct
[code
];
3274 /* For the IQ2000, transform:
3276 memory(X + <large int>)
3278 Y = <large int> & ~0x7fff;
3280 memory (Z + (<large int> & 0x7fff));
3284 iq2000_legitimize_address (rtx xinsn
, rtx old_x ATTRIBUTE_UNUSED
,
3287 if (TARGET_DEBUG_B_MODE
)
3289 GO_PRINTF ("\n========== LEGITIMIZE_ADDRESS\n");
3290 GO_DEBUG_RTX (xinsn
);
3293 if (iq2000_check_split (xinsn
, mode
))
3295 return gen_rtx_LO_SUM (Pmode
,
3296 copy_to_mode_reg (Pmode
,
3297 gen_rtx_HIGH (Pmode
, xinsn
)),
3301 if (GET_CODE (xinsn
) == PLUS
)
3303 rtx xplus0
= XEXP (xinsn
, 0);
3304 rtx xplus1
= XEXP (xinsn
, 1);
3305 enum rtx_code code0
= GET_CODE (xplus0
);
3306 enum rtx_code code1
= GET_CODE (xplus1
);
3308 if (code0
!= REG
&& code1
== REG
)
3310 xplus0
= XEXP (xinsn
, 1);
3311 xplus1
= XEXP (xinsn
, 0);
3312 code0
= GET_CODE (xplus0
);
3313 code1
= GET_CODE (xplus1
);
3316 if (code0
== REG
&& REG_MODE_OK_FOR_BASE_P (xplus0
, mode
)
3317 && code1
== CONST_INT
&& !SMALL_INT (xplus1
))
3319 rtx int_reg
= gen_reg_rtx (Pmode
);
3320 rtx ptr_reg
= gen_reg_rtx (Pmode
);
3322 emit_move_insn (int_reg
,
3323 GEN_INT (INTVAL (xplus1
) & ~ 0x7fff));
3325 emit_insn (gen_rtx_SET (ptr_reg
,
3326 gen_rtx_PLUS (Pmode
, xplus0
, int_reg
)));
3328 return plus_constant (Pmode
, ptr_reg
, INTVAL (xplus1
) & 0x7fff);
3332 if (TARGET_DEBUG_B_MODE
)
3333 GO_PRINTF ("LEGITIMIZE_ADDRESS could not fix.\n");
3340 iq2000_rtx_costs (rtx x
, machine_mode mode
, int outer_code ATTRIBUTE_UNUSED
,
3341 int opno ATTRIBUTE_UNUSED
, int * total
,
3342 bool speed ATTRIBUTE_UNUSED
)
3344 int code
= GET_CODE (x
);
3350 int num_words
= (GET_MODE_SIZE (mode
) > UNITS_PER_WORD
) ? 2 : 1;
3352 if (simple_memory_operand (x
, mode
))
3353 return COSTS_N_INSNS (num_words
) != 0;
3355 * total
= COSTS_N_INSNS (2 * num_words
);
3360 * total
= COSTS_N_INSNS (6);
3367 * total
= COSTS_N_INSNS (mode
== DImode
? 2 : 1);
3374 * total
= COSTS_N_INSNS ((GET_CODE (XEXP (x
, 1)) == CONST_INT
) ? 4 : 12);
3376 * total
= COSTS_N_INSNS (1);
3380 if (mode
== SFmode
|| mode
== DFmode
)
3381 * total
= COSTS_N_INSNS (1);
3383 * total
= COSTS_N_INSNS (4);
3388 if (mode
== SFmode
|| mode
== DFmode
)
3389 * total
= COSTS_N_INSNS (6);
3390 else if (mode
== DImode
)
3391 * total
= COSTS_N_INSNS (4);
3393 * total
= COSTS_N_INSNS (1);
3397 * total
= (mode
== DImode
) ? 4 : 1;
3402 * total
= COSTS_N_INSNS (7);
3403 else if (mode
== DFmode
)
3404 * total
= COSTS_N_INSNS (8);
3406 * total
= COSTS_N_INSNS (10);
3412 * total
= COSTS_N_INSNS (23);
3413 else if (mode
== DFmode
)
3414 * total
= COSTS_N_INSNS (36);
3416 * total
= COSTS_N_INSNS (69);
3421 * total
= COSTS_N_INSNS (69);
3425 * total
= COSTS_N_INSNS (2);
3429 * total
= COSTS_N_INSNS (1);
3437 * total
= COSTS_N_INSNS (2);
3442 rtx offset
= const0_rtx
;
3443 rtx symref
= eliminate_constant_term (XEXP (x
, 0), & offset
);
3445 if (GET_CODE (symref
) == LABEL_REF
)
3446 * total
= COSTS_N_INSNS (2);
3447 else if (GET_CODE (symref
) != SYMBOL_REF
)
3448 * total
= COSTS_N_INSNS (4);
3449 /* Let's be paranoid.... */
3450 else if (INTVAL (offset
) < -32768 || INTVAL (offset
) > 32767)
3451 * total
= COSTS_N_INSNS (2);
3453 * total
= COSTS_N_INSNS (SYMBOL_REF_FLAG (symref
) ? 1 : 2);
3458 * total
= COSTS_N_INSNS (SYMBOL_REF_FLAG (x
) ? 1 : 2);
3465 split_double (x
, & high
, & low
);
3467 * total
= COSTS_N_INSNS ( (high
== CONST0_RTX (GET_MODE (high
))
3468 || low
== CONST0_RTX (GET_MODE (low
)))
3479 /* Worker for TARGET_ASM_TRAMPOLINE_TEMPLATE. */
3482 iq2000_asm_trampoline_template (FILE *f
)
3484 fprintf (f
, "\t.word\t0x03e00821\t\t# move $1,$31\n");
3485 fprintf (f
, "\t.word\t0x04110001\t\t# bgezal $0,.+8\n");
3486 fprintf (f
, "\t.word\t0x00000000\t\t# nop\n");
3487 if (Pmode
== DImode
)
3489 fprintf (f
, "\t.word\t0xdfe30014\t\t# ld $3,20($31)\n");
3490 fprintf (f
, "\t.word\t0xdfe2001c\t\t# ld $2,28($31)\n");
3494 fprintf (f
, "\t.word\t0x8fe30014\t\t# lw $3,20($31)\n");
3495 fprintf (f
, "\t.word\t0x8fe20018\t\t# lw $2,24($31)\n");
3497 fprintf (f
, "\t.word\t0x0060c821\t\t# move $25,$3 (abicalls)\n");
3498 fprintf (f
, "\t.word\t0x00600008\t\t# jr $3\n");
3499 fprintf (f
, "\t.word\t0x0020f821\t\t# move $31,$1\n");
3500 fprintf (f
, "\t.word\t0x00000000\t\t# <function address>\n");
3501 fprintf (f
, "\t.word\t0x00000000\t\t# <static chain value>\n");
3504 /* Worker for TARGET_TRAMPOLINE_INIT. */
3507 iq2000_trampoline_init (rtx m_tramp
, tree fndecl
, rtx chain_value
)
3509 rtx fnaddr
= XEXP (DECL_RTL (fndecl
), 0);
3512 emit_block_move (m_tramp
, assemble_trampoline_template (),
3513 GEN_INT (TRAMPOLINE_CODE_SIZE
), BLOCK_OP_NORMAL
);
3515 mem
= adjust_address (m_tramp
, Pmode
, TRAMPOLINE_CODE_SIZE
);
3516 emit_move_insn (mem
, fnaddr
);
3517 mem
= adjust_address (m_tramp
, Pmode
,
3518 TRAMPOLINE_CODE_SIZE
+ GET_MODE_SIZE (Pmode
));
3519 emit_move_insn (mem
, chain_value
);
3522 /* Implement TARGET_HARD_REGNO_MODE_OK. */
3525 iq2000_hard_regno_mode_ok (unsigned int regno
, machine_mode mode
)
3527 return (REGNO_REG_CLASS (regno
) == GR_REGS
3528 ? (regno
& 1) == 0 || GET_MODE_SIZE (mode
) <= 4
3529 : (regno
& 1) == 0 || GET_MODE_SIZE (mode
) == 4);
3532 /* Implement TARGET_MODES_TIEABLE_P. */
3535 iq2000_modes_tieable_p (machine_mode mode1
, machine_mode mode2
)
3537 return ((GET_MODE_CLASS (mode1
) == MODE_FLOAT
3538 || GET_MODE_CLASS (mode1
) == MODE_COMPLEX_FLOAT
)
3539 == (GET_MODE_CLASS (mode2
) == MODE_FLOAT
3540 || GET_MODE_CLASS (mode2
) == MODE_COMPLEX_FLOAT
));
3543 /* Implement TARGET_CONSTANT_ALIGNMENT. */
3545 static HOST_WIDE_INT
3546 iq2000_constant_alignment (const_tree exp
, HOST_WIDE_INT align
)
3548 if (TREE_CODE (exp
) == STRING_CST
|| TREE_CODE (exp
) == CONSTRUCTOR
)
3549 return MAX (align
, BITS_PER_WORD
);
3553 /* Implement TARGET_STARTING_FRAME_OFFSET. */
3555 static HOST_WIDE_INT
3556 iq2000_starting_frame_offset (void)
3558 return crtl
->outgoing_args_size
;
3561 #include "gt-iq2000.h"