1 /* Subroutines used for code generation on Vitesse IQ2000 processors
2 Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009
3 Free Software Foundation, Inc.
5 This file is part of GCC.
7 GCC is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3, or (at your option)
12 GCC is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING3. If not see
19 <http://www.gnu.org/licenses/>. */
23 #include "coretypes.h"
29 #include "hard-reg-set.h"
30 #include "insn-config.h"
31 #include "conditions.h"
33 #include "insn-attr.h"
46 #include "target-def.h"
47 #include "langhooks.h"
49 /* Enumeration for all of the relational tests, so that we can build
50 arrays indexed by the test type, and not worry about the order
71 /* Structure to be filled in by compute_frame_size with register
72 save masks, and offsets for the current function. */
74 struct iq2000_frame_info
76 long total_size
; /* # bytes that the entire frame takes up. */
77 long var_size
; /* # bytes that variables take up. */
78 long args_size
; /* # bytes that outgoing arguments take up. */
79 long extra_size
; /* # bytes of extra gunk. */
80 int gp_reg_size
; /* # bytes needed to store gp regs. */
81 int fp_reg_size
; /* # bytes needed to store fp regs. */
82 long mask
; /* Mask of saved gp registers. */
83 long gp_save_offset
; /* Offset from vfp to store gp registers. */
84 long fp_save_offset
; /* Offset from vfp to store fp registers. */
85 long gp_sp_offset
; /* Offset from new sp to store gp registers. */
86 long fp_sp_offset
; /* Offset from new sp to store fp registers. */
87 int initialized
; /* != 0 if frame size already calculated. */
88 int num_gp
; /* Number of gp registers saved. */
91 struct GTY(()) machine_function
93 /* Current frame information, calculated by compute_frame_size. */
94 long total_size
; /* # bytes that the entire frame takes up. */
95 long var_size
; /* # bytes that variables take up. */
96 long args_size
; /* # bytes that outgoing arguments take up. */
97 long extra_size
; /* # bytes of extra gunk. */
98 int gp_reg_size
; /* # bytes needed to store gp regs. */
99 int fp_reg_size
; /* # bytes needed to store fp regs. */
100 long mask
; /* Mask of saved gp registers. */
101 long gp_save_offset
; /* Offset from vfp to store gp registers. */
102 long fp_save_offset
; /* Offset from vfp to store fp registers. */
103 long gp_sp_offset
; /* Offset from new sp to store gp registers. */
104 long fp_sp_offset
; /* Offset from new sp to store fp registers. */
105 int initialized
; /* != 0 if frame size already calculated. */
106 int num_gp
; /* Number of gp registers saved. */
109 /* Global variables for machine-dependent things. */
111 /* List of all IQ2000 punctuation characters used by iq2000_print_operand. */
112 static char iq2000_print_operand_punct
[256];
114 /* The target cpu for optimization and scheduling. */
115 enum processor_type iq2000_tune
;
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 enum machine_mode gpr_mode
;
146 /* Initialize the GCC target structure. */
147 static struct machine_function
* iq2000_init_machine_status (void);
148 static bool iq2000_handle_option (size_t, const char *, int);
149 static section
*iq2000_select_rtx_section (enum machine_mode
, rtx
,
150 unsigned HOST_WIDE_INT
);
151 static void iq2000_init_builtins (void);
152 static rtx
iq2000_expand_builtin (tree
, rtx
, rtx
, enum machine_mode
, int);
153 static bool iq2000_return_in_memory (const_tree
, const_tree
);
154 static void iq2000_setup_incoming_varargs (CUMULATIVE_ARGS
*,
155 enum machine_mode
, tree
, int *,
157 static bool iq2000_rtx_costs (rtx
, int, int, int *, bool);
158 static int iq2000_address_cost (rtx
, bool);
159 static section
*iq2000_select_section (tree
, int, unsigned HOST_WIDE_INT
);
160 static rtx
iq2000_legitimize_address (rtx
, rtx
, enum machine_mode
);
161 static bool iq2000_pass_by_reference (CUMULATIVE_ARGS
*, enum machine_mode
,
163 static int iq2000_arg_partial_bytes (CUMULATIVE_ARGS
*, enum machine_mode
,
165 static void iq2000_va_start (tree
, rtx
);
166 static bool iq2000_legitimate_address_p (enum machine_mode
, rtx
, bool);
167 static bool iq2000_can_eliminate (const int, const int);
168 static void iq2000_asm_trampoline_template (FILE *);
169 static void iq2000_trampoline_init (rtx
, tree
, rtx
);
170 static rtx
iq2000_function_value (const_tree
, const_tree
, bool);
171 static rtx
iq2000_libcall_value (enum machine_mode
, const_rtx
);
172 static void iq2000_print_operand (FILE *, rtx
, int);
173 static void iq2000_print_operand_address (FILE *, rtx
);
174 static bool iq2000_print_operand_punct_valid_p (unsigned char code
);
176 #undef TARGET_INIT_BUILTINS
177 #define TARGET_INIT_BUILTINS iq2000_init_builtins
178 #undef TARGET_EXPAND_BUILTIN
179 #define TARGET_EXPAND_BUILTIN iq2000_expand_builtin
180 #undef TARGET_ASM_SELECT_RTX_SECTION
181 #define TARGET_ASM_SELECT_RTX_SECTION iq2000_select_rtx_section
182 #undef TARGET_HANDLE_OPTION
183 #define TARGET_HANDLE_OPTION iq2000_handle_option
184 #undef TARGET_RTX_COSTS
185 #define TARGET_RTX_COSTS iq2000_rtx_costs
186 #undef TARGET_ADDRESS_COST
187 #define TARGET_ADDRESS_COST iq2000_address_cost
188 #undef TARGET_ASM_SELECT_SECTION
189 #define TARGET_ASM_SELECT_SECTION iq2000_select_section
191 #undef TARGET_LEGITIMIZE_ADDRESS
192 #define TARGET_LEGITIMIZE_ADDRESS iq2000_legitimize_address
194 /* The assembler supports switchable .bss sections, but
195 iq2000_select_section doesn't yet make use of them. */
196 #undef TARGET_HAVE_SWITCHABLE_BSS_SECTIONS
197 #define TARGET_HAVE_SWITCHABLE_BSS_SECTIONS false
199 #undef TARGET_PRINT_OPERAND
200 #define TARGET_PRINT_OPERAND iq2000_print_operand
201 #undef TARGET_PRINT_OPERAND_ADDRESS
202 #define TARGET_PRINT_OPERAND_ADDRESS iq2000_print_operand_address
203 #undef TARGET_PRINT_OPERAND_PUNCT_VALID_P
204 #define TARGET_PRINT_OPERAND_PUNCT_VALID_P iq2000_print_operand_punct_valid_p
206 #undef TARGET_PROMOTE_FUNCTION_MODE
207 #define TARGET_PROMOTE_FUNCTION_MODE default_promote_function_mode_always_promote
208 #undef TARGET_PROMOTE_PROTOTYPES
209 #define TARGET_PROMOTE_PROTOTYPES hook_bool_const_tree_true
211 #undef TARGET_FUNCTION_VALUE
212 #define TARGET_FUNCTION_VALUE iq2000_function_value
213 #undef TARGET_LIBCALL_VALUE
214 #define TARGET_LIBCALL_VALUE iq2000_libcall_value
215 #undef TARGET_RETURN_IN_MEMORY
216 #define TARGET_RETURN_IN_MEMORY iq2000_return_in_memory
217 #undef TARGET_PASS_BY_REFERENCE
218 #define TARGET_PASS_BY_REFERENCE iq2000_pass_by_reference
219 #undef TARGET_CALLEE_COPIES
220 #define TARGET_CALLEE_COPIES hook_callee_copies_named
221 #undef TARGET_ARG_PARTIAL_BYTES
222 #define TARGET_ARG_PARTIAL_BYTES iq2000_arg_partial_bytes
224 #undef TARGET_SETUP_INCOMING_VARARGS
225 #define TARGET_SETUP_INCOMING_VARARGS iq2000_setup_incoming_varargs
226 #undef TARGET_STRICT_ARGUMENT_NAMING
227 #define TARGET_STRICT_ARGUMENT_NAMING hook_bool_CUMULATIVE_ARGS_true
229 #undef TARGET_EXPAND_BUILTIN_VA_START
230 #define TARGET_EXPAND_BUILTIN_VA_START iq2000_va_start
232 #undef TARGET_LEGITIMATE_ADDRESS_P
233 #define TARGET_LEGITIMATE_ADDRESS_P iq2000_legitimate_address_p
235 #undef TARGET_CAN_ELIMINATE
236 #define TARGET_CAN_ELIMINATE iq2000_can_eliminate
238 #undef TARGET_ASM_TRAMPOLINE_TEMPLATE
239 #define TARGET_ASM_TRAMPOLINE_TEMPLATE iq2000_asm_trampoline_template
240 #undef TARGET_TRAMPOLINE_INIT
241 #define TARGET_TRAMPOLINE_INIT iq2000_trampoline_init
243 struct gcc_target targetm
= TARGET_INITIALIZER
;
245 /* Return nonzero if we split the address into high and low parts. */
248 iq2000_check_split (rtx address
, enum machine_mode mode
)
250 /* This is the same check used in simple_memory_operand.
251 We use it here because LO_SUM is not offsettable. */
252 if (GET_MODE_SIZE (mode
) > (unsigned) UNITS_PER_WORD
)
255 if ((GET_CODE (address
) == SYMBOL_REF
)
256 || (GET_CODE (address
) == CONST
257 && GET_CODE (XEXP (XEXP (address
, 0), 0)) == SYMBOL_REF
)
258 || GET_CODE (address
) == LABEL_REF
)
264 /* Return nonzero if REG is valid for MODE. */
267 iq2000_reg_mode_ok_for_base_p (rtx reg
,
268 enum machine_mode mode ATTRIBUTE_UNUSED
,
272 ? REGNO_MODE_OK_FOR_BASE_P (REGNO (reg
), mode
)
273 : GP_REG_OR_PSEUDO_NONSTRICT_P (REGNO (reg
), mode
));
276 /* Return a nonzero value if XINSN is a legitimate address for a
277 memory operand of the indicated MODE. STRICT is nonzero if this
278 function is called during reload. */
281 iq2000_legitimate_address_p (enum machine_mode mode
, rtx xinsn
, bool strict
)
283 if (TARGET_DEBUG_A_MODE
)
285 GO_PRINTF2 ("\n========== legitimate_address_p, %sstrict\n",
286 strict
? "" : "not ");
287 GO_DEBUG_RTX (xinsn
);
290 /* Check for constant before stripping off SUBREG, so that we don't
291 accept (subreg (const_int)) which will fail to reload. */
292 if (CONSTANT_ADDRESS_P (xinsn
)
293 && ! (iq2000_check_split (xinsn
, mode
))
294 && ! (GET_CODE (xinsn
) == CONST_INT
&& ! SMALL_INT (xinsn
)))
297 while (GET_CODE (xinsn
) == SUBREG
)
298 xinsn
= SUBREG_REG (xinsn
);
300 if (GET_CODE (xinsn
) == REG
301 && iq2000_reg_mode_ok_for_base_p (xinsn
, mode
, strict
))
304 if (GET_CODE (xinsn
) == LO_SUM
)
306 rtx xlow0
= XEXP (xinsn
, 0);
307 rtx xlow1
= XEXP (xinsn
, 1);
309 while (GET_CODE (xlow0
) == SUBREG
)
310 xlow0
= SUBREG_REG (xlow0
);
311 if (GET_CODE (xlow0
) == REG
312 && iq2000_reg_mode_ok_for_base_p (xlow0
, mode
, strict
)
313 && iq2000_check_split (xlow1
, mode
))
317 if (GET_CODE (xinsn
) == PLUS
)
319 rtx xplus0
= XEXP (xinsn
, 0);
320 rtx xplus1
= XEXP (xinsn
, 1);
324 while (GET_CODE (xplus0
) == SUBREG
)
325 xplus0
= SUBREG_REG (xplus0
);
326 code0
= GET_CODE (xplus0
);
328 while (GET_CODE (xplus1
) == SUBREG
)
329 xplus1
= SUBREG_REG (xplus1
);
330 code1
= GET_CODE (xplus1
);
333 && iq2000_reg_mode_ok_for_base_p (xplus0
, mode
, strict
))
335 if (code1
== CONST_INT
&& SMALL_INT (xplus1
)
336 && SMALL_INT_UNSIGNED (xplus1
) /* No negative offsets */)
341 if (TARGET_DEBUG_A_MODE
)
342 GO_PRINTF ("Not a enum machine_mode mode, legitimate address\n");
344 /* The address was not legitimate. */
348 /* Returns an operand string for the given instruction's delay slot,
349 after updating filled delay slot statistics.
351 We assume that operands[0] is the target register that is set.
353 In order to check the next insn, most of this functionality is moved
354 to FINAL_PRESCAN_INSN, and we just set the global variables that
358 iq2000_fill_delay_slot (const char *ret
, enum delay_type type
, rtx operands
[],
362 enum machine_mode mode
;
363 rtx next_insn
= cur_insn
? NEXT_INSN (cur_insn
) : NULL_RTX
;
366 if (type
== DELAY_LOAD
|| type
== DELAY_FCMP
)
372 /* Make sure that we don't put nop's after labels. */
373 next_insn
= NEXT_INSN (cur_insn
);
374 while (next_insn
!= 0
375 && (GET_CODE (next_insn
) == NOTE
376 || GET_CODE (next_insn
) == CODE_LABEL
))
377 next_insn
= NEXT_INSN (next_insn
);
379 dslots_load_total
+= num_nops
;
380 if (TARGET_DEBUG_C_MODE
381 || type
== DELAY_NONE
385 || GET_CODE (next_insn
) == CODE_LABEL
386 || (set_reg
= operands
[0]) == 0)
388 dslots_number_nops
= 0;
390 iq2000_load_reg2
= 0;
391 iq2000_load_reg3
= 0;
392 iq2000_load_reg4
= 0;
397 set_reg
= operands
[0];
401 while (GET_CODE (set_reg
) == SUBREG
)
402 set_reg
= SUBREG_REG (set_reg
);
404 mode
= GET_MODE (set_reg
);
405 dslots_number_nops
= num_nops
;
406 iq2000_load_reg
= set_reg
;
407 if (GET_MODE_SIZE (mode
)
408 > (unsigned) (UNITS_PER_WORD
))
409 iq2000_load_reg2
= gen_rtx_REG (SImode
, REGNO (set_reg
) + 1);
411 iq2000_load_reg2
= 0;
416 /* Determine whether a memory reference takes one (based off of the GP
417 pointer), two (normal), or three (label + reg) instructions, and bump the
418 appropriate counter for -mstats. */
421 iq2000_count_memory_refs (rtx op
, int num
)
425 rtx addr
, plus0
, plus1
;
426 enum rtx_code code0
, code1
;
429 if (TARGET_DEBUG_B_MODE
)
431 fprintf (stderr
, "\n========== iq2000_count_memory_refs:\n");
435 /* Skip MEM if passed, otherwise handle movsi of address. */
436 addr
= (GET_CODE (op
) != MEM
) ? op
: XEXP (op
, 0);
438 /* Loop, going through the address RTL. */
442 switch (GET_CODE (addr
))
450 plus0
= XEXP (addr
, 0);
451 plus1
= XEXP (addr
, 1);
452 code0
= GET_CODE (plus0
);
453 code1
= GET_CODE (plus1
);
463 if (code0
== CONST_INT
)
478 if (code1
== CONST_INT
)
485 if (code0
== SYMBOL_REF
|| code0
== LABEL_REF
|| code0
== CONST
)
492 if (code1
== SYMBOL_REF
|| code1
== LABEL_REF
|| code1
== CONST
)
502 n_words
= 2; /* Always 2 words. */
506 addr
= XEXP (addr
, 0);
511 n_words
= SYMBOL_REF_FLAG (addr
) ? 1 : 2;
523 n_words
+= additional
;
527 num_refs
[n_words
-1] += num
;
530 /* Abort after printing out a specific insn. */
533 abort_with_insn (rtx insn
, const char * reason
)
537 fancy_abort (__FILE__
, __LINE__
, __FUNCTION__
);
540 /* Return the appropriate instructions to move one operand to another. */
543 iq2000_move_1word (rtx operands
[], rtx insn
, int unsignedp
)
546 rtx op0
= operands
[0];
547 rtx op1
= operands
[1];
548 enum rtx_code code0
= GET_CODE (op0
);
549 enum rtx_code code1
= GET_CODE (op1
);
550 enum machine_mode mode
= GET_MODE (op0
);
551 int subreg_offset0
= 0;
552 int subreg_offset1
= 0;
553 enum delay_type delay
= DELAY_NONE
;
555 while (code0
== SUBREG
)
557 subreg_offset0
+= subreg_regno_offset (REGNO (SUBREG_REG (op0
)),
558 GET_MODE (SUBREG_REG (op0
)),
561 op0
= SUBREG_REG (op0
);
562 code0
= GET_CODE (op0
);
565 while (code1
== SUBREG
)
567 subreg_offset1
+= subreg_regno_offset (REGNO (SUBREG_REG (op1
)),
568 GET_MODE (SUBREG_REG (op1
)),
571 op1
= SUBREG_REG (op1
);
572 code1
= GET_CODE (op1
);
575 /* For our purposes, a condition code mode is the same as SImode. */
581 int regno0
= REGNO (op0
) + subreg_offset0
;
585 int regno1
= REGNO (op1
) + subreg_offset1
;
587 /* Do not do anything for assigning a register to itself */
588 if (regno0
== regno1
)
591 else if (GP_REG_P (regno0
))
593 if (GP_REG_P (regno1
))
594 ret
= "or\t%0,%%0,%1";
599 else if (code1
== MEM
)
604 iq2000_count_memory_refs (op1
, 1);
606 if (GP_REG_P (regno0
))
608 /* For loads, use the mode of the memory item, instead of the
609 target, so zero/sign extend can use this code as well. */
610 switch (GET_MODE (op1
))
622 ret
= (unsignedp
) ? "lhu\t%0,%1" : "lh\t%0,%1";
625 ret
= (unsignedp
) ? "lbu\t%0,%1" : "lb\t%0,%1";
631 else if (code1
== CONST_INT
632 || (code1
== CONST_DOUBLE
633 && GET_MODE (op1
) == VOIDmode
))
635 if (code1
== CONST_DOUBLE
)
637 /* This can happen when storing constants into long long
638 bitfields. Just store the least significant word of
640 operands
[1] = op1
= GEN_INT (CONST_DOUBLE_LOW (op1
));
643 if (INTVAL (op1
) == 0)
645 if (GP_REG_P (regno0
))
646 ret
= "or\t%0,%%0,%z1";
648 else if (GP_REG_P (regno0
))
650 if (SMALL_INT_UNSIGNED (op1
))
651 ret
= "ori\t%0,%%0,%x1\t\t\t# %1";
652 else if (SMALL_INT (op1
))
653 ret
= "addiu\t%0,%%0,%1\t\t\t# %1";
655 ret
= "lui\t%0,%X1\t\t\t# %1\n\tori\t%0,%0,%x1";
659 else if (code1
== CONST_DOUBLE
&& mode
== SFmode
)
661 if (op1
== CONST0_RTX (SFmode
))
663 if (GP_REG_P (regno0
))
664 ret
= "or\t%0,%%0,%.";
674 else if (code1
== LABEL_REF
)
677 iq2000_count_memory_refs (op1
, 1);
682 else if (code1
== SYMBOL_REF
|| code1
== CONST
)
685 iq2000_count_memory_refs (op1
, 1);
690 else if (code1
== PLUS
)
692 rtx add_op0
= XEXP (op1
, 0);
693 rtx add_op1
= XEXP (op1
, 1);
695 if (GET_CODE (XEXP (op1
, 1)) == REG
696 && GET_CODE (XEXP (op1
, 0)) == CONST_INT
)
697 add_op0
= XEXP (op1
, 1), add_op1
= XEXP (op1
, 0);
699 operands
[2] = add_op0
;
700 operands
[3] = add_op1
;
701 ret
= "add%:\t%0,%2,%3";
704 else if (code1
== HIGH
)
706 operands
[1] = XEXP (op1
, 0);
707 ret
= "lui\t%0,%%hi(%1)";
711 else if (code0
== MEM
)
714 iq2000_count_memory_refs (op0
, 1);
718 int regno1
= REGNO (op1
) + subreg_offset1
;
720 if (GP_REG_P (regno1
))
724 case SFmode
: ret
= "sw\t%1,%0"; break;
725 case SImode
: ret
= "sw\t%1,%0"; break;
726 case HImode
: ret
= "sh\t%1,%0"; break;
727 case QImode
: ret
= "sb\t%1,%0"; break;
733 else if (code1
== CONST_INT
&& INTVAL (op1
) == 0)
737 case SFmode
: ret
= "sw\t%z1,%0"; break;
738 case SImode
: ret
= "sw\t%z1,%0"; break;
739 case HImode
: ret
= "sh\t%z1,%0"; break;
740 case QImode
: ret
= "sb\t%z1,%0"; break;
745 else if (code1
== CONST_DOUBLE
&& op1
== CONST0_RTX (mode
))
749 case SFmode
: ret
= "sw\t%.,%0"; break;
750 case SImode
: ret
= "sw\t%.,%0"; break;
751 case HImode
: ret
= "sh\t%.,%0"; break;
752 case QImode
: ret
= "sb\t%.,%0"; break;
760 abort_with_insn (insn
, "Bad move");
764 if (delay
!= DELAY_NONE
)
765 return iq2000_fill_delay_slot (ret
, delay
, operands
, insn
);
770 /* Provide the costs of an addressing mode that contains ADDR. */
773 iq2000_address_cost (rtx addr
, bool speed
)
775 switch (GET_CODE (addr
))
785 rtx offset
= const0_rtx
;
787 addr
= eliminate_constant_term (XEXP (addr
, 0), & offset
);
788 if (GET_CODE (addr
) == LABEL_REF
)
791 if (GET_CODE (addr
) != SYMBOL_REF
)
794 if (! SMALL_INT (offset
))
801 return SYMBOL_REF_FLAG (addr
) ? 1 : 2;
805 rtx plus0
= XEXP (addr
, 0);
806 rtx plus1
= XEXP (addr
, 1);
808 if (GET_CODE (plus0
) != REG
&& GET_CODE (plus1
) == REG
)
809 plus0
= XEXP (addr
, 1), plus1
= XEXP (addr
, 0);
811 if (GET_CODE (plus0
) != REG
)
814 switch (GET_CODE (plus1
))
817 return SMALL_INT (plus1
) ? 1 : 2;
824 return iq2000_address_cost (plus1
, speed
) + 1;
838 /* Make normal rtx_code into something we can index from an array. */
840 static enum internal_test
841 map_test_to_internal_test (enum rtx_code test_code
)
843 enum internal_test test
= ITEST_MAX
;
847 case EQ
: test
= ITEST_EQ
; break;
848 case NE
: test
= ITEST_NE
; break;
849 case GT
: test
= ITEST_GT
; break;
850 case GE
: test
= ITEST_GE
; break;
851 case LT
: test
= ITEST_LT
; break;
852 case LE
: test
= ITEST_LE
; break;
853 case GTU
: test
= ITEST_GTU
; break;
854 case GEU
: test
= ITEST_GEU
; break;
855 case LTU
: test
= ITEST_LTU
; break;
856 case LEU
: test
= ITEST_LEU
; break;
863 /* Generate the code to do a TEST_CODE comparison on two integer values CMP0
864 and CMP1. P_INVERT is NULL or ptr if branch needs to reverse its test.
865 The return value RESULT is:
866 (reg:SI xx) The pseudo register the comparison is in
867 0 No register, generate a simple branch. */
870 gen_int_relational (enum rtx_code test_code
, rtx result
, rtx cmp0
, rtx cmp1
,
875 enum rtx_code test_code
; /* Code to use in instruction (LT vs. LTU). */
876 int const_low
; /* Low bound of constant we can accept. */
877 int const_high
; /* High bound of constant we can accept. */
878 int const_add
; /* Constant to add (convert LE -> LT). */
879 int reverse_regs
; /* Reverse registers in test. */
880 int invert_const
; /* != 0 if invert value if cmp1 is constant. */
881 int invert_reg
; /* != 0 if invert value if cmp1 is register. */
882 int unsignedp
; /* != 0 for unsigned comparisons. */
885 static struct cmp_info info
[ (int)ITEST_MAX
] =
887 { XOR
, 0, 65535, 0, 0, 0, 0, 0 }, /* EQ */
888 { XOR
, 0, 65535, 0, 0, 1, 1, 0 }, /* NE */
889 { LT
, -32769, 32766, 1, 1, 1, 0, 0 }, /* GT */
890 { LT
, -32768, 32767, 0, 0, 1, 1, 0 }, /* GE */
891 { LT
, -32768, 32767, 0, 0, 0, 0, 0 }, /* LT */
892 { LT
, -32769, 32766, 1, 1, 0, 1, 0 }, /* LE */
893 { LTU
, -32769, 32766, 1, 1, 1, 0, 1 }, /* GTU */
894 { LTU
, -32768, 32767, 0, 0, 1, 1, 1 }, /* GEU */
895 { LTU
, -32768, 32767, 0, 0, 0, 0, 1 }, /* LTU */
896 { LTU
, -32769, 32766, 1, 1, 0, 1, 1 }, /* LEU */
899 enum internal_test test
;
900 enum machine_mode mode
;
901 struct cmp_info
*p_info
;
908 test
= map_test_to_internal_test (test_code
);
909 gcc_assert (test
!= ITEST_MAX
);
911 p_info
= &info
[(int) test
];
912 eqne_p
= (p_info
->test_code
== XOR
);
914 mode
= GET_MODE (cmp0
);
915 if (mode
== VOIDmode
)
916 mode
= GET_MODE (cmp1
);
918 /* Eliminate simple branches. */
919 branch_p
= (result
== 0);
922 if (GET_CODE (cmp0
) == REG
|| GET_CODE (cmp0
) == SUBREG
)
924 /* Comparisons against zero are simple branches. */
925 if (GET_CODE (cmp1
) == CONST_INT
&& INTVAL (cmp1
) == 0)
928 /* Test for beq/bne. */
933 /* Allocate a pseudo to calculate the value in. */
934 result
= gen_reg_rtx (mode
);
937 /* Make sure we can handle any constants given to us. */
938 if (GET_CODE (cmp0
) == CONST_INT
)
939 cmp0
= force_reg (mode
, cmp0
);
941 if (GET_CODE (cmp1
) == CONST_INT
)
943 HOST_WIDE_INT value
= INTVAL (cmp1
);
945 if (value
< p_info
->const_low
946 || value
> p_info
->const_high
)
947 cmp1
= force_reg (mode
, cmp1
);
950 /* See if we need to invert the result. */
951 invert
= (GET_CODE (cmp1
) == CONST_INT
952 ? p_info
->invert_const
: p_info
->invert_reg
);
954 if (p_invert
!= (int *)0)
960 /* Comparison to constants, may involve adding 1 to change a LT into LE.
961 Comparison between two registers, may involve switching operands. */
962 if (GET_CODE (cmp1
) == CONST_INT
)
964 if (p_info
->const_add
!= 0)
966 HOST_WIDE_INT new_const
= INTVAL (cmp1
) + p_info
->const_add
;
968 /* If modification of cmp1 caused overflow,
969 we would get the wrong answer if we follow the usual path;
970 thus, x > 0xffffffffU would turn into x > 0U. */
971 if ((p_info
->unsignedp
972 ? (unsigned HOST_WIDE_INT
) new_const
>
973 (unsigned HOST_WIDE_INT
) INTVAL (cmp1
)
974 : new_const
> INTVAL (cmp1
))
975 != (p_info
->const_add
> 0))
977 /* This test is always true, but if INVERT is true then
978 the result of the test needs to be inverted so 0 should
979 be returned instead. */
980 emit_move_insn (result
, invert
? const0_rtx
: const_true_rtx
);
984 cmp1
= GEN_INT (new_const
);
988 else if (p_info
->reverse_regs
)
995 if (test
== ITEST_NE
&& GET_CODE (cmp1
) == CONST_INT
&& INTVAL (cmp1
) == 0)
999 reg
= (invert
|| eqne_p
) ? gen_reg_rtx (mode
) : result
;
1000 convert_move (reg
, gen_rtx_fmt_ee (p_info
->test_code
, mode
, cmp0
, cmp1
), 0);
1003 if (test
== ITEST_NE
)
1005 convert_move (result
, gen_rtx_GTU (mode
, reg
, const0_rtx
), 0);
1006 if (p_invert
!= NULL
)
1011 else if (test
== ITEST_EQ
)
1013 reg2
= invert
? gen_reg_rtx (mode
) : result
;
1014 convert_move (reg2
, gen_rtx_LTU (mode
, reg
, const1_rtx
), 0);
1023 convert_move (result
, gen_rtx_XOR (mode
, reg
, one
), 0);
1029 /* Emit the common code for doing conditional branches.
1030 operand[0] is the label to jump to.
1031 The comparison operands are saved away by cmp{si,di,sf,df}. */
1034 gen_conditional_branch (rtx operands
[], enum machine_mode mode
)
1036 enum rtx_code test_code
= GET_CODE (operands
[0]);
1037 rtx cmp0
= operands
[1];
1038 rtx cmp1
= operands
[2];
1044 reg
= gen_int_relational (test_code
, NULL_RTX
, cmp0
, cmp1
, &invert
);
1052 else if (GET_CODE (cmp1
) == CONST_INT
&& INTVAL (cmp1
) != 0)
1053 /* We don't want to build a comparison against a nonzero
1055 cmp1
= force_reg (mode
, cmp1
);
1057 /* Generate the branch. */
1058 label1
= gen_rtx_LABEL_REF (VOIDmode
, operands
[3]);
1067 emit_jump_insn (gen_rtx_SET (VOIDmode
, pc_rtx
,
1068 gen_rtx_IF_THEN_ELSE (VOIDmode
,
1069 gen_rtx_fmt_ee (test_code
,
1075 /* Initialize CUM for a function FNTYPE. */
1078 init_cumulative_args (CUMULATIVE_ARGS
*cum
, tree fntype
,
1079 rtx libname ATTRIBUTE_UNUSED
)
1081 static CUMULATIVE_ARGS zero_cum
;
1085 if (TARGET_DEBUG_D_MODE
)
1088 "\ninit_cumulative_args, fntype = 0x%.8lx", (long) fntype
);
1091 fputc ('\n', stderr
);
1095 tree ret_type
= TREE_TYPE (fntype
);
1097 fprintf (stderr
, ", fntype code = %s, ret code = %s\n",
1098 tree_code_name
[(int)TREE_CODE (fntype
)],
1099 tree_code_name
[(int)TREE_CODE (ret_type
)]);
1105 /* Determine if this function has variable arguments. This is
1106 indicated by the last argument being 'void_type_mode' if there
1107 are no variable arguments. The standard IQ2000 calling sequence
1108 passes all arguments in the general purpose registers in this case. */
1110 for (param
= fntype
? TYPE_ARG_TYPES (fntype
) : 0;
1111 param
!= 0; param
= next_param
)
1113 next_param
= TREE_CHAIN (param
);
1114 if (next_param
== 0 && TREE_VALUE (param
) != void_type_node
)
1115 cum
->gp_reg_found
= 1;
1119 /* Advance the argument of type TYPE and mode MODE to the next argument
1123 function_arg_advance (CUMULATIVE_ARGS
*cum
, enum machine_mode mode
, tree type
,
1126 if (TARGET_DEBUG_D_MODE
)
1129 "function_adv({gp reg found = %d, arg # = %2d, words = %2d}, %4s, ",
1130 cum
->gp_reg_found
, cum
->arg_number
, cum
->arg_words
,
1131 GET_MODE_NAME (mode
));
1132 fprintf (stderr
, "%p", (void *) type
);
1133 fprintf (stderr
, ", %d )\n\n", named
);
1143 gcc_assert (GET_MODE_CLASS (mode
) == MODE_COMPLEX_INT
1144 || GET_MODE_CLASS (mode
) == MODE_COMPLEX_FLOAT
);
1146 cum
->gp_reg_found
= 1;
1147 cum
->arg_words
+= ((GET_MODE_SIZE (mode
) + UNITS_PER_WORD
- 1)
1152 cum
->gp_reg_found
= 1;
1153 cum
->arg_words
+= ((int_size_in_bytes (type
) + UNITS_PER_WORD
- 1)
1159 if (! cum
->gp_reg_found
&& cum
->arg_number
<= 2)
1160 cum
->fp_code
+= 1 << ((cum
->arg_number
- 1) * 2);
1164 cum
->arg_words
+= 2;
1165 if (! cum
->gp_reg_found
&& cum
->arg_number
<= 2)
1166 cum
->fp_code
+= 2 << ((cum
->arg_number
- 1) * 2);
1170 cum
->gp_reg_found
= 1;
1171 cum
->arg_words
+= 2;
1175 cum
->gp_reg_found
= 1;
1176 cum
->arg_words
+= 4;
1182 cum
->gp_reg_found
= 1;
1188 /* Return an RTL expression containing the register for the given mode MODE
1189 and type TYPE in CUM, or 0 if the argument is to be passed on the stack. */
1192 function_arg (CUMULATIVE_ARGS
*cum
, enum machine_mode mode
, const_tree type
,
1198 unsigned int *arg_words
= &cum
->arg_words
;
1199 int struct_p
= (type
!= 0
1200 && (TREE_CODE (type
) == RECORD_TYPE
1201 || TREE_CODE (type
) == UNION_TYPE
1202 || TREE_CODE (type
) == QUAL_UNION_TYPE
));
1204 if (TARGET_DEBUG_D_MODE
)
1207 "function_arg( {gp reg found = %d, arg # = %2d, words = %2d}, %4s, ",
1208 cum
->gp_reg_found
, cum
->arg_number
, cum
->arg_words
,
1209 GET_MODE_NAME (mode
));
1210 fprintf (stderr
, "%p", (const void *) type
);
1211 fprintf (stderr
, ", %d ) = ", named
);
1215 cum
->last_arg_fp
= 0;
1219 regbase
= GP_ARG_FIRST
;
1223 cum
->arg_words
+= cum
->arg_words
& 1;
1225 regbase
= GP_ARG_FIRST
;
1229 gcc_assert (GET_MODE_CLASS (mode
) == MODE_COMPLEX_INT
1230 || GET_MODE_CLASS (mode
) == MODE_COMPLEX_FLOAT
);
1232 /* Drops through. */
1234 if (type
!= NULL_TREE
&& TYPE_ALIGN (type
) > (unsigned) BITS_PER_WORD
)
1235 cum
->arg_words
+= (cum
->arg_words
& 1);
1236 regbase
= GP_ARG_FIRST
;
1243 regbase
= GP_ARG_FIRST
;
1247 cum
->arg_words
+= (cum
->arg_words
& 1);
1248 regbase
= GP_ARG_FIRST
;
1252 cum
->arg_words
+= (cum
->arg_words
& 3);
1253 regbase
= GP_ARG_FIRST
;
1257 if (*arg_words
>= (unsigned) MAX_ARGS_IN_REGISTERS
)
1259 if (TARGET_DEBUG_D_MODE
)
1260 fprintf (stderr
, "<stack>%s\n", struct_p
? ", [struct]" : "");
1266 gcc_assert (regbase
!= -1);
1268 if (! type
|| TREE_CODE (type
) != RECORD_TYPE
1269 || ! named
|| ! TYPE_SIZE_UNIT (type
)
1270 || ! host_integerp (TYPE_SIZE_UNIT (type
), 1))
1271 ret
= gen_rtx_REG (mode
, regbase
+ *arg_words
+ bias
);
1276 for (field
= TYPE_FIELDS (type
); field
; field
= TREE_CHAIN (field
))
1277 if (TREE_CODE (field
) == FIELD_DECL
1278 && TREE_CODE (TREE_TYPE (field
)) == REAL_TYPE
1279 && TYPE_PRECISION (TREE_TYPE (field
)) == BITS_PER_WORD
1280 && host_integerp (bit_position (field
), 0)
1281 && int_bit_position (field
) % BITS_PER_WORD
== 0)
1284 /* If the whole struct fits a DFmode register,
1285 we don't need the PARALLEL. */
1286 if (! field
|| mode
== DFmode
)
1287 ret
= gen_rtx_REG (mode
, regbase
+ *arg_words
+ bias
);
1290 unsigned int chunks
;
1291 HOST_WIDE_INT bitpos
;
1295 /* ??? If this is a packed structure, then the last hunk won't
1298 = tree_low_cst (TYPE_SIZE_UNIT (type
), 1) / UNITS_PER_WORD
;
1299 if (chunks
+ *arg_words
+ bias
> (unsigned) MAX_ARGS_IN_REGISTERS
)
1300 chunks
= MAX_ARGS_IN_REGISTERS
- *arg_words
- bias
;
1302 /* Assign_parms checks the mode of ENTRY_PARM, so we must
1303 use the actual mode here. */
1304 ret
= gen_rtx_PARALLEL (mode
, rtvec_alloc (chunks
));
1307 regno
= regbase
+ *arg_words
+ bias
;
1308 field
= TYPE_FIELDS (type
);
1309 for (i
= 0; i
< chunks
; i
++)
1313 for (; field
; field
= TREE_CHAIN (field
))
1314 if (TREE_CODE (field
) == FIELD_DECL
1315 && int_bit_position (field
) >= bitpos
)
1319 && int_bit_position (field
) == bitpos
1320 && TREE_CODE (TREE_TYPE (field
)) == REAL_TYPE
1321 && TYPE_PRECISION (TREE_TYPE (field
)) == BITS_PER_WORD
)
1322 reg
= gen_rtx_REG (DFmode
, regno
++);
1324 reg
= gen_rtx_REG (word_mode
, regno
);
1327 = gen_rtx_EXPR_LIST (VOIDmode
, reg
,
1328 GEN_INT (bitpos
/ BITS_PER_UNIT
));
1336 if (TARGET_DEBUG_D_MODE
)
1337 fprintf (stderr
, "%s%s\n", reg_names
[regbase
+ *arg_words
+ bias
],
1338 struct_p
? ", [struct]" : "");
1341 /* We will be called with a mode of VOIDmode after the last argument
1342 has been seen. Whatever we return will be passed to the call
1343 insn. If we need any shifts for small structures, return them in
1345 if (mode
== VOIDmode
)
1347 if (cum
->num_adjusts
> 0)
1348 ret
= gen_rtx_PARALLEL ((enum machine_mode
) cum
->fp_code
,
1349 gen_rtvec_v (cum
->num_adjusts
, cum
->adjust
));
1356 iq2000_arg_partial_bytes (CUMULATIVE_ARGS
*cum
, enum machine_mode mode
,
1357 tree type ATTRIBUTE_UNUSED
,
1358 bool named ATTRIBUTE_UNUSED
)
1360 if (mode
== DImode
&& cum
->arg_words
== MAX_ARGS_IN_REGISTERS
- 1)
1362 if (TARGET_DEBUG_D_MODE
)
1363 fprintf (stderr
, "iq2000_arg_partial_bytes=%d\n", UNITS_PER_WORD
);
1364 return UNITS_PER_WORD
;
1370 /* Implement va_start. */
1373 iq2000_va_start (tree valist
, rtx nextarg
)
1376 /* Find out how many non-float named formals. */
1377 int gpr_save_area_size
;
1378 /* Note UNITS_PER_WORD is 4 bytes. */
1379 int_arg_words
= crtl
->args
.info
.arg_words
;
1381 if (int_arg_words
< 8 )
1382 /* Adjust for the prologue's economy measure. */
1383 gpr_save_area_size
= (8 - int_arg_words
) * UNITS_PER_WORD
;
1385 gpr_save_area_size
= 0;
1387 /* Everything is in the GPR save area, or in the overflow
1388 area which is contiguous with it. */
1389 nextarg
= plus_constant (nextarg
, - gpr_save_area_size
);
1390 std_expand_builtin_va_start (valist
, nextarg
);
1393 /* Allocate a chunk of memory for per-function machine-dependent data. */
1395 static struct machine_function
*
1396 iq2000_init_machine_status (void)
1398 return ggc_alloc_cleared_machine_function ();
1401 /* Implement TARGET_HANDLE_OPTION. */
1404 iq2000_handle_option (size_t code
, const char *arg
, int value ATTRIBUTE_UNUSED
)
1409 if (strcmp (arg
, "iq10") == 0)
1410 iq2000_tune
= PROCESSOR_IQ10
;
1411 else if (strcmp (arg
, "iq2000") == 0)
1412 iq2000_tune
= PROCESSOR_IQ2000
;
1418 /* This option has no effect at the moment. */
1419 return (strcmp (arg
, "default") == 0
1420 || strcmp (arg
, "DEFAULT") == 0
1421 || strcmp (arg
, "iq2000") == 0);
1428 /* Detect any conflicts in the switches. */
1431 override_options (void)
1433 target_flags
&= ~MASK_GPOPT
;
1435 iq2000_isa
= IQ2000_ISA_DEFAULT
;
1437 /* Identify the processor type. */
1439 iq2000_print_operand_punct
['?'] = 1;
1440 iq2000_print_operand_punct
['#'] = 1;
1441 iq2000_print_operand_punct
['&'] = 1;
1442 iq2000_print_operand_punct
['!'] = 1;
1443 iq2000_print_operand_punct
['*'] = 1;
1444 iq2000_print_operand_punct
['@'] = 1;
1445 iq2000_print_operand_punct
['.'] = 1;
1446 iq2000_print_operand_punct
['('] = 1;
1447 iq2000_print_operand_punct
[')'] = 1;
1448 iq2000_print_operand_punct
['['] = 1;
1449 iq2000_print_operand_punct
[']'] = 1;
1450 iq2000_print_operand_punct
['<'] = 1;
1451 iq2000_print_operand_punct
['>'] = 1;
1452 iq2000_print_operand_punct
['{'] = 1;
1453 iq2000_print_operand_punct
['}'] = 1;
1454 iq2000_print_operand_punct
['^'] = 1;
1455 iq2000_print_operand_punct
['$'] = 1;
1456 iq2000_print_operand_punct
['+'] = 1;
1457 iq2000_print_operand_punct
['~'] = 1;
1459 /* Save GPR registers in word_mode sized hunks. word_mode hasn't been
1460 initialized yet, so we can't use that here. */
1463 /* Function to allocate machine-dependent function status. */
1464 init_machine_status
= iq2000_init_machine_status
;
1467 /* The arg pointer (which is eliminated) points to the virtual frame pointer,
1468 while the frame pointer (which may be eliminated) points to the stack
1469 pointer after the initial adjustments. */
1472 iq2000_debugger_offset (rtx addr
, HOST_WIDE_INT offset
)
1474 rtx offset2
= const0_rtx
;
1475 rtx reg
= eliminate_constant_term (addr
, & offset2
);
1478 offset
= INTVAL (offset2
);
1480 if (reg
== stack_pointer_rtx
|| reg
== frame_pointer_rtx
1481 || reg
== hard_frame_pointer_rtx
)
1483 HOST_WIDE_INT frame_size
= (!cfun
->machine
->initialized
)
1484 ? compute_frame_size (get_frame_size ())
1485 : cfun
->machine
->total_size
;
1487 offset
= offset
- frame_size
;
1493 /* If defined, a C statement to be executed just prior to the output of
1494 assembler code for INSN, to modify the extracted operands so they will be
1497 Here the argument OPVEC is the vector containing the operands extracted
1498 from INSN, and NOPERANDS is the number of elements of the vector which
1499 contain meaningful data for this insn. The contents of this vector are
1500 what will be used to convert the insn template into assembler code, so you
1501 can change the assembler output by changing the contents of the vector.
1503 We use it to check if the current insn needs a nop in front of it because
1504 of load delays, and also to update the delay slot statistics. */
1507 final_prescan_insn (rtx insn
, rtx opvec
[] ATTRIBUTE_UNUSED
,
1508 int noperands ATTRIBUTE_UNUSED
)
1510 if (dslots_number_nops
> 0)
1512 rtx pattern
= PATTERN (insn
);
1513 int length
= get_attr_length (insn
);
1515 /* Do we need to emit a NOP? */
1517 || (iq2000_load_reg
!= 0 && reg_mentioned_p (iq2000_load_reg
, pattern
))
1518 || (iq2000_load_reg2
!= 0 && reg_mentioned_p (iq2000_load_reg2
, pattern
))
1519 || (iq2000_load_reg3
!= 0 && reg_mentioned_p (iq2000_load_reg3
, pattern
))
1520 || (iq2000_load_reg4
!= 0
1521 && reg_mentioned_p (iq2000_load_reg4
, pattern
)))
1522 fputs ("\tnop\n", asm_out_file
);
1525 dslots_load_filled
++;
1527 while (--dslots_number_nops
> 0)
1528 fputs ("\tnop\n", asm_out_file
);
1530 iq2000_load_reg
= 0;
1531 iq2000_load_reg2
= 0;
1532 iq2000_load_reg3
= 0;
1533 iq2000_load_reg4
= 0;
1536 if ( (GET_CODE (insn
) == JUMP_INSN
1537 || GET_CODE (insn
) == CALL_INSN
1538 || (GET_CODE (PATTERN (insn
)) == RETURN
))
1539 && NEXT_INSN (PREV_INSN (insn
)) == insn
)
1541 rtx nop_insn
= emit_insn_after (gen_nop (), insn
);
1543 INSN_ADDRESSES_NEW (nop_insn
, -1);
1547 && (GET_CODE (insn
) == JUMP_INSN
|| GET_CODE (insn
) == CALL_INSN
))
1548 dslots_jump_total
++;
1551 /* Return the bytes needed to compute the frame pointer from the current
1552 stack pointer where SIZE is the # of var. bytes allocated.
1554 IQ2000 stack frames look like:
1556 Before call After call
1557 +-----------------------+ +-----------------------+
1560 | caller's temps. | | caller's temps. |
1562 +-----------------------+ +-----------------------+
1564 | arguments on stack. | | arguments on stack. |
1566 +-----------------------+ +-----------------------+
1567 | 4 words to save | | 4 words to save |
1568 | arguments passed | | arguments passed |
1569 | in registers, even | | in registers, even |
1570 SP->| if not passed. | VFP->| if not passed. |
1571 +-----------------------+ +-----------------------+
1573 | fp register save |
1575 +-----------------------+
1577 | gp register save |
1579 +-----------------------+
1583 +-----------------------+
1585 | alloca allocations |
1587 +-----------------------+
1589 | GP save for V.4 abi |
1591 +-----------------------+
1593 | arguments on stack |
1595 +-----------------------+
1597 | arguments passed |
1598 | in registers, even |
1599 low SP->| if not passed. |
1600 memory +-----------------------+ */
1603 compute_frame_size (HOST_WIDE_INT size
)
1606 HOST_WIDE_INT total_size
; /* # bytes that the entire frame takes up. */
1607 HOST_WIDE_INT var_size
; /* # bytes that variables take up. */
1608 HOST_WIDE_INT args_size
; /* # bytes that outgoing arguments take up. */
1609 HOST_WIDE_INT extra_size
; /* # extra bytes. */
1610 HOST_WIDE_INT gp_reg_rounded
; /* # bytes needed to store gp after rounding. */
1611 HOST_WIDE_INT gp_reg_size
; /* # bytes needed to store gp regs. */
1612 HOST_WIDE_INT fp_reg_size
; /* # bytes needed to store fp regs. */
1613 long mask
; /* mask of saved gp registers. */
1614 int fp_inc
; /* 1 or 2 depending on the size of fp regs. */
1615 long fp_bits
; /* bitmask to use for each fp register. */
1620 extra_size
= IQ2000_STACK_ALIGN ((0));
1621 var_size
= IQ2000_STACK_ALIGN (size
);
1622 args_size
= IQ2000_STACK_ALIGN (crtl
->outgoing_args_size
);
1624 /* If a function dynamically allocates the stack and
1625 has 0 for STACK_DYNAMIC_OFFSET then allocate some stack space. */
1626 if (args_size
== 0 && cfun
->calls_alloca
)
1627 args_size
= 4 * UNITS_PER_WORD
;
1629 total_size
= var_size
+ args_size
+ extra_size
;
1631 /* Calculate space needed for gp registers. */
1632 for (regno
= GP_REG_FIRST
; regno
<= GP_REG_LAST
; regno
++)
1634 if (MUST_SAVE_REGISTER (regno
))
1636 gp_reg_size
+= GET_MODE_SIZE (gpr_mode
);
1637 mask
|= 1L << (regno
- GP_REG_FIRST
);
1641 /* We need to restore these for the handler. */
1642 if (crtl
->calls_eh_return
)
1648 regno
= EH_RETURN_DATA_REGNO (i
);
1649 if (regno
== (int) INVALID_REGNUM
)
1651 gp_reg_size
+= GET_MODE_SIZE (gpr_mode
);
1652 mask
|= 1L << (regno
- GP_REG_FIRST
);
1658 gp_reg_rounded
= IQ2000_STACK_ALIGN (gp_reg_size
);
1659 total_size
+= gp_reg_rounded
+ IQ2000_STACK_ALIGN (fp_reg_size
);
1661 /* The gp reg is caller saved, so there is no need for leaf routines
1662 (total_size == extra_size) to save the gp reg. */
1663 if (total_size
== extra_size
1665 total_size
= extra_size
= 0;
1667 total_size
+= IQ2000_STACK_ALIGN (crtl
->args
.pretend_args_size
);
1669 /* Save other computed information. */
1670 cfun
->machine
->total_size
= total_size
;
1671 cfun
->machine
->var_size
= var_size
;
1672 cfun
->machine
->args_size
= args_size
;
1673 cfun
->machine
->extra_size
= extra_size
;
1674 cfun
->machine
->gp_reg_size
= gp_reg_size
;
1675 cfun
->machine
->fp_reg_size
= fp_reg_size
;
1676 cfun
->machine
->mask
= mask
;
1677 cfun
->machine
->initialized
= reload_completed
;
1678 cfun
->machine
->num_gp
= gp_reg_size
/ UNITS_PER_WORD
;
1682 unsigned long offset
;
1684 offset
= (args_size
+ extra_size
+ var_size
1685 + gp_reg_size
- GET_MODE_SIZE (gpr_mode
));
1687 cfun
->machine
->gp_sp_offset
= offset
;
1688 cfun
->machine
->gp_save_offset
= offset
- total_size
;
1692 cfun
->machine
->gp_sp_offset
= 0;
1693 cfun
->machine
->gp_save_offset
= 0;
1696 cfun
->machine
->fp_sp_offset
= 0;
1697 cfun
->machine
->fp_save_offset
= 0;
1699 /* Ok, we're done. */
1704 /* We can always eliminate to the frame pointer. We can eliminate to the
1705 stack pointer unless a frame pointer is needed. */
1708 iq2000_can_eliminate (const int from
, const int to
)
1710 return (from
== RETURN_ADDRESS_POINTER_REGNUM
1711 && (! leaf_function_p ()
1712 || (to
== GP_REG_FIRST
+ 31 && leaf_function_p
)))
1713 || (from
!= RETURN_ADDRESS_POINTER_REGNUM
1714 && (to
== HARD_FRAME_POINTER_REGNUM
1715 || (to
== STACK_POINTER_REGNUM
1716 && ! frame_pointer_needed
)));
1719 /* Implement INITIAL_ELIMINATION_OFFSET. FROM is either the frame
1720 pointer, argument pointer, or return address pointer. TO is either
1721 the stack pointer or hard frame pointer. */
1724 iq2000_initial_elimination_offset (int from
, int to ATTRIBUTE_UNUSED
)
1728 compute_frame_size (get_frame_size ());
1729 if ((from
) == FRAME_POINTER_REGNUM
)
1731 else if ((from
) == ARG_POINTER_REGNUM
)
1732 (offset
) = (cfun
->machine
->total_size
);
1733 else if ((from
) == RETURN_ADDRESS_POINTER_REGNUM
)
1735 if (leaf_function_p ())
1737 else (offset
) = cfun
->machine
->gp_sp_offset
1738 + ((UNITS_PER_WORD
- (POINTER_SIZE
/ BITS_PER_UNIT
))
1739 * (BYTES_BIG_ENDIAN
!= 0));
1745 /* Common code to emit the insns (or to write the instructions to a file)
1746 to save/restore registers.
1747 Other parts of the code assume that IQ2000_TEMP1_REGNUM (aka large_reg)
1748 is not modified within save_restore_insns. */
1750 #define BITSET_P(VALUE,BIT) (((VALUE) & (1L << (BIT))) != 0)
1752 /* Emit instructions to load the value (SP + OFFSET) into IQ2000_TEMP2_REGNUM
1753 and return an rtl expression for the register. Write the assembly
1754 instructions directly to FILE if it is not null, otherwise emit them as
1757 This function is a subroutine of save_restore_insns. It is used when
1758 OFFSET is too large to add in a single instruction. */
1761 iq2000_add_large_offset_to_sp (HOST_WIDE_INT offset
)
1763 rtx reg
= gen_rtx_REG (Pmode
, IQ2000_TEMP2_REGNUM
);
1764 rtx offset_rtx
= GEN_INT (offset
);
1766 emit_move_insn (reg
, offset_rtx
);
1767 emit_insn (gen_addsi3 (reg
, reg
, stack_pointer_rtx
));
1771 /* Make INSN frame related and note that it performs the frame-related
1772 operation DWARF_PATTERN. */
1775 iq2000_annotate_frame_insn (rtx insn
, rtx dwarf_pattern
)
1777 RTX_FRAME_RELATED_P (insn
) = 1;
1778 REG_NOTES (insn
) = alloc_EXPR_LIST (REG_FRAME_RELATED_EXPR
,
1783 /* Emit a move instruction that stores REG in MEM. Make the instruction
1784 frame related and note that it stores REG at (SP + OFFSET). */
1787 iq2000_emit_frame_related_store (rtx mem
, rtx reg
, HOST_WIDE_INT offset
)
1789 rtx dwarf_address
= plus_constant (stack_pointer_rtx
, offset
);
1790 rtx dwarf_mem
= gen_rtx_MEM (GET_MODE (reg
), dwarf_address
);
1792 iq2000_annotate_frame_insn (emit_move_insn (mem
, reg
),
1793 gen_rtx_SET (GET_MODE (reg
), dwarf_mem
, reg
));
1796 /* Emit instructions to save/restore registers, as determined by STORE_P. */
1799 save_restore_insns (int store_p
)
1801 long mask
= cfun
->machine
->mask
;
1804 HOST_WIDE_INT base_offset
;
1805 HOST_WIDE_INT gp_offset
;
1806 HOST_WIDE_INT end_offset
;
1808 gcc_assert (!frame_pointer_needed
1809 || BITSET_P (mask
, HARD_FRAME_POINTER_REGNUM
- GP_REG_FIRST
));
1813 base_reg_rtx
= 0, base_offset
= 0;
1817 /* Save registers starting from high to low. The debuggers prefer at least
1818 the return register be stored at func+4, and also it allows us not to
1819 need a nop in the epilog if at least one register is reloaded in
1820 addition to return address. */
1822 /* Save GP registers if needed. */
1823 /* Pick which pointer to use as a base register. For small frames, just
1824 use the stack pointer. Otherwise, use a temporary register. Save 2
1825 cycles if the save area is near the end of a large frame, by reusing
1826 the constant created in the prologue/epilogue to adjust the stack
1829 gp_offset
= cfun
->machine
->gp_sp_offset
;
1831 = gp_offset
- (cfun
->machine
->gp_reg_size
1832 - GET_MODE_SIZE (gpr_mode
));
1834 if (gp_offset
< 0 || end_offset
< 0)
1836 ("gp_offset (%ld) or end_offset (%ld) is less than zero",
1837 (long) gp_offset
, (long) end_offset
);
1839 else if (gp_offset
< 32768)
1840 base_reg_rtx
= stack_pointer_rtx
, base_offset
= 0;
1844 int reg_save_count
= 0;
1846 for (regno
= GP_REG_LAST
; regno
>= GP_REG_FIRST
; regno
--)
1847 if (BITSET_P (mask
, regno
- GP_REG_FIRST
)) reg_save_count
+= 1;
1848 base_offset
= gp_offset
- ((reg_save_count
- 1) * 4);
1849 base_reg_rtx
= iq2000_add_large_offset_to_sp (base_offset
);
1852 for (regno
= GP_REG_LAST
; regno
>= GP_REG_FIRST
; regno
--)
1854 if (BITSET_P (mask
, regno
- GP_REG_FIRST
))
1858 = gen_rtx_MEM (gpr_mode
,
1859 gen_rtx_PLUS (Pmode
, base_reg_rtx
,
1860 GEN_INT (gp_offset
- base_offset
)));
1862 reg_rtx
= gen_rtx_REG (gpr_mode
, regno
);
1865 iq2000_emit_frame_related_store (mem_rtx
, reg_rtx
, gp_offset
);
1868 emit_move_insn (reg_rtx
, mem_rtx
);
1870 gp_offset
-= GET_MODE_SIZE (gpr_mode
);
1875 /* Expand the prologue into a bunch of separate insns. */
1878 iq2000_expand_prologue (void)
1881 HOST_WIDE_INT tsize
;
1882 int last_arg_is_vararg_marker
= 0;
1883 tree fndecl
= current_function_decl
;
1884 tree fntype
= TREE_TYPE (fndecl
);
1885 tree fnargs
= DECL_ARGUMENTS (fndecl
);
1890 CUMULATIVE_ARGS args_so_far
;
1891 int store_args_on_stack
= (iq2000_can_use_return_insn ());
1893 /* If struct value address is treated as the first argument. */
1894 if (aggregate_value_p (DECL_RESULT (fndecl
), fndecl
)
1895 && !cfun
->returns_pcc_struct
1896 && targetm
.calls
.struct_value_rtx (TREE_TYPE (fndecl
), 1) == 0)
1898 tree type
= build_pointer_type (fntype
);
1899 tree function_result_decl
= build_decl (BUILTINS_LOCATION
,
1900 PARM_DECL
, NULL_TREE
, type
);
1902 DECL_ARG_TYPE (function_result_decl
) = type
;
1903 TREE_CHAIN (function_result_decl
) = fnargs
;
1904 fnargs
= function_result_decl
;
1907 /* For arguments passed in registers, find the register number
1908 of the first argument in the variable part of the argument list,
1909 otherwise GP_ARG_LAST+1. Note also if the last argument is
1910 the varargs special argument, and treat it as part of the
1913 This is only needed if store_args_on_stack is true. */
1914 INIT_CUMULATIVE_ARGS (args_so_far
, fntype
, NULL_RTX
, 0, 0);
1915 regno
= GP_ARG_FIRST
;
1917 for (cur_arg
= fnargs
; cur_arg
!= 0; cur_arg
= next_arg
)
1919 tree passed_type
= DECL_ARG_TYPE (cur_arg
);
1920 enum machine_mode passed_mode
= TYPE_MODE (passed_type
);
1923 if (TREE_ADDRESSABLE (passed_type
))
1925 passed_type
= build_pointer_type (passed_type
);
1926 passed_mode
= Pmode
;
1929 entry_parm
= FUNCTION_ARG (args_so_far
, passed_mode
, passed_type
, 1);
1931 FUNCTION_ARG_ADVANCE (args_so_far
, passed_mode
, passed_type
, 1);
1932 next_arg
= TREE_CHAIN (cur_arg
);
1934 if (entry_parm
&& store_args_on_stack
)
1937 && DECL_NAME (cur_arg
)
1938 && ((0 == strcmp (IDENTIFIER_POINTER (DECL_NAME (cur_arg
)),
1939 "__builtin_va_alist"))
1940 || (0 == strcmp (IDENTIFIER_POINTER (DECL_NAME (cur_arg
)),
1943 last_arg_is_vararg_marker
= 1;
1950 gcc_assert (GET_CODE (entry_parm
) == REG
);
1952 /* Passed in a register, so will get homed automatically. */
1953 if (GET_MODE (entry_parm
) == BLKmode
)
1954 words
= (int_size_in_bytes (passed_type
) + 3) / 4;
1956 words
= (GET_MODE_SIZE (GET_MODE (entry_parm
)) + 3) / 4;
1958 regno
= REGNO (entry_parm
) + words
- 1;
1963 regno
= GP_ARG_LAST
+1;
1968 /* In order to pass small structures by value in registers we need to
1969 shift the value into the high part of the register.
1970 Function_arg has encoded a PARALLEL rtx, holding a vector of
1971 adjustments to be made as the next_arg_reg variable, so we split up the
1972 insns, and emit them separately. */
1973 next_arg_reg
= FUNCTION_ARG (args_so_far
, VOIDmode
, void_type_node
, 1);
1974 if (next_arg_reg
!= 0 && GET_CODE (next_arg_reg
) == PARALLEL
)
1976 rtvec adjust
= XVEC (next_arg_reg
, 0);
1977 int num
= GET_NUM_ELEM (adjust
);
1979 for (i
= 0; i
< num
; i
++)
1983 pattern
= RTVEC_ELT (adjust
, i
);
1984 if (GET_CODE (pattern
) != SET
1985 || GET_CODE (SET_SRC (pattern
)) != ASHIFT
)
1986 abort_with_insn (pattern
, "Insn is not a shift");
1987 PUT_CODE (SET_SRC (pattern
), ASHIFTRT
);
1989 insn
= emit_insn (pattern
);
1993 tsize
= compute_frame_size (get_frame_size ());
1995 /* If this function is a varargs function, store any registers that
1996 would normally hold arguments ($4 - $7) on the stack. */
1997 if (store_args_on_stack
1998 && ((TYPE_ARG_TYPES (fntype
) != 0
1999 && (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype
)))
2001 || last_arg_is_vararg_marker
))
2003 int offset
= (regno
- GP_ARG_FIRST
) * UNITS_PER_WORD
;
2004 rtx ptr
= stack_pointer_rtx
;
2006 for (; regno
<= GP_ARG_LAST
; regno
++)
2009 ptr
= gen_rtx_PLUS (Pmode
, stack_pointer_rtx
, GEN_INT (offset
));
2010 emit_move_insn (gen_rtx_MEM (gpr_mode
, ptr
),
2011 gen_rtx_REG (gpr_mode
, regno
));
2013 offset
+= GET_MODE_SIZE (gpr_mode
);
2019 rtx tsize_rtx
= GEN_INT (tsize
);
2020 rtx adjustment_rtx
, insn
, dwarf_pattern
;
2024 adjustment_rtx
= gen_rtx_REG (Pmode
, IQ2000_TEMP1_REGNUM
);
2025 emit_move_insn (adjustment_rtx
, tsize_rtx
);
2028 adjustment_rtx
= tsize_rtx
;
2030 insn
= emit_insn (gen_subsi3 (stack_pointer_rtx
, stack_pointer_rtx
,
2033 dwarf_pattern
= gen_rtx_SET (Pmode
, stack_pointer_rtx
,
2034 plus_constant (stack_pointer_rtx
, -tsize
));
2036 iq2000_annotate_frame_insn (insn
, dwarf_pattern
);
2038 save_restore_insns (1);
2040 if (frame_pointer_needed
)
2044 insn
= emit_insn (gen_movsi (hard_frame_pointer_rtx
,
2045 stack_pointer_rtx
));
2048 RTX_FRAME_RELATED_P (insn
) = 1;
2052 emit_insn (gen_blockage ());
2055 /* Expand the epilogue into a bunch of separate insns. */
2058 iq2000_expand_epilogue (void)
2060 HOST_WIDE_INT tsize
= cfun
->machine
->total_size
;
2061 rtx tsize_rtx
= GEN_INT (tsize
);
2062 rtx tmp_rtx
= (rtx
)0;
2064 if (iq2000_can_use_return_insn ())
2066 emit_jump_insn (gen_return ());
2072 tmp_rtx
= gen_rtx_REG (Pmode
, IQ2000_TEMP1_REGNUM
);
2073 emit_move_insn (tmp_rtx
, tsize_rtx
);
2074 tsize_rtx
= tmp_rtx
;
2079 if (frame_pointer_needed
)
2081 emit_insn (gen_blockage ());
2083 emit_insn (gen_movsi (stack_pointer_rtx
, hard_frame_pointer_rtx
));
2086 save_restore_insns (0);
2088 if (crtl
->calls_eh_return
)
2090 rtx eh_ofs
= EH_RETURN_STACKADJ_RTX
;
2091 emit_insn (gen_addsi3 (eh_ofs
, eh_ofs
, tsize_rtx
));
2095 emit_insn (gen_blockage ());
2097 if (tsize
!= 0 || crtl
->calls_eh_return
)
2099 emit_insn (gen_addsi3 (stack_pointer_rtx
, stack_pointer_rtx
,
2104 if (crtl
->calls_eh_return
)
2106 /* Perform the additional bump for __throw. */
2107 emit_move_insn (gen_rtx_REG (Pmode
, HARD_FRAME_POINTER_REGNUM
),
2109 emit_use (gen_rtx_REG (Pmode
, HARD_FRAME_POINTER_REGNUM
));
2110 emit_jump_insn (gen_eh_return_internal ());
2113 emit_jump_insn (gen_return_internal (gen_rtx_REG (Pmode
,
2114 GP_REG_FIRST
+ 31)));
2118 iq2000_expand_eh_return (rtx address
)
2120 HOST_WIDE_INT gp_offset
= cfun
->machine
->gp_sp_offset
;
2123 scratch
= plus_constant (stack_pointer_rtx
, gp_offset
);
2124 emit_move_insn (gen_rtx_MEM (GET_MODE (address
), scratch
), address
);
2127 /* Return nonzero if this function is known to have a null epilogue.
2128 This allows the optimizer to omit jumps to jumps if no stack
2132 iq2000_can_use_return_insn (void)
2134 if (! reload_completed
)
2137 if (df_regs_ever_live_p (31) || profile_flag
)
2140 if (cfun
->machine
->initialized
)
2141 return cfun
->machine
->total_size
== 0;
2143 return compute_frame_size (get_frame_size ()) == 0;
2146 /* Returns nonzero if X contains a SYMBOL_REF. */
2149 symbolic_expression_p (rtx x
)
2151 if (GET_CODE (x
) == SYMBOL_REF
)
2154 if (GET_CODE (x
) == CONST
)
2155 return symbolic_expression_p (XEXP (x
, 0));
2158 return symbolic_expression_p (XEXP (x
, 0));
2160 if (ARITHMETIC_P (x
))
2161 return (symbolic_expression_p (XEXP (x
, 0))
2162 || symbolic_expression_p (XEXP (x
, 1)));
2167 /* Choose the section to use for the constant rtx expression X that has
2171 iq2000_select_rtx_section (enum machine_mode mode
, rtx x ATTRIBUTE_UNUSED
,
2172 unsigned HOST_WIDE_INT align
)
2174 /* For embedded applications, always put constants in read-only data,
2175 in order to reduce RAM usage. */
2176 return mergeable_constant_section (mode
, align
, 0);
2179 /* Choose the section to use for DECL. RELOC is true if its value contains
2180 any relocatable expression.
2182 Some of the logic used here needs to be replicated in
2183 ENCODE_SECTION_INFO in iq2000.h so that references to these symbols
2184 are done correctly. */
2187 iq2000_select_section (tree decl
, int reloc ATTRIBUTE_UNUSED
,
2188 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED
)
2190 if (TARGET_EMBEDDED_DATA
)
2192 /* For embedded applications, always put an object in read-only data
2193 if possible, in order to reduce RAM usage. */
2194 if ((TREE_CODE (decl
) == VAR_DECL
2195 && TREE_READONLY (decl
) && !TREE_SIDE_EFFECTS (decl
)
2196 && DECL_INITIAL (decl
)
2197 && (DECL_INITIAL (decl
) == error_mark_node
2198 || TREE_CONSTANT (DECL_INITIAL (decl
))))
2199 /* Deal with calls from output_constant_def_contents. */
2200 || TREE_CODE (decl
) != VAR_DECL
)
2201 return readonly_data_section
;
2203 return data_section
;
2207 /* For hosted applications, always put an object in small data if
2208 possible, as this gives the best performance. */
2209 if ((TREE_CODE (decl
) == VAR_DECL
2210 && TREE_READONLY (decl
) && !TREE_SIDE_EFFECTS (decl
)
2211 && DECL_INITIAL (decl
)
2212 && (DECL_INITIAL (decl
) == error_mark_node
2213 || TREE_CONSTANT (DECL_INITIAL (decl
))))
2214 /* Deal with calls from output_constant_def_contents. */
2215 || TREE_CODE (decl
) != VAR_DECL
)
2216 return readonly_data_section
;
2218 return data_section
;
2221 /* Return register to use for a function return value with VALTYPE for function
2225 iq2000_function_value (const_tree valtype
,
2226 const_tree fn_decl_or_type
,
2227 bool outgoing ATTRIBUTE_UNUSED
)
2229 int reg
= GP_RETURN
;
2230 enum machine_mode mode
= TYPE_MODE (valtype
);
2231 int unsignedp
= TYPE_UNSIGNED (valtype
);
2232 tree func
= fn_decl_or_type
;
2235 && !DECL_P (fn_decl_or_type
))
2236 fn_decl_or_type
= NULL
;
2238 /* Since we promote return types, we must promote the mode here too. */
2239 mode
= promote_function_mode (valtype
, mode
, &unsignedp
, func
, 1);
2241 return gen_rtx_REG (mode
, reg
);
2244 /* Worker function for TARGET_LIBCALL_VALUE. */
2247 iq2000_libcall_value (enum machine_mode mode
, const_rtx fun ATTRIBUTE_UNUSED
)
2249 return gen_rtx_REG (((GET_MODE_CLASS (mode
) != MODE_INT
2250 || GET_MODE_SIZE (mode
) >= 4)
2255 /* Worker function for FUNCTION_VALUE_REGNO_P.
2257 On the IQ2000, R2 and R3 are the only register thus used. */
2260 iq2000_function_value_regno_p (const unsigned int regno
)
2262 return (regno
== GP_RETURN
);
2266 /* Return true when an argument must be passed by reference. */
2269 iq2000_pass_by_reference (CUMULATIVE_ARGS
*cum
, enum machine_mode mode
,
2270 const_tree type
, bool named ATTRIBUTE_UNUSED
)
2274 /* We must pass by reference if we would be both passing in registers
2275 and the stack. This is because any subsequent partial arg would be
2276 handled incorrectly in this case. */
2277 if (cum
&& targetm
.calls
.must_pass_in_stack (mode
, type
))
2279 /* Don't pass the actual CUM to FUNCTION_ARG, because we would
2280 get double copies of any offsets generated for small structs
2281 passed in registers. */
2282 CUMULATIVE_ARGS temp
;
2285 if (FUNCTION_ARG (temp
, mode
, type
, named
) != 0)
2289 if (type
== NULL_TREE
|| mode
== DImode
|| mode
== DFmode
)
2292 size
= int_size_in_bytes (type
);
2293 return size
== -1 || size
> UNITS_PER_WORD
;
2296 /* Return the length of INSN. LENGTH is the initial length computed by
2297 attributes in the machine-description file. */
2300 iq2000_adjust_insn_length (rtx insn
, int length
)
2302 /* A unconditional jump has an unfilled delay slot if it is not part
2303 of a sequence. A conditional jump normally has a delay slot. */
2304 if (simplejump_p (insn
)
2305 || ( (GET_CODE (insn
) == JUMP_INSN
2306 || GET_CODE (insn
) == CALL_INSN
)))
2312 /* Output assembly instructions to perform a conditional branch.
2314 INSN is the branch instruction. OPERANDS[0] is the condition.
2315 OPERANDS[1] is the target of the branch. OPERANDS[2] is the target
2316 of the first operand to the condition. If TWO_OPERANDS_P is
2317 nonzero the comparison takes two operands; OPERANDS[3] will be the
2320 If INVERTED_P is nonzero we are to branch if the condition does
2321 not hold. If FLOAT_P is nonzero this is a floating-point comparison.
2323 LENGTH is the length (in bytes) of the sequence we are to generate.
2324 That tells us whether to generate a simple conditional branch, or a
2325 reversed conditional branch around a `jr' instruction. */
2328 iq2000_output_conditional_branch (rtx insn
, rtx
* operands
, int two_operands_p
,
2329 int float_p
, int inverted_p
, int length
)
2331 static char buffer
[200];
2332 /* The kind of comparison we are doing. */
2333 enum rtx_code code
= GET_CODE (operands
[0]);
2334 /* Nonzero if the opcode for the comparison needs a `z' indicating
2335 that it is a comparison against zero. */
2337 /* A string to use in the assembly output to represent the first
2339 const char *op1
= "%z2";
2340 /* A string to use in the assembly output to represent the second
2341 operand. Use the hard-wired zero register if there's no second
2343 const char *op2
= (two_operands_p
? ",%z3" : ",%.");
2344 /* The operand-printing string for the comparison. */
2345 const char *comp
= (float_p
? "%F0" : "%C0");
2346 /* The operand-printing string for the inverted comparison. */
2347 const char *inverted_comp
= (float_p
? "%W0" : "%N0");
2349 /* Likely variants of each branch instruction annul the instruction
2350 in the delay slot if the branch is not taken. */
2351 iq2000_branch_likely
= (final_sequence
&& INSN_ANNULLED_BRANCH_P (insn
));
2353 if (!two_operands_p
)
2355 /* To compute whether than A > B, for example, we normally
2356 subtract B from A and then look at the sign bit. But, if we
2357 are doing an unsigned comparison, and B is zero, we don't
2358 have to do the subtraction. Instead, we can just check to
2359 see if A is nonzero. Thus, we change the CODE here to
2360 reflect the simpler comparison operation. */
2372 /* A condition which will always be true. */
2378 /* A condition which will always be false. */
2384 /* Not a special case. */
2389 /* Relative comparisons are always done against zero. But
2390 equality comparisons are done between two operands, and therefore
2391 do not require a `z' in the assembly language output. */
2392 need_z_p
= (!float_p
&& code
!= EQ
&& code
!= NE
);
2393 /* For comparisons against zero, the zero is not provided
2398 /* Begin by terminating the buffer. That way we can always use
2399 strcat to add to it. */
2406 /* Just a simple conditional branch. */
2408 sprintf (buffer
, "b%s%%?\t%%Z2%%1",
2409 inverted_p
? inverted_comp
: comp
);
2411 sprintf (buffer
, "b%s%s%%?\t%s%s,%%1",
2412 inverted_p
? inverted_comp
: comp
,
2413 need_z_p
? "z" : "",
2421 /* Generate a reversed conditional branch around ` j'
2433 Because we have to jump four bytes *past* the following
2434 instruction if this branch was annulled, we can't just use
2435 a label, as in the picture above; there's no way to put the
2436 label after the next instruction, as the assembler does not
2437 accept `.L+4' as the target of a branch. (We can't just
2438 wait until the next instruction is output; it might be a
2439 macro and take up more than four bytes. Once again, we see
2440 why we want to eliminate macros.)
2442 If the branch is annulled, we jump four more bytes that we
2443 would otherwise; that way we skip the annulled instruction
2444 in the delay slot. */
2447 = ((iq2000_branch_likely
|| length
== 16) ? ".+16" : ".+12");
2450 c
= strchr (buffer
, '\0');
2451 /* Generate the reversed comparison. This takes four
2454 sprintf (c
, "b%s\t%%Z2%s",
2455 inverted_p
? comp
: inverted_comp
,
2458 sprintf (c
, "b%s%s\t%s%s,%s",
2459 inverted_p
? comp
: inverted_comp
,
2460 need_z_p
? "z" : "",
2464 strcat (c
, "\n\tnop\n\tj\t%1");
2466 /* The delay slot was unfilled. Since we're inside
2467 .noreorder, the assembler will not fill in the NOP for
2468 us, so we must do it ourselves. */
2469 strcat (buffer
, "\n\tnop");
2481 #define def_builtin(NAME, TYPE, CODE) \
2482 add_builtin_function ((NAME), (TYPE), (CODE), BUILT_IN_MD, \
2486 iq2000_init_builtins (void)
2488 tree endlink
= void_list_node
;
2489 tree void_ftype
, void_ftype_int
, void_ftype_int_int
;
2490 tree void_ftype_int_int_int
;
2491 tree int_ftype_int
, int_ftype_int_int
, int_ftype_int_int_int
;
2492 tree int_ftype_int_int_int_int
;
2496 = build_function_type (void_type_node
,
2497 tree_cons (NULL_TREE
, void_type_node
, endlink
));
2501 = build_function_type (void_type_node
,
2502 tree_cons (NULL_TREE
, integer_type_node
, endlink
));
2504 /* void func (int, int) */
2506 = build_function_type (void_type_node
,
2507 tree_cons (NULL_TREE
, integer_type_node
,
2508 tree_cons (NULL_TREE
, integer_type_node
,
2511 /* int func (int) */
2513 = build_function_type (integer_type_node
,
2514 tree_cons (NULL_TREE
, integer_type_node
, endlink
));
2516 /* int func (int, int) */
2518 = build_function_type (integer_type_node
,
2519 tree_cons (NULL_TREE
, integer_type_node
,
2520 tree_cons (NULL_TREE
, integer_type_node
,
2523 /* void func (int, int, int) */
2524 void_ftype_int_int_int
2525 = build_function_type
2527 tree_cons (NULL_TREE
, integer_type_node
,
2528 tree_cons (NULL_TREE
, integer_type_node
,
2529 tree_cons (NULL_TREE
,
2533 /* int func (int, int, int, int) */
2534 int_ftype_int_int_int_int
2535 = build_function_type
2537 tree_cons (NULL_TREE
, integer_type_node
,
2538 tree_cons (NULL_TREE
, integer_type_node
,
2539 tree_cons (NULL_TREE
,
2541 tree_cons (NULL_TREE
,
2545 /* int func (int, int, int) */
2546 int_ftype_int_int_int
2547 = build_function_type
2549 tree_cons (NULL_TREE
, integer_type_node
,
2550 tree_cons (NULL_TREE
, integer_type_node
,
2551 tree_cons (NULL_TREE
,
2555 /* int func (int, int, int, int) */
2556 int_ftype_int_int_int_int
2557 = build_function_type
2559 tree_cons (NULL_TREE
, integer_type_node
,
2560 tree_cons (NULL_TREE
, integer_type_node
,
2561 tree_cons (NULL_TREE
,
2563 tree_cons (NULL_TREE
,
2567 def_builtin ("__builtin_ado16", int_ftype_int_int
, IQ2000_BUILTIN_ADO16
);
2568 def_builtin ("__builtin_ram", int_ftype_int_int_int_int
, IQ2000_BUILTIN_RAM
);
2569 def_builtin ("__builtin_chkhdr", void_ftype_int_int
, IQ2000_BUILTIN_CHKHDR
);
2570 def_builtin ("__builtin_pkrl", void_ftype_int_int
, IQ2000_BUILTIN_PKRL
);
2571 def_builtin ("__builtin_cfc0", int_ftype_int
, IQ2000_BUILTIN_CFC0
);
2572 def_builtin ("__builtin_cfc1", int_ftype_int
, IQ2000_BUILTIN_CFC1
);
2573 def_builtin ("__builtin_cfc2", int_ftype_int
, IQ2000_BUILTIN_CFC2
);
2574 def_builtin ("__builtin_cfc3", int_ftype_int
, IQ2000_BUILTIN_CFC3
);
2575 def_builtin ("__builtin_ctc0", void_ftype_int_int
, IQ2000_BUILTIN_CTC0
);
2576 def_builtin ("__builtin_ctc1", void_ftype_int_int
, IQ2000_BUILTIN_CTC1
);
2577 def_builtin ("__builtin_ctc2", void_ftype_int_int
, IQ2000_BUILTIN_CTC2
);
2578 def_builtin ("__builtin_ctc3", void_ftype_int_int
, IQ2000_BUILTIN_CTC3
);
2579 def_builtin ("__builtin_mfc0", int_ftype_int
, IQ2000_BUILTIN_MFC0
);
2580 def_builtin ("__builtin_mfc1", int_ftype_int
, IQ2000_BUILTIN_MFC1
);
2581 def_builtin ("__builtin_mfc2", int_ftype_int
, IQ2000_BUILTIN_MFC2
);
2582 def_builtin ("__builtin_mfc3", int_ftype_int
, IQ2000_BUILTIN_MFC3
);
2583 def_builtin ("__builtin_mtc0", void_ftype_int_int
, IQ2000_BUILTIN_MTC0
);
2584 def_builtin ("__builtin_mtc1", void_ftype_int_int
, IQ2000_BUILTIN_MTC1
);
2585 def_builtin ("__builtin_mtc2", void_ftype_int_int
, IQ2000_BUILTIN_MTC2
);
2586 def_builtin ("__builtin_mtc3", void_ftype_int_int
, IQ2000_BUILTIN_MTC3
);
2587 def_builtin ("__builtin_lur", void_ftype_int_int
, IQ2000_BUILTIN_LUR
);
2588 def_builtin ("__builtin_rb", void_ftype_int_int
, IQ2000_BUILTIN_RB
);
2589 def_builtin ("__builtin_rx", void_ftype_int_int
, IQ2000_BUILTIN_RX
);
2590 def_builtin ("__builtin_srrd", void_ftype_int
, IQ2000_BUILTIN_SRRD
);
2591 def_builtin ("__builtin_srwr", void_ftype_int_int
, IQ2000_BUILTIN_SRWR
);
2592 def_builtin ("__builtin_wb", void_ftype_int_int
, IQ2000_BUILTIN_WB
);
2593 def_builtin ("__builtin_wx", void_ftype_int_int
, IQ2000_BUILTIN_WX
);
2594 def_builtin ("__builtin_luc32l", void_ftype_int_int
, IQ2000_BUILTIN_LUC32L
);
2595 def_builtin ("__builtin_luc64", void_ftype_int_int
, IQ2000_BUILTIN_LUC64
);
2596 def_builtin ("__builtin_luc64l", void_ftype_int_int
, IQ2000_BUILTIN_LUC64L
);
2597 def_builtin ("__builtin_luk", void_ftype_int_int
, IQ2000_BUILTIN_LUK
);
2598 def_builtin ("__builtin_lulck", void_ftype_int
, IQ2000_BUILTIN_LULCK
);
2599 def_builtin ("__builtin_lum32", void_ftype_int_int
, IQ2000_BUILTIN_LUM32
);
2600 def_builtin ("__builtin_lum32l", void_ftype_int_int
, IQ2000_BUILTIN_LUM32L
);
2601 def_builtin ("__builtin_lum64", void_ftype_int_int
, IQ2000_BUILTIN_LUM64
);
2602 def_builtin ("__builtin_lum64l", void_ftype_int_int
, IQ2000_BUILTIN_LUM64L
);
2603 def_builtin ("__builtin_lurl", void_ftype_int_int
, IQ2000_BUILTIN_LURL
);
2604 def_builtin ("__builtin_mrgb", int_ftype_int_int_int
, IQ2000_BUILTIN_MRGB
);
2605 def_builtin ("__builtin_srrdl", void_ftype_int
, IQ2000_BUILTIN_SRRDL
);
2606 def_builtin ("__builtin_srulck", void_ftype_int
, IQ2000_BUILTIN_SRULCK
);
2607 def_builtin ("__builtin_srwru", void_ftype_int_int
, IQ2000_BUILTIN_SRWRU
);
2608 def_builtin ("__builtin_trapqfl", void_ftype
, IQ2000_BUILTIN_TRAPQFL
);
2609 def_builtin ("__builtin_trapqne", void_ftype
, IQ2000_BUILTIN_TRAPQNE
);
2610 def_builtin ("__builtin_traprel", void_ftype_int
, IQ2000_BUILTIN_TRAPREL
);
2611 def_builtin ("__builtin_wbu", void_ftype_int_int_int
, IQ2000_BUILTIN_WBU
);
2612 def_builtin ("__builtin_syscall", void_ftype
, IQ2000_BUILTIN_SYSCALL
);
2615 /* Builtin for ICODE having ARGCOUNT args in EXP where each arg
2619 expand_one_builtin (enum insn_code icode
, rtx target
, tree exp
,
2620 enum rtx_code
*code
, int argcount
)
2625 enum machine_mode mode
[5];
2628 mode
[0] = insn_data
[icode
].operand
[0].mode
;
2629 for (i
= 0; i
< argcount
; i
++)
2631 arg
[i
] = CALL_EXPR_ARG (exp
, i
);
2632 op
[i
] = expand_expr (arg
[i
], NULL_RTX
, VOIDmode
, 0);
2633 mode
[i
] = insn_data
[icode
].operand
[i
].mode
;
2634 if (code
[i
] == CONST_INT
&& GET_CODE (op
[i
]) != CONST_INT
)
2635 error ("argument %qd is not a constant", i
+ 1);
2637 && ! (*insn_data
[icode
].operand
[i
].predicate
) (op
[i
], mode
[i
]))
2638 op
[i
] = copy_to_mode_reg (mode
[i
], op
[i
]);
2641 if (insn_data
[icode
].operand
[0].constraint
[0] == '=')
2644 || GET_MODE (target
) != mode
[0]
2645 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, mode
[0]))
2646 target
= gen_reg_rtx (mode
[0]);
2654 pat
= GEN_FCN (icode
) (target
);
2657 pat
= GEN_FCN (icode
) (target
, op
[0]);
2659 pat
= GEN_FCN (icode
) (op
[0]);
2663 pat
= GEN_FCN (icode
) (target
, op
[0], op
[1]);
2665 pat
= GEN_FCN (icode
) (op
[0], op
[1]);
2669 pat
= GEN_FCN (icode
) (target
, op
[0], op
[1], op
[2]);
2671 pat
= GEN_FCN (icode
) (op
[0], op
[1], op
[2]);
2675 pat
= GEN_FCN (icode
) (target
, op
[0], op
[1], op
[2], op
[3]);
2677 pat
= GEN_FCN (icode
) (op
[0], op
[1], op
[2], op
[3]);
2689 /* Expand an expression EXP that calls a built-in function,
2690 with result going to TARGET if that's convenient
2691 (and in mode MODE if that's convenient).
2692 SUBTARGET may be used as the target for computing one of EXP's operands.
2693 IGNORE is nonzero if the value is to be ignored. */
2696 iq2000_expand_builtin (tree exp
, rtx target
, rtx subtarget ATTRIBUTE_UNUSED
,
2697 enum machine_mode mode ATTRIBUTE_UNUSED
,
2698 int ignore ATTRIBUTE_UNUSED
)
2700 tree fndecl
= TREE_OPERAND (CALL_EXPR_FN (exp
), 0);
2701 int fcode
= DECL_FUNCTION_CODE (fndecl
);
2702 enum rtx_code code
[5];
2714 case IQ2000_BUILTIN_ADO16
:
2715 return expand_one_builtin (CODE_FOR_ado16
, target
, exp
, code
, 2);
2717 case IQ2000_BUILTIN_RAM
:
2718 code
[1] = CONST_INT
;
2719 code
[2] = CONST_INT
;
2720 code
[3] = CONST_INT
;
2721 return expand_one_builtin (CODE_FOR_ram
, target
, exp
, code
, 4);
2723 case IQ2000_BUILTIN_CHKHDR
:
2724 return expand_one_builtin (CODE_FOR_chkhdr
, target
, exp
, code
, 2);
2726 case IQ2000_BUILTIN_PKRL
:
2727 return expand_one_builtin (CODE_FOR_pkrl
, target
, exp
, code
, 2);
2729 case IQ2000_BUILTIN_CFC0
:
2730 code
[0] = CONST_INT
;
2731 return expand_one_builtin (CODE_FOR_cfc0
, target
, exp
, code
, 1);
2733 case IQ2000_BUILTIN_CFC1
:
2734 code
[0] = CONST_INT
;
2735 return expand_one_builtin (CODE_FOR_cfc1
, target
, exp
, code
, 1);
2737 case IQ2000_BUILTIN_CFC2
:
2738 code
[0] = CONST_INT
;
2739 return expand_one_builtin (CODE_FOR_cfc2
, target
, exp
, code
, 1);
2741 case IQ2000_BUILTIN_CFC3
:
2742 code
[0] = CONST_INT
;
2743 return expand_one_builtin (CODE_FOR_cfc3
, target
, exp
, code
, 1);
2745 case IQ2000_BUILTIN_CTC0
:
2746 code
[1] = CONST_INT
;
2747 return expand_one_builtin (CODE_FOR_ctc0
, target
, exp
, code
, 2);
2749 case IQ2000_BUILTIN_CTC1
:
2750 code
[1] = CONST_INT
;
2751 return expand_one_builtin (CODE_FOR_ctc1
, target
, exp
, code
, 2);
2753 case IQ2000_BUILTIN_CTC2
:
2754 code
[1] = CONST_INT
;
2755 return expand_one_builtin (CODE_FOR_ctc2
, target
, exp
, code
, 2);
2757 case IQ2000_BUILTIN_CTC3
:
2758 code
[1] = CONST_INT
;
2759 return expand_one_builtin (CODE_FOR_ctc3
, target
, exp
, code
, 2);
2761 case IQ2000_BUILTIN_MFC0
:
2762 code
[0] = CONST_INT
;
2763 return expand_one_builtin (CODE_FOR_mfc0
, target
, exp
, code
, 1);
2765 case IQ2000_BUILTIN_MFC1
:
2766 code
[0] = CONST_INT
;
2767 return expand_one_builtin (CODE_FOR_mfc1
, target
, exp
, code
, 1);
2769 case IQ2000_BUILTIN_MFC2
:
2770 code
[0] = CONST_INT
;
2771 return expand_one_builtin (CODE_FOR_mfc2
, target
, exp
, code
, 1);
2773 case IQ2000_BUILTIN_MFC3
:
2774 code
[0] = CONST_INT
;
2775 return expand_one_builtin (CODE_FOR_mfc3
, target
, exp
, code
, 1);
2777 case IQ2000_BUILTIN_MTC0
:
2778 code
[1] = CONST_INT
;
2779 return expand_one_builtin (CODE_FOR_mtc0
, target
, exp
, code
, 2);
2781 case IQ2000_BUILTIN_MTC1
:
2782 code
[1] = CONST_INT
;
2783 return expand_one_builtin (CODE_FOR_mtc1
, target
, exp
, code
, 2);
2785 case IQ2000_BUILTIN_MTC2
:
2786 code
[1] = CONST_INT
;
2787 return expand_one_builtin (CODE_FOR_mtc2
, target
, exp
, code
, 2);
2789 case IQ2000_BUILTIN_MTC3
:
2790 code
[1] = CONST_INT
;
2791 return expand_one_builtin (CODE_FOR_mtc3
, target
, exp
, code
, 2);
2793 case IQ2000_BUILTIN_LUR
:
2794 return expand_one_builtin (CODE_FOR_lur
, target
, exp
, code
, 2);
2796 case IQ2000_BUILTIN_RB
:
2797 return expand_one_builtin (CODE_FOR_rb
, target
, exp
, code
, 2);
2799 case IQ2000_BUILTIN_RX
:
2800 return expand_one_builtin (CODE_FOR_rx
, target
, exp
, code
, 2);
2802 case IQ2000_BUILTIN_SRRD
:
2803 return expand_one_builtin (CODE_FOR_srrd
, target
, exp
, code
, 1);
2805 case IQ2000_BUILTIN_SRWR
:
2806 return expand_one_builtin (CODE_FOR_srwr
, target
, exp
, code
, 2);
2808 case IQ2000_BUILTIN_WB
:
2809 return expand_one_builtin (CODE_FOR_wb
, target
, exp
, code
, 2);
2811 case IQ2000_BUILTIN_WX
:
2812 return expand_one_builtin (CODE_FOR_wx
, target
, exp
, code
, 2);
2814 case IQ2000_BUILTIN_LUC32L
:
2815 return expand_one_builtin (CODE_FOR_luc32l
, target
, exp
, code
, 2);
2817 case IQ2000_BUILTIN_LUC64
:
2818 return expand_one_builtin (CODE_FOR_luc64
, target
, exp
, code
, 2);
2820 case IQ2000_BUILTIN_LUC64L
:
2821 return expand_one_builtin (CODE_FOR_luc64l
, target
, exp
, code
, 2);
2823 case IQ2000_BUILTIN_LUK
:
2824 return expand_one_builtin (CODE_FOR_luk
, target
, exp
, code
, 2);
2826 case IQ2000_BUILTIN_LULCK
:
2827 return expand_one_builtin (CODE_FOR_lulck
, target
, exp
, code
, 1);
2829 case IQ2000_BUILTIN_LUM32
:
2830 return expand_one_builtin (CODE_FOR_lum32
, target
, exp
, code
, 2);
2832 case IQ2000_BUILTIN_LUM32L
:
2833 return expand_one_builtin (CODE_FOR_lum32l
, target
, exp
, code
, 2);
2835 case IQ2000_BUILTIN_LUM64
:
2836 return expand_one_builtin (CODE_FOR_lum64
, target
, exp
, code
, 2);
2838 case IQ2000_BUILTIN_LUM64L
:
2839 return expand_one_builtin (CODE_FOR_lum64l
, target
, exp
, code
, 2);
2841 case IQ2000_BUILTIN_LURL
:
2842 return expand_one_builtin (CODE_FOR_lurl
, target
, exp
, code
, 2);
2844 case IQ2000_BUILTIN_MRGB
:
2845 code
[2] = CONST_INT
;
2846 return expand_one_builtin (CODE_FOR_mrgb
, target
, exp
, code
, 3);
2848 case IQ2000_BUILTIN_SRRDL
:
2849 return expand_one_builtin (CODE_FOR_srrdl
, target
, exp
, code
, 1);
2851 case IQ2000_BUILTIN_SRULCK
:
2852 return expand_one_builtin (CODE_FOR_srulck
, target
, exp
, code
, 1);
2854 case IQ2000_BUILTIN_SRWRU
:
2855 return expand_one_builtin (CODE_FOR_srwru
, target
, exp
, code
, 2);
2857 case IQ2000_BUILTIN_TRAPQFL
:
2858 return expand_one_builtin (CODE_FOR_trapqfl
, target
, exp
, code
, 0);
2860 case IQ2000_BUILTIN_TRAPQNE
:
2861 return expand_one_builtin (CODE_FOR_trapqne
, target
, exp
, code
, 0);
2863 case IQ2000_BUILTIN_TRAPREL
:
2864 return expand_one_builtin (CODE_FOR_traprel
, target
, exp
, code
, 1);
2866 case IQ2000_BUILTIN_WBU
:
2867 return expand_one_builtin (CODE_FOR_wbu
, target
, exp
, code
, 3);
2869 case IQ2000_BUILTIN_SYSCALL
:
2870 return expand_one_builtin (CODE_FOR_syscall
, target
, exp
, code
, 0);
2876 /* Worker function for TARGET_RETURN_IN_MEMORY. */
2879 iq2000_return_in_memory (const_tree type
, const_tree fntype ATTRIBUTE_UNUSED
)
2881 return ((int_size_in_bytes (type
) > (2 * UNITS_PER_WORD
))
2882 || (int_size_in_bytes (type
) == -1));
2885 /* Worker function for TARGET_SETUP_INCOMING_VARARGS. */
2888 iq2000_setup_incoming_varargs (CUMULATIVE_ARGS
*cum
,
2889 enum machine_mode mode ATTRIBUTE_UNUSED
,
2890 tree type ATTRIBUTE_UNUSED
, int * pretend_size
,
2893 unsigned int iq2000_off
= ! cum
->last_arg_fp
;
2894 unsigned int iq2000_fp_off
= cum
->last_arg_fp
;
2896 if ((cum
->arg_words
< MAX_ARGS_IN_REGISTERS
- iq2000_off
))
2898 int iq2000_save_gp_regs
2899 = MAX_ARGS_IN_REGISTERS
- cum
->arg_words
- iq2000_off
;
2900 int iq2000_save_fp_regs
2901 = (MAX_ARGS_IN_REGISTERS
- cum
->fp_arg_words
- iq2000_fp_off
);
2903 if (iq2000_save_gp_regs
< 0)
2904 iq2000_save_gp_regs
= 0;
2905 if (iq2000_save_fp_regs
< 0)
2906 iq2000_save_fp_regs
= 0;
2908 *pretend_size
= ((iq2000_save_gp_regs
* UNITS_PER_WORD
)
2909 + (iq2000_save_fp_regs
* UNITS_PER_FPREG
));
2913 if (cum
->arg_words
< MAX_ARGS_IN_REGISTERS
- iq2000_off
)
2916 ptr
= plus_constant (virtual_incoming_args_rtx
,
2917 - (iq2000_save_gp_regs
2919 mem
= gen_rtx_MEM (BLKmode
, ptr
);
2921 (cum
->arg_words
+ GP_ARG_FIRST
+ iq2000_off
,
2923 iq2000_save_gp_regs
);
2929 /* A C compound statement to output to stdio stream STREAM the
2930 assembler syntax for an instruction operand that is a memory
2931 reference whose address is ADDR. ADDR is an RTL expression. */
2934 iq2000_print_operand_address (FILE * file
, rtx addr
)
2937 error ("PRINT_OPERAND_ADDRESS, null pointer");
2940 switch (GET_CODE (addr
))
2943 if (REGNO (addr
) == ARG_POINTER_REGNUM
)
2944 abort_with_insn (addr
, "Arg pointer not eliminated.");
2946 fprintf (file
, "0(%s)", reg_names
[REGNO (addr
)]);
2951 rtx arg0
= XEXP (addr
, 0);
2952 rtx arg1
= XEXP (addr
, 1);
2954 if (GET_CODE (arg0
) != REG
)
2955 abort_with_insn (addr
,
2956 "PRINT_OPERAND_ADDRESS, LO_SUM with #1 not REG.");
2958 fprintf (file
, "%%lo(");
2959 iq2000_print_operand_address (file
, arg1
);
2960 fprintf (file
, ")(%s)", reg_names
[REGNO (arg0
)]);
2968 rtx arg0
= XEXP (addr
, 0);
2969 rtx arg1
= XEXP (addr
, 1);
2971 if (GET_CODE (arg0
) == REG
)
2975 if (GET_CODE (offset
) == REG
)
2976 abort_with_insn (addr
, "PRINT_OPERAND_ADDRESS, 2 regs");
2979 else if (GET_CODE (arg1
) == REG
)
2980 reg
= arg1
, offset
= arg0
;
2981 else if (CONSTANT_P (arg0
) && CONSTANT_P (arg1
))
2983 output_addr_const (file
, addr
);
2987 abort_with_insn (addr
, "PRINT_OPERAND_ADDRESS, no regs");
2989 if (! CONSTANT_P (offset
))
2990 abort_with_insn (addr
, "PRINT_OPERAND_ADDRESS, invalid insn #2");
2992 if (REGNO (reg
) == ARG_POINTER_REGNUM
)
2993 abort_with_insn (addr
, "Arg pointer not eliminated.");
2995 output_addr_const (file
, offset
);
2996 fprintf (file
, "(%s)", reg_names
[REGNO (reg
)]);
3004 output_addr_const (file
, addr
);
3005 if (GET_CODE (addr
) == CONST_INT
)
3006 fprintf (file
, "(%s)", reg_names
[0]);
3010 abort_with_insn (addr
, "PRINT_OPERAND_ADDRESS, invalid insn #1");
3015 /* A C compound statement to output to stdio stream FILE the
3016 assembler syntax for an instruction operand OP.
3018 LETTER is a value that can be used to specify one of several ways
3019 of printing the operand. It is used when identical operands
3020 must be printed differently depending on the context. LETTER
3021 comes from the `%' specification that was used to request
3022 printing of the operand. If the specification was just `%DIGIT'
3023 then LETTER is 0; if the specification was `%LTR DIGIT' then LETTER
3024 is the ASCII code for LTR.
3026 If OP is a register, this macro should print the register's name.
3027 The names can be found in an array `reg_names' whose type is
3028 `char *[]'. `reg_names' is initialized from `REGISTER_NAMES'.
3030 When the machine description has a specification `%PUNCT' (a `%'
3031 followed by a punctuation character), this macro is called with
3032 a null pointer for X and the punctuation character for LETTER.
3034 The IQ2000 specific codes are:
3036 'X' X is CONST_INT, prints upper 16 bits in hexadecimal format = "0x%04x",
3037 'x' X is CONST_INT, prints lower 16 bits in hexadecimal format = "0x%04x",
3038 'd' output integer constant in decimal,
3039 'z' if the operand is 0, use $0 instead of normal operand.
3040 'D' print second part of double-word register or memory operand.
3041 'L' print low-order register of double-word register operand.
3042 'M' print high-order register of double-word register operand.
3043 'C' print part of opcode for a branch condition.
3044 'F' print part of opcode for a floating-point branch condition.
3045 'N' print part of opcode for a branch condition, inverted.
3046 'W' print part of opcode for a floating-point branch condition, inverted.
3047 'A' Print part of opcode for a bit test condition.
3048 'P' Print label for a bit test.
3049 'p' Print log for a bit test.
3050 'B' print 'z' for EQ, 'n' for NE
3051 'b' print 'n' for EQ, 'z' for NE
3052 'T' print 'f' for EQ, 't' for NE
3053 't' print 't' for EQ, 'f' for NE
3054 'Z' print register and a comma, but print nothing for $fcc0
3055 '?' Print 'l' if we are to use a branch likely instead of normal branch.
3056 '@' Print the name of the assembler temporary register (at or $1).
3057 '.' Print the name of the register with a hard-wired zero (zero or $0).
3058 '$' Print the name of the stack pointer register (sp or $29).
3059 '+' Print the name of the gp register (gp or $28). */
3062 iq2000_print_operand (FILE *file
, rtx op
, int letter
)
3066 if (iq2000_print_operand_punct_valid_p (letter
))
3071 if (iq2000_branch_likely
)
3076 fputs (reg_names
[GP_REG_FIRST
+ 1], file
);
3080 fputs (reg_names
[GP_REG_FIRST
+ 0], file
);
3084 fputs (reg_names
[STACK_POINTER_REGNUM
], file
);
3088 fputs (reg_names
[GP_REG_FIRST
+ 28], file
);
3092 error ("PRINT_OPERAND: Unknown punctuation '%c'", letter
);
3101 error ("PRINT_OPERAND null pointer");
3105 code
= GET_CODE (op
);
3107 if (code
== SIGN_EXTEND
)
3108 op
= XEXP (op
, 0), code
= GET_CODE (op
);
3113 case EQ
: fputs ("eq", file
); break;
3114 case NE
: fputs ("ne", file
); break;
3115 case GT
: fputs ("gt", file
); break;
3116 case GE
: fputs ("ge", file
); break;
3117 case LT
: fputs ("lt", file
); break;
3118 case LE
: fputs ("le", file
); break;
3119 case GTU
: fputs ("ne", file
); break;
3120 case GEU
: fputs ("geu", file
); break;
3121 case LTU
: fputs ("ltu", file
); break;
3122 case LEU
: fputs ("eq", file
); break;
3124 abort_with_insn (op
, "PRINT_OPERAND, invalid insn for %%C");
3127 else if (letter
== 'N')
3130 case EQ
: fputs ("ne", file
); break;
3131 case NE
: fputs ("eq", file
); break;
3132 case GT
: fputs ("le", file
); break;
3133 case GE
: fputs ("lt", file
); break;
3134 case LT
: fputs ("ge", file
); break;
3135 case LE
: fputs ("gt", file
); break;
3136 case GTU
: fputs ("leu", file
); break;
3137 case GEU
: fputs ("ltu", file
); break;
3138 case LTU
: fputs ("geu", file
); break;
3139 case LEU
: fputs ("gtu", file
); break;
3141 abort_with_insn (op
, "PRINT_OPERAND, invalid insn for %%N");
3144 else if (letter
== 'F')
3147 case EQ
: fputs ("c1f", file
); break;
3148 case NE
: fputs ("c1t", file
); break;
3150 abort_with_insn (op
, "PRINT_OPERAND, invalid insn for %%F");
3153 else if (letter
== 'W')
3156 case EQ
: fputs ("c1t", file
); break;
3157 case NE
: fputs ("c1f", file
); break;
3159 abort_with_insn (op
, "PRINT_OPERAND, invalid insn for %%W");
3162 else if (letter
== 'A')
3163 fputs (code
== LABEL_REF
? "i" : "in", file
);
3165 else if (letter
== 'P')
3167 if (code
== LABEL_REF
)
3168 output_addr_const (file
, op
);
3169 else if (code
!= PC
)
3170 output_operand_lossage ("invalid %%P operand");
3173 else if (letter
== 'p')
3176 if (code
!= CONST_INT
3177 || (value
= exact_log2 (INTVAL (op
))) < 0)
3178 output_operand_lossage ("invalid %%p value");
3179 fprintf (file
, "%d", value
);
3182 else if (letter
== 'Z')
3187 else if (code
== REG
|| code
== SUBREG
)
3192 regnum
= REGNO (op
);
3194 regnum
= true_regnum (op
);
3196 if ((letter
== 'M' && ! WORDS_BIG_ENDIAN
)
3197 || (letter
== 'L' && WORDS_BIG_ENDIAN
)
3201 fprintf (file
, "%s", reg_names
[regnum
]);
3204 else if (code
== MEM
)
3207 output_address (plus_constant (XEXP (op
, 0), 4));
3209 output_address (XEXP (op
, 0));
3212 else if (code
== CONST_DOUBLE
3213 && GET_MODE_CLASS (GET_MODE (op
)) == MODE_FLOAT
)
3217 real_to_decimal (s
, CONST_DOUBLE_REAL_VALUE (op
), sizeof (s
), 0, 1);
3221 else if (letter
== 'x' && GET_CODE (op
) == CONST_INT
)
3222 fprintf (file
, HOST_WIDE_INT_PRINT_HEX
, 0xffff & INTVAL(op
));
3224 else if (letter
== 'X' && GET_CODE(op
) == CONST_INT
)
3225 fprintf (file
, HOST_WIDE_INT_PRINT_HEX
, 0xffff & (INTVAL (op
) >> 16));
3227 else if (letter
== 'd' && GET_CODE(op
) == CONST_INT
)
3228 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, (INTVAL(op
)));
3230 else if (letter
== 'z' && GET_CODE (op
) == CONST_INT
&& INTVAL (op
) == 0)
3231 fputs (reg_names
[GP_REG_FIRST
], file
);
3233 else if (letter
== 'd' || letter
== 'x' || letter
== 'X')
3234 output_operand_lossage ("invalid use of %%d, %%x, or %%X");
3236 else if (letter
== 'B')
3237 fputs (code
== EQ
? "z" : "n", file
);
3238 else if (letter
== 'b')
3239 fputs (code
== EQ
? "n" : "z", file
);
3240 else if (letter
== 'T')
3241 fputs (code
== EQ
? "f" : "t", file
);
3242 else if (letter
== 't')
3243 fputs (code
== EQ
? "t" : "f", file
);
3245 else if (code
== CONST
&& GET_CODE (XEXP (op
, 0)) == REG
)
3247 iq2000_print_operand (file
, XEXP (op
, 0), letter
);
3251 output_addr_const (file
, op
);
3255 iq2000_print_operand_punct_valid_p (unsigned char code
)
3257 return iq2000_print_operand_punct
[code
];
3260 /* For the IQ2000, transform:
3262 memory(X + <large int>)
3264 Y = <large int> & ~0x7fff;
3266 memory (Z + (<large int> & 0x7fff));
3270 iq2000_legitimize_address (rtx xinsn
, rtx old_x ATTRIBUTE_UNUSED
,
3271 enum machine_mode mode
)
3273 if (TARGET_DEBUG_B_MODE
)
3275 GO_PRINTF ("\n========== LEGITIMIZE_ADDRESS\n");
3276 GO_DEBUG_RTX (xinsn
);
3279 if (iq2000_check_split (xinsn
, mode
))
3281 return gen_rtx_LO_SUM (Pmode
,
3282 copy_to_mode_reg (Pmode
,
3283 gen_rtx_HIGH (Pmode
, xinsn
)),
3287 if (GET_CODE (xinsn
) == PLUS
)
3289 rtx xplus0
= XEXP (xinsn
, 0);
3290 rtx xplus1
= XEXP (xinsn
, 1);
3291 enum rtx_code code0
= GET_CODE (xplus0
);
3292 enum rtx_code code1
= GET_CODE (xplus1
);
3294 if (code0
!= REG
&& code1
== REG
)
3296 xplus0
= XEXP (xinsn
, 1);
3297 xplus1
= XEXP (xinsn
, 0);
3298 code0
= GET_CODE (xplus0
);
3299 code1
= GET_CODE (xplus1
);
3302 if (code0
== REG
&& REG_MODE_OK_FOR_BASE_P (xplus0
, mode
)
3303 && code1
== CONST_INT
&& !SMALL_INT (xplus1
))
3305 rtx int_reg
= gen_reg_rtx (Pmode
);
3306 rtx ptr_reg
= gen_reg_rtx (Pmode
);
3308 emit_move_insn (int_reg
,
3309 GEN_INT (INTVAL (xplus1
) & ~ 0x7fff));
3311 emit_insn (gen_rtx_SET (VOIDmode
,
3313 gen_rtx_PLUS (Pmode
, xplus0
, int_reg
)));
3315 return plus_constant (ptr_reg
, INTVAL (xplus1
) & 0x7fff);
3319 if (TARGET_DEBUG_B_MODE
)
3320 GO_PRINTF ("LEGITIMIZE_ADDRESS could not fix.\n");
3327 iq2000_rtx_costs (rtx x
, int code
, int outer_code ATTRIBUTE_UNUSED
, int * total
,
3328 bool speed ATTRIBUTE_UNUSED
)
3330 enum machine_mode mode
= GET_MODE (x
);
3336 int num_words
= (GET_MODE_SIZE (mode
) > UNITS_PER_WORD
) ? 2 : 1;
3338 if (simple_memory_operand (x
, mode
))
3339 return COSTS_N_INSNS (num_words
);
3341 * total
= COSTS_N_INSNS (2 * num_words
);
3346 * total
= COSTS_N_INSNS (6);
3353 * total
= COSTS_N_INSNS (mode
== DImode
? 2 : 1);
3360 * total
= COSTS_N_INSNS ((GET_CODE (XEXP (x
, 1)) == CONST_INT
) ? 4 : 12);
3362 * total
= COSTS_N_INSNS (1);
3366 if (mode
== SFmode
|| mode
== DFmode
)
3367 * total
= COSTS_N_INSNS (1);
3369 * total
= COSTS_N_INSNS (4);
3374 if (mode
== SFmode
|| mode
== DFmode
)
3375 * total
= COSTS_N_INSNS (6);
3376 else if (mode
== DImode
)
3377 * total
= COSTS_N_INSNS (4);
3379 * total
= COSTS_N_INSNS (1);
3383 * total
= (mode
== DImode
) ? 4 : 1;
3388 * total
= COSTS_N_INSNS (7);
3389 else if (mode
== DFmode
)
3390 * total
= COSTS_N_INSNS (8);
3392 * total
= COSTS_N_INSNS (10);
3398 * total
= COSTS_N_INSNS (23);
3399 else if (mode
== DFmode
)
3400 * total
= COSTS_N_INSNS (36);
3402 * total
= COSTS_N_INSNS (69);
3407 * total
= COSTS_N_INSNS (69);
3411 * total
= COSTS_N_INSNS (2);
3415 * total
= COSTS_N_INSNS (1);
3423 * total
= COSTS_N_INSNS (2);
3428 rtx offset
= const0_rtx
;
3429 rtx symref
= eliminate_constant_term (XEXP (x
, 0), & offset
);
3431 if (GET_CODE (symref
) == LABEL_REF
)
3432 * total
= COSTS_N_INSNS (2);
3433 else if (GET_CODE (symref
) != SYMBOL_REF
)
3434 * total
= COSTS_N_INSNS (4);
3435 /* Let's be paranoid.... */
3436 else if (INTVAL (offset
) < -32768 || INTVAL (offset
) > 32767)
3437 * total
= COSTS_N_INSNS (2);
3439 * total
= COSTS_N_INSNS (SYMBOL_REF_FLAG (symref
) ? 1 : 2);
3444 * total
= COSTS_N_INSNS (SYMBOL_REF_FLAG (x
) ? 1 : 2);
3451 split_double (x
, & high
, & low
);
3453 * total
= COSTS_N_INSNS ( (high
== CONST0_RTX (GET_MODE (high
))
3454 || low
== CONST0_RTX (GET_MODE (low
)))
3465 /* Worker for TARGET_ASM_TRAMPOLINE_TEMPLATE. */
3468 iq2000_asm_trampoline_template (FILE *f
)
3470 fprintf (f
, "\t.word\t0x03e00821\t\t# move $1,$31\n");
3471 fprintf (f
, "\t.word\t0x04110001\t\t# bgezal $0,.+8\n");
3472 fprintf (f
, "\t.word\t0x00000000\t\t# nop\n");
3473 if (Pmode
== DImode
)
3475 fprintf (f
, "\t.word\t0xdfe30014\t\t# ld $3,20($31)\n");
3476 fprintf (f
, "\t.word\t0xdfe2001c\t\t# ld $2,28($31)\n");
3480 fprintf (f
, "\t.word\t0x8fe30014\t\t# lw $3,20($31)\n");
3481 fprintf (f
, "\t.word\t0x8fe20018\t\t# lw $2,24($31)\n");
3483 fprintf (f
, "\t.word\t0x0060c821\t\t# move $25,$3 (abicalls)\n");
3484 fprintf (f
, "\t.word\t0x00600008\t\t# jr $3\n");
3485 fprintf (f
, "\t.word\t0x0020f821\t\t# move $31,$1\n");
3486 fprintf (f
, "\t.word\t0x00000000\t\t# <function address>\n");
3487 fprintf (f
, "\t.word\t0x00000000\t\t# <static chain value>\n");
3490 /* Worker for TARGET_TRAMPOLINE_INIT. */
3493 iq2000_trampoline_init (rtx m_tramp
, tree fndecl
, rtx chain_value
)
3495 rtx fnaddr
= XEXP (DECL_RTL (fndecl
), 0);
3498 emit_block_move (m_tramp
, assemble_trampoline_template (),
3499 GEN_INT (TRAMPOLINE_CODE_SIZE
), BLOCK_OP_NORMAL
);
3501 mem
= adjust_address (m_tramp
, Pmode
, TRAMPOLINE_CODE_SIZE
);
3502 emit_move_insn (mem
, fnaddr
);
3503 mem
= adjust_address (m_tramp
, Pmode
,
3504 TRAMPOLINE_CODE_SIZE
+ GET_MODE_SIZE (Pmode
));
3505 emit_move_insn (mem
, chain_value
);
3508 #include "gt-iq2000.h"