1 /* Subroutines used for code generation on Vitesse IQ2000 processors
2 Copyright (C) 2003-2024 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/>. */
20 #define IN_TARGET_CODE 1
24 #include "coretypes.h"
29 #include "stringpool.h"
38 #include "diagnostic-core.h"
39 #include "stor-layout.h"
43 #include "insn-attr.h"
46 #include "langhooks.h"
49 /* This file should be included last. */
50 #include "target-def.h"
52 /* Enumeration for all of the relational tests, so that we can build
53 arrays indexed by the test type, and not worry about the order
74 /* Structure to be filled in by compute_frame_size with register
75 save masks, and offsets for the current function. */
77 struct iq2000_frame_info
79 long total_size
; /* # bytes that the entire frame takes up. */
80 long var_size
; /* # bytes that variables take up. */
81 long args_size
; /* # bytes that outgoing arguments take up. */
82 long extra_size
; /* # bytes of extra gunk. */
83 int gp_reg_size
; /* # bytes needed to store gp regs. */
84 int fp_reg_size
; /* # bytes needed to store fp regs. */
85 long mask
; /* Mask of saved gp registers. */
86 long gp_save_offset
; /* Offset from vfp to store gp registers. */
87 long fp_save_offset
; /* Offset from vfp to store fp registers. */
88 long gp_sp_offset
; /* Offset from new sp to store gp registers. */
89 long fp_sp_offset
; /* Offset from new sp to store fp registers. */
90 int initialized
; /* != 0 if frame size already calculated. */
91 int num_gp
; /* Number of gp registers saved. */
94 struct GTY(()) machine_function
96 /* Current frame information, calculated by compute_frame_size. */
97 long total_size
; /* # bytes that the entire frame takes up. */
98 long var_size
; /* # bytes that variables take up. */
99 long args_size
; /* # bytes that outgoing arguments take up. */
100 long extra_size
; /* # bytes of extra gunk. */
101 int gp_reg_size
; /* # bytes needed to store gp regs. */
102 int fp_reg_size
; /* # bytes needed to store fp regs. */
103 long mask
; /* Mask of saved gp registers. */
104 long gp_save_offset
; /* Offset from vfp to store gp registers. */
105 long fp_save_offset
; /* Offset from vfp to store fp registers. */
106 long gp_sp_offset
; /* Offset from new sp to store gp registers. */
107 long fp_sp_offset
; /* Offset from new sp to store fp registers. */
108 int initialized
; /* != 0 if frame size already calculated. */
109 int num_gp
; /* Number of gp registers saved. */
112 /* Global variables for machine-dependent things. */
114 /* List of all IQ2000 punctuation characters used by iq2000_print_operand. */
115 static char iq2000_print_operand_punct
[256];
117 /* Which instruction set architecture to use. */
120 /* Local variables. */
122 /* The next branch instruction is a branch likely, not branch normal. */
123 static int iq2000_branch_likely
;
125 /* Count of delay slots and how many are filled. */
126 static int dslots_load_total
;
127 static int dslots_load_filled
;
128 static int dslots_jump_total
;
130 /* # of nops needed by previous insn. */
131 static int dslots_number_nops
;
133 /* Number of 1/2/3 word references to data items (i.e., not jal's). */
134 static int num_refs
[3];
136 /* Registers to check for load delay. */
137 static rtx iq2000_load_reg
;
138 static rtx iq2000_load_reg2
;
139 static rtx iq2000_load_reg3
;
140 static rtx iq2000_load_reg4
;
142 /* Mode used for saving/restoring general purpose registers. */
143 static machine_mode gpr_mode
;
146 /* Initialize the GCC target structure. */
147 static struct machine_function
* iq2000_init_machine_status (void);
148 static void iq2000_option_override (void);
149 static section
*iq2000_select_rtx_section (machine_mode
, rtx
,
150 unsigned HOST_WIDE_INT
);
151 static void iq2000_init_builtins (void);
152 static rtx
iq2000_expand_builtin (tree
, rtx
, rtx
, machine_mode
, int);
153 static bool iq2000_return_in_memory (const_tree
, const_tree
);
154 static void iq2000_setup_incoming_varargs (cumulative_args_t
,
155 const function_arg_info
&,
157 static bool iq2000_rtx_costs (rtx
, machine_mode
, int, int, int *, bool);
158 static int iq2000_address_cost (rtx
, machine_mode
, addr_space_t
,
160 static rtx
iq2000_legitimize_address (rtx
, rtx
, machine_mode
);
161 static bool iq2000_pass_by_reference (cumulative_args_t
,
162 const function_arg_info
&);
163 static int iq2000_arg_partial_bytes (cumulative_args_t
,
164 const function_arg_info
&arg
);
165 static rtx
iq2000_function_arg (cumulative_args_t
,
166 const function_arg_info
&);
167 static void iq2000_function_arg_advance (cumulative_args_t
,
168 const function_arg_info
&);
169 static pad_direction
iq2000_function_arg_padding (machine_mode
, const_tree
);
170 static unsigned int iq2000_function_arg_boundary (machine_mode
,
172 static void iq2000_va_start (tree
, rtx
);
173 static bool iq2000_legitimate_address_p (machine_mode
, rtx
, bool,
174 code_helper
= ERROR_MARK
);
175 static bool iq2000_can_eliminate (const int, const int);
176 static void iq2000_asm_trampoline_template (FILE *);
177 static void iq2000_trampoline_init (rtx
, tree
, rtx
);
178 static rtx
iq2000_function_value (const_tree
, const_tree
, bool);
179 static rtx
iq2000_libcall_value (machine_mode
, const_rtx
);
180 static void iq2000_print_operand (FILE *, rtx
, int);
181 static void iq2000_print_operand_address (FILE *, machine_mode
, rtx
);
182 static bool iq2000_print_operand_punct_valid_p (unsigned char code
);
183 static bool iq2000_hard_regno_mode_ok (unsigned int, machine_mode
);
184 static bool iq2000_modes_tieable_p (machine_mode
, machine_mode
);
185 static HOST_WIDE_INT
iq2000_constant_alignment (const_tree
, HOST_WIDE_INT
);
186 static HOST_WIDE_INT
iq2000_starting_frame_offset (void);
188 #undef TARGET_INIT_BUILTINS
189 #define TARGET_INIT_BUILTINS iq2000_init_builtins
190 #undef TARGET_EXPAND_BUILTIN
191 #define TARGET_EXPAND_BUILTIN iq2000_expand_builtin
192 #undef TARGET_ASM_SELECT_RTX_SECTION
193 #define TARGET_ASM_SELECT_RTX_SECTION iq2000_select_rtx_section
194 #undef TARGET_OPTION_OVERRIDE
195 #define TARGET_OPTION_OVERRIDE iq2000_option_override
196 #undef TARGET_RTX_COSTS
197 #define TARGET_RTX_COSTS iq2000_rtx_costs
198 #undef TARGET_ADDRESS_COST
199 #define TARGET_ADDRESS_COST iq2000_address_cost
201 #undef TARGET_LEGITIMIZE_ADDRESS
202 #define TARGET_LEGITIMIZE_ADDRESS iq2000_legitimize_address
204 #undef TARGET_PRINT_OPERAND
205 #define TARGET_PRINT_OPERAND iq2000_print_operand
206 #undef TARGET_PRINT_OPERAND_ADDRESS
207 #define TARGET_PRINT_OPERAND_ADDRESS iq2000_print_operand_address
208 #undef TARGET_PRINT_OPERAND_PUNCT_VALID_P
209 #define TARGET_PRINT_OPERAND_PUNCT_VALID_P iq2000_print_operand_punct_valid_p
211 #undef TARGET_PROMOTE_FUNCTION_MODE
212 #define TARGET_PROMOTE_FUNCTION_MODE default_promote_function_mode_always_promote
213 #undef TARGET_PROMOTE_PROTOTYPES
214 #define TARGET_PROMOTE_PROTOTYPES hook_bool_const_tree_true
216 #undef TARGET_FUNCTION_VALUE
217 #define TARGET_FUNCTION_VALUE iq2000_function_value
218 #undef TARGET_LIBCALL_VALUE
219 #define TARGET_LIBCALL_VALUE iq2000_libcall_value
220 #undef TARGET_RETURN_IN_MEMORY
221 #define TARGET_RETURN_IN_MEMORY iq2000_return_in_memory
222 #undef TARGET_PASS_BY_REFERENCE
223 #define TARGET_PASS_BY_REFERENCE iq2000_pass_by_reference
224 #undef TARGET_CALLEE_COPIES
225 #define TARGET_CALLEE_COPIES hook_callee_copies_named
226 #undef TARGET_ARG_PARTIAL_BYTES
227 #define TARGET_ARG_PARTIAL_BYTES iq2000_arg_partial_bytes
228 #undef TARGET_FUNCTION_ARG
229 #define TARGET_FUNCTION_ARG iq2000_function_arg
230 #undef TARGET_FUNCTION_ARG_ADVANCE
231 #define TARGET_FUNCTION_ARG_ADVANCE iq2000_function_arg_advance
232 #undef TARGET_FUNCTION_ARG_PADDING
233 #define TARGET_FUNCTION_ARG_PADDING iq2000_function_arg_padding
234 #undef TARGET_FUNCTION_ARG_BOUNDARY
235 #define TARGET_FUNCTION_ARG_BOUNDARY iq2000_function_arg_boundary
237 #undef TARGET_SETUP_INCOMING_VARARGS
238 #define TARGET_SETUP_INCOMING_VARARGS iq2000_setup_incoming_varargs
239 #undef TARGET_STRICT_ARGUMENT_NAMING
240 #define TARGET_STRICT_ARGUMENT_NAMING hook_bool_CUMULATIVE_ARGS_true
242 #undef TARGET_EXPAND_BUILTIN_VA_START
243 #define TARGET_EXPAND_BUILTIN_VA_START iq2000_va_start
245 #undef TARGET_LEGITIMATE_ADDRESS_P
246 #define TARGET_LEGITIMATE_ADDRESS_P iq2000_legitimate_address_p
248 #undef TARGET_CAN_ELIMINATE
249 #define TARGET_CAN_ELIMINATE iq2000_can_eliminate
251 #undef TARGET_ASM_TRAMPOLINE_TEMPLATE
252 #define TARGET_ASM_TRAMPOLINE_TEMPLATE iq2000_asm_trampoline_template
253 #undef TARGET_TRAMPOLINE_INIT
254 #define TARGET_TRAMPOLINE_INIT iq2000_trampoline_init
256 #undef TARGET_HARD_REGNO_MODE_OK
257 #define TARGET_HARD_REGNO_MODE_OK iq2000_hard_regno_mode_ok
258 #undef TARGET_MODES_TIEABLE_P
259 #define TARGET_MODES_TIEABLE_P iq2000_modes_tieable_p
261 #undef TARGET_CONSTANT_ALIGNMENT
262 #define TARGET_CONSTANT_ALIGNMENT iq2000_constant_alignment
264 #undef TARGET_STARTING_FRAME_OFFSET
265 #define TARGET_STARTING_FRAME_OFFSET iq2000_starting_frame_offset
267 #undef TARGET_HAVE_SPECULATION_SAFE_VALUE
268 #define TARGET_HAVE_SPECULATION_SAFE_VALUE speculation_safe_value_not_needed
270 struct gcc_target targetm
= TARGET_INITIALIZER
;
272 /* Return nonzero if we split the address into high and low parts. */
275 iq2000_check_split (rtx address
, machine_mode mode
)
277 /* This is the same check used in simple_memory_operand.
278 We use it here because LO_SUM is not offsettable. */
279 if (GET_MODE_SIZE (mode
) > (unsigned) UNITS_PER_WORD
)
282 if ((GET_CODE (address
) == SYMBOL_REF
)
283 || (GET_CODE (address
) == CONST
284 && GET_CODE (XEXP (XEXP (address
, 0), 0)) == SYMBOL_REF
)
285 || GET_CODE (address
) == LABEL_REF
)
291 /* Return nonzero if REG is valid for MODE. */
294 iq2000_reg_mode_ok_for_base_p (rtx reg
,
295 machine_mode mode ATTRIBUTE_UNUSED
,
299 ? REGNO_MODE_OK_FOR_BASE_P (REGNO (reg
), mode
)
300 : GP_REG_OR_PSEUDO_NONSTRICT_P (REGNO (reg
), mode
));
303 /* Return a nonzero value if XINSN is a legitimate address for a
304 memory operand of the indicated MODE. STRICT is nonzero if this
305 function is called during reload. */
308 iq2000_legitimate_address_p (machine_mode mode
, rtx xinsn
, bool strict
,
311 if (TARGET_DEBUG_A_MODE
)
313 GO_PRINTF2 ("\n========== legitimate_address_p, %sstrict\n",
314 strict
? "" : "not ");
315 GO_DEBUG_RTX (xinsn
);
318 /* Check for constant before stripping off SUBREG, so that we don't
319 accept (subreg (const_int)) which will fail to reload. */
320 if (CONSTANT_ADDRESS_P (xinsn
)
321 && ! (iq2000_check_split (xinsn
, mode
))
322 && ! (GET_CODE (xinsn
) == CONST_INT
&& ! SMALL_INT (xinsn
)))
325 while (GET_CODE (xinsn
) == SUBREG
)
326 xinsn
= SUBREG_REG (xinsn
);
328 if (GET_CODE (xinsn
) == REG
329 && iq2000_reg_mode_ok_for_base_p (xinsn
, mode
, strict
))
332 if (GET_CODE (xinsn
) == LO_SUM
)
334 rtx xlow0
= XEXP (xinsn
, 0);
335 rtx xlow1
= XEXP (xinsn
, 1);
337 while (GET_CODE (xlow0
) == SUBREG
)
338 xlow0
= SUBREG_REG (xlow0
);
339 if (GET_CODE (xlow0
) == REG
340 && iq2000_reg_mode_ok_for_base_p (xlow0
, mode
, strict
)
341 && iq2000_check_split (xlow1
, mode
))
345 if (GET_CODE (xinsn
) == PLUS
)
347 rtx xplus0
= XEXP (xinsn
, 0);
348 rtx xplus1
= XEXP (xinsn
, 1);
352 while (GET_CODE (xplus0
) == SUBREG
)
353 xplus0
= SUBREG_REG (xplus0
);
354 code0
= GET_CODE (xplus0
);
356 while (GET_CODE (xplus1
) == SUBREG
)
357 xplus1
= SUBREG_REG (xplus1
);
358 code1
= GET_CODE (xplus1
);
361 && iq2000_reg_mode_ok_for_base_p (xplus0
, mode
, strict
))
363 if (code1
== CONST_INT
&& SMALL_INT (xplus1
)
364 && SMALL_INT_UNSIGNED (xplus1
) /* No negative offsets */)
369 if (TARGET_DEBUG_A_MODE
)
370 GO_PRINTF ("Not a machine_mode mode, legitimate address\n");
372 /* The address was not legitimate. */
376 /* Returns an operand string for the given instruction's delay slot,
377 after updating filled delay slot statistics.
379 We assume that operands[0] is the target register that is set.
381 In order to check the next insn, most of this functionality is moved
382 to FINAL_PRESCAN_INSN, and we just set the global variables that
386 iq2000_fill_delay_slot (const char *ret
, enum delay_type type
, rtx operands
[],
391 rtx_insn
*next_insn
= cur_insn
? NEXT_INSN (cur_insn
) : NULL
;
394 if (type
== DELAY_LOAD
|| type
== DELAY_FCMP
)
400 /* Make sure that we don't put nop's after labels. */
401 next_insn
= NEXT_INSN (cur_insn
);
402 while (next_insn
!= 0
403 && (NOTE_P (next_insn
) || LABEL_P (next_insn
)))
404 next_insn
= NEXT_INSN (next_insn
);
406 dslots_load_total
+= num_nops
;
407 if (TARGET_DEBUG_C_MODE
408 || type
== DELAY_NONE
412 || LABEL_P (next_insn
)
413 || (set_reg
= operands
[0]) == 0)
415 dslots_number_nops
= 0;
417 iq2000_load_reg2
= 0;
418 iq2000_load_reg3
= 0;
419 iq2000_load_reg4
= 0;
424 set_reg
= operands
[0];
428 while (GET_CODE (set_reg
) == SUBREG
)
429 set_reg
= SUBREG_REG (set_reg
);
431 mode
= GET_MODE (set_reg
);
432 dslots_number_nops
= num_nops
;
433 iq2000_load_reg
= set_reg
;
434 if (GET_MODE_SIZE (mode
)
435 > (unsigned) (UNITS_PER_WORD
))
436 iq2000_load_reg2
= gen_rtx_REG (SImode
, REGNO (set_reg
) + 1);
438 iq2000_load_reg2
= 0;
443 /* Determine whether a memory reference takes one (based off of the GP
444 pointer), two (normal), or three (label + reg) instructions, and bump the
445 appropriate counter for -mstats. */
448 iq2000_count_memory_refs (rtx op
, int num
)
452 rtx addr
, plus0
, plus1
;
453 enum rtx_code code0
, code1
;
456 if (TARGET_DEBUG_B_MODE
)
458 fprintf (stderr
, "\n========== iq2000_count_memory_refs:\n");
462 /* Skip MEM if passed, otherwise handle movsi of address. */
463 addr
= (GET_CODE (op
) != MEM
) ? op
: XEXP (op
, 0);
465 /* Loop, going through the address RTL. */
469 switch (GET_CODE (addr
))
477 plus0
= XEXP (addr
, 0);
478 plus1
= XEXP (addr
, 1);
479 code0
= GET_CODE (plus0
);
480 code1
= GET_CODE (plus1
);
490 if (code0
== CONST_INT
)
505 if (code1
== CONST_INT
)
512 if (code0
== SYMBOL_REF
|| code0
== LABEL_REF
|| code0
== CONST
)
519 if (code1
== SYMBOL_REF
|| code1
== LABEL_REF
|| code1
== CONST
)
529 n_words
= 2; /* Always 2 words. */
533 addr
= XEXP (addr
, 0);
538 n_words
= SYMBOL_REF_FLAG (addr
) ? 1 : 2;
550 n_words
+= additional
;
554 num_refs
[n_words
-1] += num
;
557 /* Abort after printing out a specific insn. */
560 abort_with_insn (rtx insn
, const char * reason
)
564 fancy_abort (__FILE__
, __LINE__
, __FUNCTION__
);
567 /* Return the appropriate instructions to move one operand to another. */
570 iq2000_move_1word (rtx operands
[], rtx_insn
*insn
, int unsignedp
)
573 rtx op0
= operands
[0];
574 rtx op1
= operands
[1];
575 enum rtx_code code0
= GET_CODE (op0
);
576 enum rtx_code code1
= GET_CODE (op1
);
577 machine_mode mode
= GET_MODE (op0
);
578 int subreg_offset0
= 0;
579 int subreg_offset1
= 0;
580 enum delay_type delay
= DELAY_NONE
;
582 while (code0
== SUBREG
)
584 subreg_offset0
+= subreg_regno_offset (REGNO (SUBREG_REG (op0
)),
585 GET_MODE (SUBREG_REG (op0
)),
588 op0
= SUBREG_REG (op0
);
589 code0
= GET_CODE (op0
);
592 while (code1
== SUBREG
)
594 subreg_offset1
+= subreg_regno_offset (REGNO (SUBREG_REG (op1
)),
595 GET_MODE (SUBREG_REG (op1
)),
598 op1
= SUBREG_REG (op1
);
599 code1
= GET_CODE (op1
);
602 /* For our purposes, a condition code mode is the same as SImode. */
608 int regno0
= REGNO (op0
) + subreg_offset0
;
612 int regno1
= REGNO (op1
) + subreg_offset1
;
614 /* Do not do anything for assigning a register to itself */
615 if (regno0
== regno1
)
618 else if (GP_REG_P (regno0
))
620 if (GP_REG_P (regno1
))
621 ret
= "or\t%0,%%0,%1";
626 else if (code1
== MEM
)
631 iq2000_count_memory_refs (op1
, 1);
633 if (GP_REG_P (regno0
))
635 /* For loads, use the mode of the memory item, instead of the
636 target, so zero/sign extend can use this code as well. */
637 switch (GET_MODE (op1
))
649 ret
= (unsignedp
) ? "lhu\t%0,%1" : "lh\t%0,%1";
652 ret
= (unsignedp
) ? "lbu\t%0,%1" : "lb\t%0,%1";
658 else if (code1
== CONST_INT
659 || (code1
== CONST_DOUBLE
660 && GET_MODE (op1
) == VOIDmode
))
662 if (code1
== CONST_DOUBLE
)
664 /* This can happen when storing constants into long long
665 bitfields. Just store the least significant word of
667 operands
[1] = op1
= GEN_INT (CONST_DOUBLE_LOW (op1
));
670 if (INTVAL (op1
) == 0)
672 if (GP_REG_P (regno0
))
673 ret
= "or\t%0,%%0,%z1";
675 else if (GP_REG_P (regno0
))
677 if (SMALL_INT_UNSIGNED (op1
))
678 ret
= "ori\t%0,%%0,%x1\t\t\t# %1";
679 else if (SMALL_INT (op1
))
680 ret
= "addiu\t%0,%%0,%1\t\t\t# %1";
682 ret
= "lui\t%0,%X1\t\t\t# %1\n\tori\t%0,%0,%x1";
686 else if (code1
== CONST_DOUBLE
&& mode
== SFmode
)
688 if (op1
== CONST0_RTX (SFmode
))
690 if (GP_REG_P (regno0
))
691 ret
= "or\t%0,%%0,%.";
701 else if (code1
== LABEL_REF
)
704 iq2000_count_memory_refs (op1
, 1);
709 else if (code1
== SYMBOL_REF
|| code1
== CONST
)
712 iq2000_count_memory_refs (op1
, 1);
717 else if (code1
== PLUS
)
719 rtx add_op0
= XEXP (op1
, 0);
720 rtx add_op1
= XEXP (op1
, 1);
722 if (GET_CODE (XEXP (op1
, 1)) == REG
723 && GET_CODE (XEXP (op1
, 0)) == CONST_INT
)
724 add_op0
= XEXP (op1
, 1), add_op1
= XEXP (op1
, 0);
726 operands
[2] = add_op0
;
727 operands
[3] = add_op1
;
728 ret
= "add%:\t%0,%2,%3";
731 else if (code1
== HIGH
)
733 operands
[1] = XEXP (op1
, 0);
734 ret
= "lui\t%0,%%hi(%1)";
738 else if (code0
== MEM
)
741 iq2000_count_memory_refs (op0
, 1);
745 int regno1
= REGNO (op1
) + subreg_offset1
;
747 if (GP_REG_P (regno1
))
751 case E_SFmode
: ret
= "sw\t%1,%0"; break;
752 case E_SImode
: ret
= "sw\t%1,%0"; break;
753 case E_HImode
: ret
= "sh\t%1,%0"; break;
754 case E_QImode
: ret
= "sb\t%1,%0"; break;
760 else if (code1
== CONST_INT
&& INTVAL (op1
) == 0)
764 case E_SFmode
: ret
= "sw\t%z1,%0"; break;
765 case E_SImode
: ret
= "sw\t%z1,%0"; break;
766 case E_HImode
: ret
= "sh\t%z1,%0"; break;
767 case E_QImode
: ret
= "sb\t%z1,%0"; break;
772 else if (code1
== CONST_DOUBLE
&& op1
== CONST0_RTX (mode
))
776 case E_SFmode
: ret
= "sw\t%.,%0"; break;
777 case E_SImode
: ret
= "sw\t%.,%0"; break;
778 case E_HImode
: ret
= "sh\t%.,%0"; break;
779 case E_QImode
: ret
= "sb\t%.,%0"; break;
787 abort_with_insn (insn
, "Bad move");
791 if (delay
!= DELAY_NONE
)
792 return iq2000_fill_delay_slot (ret
, delay
, operands
, insn
);
797 /* Provide the costs of an addressing mode that contains ADDR. */
800 iq2000_address_cost (rtx addr
, machine_mode mode
, addr_space_t as
,
803 switch (GET_CODE (addr
))
813 rtx offset
= const0_rtx
;
815 addr
= eliminate_constant_term (XEXP (addr
, 0), & offset
);
816 if (GET_CODE (addr
) == LABEL_REF
)
819 if (GET_CODE (addr
) != SYMBOL_REF
)
822 if (! SMALL_INT (offset
))
829 return SYMBOL_REF_FLAG (addr
) ? 1 : 2;
833 rtx plus0
= XEXP (addr
, 0);
834 rtx plus1
= XEXP (addr
, 1);
836 if (GET_CODE (plus0
) != REG
&& GET_CODE (plus1
) == REG
)
837 plus0
= XEXP (addr
, 1), plus1
= XEXP (addr
, 0);
839 if (GET_CODE (plus0
) != REG
)
842 switch (GET_CODE (plus1
))
845 return SMALL_INT (plus1
) ? 1 : 2;
852 return iq2000_address_cost (plus1
, mode
, as
, speed
) + 1;
866 /* Make normal rtx_code into something we can index from an array. */
868 static enum internal_test
869 map_test_to_internal_test (enum rtx_code test_code
)
871 enum internal_test test
= ITEST_MAX
;
875 case EQ
: test
= ITEST_EQ
; break;
876 case NE
: test
= ITEST_NE
; break;
877 case GT
: test
= ITEST_GT
; break;
878 case GE
: test
= ITEST_GE
; break;
879 case LT
: test
= ITEST_LT
; break;
880 case LE
: test
= ITEST_LE
; break;
881 case GTU
: test
= ITEST_GTU
; break;
882 case GEU
: test
= ITEST_GEU
; break;
883 case LTU
: test
= ITEST_LTU
; break;
884 case LEU
: test
= ITEST_LEU
; break;
891 /* Generate the code to do a TEST_CODE comparison on two integer values CMP0
892 and CMP1. P_INVERT is NULL or ptr if branch needs to reverse its test.
893 The return value RESULT is:
894 (reg:SI xx) The pseudo register the comparison is in
895 0 No register, generate a simple branch. */
898 gen_int_relational (enum rtx_code test_code
, rtx result
, rtx cmp0
, rtx cmp1
,
903 enum rtx_code test_code
; /* Code to use in instruction (LT vs. LTU). */
904 int const_low
; /* Low bound of constant we can accept. */
905 int const_high
; /* High bound of constant we can accept. */
906 int const_add
; /* Constant to add (convert LE -> LT). */
907 int reverse_regs
; /* Reverse registers in test. */
908 int invert_const
; /* != 0 if invert value if cmp1 is constant. */
909 int invert_reg
; /* != 0 if invert value if cmp1 is register. */
910 int unsignedp
; /* != 0 for unsigned comparisons. */
913 static struct cmp_info info
[ (int)ITEST_MAX
] =
915 { XOR
, 0, 65535, 0, 0, 0, 0, 0 }, /* EQ */
916 { XOR
, 0, 65535, 0, 0, 1, 1, 0 }, /* NE */
917 { LT
, -32769, 32766, 1, 1, 1, 0, 0 }, /* GT */
918 { LT
, -32768, 32767, 0, 0, 1, 1, 0 }, /* GE */
919 { LT
, -32768, 32767, 0, 0, 0, 0, 0 }, /* LT */
920 { LT
, -32769, 32766, 1, 1, 0, 1, 0 }, /* LE */
921 { LTU
, -32769, 32766, 1, 1, 1, 0, 1 }, /* GTU */
922 { LTU
, -32768, 32767, 0, 0, 1, 1, 1 }, /* GEU */
923 { LTU
, -32768, 32767, 0, 0, 0, 0, 1 }, /* LTU */
924 { LTU
, -32769, 32766, 1, 1, 0, 1, 1 }, /* LEU */
927 enum internal_test test
;
929 struct cmp_info
*p_info
;
936 test
= map_test_to_internal_test (test_code
);
937 gcc_assert (test
!= ITEST_MAX
);
939 p_info
= &info
[(int) test
];
940 eqne_p
= (p_info
->test_code
== XOR
);
942 mode
= GET_MODE (cmp0
);
943 if (mode
== VOIDmode
)
944 mode
= GET_MODE (cmp1
);
946 /* Eliminate simple branches. */
947 branch_p
= (result
== 0);
950 if (GET_CODE (cmp0
) == REG
|| GET_CODE (cmp0
) == SUBREG
)
952 /* Comparisons against zero are simple branches. */
953 if (GET_CODE (cmp1
) == CONST_INT
&& INTVAL (cmp1
) == 0)
956 /* Test for beq/bne. */
961 /* Allocate a pseudo to calculate the value in. */
962 result
= gen_reg_rtx (mode
);
965 /* Make sure we can handle any constants given to us. */
966 if (GET_CODE (cmp0
) == CONST_INT
)
967 cmp0
= force_reg (mode
, cmp0
);
969 if (GET_CODE (cmp1
) == CONST_INT
)
971 HOST_WIDE_INT value
= INTVAL (cmp1
);
973 if (value
< p_info
->const_low
974 || value
> p_info
->const_high
)
975 cmp1
= force_reg (mode
, cmp1
);
978 /* See if we need to invert the result. */
979 invert
= (GET_CODE (cmp1
) == CONST_INT
980 ? p_info
->invert_const
: p_info
->invert_reg
);
982 if (p_invert
!= (int *)0)
988 /* Comparison to constants, may involve adding 1 to change a LT into LE.
989 Comparison between two registers, may involve switching operands. */
990 if (GET_CODE (cmp1
) == CONST_INT
)
992 if (p_info
->const_add
!= 0)
994 HOST_WIDE_INT new_const
= INTVAL (cmp1
) + p_info
->const_add
;
996 /* If modification of cmp1 caused overflow,
997 we would get the wrong answer if we follow the usual path;
998 thus, x > 0xffffffffU would turn into x > 0U. */
999 if ((p_info
->unsignedp
1000 ? (unsigned HOST_WIDE_INT
) new_const
>
1001 (unsigned HOST_WIDE_INT
) INTVAL (cmp1
)
1002 : new_const
> INTVAL (cmp1
))
1003 != (p_info
->const_add
> 0))
1005 /* This test is always true, but if INVERT is true then
1006 the result of the test needs to be inverted so 0 should
1007 be returned instead. */
1008 emit_move_insn (result
, invert
? const0_rtx
: const_true_rtx
);
1012 cmp1
= GEN_INT (new_const
);
1016 else if (p_info
->reverse_regs
)
1023 if (test
== ITEST_NE
&& GET_CODE (cmp1
) == CONST_INT
&& INTVAL (cmp1
) == 0)
1027 reg
= (invert
|| eqne_p
) ? gen_reg_rtx (mode
) : result
;
1028 convert_move (reg
, gen_rtx_fmt_ee (p_info
->test_code
, mode
, cmp0
, cmp1
), 0);
1031 if (test
== ITEST_NE
)
1033 convert_move (result
, gen_rtx_GTU (mode
, reg
, const0_rtx
), 0);
1034 if (p_invert
!= NULL
)
1039 else if (test
== ITEST_EQ
)
1041 reg2
= invert
? gen_reg_rtx (mode
) : result
;
1042 convert_move (reg2
, gen_rtx_LTU (mode
, reg
, const1_rtx
), 0);
1051 convert_move (result
, gen_rtx_XOR (mode
, reg
, one
), 0);
1057 /* Emit the common code for doing conditional branches.
1058 operand[0] is the label to jump to.
1059 The comparison operands are saved away by cmp{si,di,sf,df}. */
1062 gen_conditional_branch (rtx operands
[], machine_mode mode
)
1064 enum rtx_code test_code
= GET_CODE (operands
[0]);
1065 rtx cmp0
= operands
[1];
1066 rtx cmp1
= operands
[2];
1072 reg
= gen_int_relational (test_code
, NULL_RTX
, cmp0
, cmp1
, &invert
);
1080 else if (GET_CODE (cmp1
) == CONST_INT
&& INTVAL (cmp1
) != 0)
1081 /* We don't want to build a comparison against a nonzero
1083 cmp1
= force_reg (mode
, cmp1
);
1085 /* Generate the branch. */
1086 label1
= gen_rtx_LABEL_REF (VOIDmode
, operands
[3]);
1095 emit_jump_insn (gen_rtx_SET (pc_rtx
,
1096 gen_rtx_IF_THEN_ELSE (VOIDmode
,
1097 gen_rtx_fmt_ee (test_code
,
1103 /* Initialize CUM for a function FNTYPE. */
1106 init_cumulative_args (CUMULATIVE_ARGS
*cum
, tree fntype
,
1107 rtx libname ATTRIBUTE_UNUSED
)
1109 static CUMULATIVE_ARGS zero_cum
;
1113 if (TARGET_DEBUG_D_MODE
)
1116 "\ninit_cumulative_args, fntype = 0x%.8lx", (long) fntype
);
1119 fputc ('\n', stderr
);
1123 tree ret_type
= TREE_TYPE (fntype
);
1125 fprintf (stderr
, ", fntype code = %s, ret code = %s\n",
1126 get_tree_code_name (TREE_CODE (fntype
)),
1127 get_tree_code_name (TREE_CODE (ret_type
)));
1133 /* Determine if this function has variable arguments. This is
1134 indicated by the last argument being 'void_type_mode' if there
1135 are no variable arguments. The standard IQ2000 calling sequence
1136 passes all arguments in the general purpose registers in this case. */
1138 for (param
= fntype
? TYPE_ARG_TYPES (fntype
) : 0;
1139 param
!= 0; param
= next_param
)
1141 next_param
= TREE_CHAIN (param
);
1142 if (next_param
== 0 && TREE_VALUE (param
) != void_type_node
)
1143 cum
->gp_reg_found
= 1;
1147 /* Implement TARGET_FUNCTION_ARG_ADVANCE. */
1150 iq2000_function_arg_advance (cumulative_args_t cum_v
,
1151 const function_arg_info
&arg
)
1153 CUMULATIVE_ARGS
*cum
= get_cumulative_args (cum_v
);
1155 if (TARGET_DEBUG_D_MODE
)
1158 "function_adv({gp reg found = %d, arg # = %2d, words = %2d}, %4s, ",
1159 cum
->gp_reg_found
, cum
->arg_number
, cum
->arg_words
,
1160 GET_MODE_NAME (arg
.mode
));
1161 fprintf (stderr
, "%p", (const void *) arg
.type
);
1162 fprintf (stderr
, ", %d )\n\n", arg
.named
);
1172 gcc_assert (GET_MODE_CLASS (arg
.mode
) == MODE_COMPLEX_INT
1173 || GET_MODE_CLASS (arg
.mode
) == MODE_COMPLEX_FLOAT
);
1175 cum
->gp_reg_found
= 1;
1176 cum
->arg_words
+= ((GET_MODE_SIZE (arg
.mode
) + UNITS_PER_WORD
- 1)
1181 cum
->gp_reg_found
= 1;
1182 cum
->arg_words
+= ((int_size_in_bytes (arg
.type
) + UNITS_PER_WORD
- 1)
1188 if (! cum
->gp_reg_found
&& cum
->arg_number
<= 2)
1189 cum
->fp_code
+= 1 << ((cum
->arg_number
- 1) * 2);
1193 cum
->arg_words
+= 2;
1194 if (! cum
->gp_reg_found
&& cum
->arg_number
<= 2)
1195 cum
->fp_code
+= 2 << ((cum
->arg_number
- 1) * 2);
1199 cum
->gp_reg_found
= 1;
1200 cum
->arg_words
+= 2;
1204 cum
->gp_reg_found
= 1;
1205 cum
->arg_words
+= 4;
1211 cum
->gp_reg_found
= 1;
1217 /* Return an RTL expression containing the register for argument ARG in CUM,
1218 or 0 if the argument is to be passed on the stack. */
1221 iq2000_function_arg (cumulative_args_t cum_v
, const function_arg_info
&arg
)
1223 CUMULATIVE_ARGS
*cum
= get_cumulative_args (cum_v
);
1224 tree type
= arg
.type
;
1225 machine_mode mode
= arg
.mode
;
1229 unsigned int *arg_words
= &cum
->arg_words
;
1230 int struct_p
= (type
!= 0
1231 && RECORD_OR_UNION_TYPE_P (type
));
1233 if (TARGET_DEBUG_D_MODE
)
1236 "function_arg( {gp reg found = %d, arg # = %2d, words = %2d}, %4s, ",
1237 cum
->gp_reg_found
, cum
->arg_number
, cum
->arg_words
,
1238 GET_MODE_NAME (mode
));
1239 fprintf (stderr
, "%p", (const void *) type
);
1240 fprintf (stderr
, ", %d ) = ", arg
.named
);
1244 cum
->last_arg_fp
= 0;
1248 regbase
= GP_ARG_FIRST
;
1252 cum
->arg_words
+= cum
->arg_words
& 1;
1254 regbase
= GP_ARG_FIRST
;
1258 gcc_assert (GET_MODE_CLASS (mode
) == MODE_COMPLEX_INT
1259 || GET_MODE_CLASS (mode
) == MODE_COMPLEX_FLOAT
);
1263 if (type
!= NULL_TREE
&& TYPE_ALIGN (type
) > (unsigned) BITS_PER_WORD
)
1264 cum
->arg_words
+= (cum
->arg_words
& 1);
1265 regbase
= GP_ARG_FIRST
;
1272 regbase
= GP_ARG_FIRST
;
1276 cum
->arg_words
+= (cum
->arg_words
& 1);
1277 regbase
= GP_ARG_FIRST
;
1281 cum
->arg_words
+= (cum
->arg_words
& 3);
1282 regbase
= GP_ARG_FIRST
;
1286 if (*arg_words
>= (unsigned) MAX_ARGS_IN_REGISTERS
)
1288 if (TARGET_DEBUG_D_MODE
)
1289 fprintf (stderr
, "<stack>%s\n", struct_p
? ", [struct]" : "");
1295 gcc_assert (regbase
!= -1);
1297 if (! type
|| TREE_CODE (type
) != RECORD_TYPE
1298 || ! arg
.named
|| ! TYPE_SIZE_UNIT (type
)
1299 || ! tree_fits_uhwi_p (TYPE_SIZE_UNIT (type
)))
1300 ret
= gen_rtx_REG (mode
, regbase
+ *arg_words
+ bias
);
1305 for (field
= TYPE_FIELDS (type
); field
; field
= DECL_CHAIN (field
))
1306 if (TREE_CODE (field
) == FIELD_DECL
1307 && SCALAR_FLOAT_TYPE_P (TREE_TYPE (field
))
1308 && TYPE_PRECISION (TREE_TYPE (field
)) == BITS_PER_WORD
1309 && tree_fits_shwi_p (bit_position (field
))
1310 && int_bit_position (field
) % BITS_PER_WORD
== 0)
1313 /* If the whole struct fits a DFmode register,
1314 we don't need the PARALLEL. */
1315 if (! field
|| mode
== DFmode
)
1316 ret
= gen_rtx_REG (mode
, regbase
+ *arg_words
+ bias
);
1319 unsigned int chunks
;
1320 HOST_WIDE_INT bitpos
;
1324 /* ??? If this is a packed structure, then the last hunk won't
1327 = tree_to_uhwi (TYPE_SIZE_UNIT (type
)) / UNITS_PER_WORD
;
1328 if (chunks
+ *arg_words
+ bias
> (unsigned) MAX_ARGS_IN_REGISTERS
)
1329 chunks
= MAX_ARGS_IN_REGISTERS
- *arg_words
- bias
;
1331 /* Assign_parms checks the mode of ENTRY_PARM, so we must
1332 use the actual mode here. */
1333 ret
= gen_rtx_PARALLEL (mode
, rtvec_alloc (chunks
));
1336 regno
= regbase
+ *arg_words
+ bias
;
1337 field
= TYPE_FIELDS (type
);
1338 for (i
= 0; i
< chunks
; i
++)
1342 for (; field
; field
= DECL_CHAIN (field
))
1343 if (TREE_CODE (field
) == FIELD_DECL
1344 && int_bit_position (field
) >= bitpos
)
1348 && int_bit_position (field
) == bitpos
1349 && SCALAR_FLOAT_TYPE_P (TREE_TYPE (field
))
1350 && TYPE_PRECISION (TREE_TYPE (field
)) == BITS_PER_WORD
)
1351 reg
= gen_rtx_REG (DFmode
, regno
++);
1353 reg
= gen_rtx_REG (word_mode
, regno
);
1356 = gen_rtx_EXPR_LIST (VOIDmode
, reg
,
1357 GEN_INT (bitpos
/ BITS_PER_UNIT
));
1365 if (TARGET_DEBUG_D_MODE
)
1366 fprintf (stderr
, "%s%s\n", reg_names
[regbase
+ *arg_words
+ bias
],
1367 struct_p
? ", [struct]" : "");
1370 /* We will be called with an end marker after the last argument
1371 has been seen. Whatever we return will be passed to the call
1372 insn. If we need any shifts for small structures, return them in
1374 if (arg
.end_marker_p ())
1376 if (cum
->num_adjusts
> 0)
1377 ret
= gen_rtx_PARALLEL ((machine_mode
) cum
->fp_code
,
1378 gen_rtvec_v (cum
->num_adjusts
, cum
->adjust
));
1384 /* Implement TARGET_FUNCTION_ARG_PADDING. */
1386 static pad_direction
1387 iq2000_function_arg_padding (machine_mode mode
, const_tree type
)
1389 return (! BYTES_BIG_ENDIAN
1393 && TREE_CODE (TYPE_SIZE (type
)) == INTEGER_CST
1394 && int_size_in_bytes (type
) < (PARM_BOUNDARY
/ BITS_PER_UNIT
))
1395 : (GET_MODE_BITSIZE (mode
) < PARM_BOUNDARY
1396 && GET_MODE_CLASS (mode
) == MODE_INT
))
1397 ? PAD_DOWNWARD
: PAD_UPWARD
));
1401 iq2000_function_arg_boundary (machine_mode mode
, const_tree type
)
1403 return (type
!= NULL_TREE
1404 ? (TYPE_ALIGN (type
) <= PARM_BOUNDARY
1406 : TYPE_ALIGN (type
))
1407 : (GET_MODE_ALIGNMENT (mode
) <= PARM_BOUNDARY
1409 : GET_MODE_ALIGNMENT (mode
)));
1413 iq2000_arg_partial_bytes (cumulative_args_t cum_v
,
1414 const function_arg_info
&arg
)
1416 CUMULATIVE_ARGS
*cum
= get_cumulative_args (cum_v
);
1418 if (arg
.mode
== DImode
&& cum
->arg_words
== MAX_ARGS_IN_REGISTERS
- 1)
1420 if (TARGET_DEBUG_D_MODE
)
1421 fprintf (stderr
, "iq2000_arg_partial_bytes=%d\n", UNITS_PER_WORD
);
1422 return UNITS_PER_WORD
;
1428 /* Implement va_start. */
1431 iq2000_va_start (tree valist
, rtx nextarg
)
1434 /* Find out how many non-float named formals. */
1435 int gpr_save_area_size
;
1436 /* Note UNITS_PER_WORD is 4 bytes. */
1437 int_arg_words
= crtl
->args
.info
.arg_words
;
1439 if (int_arg_words
< 8 )
1440 /* Adjust for the prologue's economy measure. */
1441 gpr_save_area_size
= (8 - int_arg_words
) * UNITS_PER_WORD
;
1443 gpr_save_area_size
= 0;
1445 /* Everything is in the GPR save area, or in the overflow
1446 area which is contiguous with it. */
1447 nextarg
= plus_constant (Pmode
, nextarg
, - gpr_save_area_size
);
1448 std_expand_builtin_va_start (valist
, nextarg
);
1451 /* Allocate a chunk of memory for per-function machine-dependent data. */
1453 static struct machine_function
*
1454 iq2000_init_machine_status (void)
1456 return ggc_cleared_alloc
<machine_function
> ();
1459 /* Detect any conflicts in the switches. */
1462 iq2000_option_override (void)
1464 target_flags
&= ~MASK_GPOPT
;
1466 iq2000_isa
= IQ2000_ISA_DEFAULT
;
1468 /* Identify the processor type. */
1470 iq2000_print_operand_punct
['?'] = 1;
1471 iq2000_print_operand_punct
['#'] = 1;
1472 iq2000_print_operand_punct
['&'] = 1;
1473 iq2000_print_operand_punct
['!'] = 1;
1474 iq2000_print_operand_punct
['*'] = 1;
1475 iq2000_print_operand_punct
['@'] = 1;
1476 iq2000_print_operand_punct
['.'] = 1;
1477 iq2000_print_operand_punct
['('] = 1;
1478 iq2000_print_operand_punct
[')'] = 1;
1479 iq2000_print_operand_punct
['['] = 1;
1480 iq2000_print_operand_punct
[']'] = 1;
1481 iq2000_print_operand_punct
['<'] = 1;
1482 iq2000_print_operand_punct
['>'] = 1;
1483 iq2000_print_operand_punct
['{'] = 1;
1484 iq2000_print_operand_punct
['}'] = 1;
1485 iq2000_print_operand_punct
['^'] = 1;
1486 iq2000_print_operand_punct
['$'] = 1;
1487 iq2000_print_operand_punct
['+'] = 1;
1488 iq2000_print_operand_punct
['~'] = 1;
1490 /* Save GPR registers in word_mode sized hunks. word_mode hasn't been
1491 initialized yet, so we can't use that here. */
1494 /* Function to allocate machine-dependent function status. */
1495 init_machine_status
= iq2000_init_machine_status
;
1498 /* The arg pointer (which is eliminated) points to the virtual frame pointer,
1499 while the frame pointer (which may be eliminated) points to the stack
1500 pointer after the initial adjustments. */
1503 iq2000_debugger_offset (rtx addr
, HOST_WIDE_INT offset
)
1505 rtx offset2
= const0_rtx
;
1506 rtx reg
= eliminate_constant_term (addr
, & offset2
);
1509 offset
= INTVAL (offset2
);
1511 if (reg
== stack_pointer_rtx
|| reg
== frame_pointer_rtx
1512 || reg
== hard_frame_pointer_rtx
)
1514 HOST_WIDE_INT frame_size
= (!cfun
->machine
->initialized
)
1515 ? compute_frame_size (get_frame_size ())
1516 : cfun
->machine
->total_size
;
1518 offset
= offset
- frame_size
;
1524 /* If defined, a C statement to be executed just prior to the output of
1525 assembler code for INSN, to modify the extracted operands so they will be
1528 Here the argument OPVEC is the vector containing the operands extracted
1529 from INSN, and NOPERANDS is the number of elements of the vector which
1530 contain meaningful data for this insn. The contents of this vector are
1531 what will be used to convert the insn template into assembler code, so you
1532 can change the assembler output by changing the contents of the vector.
1534 We use it to check if the current insn needs a nop in front of it because
1535 of load delays, and also to update the delay slot statistics. */
1538 final_prescan_insn (rtx_insn
*insn
, rtx opvec
[] ATTRIBUTE_UNUSED
,
1539 int noperands ATTRIBUTE_UNUSED
)
1541 if (dslots_number_nops
> 0)
1543 rtx pattern
= PATTERN (insn
);
1544 int length
= get_attr_length (insn
);
1546 /* Do we need to emit a NOP? */
1548 || (iq2000_load_reg
!= 0 && reg_mentioned_p (iq2000_load_reg
, pattern
))
1549 || (iq2000_load_reg2
!= 0 && reg_mentioned_p (iq2000_load_reg2
, pattern
))
1550 || (iq2000_load_reg3
!= 0 && reg_mentioned_p (iq2000_load_reg3
, pattern
))
1551 || (iq2000_load_reg4
!= 0
1552 && reg_mentioned_p (iq2000_load_reg4
, pattern
)))
1553 fputs ("\tnop\n", asm_out_file
);
1556 dslots_load_filled
++;
1558 while (--dslots_number_nops
> 0)
1559 fputs ("\tnop\n", asm_out_file
);
1561 iq2000_load_reg
= 0;
1562 iq2000_load_reg2
= 0;
1563 iq2000_load_reg3
= 0;
1564 iq2000_load_reg4
= 0;
1569 || (GET_CODE (PATTERN (insn
)) == RETURN
))
1570 && NEXT_INSN (PREV_INSN (insn
)) == insn
)
1572 rtx_insn
*nop_insn
= emit_insn_after (gen_nop (), insn
);
1573 INSN_ADDRESSES_NEW (nop_insn
, -1);
1577 && (JUMP_P (insn
) || CALL_P (insn
)))
1578 dslots_jump_total
++;
1581 /* Return the bytes needed to compute the frame pointer from the current
1582 stack pointer where SIZE is the # of var. bytes allocated.
1584 IQ2000 stack frames look like:
1586 Before call After call
1587 +-----------------------+ +-----------------------+
1590 | caller's temps. | | caller's temps. |
1592 +-----------------------+ +-----------------------+
1594 | arguments on stack. | | arguments on stack. |
1596 +-----------------------+ +-----------------------+
1597 | 4 words to save | | 4 words to save |
1598 | arguments passed | | arguments passed |
1599 | in registers, even | | in registers, even |
1600 SP->| if not passed. | VFP->| if not passed. |
1601 +-----------------------+ +-----------------------+
1603 | fp register save |
1605 +-----------------------+
1607 | gp register save |
1609 +-----------------------+
1613 +-----------------------+
1615 | alloca allocations |
1617 +-----------------------+
1619 | GP save for V.4 abi |
1621 +-----------------------+
1623 | arguments on stack |
1625 +-----------------------+
1627 | arguments passed |
1628 | in registers, even |
1629 low SP->| if not passed. |
1630 memory +-----------------------+ */
1633 compute_frame_size (HOST_WIDE_INT size
)
1636 HOST_WIDE_INT total_size
; /* # bytes that the entire frame takes up. */
1637 HOST_WIDE_INT var_size
; /* # bytes that variables take up. */
1638 HOST_WIDE_INT args_size
; /* # bytes that outgoing arguments take up. */
1639 HOST_WIDE_INT extra_size
; /* # extra bytes. */
1640 HOST_WIDE_INT gp_reg_rounded
; /* # bytes needed to store gp after rounding. */
1641 HOST_WIDE_INT gp_reg_size
; /* # bytes needed to store gp regs. */
1642 HOST_WIDE_INT fp_reg_size
; /* # bytes needed to store fp regs. */
1643 long mask
; /* mask of saved gp registers. */
1648 extra_size
= IQ2000_STACK_ALIGN ((0));
1649 var_size
= IQ2000_STACK_ALIGN (size
);
1650 args_size
= IQ2000_STACK_ALIGN (crtl
->outgoing_args_size
);
1652 /* If a function dynamically allocates the stack and
1653 has 0 for STACK_DYNAMIC_OFFSET then allocate some stack space. */
1654 if (args_size
== 0 && cfun
->calls_alloca
)
1655 args_size
= 4 * UNITS_PER_WORD
;
1657 total_size
= var_size
+ args_size
+ extra_size
;
1659 /* Calculate space needed for gp registers. */
1660 for (regno
= GP_REG_FIRST
; regno
<= GP_REG_LAST
; regno
++)
1662 if (MUST_SAVE_REGISTER (regno
))
1664 gp_reg_size
+= GET_MODE_SIZE (gpr_mode
);
1665 mask
|= 1L << (regno
- GP_REG_FIRST
);
1669 /* We need to restore these for the handler. */
1670 if (crtl
->calls_eh_return
)
1676 regno
= EH_RETURN_DATA_REGNO (i
);
1677 if (regno
== (int) INVALID_REGNUM
)
1679 gp_reg_size
+= GET_MODE_SIZE (gpr_mode
);
1680 mask
|= 1L << (regno
- GP_REG_FIRST
);
1684 gp_reg_rounded
= IQ2000_STACK_ALIGN (gp_reg_size
);
1685 total_size
+= gp_reg_rounded
+ IQ2000_STACK_ALIGN (fp_reg_size
);
1687 /* The gp reg is caller saved, so there is no need for leaf routines
1688 (total_size == extra_size) to save the gp reg. */
1689 if (total_size
== extra_size
1691 total_size
= extra_size
= 0;
1693 total_size
+= IQ2000_STACK_ALIGN (crtl
->args
.pretend_args_size
);
1695 /* Save other computed information. */
1696 cfun
->machine
->total_size
= total_size
;
1697 cfun
->machine
->var_size
= var_size
;
1698 cfun
->machine
->args_size
= args_size
;
1699 cfun
->machine
->extra_size
= extra_size
;
1700 cfun
->machine
->gp_reg_size
= gp_reg_size
;
1701 cfun
->machine
->fp_reg_size
= fp_reg_size
;
1702 cfun
->machine
->mask
= mask
;
1703 cfun
->machine
->initialized
= reload_completed
;
1704 cfun
->machine
->num_gp
= gp_reg_size
/ UNITS_PER_WORD
;
1708 unsigned long offset
;
1710 offset
= (args_size
+ extra_size
+ var_size
1711 + gp_reg_size
- GET_MODE_SIZE (gpr_mode
));
1713 cfun
->machine
->gp_sp_offset
= offset
;
1714 cfun
->machine
->gp_save_offset
= offset
- total_size
;
1718 cfun
->machine
->gp_sp_offset
= 0;
1719 cfun
->machine
->gp_save_offset
= 0;
1722 cfun
->machine
->fp_sp_offset
= 0;
1723 cfun
->machine
->fp_save_offset
= 0;
1725 /* Ok, we're done. */
1730 /* We can always eliminate to the frame pointer. We can eliminate to the
1731 stack pointer unless a frame pointer is needed. */
1734 iq2000_can_eliminate (const int from
, const int to
)
1736 return (from
== RETURN_ADDRESS_POINTER_REGNUM
1737 && (! leaf_function_p ()
1738 || (to
== GP_REG_FIRST
+ 31 && leaf_function_p ())))
1739 || (from
!= RETURN_ADDRESS_POINTER_REGNUM
1740 && (to
== HARD_FRAME_POINTER_REGNUM
1741 || (to
== STACK_POINTER_REGNUM
1742 && ! frame_pointer_needed
)));
1745 /* Implement INITIAL_ELIMINATION_OFFSET. FROM is either the frame
1746 pointer, argument pointer, or return address pointer. TO is either
1747 the stack pointer or hard frame pointer. */
1750 iq2000_initial_elimination_offset (int from
, int to ATTRIBUTE_UNUSED
)
1754 compute_frame_size (get_frame_size ());
1755 if ((from
) == FRAME_POINTER_REGNUM
)
1757 else if ((from
) == ARG_POINTER_REGNUM
)
1758 (offset
) = (cfun
->machine
->total_size
);
1759 else if ((from
) == RETURN_ADDRESS_POINTER_REGNUM
)
1761 if (leaf_function_p ())
1763 else (offset
) = cfun
->machine
->gp_sp_offset
1764 + ((UNITS_PER_WORD
- (POINTER_SIZE
/ BITS_PER_UNIT
))
1765 * (BYTES_BIG_ENDIAN
!= 0));
1773 /* Common code to emit the insns (or to write the instructions to a file)
1774 to save/restore registers.
1775 Other parts of the code assume that IQ2000_TEMP1_REGNUM (aka large_reg)
1776 is not modified within save_restore_insns. */
1778 #define BITSET_P(VALUE,BIT) (((VALUE) & (1L << (BIT))) != 0)
1780 /* Emit instructions to load the value (SP + OFFSET) into IQ2000_TEMP2_REGNUM
1781 and return an rtl expression for the register. Write the assembly
1782 instructions directly to FILE if it is not null, otherwise emit them as
1785 This function is a subroutine of save_restore_insns. It is used when
1786 OFFSET is too large to add in a single instruction. */
1789 iq2000_add_large_offset_to_sp (HOST_WIDE_INT offset
)
1791 rtx reg
= gen_rtx_REG (Pmode
, IQ2000_TEMP2_REGNUM
);
1792 rtx offset_rtx
= GEN_INT (offset
);
1794 emit_move_insn (reg
, offset_rtx
);
1795 emit_insn (gen_addsi3 (reg
, reg
, stack_pointer_rtx
));
1799 /* Make INSN frame related and note that it performs the frame-related
1800 operation DWARF_PATTERN. */
1803 iq2000_annotate_frame_insn (rtx_insn
*insn
, rtx dwarf_pattern
)
1805 RTX_FRAME_RELATED_P (insn
) = 1;
1806 REG_NOTES (insn
) = alloc_EXPR_LIST (REG_FRAME_RELATED_EXPR
,
1811 /* Emit a move instruction that stores REG in MEM. Make the instruction
1812 frame related and note that it stores REG at (SP + OFFSET). */
1815 iq2000_emit_frame_related_store (rtx mem
, rtx reg
, HOST_WIDE_INT offset
)
1817 rtx dwarf_address
= plus_constant (Pmode
, stack_pointer_rtx
, offset
);
1818 rtx dwarf_mem
= gen_rtx_MEM (GET_MODE (reg
), dwarf_address
);
1820 iq2000_annotate_frame_insn (emit_move_insn (mem
, reg
),
1821 gen_rtx_SET (dwarf_mem
, reg
));
1824 /* Emit instructions to save/restore registers, as determined by STORE_P. */
1827 save_restore_insns (int store_p
)
1829 long mask
= cfun
->machine
->mask
;
1832 HOST_WIDE_INT base_offset
;
1833 HOST_WIDE_INT gp_offset
;
1834 HOST_WIDE_INT end_offset
;
1836 gcc_assert (!frame_pointer_needed
1837 || BITSET_P (mask
, HARD_FRAME_POINTER_REGNUM
- GP_REG_FIRST
));
1841 base_reg_rtx
= 0, base_offset
= 0;
1845 /* Save registers starting from high to low. The debuggers prefer at least
1846 the return register be stored at func+4, and also it allows us not to
1847 need a nop in the epilog if at least one register is reloaded in
1848 addition to return address. */
1850 /* Save GP registers if needed. */
1851 /* Pick which pointer to use as a base register. For small frames, just
1852 use the stack pointer. Otherwise, use a temporary register. Save 2
1853 cycles if the save area is near the end of a large frame, by reusing
1854 the constant created in the prologue/epilogue to adjust the stack
1857 gp_offset
= cfun
->machine
->gp_sp_offset
;
1859 = gp_offset
- (cfun
->machine
->gp_reg_size
1860 - GET_MODE_SIZE (gpr_mode
));
1862 if (gp_offset
< 0 || end_offset
< 0)
1864 ("%<gp_offset%> (%ld) or %<end_offset%> (%ld) is less than zero",
1865 (long) gp_offset
, (long) end_offset
);
1867 else if (gp_offset
< 32768)
1868 base_reg_rtx
= stack_pointer_rtx
, base_offset
= 0;
1872 int reg_save_count
= 0;
1874 for (regno
= GP_REG_LAST
; regno
>= GP_REG_FIRST
; regno
--)
1875 if (BITSET_P (mask
, regno
- GP_REG_FIRST
)) reg_save_count
+= 1;
1876 base_offset
= gp_offset
- ((reg_save_count
- 1) * 4);
1877 base_reg_rtx
= iq2000_add_large_offset_to_sp (base_offset
);
1880 for (regno
= GP_REG_LAST
; regno
>= GP_REG_FIRST
; regno
--)
1882 if (BITSET_P (mask
, regno
- GP_REG_FIRST
))
1886 = gen_rtx_MEM (gpr_mode
,
1887 gen_rtx_PLUS (Pmode
, base_reg_rtx
,
1888 GEN_INT (gp_offset
- base_offset
)));
1890 reg_rtx
= gen_rtx_REG (gpr_mode
, regno
);
1893 iq2000_emit_frame_related_store (mem_rtx
, reg_rtx
, gp_offset
);
1896 emit_move_insn (reg_rtx
, mem_rtx
);
1898 gp_offset
-= GET_MODE_SIZE (gpr_mode
);
1903 /* Expand the prologue into a bunch of separate insns. */
1906 iq2000_expand_prologue (void)
1909 HOST_WIDE_INT tsize
;
1910 int last_arg_is_vararg_marker
= 0;
1911 tree fndecl
= current_function_decl
;
1912 tree fntype
= TREE_TYPE (fndecl
);
1913 tree fnargs
= DECL_ARGUMENTS (fndecl
);
1918 CUMULATIVE_ARGS args_so_far_v
;
1919 cumulative_args_t args_so_far
;
1920 int store_args_on_stack
= (iq2000_can_use_return_insn ());
1922 /* If struct value address is treated as the first argument. */
1923 if (aggregate_value_p (DECL_RESULT (fndecl
), fndecl
)
1924 && !cfun
->returns_pcc_struct
1925 && targetm
.calls
.struct_value_rtx (TREE_TYPE (fndecl
), 1) == 0)
1927 tree type
= build_pointer_type (fntype
);
1928 tree function_result_decl
= build_decl (BUILTINS_LOCATION
,
1929 PARM_DECL
, NULL_TREE
, type
);
1931 DECL_ARG_TYPE (function_result_decl
) = type
;
1932 DECL_CHAIN (function_result_decl
) = fnargs
;
1933 fnargs
= function_result_decl
;
1936 /* For arguments passed in registers, find the register number
1937 of the first argument in the variable part of the argument list,
1938 otherwise GP_ARG_LAST+1. Note also if the last argument is
1939 the varargs special argument, and treat it as part of the
1942 This is only needed if store_args_on_stack is true. */
1943 INIT_CUMULATIVE_ARGS (args_so_far_v
, fntype
, NULL_RTX
, 0, 0);
1944 args_so_far
= pack_cumulative_args (&args_so_far_v
);
1945 regno
= GP_ARG_FIRST
;
1947 for (cur_arg
= fnargs
; cur_arg
!= 0; cur_arg
= next_arg
)
1949 tree passed_type
= DECL_ARG_TYPE (cur_arg
);
1950 machine_mode passed_mode
= TYPE_MODE (passed_type
);
1953 if (TREE_ADDRESSABLE (passed_type
))
1955 passed_type
= build_pointer_type (passed_type
);
1956 passed_mode
= Pmode
;
1959 function_arg_info
arg (passed_type
, passed_mode
, /*named=*/true);
1960 entry_parm
= iq2000_function_arg (args_so_far
, arg
);
1962 iq2000_function_arg_advance (args_so_far
, arg
);
1963 next_arg
= DECL_CHAIN (cur_arg
);
1965 if (entry_parm
&& store_args_on_stack
)
1968 && DECL_NAME (cur_arg
)
1969 && (strcmp (IDENTIFIER_POINTER (DECL_NAME (cur_arg
)),
1970 "__builtin_va_alist") == 0
1971 || strcmp (IDENTIFIER_POINTER (DECL_NAME (cur_arg
)),
1974 last_arg_is_vararg_marker
= 1;
1981 gcc_assert (GET_CODE (entry_parm
) == REG
);
1983 /* Passed in a register, so will get homed automatically. */
1984 if (GET_MODE (entry_parm
) == BLKmode
)
1985 words
= (int_size_in_bytes (passed_type
) + 3) / 4;
1987 words
= (GET_MODE_SIZE (GET_MODE (entry_parm
)) + 3) / 4;
1989 regno
= REGNO (entry_parm
) + words
- 1;
1994 regno
= GP_ARG_LAST
+1;
1999 /* In order to pass small structures by value in registers we need to
2000 shift the value into the high part of the register.
2001 iq2000_unction_arg has encoded a PARALLEL rtx, holding a vector of
2002 adjustments to be made as the next_arg_reg variable, so we split up
2003 the insns, and emit them separately. */
2004 next_arg_reg
= iq2000_function_arg (args_so_far
,
2005 function_arg_info::end_marker ());
2006 if (next_arg_reg
!= 0 && GET_CODE (next_arg_reg
) == PARALLEL
)
2008 rtvec adjust
= XVEC (next_arg_reg
, 0);
2009 int num
= GET_NUM_ELEM (adjust
);
2011 for (i
= 0; i
< num
; i
++)
2015 pattern
= RTVEC_ELT (adjust
, i
);
2016 if (GET_CODE (pattern
) != SET
2017 || GET_CODE (SET_SRC (pattern
)) != ASHIFT
)
2018 abort_with_insn (pattern
, "Insn is not a shift");
2019 PUT_CODE (SET_SRC (pattern
), ASHIFTRT
);
2021 emit_insn (pattern
);
2025 tsize
= compute_frame_size (get_frame_size ());
2027 /* If this function is a varargs function, store any registers that
2028 would normally hold arguments ($4 - $7) on the stack. */
2029 if (store_args_on_stack
2030 && (stdarg_p (fntype
)
2031 || last_arg_is_vararg_marker
))
2033 int offset
= (regno
- GP_ARG_FIRST
) * UNITS_PER_WORD
;
2034 rtx ptr
= stack_pointer_rtx
;
2036 for (; regno
<= GP_ARG_LAST
; regno
++)
2039 ptr
= gen_rtx_PLUS (Pmode
, stack_pointer_rtx
, GEN_INT (offset
));
2040 emit_move_insn (gen_rtx_MEM (gpr_mode
, ptr
),
2041 gen_rtx_REG (gpr_mode
, regno
));
2043 offset
+= GET_MODE_SIZE (gpr_mode
);
2049 rtx tsize_rtx
= GEN_INT (tsize
);
2050 rtx adjustment_rtx
, dwarf_pattern
;
2055 adjustment_rtx
= gen_rtx_REG (Pmode
, IQ2000_TEMP1_REGNUM
);
2056 emit_move_insn (adjustment_rtx
, tsize_rtx
);
2059 adjustment_rtx
= tsize_rtx
;
2061 insn
= emit_insn (gen_subsi3 (stack_pointer_rtx
, stack_pointer_rtx
,
2064 dwarf_pattern
= gen_rtx_SET (stack_pointer_rtx
,
2065 plus_constant (Pmode
, stack_pointer_rtx
,
2068 iq2000_annotate_frame_insn (insn
, dwarf_pattern
);
2070 save_restore_insns (1);
2072 if (frame_pointer_needed
)
2076 insn
= emit_insn (gen_movsi (hard_frame_pointer_rtx
,
2077 stack_pointer_rtx
));
2080 RTX_FRAME_RELATED_P (insn
) = 1;
2084 if (flag_stack_usage_info
)
2085 current_function_static_stack_size
= cfun
->machine
->total_size
;
2087 emit_insn (gen_blockage ());
2090 /* Expand the epilogue into a bunch of separate insns. */
2093 iq2000_expand_epilogue (void)
2095 HOST_WIDE_INT tsize
= cfun
->machine
->total_size
;
2096 rtx tsize_rtx
= GEN_INT (tsize
);
2097 rtx tmp_rtx
= (rtx
)0;
2099 if (iq2000_can_use_return_insn ())
2101 emit_jump_insn (gen_return ());
2107 tmp_rtx
= gen_rtx_REG (Pmode
, IQ2000_TEMP1_REGNUM
);
2108 emit_move_insn (tmp_rtx
, tsize_rtx
);
2109 tsize_rtx
= tmp_rtx
;
2114 if (frame_pointer_needed
)
2116 emit_insn (gen_blockage ());
2118 emit_insn (gen_movsi (stack_pointer_rtx
, hard_frame_pointer_rtx
));
2121 save_restore_insns (0);
2123 if (crtl
->calls_eh_return
)
2125 rtx eh_ofs
= EH_RETURN_STACKADJ_RTX
;
2126 emit_insn (gen_addsi3 (eh_ofs
, eh_ofs
, tsize_rtx
));
2130 emit_insn (gen_blockage ());
2132 if (tsize
!= 0 || crtl
->calls_eh_return
)
2134 emit_insn (gen_addsi3 (stack_pointer_rtx
, stack_pointer_rtx
,
2139 if (crtl
->calls_eh_return
)
2141 /* Perform the additional bump for __throw. */
2142 emit_move_insn (gen_rtx_REG (Pmode
, HARD_FRAME_POINTER_REGNUM
),
2144 emit_use (gen_rtx_REG (Pmode
, HARD_FRAME_POINTER_REGNUM
));
2145 emit_jump_insn (gen_eh_return_internal ());
2148 emit_jump_insn (gen_return_internal (gen_rtx_REG (Pmode
,
2149 GP_REG_FIRST
+ 31)));
2153 iq2000_expand_eh_return (rtx address
)
2155 HOST_WIDE_INT gp_offset
= cfun
->machine
->gp_sp_offset
;
2158 scratch
= plus_constant (Pmode
, stack_pointer_rtx
, gp_offset
);
2159 emit_move_insn (gen_rtx_MEM (GET_MODE (address
), scratch
), address
);
2162 /* Return nonzero if this function is known to have a null epilogue.
2163 This allows the optimizer to omit jumps to jumps if no stack
2167 iq2000_can_use_return_insn (void)
2169 if (! reload_completed
)
2172 if (df_regs_ever_live_p (31) || profile_flag
)
2175 if (cfun
->machine
->initialized
)
2176 return cfun
->machine
->total_size
== 0;
2178 return compute_frame_size (get_frame_size ()) == 0;
2181 /* Choose the section to use for the constant rtx expression X that has
2185 iq2000_select_rtx_section (machine_mode mode
, rtx x ATTRIBUTE_UNUSED
,
2186 unsigned HOST_WIDE_INT align
)
2188 /* For embedded applications, always put constants in read-only data,
2189 in order to reduce RAM usage. */
2190 return mergeable_constant_section (mode
, align
, 0);
2193 /* 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 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 (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_t cum_v
,
2242 const function_arg_info
&arg
)
2244 CUMULATIVE_ARGS
*cum
= get_cumulative_args (cum_v
);
2247 /* We must pass by reference if we would be both passing in registers
2248 and the stack. This is because any subsequent partial arg would be
2249 handled incorrectly in this case. */
2250 if (cum
&& targetm
.calls
.must_pass_in_stack (arg
))
2252 /* Don't pass the actual CUM to FUNCTION_ARG, because we would
2253 get double copies of any offsets generated for small structs
2254 passed in registers. */
2255 CUMULATIVE_ARGS temp
;
2258 if (iq2000_function_arg (pack_cumulative_args (&temp
), arg
) != 0)
2262 if (arg
.type
== NULL_TREE
|| arg
.mode
== DImode
|| arg
.mode
== DFmode
)
2265 size
= int_size_in_bytes (arg
.type
);
2266 return size
== -1 || size
> UNITS_PER_WORD
;
2269 /* Return the length of INSN. LENGTH is the initial length computed by
2270 attributes in the machine-description file. */
2273 iq2000_adjust_insn_length (rtx_insn
*insn
, int length
)
2275 /* A unconditional jump has an unfilled delay slot if it is not part
2276 of a sequence. A conditional jump normally has a delay slot. */
2277 if (simplejump_p (insn
)
2285 /* Output assembly instructions to perform a conditional branch.
2287 INSN is the branch instruction. OPERANDS[0] is the condition.
2288 OPERANDS[1] is the target of the branch. OPERANDS[2] is the target
2289 of the first operand to the condition. If TWO_OPERANDS_P is
2290 nonzero the comparison takes two operands; OPERANDS[3] will be the
2293 If INVERTED_P is nonzero we are to branch if the condition does
2294 not hold. If FLOAT_P is nonzero this is a floating-point comparison.
2296 LENGTH is the length (in bytes) of the sequence we are to generate.
2297 That tells us whether to generate a simple conditional branch, or a
2298 reversed conditional branch around a `jr' instruction. */
2301 iq2000_output_conditional_branch (rtx_insn
*insn
, rtx
* operands
,
2302 int two_operands_p
, int float_p
,
2303 int inverted_p
, int length
)
2305 static char buffer
[200];
2306 /* The kind of comparison we are doing. */
2307 enum rtx_code code
= GET_CODE (operands
[0]);
2308 /* Nonzero if the opcode for the comparison needs a `z' indicating
2309 that it is a comparison against zero. */
2311 /* A string to use in the assembly output to represent the first
2313 const char *op1
= "%z2";
2314 /* A string to use in the assembly output to represent the second
2315 operand. Use the hard-wired zero register if there's no second
2317 const char *op2
= (two_operands_p
? ",%z3" : ",%.");
2318 /* The operand-printing string for the comparison. */
2319 const char *comp
= (float_p
? "%F0" : "%C0");
2320 /* The operand-printing string for the inverted comparison. */
2321 const char *inverted_comp
= (float_p
? "%W0" : "%N0");
2323 /* Likely variants of each branch instruction annul the instruction
2324 in the delay slot if the branch is not taken. */
2325 iq2000_branch_likely
= (final_sequence
&& INSN_ANNULLED_BRANCH_P (insn
));
2327 if (!two_operands_p
)
2329 /* To compute whether than A > B, for example, we normally
2330 subtract B from A and then look at the sign bit. But, if we
2331 are doing an unsigned comparison, and B is zero, we don't
2332 have to do the subtraction. Instead, we can just check to
2333 see if A is nonzero. Thus, we change the CODE here to
2334 reflect the simpler comparison operation. */
2346 /* A condition which will always be true. */
2352 /* A condition which will always be false. */
2358 /* Not a special case. */
2363 /* Relative comparisons are always done against zero. But
2364 equality comparisons are done between two operands, and therefore
2365 do not require a `z' in the assembly language output. */
2366 need_z_p
= (!float_p
&& code
!= EQ
&& code
!= NE
);
2367 /* For comparisons against zero, the zero is not provided
2372 /* Begin by terminating the buffer. That way we can always use
2373 strcat to add to it. */
2380 /* Just a simple conditional branch. */
2382 sprintf (buffer
, "b%s%%?\t%%Z2%%1",
2383 inverted_p
? inverted_comp
: comp
);
2385 sprintf (buffer
, "b%s%s%%?\t%s%s,%%1",
2386 inverted_p
? inverted_comp
: comp
,
2387 need_z_p
? "z" : "",
2395 /* Generate a reversed conditional branch around ` j'
2407 Because we have to jump four bytes *past* the following
2408 instruction if this branch was annulled, we can't just use
2409 a label, as in the picture above; there's no way to put the
2410 label after the next instruction, as the assembler does not
2411 accept `.L+4' as the target of a branch. (We can't just
2412 wait until the next instruction is output; it might be a
2413 macro and take up more than four bytes. Once again, we see
2414 why we want to eliminate macros.)
2416 If the branch is annulled, we jump four more bytes that we
2417 would otherwise; that way we skip the annulled instruction
2418 in the delay slot. */
2421 = ((iq2000_branch_likely
|| length
== 16) ? ".+16" : ".+12");
2424 c
= strchr (buffer
, '\0');
2425 /* Generate the reversed comparison. This takes four
2428 sprintf (c
, "b%s\t%%Z2%s",
2429 inverted_p
? comp
: inverted_comp
,
2432 sprintf (c
, "b%s%s\t%s%s,%s",
2433 inverted_p
? comp
: inverted_comp
,
2434 need_z_p
? "z" : "",
2438 strcat (c
, "\n\tnop\n\tj\t%1");
2440 /* The delay slot was unfilled. Since we're inside
2441 .noreorder, the assembler will not fill in the NOP for
2442 us, so we must do it ourselves. */
2443 strcat (buffer
, "\n\tnop");
2455 #define def_builtin(NAME, TYPE, CODE) \
2456 add_builtin_function ((NAME), (TYPE), (CODE), BUILT_IN_MD, \
2460 iq2000_init_builtins (void)
2462 tree void_ftype
, void_ftype_int
, void_ftype_int_int
;
2463 tree void_ftype_int_int_int
;
2464 tree int_ftype_int
, int_ftype_int_int
, int_ftype_int_int_int
;
2465 tree int_ftype_int_int_int_int
;
2469 = build_function_type_list (void_type_node
, NULL_TREE
);
2473 = build_function_type_list (void_type_node
, integer_type_node
, NULL_TREE
);
2475 /* void func (int, int) */
2477 = build_function_type_list (void_type_node
,
2482 /* int func (int) */
2484 = build_function_type_list (integer_type_node
,
2485 integer_type_node
, NULL_TREE
);
2487 /* int func (int, int) */
2489 = build_function_type_list (integer_type_node
,
2494 /* void func (int, int, int) */
2495 void_ftype_int_int_int
2496 = build_function_type_list (void_type_node
,
2502 /* int func (int, int, int) */
2503 int_ftype_int_int_int
2504 = build_function_type_list (integer_type_node
,
2510 /* int func (int, int, int, int) */
2511 int_ftype_int_int_int_int
2512 = build_function_type_list (integer_type_node
,
2519 def_builtin ("__builtin_ado16", int_ftype_int_int
, IQ2000_BUILTIN_ADO16
);
2520 def_builtin ("__builtin_ram", int_ftype_int_int_int_int
, IQ2000_BUILTIN_RAM
);
2521 def_builtin ("__builtin_chkhdr", void_ftype_int_int
, IQ2000_BUILTIN_CHKHDR
);
2522 def_builtin ("__builtin_pkrl", void_ftype_int_int
, IQ2000_BUILTIN_PKRL
);
2523 def_builtin ("__builtin_cfc0", int_ftype_int
, IQ2000_BUILTIN_CFC0
);
2524 def_builtin ("__builtin_cfc1", int_ftype_int
, IQ2000_BUILTIN_CFC1
);
2525 def_builtin ("__builtin_cfc2", int_ftype_int
, IQ2000_BUILTIN_CFC2
);
2526 def_builtin ("__builtin_cfc3", int_ftype_int
, IQ2000_BUILTIN_CFC3
);
2527 def_builtin ("__builtin_ctc0", void_ftype_int_int
, IQ2000_BUILTIN_CTC0
);
2528 def_builtin ("__builtin_ctc1", void_ftype_int_int
, IQ2000_BUILTIN_CTC1
);
2529 def_builtin ("__builtin_ctc2", void_ftype_int_int
, IQ2000_BUILTIN_CTC2
);
2530 def_builtin ("__builtin_ctc3", void_ftype_int_int
, IQ2000_BUILTIN_CTC3
);
2531 def_builtin ("__builtin_mfc0", int_ftype_int
, IQ2000_BUILTIN_MFC0
);
2532 def_builtin ("__builtin_mfc1", int_ftype_int
, IQ2000_BUILTIN_MFC1
);
2533 def_builtin ("__builtin_mfc2", int_ftype_int
, IQ2000_BUILTIN_MFC2
);
2534 def_builtin ("__builtin_mfc3", int_ftype_int
, IQ2000_BUILTIN_MFC3
);
2535 def_builtin ("__builtin_mtc0", void_ftype_int_int
, IQ2000_BUILTIN_MTC0
);
2536 def_builtin ("__builtin_mtc1", void_ftype_int_int
, IQ2000_BUILTIN_MTC1
);
2537 def_builtin ("__builtin_mtc2", void_ftype_int_int
, IQ2000_BUILTIN_MTC2
);
2538 def_builtin ("__builtin_mtc3", void_ftype_int_int
, IQ2000_BUILTIN_MTC3
);
2539 def_builtin ("__builtin_lur", void_ftype_int_int
, IQ2000_BUILTIN_LUR
);
2540 def_builtin ("__builtin_rb", void_ftype_int_int
, IQ2000_BUILTIN_RB
);
2541 def_builtin ("__builtin_rx", void_ftype_int_int
, IQ2000_BUILTIN_RX
);
2542 def_builtin ("__builtin_srrd", void_ftype_int
, IQ2000_BUILTIN_SRRD
);
2543 def_builtin ("__builtin_srwr", void_ftype_int_int
, IQ2000_BUILTIN_SRWR
);
2544 def_builtin ("__builtin_wb", void_ftype_int_int
, IQ2000_BUILTIN_WB
);
2545 def_builtin ("__builtin_wx", void_ftype_int_int
, IQ2000_BUILTIN_WX
);
2546 def_builtin ("__builtin_luc32l", void_ftype_int_int
, IQ2000_BUILTIN_LUC32L
);
2547 def_builtin ("__builtin_luc64", void_ftype_int_int
, IQ2000_BUILTIN_LUC64
);
2548 def_builtin ("__builtin_luc64l", void_ftype_int_int
, IQ2000_BUILTIN_LUC64L
);
2549 def_builtin ("__builtin_luk", void_ftype_int_int
, IQ2000_BUILTIN_LUK
);
2550 def_builtin ("__builtin_lulck", void_ftype_int
, IQ2000_BUILTIN_LULCK
);
2551 def_builtin ("__builtin_lum32", void_ftype_int_int
, IQ2000_BUILTIN_LUM32
);
2552 def_builtin ("__builtin_lum32l", void_ftype_int_int
, IQ2000_BUILTIN_LUM32L
);
2553 def_builtin ("__builtin_lum64", void_ftype_int_int
, IQ2000_BUILTIN_LUM64
);
2554 def_builtin ("__builtin_lum64l", void_ftype_int_int
, IQ2000_BUILTIN_LUM64L
);
2555 def_builtin ("__builtin_lurl", void_ftype_int_int
, IQ2000_BUILTIN_LURL
);
2556 def_builtin ("__builtin_mrgb", int_ftype_int_int_int
, IQ2000_BUILTIN_MRGB
);
2557 def_builtin ("__builtin_srrdl", void_ftype_int
, IQ2000_BUILTIN_SRRDL
);
2558 def_builtin ("__builtin_srulck", void_ftype_int
, IQ2000_BUILTIN_SRULCK
);
2559 def_builtin ("__builtin_srwru", void_ftype_int_int
, IQ2000_BUILTIN_SRWRU
);
2560 def_builtin ("__builtin_trapqfl", void_ftype
, IQ2000_BUILTIN_TRAPQFL
);
2561 def_builtin ("__builtin_trapqne", void_ftype
, IQ2000_BUILTIN_TRAPQNE
);
2562 def_builtin ("__builtin_traprel", void_ftype_int
, IQ2000_BUILTIN_TRAPREL
);
2563 def_builtin ("__builtin_wbu", void_ftype_int_int_int
, IQ2000_BUILTIN_WBU
);
2564 def_builtin ("__builtin_syscall", void_ftype
, IQ2000_BUILTIN_SYSCALL
);
2567 /* Builtin for ICODE having ARGCOUNT args in EXP where each arg
2571 expand_one_builtin (enum insn_code icode
, rtx target
, tree exp
,
2572 enum rtx_code
*code
, int argcount
)
2577 machine_mode mode
[5];
2580 mode
[0] = insn_data
[icode
].operand
[0].mode
;
2581 for (i
= 0; i
< argcount
; i
++)
2583 arg
[i
] = CALL_EXPR_ARG (exp
, i
);
2584 op
[i
] = expand_normal (arg
[i
]);
2585 mode
[i
] = insn_data
[icode
].operand
[i
].mode
;
2586 if (code
[i
] == CONST_INT
&& GET_CODE (op
[i
]) != CONST_INT
)
2587 error ("argument %qd is not a constant", i
+ 1);
2589 && ! (*insn_data
[icode
].operand
[i
].predicate
) (op
[i
], mode
[i
]))
2590 op
[i
] = copy_to_mode_reg (mode
[i
], op
[i
]);
2593 if (insn_data
[icode
].operand
[0].constraint
[0] == '=')
2596 || GET_MODE (target
) != mode
[0]
2597 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, mode
[0]))
2598 target
= gen_reg_rtx (mode
[0]);
2606 pat
= GEN_FCN (icode
) (target
);
2610 pat
= GEN_FCN (icode
) (target
, op
[0]);
2612 pat
= GEN_FCN (icode
) (op
[0]);
2616 pat
= GEN_FCN (icode
) (target
, op
[0], op
[1]);
2618 pat
= GEN_FCN (icode
) (op
[0], op
[1]);
2622 pat
= GEN_FCN (icode
) (target
, op
[0], op
[1], op
[2]);
2624 pat
= GEN_FCN (icode
) (op
[0], op
[1], op
[2]);
2628 pat
= GEN_FCN (icode
) (target
, op
[0], op
[1], op
[2], op
[3]);
2630 pat
= GEN_FCN (icode
) (op
[0], op
[1], op
[2], op
[3]);
2642 /* Expand an expression EXP that calls a built-in function,
2643 with result going to TARGET if that's convenient
2644 (and in mode MODE if that's convenient).
2645 SUBTARGET may be used as the target for computing one of EXP's operands.
2646 IGNORE is nonzero if the value is to be ignored. */
2649 iq2000_expand_builtin (tree exp
, rtx target
, rtx subtarget ATTRIBUTE_UNUSED
,
2650 machine_mode mode ATTRIBUTE_UNUSED
,
2651 int ignore ATTRIBUTE_UNUSED
)
2653 tree fndecl
= TREE_OPERAND (CALL_EXPR_FN (exp
), 0);
2654 int fcode
= DECL_MD_FUNCTION_CODE (fndecl
);
2655 enum rtx_code code
[5];
2667 case IQ2000_BUILTIN_ADO16
:
2668 return expand_one_builtin (CODE_FOR_ado16
, target
, exp
, code
, 2);
2670 case IQ2000_BUILTIN_RAM
:
2671 code
[1] = CONST_INT
;
2672 code
[2] = CONST_INT
;
2673 code
[3] = CONST_INT
;
2674 return expand_one_builtin (CODE_FOR_ram
, target
, exp
, code
, 4);
2676 case IQ2000_BUILTIN_CHKHDR
:
2677 return expand_one_builtin (CODE_FOR_chkhdr
, target
, exp
, code
, 2);
2679 case IQ2000_BUILTIN_PKRL
:
2680 return expand_one_builtin (CODE_FOR_pkrl
, target
, exp
, code
, 2);
2682 case IQ2000_BUILTIN_CFC0
:
2683 code
[0] = CONST_INT
;
2684 return expand_one_builtin (CODE_FOR_cfc0
, target
, exp
, code
, 1);
2686 case IQ2000_BUILTIN_CFC1
:
2687 code
[0] = CONST_INT
;
2688 return expand_one_builtin (CODE_FOR_cfc1
, target
, exp
, code
, 1);
2690 case IQ2000_BUILTIN_CFC2
:
2691 code
[0] = CONST_INT
;
2692 return expand_one_builtin (CODE_FOR_cfc2
, target
, exp
, code
, 1);
2694 case IQ2000_BUILTIN_CFC3
:
2695 code
[0] = CONST_INT
;
2696 return expand_one_builtin (CODE_FOR_cfc3
, target
, exp
, code
, 1);
2698 case IQ2000_BUILTIN_CTC0
:
2699 code
[1] = CONST_INT
;
2700 return expand_one_builtin (CODE_FOR_ctc0
, target
, exp
, code
, 2);
2702 case IQ2000_BUILTIN_CTC1
:
2703 code
[1] = CONST_INT
;
2704 return expand_one_builtin (CODE_FOR_ctc1
, target
, exp
, code
, 2);
2706 case IQ2000_BUILTIN_CTC2
:
2707 code
[1] = CONST_INT
;
2708 return expand_one_builtin (CODE_FOR_ctc2
, target
, exp
, code
, 2);
2710 case IQ2000_BUILTIN_CTC3
:
2711 code
[1] = CONST_INT
;
2712 return expand_one_builtin (CODE_FOR_ctc3
, target
, exp
, code
, 2);
2714 case IQ2000_BUILTIN_MFC0
:
2715 code
[0] = CONST_INT
;
2716 return expand_one_builtin (CODE_FOR_mfc0
, target
, exp
, code
, 1);
2718 case IQ2000_BUILTIN_MFC1
:
2719 code
[0] = CONST_INT
;
2720 return expand_one_builtin (CODE_FOR_mfc1
, target
, exp
, code
, 1);
2722 case IQ2000_BUILTIN_MFC2
:
2723 code
[0] = CONST_INT
;
2724 return expand_one_builtin (CODE_FOR_mfc2
, target
, exp
, code
, 1);
2726 case IQ2000_BUILTIN_MFC3
:
2727 code
[0] = CONST_INT
;
2728 return expand_one_builtin (CODE_FOR_mfc3
, target
, exp
, code
, 1);
2730 case IQ2000_BUILTIN_MTC0
:
2731 code
[1] = CONST_INT
;
2732 return expand_one_builtin (CODE_FOR_mtc0
, target
, exp
, code
, 2);
2734 case IQ2000_BUILTIN_MTC1
:
2735 code
[1] = CONST_INT
;
2736 return expand_one_builtin (CODE_FOR_mtc1
, target
, exp
, code
, 2);
2738 case IQ2000_BUILTIN_MTC2
:
2739 code
[1] = CONST_INT
;
2740 return expand_one_builtin (CODE_FOR_mtc2
, target
, exp
, code
, 2);
2742 case IQ2000_BUILTIN_MTC3
:
2743 code
[1] = CONST_INT
;
2744 return expand_one_builtin (CODE_FOR_mtc3
, target
, exp
, code
, 2);
2746 case IQ2000_BUILTIN_LUR
:
2747 return expand_one_builtin (CODE_FOR_lur
, target
, exp
, code
, 2);
2749 case IQ2000_BUILTIN_RB
:
2750 return expand_one_builtin (CODE_FOR_rb
, target
, exp
, code
, 2);
2752 case IQ2000_BUILTIN_RX
:
2753 return expand_one_builtin (CODE_FOR_rx
, target
, exp
, code
, 2);
2755 case IQ2000_BUILTIN_SRRD
:
2756 return expand_one_builtin (CODE_FOR_srrd
, target
, exp
, code
, 1);
2758 case IQ2000_BUILTIN_SRWR
:
2759 return expand_one_builtin (CODE_FOR_srwr
, target
, exp
, code
, 2);
2761 case IQ2000_BUILTIN_WB
:
2762 return expand_one_builtin (CODE_FOR_wb
, target
, exp
, code
, 2);
2764 case IQ2000_BUILTIN_WX
:
2765 return expand_one_builtin (CODE_FOR_wx
, target
, exp
, code
, 2);
2767 case IQ2000_BUILTIN_LUC32L
:
2768 return expand_one_builtin (CODE_FOR_luc32l
, target
, exp
, code
, 2);
2770 case IQ2000_BUILTIN_LUC64
:
2771 return expand_one_builtin (CODE_FOR_luc64
, target
, exp
, code
, 2);
2773 case IQ2000_BUILTIN_LUC64L
:
2774 return expand_one_builtin (CODE_FOR_luc64l
, target
, exp
, code
, 2);
2776 case IQ2000_BUILTIN_LUK
:
2777 return expand_one_builtin (CODE_FOR_luk
, target
, exp
, code
, 2);
2779 case IQ2000_BUILTIN_LULCK
:
2780 return expand_one_builtin (CODE_FOR_lulck
, target
, exp
, code
, 1);
2782 case IQ2000_BUILTIN_LUM32
:
2783 return expand_one_builtin (CODE_FOR_lum32
, target
, exp
, code
, 2);
2785 case IQ2000_BUILTIN_LUM32L
:
2786 return expand_one_builtin (CODE_FOR_lum32l
, target
, exp
, code
, 2);
2788 case IQ2000_BUILTIN_LUM64
:
2789 return expand_one_builtin (CODE_FOR_lum64
, target
, exp
, code
, 2);
2791 case IQ2000_BUILTIN_LUM64L
:
2792 return expand_one_builtin (CODE_FOR_lum64l
, target
, exp
, code
, 2);
2794 case IQ2000_BUILTIN_LURL
:
2795 return expand_one_builtin (CODE_FOR_lurl
, target
, exp
, code
, 2);
2797 case IQ2000_BUILTIN_MRGB
:
2798 code
[2] = CONST_INT
;
2799 return expand_one_builtin (CODE_FOR_mrgb
, target
, exp
, code
, 3);
2801 case IQ2000_BUILTIN_SRRDL
:
2802 return expand_one_builtin (CODE_FOR_srrdl
, target
, exp
, code
, 1);
2804 case IQ2000_BUILTIN_SRULCK
:
2805 return expand_one_builtin (CODE_FOR_srulck
, target
, exp
, code
, 1);
2807 case IQ2000_BUILTIN_SRWRU
:
2808 return expand_one_builtin (CODE_FOR_srwru
, target
, exp
, code
, 2);
2810 case IQ2000_BUILTIN_TRAPQFL
:
2811 return expand_one_builtin (CODE_FOR_trapqfl
, target
, exp
, code
, 0);
2813 case IQ2000_BUILTIN_TRAPQNE
:
2814 return expand_one_builtin (CODE_FOR_trapqne
, target
, exp
, code
, 0);
2816 case IQ2000_BUILTIN_TRAPREL
:
2817 return expand_one_builtin (CODE_FOR_traprel
, target
, exp
, code
, 1);
2819 case IQ2000_BUILTIN_WBU
:
2820 return expand_one_builtin (CODE_FOR_wbu
, target
, exp
, code
, 3);
2822 case IQ2000_BUILTIN_SYSCALL
:
2823 return expand_one_builtin (CODE_FOR_syscall
, target
, exp
, code
, 0);
2829 /* Worker function for TARGET_RETURN_IN_MEMORY. */
2832 iq2000_return_in_memory (const_tree type
, const_tree fntype ATTRIBUTE_UNUSED
)
2834 return ((int_size_in_bytes (type
) > (2 * UNITS_PER_WORD
))
2835 || (int_size_in_bytes (type
) == -1));
2838 /* Worker function for TARGET_SETUP_INCOMING_VARARGS. */
2841 iq2000_setup_incoming_varargs (cumulative_args_t cum_v
,
2842 const function_arg_info
&,
2843 int *pretend_size
, int no_rtl
)
2845 CUMULATIVE_ARGS
*cum
= get_cumulative_args (cum_v
);
2846 unsigned int iq2000_off
= ! cum
->last_arg_fp
;
2847 unsigned int iq2000_fp_off
= cum
->last_arg_fp
;
2849 if ((cum
->arg_words
< MAX_ARGS_IN_REGISTERS
- iq2000_off
))
2851 int iq2000_save_gp_regs
2852 = MAX_ARGS_IN_REGISTERS
- cum
->arg_words
- iq2000_off
;
2853 int iq2000_save_fp_regs
2854 = (MAX_ARGS_IN_REGISTERS
- cum
->fp_arg_words
- iq2000_fp_off
);
2856 if (iq2000_save_gp_regs
< 0)
2857 iq2000_save_gp_regs
= 0;
2858 if (iq2000_save_fp_regs
< 0)
2859 iq2000_save_fp_regs
= 0;
2861 *pretend_size
= ((iq2000_save_gp_regs
* UNITS_PER_WORD
)
2862 + (iq2000_save_fp_regs
* UNITS_PER_FPREG
));
2866 if (cum
->arg_words
< MAX_ARGS_IN_REGISTERS
- iq2000_off
)
2869 ptr
= plus_constant (Pmode
, virtual_incoming_args_rtx
,
2870 - (iq2000_save_gp_regs
2872 mem
= gen_rtx_MEM (BLKmode
, ptr
);
2874 (cum
->arg_words
+ GP_ARG_FIRST
+ iq2000_off
,
2876 iq2000_save_gp_regs
);
2882 /* A C compound statement to output to stdio stream STREAM the
2883 assembler syntax for an instruction operand that is a memory
2884 reference whose address is ADDR. ADDR is an RTL expression. */
2887 iq2000_print_operand_address (FILE * file
, machine_mode mode
, rtx addr
)
2890 error ("%<PRINT_OPERAND_ADDRESS%>, null pointer");
2893 switch (GET_CODE (addr
))
2896 if (REGNO (addr
) == ARG_POINTER_REGNUM
)
2897 abort_with_insn (addr
, "Arg pointer not eliminated.");
2899 fprintf (file
, "0(%s)", reg_names
[REGNO (addr
)]);
2904 rtx arg0
= XEXP (addr
, 0);
2905 rtx arg1
= XEXP (addr
, 1);
2907 if (GET_CODE (arg0
) != REG
)
2908 abort_with_insn (addr
,
2909 "PRINT_OPERAND_ADDRESS, LO_SUM with #1 not REG.");
2911 fprintf (file
, "%%lo(");
2912 iq2000_print_operand_address (file
, mode
, arg1
);
2913 fprintf (file
, ")(%s)", reg_names
[REGNO (arg0
)]);
2921 rtx arg0
= XEXP (addr
, 0);
2922 rtx arg1
= XEXP (addr
, 1);
2924 if (GET_CODE (arg0
) == REG
)
2928 if (GET_CODE (offset
) == REG
)
2929 abort_with_insn (addr
, "PRINT_OPERAND_ADDRESS, 2 regs");
2932 else if (GET_CODE (arg1
) == REG
)
2933 reg
= arg1
, offset
= arg0
;
2934 else if (CONSTANT_P (arg0
) && CONSTANT_P (arg1
))
2936 output_addr_const (file
, addr
);
2940 abort_with_insn (addr
, "PRINT_OPERAND_ADDRESS, no regs");
2942 if (! CONSTANT_P (offset
))
2943 abort_with_insn (addr
, "PRINT_OPERAND_ADDRESS, invalid insn #2");
2945 if (REGNO (reg
) == ARG_POINTER_REGNUM
)
2946 abort_with_insn (addr
, "Arg pointer not eliminated.");
2948 output_addr_const (file
, offset
);
2949 fprintf (file
, "(%s)", reg_names
[REGNO (reg
)]);
2957 output_addr_const (file
, addr
);
2958 if (GET_CODE (addr
) == CONST_INT
)
2959 fprintf (file
, "(%s)", reg_names
[0]);
2963 abort_with_insn (addr
, "PRINT_OPERAND_ADDRESS, invalid insn #1");
2968 /* A C compound statement to output to stdio stream FILE the
2969 assembler syntax for an instruction operand OP.
2971 LETTER is a value that can be used to specify one of several ways
2972 of printing the operand. It is used when identical operands
2973 must be printed differently depending on the context. LETTER
2974 comes from the `%' specification that was used to request
2975 printing of the operand. If the specification was just `%DIGIT'
2976 then LETTER is 0; if the specification was `%LTR DIGIT' then LETTER
2977 is the ASCII code for LTR.
2979 If OP is a register, this macro should print the register's name.
2980 The names can be found in an array `reg_names' whose type is
2981 `char *[]'. `reg_names' is initialized from `REGISTER_NAMES'.
2983 When the machine description has a specification `%PUNCT' (a `%'
2984 followed by a punctuation character), this macro is called with
2985 a null pointer for X and the punctuation character for LETTER.
2987 The IQ2000 specific codes are:
2989 'X' X is CONST_INT, prints upper 16 bits in hexadecimal format = "0x%04x",
2990 'x' X is CONST_INT, prints lower 16 bits in hexadecimal format = "0x%04x",
2991 'd' output integer constant in decimal,
2992 'z' if the operand is 0, use $0 instead of normal operand.
2993 'D' print second part of double-word register or memory operand.
2994 'L' print low-order register of double-word register operand.
2995 'M' print high-order register of double-word register operand.
2996 'C' print part of opcode for a branch condition.
2997 'F' print part of opcode for a floating-point branch condition.
2998 'N' print part of opcode for a branch condition, inverted.
2999 'W' print part of opcode for a floating-point branch condition, inverted.
3000 'A' Print part of opcode for a bit test condition.
3001 'P' Print label for a bit test.
3002 'p' Print log for a bit test.
3003 'B' print 'z' for EQ, 'n' for NE
3004 'b' print 'n' for EQ, 'z' for NE
3005 'T' print 'f' for EQ, 't' for NE
3006 't' print 't' for EQ, 'f' for NE
3007 'Z' print register and a comma, but print nothing for $fcc0
3008 '?' Print 'l' if we are to use a branch likely instead of normal branch.
3009 '@' Print the name of the assembler temporary register (at or $1).
3010 '.' Print the name of the register with a hard-wired zero (zero or $0).
3011 '$' Print the name of the stack pointer register (sp or $29).
3012 '+' Print the name of the gp register (gp or $28). */
3015 iq2000_print_operand (FILE *file
, rtx op
, int letter
)
3019 if (iq2000_print_operand_punct_valid_p (letter
))
3024 if (iq2000_branch_likely
)
3029 fputs (reg_names
[GP_REG_FIRST
+ 1], file
);
3033 fputs (reg_names
[GP_REG_FIRST
+ 0], file
);
3037 fputs (reg_names
[STACK_POINTER_REGNUM
], file
);
3041 fputs (reg_names
[GP_REG_FIRST
+ 28], file
);
3045 error ("%<PRINT_OPERAND%>: Unknown punctuation %<%c%>", letter
);
3054 error ("%<PRINT_OPERAND%> null pointer");
3058 code
= GET_CODE (op
);
3060 if (code
== SIGN_EXTEND
)
3061 op
= XEXP (op
, 0), code
= GET_CODE (op
);
3066 case EQ
: fputs ("eq", file
); break;
3067 case NE
: fputs ("ne", file
); break;
3068 case GT
: fputs ("gt", file
); break;
3069 case GE
: fputs ("ge", file
); break;
3070 case LT
: fputs ("lt", file
); break;
3071 case LE
: fputs ("le", file
); break;
3072 case GTU
: fputs ("ne", file
); break;
3073 case GEU
: fputs ("geu", file
); break;
3074 case LTU
: fputs ("ltu", file
); break;
3075 case LEU
: fputs ("eq", file
); break;
3077 abort_with_insn (op
, "PRINT_OPERAND, invalid insn for %%C");
3080 else if (letter
== 'N')
3083 case EQ
: fputs ("ne", file
); break;
3084 case NE
: fputs ("eq", file
); break;
3085 case GT
: fputs ("le", file
); break;
3086 case GE
: fputs ("lt", file
); break;
3087 case LT
: fputs ("ge", file
); break;
3088 case LE
: fputs ("gt", file
); break;
3089 case GTU
: fputs ("leu", file
); break;
3090 case GEU
: fputs ("ltu", file
); break;
3091 case LTU
: fputs ("geu", file
); break;
3092 case LEU
: fputs ("gtu", file
); break;
3094 abort_with_insn (op
, "PRINT_OPERAND, invalid insn for %%N");
3097 else if (letter
== 'F')
3100 case EQ
: fputs ("c1f", file
); break;
3101 case NE
: fputs ("c1t", file
); break;
3103 abort_with_insn (op
, "PRINT_OPERAND, invalid insn for %%F");
3106 else if (letter
== 'W')
3109 case EQ
: fputs ("c1t", file
); break;
3110 case NE
: fputs ("c1f", file
); break;
3112 abort_with_insn (op
, "PRINT_OPERAND, invalid insn for %%W");
3115 else if (letter
== 'A')
3116 fputs (code
== LABEL_REF
? "i" : "in", file
);
3118 else if (letter
== 'P')
3120 if (code
== LABEL_REF
)
3121 output_addr_const (file
, op
);
3122 else if (code
!= PC
)
3123 output_operand_lossage ("invalid %%P operand");
3126 else if (letter
== 'p')
3129 if (code
!= CONST_INT
3130 || (value
= exact_log2 (INTVAL (op
))) < 0)
3131 output_operand_lossage ("invalid %%p value");
3133 fprintf (file
, "%d", value
);
3136 else if (letter
== 'Z')
3141 else if (code
== REG
|| code
== SUBREG
)
3146 regnum
= REGNO (op
);
3148 regnum
= true_regnum (op
);
3150 if ((letter
== 'M' && ! WORDS_BIG_ENDIAN
)
3151 || (letter
== 'L' && WORDS_BIG_ENDIAN
)
3155 fprintf (file
, "%s", reg_names
[regnum
]);
3158 else if (code
== MEM
)
3160 machine_mode mode
= GET_MODE (op
);
3163 output_address (mode
, plus_constant (Pmode
, XEXP (op
, 0), 4));
3165 output_address (mode
, XEXP (op
, 0));
3168 else if (code
== CONST_DOUBLE
3169 && GET_MODE_CLASS (GET_MODE (op
)) == MODE_FLOAT
)
3173 real_to_decimal (s
, CONST_DOUBLE_REAL_VALUE (op
), sizeof (s
), 0, 1);
3177 else if (letter
== 'x' && GET_CODE (op
) == CONST_INT
)
3178 fprintf (file
, HOST_WIDE_INT_PRINT_HEX
, 0xffff & INTVAL(op
));
3180 else if (letter
== 'X' && GET_CODE(op
) == CONST_INT
)
3181 fprintf (file
, HOST_WIDE_INT_PRINT_HEX
, 0xffff & (INTVAL (op
) >> 16));
3183 else if (letter
== 'd' && GET_CODE(op
) == CONST_INT
)
3184 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, (INTVAL(op
)));
3186 else if (letter
== 'z' && GET_CODE (op
) == CONST_INT
&& INTVAL (op
) == 0)
3187 fputs (reg_names
[GP_REG_FIRST
], file
);
3189 else if (letter
== 'd' || letter
== 'x' || letter
== 'X')
3190 output_operand_lossage ("invalid use of %%d, %%x, or %%X");
3192 else if (letter
== 'B')
3193 fputs (code
== EQ
? "z" : "n", file
);
3194 else if (letter
== 'b')
3195 fputs (code
== EQ
? "n" : "z", file
);
3196 else if (letter
== 'T')
3197 fputs (code
== EQ
? "f" : "t", file
);
3198 else if (letter
== 't')
3199 fputs (code
== EQ
? "t" : "f", file
);
3201 else if (code
== CONST
&& GET_CODE (XEXP (op
, 0)) == REG
)
3203 iq2000_print_operand (file
, XEXP (op
, 0), letter
);
3207 output_addr_const (file
, op
);
3211 iq2000_print_operand_punct_valid_p (unsigned char code
)
3213 return iq2000_print_operand_punct
[code
];
3216 /* For the IQ2000, transform:
3218 memory(X + <large int>)
3220 Y = <large int> & ~0x7fff;
3222 memory (Z + (<large int> & 0x7fff));
3226 iq2000_legitimize_address (rtx xinsn
, rtx old_x ATTRIBUTE_UNUSED
,
3229 if (TARGET_DEBUG_B_MODE
)
3231 GO_PRINTF ("\n========== LEGITIMIZE_ADDRESS\n");
3232 GO_DEBUG_RTX (xinsn
);
3235 if (iq2000_check_split (xinsn
, mode
))
3237 return gen_rtx_LO_SUM (Pmode
,
3238 copy_to_mode_reg (Pmode
,
3239 gen_rtx_HIGH (Pmode
, xinsn
)),
3243 if (GET_CODE (xinsn
) == PLUS
)
3245 rtx xplus0
= XEXP (xinsn
, 0);
3246 rtx xplus1
= XEXP (xinsn
, 1);
3247 enum rtx_code code0
= GET_CODE (xplus0
);
3248 enum rtx_code code1
= GET_CODE (xplus1
);
3250 if (code0
!= REG
&& code1
== REG
)
3252 xplus0
= XEXP (xinsn
, 1);
3253 xplus1
= XEXP (xinsn
, 0);
3254 code0
= GET_CODE (xplus0
);
3255 code1
= GET_CODE (xplus1
);
3258 if (code0
== REG
&& REG_MODE_OK_FOR_BASE_P (xplus0
, mode
)
3259 && code1
== CONST_INT
&& !SMALL_INT (xplus1
))
3261 rtx int_reg
= gen_reg_rtx (Pmode
);
3262 rtx ptr_reg
= gen_reg_rtx (Pmode
);
3264 emit_move_insn (int_reg
,
3265 GEN_INT (INTVAL (xplus1
) & ~ 0x7fff));
3267 emit_insn (gen_rtx_SET (ptr_reg
,
3268 gen_rtx_PLUS (Pmode
, xplus0
, int_reg
)));
3270 return plus_constant (Pmode
, ptr_reg
, INTVAL (xplus1
) & 0x7fff);
3274 if (TARGET_DEBUG_B_MODE
)
3275 GO_PRINTF ("LEGITIMIZE_ADDRESS could not fix.\n");
3282 iq2000_rtx_costs (rtx x
, machine_mode mode
, int outer_code ATTRIBUTE_UNUSED
,
3283 int opno ATTRIBUTE_UNUSED
, int * total
,
3284 bool speed ATTRIBUTE_UNUSED
)
3286 int code
= GET_CODE (x
);
3292 int num_words
= (GET_MODE_SIZE (mode
) > UNITS_PER_WORD
) ? 2 : 1;
3294 if (simple_memory_operand (x
, mode
))
3295 return COSTS_N_INSNS (num_words
) != 0;
3297 * total
= COSTS_N_INSNS (2 * num_words
);
3302 * total
= COSTS_N_INSNS (6);
3309 * total
= COSTS_N_INSNS (mode
== DImode
? 2 : 1);
3316 * total
= COSTS_N_INSNS ((GET_CODE (XEXP (x
, 1)) == CONST_INT
) ? 4 : 12);
3318 * total
= COSTS_N_INSNS (1);
3322 if (mode
== SFmode
|| mode
== DFmode
)
3323 * total
= COSTS_N_INSNS (1);
3325 * total
= COSTS_N_INSNS (4);
3330 if (mode
== SFmode
|| mode
== DFmode
)
3331 * total
= COSTS_N_INSNS (6);
3332 else if (mode
== DImode
)
3333 * total
= COSTS_N_INSNS (4);
3335 * total
= COSTS_N_INSNS (1);
3339 * total
= (mode
== DImode
) ? 4 : 1;
3344 * total
= COSTS_N_INSNS (7);
3345 else if (mode
== DFmode
)
3346 * total
= COSTS_N_INSNS (8);
3348 * total
= COSTS_N_INSNS (10);
3354 * total
= COSTS_N_INSNS (23);
3355 else if (mode
== DFmode
)
3356 * total
= COSTS_N_INSNS (36);
3358 * total
= COSTS_N_INSNS (69);
3363 * total
= COSTS_N_INSNS (69);
3367 * total
= COSTS_N_INSNS (2);
3371 * total
= COSTS_N_INSNS (1);
3379 * total
= COSTS_N_INSNS (2);
3384 rtx offset
= const0_rtx
;
3385 rtx symref
= eliminate_constant_term (XEXP (x
, 0), & offset
);
3387 if (GET_CODE (symref
) == LABEL_REF
)
3388 * total
= COSTS_N_INSNS (2);
3389 else if (GET_CODE (symref
) != SYMBOL_REF
)
3390 * total
= COSTS_N_INSNS (4);
3391 /* Let's be paranoid.... */
3392 else if (INTVAL (offset
) < -32768 || INTVAL (offset
) > 32767)
3393 * total
= COSTS_N_INSNS (2);
3395 * total
= COSTS_N_INSNS (SYMBOL_REF_FLAG (symref
) ? 1 : 2);
3400 * total
= COSTS_N_INSNS (SYMBOL_REF_FLAG (x
) ? 1 : 2);
3407 split_double (x
, & high
, & low
);
3409 * total
= COSTS_N_INSNS ( (high
== CONST0_RTX (GET_MODE (high
))
3410 || low
== CONST0_RTX (GET_MODE (low
)))
3421 /* Worker for TARGET_ASM_TRAMPOLINE_TEMPLATE. */
3424 iq2000_asm_trampoline_template (FILE *f
)
3426 fprintf (f
, "\t.word\t0x03e00821\t\t# move $1,$31\n");
3427 fprintf (f
, "\t.word\t0x04110001\t\t# bgezal $0,.+8\n");
3428 fprintf (f
, "\t.word\t0x00000000\t\t# nop\n");
3429 if (Pmode
== DImode
)
3431 fprintf (f
, "\t.word\t0xdfe30014\t\t# ld $3,20($31)\n");
3432 fprintf (f
, "\t.word\t0xdfe2001c\t\t# ld $2,28($31)\n");
3436 fprintf (f
, "\t.word\t0x8fe30014\t\t# lw $3,20($31)\n");
3437 fprintf (f
, "\t.word\t0x8fe20018\t\t# lw $2,24($31)\n");
3439 fprintf (f
, "\t.word\t0x0060c821\t\t# move $25,$3 (abicalls)\n");
3440 fprintf (f
, "\t.word\t0x00600008\t\t# jr $3\n");
3441 fprintf (f
, "\t.word\t0x0020f821\t\t# move $31,$1\n");
3442 fprintf (f
, "\t.word\t0x00000000\t\t# <function address>\n");
3443 fprintf (f
, "\t.word\t0x00000000\t\t# <static chain value>\n");
3446 /* Worker for TARGET_TRAMPOLINE_INIT. */
3449 iq2000_trampoline_init (rtx m_tramp
, tree fndecl
, rtx chain_value
)
3451 rtx fnaddr
= XEXP (DECL_RTL (fndecl
), 0);
3454 emit_block_move (m_tramp
, assemble_trampoline_template (),
3455 GEN_INT (TRAMPOLINE_CODE_SIZE
), BLOCK_OP_NORMAL
);
3457 mem
= adjust_address (m_tramp
, Pmode
, TRAMPOLINE_CODE_SIZE
);
3458 emit_move_insn (mem
, fnaddr
);
3459 mem
= adjust_address (m_tramp
, Pmode
,
3460 TRAMPOLINE_CODE_SIZE
+ GET_MODE_SIZE (Pmode
));
3461 emit_move_insn (mem
, chain_value
);
3464 /* Implement TARGET_HARD_REGNO_MODE_OK. */
3467 iq2000_hard_regno_mode_ok (unsigned int regno
, machine_mode mode
)
3469 return (REGNO_REG_CLASS (regno
) == GR_REGS
3470 ? (regno
& 1) == 0 || GET_MODE_SIZE (mode
) <= 4
3471 : (regno
& 1) == 0 || GET_MODE_SIZE (mode
) == 4);
3474 /* Implement TARGET_MODES_TIEABLE_P. */
3477 iq2000_modes_tieable_p (machine_mode mode1
, machine_mode mode2
)
3479 return ((GET_MODE_CLASS (mode1
) == MODE_FLOAT
3480 || GET_MODE_CLASS (mode1
) == MODE_COMPLEX_FLOAT
)
3481 == (GET_MODE_CLASS (mode2
) == MODE_FLOAT
3482 || GET_MODE_CLASS (mode2
) == MODE_COMPLEX_FLOAT
));
3485 /* Implement TARGET_CONSTANT_ALIGNMENT. */
3487 static HOST_WIDE_INT
3488 iq2000_constant_alignment (const_tree exp
, HOST_WIDE_INT align
)
3490 if (TREE_CODE (exp
) == STRING_CST
|| TREE_CODE (exp
) == CONSTRUCTOR
)
3491 return MAX (align
, BITS_PER_WORD
);
3495 /* Implement TARGET_STARTING_FRAME_OFFSET. */
3497 static HOST_WIDE_INT
3498 iq2000_starting_frame_offset (void)
3500 return crtl
->outgoing_args_size
;
3503 #include "gt-iq2000.h"