1 /* Subroutines used for code generation on Vitesse IQ2000 processors
2 Copyright (C) 2003, 2004 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 2, 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 COPYING. If not, write to
18 the Free Software Foundation, 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA. */
23 #include "coretypes.h"
29 #include "hard-reg-set.h"
31 #include "insn-config.h"
32 #include "conditions.h"
34 #include "insn-attr.h"
47 #include "target-def.h"
48 #include "langhooks.h"
50 /* Enumeration for all of the relational tests, so that we can build
51 arrays indexed by the test type, and not worry about the order
72 /* Structure to be filled in by compute_frame_size with register
73 save masks, and offsets for the current function. */
75 struct iq2000_frame_info
77 long total_size
; /* # bytes that the entire frame takes up. */
78 long var_size
; /* # bytes that variables take up. */
79 long args_size
; /* # bytes that outgoing arguments take up. */
80 long extra_size
; /* # bytes of extra gunk. */
81 int gp_reg_size
; /* # bytes needed to store gp regs. */
82 int fp_reg_size
; /* # bytes needed to store fp regs. */
83 long mask
; /* Mask of saved gp registers. */
84 long gp_save_offset
; /* Offset from vfp to store gp registers. */
85 long fp_save_offset
; /* Offset from vfp to store fp registers. */
86 long gp_sp_offset
; /* Offset from new sp to store gp registers. */
87 long fp_sp_offset
; /* Offset from new sp to store fp registers. */
88 int initialized
; /* != 0 if frame size already calculated. */
89 int num_gp
; /* Number of gp registers saved. */
92 struct machine_function
GTY(())
94 /* Current frame information, calculated by compute_frame_size. */
95 long total_size
; /* # bytes that the entire frame takes up. */
96 long var_size
; /* # bytes that variables take up. */
97 long args_size
; /* # bytes that outgoing arguments take up. */
98 long extra_size
; /* # bytes of extra gunk. */
99 int gp_reg_size
; /* # bytes needed to store gp regs. */
100 int fp_reg_size
; /* # bytes needed to store fp regs. */
101 long mask
; /* Mask of saved gp registers. */
102 long gp_save_offset
; /* Offset from vfp to store gp registers. */
103 long fp_save_offset
; /* Offset from vfp to store fp registers. */
104 long gp_sp_offset
; /* Offset from new sp to store gp registers. */
105 long fp_sp_offset
; /* Offset from new sp to store fp registers. */
106 int initialized
; /* != 0 if frame size already calculated. */
107 int num_gp
; /* Number of gp registers saved. */
110 /* Global variables for machine-dependent things. */
112 /* List of all IQ2000 punctuation characters used by print_operand. */
113 char iq2000_print_operand_punct
[256];
115 /* The target cpu for optimization and scheduling. */
116 enum processor_type iq2000_tune
;
118 /* Which instruction set architecture to use. */
121 /* Cached operands, and operator to compare for use in set/branch/trap
122 on condition codes. */
125 /* What type of branch to use. */
126 enum cmp_type branch_type
;
128 /* Strings to hold which cpu and instruction set architecture to use. */
129 const char * iq2000_cpu_string
; /* For -mcpu=<xxx>. */
130 const char * iq2000_arch_string
; /* For -march=<xxx>. */
133 /* Local variables. */
135 /* The next branch instruction is a branch likely, not branch normal. */
136 static int iq2000_branch_likely
;
138 /* Count of delay slots and how many are filled. */
139 static int dslots_load_total
;
140 static int dslots_load_filled
;
141 static int dslots_jump_total
;
143 /* # of nops needed by previous insn. */
144 static int dslots_number_nops
;
146 /* Number of 1/2/3 word references to data items (i.e., not jal's). */
147 static int num_refs
[3];
149 /* Registers to check for load delay. */
150 static rtx iq2000_load_reg
;
151 static rtx iq2000_load_reg2
;
152 static rtx iq2000_load_reg3
;
153 static rtx iq2000_load_reg4
;
155 /* The target cpu for code generation. */
156 static enum processor_type iq2000_arch
;
158 /* Mode used for saving/restoring general purpose registers. */
159 static enum machine_mode gpr_mode
;
162 /* Initialize the GCC target structure. */
163 static struct machine_function
* iq2000_init_machine_status (void);
164 static void iq2000_select_rtx_section (enum machine_mode
, rtx
, unsigned HOST_WIDE_INT
);
165 static void iq2000_init_builtins (void);
166 static rtx
iq2000_expand_builtin (tree
, rtx
, rtx
, enum machine_mode
, int);
167 static bool iq2000_return_in_memory (tree
, tree
);
168 static void iq2000_setup_incoming_varargs (CUMULATIVE_ARGS
*,
169 enum machine_mode
, tree
, int *,
171 static bool iq2000_rtx_costs (rtx
, int, int, int *);
172 static int iq2000_address_cost (rtx
);
173 static void iq2000_select_section (tree
, int, unsigned HOST_WIDE_INT
);
174 static bool iq2000_return_in_memory (tree
, tree
);
175 static bool iq2000_pass_by_reference (CUMULATIVE_ARGS
*, enum machine_mode
,
177 static int iq2000_arg_partial_bytes (CUMULATIVE_ARGS
*, enum machine_mode
,
180 #undef TARGET_INIT_BUILTINS
181 #define TARGET_INIT_BUILTINS iq2000_init_builtins
182 #undef TARGET_EXPAND_BUILTIN
183 #define TARGET_EXPAND_BUILTIN iq2000_expand_builtin
184 #undef TARGET_ASM_SELECT_RTX_SECTION
185 #define TARGET_ASM_SELECT_RTX_SECTION iq2000_select_rtx_section
186 #undef TARGET_RTX_COSTS
187 #define TARGET_RTX_COSTS iq2000_rtx_costs
188 #undef TARGET_ADDRESS_COST
189 #define TARGET_ADDRESS_COST iq2000_address_cost
190 #undef TARGET_ASM_SELECT_SECTION
191 #define TARGET_ASM_SELECT_SECTION iq2000_select_section
193 #undef TARGET_PROMOTE_FUNCTION_ARGS
194 #define TARGET_PROMOTE_FUNCTION_ARGS hook_bool_tree_true
195 #undef TARGET_PROMOTE_FUNCTION_RETURN
196 #define TARGET_PROMOTE_FUNCTION_RETURN hook_bool_tree_true
197 #undef TARGET_PROMOTE_PROTOTYPES
198 #define TARGET_PROMOTE_PROTOTYPES hook_bool_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 struct gcc_target targetm
= TARGET_INITIALIZER
;
216 /* Return 1 if OP can be used as an operand where a register or 16 bit unsigned
217 integer is needed. */
220 uns_arith_operand (rtx op
, enum machine_mode mode
)
222 if (GET_CODE (op
) == CONST_INT
&& SMALL_INT_UNSIGNED (op
))
225 return register_operand (op
, mode
);
228 /* Return 1 if OP can be used as an operand where a 16 bit integer is needed. */
231 arith_operand (rtx op
, enum machine_mode mode
)
233 if (GET_CODE (op
) == CONST_INT
&& SMALL_INT (op
))
236 return register_operand (op
, mode
);
239 /* Return 1 if OP is a integer which fits in 16 bits. */
242 small_int (rtx op
, enum machine_mode mode ATTRIBUTE_UNUSED
)
244 return (GET_CODE (op
) == CONST_INT
&& SMALL_INT (op
));
247 /* Return 1 if OP is a 32 bit integer which is too big to be loaded with one
251 large_int (rtx op
, enum machine_mode mode ATTRIBUTE_UNUSED
)
255 if (GET_CODE (op
) != CONST_INT
)
260 /* IOR reg,$r0,value. */
261 if ((value
& ~ ((HOST_WIDE_INT
) 0x0000ffff)) == 0)
264 /* SUBU reg,$r0,value. */
265 if (((unsigned HOST_WIDE_INT
) (value
+ 32768)) <= 32767)
268 /* LUI reg,value >> 16. */
269 if ((value
& 0x0000ffff) == 0)
275 /* Return 1 if OP is a register or the constant 0. */
278 reg_or_0_operand (rtx op
, enum machine_mode mode
)
280 switch (GET_CODE (op
))
283 return INTVAL (op
) == 0;
286 return op
== CONST0_RTX (mode
);
290 return register_operand (op
, mode
);
299 /* Return 1 if OP is a memory operand that fits in a single instruction
300 (i.e., register + small offset). */
303 simple_memory_operand (rtx op
, enum machine_mode mode ATTRIBUTE_UNUSED
)
305 rtx addr
, plus0
, plus1
;
307 /* Eliminate non-memory operations. */
308 if (GET_CODE (op
) != MEM
)
311 /* Dword operations really put out 2 instructions, so eliminate them. */
312 if (GET_MODE_SIZE (GET_MODE (op
)) > (unsigned) UNITS_PER_WORD
)
315 /* Decode the address now. */
317 switch (GET_CODE (addr
))
324 return SMALL_INT (addr
);
327 plus0
= XEXP (addr
, 0);
328 plus1
= XEXP (addr
, 1);
329 if (GET_CODE (plus0
) == REG
330 && GET_CODE (plus1
) == CONST_INT
&& SMALL_INT (plus1
)
331 && SMALL_INT_UNSIGNED (plus1
) /* No negative offsets. */)
334 else if (GET_CODE (plus1
) == REG
335 && GET_CODE (plus0
) == CONST_INT
&& SMALL_INT (plus0
)
336 && SMALL_INT_UNSIGNED (plus1
) /* No negative offsets. */)
352 /* Return nonzero if the code of this rtx pattern is EQ or NE. */
355 equality_op (rtx op
, enum machine_mode mode
)
357 if (mode
!= GET_MODE (op
))
360 return GET_CODE (op
) == EQ
|| GET_CODE (op
) == NE
;
363 /* Return nonzero if the code is a relational operations (EQ, LE, etc). */
366 cmp_op (rtx op
, enum machine_mode mode
)
368 if (mode
!= GET_MODE (op
))
371 return COMPARISON_P (op
);
374 /* Return nonzero if the operand is either the PC or a label_ref. */
377 pc_or_label_operand (rtx op
, enum machine_mode mode ATTRIBUTE_UNUSED
)
382 if (GET_CODE (op
) == LABEL_REF
)
388 /* Return nonzero if OP is a valid operand for a call instruction. */
391 call_insn_operand (rtx op
, enum machine_mode mode ATTRIBUTE_UNUSED
)
393 return (CONSTANT_ADDRESS_P (op
)
394 || (GET_CODE (op
) == REG
&& op
!= arg_pointer_rtx
395 && ! (REGNO (op
) >= FIRST_PSEUDO_REGISTER
396 && REGNO (op
) <= LAST_VIRTUAL_REGISTER
)));
399 /* Return nonzero if OP is valid as a source operand for a move instruction. */
402 move_operand (rtx op
, enum machine_mode mode
)
404 /* Accept any general operand after reload has started; doing so
405 avoids losing if reload does an in-place replacement of a register
406 with a SYMBOL_REF or CONST. */
407 return (general_operand (op
, mode
)
408 && (! (iq2000_check_split (op
, mode
))
409 || reload_in_progress
|| reload_completed
));
412 /* Return nonzero if OP is a constant power of 2. */
415 power_of_2_operand (rtx op
, enum machine_mode mode ATTRIBUTE_UNUSED
)
419 if (GET_CODE (op
) != CONST_INT
)
422 intval
= INTVAL (op
);
424 return ((intval
& ((unsigned)(intval
) - 1)) == 0);
427 /* Return nonzero if we split the address into high and low parts. */
430 iq2000_check_split (rtx address
, enum machine_mode mode
)
432 /* This is the same check used in simple_memory_operand.
433 We use it here because LO_SUM is not offsettable. */
434 if (GET_MODE_SIZE (mode
) > (unsigned) UNITS_PER_WORD
)
437 if ((GET_CODE (address
) == SYMBOL_REF
)
438 || (GET_CODE (address
) == CONST
439 && GET_CODE (XEXP (XEXP (address
, 0), 0)) == SYMBOL_REF
)
440 || GET_CODE (address
) == LABEL_REF
)
446 /* Return nonzero if REG is valid for MODE. */
449 iq2000_reg_mode_ok_for_base_p (rtx reg
,
450 enum machine_mode mode ATTRIBUTE_UNUSED
,
454 ? REGNO_MODE_OK_FOR_BASE_P (REGNO (reg
), mode
)
455 : GP_REG_OR_PSEUDO_NONSTRICT_P (REGNO (reg
), mode
));
458 /* Return a nonzero value if XINSN is a legitimate address for a
459 memory operand of the indicated MODE. STRICT is nonzero if this
460 function is called during reload. */
463 iq2000_legitimate_address_p (enum machine_mode mode
, rtx xinsn
, int strict
)
465 if (TARGET_DEBUG_A_MODE
)
467 GO_PRINTF2 ("\n========== GO_IF_LEGITIMATE_ADDRESS, %sstrict\n",
468 strict
? "" : "not ");
469 GO_DEBUG_RTX (xinsn
);
472 /* Check for constant before stripping off SUBREG, so that we don't
473 accept (subreg (const_int)) which will fail to reload. */
474 if (CONSTANT_ADDRESS_P (xinsn
)
475 && ! (iq2000_check_split (xinsn
, mode
))
476 && ! (GET_CODE (xinsn
) == CONST_INT
&& ! SMALL_INT (xinsn
)))
479 while (GET_CODE (xinsn
) == SUBREG
)
480 xinsn
= SUBREG_REG (xinsn
);
482 if (GET_CODE (xinsn
) == REG
483 && iq2000_reg_mode_ok_for_base_p (xinsn
, mode
, strict
))
486 if (GET_CODE (xinsn
) == LO_SUM
)
488 rtx xlow0
= XEXP (xinsn
, 0);
489 rtx xlow1
= XEXP (xinsn
, 1);
491 while (GET_CODE (xlow0
) == SUBREG
)
492 xlow0
= SUBREG_REG (xlow0
);
493 if (GET_CODE (xlow0
) == REG
494 && iq2000_reg_mode_ok_for_base_p (xlow0
, mode
, strict
)
495 && iq2000_check_split (xlow1
, mode
))
499 if (GET_CODE (xinsn
) == PLUS
)
501 rtx xplus0
= XEXP (xinsn
, 0);
502 rtx xplus1
= XEXP (xinsn
, 1);
506 while (GET_CODE (xplus0
) == SUBREG
)
507 xplus0
= SUBREG_REG (xplus0
);
508 code0
= GET_CODE (xplus0
);
510 while (GET_CODE (xplus1
) == SUBREG
)
511 xplus1
= SUBREG_REG (xplus1
);
512 code1
= GET_CODE (xplus1
);
515 && iq2000_reg_mode_ok_for_base_p (xplus0
, mode
, strict
))
517 if (code1
== CONST_INT
&& SMALL_INT (xplus1
)
518 && SMALL_INT_UNSIGNED (xplus1
) /* No negative offsets */)
523 if (TARGET_DEBUG_A_MODE
)
524 GO_PRINTF ("Not a legitimate address\n");
526 /* The address was not legitimate. */
530 /* Returns an operand string for the given instruction's delay slot,
531 after updating filled delay slot statistics.
533 We assume that operands[0] is the target register that is set.
535 In order to check the next insn, most of this functionality is moved
536 to FINAL_PRESCAN_INSN, and we just set the global variables that
540 iq2000_fill_delay_slot (const char *ret
, enum delay_type type
, rtx operands
[],
544 enum machine_mode mode
;
545 rtx next_insn
= cur_insn
? NEXT_INSN (cur_insn
) : NULL_RTX
;
548 if (type
== DELAY_LOAD
|| type
== DELAY_FCMP
)
554 /* Make sure that we don't put nop's after labels. */
555 next_insn
= NEXT_INSN (cur_insn
);
556 while (next_insn
!= 0
557 && (GET_CODE (next_insn
) == NOTE
558 || GET_CODE (next_insn
) == CODE_LABEL
))
559 next_insn
= NEXT_INSN (next_insn
);
561 dslots_load_total
+= num_nops
;
562 if (TARGET_DEBUG_C_MODE
563 || type
== DELAY_NONE
567 || GET_CODE (next_insn
) == CODE_LABEL
568 || (set_reg
= operands
[0]) == 0)
570 dslots_number_nops
= 0;
572 iq2000_load_reg2
= 0;
573 iq2000_load_reg3
= 0;
574 iq2000_load_reg4
= 0;
579 set_reg
= operands
[0];
583 while (GET_CODE (set_reg
) == SUBREG
)
584 set_reg
= SUBREG_REG (set_reg
);
586 mode
= GET_MODE (set_reg
);
587 dslots_number_nops
= num_nops
;
588 iq2000_load_reg
= set_reg
;
589 if (GET_MODE_SIZE (mode
)
590 > (unsigned) (UNITS_PER_WORD
))
591 iq2000_load_reg2
= gen_rtx_REG (SImode
, REGNO (set_reg
) + 1);
593 iq2000_load_reg2
= 0;
598 /* Determine whether a memory reference takes one (based off of the GP
599 pointer), two (normal), or three (label + reg) instructions, and bump the
600 appropriate counter for -mstats. */
603 iq2000_count_memory_refs (rtx op
, int num
)
607 rtx addr
, plus0
, plus1
;
608 enum rtx_code code0
, code1
;
611 if (TARGET_DEBUG_B_MODE
)
613 fprintf (stderr
, "\n========== iq2000_count_memory_refs:\n");
617 /* Skip MEM if passed, otherwise handle movsi of address. */
618 addr
= (GET_CODE (op
) != MEM
) ? op
: XEXP (op
, 0);
620 /* Loop, going through the address RTL. */
624 switch (GET_CODE (addr
))
632 plus0
= XEXP (addr
, 0);
633 plus1
= XEXP (addr
, 1);
634 code0
= GET_CODE (plus0
);
635 code1
= GET_CODE (plus1
);
645 if (code0
== CONST_INT
)
660 if (code1
== CONST_INT
)
667 if (code0
== SYMBOL_REF
|| code0
== LABEL_REF
|| code0
== CONST
)
674 if (code1
== SYMBOL_REF
|| code1
== LABEL_REF
|| code1
== CONST
)
684 n_words
= 2; /* Always 2 words. */
688 addr
= XEXP (addr
, 0);
693 n_words
= SYMBOL_REF_FLAG (addr
) ? 1 : 2;
705 n_words
+= additional
;
709 num_refs
[n_words
-1] += num
;
712 /* Abort after printing out a specific insn. */
715 abort_with_insn (rtx insn
, const char * reason
)
722 /* Return the appropriate instructions to move one operand to another. */
725 iq2000_move_1word (rtx operands
[], rtx insn
, int unsignedp
)
728 rtx op0
= operands
[0];
729 rtx op1
= operands
[1];
730 enum rtx_code code0
= GET_CODE (op0
);
731 enum rtx_code code1
= GET_CODE (op1
);
732 enum machine_mode mode
= GET_MODE (op0
);
733 int subreg_offset0
= 0;
734 int subreg_offset1
= 0;
735 enum delay_type delay
= DELAY_NONE
;
737 while (code0
== SUBREG
)
739 subreg_offset0
+= subreg_regno_offset (REGNO (SUBREG_REG (op0
)),
740 GET_MODE (SUBREG_REG (op0
)),
743 op0
= SUBREG_REG (op0
);
744 code0
= GET_CODE (op0
);
747 while (code1
== SUBREG
)
749 subreg_offset1
+= subreg_regno_offset (REGNO (SUBREG_REG (op1
)),
750 GET_MODE (SUBREG_REG (op1
)),
753 op1
= SUBREG_REG (op1
);
754 code1
= GET_CODE (op1
);
757 /* For our purposes, a condition code mode is the same as SImode. */
763 int regno0
= REGNO (op0
) + subreg_offset0
;
767 int regno1
= REGNO (op1
) + subreg_offset1
;
769 /* Do not do anything for assigning a register to itself */
770 if (regno0
== regno1
)
773 else if (GP_REG_P (regno0
))
775 if (GP_REG_P (regno1
))
776 ret
= "or\t%0,%%0,%1";
781 else if (code1
== MEM
)
786 iq2000_count_memory_refs (op1
, 1);
788 if (GP_REG_P (regno0
))
790 /* For loads, use the mode of the memory item, instead of the
791 target, so zero/sign extend can use this code as well. */
792 switch (GET_MODE (op1
))
804 ret
= (unsignedp
) ? "lhu\t%0,%1" : "lh\t%0,%1";
807 ret
= (unsignedp
) ? "lbu\t%0,%1" : "lb\t%0,%1";
813 else if (code1
== CONST_INT
814 || (code1
== CONST_DOUBLE
815 && GET_MODE (op1
) == VOIDmode
))
817 if (code1
== CONST_DOUBLE
)
819 /* This can happen when storing constants into long long
820 bitfields. Just store the least significant word of
822 operands
[1] = op1
= GEN_INT (CONST_DOUBLE_LOW (op1
));
825 if (INTVAL (op1
) == 0)
827 if (GP_REG_P (regno0
))
828 ret
= "or\t%0,%%0,%z1";
830 else if (GP_REG_P (regno0
))
832 if (SMALL_INT_UNSIGNED (op1
))
833 ret
= "ori\t%0,%%0,%x1\t\t\t# %1";
834 else if (SMALL_INT (op1
))
835 ret
= "addiu\t%0,%%0,%1\t\t\t# %1";
837 ret
= "lui\t%0,%X1\t\t\t# %1\n\tori\t%0,%0,%x1";
841 else if (code1
== CONST_DOUBLE
&& mode
== SFmode
)
843 if (op1
== CONST0_RTX (SFmode
))
845 if (GP_REG_P (regno0
))
846 ret
= "or\t%0,%%0,%.";
856 else if (code1
== LABEL_REF
)
859 iq2000_count_memory_refs (op1
, 1);
864 else if (code1
== SYMBOL_REF
|| code1
== CONST
)
867 iq2000_count_memory_refs (op1
, 1);
872 else if (code1
== PLUS
)
874 rtx add_op0
= XEXP (op1
, 0);
875 rtx add_op1
= XEXP (op1
, 1);
877 if (GET_CODE (XEXP (op1
, 1)) == REG
878 && GET_CODE (XEXP (op1
, 0)) == CONST_INT
)
879 add_op0
= XEXP (op1
, 1), add_op1
= XEXP (op1
, 0);
881 operands
[2] = add_op0
;
882 operands
[3] = add_op1
;
883 ret
= "add%:\t%0,%2,%3";
886 else if (code1
== HIGH
)
888 operands
[1] = XEXP (op1
, 0);
889 ret
= "lui\t%0,%%hi(%1)";
893 else if (code0
== MEM
)
896 iq2000_count_memory_refs (op0
, 1);
900 int regno1
= REGNO (op1
) + subreg_offset1
;
902 if (GP_REG_P (regno1
))
906 case SFmode
: ret
= "sw\t%1,%0"; break;
907 case SImode
: ret
= "sw\t%1,%0"; break;
908 case HImode
: ret
= "sh\t%1,%0"; break;
909 case QImode
: ret
= "sb\t%1,%0"; break;
915 else if (code1
== CONST_INT
&& INTVAL (op1
) == 0)
919 case SFmode
: ret
= "sw\t%z1,%0"; break;
920 case SImode
: ret
= "sw\t%z1,%0"; break;
921 case HImode
: ret
= "sh\t%z1,%0"; break;
922 case QImode
: ret
= "sb\t%z1,%0"; break;
927 else if (code1
== CONST_DOUBLE
&& op1
== CONST0_RTX (mode
))
931 case SFmode
: ret
= "sw\t%.,%0"; break;
932 case SImode
: ret
= "sw\t%.,%0"; break;
933 case HImode
: ret
= "sh\t%.,%0"; break;
934 case QImode
: ret
= "sb\t%.,%0"; break;
942 abort_with_insn (insn
, "Bad move");
946 if (delay
!= DELAY_NONE
)
947 return iq2000_fill_delay_slot (ret
, delay
, operands
, insn
);
952 /* Provide the costs of an addressing mode that contains ADDR. */
955 iq2000_address_cost (rtx addr
)
957 switch (GET_CODE (addr
))
967 rtx offset
= const0_rtx
;
969 addr
= eliminate_constant_term (XEXP (addr
, 0), & offset
);
970 if (GET_CODE (addr
) == LABEL_REF
)
973 if (GET_CODE (addr
) != SYMBOL_REF
)
976 if (! SMALL_INT (offset
))
983 return SYMBOL_REF_FLAG (addr
) ? 1 : 2;
987 rtx plus0
= XEXP (addr
, 0);
988 rtx plus1
= XEXP (addr
, 1);
990 if (GET_CODE (plus0
) != REG
&& GET_CODE (plus1
) == REG
)
991 plus0
= XEXP (addr
, 1), plus1
= XEXP (addr
, 0);
993 if (GET_CODE (plus0
) != REG
)
996 switch (GET_CODE (plus1
))
999 return SMALL_INT (plus1
) ? 1 : 2;
1006 return iq2000_address_cost (plus1
) + 1;
1020 /* Make normal rtx_code into something we can index from an array. */
1022 static enum internal_test
1023 map_test_to_internal_test (enum rtx_code test_code
)
1025 enum internal_test test
= ITEST_MAX
;
1029 case EQ
: test
= ITEST_EQ
; break;
1030 case NE
: test
= ITEST_NE
; break;
1031 case GT
: test
= ITEST_GT
; break;
1032 case GE
: test
= ITEST_GE
; break;
1033 case LT
: test
= ITEST_LT
; break;
1034 case LE
: test
= ITEST_LE
; break;
1035 case GTU
: test
= ITEST_GTU
; break;
1036 case GEU
: test
= ITEST_GEU
; break;
1037 case LTU
: test
= ITEST_LTU
; break;
1038 case LEU
: test
= ITEST_LEU
; break;
1045 /* Generate the code to do a TEST_CODE comparison on two integer values CMP0
1046 and CMP1. P_INVERT is NULL or ptr if branch needs to reverse its test.
1047 The return value RESULT is:
1048 (reg:SI xx) The pseudo register the comparison is in
1049 0 No register, generate a simple branch. */
1052 gen_int_relational (enum rtx_code test_code
, rtx result
, rtx cmp0
, rtx cmp1
,
1057 enum rtx_code test_code
; /* Code to use in instruction (LT vs. LTU). */
1058 int const_low
; /* Low bound of constant we can accept. */
1059 int const_high
; /* High bound of constant we can accept. */
1060 int const_add
; /* Constant to add (convert LE -> LT). */
1061 int reverse_regs
; /* Reverse registers in test. */
1062 int invert_const
; /* != 0 if invert value if cmp1 is constant. */
1063 int invert_reg
; /* != 0 if invert value if cmp1 is register. */
1064 int unsignedp
; /* != 0 for unsigned comparisons. */
1067 static struct cmp_info info
[ (int)ITEST_MAX
] =
1069 { XOR
, 0, 65535, 0, 0, 0, 0, 0 }, /* EQ */
1070 { XOR
, 0, 65535, 0, 0, 1, 1, 0 }, /* NE */
1071 { LT
, -32769, 32766, 1, 1, 1, 0, 0 }, /* GT */
1072 { LT
, -32768, 32767, 0, 0, 1, 1, 0 }, /* GE */
1073 { LT
, -32768, 32767, 0, 0, 0, 0, 0 }, /* LT */
1074 { LT
, -32769, 32766, 1, 1, 0, 1, 0 }, /* LE */
1075 { LTU
, -32769, 32766, 1, 1, 1, 0, 1 }, /* GTU */
1076 { LTU
, -32768, 32767, 0, 0, 1, 1, 1 }, /* GEU */
1077 { LTU
, -32768, 32767, 0, 0, 0, 0, 1 }, /* LTU */
1078 { LTU
, -32769, 32766, 1, 1, 0, 1, 1 }, /* LEU */
1081 enum internal_test test
;
1082 enum machine_mode mode
;
1083 struct cmp_info
*p_info
;
1090 test
= map_test_to_internal_test (test_code
);
1091 if (test
== ITEST_MAX
)
1094 p_info
= &info
[(int) test
];
1095 eqne_p
= (p_info
->test_code
== XOR
);
1097 mode
= GET_MODE (cmp0
);
1098 if (mode
== VOIDmode
)
1099 mode
= GET_MODE (cmp1
);
1101 /* Eliminate simple branches. */
1102 branch_p
= (result
== 0);
1105 if (GET_CODE (cmp0
) == REG
|| GET_CODE (cmp0
) == SUBREG
)
1107 /* Comparisons against zero are simple branches. */
1108 if (GET_CODE (cmp1
) == CONST_INT
&& INTVAL (cmp1
) == 0)
1111 /* Test for beq/bne. */
1116 /* Allocate a pseudo to calculate the value in. */
1117 result
= gen_reg_rtx (mode
);
1120 /* Make sure we can handle any constants given to us. */
1121 if (GET_CODE (cmp0
) == CONST_INT
)
1122 cmp0
= force_reg (mode
, cmp0
);
1124 if (GET_CODE (cmp1
) == CONST_INT
)
1126 HOST_WIDE_INT value
= INTVAL (cmp1
);
1128 if (value
< p_info
->const_low
1129 || value
> p_info
->const_high
)
1130 cmp1
= force_reg (mode
, cmp1
);
1133 /* See if we need to invert the result. */
1134 invert
= (GET_CODE (cmp1
) == CONST_INT
1135 ? p_info
->invert_const
: p_info
->invert_reg
);
1137 if (p_invert
!= (int *)0)
1143 /* Comparison to constants, may involve adding 1 to change a LT into LE.
1144 Comparison between two registers, may involve switching operands. */
1145 if (GET_CODE (cmp1
) == CONST_INT
)
1147 if (p_info
->const_add
!= 0)
1149 HOST_WIDE_INT
new = INTVAL (cmp1
) + p_info
->const_add
;
1151 /* If modification of cmp1 caused overflow,
1152 we would get the wrong answer if we follow the usual path;
1153 thus, x > 0xffffffffU would turn into x > 0U. */
1154 if ((p_info
->unsignedp
1155 ? (unsigned HOST_WIDE_INT
) new >
1156 (unsigned HOST_WIDE_INT
) INTVAL (cmp1
)
1157 : new > INTVAL (cmp1
))
1158 != (p_info
->const_add
> 0))
1160 /* This test is always true, but if INVERT is true then
1161 the result of the test needs to be inverted so 0 should
1162 be returned instead. */
1163 emit_move_insn (result
, invert
? const0_rtx
: const_true_rtx
);
1167 cmp1
= GEN_INT (new);
1171 else if (p_info
->reverse_regs
)
1178 if (test
== ITEST_NE
&& GET_CODE (cmp1
) == CONST_INT
&& INTVAL (cmp1
) == 0)
1182 reg
= (invert
|| eqne_p
) ? gen_reg_rtx (mode
) : result
;
1183 convert_move (reg
, gen_rtx_fmt_ee (p_info
->test_code
, mode
, cmp0
, cmp1
), 0);
1186 if (test
== ITEST_NE
)
1188 convert_move (result
, gen_rtx_GTU (mode
, reg
, const0_rtx
), 0);
1189 if (p_invert
!= NULL
)
1194 else if (test
== ITEST_EQ
)
1196 reg2
= invert
? gen_reg_rtx (mode
) : result
;
1197 convert_move (reg2
, gen_rtx_LTU (mode
, reg
, const1_rtx
), 0);
1206 convert_move (result
, gen_rtx_XOR (mode
, reg
, one
), 0);
1212 /* Emit the common code for doing conditional branches.
1213 operand[0] is the label to jump to.
1214 The comparison operands are saved away by cmp{si,di,sf,df}. */
1217 gen_conditional_branch (rtx operands
[], enum rtx_code test_code
)
1219 enum cmp_type type
= branch_type
;
1220 rtx cmp0
= branch_cmp
[0];
1221 rtx cmp1
= branch_cmp
[1];
1222 enum machine_mode mode
;
1231 mode
= type
== CMP_SI
? SImode
: DImode
;
1233 reg
= gen_int_relational (test_code
, NULL_RTX
, cmp0
, cmp1
, &invert
);
1241 else if (GET_CODE (cmp1
) == CONST_INT
&& INTVAL (cmp1
) != 0)
1242 /* We don't want to build a comparison against a nonzero
1244 cmp1
= force_reg (mode
, cmp1
);
1250 reg
= gen_reg_rtx (CCmode
);
1252 /* For cmp0 != cmp1, build cmp0 == cmp1, and test for result == 0. */
1253 emit_insn (gen_rtx_SET (VOIDmode
, reg
,
1254 gen_rtx_fmt_ee (test_code
== NE
? EQ
: test_code
,
1255 CCmode
, cmp0
, cmp1
)));
1257 test_code
= test_code
== NE
? EQ
: NE
;
1265 abort_with_insn (gen_rtx_fmt_ee (test_code
, VOIDmode
, cmp0
, cmp1
),
1269 /* Generate the branch. */
1270 label1
= gen_rtx_LABEL_REF (VOIDmode
, operands
[0]);
1279 emit_jump_insn (gen_rtx_SET (VOIDmode
, pc_rtx
,
1280 gen_rtx_IF_THEN_ELSE (VOIDmode
,
1281 gen_rtx_fmt_ee (test_code
,
1287 /* Initialize CUM for a function FNTYPE. */
1290 init_cumulative_args (CUMULATIVE_ARGS
*cum
, tree fntype
,
1291 rtx libname ATTRIBUTE_UNUSED
)
1293 static CUMULATIVE_ARGS zero_cum
;
1297 if (TARGET_DEBUG_D_MODE
)
1300 "\ninit_cumulative_args, fntype = 0x%.8lx", (long) fntype
);
1303 fputc ('\n', stderr
);
1307 tree ret_type
= TREE_TYPE (fntype
);
1309 fprintf (stderr
, ", fntype code = %s, ret code = %s\n",
1310 tree_code_name
[(int)TREE_CODE (fntype
)],
1311 tree_code_name
[(int)TREE_CODE (ret_type
)]);
1317 /* Determine if this function has variable arguments. This is
1318 indicated by the last argument being 'void_type_mode' if there
1319 are no variable arguments. The standard IQ2000 calling sequence
1320 passes all arguments in the general purpose registers in this case. */
1322 for (param
= fntype
? TYPE_ARG_TYPES (fntype
) : 0;
1323 param
!= 0; param
= next_param
)
1325 next_param
= TREE_CHAIN (param
);
1326 if (next_param
== 0 && TREE_VALUE (param
) != void_type_node
)
1327 cum
->gp_reg_found
= 1;
1331 /* Advance the argument of type TYPE and mode MODE to the next argument
1335 function_arg_advance (CUMULATIVE_ARGS
*cum
, enum machine_mode mode
, tree type
,
1338 if (TARGET_DEBUG_D_MODE
)
1341 "function_adv({gp reg found = %d, arg # = %2d, words = %2d}, %4s, ",
1342 cum
->gp_reg_found
, cum
->arg_number
, cum
->arg_words
,
1343 GET_MODE_NAME (mode
));
1344 fprintf (stderr
, HOST_PTR_PRINTF
, (const PTR
) type
);
1345 fprintf (stderr
, ", %d )\n\n", named
);
1355 if (GET_MODE_CLASS (mode
) != MODE_COMPLEX_INT
1356 && GET_MODE_CLASS (mode
) != MODE_COMPLEX_FLOAT
)
1359 cum
->gp_reg_found
= 1;
1360 cum
->arg_words
+= ((GET_MODE_SIZE (mode
) + UNITS_PER_WORD
- 1)
1365 cum
->gp_reg_found
= 1;
1366 cum
->arg_words
+= ((int_size_in_bytes (type
) + UNITS_PER_WORD
- 1)
1372 if (! cum
->gp_reg_found
&& cum
->arg_number
<= 2)
1373 cum
->fp_code
+= 1 << ((cum
->arg_number
- 1) * 2);
1377 cum
->arg_words
+= 2;
1378 if (! cum
->gp_reg_found
&& cum
->arg_number
<= 2)
1379 cum
->fp_code
+= 2 << ((cum
->arg_number
- 1) * 2);
1383 cum
->gp_reg_found
= 1;
1384 cum
->arg_words
+= 2;
1390 cum
->gp_reg_found
= 1;
1396 /* Return an RTL expression containing the register for the given mode MODE
1397 and type TYPE in CUM, or 0 if the argument is to be passed on the stack. */
1400 function_arg (CUMULATIVE_ARGS
*cum
, enum machine_mode mode
, tree type
,
1406 unsigned int *arg_words
= &cum
->arg_words
;
1407 int struct_p
= (type
!= 0
1408 && (TREE_CODE (type
) == RECORD_TYPE
1409 || TREE_CODE (type
) == UNION_TYPE
1410 || TREE_CODE (type
) == QUAL_UNION_TYPE
));
1412 if (TARGET_DEBUG_D_MODE
)
1415 "function_arg( {gp reg found = %d, arg # = %2d, words = %2d}, %4s, ",
1416 cum
->gp_reg_found
, cum
->arg_number
, cum
->arg_words
,
1417 GET_MODE_NAME (mode
));
1418 fprintf (stderr
, HOST_PTR_PRINTF
, (const PTR
) type
);
1419 fprintf (stderr
, ", %d ) = ", named
);
1423 cum
->last_arg_fp
= 0;
1427 regbase
= GP_ARG_FIRST
;
1431 cum
->arg_words
+= cum
->arg_words
& 1;
1433 regbase
= GP_ARG_FIRST
;
1437 if (GET_MODE_CLASS (mode
) != MODE_COMPLEX_INT
1438 && GET_MODE_CLASS (mode
) != MODE_COMPLEX_FLOAT
)
1441 /* Drops through. */
1443 if (type
!= NULL_TREE
&& TYPE_ALIGN (type
) > (unsigned) BITS_PER_WORD
)
1444 cum
->arg_words
+= (cum
->arg_words
& 1);
1445 regbase
= GP_ARG_FIRST
;
1452 regbase
= GP_ARG_FIRST
;
1456 cum
->arg_words
+= (cum
->arg_words
& 1);
1457 regbase
= GP_ARG_FIRST
;
1460 if (*arg_words
>= (unsigned) MAX_ARGS_IN_REGISTERS
)
1462 if (TARGET_DEBUG_D_MODE
)
1463 fprintf (stderr
, "<stack>%s\n", struct_p
? ", [struct]" : "");
1472 if (! type
|| TREE_CODE (type
) != RECORD_TYPE
1473 || ! named
|| ! TYPE_SIZE_UNIT (type
)
1474 || ! host_integerp (TYPE_SIZE_UNIT (type
), 1))
1475 ret
= gen_rtx_REG (mode
, regbase
+ *arg_words
+ bias
);
1480 for (field
= TYPE_FIELDS (type
); field
; field
= TREE_CHAIN (field
))
1481 if (TREE_CODE (field
) == FIELD_DECL
1482 && TREE_CODE (TREE_TYPE (field
)) == REAL_TYPE
1483 && TYPE_PRECISION (TREE_TYPE (field
)) == BITS_PER_WORD
1484 && host_integerp (bit_position (field
), 0)
1485 && int_bit_position (field
) % BITS_PER_WORD
== 0)
1488 /* If the whole struct fits a DFmode register,
1489 we don't need the PARALLEL. */
1490 if (! field
|| mode
== DFmode
)
1491 ret
= gen_rtx_REG (mode
, regbase
+ *arg_words
+ bias
);
1494 unsigned int chunks
;
1495 HOST_WIDE_INT bitpos
;
1499 /* ??? If this is a packed structure, then the last hunk won't
1502 = tree_low_cst (TYPE_SIZE_UNIT (type
), 1) / UNITS_PER_WORD
;
1503 if (chunks
+ *arg_words
+ bias
> (unsigned) MAX_ARGS_IN_REGISTERS
)
1504 chunks
= MAX_ARGS_IN_REGISTERS
- *arg_words
- bias
;
1506 /* Assign_parms checks the mode of ENTRY_PARM, so we must
1507 use the actual mode here. */
1508 ret
= gen_rtx_PARALLEL (mode
, rtvec_alloc (chunks
));
1511 regno
= regbase
+ *arg_words
+ bias
;
1512 field
= TYPE_FIELDS (type
);
1513 for (i
= 0; i
< chunks
; i
++)
1517 for (; field
; field
= TREE_CHAIN (field
))
1518 if (TREE_CODE (field
) == FIELD_DECL
1519 && int_bit_position (field
) >= bitpos
)
1523 && int_bit_position (field
) == bitpos
1524 && TREE_CODE (TREE_TYPE (field
)) == REAL_TYPE
1525 && TYPE_PRECISION (TREE_TYPE (field
)) == BITS_PER_WORD
)
1526 reg
= gen_rtx_REG (DFmode
, regno
++);
1528 reg
= gen_rtx_REG (word_mode
, regno
);
1531 = gen_rtx_EXPR_LIST (VOIDmode
, reg
,
1532 GEN_INT (bitpos
/ BITS_PER_UNIT
));
1540 if (TARGET_DEBUG_D_MODE
)
1541 fprintf (stderr
, "%s%s\n", reg_names
[regbase
+ *arg_words
+ bias
],
1542 struct_p
? ", [struct]" : "");
1545 /* We will be called with a mode of VOIDmode after the last argument
1546 has been seen. Whatever we return will be passed to the call
1547 insn. If we need any shifts for small structures, return them in
1549 if (mode
== VOIDmode
)
1551 if (cum
->num_adjusts
> 0)
1552 ret
= gen_rtx_PARALLEL ((enum machine_mode
) cum
->fp_code
,
1553 gen_rtvec_v (cum
->num_adjusts
, cum
->adjust
));
1560 iq2000_arg_partial_bytes (CUMULATIVE_ARGS
*cum
, enum machine_mode mode
,
1561 tree type ATTRIBUTE_UNUSED
,
1562 bool named ATTRIBUTE_UNUSED
)
1564 if (mode
== DImode
&& cum
->arg_words
== MAX_ARGS_IN_REGISTERS
- 1)
1566 if (TARGET_DEBUG_D_MODE
)
1567 fprintf (stderr
, "iq2000_arg_partial_bytes=%d\n", UNITS_PER_WORD
);
1568 return UNITS_PER_WORD
;
1574 /* Implement va_start. */
1577 iq2000_va_start (tree valist
, rtx nextarg
)
1580 /* Find out how many non-float named formals. */
1581 int gpr_save_area_size
;
1582 /* Note UNITS_PER_WORD is 4 bytes. */
1583 int_arg_words
= current_function_args_info
.arg_words
;
1585 if (int_arg_words
< 8 )
1586 /* Adjust for the prologue's economy measure. */
1587 gpr_save_area_size
= (8 - int_arg_words
) * UNITS_PER_WORD
;
1589 gpr_save_area_size
= 0;
1591 /* Everything is in the GPR save area, or in the overflow
1592 area which is contiguous with it. */
1593 nextarg
= plus_constant (nextarg
, - gpr_save_area_size
);
1594 std_expand_builtin_va_start (valist
, nextarg
);
1597 /* Allocate a chunk of memory for per-function machine-dependent data. */
1599 static struct machine_function
*
1600 iq2000_init_machine_status (void)
1602 struct machine_function
*f
;
1604 f
= ggc_alloc_cleared (sizeof (struct machine_function
));
1609 static enum processor_type
1610 iq2000_parse_cpu (const char * cpu_string
)
1612 const char *p
= cpu_string
;
1613 enum processor_type cpu
;
1615 cpu
= PROCESSOR_DEFAULT
;
1619 if (!strcmp (p
, "iq10"))
1620 cpu
= PROCESSOR_IQ10
;
1623 if (!strcmp (p
, "iq2000"))
1624 cpu
= PROCESSOR_IQ2000
;
1631 /* Detect any conflicts in the switches. */
1634 override_options (void)
1636 enum processor_type iq2000_cpu
;
1638 target_flags
&= ~MASK_GPOPT
;
1640 iq2000_isa
= IQ2000_ISA_DEFAULT
;
1642 /* Identify the processor type. */
1644 if (iq2000_cpu_string
!= 0)
1646 iq2000_cpu
= iq2000_parse_cpu (iq2000_cpu_string
);
1647 if (iq2000_cpu
== PROCESSOR_DEFAULT
)
1649 error ("bad value (%s) for -mcpu= switch", iq2000_arch_string
);
1650 iq2000_cpu_string
= "default";
1652 iq2000_arch
= iq2000_cpu
;
1653 iq2000_tune
= iq2000_cpu
;
1656 if (iq2000_arch_string
== 0
1657 || ! strcmp (iq2000_arch_string
, "default")
1658 || ! strcmp (iq2000_arch_string
, "DEFAULT"))
1663 iq2000_arch_string
= "iq2000";
1664 iq2000_arch
= PROCESSOR_IQ2000
;
1670 iq2000_arch
= iq2000_parse_cpu (iq2000_arch_string
);
1671 if (iq2000_arch
== PROCESSOR_DEFAULT
)
1673 error ("bad value (%s) for -march= switch", iq2000_arch_string
);
1674 iq2000_arch_string
= "default";
1676 if (iq2000_arch
== PROCESSOR_IQ10
)
1678 error ("The compiler does not support -march=%s.", iq2000_arch_string
);
1679 iq2000_arch_string
= "default";
1683 iq2000_print_operand_punct
['?'] = 1;
1684 iq2000_print_operand_punct
['#'] = 1;
1685 iq2000_print_operand_punct
['&'] = 1;
1686 iq2000_print_operand_punct
['!'] = 1;
1687 iq2000_print_operand_punct
['*'] = 1;
1688 iq2000_print_operand_punct
['@'] = 1;
1689 iq2000_print_operand_punct
['.'] = 1;
1690 iq2000_print_operand_punct
['('] = 1;
1691 iq2000_print_operand_punct
[')'] = 1;
1692 iq2000_print_operand_punct
['['] = 1;
1693 iq2000_print_operand_punct
[']'] = 1;
1694 iq2000_print_operand_punct
['<'] = 1;
1695 iq2000_print_operand_punct
['>'] = 1;
1696 iq2000_print_operand_punct
['{'] = 1;
1697 iq2000_print_operand_punct
['}'] = 1;
1698 iq2000_print_operand_punct
['^'] = 1;
1699 iq2000_print_operand_punct
['$'] = 1;
1700 iq2000_print_operand_punct
['+'] = 1;
1701 iq2000_print_operand_punct
['~'] = 1;
1703 /* Save GPR registers in word_mode sized hunks. word_mode hasn't been
1704 initialized yet, so we can't use that here. */
1707 /* Function to allocate machine-dependent function status. */
1708 init_machine_status
= iq2000_init_machine_status
;
1711 /* The arg pointer (which is eliminated) points to the virtual frame pointer,
1712 while the frame pointer (which may be eliminated) points to the stack
1713 pointer after the initial adjustments. */
1716 iq2000_debugger_offset (rtx addr
, HOST_WIDE_INT offset
)
1718 rtx offset2
= const0_rtx
;
1719 rtx reg
= eliminate_constant_term (addr
, & offset2
);
1722 offset
= INTVAL (offset2
);
1724 if (reg
== stack_pointer_rtx
|| reg
== frame_pointer_rtx
1725 || reg
== hard_frame_pointer_rtx
)
1727 HOST_WIDE_INT frame_size
= (!cfun
->machine
->initialized
)
1728 ? compute_frame_size (get_frame_size ())
1729 : cfun
->machine
->total_size
;
1731 offset
= offset
- frame_size
;
1737 /* If defined, a C statement to be executed just prior to the output of
1738 assembler code for INSN, to modify the extracted operands so they will be
1741 Here the argument OPVEC is the vector containing the operands extracted
1742 from INSN, and NOPERANDS is the number of elements of the vector which
1743 contain meaningful data for this insn. The contents of this vector are
1744 what will be used to convert the insn template into assembler code, so you
1745 can change the assembler output by changing the contents of the vector.
1747 We use it to check if the current insn needs a nop in front of it because
1748 of load delays, and also to update the delay slot statistics. */
1751 final_prescan_insn (rtx insn
, rtx opvec
[] ATTRIBUTE_UNUSED
,
1752 int noperands ATTRIBUTE_UNUSED
)
1754 if (dslots_number_nops
> 0)
1756 rtx pattern
= PATTERN (insn
);
1757 int length
= get_attr_length (insn
);
1759 /* Do we need to emit a NOP? */
1761 || (iq2000_load_reg
!= 0 && reg_mentioned_p (iq2000_load_reg
, pattern
))
1762 || (iq2000_load_reg2
!= 0 && reg_mentioned_p (iq2000_load_reg2
, pattern
))
1763 || (iq2000_load_reg3
!= 0 && reg_mentioned_p (iq2000_load_reg3
, pattern
))
1764 || (iq2000_load_reg4
!= 0
1765 && reg_mentioned_p (iq2000_load_reg4
, pattern
)))
1766 fputs ("\tnop\n", asm_out_file
);
1769 dslots_load_filled
++;
1771 while (--dslots_number_nops
> 0)
1772 fputs ("\tnop\n", asm_out_file
);
1774 iq2000_load_reg
= 0;
1775 iq2000_load_reg2
= 0;
1776 iq2000_load_reg3
= 0;
1777 iq2000_load_reg4
= 0;
1780 if ( (GET_CODE (insn
) == JUMP_INSN
1781 || GET_CODE (insn
) == CALL_INSN
1782 || (GET_CODE (PATTERN (insn
)) == RETURN
))
1783 && NEXT_INSN (PREV_INSN (insn
)) == insn
)
1785 rtx nop_insn
= emit_insn_after (gen_nop (), insn
);
1787 INSN_ADDRESSES_NEW (nop_insn
, -1);
1791 && (GET_CODE (insn
) == JUMP_INSN
|| GET_CODE (insn
) == CALL_INSN
))
1792 dslots_jump_total
++;
1795 /* Return the bytes needed to compute the frame pointer from the current
1796 stack pointer where SIZE is the # of var. bytes allocated.
1798 IQ2000 stack frames look like:
1800 Before call After call
1801 +-----------------------+ +-----------------------+
1804 | caller's temps. | | caller's temps. |
1806 +-----------------------+ +-----------------------+
1808 | arguments on stack. | | arguments on stack. |
1810 +-----------------------+ +-----------------------+
1811 | 4 words to save | | 4 words to save |
1812 | arguments passed | | arguments passed |
1813 | in registers, even | | in registers, even |
1814 SP->| if not passed. | VFP->| if not passed. |
1815 +-----------------------+ +-----------------------+
1817 | fp register save |
1819 +-----------------------+
1821 | gp register save |
1823 +-----------------------+
1827 +-----------------------+
1829 | alloca allocations |
1831 +-----------------------+
1833 | GP save for V.4 abi |
1835 +-----------------------+
1837 | arguments on stack |
1839 +-----------------------+
1841 | arguments passed |
1842 | in registers, even |
1843 low SP->| if not passed. |
1844 memory +-----------------------+ */
1847 compute_frame_size (HOST_WIDE_INT size
)
1850 HOST_WIDE_INT total_size
; /* # bytes that the entire frame takes up. */
1851 HOST_WIDE_INT var_size
; /* # bytes that variables take up. */
1852 HOST_WIDE_INT args_size
; /* # bytes that outgoing arguments take up. */
1853 HOST_WIDE_INT extra_size
; /* # extra bytes. */
1854 HOST_WIDE_INT gp_reg_rounded
; /* # bytes needed to store gp after rounding. */
1855 HOST_WIDE_INT gp_reg_size
; /* # bytes needed to store gp regs. */
1856 HOST_WIDE_INT fp_reg_size
; /* # bytes needed to store fp regs. */
1857 long mask
; /* mask of saved gp registers. */
1858 int fp_inc
; /* 1 or 2 depending on the size of fp regs. */
1859 long fp_bits
; /* bitmask to use for each fp register. */
1864 extra_size
= IQ2000_STACK_ALIGN ((0));
1865 var_size
= IQ2000_STACK_ALIGN (size
);
1866 args_size
= IQ2000_STACK_ALIGN (current_function_outgoing_args_size
);
1868 /* If a function dynamically allocates the stack and
1869 has 0 for STACK_DYNAMIC_OFFSET then allocate some stack space. */
1870 if (args_size
== 0 && current_function_calls_alloca
)
1871 args_size
= 4 * UNITS_PER_WORD
;
1873 total_size
= var_size
+ args_size
+ extra_size
;
1875 /* Calculate space needed for gp registers. */
1876 for (regno
= GP_REG_FIRST
; regno
<= GP_REG_LAST
; regno
++)
1878 if (MUST_SAVE_REGISTER (regno
))
1880 gp_reg_size
+= GET_MODE_SIZE (gpr_mode
);
1881 mask
|= 1L << (regno
- GP_REG_FIRST
);
1885 /* We need to restore these for the handler. */
1886 if (current_function_calls_eh_return
)
1892 regno
= EH_RETURN_DATA_REGNO (i
);
1893 if (regno
== (int) INVALID_REGNUM
)
1895 gp_reg_size
+= GET_MODE_SIZE (gpr_mode
);
1896 mask
|= 1L << (regno
- GP_REG_FIRST
);
1902 gp_reg_rounded
= IQ2000_STACK_ALIGN (gp_reg_size
);
1903 total_size
+= gp_reg_rounded
+ IQ2000_STACK_ALIGN (fp_reg_size
);
1905 /* The gp reg is caller saved, so there is no need for leaf routines
1906 (total_size == extra_size) to save the gp reg. */
1907 if (total_size
== extra_size
1909 total_size
= extra_size
= 0;
1911 total_size
+= IQ2000_STACK_ALIGN (current_function_pretend_args_size
);
1913 /* Save other computed information. */
1914 cfun
->machine
->total_size
= total_size
;
1915 cfun
->machine
->var_size
= var_size
;
1916 cfun
->machine
->args_size
= args_size
;
1917 cfun
->machine
->extra_size
= extra_size
;
1918 cfun
->machine
->gp_reg_size
= gp_reg_size
;
1919 cfun
->machine
->fp_reg_size
= fp_reg_size
;
1920 cfun
->machine
->mask
= mask
;
1921 cfun
->machine
->initialized
= reload_completed
;
1922 cfun
->machine
->num_gp
= gp_reg_size
/ UNITS_PER_WORD
;
1926 unsigned long offset
;
1928 offset
= (args_size
+ extra_size
+ var_size
1929 + gp_reg_size
- GET_MODE_SIZE (gpr_mode
));
1931 cfun
->machine
->gp_sp_offset
= offset
;
1932 cfun
->machine
->gp_save_offset
= offset
- total_size
;
1936 cfun
->machine
->gp_sp_offset
= 0;
1937 cfun
->machine
->gp_save_offset
= 0;
1940 cfun
->machine
->fp_sp_offset
= 0;
1941 cfun
->machine
->fp_save_offset
= 0;
1943 /* Ok, we're done. */
1947 /* Implement INITIAL_ELIMINATION_OFFSET. FROM is either the frame
1948 pointer, argument pointer, or return address pointer. TO is either
1949 the stack pointer or hard frame pointer. */
1952 iq2000_initial_elimination_offset (int from
, int to ATTRIBUTE_UNUSED
)
1956 compute_frame_size (get_frame_size ());
1957 if ((from
) == FRAME_POINTER_REGNUM
)
1959 else if ((from
) == ARG_POINTER_REGNUM
)
1960 (offset
) = (cfun
->machine
->total_size
);
1961 else if ((from
) == RETURN_ADDRESS_POINTER_REGNUM
)
1963 if (leaf_function_p ())
1965 else (offset
) = cfun
->machine
->gp_sp_offset
1966 + ((UNITS_PER_WORD
- (POINTER_SIZE
/ BITS_PER_UNIT
))
1967 * (BYTES_BIG_ENDIAN
!= 0));
1973 /* Common code to emit the insns (or to write the instructions to a file)
1974 to save/restore registers.
1975 Other parts of the code assume that IQ2000_TEMP1_REGNUM (aka large_reg)
1976 is not modified within save_restore_insns. */
1978 #define BITSET_P(VALUE,BIT) (((VALUE) & (1L << (BIT))) != 0)
1980 /* Emit instructions to load the value (SP + OFFSET) into IQ2000_TEMP2_REGNUM
1981 and return an rtl expression for the register. Write the assembly
1982 instructions directly to FILE if it is not null, otherwise emit them as
1985 This function is a subroutine of save_restore_insns. It is used when
1986 OFFSET is too large to add in a single instruction. */
1989 iq2000_add_large_offset_to_sp (HOST_WIDE_INT offset
)
1991 rtx reg
= gen_rtx_REG (Pmode
, IQ2000_TEMP2_REGNUM
);
1992 rtx offset_rtx
= GEN_INT (offset
);
1994 emit_move_insn (reg
, offset_rtx
);
1995 emit_insn (gen_addsi3 (reg
, reg
, stack_pointer_rtx
));
1999 /* Make INSN frame related and note that it performs the frame-related
2000 operation DWARF_PATTERN. */
2003 iq2000_annotate_frame_insn (rtx insn
, rtx dwarf_pattern
)
2005 RTX_FRAME_RELATED_P (insn
) = 1;
2006 REG_NOTES (insn
) = alloc_EXPR_LIST (REG_FRAME_RELATED_EXPR
,
2011 /* Emit a move instruction that stores REG in MEM. Make the instruction
2012 frame related and note that it stores REG at (SP + OFFSET). */
2015 iq2000_emit_frame_related_store (rtx mem
, rtx reg
, HOST_WIDE_INT offset
)
2017 rtx dwarf_address
= plus_constant (stack_pointer_rtx
, offset
);
2018 rtx dwarf_mem
= gen_rtx_MEM (GET_MODE (reg
), dwarf_address
);
2020 iq2000_annotate_frame_insn (emit_move_insn (mem
, reg
),
2021 gen_rtx_SET (GET_MODE (reg
), dwarf_mem
, reg
));
2024 /* Emit instructions to save/restore registers, as determined by STORE_P. */
2027 save_restore_insns (int store_p
)
2029 long mask
= cfun
->machine
->mask
;
2032 HOST_WIDE_INT base_offset
;
2033 HOST_WIDE_INT gp_offset
;
2034 HOST_WIDE_INT end_offset
;
2036 if (frame_pointer_needed
2037 && ! BITSET_P (mask
, HARD_FRAME_POINTER_REGNUM
- GP_REG_FIRST
))
2042 base_reg_rtx
= 0, base_offset
= 0;
2046 /* Save registers starting from high to low. The debuggers prefer at least
2047 the return register be stored at func+4, and also it allows us not to
2048 need a nop in the epilog if at least one register is reloaded in
2049 addition to return address. */
2051 /* Save GP registers if needed. */
2052 /* Pick which pointer to use as a base register. For small frames, just
2053 use the stack pointer. Otherwise, use a temporary register. Save 2
2054 cycles if the save area is near the end of a large frame, by reusing
2055 the constant created in the prologue/epilogue to adjust the stack
2058 gp_offset
= cfun
->machine
->gp_sp_offset
;
2060 = gp_offset
- (cfun
->machine
->gp_reg_size
2061 - GET_MODE_SIZE (gpr_mode
));
2063 if (gp_offset
< 0 || end_offset
< 0)
2065 ("gp_offset (%ld) or end_offset (%ld) is less than zero.",
2066 (long) gp_offset
, (long) end_offset
);
2068 else if (gp_offset
< 32768)
2069 base_reg_rtx
= stack_pointer_rtx
, base_offset
= 0;
2073 int reg_save_count
= 0;
2075 for (regno
= GP_REG_LAST
; regno
>= GP_REG_FIRST
; regno
--)
2076 if (BITSET_P (mask
, regno
- GP_REG_FIRST
)) reg_save_count
+= 1;
2077 base_offset
= gp_offset
- ((reg_save_count
- 1) * 4);
2078 base_reg_rtx
= iq2000_add_large_offset_to_sp (base_offset
);
2081 for (regno
= GP_REG_LAST
; regno
>= GP_REG_FIRST
; regno
--)
2083 if (BITSET_P (mask
, regno
- GP_REG_FIRST
))
2087 = gen_rtx_MEM (gpr_mode
,
2088 gen_rtx_PLUS (Pmode
, base_reg_rtx
,
2089 GEN_INT (gp_offset
- base_offset
)));
2091 reg_rtx
= gen_rtx_REG (gpr_mode
, regno
);
2094 iq2000_emit_frame_related_store (mem_rtx
, reg_rtx
, gp_offset
);
2097 emit_move_insn (reg_rtx
, mem_rtx
);
2099 gp_offset
-= GET_MODE_SIZE (gpr_mode
);
2104 /* Expand the prologue into a bunch of separate insns. */
2107 iq2000_expand_prologue (void)
2110 HOST_WIDE_INT tsize
;
2111 int last_arg_is_vararg_marker
= 0;
2112 tree fndecl
= current_function_decl
;
2113 tree fntype
= TREE_TYPE (fndecl
);
2114 tree fnargs
= DECL_ARGUMENTS (fndecl
);
2119 CUMULATIVE_ARGS args_so_far
;
2120 int store_args_on_stack
= (iq2000_can_use_return_insn ());
2122 /* If struct value address is treated as the first argument. */
2123 if (aggregate_value_p (DECL_RESULT (fndecl
), fndecl
)
2124 && ! current_function_returns_pcc_struct
2125 && targetm
.calls
.struct_value_rtx (TREE_TYPE (fndecl
), 1) == 0)
2127 tree type
= build_pointer_type (fntype
);
2128 tree function_result_decl
= build_decl (PARM_DECL
, NULL_TREE
, type
);
2130 DECL_ARG_TYPE (function_result_decl
) = type
;
2131 TREE_CHAIN (function_result_decl
) = fnargs
;
2132 fnargs
= function_result_decl
;
2135 /* For arguments passed in registers, find the register number
2136 of the first argument in the variable part of the argument list,
2137 otherwise GP_ARG_LAST+1. Note also if the last argument is
2138 the varargs special argument, and treat it as part of the
2141 This is only needed if store_args_on_stack is true. */
2142 INIT_CUMULATIVE_ARGS (args_so_far
, fntype
, NULL_RTX
, 0, 0);
2143 regno
= GP_ARG_FIRST
;
2145 for (cur_arg
= fnargs
; cur_arg
!= 0; cur_arg
= next_arg
)
2147 tree passed_type
= DECL_ARG_TYPE (cur_arg
);
2148 enum machine_mode passed_mode
= TYPE_MODE (passed_type
);
2151 if (TREE_ADDRESSABLE (passed_type
))
2153 passed_type
= build_pointer_type (passed_type
);
2154 passed_mode
= Pmode
;
2157 entry_parm
= FUNCTION_ARG (args_so_far
, passed_mode
, passed_type
, 1);
2159 FUNCTION_ARG_ADVANCE (args_so_far
, passed_mode
, passed_type
, 1);
2160 next_arg
= TREE_CHAIN (cur_arg
);
2162 if (entry_parm
&& store_args_on_stack
)
2165 && DECL_NAME (cur_arg
)
2166 && ((0 == strcmp (IDENTIFIER_POINTER (DECL_NAME (cur_arg
)),
2167 "__builtin_va_alist"))
2168 || (0 == strcmp (IDENTIFIER_POINTER (DECL_NAME (cur_arg
)),
2171 last_arg_is_vararg_marker
= 1;
2178 if (GET_CODE (entry_parm
) != REG
)
2181 /* Passed in a register, so will get homed automatically. */
2182 if (GET_MODE (entry_parm
) == BLKmode
)
2183 words
= (int_size_in_bytes (passed_type
) + 3) / 4;
2185 words
= (GET_MODE_SIZE (GET_MODE (entry_parm
)) + 3) / 4;
2187 regno
= REGNO (entry_parm
) + words
- 1;
2192 regno
= GP_ARG_LAST
+1;
2197 /* In order to pass small structures by value in registers we need to
2198 shift the value into the high part of the register.
2199 Function_arg has encoded a PARALLEL rtx, holding a vector of
2200 adjustments to be made as the next_arg_reg variable, so we split up the
2201 insns, and emit them separately. */
2202 next_arg_reg
= FUNCTION_ARG (args_so_far
, VOIDmode
, void_type_node
, 1);
2203 if (next_arg_reg
!= 0 && GET_CODE (next_arg_reg
) == PARALLEL
)
2205 rtvec adjust
= XVEC (next_arg_reg
, 0);
2206 int num
= GET_NUM_ELEM (adjust
);
2208 for (i
= 0; i
< num
; i
++)
2212 pattern
= RTVEC_ELT (adjust
, i
);
2213 if (GET_CODE (pattern
) != SET
2214 || GET_CODE (SET_SRC (pattern
)) != ASHIFT
)
2215 abort_with_insn (pattern
, "Insn is not a shift");
2216 PUT_CODE (SET_SRC (pattern
), ASHIFTRT
);
2218 insn
= emit_insn (pattern
);
2220 /* Global life information isn't valid at this point, so we
2221 can't check whether these shifts are actually used. Mark
2222 them MAYBE_DEAD so that flow2 will remove them, and not
2223 complain about dead code in the prologue. */
2224 REG_NOTES(insn
) = gen_rtx_EXPR_LIST (REG_MAYBE_DEAD
, NULL_RTX
,
2229 tsize
= compute_frame_size (get_frame_size ());
2231 /* If this function is a varargs function, store any registers that
2232 would normally hold arguments ($4 - $7) on the stack. */
2233 if (store_args_on_stack
2234 && ((TYPE_ARG_TYPES (fntype
) != 0
2235 && (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype
)))
2237 || last_arg_is_vararg_marker
))
2239 int offset
= (regno
- GP_ARG_FIRST
) * UNITS_PER_WORD
;
2240 rtx ptr
= stack_pointer_rtx
;
2242 for (; regno
<= GP_ARG_LAST
; regno
++)
2245 ptr
= gen_rtx_PLUS (Pmode
, stack_pointer_rtx
, GEN_INT (offset
));
2246 emit_move_insn (gen_rtx_MEM (gpr_mode
, ptr
),
2247 gen_rtx_REG (gpr_mode
, regno
));
2249 offset
+= GET_MODE_SIZE (gpr_mode
);
2255 rtx tsize_rtx
= GEN_INT (tsize
);
2256 rtx adjustment_rtx
, insn
, dwarf_pattern
;
2260 adjustment_rtx
= gen_rtx_REG (Pmode
, IQ2000_TEMP1_REGNUM
);
2261 emit_move_insn (adjustment_rtx
, tsize_rtx
);
2264 adjustment_rtx
= tsize_rtx
;
2266 insn
= emit_insn (gen_subsi3 (stack_pointer_rtx
, stack_pointer_rtx
,
2269 dwarf_pattern
= gen_rtx_SET (Pmode
, stack_pointer_rtx
,
2270 plus_constant (stack_pointer_rtx
, -tsize
));
2272 iq2000_annotate_frame_insn (insn
, dwarf_pattern
);
2274 save_restore_insns (1);
2276 if (frame_pointer_needed
)
2280 insn
= emit_insn (gen_movsi (hard_frame_pointer_rtx
,
2281 stack_pointer_rtx
));
2284 RTX_FRAME_RELATED_P (insn
) = 1;
2288 emit_insn (gen_blockage ());
2291 /* Expand the epilogue into a bunch of separate insns. */
2294 iq2000_expand_epilogue (void)
2296 HOST_WIDE_INT tsize
= cfun
->machine
->total_size
;
2297 rtx tsize_rtx
= GEN_INT (tsize
);
2298 rtx tmp_rtx
= (rtx
)0;
2300 if (iq2000_can_use_return_insn ())
2302 emit_jump_insn (gen_return ());
2308 tmp_rtx
= gen_rtx_REG (Pmode
, IQ2000_TEMP1_REGNUM
);
2309 emit_move_insn (tmp_rtx
, tsize_rtx
);
2310 tsize_rtx
= tmp_rtx
;
2315 if (frame_pointer_needed
)
2317 emit_insn (gen_blockage ());
2319 emit_insn (gen_movsi (stack_pointer_rtx
, hard_frame_pointer_rtx
));
2322 save_restore_insns (0);
2324 if (current_function_calls_eh_return
)
2326 rtx eh_ofs
= EH_RETURN_STACKADJ_RTX
;
2327 emit_insn (gen_addsi3 (eh_ofs
, eh_ofs
, tsize_rtx
));
2331 emit_insn (gen_blockage ());
2333 if (tsize
!= 0 || current_function_calls_eh_return
)
2335 emit_insn (gen_addsi3 (stack_pointer_rtx
, stack_pointer_rtx
,
2340 if (current_function_calls_eh_return
)
2342 /* Perform the additional bump for __throw. */
2343 emit_move_insn (gen_rtx_REG (Pmode
, HARD_FRAME_POINTER_REGNUM
),
2345 emit_insn (gen_rtx_USE (VOIDmode
, gen_rtx_REG (Pmode
,
2346 HARD_FRAME_POINTER_REGNUM
)));
2347 emit_jump_insn (gen_eh_return_internal ());
2350 emit_jump_insn (gen_return_internal (gen_rtx_REG (Pmode
,
2351 GP_REG_FIRST
+ 31)));
2355 iq2000_expand_eh_return (rtx address
)
2357 HOST_WIDE_INT gp_offset
= cfun
->machine
->gp_sp_offset
;
2360 scratch
= plus_constant (stack_pointer_rtx
, gp_offset
);
2361 emit_move_insn (gen_rtx_MEM (GET_MODE (address
), scratch
), address
);
2364 /* Return nonzero if this function is known to have a null epilogue.
2365 This allows the optimizer to omit jumps to jumps if no stack
2369 iq2000_can_use_return_insn (void)
2371 if (! reload_completed
)
2374 if (regs_ever_live
[31] || profile_flag
)
2377 if (cfun
->machine
->initialized
)
2378 return cfun
->machine
->total_size
== 0;
2380 return compute_frame_size (get_frame_size ()) == 0;
2383 /* Returns nonzero if X contains a SYMBOL_REF. */
2386 symbolic_expression_p (rtx x
)
2388 if (GET_CODE (x
) == SYMBOL_REF
)
2391 if (GET_CODE (x
) == CONST
)
2392 return symbolic_expression_p (XEXP (x
, 0));
2395 return symbolic_expression_p (XEXP (x
, 0));
2397 if (ARITHMETIC_P (x
))
2398 return (symbolic_expression_p (XEXP (x
, 0))
2399 || symbolic_expression_p (XEXP (x
, 1)));
2404 /* Choose the section to use for the constant rtx expression X that has
2408 iq2000_select_rtx_section (enum machine_mode mode
, rtx x ATTRIBUTE_UNUSED
,
2409 unsigned HOST_WIDE_INT align
)
2411 /* For embedded applications, always put constants in read-only data,
2412 in order to reduce RAM usage. */
2413 /* For embedded applications, always put constants in read-only data,
2414 in order to reduce RAM usage. */
2415 mergeable_constant_section (mode
, align
, 0);
2418 /* Choose the section to use for DECL. RELOC is true if its value contains
2419 any relocatable expression.
2421 Some of the logic used here needs to be replicated in
2422 ENCODE_SECTION_INFO in iq2000.h so that references to these symbols
2423 are done correctly. */
2426 iq2000_select_section (tree decl
, int reloc ATTRIBUTE_UNUSED
,
2427 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED
)
2429 if (TARGET_EMBEDDED_DATA
)
2431 /* For embedded applications, always put an object in read-only data
2432 if possible, in order to reduce RAM usage. */
2433 if ((TREE_CODE (decl
) == VAR_DECL
2434 && TREE_READONLY (decl
) && !TREE_SIDE_EFFECTS (decl
)
2435 && DECL_INITIAL (decl
)
2436 && (DECL_INITIAL (decl
) == error_mark_node
2437 || TREE_CONSTANT (DECL_INITIAL (decl
))))
2438 /* Deal with calls from output_constant_def_contents. */
2439 || TREE_CODE (decl
) != VAR_DECL
)
2440 readonly_data_section ();
2446 /* For hosted applications, always put an object in small data if
2447 possible, as this gives the best performance. */
2448 if ((TREE_CODE (decl
) == VAR_DECL
2449 && TREE_READONLY (decl
) && !TREE_SIDE_EFFECTS (decl
)
2450 && DECL_INITIAL (decl
)
2451 && (DECL_INITIAL (decl
) == error_mark_node
2452 || TREE_CONSTANT (DECL_INITIAL (decl
))))
2453 /* Deal with calls from output_constant_def_contents. */
2454 || TREE_CODE (decl
) != VAR_DECL
)
2455 readonly_data_section ();
2460 /* Return register to use for a function return value with VALTYPE for function
2464 iq2000_function_value (tree valtype
, tree func ATTRIBUTE_UNUSED
)
2466 int reg
= GP_RETURN
;
2467 enum machine_mode mode
= TYPE_MODE (valtype
);
2468 int unsignedp
= TYPE_UNSIGNED (valtype
);
2470 /* Since we define TARGET_PROMOTE_FUNCTION_RETURN that returns true,
2471 we must promote the mode just as PROMOTE_MODE does. */
2472 mode
= promote_mode (valtype
, mode
, &unsignedp
, 1);
2474 return gen_rtx_REG (mode
, reg
);
2477 /* Return true when an argument must be passed by reference. */
2480 iq2000_pass_by_reference (CUMULATIVE_ARGS
*cum
, enum machine_mode mode
,
2481 tree type
, bool named ATTRIBUTE_UNUSED
)
2485 /* We must pass by reference if we would be both passing in registers
2486 and the stack. This is because any subsequent partial arg would be
2487 handled incorrectly in this case. */
2488 if (cum
&& targetm
.calls
.must_pass_in_stack (mode
, type
))
2490 /* Don't pass the actual CUM to FUNCTION_ARG, because we would
2491 get double copies of any offsets generated for small structs
2492 passed in registers. */
2493 CUMULATIVE_ARGS temp
;
2496 if (FUNCTION_ARG (temp
, mode
, type
, named
) != 0)
2500 if (type
== NULL_TREE
|| mode
== DImode
|| mode
== DFmode
)
2503 size
= int_size_in_bytes (type
);
2504 return size
== -1 || size
> UNITS_PER_WORD
;
2507 /* Return the length of INSN. LENGTH is the initial length computed by
2508 attributes in the machine-description file. */
2511 iq2000_adjust_insn_length (rtx insn
, int length
)
2513 /* A unconditional jump has an unfilled delay slot if it is not part
2514 of a sequence. A conditional jump normally has a delay slot. */
2515 if (simplejump_p (insn
)
2516 || ( (GET_CODE (insn
) == JUMP_INSN
2517 || GET_CODE (insn
) == CALL_INSN
)))
2523 /* Output assembly instructions to perform a conditional branch.
2525 INSN is the branch instruction. OPERANDS[0] is the condition.
2526 OPERANDS[1] is the target of the branch. OPERANDS[2] is the target
2527 of the first operand to the condition. If TWO_OPERANDS_P is
2528 nonzero the comparison takes two operands; OPERANDS[3] will be the
2531 If INVERTED_P is nonzero we are to branch if the condition does
2532 not hold. If FLOAT_P is nonzero this is a floating-point comparison.
2534 LENGTH is the length (in bytes) of the sequence we are to generate.
2535 That tells us whether to generate a simple conditional branch, or a
2536 reversed conditional branch around a `jr' instruction. */
2539 iq2000_output_conditional_branch (rtx insn
, rtx
* operands
, int two_operands_p
,
2540 int float_p
, int inverted_p
, int length
)
2542 static char buffer
[200];
2543 /* The kind of comparison we are doing. */
2544 enum rtx_code code
= GET_CODE (operands
[0]);
2545 /* Nonzero if the opcode for the comparison needs a `z' indicating
2546 that it is a comparison against zero. */
2548 /* A string to use in the assembly output to represent the first
2550 const char *op1
= "%z2";
2551 /* A string to use in the assembly output to represent the second
2552 operand. Use the hard-wired zero register if there's no second
2554 const char *op2
= (two_operands_p
? ",%z3" : ",%.");
2555 /* The operand-printing string for the comparison. */
2556 const char *comp
= (float_p
? "%F0" : "%C0");
2557 /* The operand-printing string for the inverted comparison. */
2558 const char *inverted_comp
= (float_p
? "%W0" : "%N0");
2560 /* Likely variants of each branch instruction annul the instruction
2561 in the delay slot if the branch is not taken. */
2562 iq2000_branch_likely
= (final_sequence
&& INSN_ANNULLED_BRANCH_P (insn
));
2564 if (!two_operands_p
)
2566 /* To compute whether than A > B, for example, we normally
2567 subtract B from A and then look at the sign bit. But, if we
2568 are doing an unsigned comparison, and B is zero, we don't
2569 have to do the subtraction. Instead, we can just check to
2570 see if A is nonzero. Thus, we change the CODE here to
2571 reflect the simpler comparison operation. */
2583 /* A condition which will always be true. */
2589 /* A condition which will always be false. */
2595 /* Not a special case. */
2600 /* Relative comparisons are always done against zero. But
2601 equality comparisons are done between two operands, and therefore
2602 do not require a `z' in the assembly language output. */
2603 need_z_p
= (!float_p
&& code
!= EQ
&& code
!= NE
);
2604 /* For comparisons against zero, the zero is not provided
2609 /* Begin by terminating the buffer. That way we can always use
2610 strcat to add to it. */
2617 /* Just a simple conditional branch. */
2619 sprintf (buffer
, "b%s%%?\t%%Z2%%1",
2620 inverted_p
? inverted_comp
: comp
);
2622 sprintf (buffer
, "b%s%s%%?\t%s%s,%%1",
2623 inverted_p
? inverted_comp
: comp
,
2624 need_z_p
? "z" : "",
2632 /* Generate a reversed conditional branch around ` j'
2644 Because we have to jump four bytes *past* the following
2645 instruction if this branch was annulled, we can't just use
2646 a label, as in the picture above; there's no way to put the
2647 label after the next instruction, as the assembler does not
2648 accept `.L+4' as the target of a branch. (We can't just
2649 wait until the next instruction is output; it might be a
2650 macro and take up more than four bytes. Once again, we see
2651 why we want to eliminate macros.)
2653 If the branch is annulled, we jump four more bytes that we
2654 would otherwise; that way we skip the annulled instruction
2655 in the delay slot. */
2658 = ((iq2000_branch_likely
|| length
== 16) ? ".+16" : ".+12");
2661 c
= strchr (buffer
, '\0');
2662 /* Generate the reversed comparison. This takes four
2665 sprintf (c
, "b%s\t%%Z2%s",
2666 inverted_p
? comp
: inverted_comp
,
2669 sprintf (c
, "b%s%s\t%s%s,%s",
2670 inverted_p
? comp
: inverted_comp
,
2671 need_z_p
? "z" : "",
2675 strcat (c
, "\n\tnop\n\tj\t%1");
2677 /* The delay slot was unfilled. Since we're inside
2678 .noreorder, the assembler will not fill in the NOP for
2679 us, so we must do it ourselves. */
2680 strcat (buffer
, "\n\tnop");
2692 #define def_builtin(NAME, TYPE, CODE) \
2693 lang_hooks.builtin_function ((NAME), (TYPE), (CODE), BUILT_IN_MD, \
2697 iq2000_init_builtins (void)
2699 tree endlink
= void_list_node
;
2700 tree void_ftype
, void_ftype_int
, void_ftype_int_int
;
2701 tree void_ftype_int_int_int
;
2702 tree int_ftype_int
, int_ftype_int_int
, int_ftype_int_int_int
;
2703 tree int_ftype_int_int_int_int
;
2707 = build_function_type (void_type_node
,
2708 tree_cons (NULL_TREE
, void_type_node
, endlink
));
2712 = build_function_type (void_type_node
,
2713 tree_cons (NULL_TREE
, integer_type_node
, endlink
));
2715 /* void func (int, int) */
2717 = build_function_type (void_type_node
,
2718 tree_cons (NULL_TREE
, integer_type_node
,
2719 tree_cons (NULL_TREE
, integer_type_node
,
2722 /* int func (int) */
2724 = build_function_type (integer_type_node
,
2725 tree_cons (NULL_TREE
, integer_type_node
, endlink
));
2727 /* int func (int, int) */
2729 = build_function_type (integer_type_node
,
2730 tree_cons (NULL_TREE
, integer_type_node
,
2731 tree_cons (NULL_TREE
, integer_type_node
,
2734 /* void func (int, int, int) */
2735 void_ftype_int_int_int
2736 = build_function_type
2738 tree_cons (NULL_TREE
, integer_type_node
,
2739 tree_cons (NULL_TREE
, integer_type_node
,
2740 tree_cons (NULL_TREE
,
2744 /* int func (int, int, int, int) */
2745 int_ftype_int_int_int_int
2746 = build_function_type
2748 tree_cons (NULL_TREE
, integer_type_node
,
2749 tree_cons (NULL_TREE
, integer_type_node
,
2750 tree_cons (NULL_TREE
,
2752 tree_cons (NULL_TREE
,
2756 /* int func (int, int, int) */
2757 int_ftype_int_int_int
2758 = build_function_type
2760 tree_cons (NULL_TREE
, integer_type_node
,
2761 tree_cons (NULL_TREE
, integer_type_node
,
2762 tree_cons (NULL_TREE
,
2766 /* int func (int, int, int, int) */
2767 int_ftype_int_int_int_int
2768 = build_function_type
2770 tree_cons (NULL_TREE
, integer_type_node
,
2771 tree_cons (NULL_TREE
, integer_type_node
,
2772 tree_cons (NULL_TREE
,
2774 tree_cons (NULL_TREE
,
2778 def_builtin ("__builtin_ado16", int_ftype_int_int
, IQ2000_BUILTIN_ADO16
);
2779 def_builtin ("__builtin_ram", int_ftype_int_int_int_int
, IQ2000_BUILTIN_RAM
);
2780 def_builtin ("__builtin_chkhdr", void_ftype_int_int
, IQ2000_BUILTIN_CHKHDR
);
2781 def_builtin ("__builtin_pkrl", void_ftype_int_int
, IQ2000_BUILTIN_PKRL
);
2782 def_builtin ("__builtin_cfc0", int_ftype_int
, IQ2000_BUILTIN_CFC0
);
2783 def_builtin ("__builtin_cfc1", int_ftype_int
, IQ2000_BUILTIN_CFC1
);
2784 def_builtin ("__builtin_cfc2", int_ftype_int
, IQ2000_BUILTIN_CFC2
);
2785 def_builtin ("__builtin_cfc3", int_ftype_int
, IQ2000_BUILTIN_CFC3
);
2786 def_builtin ("__builtin_ctc0", void_ftype_int_int
, IQ2000_BUILTIN_CTC0
);
2787 def_builtin ("__builtin_ctc1", void_ftype_int_int
, IQ2000_BUILTIN_CTC1
);
2788 def_builtin ("__builtin_ctc2", void_ftype_int_int
, IQ2000_BUILTIN_CTC2
);
2789 def_builtin ("__builtin_ctc3", void_ftype_int_int
, IQ2000_BUILTIN_CTC3
);
2790 def_builtin ("__builtin_mfc0", int_ftype_int
, IQ2000_BUILTIN_MFC0
);
2791 def_builtin ("__builtin_mfc1", int_ftype_int
, IQ2000_BUILTIN_MFC1
);
2792 def_builtin ("__builtin_mfc2", int_ftype_int
, IQ2000_BUILTIN_MFC2
);
2793 def_builtin ("__builtin_mfc3", int_ftype_int
, IQ2000_BUILTIN_MFC3
);
2794 def_builtin ("__builtin_mtc0", void_ftype_int_int
, IQ2000_BUILTIN_MTC0
);
2795 def_builtin ("__builtin_mtc1", void_ftype_int_int
, IQ2000_BUILTIN_MTC1
);
2796 def_builtin ("__builtin_mtc2", void_ftype_int_int
, IQ2000_BUILTIN_MTC2
);
2797 def_builtin ("__builtin_mtc3", void_ftype_int_int
, IQ2000_BUILTIN_MTC3
);
2798 def_builtin ("__builtin_lur", void_ftype_int_int
, IQ2000_BUILTIN_LUR
);
2799 def_builtin ("__builtin_rb", void_ftype_int_int
, IQ2000_BUILTIN_RB
);
2800 def_builtin ("__builtin_rx", void_ftype_int_int
, IQ2000_BUILTIN_RX
);
2801 def_builtin ("__builtin_srrd", void_ftype_int
, IQ2000_BUILTIN_SRRD
);
2802 def_builtin ("__builtin_srwr", void_ftype_int_int
, IQ2000_BUILTIN_SRWR
);
2803 def_builtin ("__builtin_wb", void_ftype_int_int
, IQ2000_BUILTIN_WB
);
2804 def_builtin ("__builtin_wx", void_ftype_int_int
, IQ2000_BUILTIN_WX
);
2805 def_builtin ("__builtin_luc32l", void_ftype_int_int
, IQ2000_BUILTIN_LUC32L
);
2806 def_builtin ("__builtin_luc64", void_ftype_int_int
, IQ2000_BUILTIN_LUC64
);
2807 def_builtin ("__builtin_luc64l", void_ftype_int_int
, IQ2000_BUILTIN_LUC64L
);
2808 def_builtin ("__builtin_luk", void_ftype_int_int
, IQ2000_BUILTIN_LUK
);
2809 def_builtin ("__builtin_lulck", void_ftype_int
, IQ2000_BUILTIN_LULCK
);
2810 def_builtin ("__builtin_lum32", void_ftype_int_int
, IQ2000_BUILTIN_LUM32
);
2811 def_builtin ("__builtin_lum32l", void_ftype_int_int
, IQ2000_BUILTIN_LUM32L
);
2812 def_builtin ("__builtin_lum64", void_ftype_int_int
, IQ2000_BUILTIN_LUM64
);
2813 def_builtin ("__builtin_lum64l", void_ftype_int_int
, IQ2000_BUILTIN_LUM64L
);
2814 def_builtin ("__builtin_lurl", void_ftype_int_int
, IQ2000_BUILTIN_LURL
);
2815 def_builtin ("__builtin_mrgb", int_ftype_int_int_int
, IQ2000_BUILTIN_MRGB
);
2816 def_builtin ("__builtin_srrdl", void_ftype_int
, IQ2000_BUILTIN_SRRDL
);
2817 def_builtin ("__builtin_srulck", void_ftype_int
, IQ2000_BUILTIN_SRULCK
);
2818 def_builtin ("__builtin_srwru", void_ftype_int_int
, IQ2000_BUILTIN_SRWRU
);
2819 def_builtin ("__builtin_trapqfl", void_ftype
, IQ2000_BUILTIN_TRAPQFL
);
2820 def_builtin ("__builtin_trapqne", void_ftype
, IQ2000_BUILTIN_TRAPQNE
);
2821 def_builtin ("__builtin_traprel", void_ftype_int
, IQ2000_BUILTIN_TRAPREL
);
2822 def_builtin ("__builtin_wbu", void_ftype_int_int_int
, IQ2000_BUILTIN_WBU
);
2823 def_builtin ("__builtin_syscall", void_ftype
, IQ2000_BUILTIN_SYSCALL
);
2826 /* Builtin for ICODE having ARGCOUNT args in ARGLIST where each arg
2830 expand_one_builtin (enum insn_code icode
, rtx target
, tree arglist
,
2831 enum rtx_code
*code
, int argcount
)
2836 enum machine_mode mode
[5];
2839 mode
[0] = insn_data
[icode
].operand
[0].mode
;
2840 for (i
= 0; i
< argcount
; i
++)
2842 arg
[i
] = TREE_VALUE (arglist
);
2843 arglist
= TREE_CHAIN (arglist
);
2844 op
[i
] = expand_expr (arg
[i
], NULL_RTX
, VOIDmode
, 0);
2845 mode
[i
] = insn_data
[icode
].operand
[i
].mode
;
2846 if (code
[i
] == CONST_INT
&& GET_CODE (op
[i
]) != CONST_INT
)
2847 error ("argument %qd is not a constant", i
+ 1);
2849 && ! (*insn_data
[icode
].operand
[i
].predicate
) (op
[i
], mode
[i
]))
2850 op
[i
] = copy_to_mode_reg (mode
[i
], op
[i
]);
2853 if (insn_data
[icode
].operand
[0].constraint
[0] == '=')
2856 || GET_MODE (target
) != mode
[0]
2857 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, mode
[0]))
2858 target
= gen_reg_rtx (mode
[0]);
2866 pat
= GEN_FCN (icode
) (target
);
2869 pat
= GEN_FCN (icode
) (target
, op
[0]);
2871 pat
= GEN_FCN (icode
) (op
[0]);
2875 pat
= GEN_FCN (icode
) (target
, op
[0], op
[1]);
2877 pat
= GEN_FCN (icode
) (op
[0], op
[1]);
2881 pat
= GEN_FCN (icode
) (target
, op
[0], op
[1], op
[2]);
2883 pat
= GEN_FCN (icode
) (op
[0], op
[1], op
[2]);
2887 pat
= GEN_FCN (icode
) (target
, op
[0], op
[1], op
[2], op
[3]);
2889 pat
= GEN_FCN (icode
) (op
[0], op
[1], op
[2], op
[3]);
2901 /* Expand an expression EXP that calls a built-in function,
2902 with result going to TARGET if that's convenient
2903 (and in mode MODE if that's convenient).
2904 SUBTARGET may be used as the target for computing one of EXP's operands.
2905 IGNORE is nonzero if the value is to be ignored. */
2908 iq2000_expand_builtin (tree exp
, rtx target
, rtx subtarget ATTRIBUTE_UNUSED
,
2909 enum machine_mode mode ATTRIBUTE_UNUSED
,
2910 int ignore ATTRIBUTE_UNUSED
)
2912 tree fndecl
= TREE_OPERAND (TREE_OPERAND (exp
, 0), 0);
2913 tree arglist
= TREE_OPERAND (exp
, 1);
2914 int fcode
= DECL_FUNCTION_CODE (fndecl
);
2915 enum rtx_code code
[5];
2927 case IQ2000_BUILTIN_ADO16
:
2928 return expand_one_builtin (CODE_FOR_ado16
, target
, arglist
, code
, 2);
2930 case IQ2000_BUILTIN_RAM
:
2931 code
[1] = CONST_INT
;
2932 code
[2] = CONST_INT
;
2933 code
[3] = CONST_INT
;
2934 return expand_one_builtin (CODE_FOR_ram
, target
, arglist
, code
, 4);
2936 case IQ2000_BUILTIN_CHKHDR
:
2937 return expand_one_builtin (CODE_FOR_chkhdr
, target
, arglist
, code
, 2);
2939 case IQ2000_BUILTIN_PKRL
:
2940 return expand_one_builtin (CODE_FOR_pkrl
, target
, arglist
, code
, 2);
2942 case IQ2000_BUILTIN_CFC0
:
2943 code
[0] = CONST_INT
;
2944 return expand_one_builtin (CODE_FOR_cfc0
, target
, arglist
, code
, 1);
2946 case IQ2000_BUILTIN_CFC1
:
2947 code
[0] = CONST_INT
;
2948 return expand_one_builtin (CODE_FOR_cfc1
, target
, arglist
, code
, 1);
2950 case IQ2000_BUILTIN_CFC2
:
2951 code
[0] = CONST_INT
;
2952 return expand_one_builtin (CODE_FOR_cfc2
, target
, arglist
, code
, 1);
2954 case IQ2000_BUILTIN_CFC3
:
2955 code
[0] = CONST_INT
;
2956 return expand_one_builtin (CODE_FOR_cfc3
, target
, arglist
, code
, 1);
2958 case IQ2000_BUILTIN_CTC0
:
2959 code
[1] = CONST_INT
;
2960 return expand_one_builtin (CODE_FOR_ctc0
, target
, arglist
, code
, 2);
2962 case IQ2000_BUILTIN_CTC1
:
2963 code
[1] = CONST_INT
;
2964 return expand_one_builtin (CODE_FOR_ctc1
, target
, arglist
, code
, 2);
2966 case IQ2000_BUILTIN_CTC2
:
2967 code
[1] = CONST_INT
;
2968 return expand_one_builtin (CODE_FOR_ctc2
, target
, arglist
, code
, 2);
2970 case IQ2000_BUILTIN_CTC3
:
2971 code
[1] = CONST_INT
;
2972 return expand_one_builtin (CODE_FOR_ctc3
, target
, arglist
, code
, 2);
2974 case IQ2000_BUILTIN_MFC0
:
2975 code
[0] = CONST_INT
;
2976 return expand_one_builtin (CODE_FOR_mfc0
, target
, arglist
, code
, 1);
2978 case IQ2000_BUILTIN_MFC1
:
2979 code
[0] = CONST_INT
;
2980 return expand_one_builtin (CODE_FOR_mfc1
, target
, arglist
, code
, 1);
2982 case IQ2000_BUILTIN_MFC2
:
2983 code
[0] = CONST_INT
;
2984 return expand_one_builtin (CODE_FOR_mfc2
, target
, arglist
, code
, 1);
2986 case IQ2000_BUILTIN_MFC3
:
2987 code
[0] = CONST_INT
;
2988 return expand_one_builtin (CODE_FOR_mfc3
, target
, arglist
, code
, 1);
2990 case IQ2000_BUILTIN_MTC0
:
2991 code
[1] = CONST_INT
;
2992 return expand_one_builtin (CODE_FOR_mtc0
, target
, arglist
, code
, 2);
2994 case IQ2000_BUILTIN_MTC1
:
2995 code
[1] = CONST_INT
;
2996 return expand_one_builtin (CODE_FOR_mtc1
, target
, arglist
, code
, 2);
2998 case IQ2000_BUILTIN_MTC2
:
2999 code
[1] = CONST_INT
;
3000 return expand_one_builtin (CODE_FOR_mtc2
, target
, arglist
, code
, 2);
3002 case IQ2000_BUILTIN_MTC3
:
3003 code
[1] = CONST_INT
;
3004 return expand_one_builtin (CODE_FOR_mtc3
, target
, arglist
, code
, 2);
3006 case IQ2000_BUILTIN_LUR
:
3007 return expand_one_builtin (CODE_FOR_lur
, target
, arglist
, code
, 2);
3009 case IQ2000_BUILTIN_RB
:
3010 return expand_one_builtin (CODE_FOR_rb
, target
, arglist
, code
, 2);
3012 case IQ2000_BUILTIN_RX
:
3013 return expand_one_builtin (CODE_FOR_rx
, target
, arglist
, code
, 2);
3015 case IQ2000_BUILTIN_SRRD
:
3016 return expand_one_builtin (CODE_FOR_srrd
, target
, arglist
, code
, 1);
3018 case IQ2000_BUILTIN_SRWR
:
3019 return expand_one_builtin (CODE_FOR_srwr
, target
, arglist
, code
, 2);
3021 case IQ2000_BUILTIN_WB
:
3022 return expand_one_builtin (CODE_FOR_wb
, target
, arglist
, code
, 2);
3024 case IQ2000_BUILTIN_WX
:
3025 return expand_one_builtin (CODE_FOR_wx
, target
, arglist
, code
, 2);
3027 case IQ2000_BUILTIN_LUC32L
:
3028 return expand_one_builtin (CODE_FOR_luc32l
, target
, arglist
, code
, 2);
3030 case IQ2000_BUILTIN_LUC64
:
3031 return expand_one_builtin (CODE_FOR_luc64
, target
, arglist
, code
, 2);
3033 case IQ2000_BUILTIN_LUC64L
:
3034 return expand_one_builtin (CODE_FOR_luc64l
, target
, arglist
, code
, 2);
3036 case IQ2000_BUILTIN_LUK
:
3037 return expand_one_builtin (CODE_FOR_luk
, target
, arglist
, code
, 2);
3039 case IQ2000_BUILTIN_LULCK
:
3040 return expand_one_builtin (CODE_FOR_lulck
, target
, arglist
, code
, 1);
3042 case IQ2000_BUILTIN_LUM32
:
3043 return expand_one_builtin (CODE_FOR_lum32
, target
, arglist
, code
, 2);
3045 case IQ2000_BUILTIN_LUM32L
:
3046 return expand_one_builtin (CODE_FOR_lum32l
, target
, arglist
, code
, 2);
3048 case IQ2000_BUILTIN_LUM64
:
3049 return expand_one_builtin (CODE_FOR_lum64
, target
, arglist
, code
, 2);
3051 case IQ2000_BUILTIN_LUM64L
:
3052 return expand_one_builtin (CODE_FOR_lum64l
, target
, arglist
, code
, 2);
3054 case IQ2000_BUILTIN_LURL
:
3055 return expand_one_builtin (CODE_FOR_lurl
, target
, arglist
, code
, 2);
3057 case IQ2000_BUILTIN_MRGB
:
3058 code
[2] = CONST_INT
;
3059 return expand_one_builtin (CODE_FOR_mrgb
, target
, arglist
, code
, 3);
3061 case IQ2000_BUILTIN_SRRDL
:
3062 return expand_one_builtin (CODE_FOR_srrdl
, target
, arglist
, code
, 1);
3064 case IQ2000_BUILTIN_SRULCK
:
3065 return expand_one_builtin (CODE_FOR_srulck
, target
, arglist
, code
, 1);
3067 case IQ2000_BUILTIN_SRWRU
:
3068 return expand_one_builtin (CODE_FOR_srwru
, target
, arglist
, code
, 2);
3070 case IQ2000_BUILTIN_TRAPQFL
:
3071 return expand_one_builtin (CODE_FOR_trapqfl
, target
, arglist
, code
, 0);
3073 case IQ2000_BUILTIN_TRAPQNE
:
3074 return expand_one_builtin (CODE_FOR_trapqne
, target
, arglist
, code
, 0);
3076 case IQ2000_BUILTIN_TRAPREL
:
3077 return expand_one_builtin (CODE_FOR_traprel
, target
, arglist
, code
, 1);
3079 case IQ2000_BUILTIN_WBU
:
3080 return expand_one_builtin (CODE_FOR_wbu
, target
, arglist
, code
, 3);
3082 case IQ2000_BUILTIN_SYSCALL
:
3083 return expand_one_builtin (CODE_FOR_syscall
, target
, arglist
, code
, 0);
3089 /* Worker function for TARGET_RETURN_IN_MEMORY. */
3092 iq2000_return_in_memory (tree type
, tree fntype ATTRIBUTE_UNUSED
)
3094 return ((int_size_in_bytes (type
) > (2 * UNITS_PER_WORD
))
3095 || (int_size_in_bytes (type
) == -1));
3098 /* Worker function for TARGET_SETUP_INCOMING_VARARGS. */
3101 iq2000_setup_incoming_varargs (CUMULATIVE_ARGS
*cum
,
3102 enum machine_mode mode ATTRIBUTE_UNUSED
,
3103 tree type ATTRIBUTE_UNUSED
, int * pretend_size
,
3106 unsigned int iq2000_off
= ! cum
->last_arg_fp
;
3107 unsigned int iq2000_fp_off
= cum
->last_arg_fp
;
3109 if ((cum
->arg_words
< MAX_ARGS_IN_REGISTERS
- iq2000_off
))
3111 int iq2000_save_gp_regs
3112 = MAX_ARGS_IN_REGISTERS
- cum
->arg_words
- iq2000_off
;
3113 int iq2000_save_fp_regs
3114 = (MAX_ARGS_IN_REGISTERS
- cum
->fp_arg_words
- iq2000_fp_off
);
3116 if (iq2000_save_gp_regs
< 0)
3117 iq2000_save_gp_regs
= 0;
3118 if (iq2000_save_fp_regs
< 0)
3119 iq2000_save_fp_regs
= 0;
3121 *pretend_size
= ((iq2000_save_gp_regs
* UNITS_PER_WORD
)
3122 + (iq2000_save_fp_regs
* UNITS_PER_FPREG
));
3126 if (cum
->arg_words
< MAX_ARGS_IN_REGISTERS
- iq2000_off
)
3129 ptr
= plus_constant (virtual_incoming_args_rtx
,
3130 - (iq2000_save_gp_regs
3132 mem
= gen_rtx_MEM (BLKmode
, ptr
);
3134 (cum
->arg_words
+ GP_ARG_FIRST
+ iq2000_off
,
3136 iq2000_save_gp_regs
);
3142 /* A C compound statement to output to stdio stream STREAM the
3143 assembler syntax for an instruction operand that is a memory
3144 reference whose address is ADDR. ADDR is an RTL expression. */
3147 print_operand_address (FILE * file
, rtx addr
)
3150 error ("PRINT_OPERAND_ADDRESS, null pointer");
3153 switch (GET_CODE (addr
))
3156 if (REGNO (addr
) == ARG_POINTER_REGNUM
)
3157 abort_with_insn (addr
, "Arg pointer not eliminated.");
3159 fprintf (file
, "0(%s)", reg_names
[REGNO (addr
)]);
3164 rtx arg0
= XEXP (addr
, 0);
3165 rtx arg1
= XEXP (addr
, 1);
3167 if (GET_CODE (arg0
) != REG
)
3168 abort_with_insn (addr
,
3169 "PRINT_OPERAND_ADDRESS, LO_SUM with #1 not REG.");
3171 fprintf (file
, "%%lo(");
3172 print_operand_address (file
, arg1
);
3173 fprintf (file
, ")(%s)", reg_names
[REGNO (arg0
)]);
3181 rtx arg0
= XEXP (addr
, 0);
3182 rtx arg1
= XEXP (addr
, 1);
3184 if (GET_CODE (arg0
) == REG
)
3188 if (GET_CODE (offset
) == REG
)
3189 abort_with_insn (addr
, "PRINT_OPERAND_ADDRESS, 2 regs");
3192 else if (GET_CODE (arg1
) == REG
)
3193 reg
= arg1
, offset
= arg0
;
3194 else if (CONSTANT_P (arg0
) && CONSTANT_P (arg1
))
3196 output_addr_const (file
, addr
);
3200 abort_with_insn (addr
, "PRINT_OPERAND_ADDRESS, no regs");
3202 if (! CONSTANT_P (offset
))
3203 abort_with_insn (addr
, "PRINT_OPERAND_ADDRESS, invalid insn #2");
3205 if (REGNO (reg
) == ARG_POINTER_REGNUM
)
3206 abort_with_insn (addr
, "Arg pointer not eliminated.");
3208 output_addr_const (file
, offset
);
3209 fprintf (file
, "(%s)", reg_names
[REGNO (reg
)]);
3217 output_addr_const (file
, addr
);
3218 if (GET_CODE (addr
) == CONST_INT
)
3219 fprintf (file
, "(%s)", reg_names
[0]);
3223 abort_with_insn (addr
, "PRINT_OPERAND_ADDRESS, invalid insn #1");
3228 /* A C compound statement to output to stdio stream FILE the
3229 assembler syntax for an instruction operand OP.
3231 LETTER is a value that can be used to specify one of several ways
3232 of printing the operand. It is used when identical operands
3233 must be printed differently depending on the context. LETTER
3234 comes from the `%' specification that was used to request
3235 printing of the operand. If the specification was just `%DIGIT'
3236 then LETTER is 0; if the specification was `%LTR DIGIT' then LETTER
3237 is the ASCII code for LTR.
3239 If OP is a register, this macro should print the register's name.
3240 The names can be found in an array `reg_names' whose type is
3241 `char *[]'. `reg_names' is initialized from `REGISTER_NAMES'.
3243 When the machine description has a specification `%PUNCT' (a `%'
3244 followed by a punctuation character), this macro is called with
3245 a null pointer for X and the punctuation character for LETTER.
3247 The IQ2000 specific codes are:
3249 'X' X is CONST_INT, prints upper 16 bits in hexadecimal format = "0x%04x",
3250 'x' X is CONST_INT, prints lower 16 bits in hexadecimal format = "0x%04x",
3251 'd' output integer constant in decimal,
3252 'z' if the operand is 0, use $0 instead of normal operand.
3253 'D' print second part of double-word register or memory operand.
3254 'L' print low-order register of double-word register operand.
3255 'M' print high-order register of double-word register operand.
3256 'C' print part of opcode for a branch condition.
3257 'F' print part of opcode for a floating-point branch condition.
3258 'N' print part of opcode for a branch condition, inverted.
3259 'W' print part of opcode for a floating-point branch condition, inverted.
3260 'A' Print part of opcode for a bit test condition.
3261 'P' Print label for a bit test.
3262 'p' Print log for a bit test.
3263 'B' print 'z' for EQ, 'n' for NE
3264 'b' print 'n' for EQ, 'z' for NE
3265 'T' print 'f' for EQ, 't' for NE
3266 't' print 't' for EQ, 'f' for NE
3267 'Z' print register and a comma, but print nothing for $fcc0
3268 '?' Print 'l' if we are to use a branch likely instead of normal branch.
3269 '@' Print the name of the assembler temporary register (at or $1).
3270 '.' Print the name of the register with a hard-wired zero (zero or $0).
3271 '$' Print the name of the stack pointer register (sp or $29).
3272 '+' Print the name of the gp register (gp or $28). */
3275 print_operand (FILE *file
, rtx op
, int letter
)
3279 if (PRINT_OPERAND_PUNCT_VALID_P (letter
))
3284 if (iq2000_branch_likely
)
3289 fputs (reg_names
[GP_REG_FIRST
+ 1], file
);
3293 fputs (reg_names
[GP_REG_FIRST
+ 0], file
);
3297 fputs (reg_names
[STACK_POINTER_REGNUM
], file
);
3301 fputs (reg_names
[GP_REG_FIRST
+ 28], file
);
3305 error ("PRINT_OPERAND: Unknown punctuation '%c'", letter
);
3314 error ("PRINT_OPERAND null pointer");
3318 code
= GET_CODE (op
);
3320 if (code
== SIGN_EXTEND
)
3321 op
= XEXP (op
, 0), code
= GET_CODE (op
);
3326 case EQ
: fputs ("eq", file
); break;
3327 case NE
: fputs ("ne", file
); break;
3328 case GT
: fputs ("gt", file
); break;
3329 case GE
: fputs ("ge", file
); break;
3330 case LT
: fputs ("lt", file
); break;
3331 case LE
: fputs ("le", file
); break;
3332 case GTU
: fputs ("ne", file
); break;
3333 case GEU
: fputs ("geu", file
); break;
3334 case LTU
: fputs ("ltu", file
); break;
3335 case LEU
: fputs ("eq", file
); break;
3337 abort_with_insn (op
, "PRINT_OPERAND, invalid insn for %%C");
3340 else if (letter
== 'N')
3343 case EQ
: fputs ("ne", file
); break;
3344 case NE
: fputs ("eq", file
); break;
3345 case GT
: fputs ("le", file
); break;
3346 case GE
: fputs ("lt", file
); break;
3347 case LT
: fputs ("ge", file
); break;
3348 case LE
: fputs ("gt", file
); break;
3349 case GTU
: fputs ("leu", file
); break;
3350 case GEU
: fputs ("ltu", file
); break;
3351 case LTU
: fputs ("geu", file
); break;
3352 case LEU
: fputs ("gtu", file
); break;
3354 abort_with_insn (op
, "PRINT_OPERAND, invalid insn for %%N");
3357 else if (letter
== 'F')
3360 case EQ
: fputs ("c1f", file
); break;
3361 case NE
: fputs ("c1t", file
); break;
3363 abort_with_insn (op
, "PRINT_OPERAND, invalid insn for %%F");
3366 else if (letter
== 'W')
3369 case EQ
: fputs ("c1t", file
); break;
3370 case NE
: fputs ("c1f", file
); break;
3372 abort_with_insn (op
, "PRINT_OPERAND, invalid insn for %%W");
3375 else if (letter
== 'A')
3376 fputs (code
== LABEL_REF
? "i" : "in", file
);
3378 else if (letter
== 'P')
3380 if (code
== LABEL_REF
)
3381 output_addr_const (file
, op
);
3382 else if (code
!= PC
)
3383 output_operand_lossage ("invalid %%P operand");
3386 else if (letter
== 'p')
3389 if (code
!= CONST_INT
3390 || (value
= exact_log2 (INTVAL (op
))) < 0)
3391 output_operand_lossage ("invalid %%p value");
3392 fprintf (file
, "%d", value
);
3395 else if (letter
== 'Z')
3402 regnum
= REGNO (op
);
3405 fprintf (file
, "%s,", reg_names
[regnum
]);
3408 else if (code
== REG
|| code
== SUBREG
)
3413 regnum
= REGNO (op
);
3415 regnum
= true_regnum (op
);
3417 if ((letter
== 'M' && ! WORDS_BIG_ENDIAN
)
3418 || (letter
== 'L' && WORDS_BIG_ENDIAN
)
3422 fprintf (file
, "%s", reg_names
[regnum
]);
3425 else if (code
== MEM
)
3428 output_address (plus_constant (XEXP (op
, 0), 4));
3430 output_address (XEXP (op
, 0));
3433 else if (code
== CONST_DOUBLE
3434 && GET_MODE_CLASS (GET_MODE (op
)) == MODE_FLOAT
)
3438 real_to_decimal (s
, CONST_DOUBLE_REAL_VALUE (op
), sizeof (s
), 0, 1);
3442 else if (letter
== 'x' && GET_CODE (op
) == CONST_INT
)
3443 fprintf (file
, HOST_WIDE_INT_PRINT_HEX
, 0xffff & INTVAL(op
));
3445 else if (letter
== 'X' && GET_CODE(op
) == CONST_INT
)
3446 fprintf (file
, HOST_WIDE_INT_PRINT_HEX
, 0xffff & (INTVAL (op
) >> 16));
3448 else if (letter
== 'd' && GET_CODE(op
) == CONST_INT
)
3449 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, (INTVAL(op
)));
3451 else if (letter
== 'z' && GET_CODE (op
) == CONST_INT
&& INTVAL (op
) == 0)
3452 fputs (reg_names
[GP_REG_FIRST
], file
);
3454 else if (letter
== 'd' || letter
== 'x' || letter
== 'X')
3455 output_operand_lossage ("invalid use of %%d, %%x, or %%X");
3457 else if (letter
== 'B')
3458 fputs (code
== EQ
? "z" : "n", file
);
3459 else if (letter
== 'b')
3460 fputs (code
== EQ
? "n" : "z", file
);
3461 else if (letter
== 'T')
3462 fputs (code
== EQ
? "f" : "t", file
);
3463 else if (letter
== 't')
3464 fputs (code
== EQ
? "t" : "f", file
);
3466 else if (code
== CONST
&& GET_CODE (XEXP (op
, 0)) == REG
)
3468 print_operand (file
, XEXP (op
, 0), letter
);
3472 output_addr_const (file
, op
);
3476 iq2000_rtx_costs (rtx x
, int code
, int outer_code ATTRIBUTE_UNUSED
, int * total
)
3478 enum machine_mode mode
= GET_MODE (x
);
3484 int num_words
= (GET_MODE_SIZE (mode
) > UNITS_PER_WORD
) ? 2 : 1;
3486 if (simple_memory_operand (x
, mode
))
3487 return COSTS_N_INSNS (num_words
);
3489 * total
= COSTS_N_INSNS (2 * num_words
);
3494 * total
= COSTS_N_INSNS (6);
3501 * total
= COSTS_N_INSNS (mode
== DImode
? 2 : 1);
3508 * total
= COSTS_N_INSNS ((GET_CODE (XEXP (x
, 1)) == CONST_INT
) ? 4 : 12);
3510 * total
= COSTS_N_INSNS (1);
3514 if (mode
== SFmode
|| mode
== DFmode
)
3515 * total
= COSTS_N_INSNS (1);
3517 * total
= COSTS_N_INSNS (4);
3522 if (mode
== SFmode
|| mode
== DFmode
)
3523 * total
= COSTS_N_INSNS (6);
3524 else if (mode
== DImode
)
3525 * total
= COSTS_N_INSNS (4);
3527 * total
= COSTS_N_INSNS (1);
3531 * total
= (mode
== DImode
) ? 4 : 1;
3536 * total
= COSTS_N_INSNS (7);
3537 else if (mode
== DFmode
)
3538 * total
= COSTS_N_INSNS (8);
3540 * total
= COSTS_N_INSNS (10);
3546 * total
= COSTS_N_INSNS (23);
3547 else if (mode
== DFmode
)
3548 * total
= COSTS_N_INSNS (36);
3550 * total
= COSTS_N_INSNS (69);
3555 * total
= COSTS_N_INSNS (69);
3559 * total
= COSTS_N_INSNS (2);
3563 * total
= COSTS_N_INSNS (1);
3571 * total
= COSTS_N_INSNS (2);
3576 rtx offset
= const0_rtx
;
3577 rtx symref
= eliminate_constant_term (XEXP (x
, 0), & offset
);
3579 if (GET_CODE (symref
) == LABEL_REF
)
3580 * total
= COSTS_N_INSNS (2);
3581 else if (GET_CODE (symref
) != SYMBOL_REF
)
3582 * total
= COSTS_N_INSNS (4);
3583 /* Let's be paranoid.... */
3584 else if (INTVAL (offset
) < -32768 || INTVAL (offset
) > 32767)
3585 * total
= COSTS_N_INSNS (2);
3587 * total
= COSTS_N_INSNS (SYMBOL_REF_FLAG (symref
) ? 1 : 2);
3592 * total
= COSTS_N_INSNS (SYMBOL_REF_FLAG (x
) ? 1 : 2);
3599 split_double (x
, & high
, & low
);
3601 * total
= COSTS_N_INSNS ( (high
== CONST0_RTX (GET_MODE (high
))
3602 || low
== CONST0_RTX (GET_MODE (low
)))
3613 #include "gt-iq2000.h"