1 /* Subroutines used for code generation on Vitesse IQ2000 processors
2 Copyright (C) 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
4 This file is part of GCC.
6 GCC is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3, or (at your option)
11 GCC is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GCC; see the file COPYING3. If not see
18 <http://www.gnu.org/licenses/>. */
22 #include "coretypes.h"
28 #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 machine_function
GTY(())
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 print_operand. */
112 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 /* Cached operands, and operator to compare for use in set/branch/trap
121 on condition codes. */
124 /* What type of branch to use. */
125 enum cmp_type branch_type
;
127 /* Local variables. */
129 /* The next branch instruction is a branch likely, not branch normal. */
130 static int iq2000_branch_likely
;
132 /* Count of delay slots and how many are filled. */
133 static int dslots_load_total
;
134 static int dslots_load_filled
;
135 static int dslots_jump_total
;
137 /* # of nops needed by previous insn. */
138 static int dslots_number_nops
;
140 /* Number of 1/2/3 word references to data items (i.e., not jal's). */
141 static int num_refs
[3];
143 /* Registers to check for load delay. */
144 static rtx iq2000_load_reg
;
145 static rtx iq2000_load_reg2
;
146 static rtx iq2000_load_reg3
;
147 static rtx iq2000_load_reg4
;
149 /* Mode used for saving/restoring general purpose registers. */
150 static enum machine_mode gpr_mode
;
153 /* Initialize the GCC target structure. */
154 static struct machine_function
* iq2000_init_machine_status (void);
155 static bool iq2000_handle_option (size_t, const char *, int);
156 static section
*iq2000_select_rtx_section (enum machine_mode
, rtx
,
157 unsigned HOST_WIDE_INT
);
158 static void iq2000_init_builtins (void);
159 static rtx
iq2000_expand_builtin (tree
, rtx
, rtx
, enum machine_mode
, int);
160 static bool iq2000_return_in_memory (const_tree
, const_tree
);
161 static void iq2000_setup_incoming_varargs (CUMULATIVE_ARGS
*,
162 enum machine_mode
, tree
, int *,
164 static bool iq2000_rtx_costs (rtx
, int, int, int *);
165 static int iq2000_address_cost (rtx
);
166 static section
*iq2000_select_section (tree
, int, unsigned HOST_WIDE_INT
);
167 static bool iq2000_pass_by_reference (CUMULATIVE_ARGS
*, enum machine_mode
,
169 static int iq2000_arg_partial_bytes (CUMULATIVE_ARGS
*, enum machine_mode
,
171 static void iq2000_va_start (tree
, rtx
);
173 #undef TARGET_INIT_BUILTINS
174 #define TARGET_INIT_BUILTINS iq2000_init_builtins
175 #undef TARGET_EXPAND_BUILTIN
176 #define TARGET_EXPAND_BUILTIN iq2000_expand_builtin
177 #undef TARGET_ASM_SELECT_RTX_SECTION
178 #define TARGET_ASM_SELECT_RTX_SECTION iq2000_select_rtx_section
179 #undef TARGET_HANDLE_OPTION
180 #define TARGET_HANDLE_OPTION iq2000_handle_option
181 #undef TARGET_RTX_COSTS
182 #define TARGET_RTX_COSTS iq2000_rtx_costs
183 #undef TARGET_ADDRESS_COST
184 #define TARGET_ADDRESS_COST iq2000_address_cost
185 #undef TARGET_ASM_SELECT_SECTION
186 #define TARGET_ASM_SELECT_SECTION iq2000_select_section
188 /* The assembler supports switchable .bss sections, but
189 iq2000_select_section doesn't yet make use of them. */
190 #undef TARGET_HAVE_SWITCHABLE_BSS_SECTIONS
191 #define TARGET_HAVE_SWITCHABLE_BSS_SECTIONS false
193 #undef TARGET_PROMOTE_FUNCTION_ARGS
194 #define TARGET_PROMOTE_FUNCTION_ARGS hook_bool_const_tree_true
195 #undef TARGET_PROMOTE_FUNCTION_RETURN
196 #define TARGET_PROMOTE_FUNCTION_RETURN hook_bool_const_tree_true
197 #undef TARGET_PROMOTE_PROTOTYPES
198 #define TARGET_PROMOTE_PROTOTYPES hook_bool_const_tree_true
200 #undef TARGET_RETURN_IN_MEMORY
201 #define TARGET_RETURN_IN_MEMORY iq2000_return_in_memory
202 #undef TARGET_PASS_BY_REFERENCE
203 #define TARGET_PASS_BY_REFERENCE iq2000_pass_by_reference
204 #undef TARGET_CALLEE_COPIES
205 #define TARGET_CALLEE_COPIES hook_callee_copies_named
206 #undef TARGET_ARG_PARTIAL_BYTES
207 #define TARGET_ARG_PARTIAL_BYTES iq2000_arg_partial_bytes
209 #undef TARGET_SETUP_INCOMING_VARARGS
210 #define TARGET_SETUP_INCOMING_VARARGS iq2000_setup_incoming_varargs
211 #undef TARGET_STRICT_ARGUMENT_NAMING
212 #define TARGET_STRICT_ARGUMENT_NAMING hook_bool_CUMULATIVE_ARGS_true
214 #undef TARGET_EXPAND_BUILTIN_VA_START
215 #define TARGET_EXPAND_BUILTIN_VA_START iq2000_va_start
217 struct gcc_target targetm
= TARGET_INITIALIZER
;
219 /* Return nonzero if we split the address into high and low parts. */
222 iq2000_check_split (rtx address
, enum machine_mode mode
)
224 /* This is the same check used in simple_memory_operand.
225 We use it here because LO_SUM is not offsettable. */
226 if (GET_MODE_SIZE (mode
) > (unsigned) UNITS_PER_WORD
)
229 if ((GET_CODE (address
) == SYMBOL_REF
)
230 || (GET_CODE (address
) == CONST
231 && GET_CODE (XEXP (XEXP (address
, 0), 0)) == SYMBOL_REF
)
232 || GET_CODE (address
) == LABEL_REF
)
238 /* Return nonzero if REG is valid for MODE. */
241 iq2000_reg_mode_ok_for_base_p (rtx reg
,
242 enum machine_mode mode ATTRIBUTE_UNUSED
,
246 ? REGNO_MODE_OK_FOR_BASE_P (REGNO (reg
), mode
)
247 : GP_REG_OR_PSEUDO_NONSTRICT_P (REGNO (reg
), mode
));
250 /* Return a nonzero value if XINSN is a legitimate address for a
251 memory operand of the indicated MODE. STRICT is nonzero if this
252 function is called during reload. */
255 iq2000_legitimate_address_p (enum machine_mode mode
, rtx xinsn
, int strict
)
257 if (TARGET_DEBUG_A_MODE
)
259 GO_PRINTF2 ("\n========== GO_IF_LEGITIMATE_ADDRESS, %sstrict\n",
260 strict
? "" : "not ");
261 GO_DEBUG_RTX (xinsn
);
264 /* Check for constant before stripping off SUBREG, so that we don't
265 accept (subreg (const_int)) which will fail to reload. */
266 if (CONSTANT_ADDRESS_P (xinsn
)
267 && ! (iq2000_check_split (xinsn
, mode
))
268 && ! (GET_CODE (xinsn
) == CONST_INT
&& ! SMALL_INT (xinsn
)))
271 while (GET_CODE (xinsn
) == SUBREG
)
272 xinsn
= SUBREG_REG (xinsn
);
274 if (GET_CODE (xinsn
) == REG
275 && iq2000_reg_mode_ok_for_base_p (xinsn
, mode
, strict
))
278 if (GET_CODE (xinsn
) == LO_SUM
)
280 rtx xlow0
= XEXP (xinsn
, 0);
281 rtx xlow1
= XEXP (xinsn
, 1);
283 while (GET_CODE (xlow0
) == SUBREG
)
284 xlow0
= SUBREG_REG (xlow0
);
285 if (GET_CODE (xlow0
) == REG
286 && iq2000_reg_mode_ok_for_base_p (xlow0
, mode
, strict
)
287 && iq2000_check_split (xlow1
, mode
))
291 if (GET_CODE (xinsn
) == PLUS
)
293 rtx xplus0
= XEXP (xinsn
, 0);
294 rtx xplus1
= XEXP (xinsn
, 1);
298 while (GET_CODE (xplus0
) == SUBREG
)
299 xplus0
= SUBREG_REG (xplus0
);
300 code0
= GET_CODE (xplus0
);
302 while (GET_CODE (xplus1
) == SUBREG
)
303 xplus1
= SUBREG_REG (xplus1
);
304 code1
= GET_CODE (xplus1
);
307 && iq2000_reg_mode_ok_for_base_p (xplus0
, mode
, strict
))
309 if (code1
== CONST_INT
&& SMALL_INT (xplus1
)
310 && SMALL_INT_UNSIGNED (xplus1
) /* No negative offsets */)
315 if (TARGET_DEBUG_A_MODE
)
316 GO_PRINTF ("Not a legitimate address\n");
318 /* The address was not legitimate. */
322 /* Returns an operand string for the given instruction's delay slot,
323 after updating filled delay slot statistics.
325 We assume that operands[0] is the target register that is set.
327 In order to check the next insn, most of this functionality is moved
328 to FINAL_PRESCAN_INSN, and we just set the global variables that
332 iq2000_fill_delay_slot (const char *ret
, enum delay_type type
, rtx operands
[],
336 enum machine_mode mode
;
337 rtx next_insn
= cur_insn
? NEXT_INSN (cur_insn
) : NULL_RTX
;
340 if (type
== DELAY_LOAD
|| type
== DELAY_FCMP
)
346 /* Make sure that we don't put nop's after labels. */
347 next_insn
= NEXT_INSN (cur_insn
);
348 while (next_insn
!= 0
349 && (GET_CODE (next_insn
) == NOTE
350 || GET_CODE (next_insn
) == CODE_LABEL
))
351 next_insn
= NEXT_INSN (next_insn
);
353 dslots_load_total
+= num_nops
;
354 if (TARGET_DEBUG_C_MODE
355 || type
== DELAY_NONE
359 || GET_CODE (next_insn
) == CODE_LABEL
360 || (set_reg
= operands
[0]) == 0)
362 dslots_number_nops
= 0;
364 iq2000_load_reg2
= 0;
365 iq2000_load_reg3
= 0;
366 iq2000_load_reg4
= 0;
371 set_reg
= operands
[0];
375 while (GET_CODE (set_reg
) == SUBREG
)
376 set_reg
= SUBREG_REG (set_reg
);
378 mode
= GET_MODE (set_reg
);
379 dslots_number_nops
= num_nops
;
380 iq2000_load_reg
= set_reg
;
381 if (GET_MODE_SIZE (mode
)
382 > (unsigned) (UNITS_PER_WORD
))
383 iq2000_load_reg2
= gen_rtx_REG (SImode
, REGNO (set_reg
) + 1);
385 iq2000_load_reg2
= 0;
390 /* Determine whether a memory reference takes one (based off of the GP
391 pointer), two (normal), or three (label + reg) instructions, and bump the
392 appropriate counter for -mstats. */
395 iq2000_count_memory_refs (rtx op
, int num
)
399 rtx addr
, plus0
, plus1
;
400 enum rtx_code code0
, code1
;
403 if (TARGET_DEBUG_B_MODE
)
405 fprintf (stderr
, "\n========== iq2000_count_memory_refs:\n");
409 /* Skip MEM if passed, otherwise handle movsi of address. */
410 addr
= (GET_CODE (op
) != MEM
) ? op
: XEXP (op
, 0);
412 /* Loop, going through the address RTL. */
416 switch (GET_CODE (addr
))
424 plus0
= XEXP (addr
, 0);
425 plus1
= XEXP (addr
, 1);
426 code0
= GET_CODE (plus0
);
427 code1
= GET_CODE (plus1
);
437 if (code0
== CONST_INT
)
452 if (code1
== CONST_INT
)
459 if (code0
== SYMBOL_REF
|| code0
== LABEL_REF
|| code0
== CONST
)
466 if (code1
== SYMBOL_REF
|| code1
== LABEL_REF
|| code1
== CONST
)
476 n_words
= 2; /* Always 2 words. */
480 addr
= XEXP (addr
, 0);
485 n_words
= SYMBOL_REF_FLAG (addr
) ? 1 : 2;
497 n_words
+= additional
;
501 num_refs
[n_words
-1] += num
;
504 /* Abort after printing out a specific insn. */
507 abort_with_insn (rtx insn
, const char * reason
)
511 fancy_abort (__FILE__
, __LINE__
, __FUNCTION__
);
514 /* Return the appropriate instructions to move one operand to another. */
517 iq2000_move_1word (rtx operands
[], rtx insn
, int unsignedp
)
520 rtx op0
= operands
[0];
521 rtx op1
= operands
[1];
522 enum rtx_code code0
= GET_CODE (op0
);
523 enum rtx_code code1
= GET_CODE (op1
);
524 enum machine_mode mode
= GET_MODE (op0
);
525 int subreg_offset0
= 0;
526 int subreg_offset1
= 0;
527 enum delay_type delay
= DELAY_NONE
;
529 while (code0
== SUBREG
)
531 subreg_offset0
+= subreg_regno_offset (REGNO (SUBREG_REG (op0
)),
532 GET_MODE (SUBREG_REG (op0
)),
535 op0
= SUBREG_REG (op0
);
536 code0
= GET_CODE (op0
);
539 while (code1
== SUBREG
)
541 subreg_offset1
+= subreg_regno_offset (REGNO (SUBREG_REG (op1
)),
542 GET_MODE (SUBREG_REG (op1
)),
545 op1
= SUBREG_REG (op1
);
546 code1
= GET_CODE (op1
);
549 /* For our purposes, a condition code mode is the same as SImode. */
555 int regno0
= REGNO (op0
) + subreg_offset0
;
559 int regno1
= REGNO (op1
) + subreg_offset1
;
561 /* Do not do anything for assigning a register to itself */
562 if (regno0
== regno1
)
565 else if (GP_REG_P (regno0
))
567 if (GP_REG_P (regno1
))
568 ret
= "or\t%0,%%0,%1";
573 else if (code1
== MEM
)
578 iq2000_count_memory_refs (op1
, 1);
580 if (GP_REG_P (regno0
))
582 /* For loads, use the mode of the memory item, instead of the
583 target, so zero/sign extend can use this code as well. */
584 switch (GET_MODE (op1
))
596 ret
= (unsignedp
) ? "lhu\t%0,%1" : "lh\t%0,%1";
599 ret
= (unsignedp
) ? "lbu\t%0,%1" : "lb\t%0,%1";
605 else if (code1
== CONST_INT
606 || (code1
== CONST_DOUBLE
607 && GET_MODE (op1
) == VOIDmode
))
609 if (code1
== CONST_DOUBLE
)
611 /* This can happen when storing constants into long long
612 bitfields. Just store the least significant word of
614 operands
[1] = op1
= GEN_INT (CONST_DOUBLE_LOW (op1
));
617 if (INTVAL (op1
) == 0)
619 if (GP_REG_P (regno0
))
620 ret
= "or\t%0,%%0,%z1";
622 else if (GP_REG_P (regno0
))
624 if (SMALL_INT_UNSIGNED (op1
))
625 ret
= "ori\t%0,%%0,%x1\t\t\t# %1";
626 else if (SMALL_INT (op1
))
627 ret
= "addiu\t%0,%%0,%1\t\t\t# %1";
629 ret
= "lui\t%0,%X1\t\t\t# %1\n\tori\t%0,%0,%x1";
633 else if (code1
== CONST_DOUBLE
&& mode
== SFmode
)
635 if (op1
== CONST0_RTX (SFmode
))
637 if (GP_REG_P (regno0
))
638 ret
= "or\t%0,%%0,%.";
648 else if (code1
== LABEL_REF
)
651 iq2000_count_memory_refs (op1
, 1);
656 else if (code1
== SYMBOL_REF
|| code1
== CONST
)
659 iq2000_count_memory_refs (op1
, 1);
664 else if (code1
== PLUS
)
666 rtx add_op0
= XEXP (op1
, 0);
667 rtx add_op1
= XEXP (op1
, 1);
669 if (GET_CODE (XEXP (op1
, 1)) == REG
670 && GET_CODE (XEXP (op1
, 0)) == CONST_INT
)
671 add_op0
= XEXP (op1
, 1), add_op1
= XEXP (op1
, 0);
673 operands
[2] = add_op0
;
674 operands
[3] = add_op1
;
675 ret
= "add%:\t%0,%2,%3";
678 else if (code1
== HIGH
)
680 operands
[1] = XEXP (op1
, 0);
681 ret
= "lui\t%0,%%hi(%1)";
685 else if (code0
== MEM
)
688 iq2000_count_memory_refs (op0
, 1);
692 int regno1
= REGNO (op1
) + subreg_offset1
;
694 if (GP_REG_P (regno1
))
698 case SFmode
: ret
= "sw\t%1,%0"; break;
699 case SImode
: ret
= "sw\t%1,%0"; break;
700 case HImode
: ret
= "sh\t%1,%0"; break;
701 case QImode
: ret
= "sb\t%1,%0"; break;
707 else if (code1
== CONST_INT
&& INTVAL (op1
) == 0)
711 case SFmode
: ret
= "sw\t%z1,%0"; break;
712 case SImode
: ret
= "sw\t%z1,%0"; break;
713 case HImode
: ret
= "sh\t%z1,%0"; break;
714 case QImode
: ret
= "sb\t%z1,%0"; break;
719 else if (code1
== CONST_DOUBLE
&& op1
== CONST0_RTX (mode
))
723 case SFmode
: ret
= "sw\t%.,%0"; break;
724 case SImode
: ret
= "sw\t%.,%0"; break;
725 case HImode
: ret
= "sh\t%.,%0"; break;
726 case QImode
: ret
= "sb\t%.,%0"; break;
734 abort_with_insn (insn
, "Bad move");
738 if (delay
!= DELAY_NONE
)
739 return iq2000_fill_delay_slot (ret
, delay
, operands
, insn
);
744 /* Provide the costs of an addressing mode that contains ADDR. */
747 iq2000_address_cost (rtx addr
)
749 switch (GET_CODE (addr
))
759 rtx offset
= const0_rtx
;
761 addr
= eliminate_constant_term (XEXP (addr
, 0), & offset
);
762 if (GET_CODE (addr
) == LABEL_REF
)
765 if (GET_CODE (addr
) != SYMBOL_REF
)
768 if (! SMALL_INT (offset
))
775 return SYMBOL_REF_FLAG (addr
) ? 1 : 2;
779 rtx plus0
= XEXP (addr
, 0);
780 rtx plus1
= XEXP (addr
, 1);
782 if (GET_CODE (plus0
) != REG
&& GET_CODE (plus1
) == REG
)
783 plus0
= XEXP (addr
, 1), plus1
= XEXP (addr
, 0);
785 if (GET_CODE (plus0
) != REG
)
788 switch (GET_CODE (plus1
))
791 return SMALL_INT (plus1
) ? 1 : 2;
798 return iq2000_address_cost (plus1
) + 1;
812 /* Make normal rtx_code into something we can index from an array. */
814 static enum internal_test
815 map_test_to_internal_test (enum rtx_code test_code
)
817 enum internal_test test
= ITEST_MAX
;
821 case EQ
: test
= ITEST_EQ
; break;
822 case NE
: test
= ITEST_NE
; break;
823 case GT
: test
= ITEST_GT
; break;
824 case GE
: test
= ITEST_GE
; break;
825 case LT
: test
= ITEST_LT
; break;
826 case LE
: test
= ITEST_LE
; break;
827 case GTU
: test
= ITEST_GTU
; break;
828 case GEU
: test
= ITEST_GEU
; break;
829 case LTU
: test
= ITEST_LTU
; break;
830 case LEU
: test
= ITEST_LEU
; break;
837 /* Generate the code to do a TEST_CODE comparison on two integer values CMP0
838 and CMP1. P_INVERT is NULL or ptr if branch needs to reverse its test.
839 The return value RESULT is:
840 (reg:SI xx) The pseudo register the comparison is in
841 0 No register, generate a simple branch. */
844 gen_int_relational (enum rtx_code test_code
, rtx result
, rtx cmp0
, rtx cmp1
,
849 enum rtx_code test_code
; /* Code to use in instruction (LT vs. LTU). */
850 int const_low
; /* Low bound of constant we can accept. */
851 int const_high
; /* High bound of constant we can accept. */
852 int const_add
; /* Constant to add (convert LE -> LT). */
853 int reverse_regs
; /* Reverse registers in test. */
854 int invert_const
; /* != 0 if invert value if cmp1 is constant. */
855 int invert_reg
; /* != 0 if invert value if cmp1 is register. */
856 int unsignedp
; /* != 0 for unsigned comparisons. */
859 static struct cmp_info info
[ (int)ITEST_MAX
] =
861 { XOR
, 0, 65535, 0, 0, 0, 0, 0 }, /* EQ */
862 { XOR
, 0, 65535, 0, 0, 1, 1, 0 }, /* NE */
863 { LT
, -32769, 32766, 1, 1, 1, 0, 0 }, /* GT */
864 { LT
, -32768, 32767, 0, 0, 1, 1, 0 }, /* GE */
865 { LT
, -32768, 32767, 0, 0, 0, 0, 0 }, /* LT */
866 { LT
, -32769, 32766, 1, 1, 0, 1, 0 }, /* LE */
867 { LTU
, -32769, 32766, 1, 1, 1, 0, 1 }, /* GTU */
868 { LTU
, -32768, 32767, 0, 0, 1, 1, 1 }, /* GEU */
869 { LTU
, -32768, 32767, 0, 0, 0, 0, 1 }, /* LTU */
870 { LTU
, -32769, 32766, 1, 1, 0, 1, 1 }, /* LEU */
873 enum internal_test test
;
874 enum machine_mode mode
;
875 struct cmp_info
*p_info
;
882 test
= map_test_to_internal_test (test_code
);
883 gcc_assert (test
!= ITEST_MAX
);
885 p_info
= &info
[(int) test
];
886 eqne_p
= (p_info
->test_code
== XOR
);
888 mode
= GET_MODE (cmp0
);
889 if (mode
== VOIDmode
)
890 mode
= GET_MODE (cmp1
);
892 /* Eliminate simple branches. */
893 branch_p
= (result
== 0);
896 if (GET_CODE (cmp0
) == REG
|| GET_CODE (cmp0
) == SUBREG
)
898 /* Comparisons against zero are simple branches. */
899 if (GET_CODE (cmp1
) == CONST_INT
&& INTVAL (cmp1
) == 0)
902 /* Test for beq/bne. */
907 /* Allocate a pseudo to calculate the value in. */
908 result
= gen_reg_rtx (mode
);
911 /* Make sure we can handle any constants given to us. */
912 if (GET_CODE (cmp0
) == CONST_INT
)
913 cmp0
= force_reg (mode
, cmp0
);
915 if (GET_CODE (cmp1
) == CONST_INT
)
917 HOST_WIDE_INT value
= INTVAL (cmp1
);
919 if (value
< p_info
->const_low
920 || value
> p_info
->const_high
)
921 cmp1
= force_reg (mode
, cmp1
);
924 /* See if we need to invert the result. */
925 invert
= (GET_CODE (cmp1
) == CONST_INT
926 ? p_info
->invert_const
: p_info
->invert_reg
);
928 if (p_invert
!= (int *)0)
934 /* Comparison to constants, may involve adding 1 to change a LT into LE.
935 Comparison between two registers, may involve switching operands. */
936 if (GET_CODE (cmp1
) == CONST_INT
)
938 if (p_info
->const_add
!= 0)
940 HOST_WIDE_INT
new = INTVAL (cmp1
) + p_info
->const_add
;
942 /* If modification of cmp1 caused overflow,
943 we would get the wrong answer if we follow the usual path;
944 thus, x > 0xffffffffU would turn into x > 0U. */
945 if ((p_info
->unsignedp
946 ? (unsigned HOST_WIDE_INT
) new >
947 (unsigned HOST_WIDE_INT
) INTVAL (cmp1
)
948 : new > INTVAL (cmp1
))
949 != (p_info
->const_add
> 0))
951 /* This test is always true, but if INVERT is true then
952 the result of the test needs to be inverted so 0 should
953 be returned instead. */
954 emit_move_insn (result
, invert
? const0_rtx
: const_true_rtx
);
958 cmp1
= GEN_INT (new);
962 else if (p_info
->reverse_regs
)
969 if (test
== ITEST_NE
&& GET_CODE (cmp1
) == CONST_INT
&& INTVAL (cmp1
) == 0)
973 reg
= (invert
|| eqne_p
) ? gen_reg_rtx (mode
) : result
;
974 convert_move (reg
, gen_rtx_fmt_ee (p_info
->test_code
, mode
, cmp0
, cmp1
), 0);
977 if (test
== ITEST_NE
)
979 convert_move (result
, gen_rtx_GTU (mode
, reg
, const0_rtx
), 0);
980 if (p_invert
!= NULL
)
985 else if (test
== ITEST_EQ
)
987 reg2
= invert
? gen_reg_rtx (mode
) : result
;
988 convert_move (reg2
, gen_rtx_LTU (mode
, reg
, const1_rtx
), 0);
997 convert_move (result
, gen_rtx_XOR (mode
, reg
, one
), 0);
1003 /* Emit the common code for doing conditional branches.
1004 operand[0] is the label to jump to.
1005 The comparison operands are saved away by cmp{si,di,sf,df}. */
1008 gen_conditional_branch (rtx operands
[], enum rtx_code test_code
)
1010 enum cmp_type type
= branch_type
;
1011 rtx cmp0
= branch_cmp
[0];
1012 rtx cmp1
= branch_cmp
[1];
1013 enum machine_mode mode
;
1022 mode
= type
== CMP_SI
? SImode
: DImode
;
1024 reg
= gen_int_relational (test_code
, NULL_RTX
, cmp0
, cmp1
, &invert
);
1032 else if (GET_CODE (cmp1
) == CONST_INT
&& INTVAL (cmp1
) != 0)
1033 /* We don't want to build a comparison against a nonzero
1035 cmp1
= force_reg (mode
, cmp1
);
1041 reg
= gen_reg_rtx (CCmode
);
1043 /* For cmp0 != cmp1, build cmp0 == cmp1, and test for result == 0. */
1044 emit_insn (gen_rtx_SET (VOIDmode
, reg
,
1045 gen_rtx_fmt_ee (test_code
== NE
? EQ
: test_code
,
1046 CCmode
, cmp0
, cmp1
)));
1048 test_code
= test_code
== NE
? EQ
: NE
;
1056 abort_with_insn (gen_rtx_fmt_ee (test_code
, VOIDmode
, cmp0
, cmp1
),
1060 /* Generate the branch. */
1061 label1
= gen_rtx_LABEL_REF (VOIDmode
, operands
[0]);
1070 emit_jump_insn (gen_rtx_SET (VOIDmode
, pc_rtx
,
1071 gen_rtx_IF_THEN_ELSE (VOIDmode
,
1072 gen_rtx_fmt_ee (test_code
,
1078 /* Initialize CUM for a function FNTYPE. */
1081 init_cumulative_args (CUMULATIVE_ARGS
*cum
, tree fntype
,
1082 rtx libname ATTRIBUTE_UNUSED
)
1084 static CUMULATIVE_ARGS zero_cum
;
1088 if (TARGET_DEBUG_D_MODE
)
1091 "\ninit_cumulative_args, fntype = 0x%.8lx", (long) fntype
);
1094 fputc ('\n', stderr
);
1098 tree ret_type
= TREE_TYPE (fntype
);
1100 fprintf (stderr
, ", fntype code = %s, ret code = %s\n",
1101 tree_code_name
[(int)TREE_CODE (fntype
)],
1102 tree_code_name
[(int)TREE_CODE (ret_type
)]);
1108 /* Determine if this function has variable arguments. This is
1109 indicated by the last argument being 'void_type_mode' if there
1110 are no variable arguments. The standard IQ2000 calling sequence
1111 passes all arguments in the general purpose registers in this case. */
1113 for (param
= fntype
? TYPE_ARG_TYPES (fntype
) : 0;
1114 param
!= 0; param
= next_param
)
1116 next_param
= TREE_CHAIN (param
);
1117 if (next_param
== 0 && TREE_VALUE (param
) != void_type_node
)
1118 cum
->gp_reg_found
= 1;
1122 /* Advance the argument of type TYPE and mode MODE to the next argument
1126 function_arg_advance (CUMULATIVE_ARGS
*cum
, enum machine_mode mode
, tree type
,
1129 if (TARGET_DEBUG_D_MODE
)
1132 "function_adv({gp reg found = %d, arg # = %2d, words = %2d}, %4s, ",
1133 cum
->gp_reg_found
, cum
->arg_number
, cum
->arg_words
,
1134 GET_MODE_NAME (mode
));
1135 fprintf (stderr
, "%p", (void *) type
);
1136 fprintf (stderr
, ", %d )\n\n", named
);
1146 gcc_assert (GET_MODE_CLASS (mode
) == MODE_COMPLEX_INT
1147 || GET_MODE_CLASS (mode
) == MODE_COMPLEX_FLOAT
);
1149 cum
->gp_reg_found
= 1;
1150 cum
->arg_words
+= ((GET_MODE_SIZE (mode
) + UNITS_PER_WORD
- 1)
1155 cum
->gp_reg_found
= 1;
1156 cum
->arg_words
+= ((int_size_in_bytes (type
) + UNITS_PER_WORD
- 1)
1162 if (! cum
->gp_reg_found
&& cum
->arg_number
<= 2)
1163 cum
->fp_code
+= 1 << ((cum
->arg_number
- 1) * 2);
1167 cum
->arg_words
+= 2;
1168 if (! cum
->gp_reg_found
&& cum
->arg_number
<= 2)
1169 cum
->fp_code
+= 2 << ((cum
->arg_number
- 1) * 2);
1173 cum
->gp_reg_found
= 1;
1174 cum
->arg_words
+= 2;
1180 cum
->gp_reg_found
= 1;
1186 /* Return an RTL expression containing the register for the given mode MODE
1187 and type TYPE in CUM, or 0 if the argument is to be passed on the stack. */
1190 function_arg (CUMULATIVE_ARGS
*cum
, enum machine_mode mode
, const_tree type
,
1196 unsigned int *arg_words
= &cum
->arg_words
;
1197 int struct_p
= (type
!= 0
1198 && (TREE_CODE (type
) == RECORD_TYPE
1199 || TREE_CODE (type
) == UNION_TYPE
1200 || TREE_CODE (type
) == QUAL_UNION_TYPE
));
1202 if (TARGET_DEBUG_D_MODE
)
1205 "function_arg( {gp reg found = %d, arg # = %2d, words = %2d}, %4s, ",
1206 cum
->gp_reg_found
, cum
->arg_number
, cum
->arg_words
,
1207 GET_MODE_NAME (mode
));
1208 fprintf (stderr
, "%p", (const void *) type
);
1209 fprintf (stderr
, ", %d ) = ", named
);
1213 cum
->last_arg_fp
= 0;
1217 regbase
= GP_ARG_FIRST
;
1221 cum
->arg_words
+= cum
->arg_words
& 1;
1223 regbase
= GP_ARG_FIRST
;
1227 gcc_assert (GET_MODE_CLASS (mode
) == MODE_COMPLEX_INT
1228 || GET_MODE_CLASS (mode
) == MODE_COMPLEX_FLOAT
);
1230 /* Drops through. */
1232 if (type
!= NULL_TREE
&& TYPE_ALIGN (type
) > (unsigned) BITS_PER_WORD
)
1233 cum
->arg_words
+= (cum
->arg_words
& 1);
1234 regbase
= GP_ARG_FIRST
;
1241 regbase
= GP_ARG_FIRST
;
1245 cum
->arg_words
+= (cum
->arg_words
& 1);
1246 regbase
= GP_ARG_FIRST
;
1249 if (*arg_words
>= (unsigned) MAX_ARGS_IN_REGISTERS
)
1251 if (TARGET_DEBUG_D_MODE
)
1252 fprintf (stderr
, "<stack>%s\n", struct_p
? ", [struct]" : "");
1258 gcc_assert (regbase
!= -1);
1260 if (! type
|| TREE_CODE (type
) != RECORD_TYPE
1261 || ! named
|| ! TYPE_SIZE_UNIT (type
)
1262 || ! host_integerp (TYPE_SIZE_UNIT (type
), 1))
1263 ret
= gen_rtx_REG (mode
, regbase
+ *arg_words
+ bias
);
1268 for (field
= TYPE_FIELDS (type
); field
; field
= TREE_CHAIN (field
))
1269 if (TREE_CODE (field
) == FIELD_DECL
1270 && TREE_CODE (TREE_TYPE (field
)) == REAL_TYPE
1271 && TYPE_PRECISION (TREE_TYPE (field
)) == BITS_PER_WORD
1272 && host_integerp (bit_position (field
), 0)
1273 && int_bit_position (field
) % BITS_PER_WORD
== 0)
1276 /* If the whole struct fits a DFmode register,
1277 we don't need the PARALLEL. */
1278 if (! field
|| mode
== DFmode
)
1279 ret
= gen_rtx_REG (mode
, regbase
+ *arg_words
+ bias
);
1282 unsigned int chunks
;
1283 HOST_WIDE_INT bitpos
;
1287 /* ??? If this is a packed structure, then the last hunk won't
1290 = tree_low_cst (TYPE_SIZE_UNIT (type
), 1) / UNITS_PER_WORD
;
1291 if (chunks
+ *arg_words
+ bias
> (unsigned) MAX_ARGS_IN_REGISTERS
)
1292 chunks
= MAX_ARGS_IN_REGISTERS
- *arg_words
- bias
;
1294 /* Assign_parms checks the mode of ENTRY_PARM, so we must
1295 use the actual mode here. */
1296 ret
= gen_rtx_PARALLEL (mode
, rtvec_alloc (chunks
));
1299 regno
= regbase
+ *arg_words
+ bias
;
1300 field
= TYPE_FIELDS (type
);
1301 for (i
= 0; i
< chunks
; i
++)
1305 for (; field
; field
= TREE_CHAIN (field
))
1306 if (TREE_CODE (field
) == FIELD_DECL
1307 && int_bit_position (field
) >= bitpos
)
1311 && int_bit_position (field
) == bitpos
1312 && TREE_CODE (TREE_TYPE (field
)) == REAL_TYPE
1313 && TYPE_PRECISION (TREE_TYPE (field
)) == BITS_PER_WORD
)
1314 reg
= gen_rtx_REG (DFmode
, regno
++);
1316 reg
= gen_rtx_REG (word_mode
, regno
);
1319 = gen_rtx_EXPR_LIST (VOIDmode
, reg
,
1320 GEN_INT (bitpos
/ BITS_PER_UNIT
));
1328 if (TARGET_DEBUG_D_MODE
)
1329 fprintf (stderr
, "%s%s\n", reg_names
[regbase
+ *arg_words
+ bias
],
1330 struct_p
? ", [struct]" : "");
1333 /* We will be called with a mode of VOIDmode after the last argument
1334 has been seen. Whatever we return will be passed to the call
1335 insn. If we need any shifts for small structures, return them in
1337 if (mode
== VOIDmode
)
1339 if (cum
->num_adjusts
> 0)
1340 ret
= gen_rtx_PARALLEL ((enum machine_mode
) cum
->fp_code
,
1341 gen_rtvec_v (cum
->num_adjusts
, cum
->adjust
));
1348 iq2000_arg_partial_bytes (CUMULATIVE_ARGS
*cum
, enum machine_mode mode
,
1349 tree type ATTRIBUTE_UNUSED
,
1350 bool named ATTRIBUTE_UNUSED
)
1352 if (mode
== DImode
&& cum
->arg_words
== MAX_ARGS_IN_REGISTERS
- 1)
1354 if (TARGET_DEBUG_D_MODE
)
1355 fprintf (stderr
, "iq2000_arg_partial_bytes=%d\n", UNITS_PER_WORD
);
1356 return UNITS_PER_WORD
;
1362 /* Implement va_start. */
1365 iq2000_va_start (tree valist
, rtx nextarg
)
1368 /* Find out how many non-float named formals. */
1369 int gpr_save_area_size
;
1370 /* Note UNITS_PER_WORD is 4 bytes. */
1371 int_arg_words
= crtl
->args
.info
.arg_words
;
1373 if (int_arg_words
< 8 )
1374 /* Adjust for the prologue's economy measure. */
1375 gpr_save_area_size
= (8 - int_arg_words
) * UNITS_PER_WORD
;
1377 gpr_save_area_size
= 0;
1379 /* Everything is in the GPR save area, or in the overflow
1380 area which is contiguous with it. */
1381 nextarg
= plus_constant (nextarg
, - gpr_save_area_size
);
1382 std_expand_builtin_va_start (valist
, nextarg
);
1385 /* Allocate a chunk of memory for per-function machine-dependent data. */
1387 static struct machine_function
*
1388 iq2000_init_machine_status (void)
1390 struct machine_function
*f
;
1392 f
= ggc_alloc_cleared (sizeof (struct machine_function
));
1397 /* Implement TARGET_HANDLE_OPTION. */
1400 iq2000_handle_option (size_t code
, const char *arg
, int value ATTRIBUTE_UNUSED
)
1405 if (strcmp (arg
, "iq10") == 0)
1406 iq2000_tune
= PROCESSOR_IQ10
;
1407 else if (strcmp (arg
, "iq2000") == 0)
1408 iq2000_tune
= PROCESSOR_IQ2000
;
1414 /* This option has no effect at the moment. */
1415 return (strcmp (arg
, "default") == 0
1416 || strcmp (arg
, "DEFAULT") == 0
1417 || strcmp (arg
, "iq2000") == 0);
1424 /* Detect any conflicts in the switches. */
1427 override_options (void)
1429 target_flags
&= ~MASK_GPOPT
;
1431 iq2000_isa
= IQ2000_ISA_DEFAULT
;
1433 /* Identify the processor type. */
1435 iq2000_print_operand_punct
['?'] = 1;
1436 iq2000_print_operand_punct
['#'] = 1;
1437 iq2000_print_operand_punct
['&'] = 1;
1438 iq2000_print_operand_punct
['!'] = 1;
1439 iq2000_print_operand_punct
['*'] = 1;
1440 iq2000_print_operand_punct
['@'] = 1;
1441 iq2000_print_operand_punct
['.'] = 1;
1442 iq2000_print_operand_punct
['('] = 1;
1443 iq2000_print_operand_punct
[')'] = 1;
1444 iq2000_print_operand_punct
['['] = 1;
1445 iq2000_print_operand_punct
[']'] = 1;
1446 iq2000_print_operand_punct
['<'] = 1;
1447 iq2000_print_operand_punct
['>'] = 1;
1448 iq2000_print_operand_punct
['{'] = 1;
1449 iq2000_print_operand_punct
['}'] = 1;
1450 iq2000_print_operand_punct
['^'] = 1;
1451 iq2000_print_operand_punct
['$'] = 1;
1452 iq2000_print_operand_punct
['+'] = 1;
1453 iq2000_print_operand_punct
['~'] = 1;
1455 /* Save GPR registers in word_mode sized hunks. word_mode hasn't been
1456 initialized yet, so we can't use that here. */
1459 /* Function to allocate machine-dependent function status. */
1460 init_machine_status
= iq2000_init_machine_status
;
1463 /* The arg pointer (which is eliminated) points to the virtual frame pointer,
1464 while the frame pointer (which may be eliminated) points to the stack
1465 pointer after the initial adjustments. */
1468 iq2000_debugger_offset (rtx addr
, HOST_WIDE_INT offset
)
1470 rtx offset2
= const0_rtx
;
1471 rtx reg
= eliminate_constant_term (addr
, & offset2
);
1474 offset
= INTVAL (offset2
);
1476 if (reg
== stack_pointer_rtx
|| reg
== frame_pointer_rtx
1477 || reg
== hard_frame_pointer_rtx
)
1479 HOST_WIDE_INT frame_size
= (!cfun
->machine
->initialized
)
1480 ? compute_frame_size (get_frame_size ())
1481 : cfun
->machine
->total_size
;
1483 offset
= offset
- frame_size
;
1489 /* If defined, a C statement to be executed just prior to the output of
1490 assembler code for INSN, to modify the extracted operands so they will be
1493 Here the argument OPVEC is the vector containing the operands extracted
1494 from INSN, and NOPERANDS is the number of elements of the vector which
1495 contain meaningful data for this insn. The contents of this vector are
1496 what will be used to convert the insn template into assembler code, so you
1497 can change the assembler output by changing the contents of the vector.
1499 We use it to check if the current insn needs a nop in front of it because
1500 of load delays, and also to update the delay slot statistics. */
1503 final_prescan_insn (rtx insn
, rtx opvec
[] ATTRIBUTE_UNUSED
,
1504 int noperands ATTRIBUTE_UNUSED
)
1506 if (dslots_number_nops
> 0)
1508 rtx pattern
= PATTERN (insn
);
1509 int length
= get_attr_length (insn
);
1511 /* Do we need to emit a NOP? */
1513 || (iq2000_load_reg
!= 0 && reg_mentioned_p (iq2000_load_reg
, pattern
))
1514 || (iq2000_load_reg2
!= 0 && reg_mentioned_p (iq2000_load_reg2
, pattern
))
1515 || (iq2000_load_reg3
!= 0 && reg_mentioned_p (iq2000_load_reg3
, pattern
))
1516 || (iq2000_load_reg4
!= 0
1517 && reg_mentioned_p (iq2000_load_reg4
, pattern
)))
1518 fputs ("\tnop\n", asm_out_file
);
1521 dslots_load_filled
++;
1523 while (--dslots_number_nops
> 0)
1524 fputs ("\tnop\n", asm_out_file
);
1526 iq2000_load_reg
= 0;
1527 iq2000_load_reg2
= 0;
1528 iq2000_load_reg3
= 0;
1529 iq2000_load_reg4
= 0;
1532 if ( (GET_CODE (insn
) == JUMP_INSN
1533 || GET_CODE (insn
) == CALL_INSN
1534 || (GET_CODE (PATTERN (insn
)) == RETURN
))
1535 && NEXT_INSN (PREV_INSN (insn
)) == insn
)
1537 rtx nop_insn
= emit_insn_after (gen_nop (), insn
);
1539 INSN_ADDRESSES_NEW (nop_insn
, -1);
1543 && (GET_CODE (insn
) == JUMP_INSN
|| GET_CODE (insn
) == CALL_INSN
))
1544 dslots_jump_total
++;
1547 /* Return the bytes needed to compute the frame pointer from the current
1548 stack pointer where SIZE is the # of var. bytes allocated.
1550 IQ2000 stack frames look like:
1552 Before call After call
1553 +-----------------------+ +-----------------------+
1556 | caller's temps. | | caller's temps. |
1558 +-----------------------+ +-----------------------+
1560 | arguments on stack. | | arguments on stack. |
1562 +-----------------------+ +-----------------------+
1563 | 4 words to save | | 4 words to save |
1564 | arguments passed | | arguments passed |
1565 | in registers, even | | in registers, even |
1566 SP->| if not passed. | VFP->| if not passed. |
1567 +-----------------------+ +-----------------------+
1569 | fp register save |
1571 +-----------------------+
1573 | gp register save |
1575 +-----------------------+
1579 +-----------------------+
1581 | alloca allocations |
1583 +-----------------------+
1585 | GP save for V.4 abi |
1587 +-----------------------+
1589 | arguments on stack |
1591 +-----------------------+
1593 | arguments passed |
1594 | in registers, even |
1595 low SP->| if not passed. |
1596 memory +-----------------------+ */
1599 compute_frame_size (HOST_WIDE_INT size
)
1602 HOST_WIDE_INT total_size
; /* # bytes that the entire frame takes up. */
1603 HOST_WIDE_INT var_size
; /* # bytes that variables take up. */
1604 HOST_WIDE_INT args_size
; /* # bytes that outgoing arguments take up. */
1605 HOST_WIDE_INT extra_size
; /* # extra bytes. */
1606 HOST_WIDE_INT gp_reg_rounded
; /* # bytes needed to store gp after rounding. */
1607 HOST_WIDE_INT gp_reg_size
; /* # bytes needed to store gp regs. */
1608 HOST_WIDE_INT fp_reg_size
; /* # bytes needed to store fp regs. */
1609 long mask
; /* mask of saved gp registers. */
1610 int fp_inc
; /* 1 or 2 depending on the size of fp regs. */
1611 long fp_bits
; /* bitmask to use for each fp register. */
1616 extra_size
= IQ2000_STACK_ALIGN ((0));
1617 var_size
= IQ2000_STACK_ALIGN (size
);
1618 args_size
= IQ2000_STACK_ALIGN (crtl
->outgoing_args_size
);
1620 /* If a function dynamically allocates the stack and
1621 has 0 for STACK_DYNAMIC_OFFSET then allocate some stack space. */
1622 if (args_size
== 0 && cfun
->calls_alloca
)
1623 args_size
= 4 * UNITS_PER_WORD
;
1625 total_size
= var_size
+ args_size
+ extra_size
;
1627 /* Calculate space needed for gp registers. */
1628 for (regno
= GP_REG_FIRST
; regno
<= GP_REG_LAST
; regno
++)
1630 if (MUST_SAVE_REGISTER (regno
))
1632 gp_reg_size
+= GET_MODE_SIZE (gpr_mode
);
1633 mask
|= 1L << (regno
- GP_REG_FIRST
);
1637 /* We need to restore these for the handler. */
1638 if (crtl
->calls_eh_return
)
1644 regno
= EH_RETURN_DATA_REGNO (i
);
1645 if (regno
== (int) INVALID_REGNUM
)
1647 gp_reg_size
+= GET_MODE_SIZE (gpr_mode
);
1648 mask
|= 1L << (regno
- GP_REG_FIRST
);
1654 gp_reg_rounded
= IQ2000_STACK_ALIGN (gp_reg_size
);
1655 total_size
+= gp_reg_rounded
+ IQ2000_STACK_ALIGN (fp_reg_size
);
1657 /* The gp reg is caller saved, so there is no need for leaf routines
1658 (total_size == extra_size) to save the gp reg. */
1659 if (total_size
== extra_size
1661 total_size
= extra_size
= 0;
1663 total_size
+= IQ2000_STACK_ALIGN (crtl
->args
.pretend_args_size
);
1665 /* Save other computed information. */
1666 cfun
->machine
->total_size
= total_size
;
1667 cfun
->machine
->var_size
= var_size
;
1668 cfun
->machine
->args_size
= args_size
;
1669 cfun
->machine
->extra_size
= extra_size
;
1670 cfun
->machine
->gp_reg_size
= gp_reg_size
;
1671 cfun
->machine
->fp_reg_size
= fp_reg_size
;
1672 cfun
->machine
->mask
= mask
;
1673 cfun
->machine
->initialized
= reload_completed
;
1674 cfun
->machine
->num_gp
= gp_reg_size
/ UNITS_PER_WORD
;
1678 unsigned long offset
;
1680 offset
= (args_size
+ extra_size
+ var_size
1681 + gp_reg_size
- GET_MODE_SIZE (gpr_mode
));
1683 cfun
->machine
->gp_sp_offset
= offset
;
1684 cfun
->machine
->gp_save_offset
= offset
- total_size
;
1688 cfun
->machine
->gp_sp_offset
= 0;
1689 cfun
->machine
->gp_save_offset
= 0;
1692 cfun
->machine
->fp_sp_offset
= 0;
1693 cfun
->machine
->fp_save_offset
= 0;
1695 /* Ok, we're done. */
1699 /* Implement INITIAL_ELIMINATION_OFFSET. FROM is either the frame
1700 pointer, argument pointer, or return address pointer. TO is either
1701 the stack pointer or hard frame pointer. */
1704 iq2000_initial_elimination_offset (int from
, int to ATTRIBUTE_UNUSED
)
1708 compute_frame_size (get_frame_size ());
1709 if ((from
) == FRAME_POINTER_REGNUM
)
1711 else if ((from
) == ARG_POINTER_REGNUM
)
1712 (offset
) = (cfun
->machine
->total_size
);
1713 else if ((from
) == RETURN_ADDRESS_POINTER_REGNUM
)
1715 if (leaf_function_p ())
1717 else (offset
) = cfun
->machine
->gp_sp_offset
1718 + ((UNITS_PER_WORD
- (POINTER_SIZE
/ BITS_PER_UNIT
))
1719 * (BYTES_BIG_ENDIAN
!= 0));
1725 /* Common code to emit the insns (or to write the instructions to a file)
1726 to save/restore registers.
1727 Other parts of the code assume that IQ2000_TEMP1_REGNUM (aka large_reg)
1728 is not modified within save_restore_insns. */
1730 #define BITSET_P(VALUE,BIT) (((VALUE) & (1L << (BIT))) != 0)
1732 /* Emit instructions to load the value (SP + OFFSET) into IQ2000_TEMP2_REGNUM
1733 and return an rtl expression for the register. Write the assembly
1734 instructions directly to FILE if it is not null, otherwise emit them as
1737 This function is a subroutine of save_restore_insns. It is used when
1738 OFFSET is too large to add in a single instruction. */
1741 iq2000_add_large_offset_to_sp (HOST_WIDE_INT offset
)
1743 rtx reg
= gen_rtx_REG (Pmode
, IQ2000_TEMP2_REGNUM
);
1744 rtx offset_rtx
= GEN_INT (offset
);
1746 emit_move_insn (reg
, offset_rtx
);
1747 emit_insn (gen_addsi3 (reg
, reg
, stack_pointer_rtx
));
1751 /* Make INSN frame related and note that it performs the frame-related
1752 operation DWARF_PATTERN. */
1755 iq2000_annotate_frame_insn (rtx insn
, rtx dwarf_pattern
)
1757 RTX_FRAME_RELATED_P (insn
) = 1;
1758 REG_NOTES (insn
) = alloc_EXPR_LIST (REG_FRAME_RELATED_EXPR
,
1763 /* Emit a move instruction that stores REG in MEM. Make the instruction
1764 frame related and note that it stores REG at (SP + OFFSET). */
1767 iq2000_emit_frame_related_store (rtx mem
, rtx reg
, HOST_WIDE_INT offset
)
1769 rtx dwarf_address
= plus_constant (stack_pointer_rtx
, offset
);
1770 rtx dwarf_mem
= gen_rtx_MEM (GET_MODE (reg
), dwarf_address
);
1772 iq2000_annotate_frame_insn (emit_move_insn (mem
, reg
),
1773 gen_rtx_SET (GET_MODE (reg
), dwarf_mem
, reg
));
1776 /* Emit instructions to save/restore registers, as determined by STORE_P. */
1779 save_restore_insns (int store_p
)
1781 long mask
= cfun
->machine
->mask
;
1784 HOST_WIDE_INT base_offset
;
1785 HOST_WIDE_INT gp_offset
;
1786 HOST_WIDE_INT end_offset
;
1788 gcc_assert (!frame_pointer_needed
1789 || BITSET_P (mask
, HARD_FRAME_POINTER_REGNUM
- GP_REG_FIRST
));
1793 base_reg_rtx
= 0, base_offset
= 0;
1797 /* Save registers starting from high to low. The debuggers prefer at least
1798 the return register be stored at func+4, and also it allows us not to
1799 need a nop in the epilog if at least one register is reloaded in
1800 addition to return address. */
1802 /* Save GP registers if needed. */
1803 /* Pick which pointer to use as a base register. For small frames, just
1804 use the stack pointer. Otherwise, use a temporary register. Save 2
1805 cycles if the save area is near the end of a large frame, by reusing
1806 the constant created in the prologue/epilogue to adjust the stack
1809 gp_offset
= cfun
->machine
->gp_sp_offset
;
1811 = gp_offset
- (cfun
->machine
->gp_reg_size
1812 - GET_MODE_SIZE (gpr_mode
));
1814 if (gp_offset
< 0 || end_offset
< 0)
1816 ("gp_offset (%ld) or end_offset (%ld) is less than zero",
1817 (long) gp_offset
, (long) end_offset
);
1819 else if (gp_offset
< 32768)
1820 base_reg_rtx
= stack_pointer_rtx
, base_offset
= 0;
1824 int reg_save_count
= 0;
1826 for (regno
= GP_REG_LAST
; regno
>= GP_REG_FIRST
; regno
--)
1827 if (BITSET_P (mask
, regno
- GP_REG_FIRST
)) reg_save_count
+= 1;
1828 base_offset
= gp_offset
- ((reg_save_count
- 1) * 4);
1829 base_reg_rtx
= iq2000_add_large_offset_to_sp (base_offset
);
1832 for (regno
= GP_REG_LAST
; regno
>= GP_REG_FIRST
; regno
--)
1834 if (BITSET_P (mask
, regno
- GP_REG_FIRST
))
1838 = gen_rtx_MEM (gpr_mode
,
1839 gen_rtx_PLUS (Pmode
, base_reg_rtx
,
1840 GEN_INT (gp_offset
- base_offset
)));
1842 reg_rtx
= gen_rtx_REG (gpr_mode
, regno
);
1845 iq2000_emit_frame_related_store (mem_rtx
, reg_rtx
, gp_offset
);
1848 emit_move_insn (reg_rtx
, mem_rtx
);
1850 gp_offset
-= GET_MODE_SIZE (gpr_mode
);
1855 /* Expand the prologue into a bunch of separate insns. */
1858 iq2000_expand_prologue (void)
1861 HOST_WIDE_INT tsize
;
1862 int last_arg_is_vararg_marker
= 0;
1863 tree fndecl
= current_function_decl
;
1864 tree fntype
= TREE_TYPE (fndecl
);
1865 tree fnargs
= DECL_ARGUMENTS (fndecl
);
1870 CUMULATIVE_ARGS args_so_far
;
1871 int store_args_on_stack
= (iq2000_can_use_return_insn ());
1873 /* If struct value address is treated as the first argument. */
1874 if (aggregate_value_p (DECL_RESULT (fndecl
), fndecl
)
1875 && !cfun
->returns_pcc_struct
1876 && targetm
.calls
.struct_value_rtx (TREE_TYPE (fndecl
), 1) == 0)
1878 tree type
= build_pointer_type (fntype
);
1879 tree function_result_decl
= build_decl (PARM_DECL
, NULL_TREE
, type
);
1881 DECL_ARG_TYPE (function_result_decl
) = type
;
1882 TREE_CHAIN (function_result_decl
) = fnargs
;
1883 fnargs
= function_result_decl
;
1886 /* For arguments passed in registers, find the register number
1887 of the first argument in the variable part of the argument list,
1888 otherwise GP_ARG_LAST+1. Note also if the last argument is
1889 the varargs special argument, and treat it as part of the
1892 This is only needed if store_args_on_stack is true. */
1893 INIT_CUMULATIVE_ARGS (args_so_far
, fntype
, NULL_RTX
, 0, 0);
1894 regno
= GP_ARG_FIRST
;
1896 for (cur_arg
= fnargs
; cur_arg
!= 0; cur_arg
= next_arg
)
1898 tree passed_type
= DECL_ARG_TYPE (cur_arg
);
1899 enum machine_mode passed_mode
= TYPE_MODE (passed_type
);
1902 if (TREE_ADDRESSABLE (passed_type
))
1904 passed_type
= build_pointer_type (passed_type
);
1905 passed_mode
= Pmode
;
1908 entry_parm
= FUNCTION_ARG (args_so_far
, passed_mode
, passed_type
, 1);
1910 FUNCTION_ARG_ADVANCE (args_so_far
, passed_mode
, passed_type
, 1);
1911 next_arg
= TREE_CHAIN (cur_arg
);
1913 if (entry_parm
&& store_args_on_stack
)
1916 && DECL_NAME (cur_arg
)
1917 && ((0 == strcmp (IDENTIFIER_POINTER (DECL_NAME (cur_arg
)),
1918 "__builtin_va_alist"))
1919 || (0 == strcmp (IDENTIFIER_POINTER (DECL_NAME (cur_arg
)),
1922 last_arg_is_vararg_marker
= 1;
1929 gcc_assert (GET_CODE (entry_parm
) == REG
);
1931 /* Passed in a register, so will get homed automatically. */
1932 if (GET_MODE (entry_parm
) == BLKmode
)
1933 words
= (int_size_in_bytes (passed_type
) + 3) / 4;
1935 words
= (GET_MODE_SIZE (GET_MODE (entry_parm
)) + 3) / 4;
1937 regno
= REGNO (entry_parm
) + words
- 1;
1942 regno
= GP_ARG_LAST
+1;
1947 /* In order to pass small structures by value in registers we need to
1948 shift the value into the high part of the register.
1949 Function_arg has encoded a PARALLEL rtx, holding a vector of
1950 adjustments to be made as the next_arg_reg variable, so we split up the
1951 insns, and emit them separately. */
1952 next_arg_reg
= FUNCTION_ARG (args_so_far
, VOIDmode
, void_type_node
, 1);
1953 if (next_arg_reg
!= 0 && GET_CODE (next_arg_reg
) == PARALLEL
)
1955 rtvec adjust
= XVEC (next_arg_reg
, 0);
1956 int num
= GET_NUM_ELEM (adjust
);
1958 for (i
= 0; i
< num
; i
++)
1962 pattern
= RTVEC_ELT (adjust
, i
);
1963 if (GET_CODE (pattern
) != SET
1964 || GET_CODE (SET_SRC (pattern
)) != ASHIFT
)
1965 abort_with_insn (pattern
, "Insn is not a shift");
1966 PUT_CODE (SET_SRC (pattern
), ASHIFTRT
);
1968 insn
= emit_insn (pattern
);
1972 tsize
= compute_frame_size (get_frame_size ());
1974 /* If this function is a varargs function, store any registers that
1975 would normally hold arguments ($4 - $7) on the stack. */
1976 if (store_args_on_stack
1977 && ((TYPE_ARG_TYPES (fntype
) != 0
1978 && (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype
)))
1980 || last_arg_is_vararg_marker
))
1982 int offset
= (regno
- GP_ARG_FIRST
) * UNITS_PER_WORD
;
1983 rtx ptr
= stack_pointer_rtx
;
1985 for (; regno
<= GP_ARG_LAST
; regno
++)
1988 ptr
= gen_rtx_PLUS (Pmode
, stack_pointer_rtx
, GEN_INT (offset
));
1989 emit_move_insn (gen_rtx_MEM (gpr_mode
, ptr
),
1990 gen_rtx_REG (gpr_mode
, regno
));
1992 offset
+= GET_MODE_SIZE (gpr_mode
);
1998 rtx tsize_rtx
= GEN_INT (tsize
);
1999 rtx adjustment_rtx
, insn
, dwarf_pattern
;
2003 adjustment_rtx
= gen_rtx_REG (Pmode
, IQ2000_TEMP1_REGNUM
);
2004 emit_move_insn (adjustment_rtx
, tsize_rtx
);
2007 adjustment_rtx
= tsize_rtx
;
2009 insn
= emit_insn (gen_subsi3 (stack_pointer_rtx
, stack_pointer_rtx
,
2012 dwarf_pattern
= gen_rtx_SET (Pmode
, stack_pointer_rtx
,
2013 plus_constant (stack_pointer_rtx
, -tsize
));
2015 iq2000_annotate_frame_insn (insn
, dwarf_pattern
);
2017 save_restore_insns (1);
2019 if (frame_pointer_needed
)
2023 insn
= emit_insn (gen_movsi (hard_frame_pointer_rtx
,
2024 stack_pointer_rtx
));
2027 RTX_FRAME_RELATED_P (insn
) = 1;
2031 emit_insn (gen_blockage ());
2034 /* Expand the epilogue into a bunch of separate insns. */
2037 iq2000_expand_epilogue (void)
2039 HOST_WIDE_INT tsize
= cfun
->machine
->total_size
;
2040 rtx tsize_rtx
= GEN_INT (tsize
);
2041 rtx tmp_rtx
= (rtx
)0;
2043 if (iq2000_can_use_return_insn ())
2045 emit_jump_insn (gen_return ());
2051 tmp_rtx
= gen_rtx_REG (Pmode
, IQ2000_TEMP1_REGNUM
);
2052 emit_move_insn (tmp_rtx
, tsize_rtx
);
2053 tsize_rtx
= tmp_rtx
;
2058 if (frame_pointer_needed
)
2060 emit_insn (gen_blockage ());
2062 emit_insn (gen_movsi (stack_pointer_rtx
, hard_frame_pointer_rtx
));
2065 save_restore_insns (0);
2067 if (crtl
->calls_eh_return
)
2069 rtx eh_ofs
= EH_RETURN_STACKADJ_RTX
;
2070 emit_insn (gen_addsi3 (eh_ofs
, eh_ofs
, tsize_rtx
));
2074 emit_insn (gen_blockage ());
2076 if (tsize
!= 0 || crtl
->calls_eh_return
)
2078 emit_insn (gen_addsi3 (stack_pointer_rtx
, stack_pointer_rtx
,
2083 if (crtl
->calls_eh_return
)
2085 /* Perform the additional bump for __throw. */
2086 emit_move_insn (gen_rtx_REG (Pmode
, HARD_FRAME_POINTER_REGNUM
),
2088 emit_insn (gen_rtx_USE (VOIDmode
, gen_rtx_REG (Pmode
,
2089 HARD_FRAME_POINTER_REGNUM
)));
2090 emit_jump_insn (gen_eh_return_internal ());
2093 emit_jump_insn (gen_return_internal (gen_rtx_REG (Pmode
,
2094 GP_REG_FIRST
+ 31)));
2098 iq2000_expand_eh_return (rtx address
)
2100 HOST_WIDE_INT gp_offset
= cfun
->machine
->gp_sp_offset
;
2103 scratch
= plus_constant (stack_pointer_rtx
, gp_offset
);
2104 emit_move_insn (gen_rtx_MEM (GET_MODE (address
), scratch
), address
);
2107 /* Return nonzero if this function is known to have a null epilogue.
2108 This allows the optimizer to omit jumps to jumps if no stack
2112 iq2000_can_use_return_insn (void)
2114 if (! reload_completed
)
2117 if (df_regs_ever_live_p (31) || profile_flag
)
2120 if (cfun
->machine
->initialized
)
2121 return cfun
->machine
->total_size
== 0;
2123 return compute_frame_size (get_frame_size ()) == 0;
2126 /* Returns nonzero if X contains a SYMBOL_REF. */
2129 symbolic_expression_p (rtx x
)
2131 if (GET_CODE (x
) == SYMBOL_REF
)
2134 if (GET_CODE (x
) == CONST
)
2135 return symbolic_expression_p (XEXP (x
, 0));
2138 return symbolic_expression_p (XEXP (x
, 0));
2140 if (ARITHMETIC_P (x
))
2141 return (symbolic_expression_p (XEXP (x
, 0))
2142 || symbolic_expression_p (XEXP (x
, 1)));
2147 /* Choose the section to use for the constant rtx expression X that has
2151 iq2000_select_rtx_section (enum machine_mode mode
, rtx x ATTRIBUTE_UNUSED
,
2152 unsigned HOST_WIDE_INT align
)
2154 /* For embedded applications, always put constants in read-only data,
2155 in order to reduce RAM usage. */
2156 return mergeable_constant_section (mode
, align
, 0);
2159 /* Choose the section to use for DECL. RELOC is true if its value contains
2160 any relocatable expression.
2162 Some of the logic used here needs to be replicated in
2163 ENCODE_SECTION_INFO in iq2000.h so that references to these symbols
2164 are done correctly. */
2167 iq2000_select_section (tree decl
, int reloc ATTRIBUTE_UNUSED
,
2168 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED
)
2170 if (TARGET_EMBEDDED_DATA
)
2172 /* For embedded applications, always put an object in read-only data
2173 if possible, in order to reduce RAM usage. */
2174 if ((TREE_CODE (decl
) == VAR_DECL
2175 && TREE_READONLY (decl
) && !TREE_SIDE_EFFECTS (decl
)
2176 && DECL_INITIAL (decl
)
2177 && (DECL_INITIAL (decl
) == error_mark_node
2178 || TREE_CONSTANT (DECL_INITIAL (decl
))))
2179 /* Deal with calls from output_constant_def_contents. */
2180 || TREE_CODE (decl
) != VAR_DECL
)
2181 return readonly_data_section
;
2183 return data_section
;
2187 /* For hosted applications, always put an object in small data if
2188 possible, as this gives the best performance. */
2189 if ((TREE_CODE (decl
) == VAR_DECL
2190 && TREE_READONLY (decl
) && !TREE_SIDE_EFFECTS (decl
)
2191 && DECL_INITIAL (decl
)
2192 && (DECL_INITIAL (decl
) == error_mark_node
2193 || TREE_CONSTANT (DECL_INITIAL (decl
))))
2194 /* Deal with calls from output_constant_def_contents. */
2195 || TREE_CODE (decl
) != VAR_DECL
)
2196 return readonly_data_section
;
2198 return data_section
;
2201 /* Return register to use for a function return value with VALTYPE for function
2205 iq2000_function_value (const_tree valtype
, const_tree func ATTRIBUTE_UNUSED
)
2207 int reg
= GP_RETURN
;
2208 enum machine_mode mode
= TYPE_MODE (valtype
);
2209 int unsignedp
= TYPE_UNSIGNED (valtype
);
2211 /* Since we define TARGET_PROMOTE_FUNCTION_RETURN that returns true,
2212 we must promote the mode just as PROMOTE_MODE does. */
2213 mode
= promote_mode (valtype
, mode
, &unsignedp
, 1);
2215 return gen_rtx_REG (mode
, reg
);
2218 /* Return true when an argument must be passed by reference. */
2221 iq2000_pass_by_reference (CUMULATIVE_ARGS
*cum
, enum machine_mode mode
,
2222 const_tree type
, bool named ATTRIBUTE_UNUSED
)
2226 /* We must pass by reference if we would be both passing in registers
2227 and the stack. This is because any subsequent partial arg would be
2228 handled incorrectly in this case. */
2229 if (cum
&& targetm
.calls
.must_pass_in_stack (mode
, type
))
2231 /* Don't pass the actual CUM to FUNCTION_ARG, because we would
2232 get double copies of any offsets generated for small structs
2233 passed in registers. */
2234 CUMULATIVE_ARGS temp
;
2237 if (FUNCTION_ARG (temp
, mode
, type
, named
) != 0)
2241 if (type
== NULL_TREE
|| mode
== DImode
|| mode
== DFmode
)
2244 size
= int_size_in_bytes (type
);
2245 return size
== -1 || size
> UNITS_PER_WORD
;
2248 /* Return the length of INSN. LENGTH is the initial length computed by
2249 attributes in the machine-description file. */
2252 iq2000_adjust_insn_length (rtx insn
, int length
)
2254 /* A unconditional jump has an unfilled delay slot if it is not part
2255 of a sequence. A conditional jump normally has a delay slot. */
2256 if (simplejump_p (insn
)
2257 || ( (GET_CODE (insn
) == JUMP_INSN
2258 || GET_CODE (insn
) == CALL_INSN
)))
2264 /* Output assembly instructions to perform a conditional branch.
2266 INSN is the branch instruction. OPERANDS[0] is the condition.
2267 OPERANDS[1] is the target of the branch. OPERANDS[2] is the target
2268 of the first operand to the condition. If TWO_OPERANDS_P is
2269 nonzero the comparison takes two operands; OPERANDS[3] will be the
2272 If INVERTED_P is nonzero we are to branch if the condition does
2273 not hold. If FLOAT_P is nonzero this is a floating-point comparison.
2275 LENGTH is the length (in bytes) of the sequence we are to generate.
2276 That tells us whether to generate a simple conditional branch, or a
2277 reversed conditional branch around a `jr' instruction. */
2280 iq2000_output_conditional_branch (rtx insn
, rtx
* operands
, int two_operands_p
,
2281 int float_p
, int inverted_p
, int length
)
2283 static char buffer
[200];
2284 /* The kind of comparison we are doing. */
2285 enum rtx_code code
= GET_CODE (operands
[0]);
2286 /* Nonzero if the opcode for the comparison needs a `z' indicating
2287 that it is a comparison against zero. */
2289 /* A string to use in the assembly output to represent the first
2291 const char *op1
= "%z2";
2292 /* A string to use in the assembly output to represent the second
2293 operand. Use the hard-wired zero register if there's no second
2295 const char *op2
= (two_operands_p
? ",%z3" : ",%.");
2296 /* The operand-printing string for the comparison. */
2297 const char *comp
= (float_p
? "%F0" : "%C0");
2298 /* The operand-printing string for the inverted comparison. */
2299 const char *inverted_comp
= (float_p
? "%W0" : "%N0");
2301 /* Likely variants of each branch instruction annul the instruction
2302 in the delay slot if the branch is not taken. */
2303 iq2000_branch_likely
= (final_sequence
&& INSN_ANNULLED_BRANCH_P (insn
));
2305 if (!two_operands_p
)
2307 /* To compute whether than A > B, for example, we normally
2308 subtract B from A and then look at the sign bit. But, if we
2309 are doing an unsigned comparison, and B is zero, we don't
2310 have to do the subtraction. Instead, we can just check to
2311 see if A is nonzero. Thus, we change the CODE here to
2312 reflect the simpler comparison operation. */
2324 /* A condition which will always be true. */
2330 /* A condition which will always be false. */
2336 /* Not a special case. */
2341 /* Relative comparisons are always done against zero. But
2342 equality comparisons are done between two operands, and therefore
2343 do not require a `z' in the assembly language output. */
2344 need_z_p
= (!float_p
&& code
!= EQ
&& code
!= NE
);
2345 /* For comparisons against zero, the zero is not provided
2350 /* Begin by terminating the buffer. That way we can always use
2351 strcat to add to it. */
2358 /* Just a simple conditional branch. */
2360 sprintf (buffer
, "b%s%%?\t%%Z2%%1",
2361 inverted_p
? inverted_comp
: comp
);
2363 sprintf (buffer
, "b%s%s%%?\t%s%s,%%1",
2364 inverted_p
? inverted_comp
: comp
,
2365 need_z_p
? "z" : "",
2373 /* Generate a reversed conditional branch around ` j'
2385 Because we have to jump four bytes *past* the following
2386 instruction if this branch was annulled, we can't just use
2387 a label, as in the picture above; there's no way to put the
2388 label after the next instruction, as the assembler does not
2389 accept `.L+4' as the target of a branch. (We can't just
2390 wait until the next instruction is output; it might be a
2391 macro and take up more than four bytes. Once again, we see
2392 why we want to eliminate macros.)
2394 If the branch is annulled, we jump four more bytes that we
2395 would otherwise; that way we skip the annulled instruction
2396 in the delay slot. */
2399 = ((iq2000_branch_likely
|| length
== 16) ? ".+16" : ".+12");
2402 c
= strchr (buffer
, '\0');
2403 /* Generate the reversed comparison. This takes four
2406 sprintf (c
, "b%s\t%%Z2%s",
2407 inverted_p
? comp
: inverted_comp
,
2410 sprintf (c
, "b%s%s\t%s%s,%s",
2411 inverted_p
? comp
: inverted_comp
,
2412 need_z_p
? "z" : "",
2416 strcat (c
, "\n\tnop\n\tj\t%1");
2418 /* The delay slot was unfilled. Since we're inside
2419 .noreorder, the assembler will not fill in the NOP for
2420 us, so we must do it ourselves. */
2421 strcat (buffer
, "\n\tnop");
2433 #define def_builtin(NAME, TYPE, CODE) \
2434 add_builtin_function ((NAME), (TYPE), (CODE), BUILT_IN_MD, \
2438 iq2000_init_builtins (void)
2440 tree endlink
= void_list_node
;
2441 tree void_ftype
, void_ftype_int
, void_ftype_int_int
;
2442 tree void_ftype_int_int_int
;
2443 tree int_ftype_int
, int_ftype_int_int
, int_ftype_int_int_int
;
2444 tree int_ftype_int_int_int_int
;
2448 = build_function_type (void_type_node
,
2449 tree_cons (NULL_TREE
, void_type_node
, endlink
));
2453 = build_function_type (void_type_node
,
2454 tree_cons (NULL_TREE
, integer_type_node
, endlink
));
2456 /* void func (int, int) */
2458 = build_function_type (void_type_node
,
2459 tree_cons (NULL_TREE
, integer_type_node
,
2460 tree_cons (NULL_TREE
, integer_type_node
,
2463 /* int func (int) */
2465 = build_function_type (integer_type_node
,
2466 tree_cons (NULL_TREE
, integer_type_node
, endlink
));
2468 /* int func (int, int) */
2470 = build_function_type (integer_type_node
,
2471 tree_cons (NULL_TREE
, integer_type_node
,
2472 tree_cons (NULL_TREE
, integer_type_node
,
2475 /* void func (int, int, int) */
2476 void_ftype_int_int_int
2477 = build_function_type
2479 tree_cons (NULL_TREE
, integer_type_node
,
2480 tree_cons (NULL_TREE
, integer_type_node
,
2481 tree_cons (NULL_TREE
,
2485 /* int func (int, int, int, int) */
2486 int_ftype_int_int_int_int
2487 = build_function_type
2489 tree_cons (NULL_TREE
, integer_type_node
,
2490 tree_cons (NULL_TREE
, integer_type_node
,
2491 tree_cons (NULL_TREE
,
2493 tree_cons (NULL_TREE
,
2497 /* int func (int, int, int) */
2498 int_ftype_int_int_int
2499 = build_function_type
2501 tree_cons (NULL_TREE
, integer_type_node
,
2502 tree_cons (NULL_TREE
, integer_type_node
,
2503 tree_cons (NULL_TREE
,
2507 /* int func (int, int, int, int) */
2508 int_ftype_int_int_int_int
2509 = build_function_type
2511 tree_cons (NULL_TREE
, integer_type_node
,
2512 tree_cons (NULL_TREE
, integer_type_node
,
2513 tree_cons (NULL_TREE
,
2515 tree_cons (NULL_TREE
,
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 enum 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_expr (arg
[i
], NULL_RTX
, VOIDmode
, 0);
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
);
2609 pat
= GEN_FCN (icode
) (target
, op
[0]);
2611 pat
= GEN_FCN (icode
) (op
[0]);
2615 pat
= GEN_FCN (icode
) (target
, op
[0], op
[1]);
2617 pat
= GEN_FCN (icode
) (op
[0], op
[1]);
2621 pat
= GEN_FCN (icode
) (target
, op
[0], op
[1], op
[2]);
2623 pat
= GEN_FCN (icode
) (op
[0], op
[1], op
[2]);
2627 pat
= GEN_FCN (icode
) (target
, op
[0], op
[1], op
[2], op
[3]);
2629 pat
= GEN_FCN (icode
) (op
[0], op
[1], op
[2], op
[3]);
2641 /* Expand an expression EXP that calls a built-in function,
2642 with result going to TARGET if that's convenient
2643 (and in mode MODE if that's convenient).
2644 SUBTARGET may be used as the target for computing one of EXP's operands.
2645 IGNORE is nonzero if the value is to be ignored. */
2648 iq2000_expand_builtin (tree exp
, rtx target
, rtx subtarget ATTRIBUTE_UNUSED
,
2649 enum machine_mode mode ATTRIBUTE_UNUSED
,
2650 int ignore ATTRIBUTE_UNUSED
)
2652 tree fndecl
= TREE_OPERAND (CALL_EXPR_FN (exp
), 0);
2653 int fcode
= DECL_FUNCTION_CODE (fndecl
);
2654 enum rtx_code code
[5];
2666 case IQ2000_BUILTIN_ADO16
:
2667 return expand_one_builtin (CODE_FOR_ado16
, target
, exp
, code
, 2);
2669 case IQ2000_BUILTIN_RAM
:
2670 code
[1] = CONST_INT
;
2671 code
[2] = CONST_INT
;
2672 code
[3] = CONST_INT
;
2673 return expand_one_builtin (CODE_FOR_ram
, target
, exp
, code
, 4);
2675 case IQ2000_BUILTIN_CHKHDR
:
2676 return expand_one_builtin (CODE_FOR_chkhdr
, target
, exp
, code
, 2);
2678 case IQ2000_BUILTIN_PKRL
:
2679 return expand_one_builtin (CODE_FOR_pkrl
, target
, exp
, code
, 2);
2681 case IQ2000_BUILTIN_CFC0
:
2682 code
[0] = CONST_INT
;
2683 return expand_one_builtin (CODE_FOR_cfc0
, target
, exp
, code
, 1);
2685 case IQ2000_BUILTIN_CFC1
:
2686 code
[0] = CONST_INT
;
2687 return expand_one_builtin (CODE_FOR_cfc1
, target
, exp
, code
, 1);
2689 case IQ2000_BUILTIN_CFC2
:
2690 code
[0] = CONST_INT
;
2691 return expand_one_builtin (CODE_FOR_cfc2
, target
, exp
, code
, 1);
2693 case IQ2000_BUILTIN_CFC3
:
2694 code
[0] = CONST_INT
;
2695 return expand_one_builtin (CODE_FOR_cfc3
, target
, exp
, code
, 1);
2697 case IQ2000_BUILTIN_CTC0
:
2698 code
[1] = CONST_INT
;
2699 return expand_one_builtin (CODE_FOR_ctc0
, target
, exp
, code
, 2);
2701 case IQ2000_BUILTIN_CTC1
:
2702 code
[1] = CONST_INT
;
2703 return expand_one_builtin (CODE_FOR_ctc1
, target
, exp
, code
, 2);
2705 case IQ2000_BUILTIN_CTC2
:
2706 code
[1] = CONST_INT
;
2707 return expand_one_builtin (CODE_FOR_ctc2
, target
, exp
, code
, 2);
2709 case IQ2000_BUILTIN_CTC3
:
2710 code
[1] = CONST_INT
;
2711 return expand_one_builtin (CODE_FOR_ctc3
, target
, exp
, code
, 2);
2713 case IQ2000_BUILTIN_MFC0
:
2714 code
[0] = CONST_INT
;
2715 return expand_one_builtin (CODE_FOR_mfc0
, target
, exp
, code
, 1);
2717 case IQ2000_BUILTIN_MFC1
:
2718 code
[0] = CONST_INT
;
2719 return expand_one_builtin (CODE_FOR_mfc1
, target
, exp
, code
, 1);
2721 case IQ2000_BUILTIN_MFC2
:
2722 code
[0] = CONST_INT
;
2723 return expand_one_builtin (CODE_FOR_mfc2
, target
, exp
, code
, 1);
2725 case IQ2000_BUILTIN_MFC3
:
2726 code
[0] = CONST_INT
;
2727 return expand_one_builtin (CODE_FOR_mfc3
, target
, exp
, code
, 1);
2729 case IQ2000_BUILTIN_MTC0
:
2730 code
[1] = CONST_INT
;
2731 return expand_one_builtin (CODE_FOR_mtc0
, target
, exp
, code
, 2);
2733 case IQ2000_BUILTIN_MTC1
:
2734 code
[1] = CONST_INT
;
2735 return expand_one_builtin (CODE_FOR_mtc1
, target
, exp
, code
, 2);
2737 case IQ2000_BUILTIN_MTC2
:
2738 code
[1] = CONST_INT
;
2739 return expand_one_builtin (CODE_FOR_mtc2
, target
, exp
, code
, 2);
2741 case IQ2000_BUILTIN_MTC3
:
2742 code
[1] = CONST_INT
;
2743 return expand_one_builtin (CODE_FOR_mtc3
, target
, exp
, code
, 2);
2745 case IQ2000_BUILTIN_LUR
:
2746 return expand_one_builtin (CODE_FOR_lur
, target
, exp
, code
, 2);
2748 case IQ2000_BUILTIN_RB
:
2749 return expand_one_builtin (CODE_FOR_rb
, target
, exp
, code
, 2);
2751 case IQ2000_BUILTIN_RX
:
2752 return expand_one_builtin (CODE_FOR_rx
, target
, exp
, code
, 2);
2754 case IQ2000_BUILTIN_SRRD
:
2755 return expand_one_builtin (CODE_FOR_srrd
, target
, exp
, code
, 1);
2757 case IQ2000_BUILTIN_SRWR
:
2758 return expand_one_builtin (CODE_FOR_srwr
, target
, exp
, code
, 2);
2760 case IQ2000_BUILTIN_WB
:
2761 return expand_one_builtin (CODE_FOR_wb
, target
, exp
, code
, 2);
2763 case IQ2000_BUILTIN_WX
:
2764 return expand_one_builtin (CODE_FOR_wx
, target
, exp
, code
, 2);
2766 case IQ2000_BUILTIN_LUC32L
:
2767 return expand_one_builtin (CODE_FOR_luc32l
, target
, exp
, code
, 2);
2769 case IQ2000_BUILTIN_LUC64
:
2770 return expand_one_builtin (CODE_FOR_luc64
, target
, exp
, code
, 2);
2772 case IQ2000_BUILTIN_LUC64L
:
2773 return expand_one_builtin (CODE_FOR_luc64l
, target
, exp
, code
, 2);
2775 case IQ2000_BUILTIN_LUK
:
2776 return expand_one_builtin (CODE_FOR_luk
, target
, exp
, code
, 2);
2778 case IQ2000_BUILTIN_LULCK
:
2779 return expand_one_builtin (CODE_FOR_lulck
, target
, exp
, code
, 1);
2781 case IQ2000_BUILTIN_LUM32
:
2782 return expand_one_builtin (CODE_FOR_lum32
, target
, exp
, code
, 2);
2784 case IQ2000_BUILTIN_LUM32L
:
2785 return expand_one_builtin (CODE_FOR_lum32l
, target
, exp
, code
, 2);
2787 case IQ2000_BUILTIN_LUM64
:
2788 return expand_one_builtin (CODE_FOR_lum64
, target
, exp
, code
, 2);
2790 case IQ2000_BUILTIN_LUM64L
:
2791 return expand_one_builtin (CODE_FOR_lum64l
, target
, exp
, code
, 2);
2793 case IQ2000_BUILTIN_LURL
:
2794 return expand_one_builtin (CODE_FOR_lurl
, target
, exp
, code
, 2);
2796 case IQ2000_BUILTIN_MRGB
:
2797 code
[2] = CONST_INT
;
2798 return expand_one_builtin (CODE_FOR_mrgb
, target
, exp
, code
, 3);
2800 case IQ2000_BUILTIN_SRRDL
:
2801 return expand_one_builtin (CODE_FOR_srrdl
, target
, exp
, code
, 1);
2803 case IQ2000_BUILTIN_SRULCK
:
2804 return expand_one_builtin (CODE_FOR_srulck
, target
, exp
, code
, 1);
2806 case IQ2000_BUILTIN_SRWRU
:
2807 return expand_one_builtin (CODE_FOR_srwru
, target
, exp
, code
, 2);
2809 case IQ2000_BUILTIN_TRAPQFL
:
2810 return expand_one_builtin (CODE_FOR_trapqfl
, target
, exp
, code
, 0);
2812 case IQ2000_BUILTIN_TRAPQNE
:
2813 return expand_one_builtin (CODE_FOR_trapqne
, target
, exp
, code
, 0);
2815 case IQ2000_BUILTIN_TRAPREL
:
2816 return expand_one_builtin (CODE_FOR_traprel
, target
, exp
, code
, 1);
2818 case IQ2000_BUILTIN_WBU
:
2819 return expand_one_builtin (CODE_FOR_wbu
, target
, exp
, code
, 3);
2821 case IQ2000_BUILTIN_SYSCALL
:
2822 return expand_one_builtin (CODE_FOR_syscall
, target
, exp
, code
, 0);
2828 /* Worker function for TARGET_RETURN_IN_MEMORY. */
2831 iq2000_return_in_memory (const_tree type
, const_tree fntype ATTRIBUTE_UNUSED
)
2833 return ((int_size_in_bytes (type
) > (2 * UNITS_PER_WORD
))
2834 || (int_size_in_bytes (type
) == -1));
2837 /* Worker function for TARGET_SETUP_INCOMING_VARARGS. */
2840 iq2000_setup_incoming_varargs (CUMULATIVE_ARGS
*cum
,
2841 enum machine_mode mode ATTRIBUTE_UNUSED
,
2842 tree type ATTRIBUTE_UNUSED
, int * pretend_size
,
2845 unsigned int iq2000_off
= ! cum
->last_arg_fp
;
2846 unsigned int iq2000_fp_off
= cum
->last_arg_fp
;
2848 if ((cum
->arg_words
< MAX_ARGS_IN_REGISTERS
- iq2000_off
))
2850 int iq2000_save_gp_regs
2851 = MAX_ARGS_IN_REGISTERS
- cum
->arg_words
- iq2000_off
;
2852 int iq2000_save_fp_regs
2853 = (MAX_ARGS_IN_REGISTERS
- cum
->fp_arg_words
- iq2000_fp_off
);
2855 if (iq2000_save_gp_regs
< 0)
2856 iq2000_save_gp_regs
= 0;
2857 if (iq2000_save_fp_regs
< 0)
2858 iq2000_save_fp_regs
= 0;
2860 *pretend_size
= ((iq2000_save_gp_regs
* UNITS_PER_WORD
)
2861 + (iq2000_save_fp_regs
* UNITS_PER_FPREG
));
2865 if (cum
->arg_words
< MAX_ARGS_IN_REGISTERS
- iq2000_off
)
2868 ptr
= plus_constant (virtual_incoming_args_rtx
,
2869 - (iq2000_save_gp_regs
2871 mem
= gen_rtx_MEM (BLKmode
, ptr
);
2873 (cum
->arg_words
+ GP_ARG_FIRST
+ iq2000_off
,
2875 iq2000_save_gp_regs
);
2881 /* A C compound statement to output to stdio stream STREAM the
2882 assembler syntax for an instruction operand that is a memory
2883 reference whose address is ADDR. ADDR is an RTL expression. */
2886 print_operand_address (FILE * file
, rtx addr
)
2889 error ("PRINT_OPERAND_ADDRESS, null pointer");
2892 switch (GET_CODE (addr
))
2895 if (REGNO (addr
) == ARG_POINTER_REGNUM
)
2896 abort_with_insn (addr
, "Arg pointer not eliminated.");
2898 fprintf (file
, "0(%s)", reg_names
[REGNO (addr
)]);
2903 rtx arg0
= XEXP (addr
, 0);
2904 rtx arg1
= XEXP (addr
, 1);
2906 if (GET_CODE (arg0
) != REG
)
2907 abort_with_insn (addr
,
2908 "PRINT_OPERAND_ADDRESS, LO_SUM with #1 not REG.");
2910 fprintf (file
, "%%lo(");
2911 print_operand_address (file
, arg1
);
2912 fprintf (file
, ")(%s)", reg_names
[REGNO (arg0
)]);
2920 rtx arg0
= XEXP (addr
, 0);
2921 rtx arg1
= XEXP (addr
, 1);
2923 if (GET_CODE (arg0
) == REG
)
2927 if (GET_CODE (offset
) == REG
)
2928 abort_with_insn (addr
, "PRINT_OPERAND_ADDRESS, 2 regs");
2931 else if (GET_CODE (arg1
) == REG
)
2932 reg
= arg1
, offset
= arg0
;
2933 else if (CONSTANT_P (arg0
) && CONSTANT_P (arg1
))
2935 output_addr_const (file
, addr
);
2939 abort_with_insn (addr
, "PRINT_OPERAND_ADDRESS, no regs");
2941 if (! CONSTANT_P (offset
))
2942 abort_with_insn (addr
, "PRINT_OPERAND_ADDRESS, invalid insn #2");
2944 if (REGNO (reg
) == ARG_POINTER_REGNUM
)
2945 abort_with_insn (addr
, "Arg pointer not eliminated.");
2947 output_addr_const (file
, offset
);
2948 fprintf (file
, "(%s)", reg_names
[REGNO (reg
)]);
2956 output_addr_const (file
, addr
);
2957 if (GET_CODE (addr
) == CONST_INT
)
2958 fprintf (file
, "(%s)", reg_names
[0]);
2962 abort_with_insn (addr
, "PRINT_OPERAND_ADDRESS, invalid insn #1");
2967 /* A C compound statement to output to stdio stream FILE the
2968 assembler syntax for an instruction operand OP.
2970 LETTER is a value that can be used to specify one of several ways
2971 of printing the operand. It is used when identical operands
2972 must be printed differently depending on the context. LETTER
2973 comes from the `%' specification that was used to request
2974 printing of the operand. If the specification was just `%DIGIT'
2975 then LETTER is 0; if the specification was `%LTR DIGIT' then LETTER
2976 is the ASCII code for LTR.
2978 If OP is a register, this macro should print the register's name.
2979 The names can be found in an array `reg_names' whose type is
2980 `char *[]'. `reg_names' is initialized from `REGISTER_NAMES'.
2982 When the machine description has a specification `%PUNCT' (a `%'
2983 followed by a punctuation character), this macro is called with
2984 a null pointer for X and the punctuation character for LETTER.
2986 The IQ2000 specific codes are:
2988 'X' X is CONST_INT, prints upper 16 bits in hexadecimal format = "0x%04x",
2989 'x' X is CONST_INT, prints lower 16 bits in hexadecimal format = "0x%04x",
2990 'd' output integer constant in decimal,
2991 'z' if the operand is 0, use $0 instead of normal operand.
2992 'D' print second part of double-word register or memory operand.
2993 'L' print low-order register of double-word register operand.
2994 'M' print high-order register of double-word register operand.
2995 'C' print part of opcode for a branch condition.
2996 'F' print part of opcode for a floating-point branch condition.
2997 'N' print part of opcode for a branch condition, inverted.
2998 'W' print part of opcode for a floating-point branch condition, inverted.
2999 'A' Print part of opcode for a bit test condition.
3000 'P' Print label for a bit test.
3001 'p' Print log for a bit test.
3002 'B' print 'z' for EQ, 'n' for NE
3003 'b' print 'n' for EQ, 'z' for NE
3004 'T' print 'f' for EQ, 't' for NE
3005 't' print 't' for EQ, 'f' for NE
3006 'Z' print register and a comma, but print nothing for $fcc0
3007 '?' Print 'l' if we are to use a branch likely instead of normal branch.
3008 '@' Print the name of the assembler temporary register (at or $1).
3009 '.' Print the name of the register with a hard-wired zero (zero or $0).
3010 '$' Print the name of the stack pointer register (sp or $29).
3011 '+' Print the name of the gp register (gp or $28). */
3014 print_operand (FILE *file
, rtx op
, int letter
)
3018 if (PRINT_OPERAND_PUNCT_VALID_P (letter
))
3023 if (iq2000_branch_likely
)
3028 fputs (reg_names
[GP_REG_FIRST
+ 1], file
);
3032 fputs (reg_names
[GP_REG_FIRST
+ 0], file
);
3036 fputs (reg_names
[STACK_POINTER_REGNUM
], file
);
3040 fputs (reg_names
[GP_REG_FIRST
+ 28], file
);
3044 error ("PRINT_OPERAND: Unknown punctuation '%c'", letter
);
3053 error ("PRINT_OPERAND null pointer");
3057 code
= GET_CODE (op
);
3059 if (code
== SIGN_EXTEND
)
3060 op
= XEXP (op
, 0), code
= GET_CODE (op
);
3065 case EQ
: fputs ("eq", file
); break;
3066 case NE
: fputs ("ne", file
); break;
3067 case GT
: fputs ("gt", file
); break;
3068 case GE
: fputs ("ge", file
); break;
3069 case LT
: fputs ("lt", file
); break;
3070 case LE
: fputs ("le", file
); break;
3071 case GTU
: fputs ("ne", file
); break;
3072 case GEU
: fputs ("geu", file
); break;
3073 case LTU
: fputs ("ltu", file
); break;
3074 case LEU
: fputs ("eq", file
); break;
3076 abort_with_insn (op
, "PRINT_OPERAND, invalid insn for %%C");
3079 else if (letter
== 'N')
3082 case EQ
: fputs ("ne", file
); break;
3083 case NE
: fputs ("eq", file
); break;
3084 case GT
: fputs ("le", file
); break;
3085 case GE
: fputs ("lt", file
); break;
3086 case LT
: fputs ("ge", file
); break;
3087 case LE
: fputs ("gt", file
); break;
3088 case GTU
: fputs ("leu", file
); break;
3089 case GEU
: fputs ("ltu", file
); break;
3090 case LTU
: fputs ("geu", file
); break;
3091 case LEU
: fputs ("gtu", file
); break;
3093 abort_with_insn (op
, "PRINT_OPERAND, invalid insn for %%N");
3096 else if (letter
== 'F')
3099 case EQ
: fputs ("c1f", file
); break;
3100 case NE
: fputs ("c1t", file
); break;
3102 abort_with_insn (op
, "PRINT_OPERAND, invalid insn for %%F");
3105 else if (letter
== 'W')
3108 case EQ
: fputs ("c1t", file
); break;
3109 case NE
: fputs ("c1f", file
); break;
3111 abort_with_insn (op
, "PRINT_OPERAND, invalid insn for %%W");
3114 else if (letter
== 'A')
3115 fputs (code
== LABEL_REF
? "i" : "in", file
);
3117 else if (letter
== 'P')
3119 if (code
== LABEL_REF
)
3120 output_addr_const (file
, op
);
3121 else if (code
!= PC
)
3122 output_operand_lossage ("invalid %%P operand");
3125 else if (letter
== 'p')
3128 if (code
!= CONST_INT
3129 || (value
= exact_log2 (INTVAL (op
))) < 0)
3130 output_operand_lossage ("invalid %%p value");
3131 fprintf (file
, "%d", value
);
3134 else if (letter
== 'Z')
3139 else if (code
== REG
|| code
== SUBREG
)
3144 regnum
= REGNO (op
);
3146 regnum
= true_regnum (op
);
3148 if ((letter
== 'M' && ! WORDS_BIG_ENDIAN
)
3149 || (letter
== 'L' && WORDS_BIG_ENDIAN
)
3153 fprintf (file
, "%s", reg_names
[regnum
]);
3156 else if (code
== MEM
)
3159 output_address (plus_constant (XEXP (op
, 0), 4));
3161 output_address (XEXP (op
, 0));
3164 else if (code
== CONST_DOUBLE
3165 && GET_MODE_CLASS (GET_MODE (op
)) == MODE_FLOAT
)
3169 real_to_decimal (s
, CONST_DOUBLE_REAL_VALUE (op
), sizeof (s
), 0, 1);
3173 else if (letter
== 'x' && GET_CODE (op
) == CONST_INT
)
3174 fprintf (file
, HOST_WIDE_INT_PRINT_HEX
, 0xffff & INTVAL(op
));
3176 else if (letter
== 'X' && GET_CODE(op
) == CONST_INT
)
3177 fprintf (file
, HOST_WIDE_INT_PRINT_HEX
, 0xffff & (INTVAL (op
) >> 16));
3179 else if (letter
== 'd' && GET_CODE(op
) == CONST_INT
)
3180 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, (INTVAL(op
)));
3182 else if (letter
== 'z' && GET_CODE (op
) == CONST_INT
&& INTVAL (op
) == 0)
3183 fputs (reg_names
[GP_REG_FIRST
], file
);
3185 else if (letter
== 'd' || letter
== 'x' || letter
== 'X')
3186 output_operand_lossage ("invalid use of %%d, %%x, or %%X");
3188 else if (letter
== 'B')
3189 fputs (code
== EQ
? "z" : "n", file
);
3190 else if (letter
== 'b')
3191 fputs (code
== EQ
? "n" : "z", file
);
3192 else if (letter
== 'T')
3193 fputs (code
== EQ
? "f" : "t", file
);
3194 else if (letter
== 't')
3195 fputs (code
== EQ
? "t" : "f", file
);
3197 else if (code
== CONST
&& GET_CODE (XEXP (op
, 0)) == REG
)
3199 print_operand (file
, XEXP (op
, 0), letter
);
3203 output_addr_const (file
, op
);
3207 iq2000_rtx_costs (rtx x
, int code
, int outer_code ATTRIBUTE_UNUSED
, int * total
)
3209 enum machine_mode mode
= GET_MODE (x
);
3215 int num_words
= (GET_MODE_SIZE (mode
) > UNITS_PER_WORD
) ? 2 : 1;
3217 if (simple_memory_operand (x
, mode
))
3218 return COSTS_N_INSNS (num_words
);
3220 * total
= COSTS_N_INSNS (2 * num_words
);
3225 * total
= COSTS_N_INSNS (6);
3232 * total
= COSTS_N_INSNS (mode
== DImode
? 2 : 1);
3239 * total
= COSTS_N_INSNS ((GET_CODE (XEXP (x
, 1)) == CONST_INT
) ? 4 : 12);
3241 * total
= COSTS_N_INSNS (1);
3245 if (mode
== SFmode
|| mode
== DFmode
)
3246 * total
= COSTS_N_INSNS (1);
3248 * total
= COSTS_N_INSNS (4);
3253 if (mode
== SFmode
|| mode
== DFmode
)
3254 * total
= COSTS_N_INSNS (6);
3255 else if (mode
== DImode
)
3256 * total
= COSTS_N_INSNS (4);
3258 * total
= COSTS_N_INSNS (1);
3262 * total
= (mode
== DImode
) ? 4 : 1;
3267 * total
= COSTS_N_INSNS (7);
3268 else if (mode
== DFmode
)
3269 * total
= COSTS_N_INSNS (8);
3271 * total
= COSTS_N_INSNS (10);
3277 * total
= COSTS_N_INSNS (23);
3278 else if (mode
== DFmode
)
3279 * total
= COSTS_N_INSNS (36);
3281 * total
= COSTS_N_INSNS (69);
3286 * total
= COSTS_N_INSNS (69);
3290 * total
= COSTS_N_INSNS (2);
3294 * total
= COSTS_N_INSNS (1);
3302 * total
= COSTS_N_INSNS (2);
3307 rtx offset
= const0_rtx
;
3308 rtx symref
= eliminate_constant_term (XEXP (x
, 0), & offset
);
3310 if (GET_CODE (symref
) == LABEL_REF
)
3311 * total
= COSTS_N_INSNS (2);
3312 else if (GET_CODE (symref
) != SYMBOL_REF
)
3313 * total
= COSTS_N_INSNS (4);
3314 /* Let's be paranoid.... */
3315 else if (INTVAL (offset
) < -32768 || INTVAL (offset
) > 32767)
3316 * total
= COSTS_N_INSNS (2);
3318 * total
= COSTS_N_INSNS (SYMBOL_REF_FLAG (symref
) ? 1 : 2);
3323 * total
= COSTS_N_INSNS (SYMBOL_REF_FLAG (x
) ? 1 : 2);
3330 split_double (x
, & high
, & low
);
3332 * total
= COSTS_N_INSNS ( (high
== CONST0_RTX (GET_MODE (high
))
3333 || low
== CONST0_RTX (GET_MODE (low
)))
3344 #include "gt-iq2000.h"