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"
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 /* Strings to hold which cpu and instruction set architecture to use. */
128 const char * iq2000_cpu_string
; /* For -mcpu=<xxx>. */
129 const char * iq2000_arch_string
; /* For -march=<xxx>. */
132 /* Local variables. */
134 /* The next branch instruction is a branch likely, not branch normal. */
135 static int iq2000_branch_likely
;
137 /* Count of delay slots and how many are filled. */
138 static int dslots_load_total
;
139 static int dslots_load_filled
;
140 static int dslots_jump_total
;
142 /* # of nops needed by previous insn. */
143 static int dslots_number_nops
;
145 /* Number of 1/2/3 word references to data items (ie, not jal's). */
146 static int num_refs
[3];
148 /* Registers to check for load delay. */
149 static rtx iq2000_load_reg
;
150 static rtx iq2000_load_reg2
;
151 static rtx iq2000_load_reg3
;
152 static rtx iq2000_load_reg4
;
154 /* The target cpu for code generation. */
155 static enum processor_type iq2000_arch
;
157 /* Mode used for saving/restoring general purpose registers. */
158 static enum machine_mode gpr_mode
;
161 /* Initialize the GCC target structure. */
162 static struct machine_function
* iq2000_init_machine_status (void);
163 static void iq2000_select_rtx_section (enum machine_mode
, rtx
, unsigned HOST_WIDE_INT
);
164 static void iq2000_init_builtins (void);
165 static rtx
iq2000_expand_builtin (tree
, rtx
, rtx
, enum machine_mode
, int);
166 static bool iq2000_return_in_memory (tree
, tree
);
167 static void iq2000_setup_incoming_varargs (CUMULATIVE_ARGS
*,
168 enum machine_mode
, tree
, int *,
170 static bool iq2000_rtx_costs (rtx
, int, int, int *);
171 static int iq2000_address_cost (rtx
);
172 static void iq2000_select_section (tree
, int, unsigned HOST_WIDE_INT
);
173 static bool iq2000_return_in_memory (tree
, tree
);
175 #undef TARGET_INIT_BUILTINS
176 #define TARGET_INIT_BUILTINS iq2000_init_builtins
177 #undef TARGET_EXPAND_BUILTIN
178 #define TARGET_EXPAND_BUILTIN iq2000_expand_builtin
179 #undef TARGET_ASM_SELECT_RTX_SECTION
180 #define TARGET_ASM_SELECT_RTX_SECTION iq2000_select_rtx_section
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 #undef TARGET_PROMOTE_FUNCTION_ARGS
189 #define TARGET_PROMOTE_FUNCTION_ARGS hook_bool_tree_true
190 #undef TARGET_PROMOTE_FUNCTION_RETURN
191 #define TARGET_PROMOTE_FUNCTION_RETURN hook_bool_tree_true
192 #undef TARGET_PROMOTE_PROTOTYPES
193 #define TARGET_PROMOTE_PROTOTYPES hook_bool_tree_true
195 #undef TARGET_STRUCT_VALUE_RTX
196 #define TARGET_STRUCT_VALUE_RTX hook_rtx_tree_int_null
197 #undef TARGET_RETURN_IN_MEMORY
198 #define TARGET_RETURN_IN_MEMORY iq2000_return_in_memory
200 #undef TARGET_SETUP_INCOMING_VARARGS
201 #define TARGET_SETUP_INCOMING_VARARGS iq2000_setup_incoming_varargs
202 #undef TARGET_STRICT_ARGUMENT_NAMING
203 #define TARGET_STRICT_ARGUMENT_NAMING hook_bool_CUMULATIVE_ARGS_true
205 struct gcc_target targetm
= TARGET_INITIALIZER
;
207 /* Return 1 if OP can be used as an operand where a register or 16 bit unsigned
208 integer is needed. */
211 uns_arith_operand (rtx op
, enum machine_mode mode
)
213 if (GET_CODE (op
) == CONST_INT
&& SMALL_INT_UNSIGNED (op
))
216 return register_operand (op
, mode
);
219 /* Return 1 if OP can be used as an operand where a 16 bit integer is needed. */
222 arith_operand (rtx op
, enum machine_mode mode
)
224 if (GET_CODE (op
) == CONST_INT
&& SMALL_INT (op
))
227 return register_operand (op
, mode
);
230 /* Return 1 if OP is a integer which fits in 16 bits. */
233 small_int (rtx op
, enum machine_mode mode ATTRIBUTE_UNUSED
)
235 return (GET_CODE (op
) == CONST_INT
&& SMALL_INT (op
));
238 /* Return 1 if OP is a 32 bit integer which is too big to be loaded with one
242 large_int (rtx op
, enum machine_mode mode ATTRIBUTE_UNUSED
)
246 if (GET_CODE (op
) != CONST_INT
)
251 /* IOR reg,$r0,value. */
252 if ((value
& ~ ((HOST_WIDE_INT
) 0x0000ffff)) == 0)
255 /* SUBU reg,$r0,value. */
256 if (((unsigned HOST_WIDE_INT
) (value
+ 32768)) <= 32767)
259 /* LUI reg,value >> 16. */
260 if ((value
& 0x0000ffff) == 0)
266 /* Return 1 if OP is a register or the constant 0. */
269 reg_or_0_operand (rtx op
, enum machine_mode mode
)
271 switch (GET_CODE (op
))
274 return INTVAL (op
) == 0;
277 return op
== CONST0_RTX (mode
);
281 return register_operand (op
, mode
);
290 /* Return 1 if OP is a memory operand that fits in a single instruction
291 (ie, register + small offset). */
294 simple_memory_operand (rtx op
, enum machine_mode mode ATTRIBUTE_UNUSED
)
296 rtx addr
, plus0
, plus1
;
298 /* Eliminate non-memory operations. */
299 if (GET_CODE (op
) != MEM
)
302 /* Dword operations really put out 2 instructions, so eliminate them. */
303 if (GET_MODE_SIZE (GET_MODE (op
)) > (unsigned) UNITS_PER_WORD
)
306 /* Decode the address now. */
308 switch (GET_CODE (addr
))
315 return SMALL_INT (addr
);
318 plus0
= XEXP (addr
, 0);
319 plus1
= XEXP (addr
, 1);
320 if (GET_CODE (plus0
) == REG
321 && GET_CODE (plus1
) == CONST_INT
&& SMALL_INT (plus1
)
322 && SMALL_INT_UNSIGNED (plus1
) /* No negative offsets. */)
325 else if (GET_CODE (plus1
) == REG
326 && GET_CODE (plus0
) == CONST_INT
&& SMALL_INT (plus0
)
327 && SMALL_INT_UNSIGNED (plus1
) /* No negative offsets. */)
343 /* Return nonzero if the code of this rtx pattern is EQ or NE. */
346 equality_op (rtx op
, enum machine_mode mode
)
348 if (mode
!= GET_MODE (op
))
351 return GET_CODE (op
) == EQ
|| GET_CODE (op
) == NE
;
354 /* Return nonzero if the code is a relational operations (EQ, LE, etc). */
357 cmp_op (rtx op
, enum machine_mode mode
)
359 if (mode
!= GET_MODE (op
))
362 return GET_RTX_CLASS (GET_CODE (op
)) == '<';
365 /* Return nonzero if the operand is either the PC or a label_ref. */
368 pc_or_label_operand (rtx op
, enum machine_mode mode ATTRIBUTE_UNUSED
)
373 if (GET_CODE (op
) == LABEL_REF
)
379 /* Return nonzero if OP is a valid operand for a call instruction. */
382 call_insn_operand (rtx op
, enum machine_mode mode ATTRIBUTE_UNUSED
)
384 return (CONSTANT_ADDRESS_P (op
)
385 || (GET_CODE (op
) == REG
&& op
!= arg_pointer_rtx
386 && ! (REGNO (op
) >= FIRST_PSEUDO_REGISTER
387 && REGNO (op
) <= LAST_VIRTUAL_REGISTER
)));
390 /* Return nonzero if OP is valid as a source operand for a move instruction. */
393 move_operand (rtx op
, enum machine_mode mode
)
395 /* Accept any general operand after reload has started; doing so
396 avoids losing if reload does an in-place replacement of a register
397 with a SYMBOL_REF or CONST. */
398 return (general_operand (op
, mode
)
399 && (! (iq2000_check_split (op
, mode
))
400 || reload_in_progress
|| reload_completed
));
403 /* Return nonzero if OP is a constant power of 2. */
406 power_of_2_operand (rtx op
, enum machine_mode mode ATTRIBUTE_UNUSED
)
410 if (GET_CODE (op
) != CONST_INT
)
413 intval
= INTVAL (op
);
415 return ((intval
& ((unsigned)(intval
) - 1)) == 0);
418 /* Return nonzero if we split the address into high and low parts. */
421 iq2000_check_split (rtx address
, enum machine_mode mode
)
423 /* This is the same check used in simple_memory_operand.
424 We use it here because LO_SUM is not offsettable. */
425 if (GET_MODE_SIZE (mode
) > (unsigned) UNITS_PER_WORD
)
428 if ((GET_CODE (address
) == SYMBOL_REF
)
429 || (GET_CODE (address
) == CONST
430 && GET_CODE (XEXP (XEXP (address
, 0), 0)) == SYMBOL_REF
)
431 || GET_CODE (address
) == LABEL_REF
)
437 /* Return nonzero if REG is valid for MODE. */
440 iq2000_reg_mode_ok_for_base_p (rtx reg
,
441 enum machine_mode mode ATTRIBUTE_UNUSED
,
445 ? REGNO_MODE_OK_FOR_BASE_P (REGNO (reg
), mode
)
446 : GP_REG_OR_PSEUDO_NONSTRICT_P (REGNO (reg
), mode
));
449 /* Return a nonzero value if XINSN is a legitimate address for a
450 memory operand of the indicated MODE. STRICT is nonzero if this
451 function is called during reload. */
454 iq2000_legitimate_address_p (enum machine_mode mode
, rtx xinsn
, int strict
)
456 if (TARGET_DEBUG_A_MODE
)
458 GO_PRINTF2 ("\n========== GO_IF_LEGITIMATE_ADDRESS, %sstrict\n",
459 strict
? "" : "not ");
460 GO_DEBUG_RTX (xinsn
);
463 /* Check for constant before stripping off SUBREG, so that we don't
464 accept (subreg (const_int)) which will fail to reload. */
465 if (CONSTANT_ADDRESS_P (xinsn
)
466 && ! (iq2000_check_split (xinsn
, mode
))
467 && ! (GET_CODE (xinsn
) == CONST_INT
&& ! SMALL_INT (xinsn
)))
470 while (GET_CODE (xinsn
) == SUBREG
)
471 xinsn
= SUBREG_REG (xinsn
);
473 if (GET_CODE (xinsn
) == REG
474 && iq2000_reg_mode_ok_for_base_p (xinsn
, mode
, strict
))
477 if (GET_CODE (xinsn
) == LO_SUM
)
479 rtx xlow0
= XEXP (xinsn
, 0);
480 rtx xlow1
= XEXP (xinsn
, 1);
482 while (GET_CODE (xlow0
) == SUBREG
)
483 xlow0
= SUBREG_REG (xlow0
);
484 if (GET_CODE (xlow0
) == REG
485 && iq2000_reg_mode_ok_for_base_p (xlow0
, mode
, strict
)
486 && iq2000_check_split (xlow1
, mode
))
490 if (GET_CODE (xinsn
) == PLUS
)
492 rtx xplus0
= XEXP (xinsn
, 0);
493 rtx xplus1
= XEXP (xinsn
, 1);
497 while (GET_CODE (xplus0
) == SUBREG
)
498 xplus0
= SUBREG_REG (xplus0
);
499 code0
= GET_CODE (xplus0
);
501 while (GET_CODE (xplus1
) == SUBREG
)
502 xplus1
= SUBREG_REG (xplus1
);
503 code1
= GET_CODE (xplus1
);
506 && iq2000_reg_mode_ok_for_base_p (xplus0
, mode
, strict
))
508 if (code1
== CONST_INT
&& SMALL_INT (xplus1
)
509 && SMALL_INT_UNSIGNED (xplus1
) /* No negative offsets */)
514 if (TARGET_DEBUG_A_MODE
)
515 GO_PRINTF ("Not a legitimate address\n");
517 /* The address was not legitimate. */
521 /* Returns an operand string for the given instruction's delay slot,
522 after updating filled delay slot statistics.
524 We assume that operands[0] is the target register that is set.
526 In order to check the next insn, most of this functionality is moved
527 to FINAL_PRESCAN_INSN, and we just set the global variables that
531 iq2000_fill_delay_slot (const char *ret
, enum delay_type type
, rtx operands
[],
535 enum machine_mode mode
;
536 rtx next_insn
= cur_insn
? NEXT_INSN (cur_insn
) : NULL_RTX
;
539 if (type
== DELAY_LOAD
|| type
== DELAY_FCMP
)
545 /* Make sure that we don't put nop's after labels. */
546 next_insn
= NEXT_INSN (cur_insn
);
547 while (next_insn
!= 0
548 && (GET_CODE (next_insn
) == NOTE
549 || GET_CODE (next_insn
) == CODE_LABEL
))
550 next_insn
= NEXT_INSN (next_insn
);
552 dslots_load_total
+= num_nops
;
553 if (TARGET_DEBUG_C_MODE
554 || type
== DELAY_NONE
558 || GET_CODE (next_insn
) == CODE_LABEL
559 || (set_reg
= operands
[0]) == 0)
561 dslots_number_nops
= 0;
563 iq2000_load_reg2
= 0;
564 iq2000_load_reg3
= 0;
565 iq2000_load_reg4
= 0;
570 set_reg
= operands
[0];
574 while (GET_CODE (set_reg
) == SUBREG
)
575 set_reg
= SUBREG_REG (set_reg
);
577 mode
= GET_MODE (set_reg
);
578 dslots_number_nops
= num_nops
;
579 iq2000_load_reg
= set_reg
;
580 if (GET_MODE_SIZE (mode
)
581 > (unsigned) (UNITS_PER_WORD
))
582 iq2000_load_reg2
= gen_rtx_REG (SImode
, REGNO (set_reg
) + 1);
584 iq2000_load_reg2
= 0;
589 /* Determine whether a memory reference takes one (based off of the GP
590 pointer), two (normal), or three (label + reg) instructions, and bump the
591 appropriate counter for -mstats. */
594 iq2000_count_memory_refs (rtx op
, int num
)
598 rtx addr
, plus0
, plus1
;
599 enum rtx_code code0
, code1
;
602 if (TARGET_DEBUG_B_MODE
)
604 fprintf (stderr
, "\n========== iq2000_count_memory_refs:\n");
608 /* Skip MEM if passed, otherwise handle movsi of address. */
609 addr
= (GET_CODE (op
) != MEM
) ? op
: XEXP (op
, 0);
611 /* Loop, going through the address RTL. */
615 switch (GET_CODE (addr
))
623 plus0
= XEXP (addr
, 0);
624 plus1
= XEXP (addr
, 1);
625 code0
= GET_CODE (plus0
);
626 code1
= GET_CODE (plus1
);
636 if (code0
== CONST_INT
)
651 if (code1
== CONST_INT
)
658 if (code0
== SYMBOL_REF
|| code0
== LABEL_REF
|| code0
== CONST
)
665 if (code1
== SYMBOL_REF
|| code1
== LABEL_REF
|| code1
== CONST
)
675 n_words
= 2; /* Always 2 words. */
679 addr
= XEXP (addr
, 0);
684 n_words
= SYMBOL_REF_FLAG (addr
) ? 1 : 2;
696 n_words
+= additional
;
700 num_refs
[n_words
-1] += num
;
703 /* Abort after printing out a specific insn. */
706 abort_with_insn (rtx insn
, const char * reason
)
713 /* Return the appropriate instructions to move one operand to another. */
716 iq2000_move_1word (rtx operands
[], rtx insn
, int unsignedp
)
719 rtx op0
= operands
[0];
720 rtx op1
= operands
[1];
721 enum rtx_code code0
= GET_CODE (op0
);
722 enum rtx_code code1
= GET_CODE (op1
);
723 enum machine_mode mode
= GET_MODE (op0
);
724 int subreg_offset0
= 0;
725 int subreg_offset1
= 0;
726 enum delay_type delay
= DELAY_NONE
;
728 while (code0
== SUBREG
)
730 subreg_offset0
+= subreg_regno_offset (REGNO (SUBREG_REG (op0
)),
731 GET_MODE (SUBREG_REG (op0
)),
734 op0
= SUBREG_REG (op0
);
735 code0
= GET_CODE (op0
);
738 while (code1
== SUBREG
)
740 subreg_offset1
+= subreg_regno_offset (REGNO (SUBREG_REG (op1
)),
741 GET_MODE (SUBREG_REG (op1
)),
744 op1
= SUBREG_REG (op1
);
745 code1
= GET_CODE (op1
);
748 /* For our purposes, a condition code mode is the same as SImode. */
754 int regno0
= REGNO (op0
) + subreg_offset0
;
758 int regno1
= REGNO (op1
) + subreg_offset1
;
760 /* Do not do anything for assigning a register to itself */
761 if (regno0
== regno1
)
764 else if (GP_REG_P (regno0
))
766 if (GP_REG_P (regno1
))
767 ret
= "or\t%0,%%0,%1";
772 else if (code1
== MEM
)
777 iq2000_count_memory_refs (op1
, 1);
779 if (GP_REG_P (regno0
))
781 /* For loads, use the mode of the memory item, instead of the
782 target, so zero/sign extend can use this code as well. */
783 switch (GET_MODE (op1
))
795 ret
= (unsignedp
) ? "lhu\t%0,%1" : "lh\t%0,%1";
798 ret
= (unsignedp
) ? "lbu\t%0,%1" : "lb\t%0,%1";
804 else if (code1
== CONST_INT
805 || (code1
== CONST_DOUBLE
806 && GET_MODE (op1
) == VOIDmode
))
808 if (code1
== CONST_DOUBLE
)
810 /* This can happen when storing constants into long long
811 bitfields. Just store the least significant word of
813 operands
[1] = op1
= GEN_INT (CONST_DOUBLE_LOW (op1
));
816 if (INTVAL (op1
) == 0)
818 if (GP_REG_P (regno0
))
819 ret
= "or\t%0,%%0,%z1";
821 else if (GP_REG_P (regno0
))
823 if (SMALL_INT_UNSIGNED (op1
))
824 ret
= "ori\t%0,%%0,%x1\t\t\t# %1";
825 else if (SMALL_INT (op1
))
826 ret
= "addiu\t%0,%%0,%1\t\t\t# %1";
828 ret
= "lui\t%0,%X1\t\t\t# %1\n\tori\t%0,%0,%x1";
832 else if (code1
== CONST_DOUBLE
&& mode
== SFmode
)
834 if (op1
== CONST0_RTX (SFmode
))
836 if (GP_REG_P (regno0
))
837 ret
= "or\t%0,%%0,%.";
847 else if (code1
== LABEL_REF
)
850 iq2000_count_memory_refs (op1
, 1);
855 else if (code1
== SYMBOL_REF
|| code1
== CONST
)
858 iq2000_count_memory_refs (op1
, 1);
863 else if (code1
== PLUS
)
865 rtx add_op0
= XEXP (op1
, 0);
866 rtx add_op1
= XEXP (op1
, 1);
868 if (GET_CODE (XEXP (op1
, 1)) == REG
869 && GET_CODE (XEXP (op1
, 0)) == CONST_INT
)
870 add_op0
= XEXP (op1
, 1), add_op1
= XEXP (op1
, 0);
872 operands
[2] = add_op0
;
873 operands
[3] = add_op1
;
874 ret
= "add%:\t%0,%2,%3";
877 else if (code1
== HIGH
)
879 operands
[1] = XEXP (op1
, 0);
880 ret
= "lui\t%0,%%hi(%1)";
884 else if (code0
== MEM
)
887 iq2000_count_memory_refs (op0
, 1);
891 int regno1
= REGNO (op1
) + subreg_offset1
;
893 if (GP_REG_P (regno1
))
897 case SFmode
: ret
= "sw\t%1,%0"; break;
898 case SImode
: ret
= "sw\t%1,%0"; break;
899 case HImode
: ret
= "sh\t%1,%0"; break;
900 case QImode
: ret
= "sb\t%1,%0"; break;
906 else if (code1
== CONST_INT
&& INTVAL (op1
) == 0)
910 case SFmode
: ret
= "sw\t%z1,%0"; break;
911 case SImode
: ret
= "sw\t%z1,%0"; break;
912 case HImode
: ret
= "sh\t%z1,%0"; break;
913 case QImode
: ret
= "sb\t%z1,%0"; break;
918 else if (code1
== CONST_DOUBLE
&& op1
== CONST0_RTX (mode
))
922 case SFmode
: ret
= "sw\t%.,%0"; break;
923 case SImode
: ret
= "sw\t%.,%0"; break;
924 case HImode
: ret
= "sh\t%.,%0"; break;
925 case QImode
: ret
= "sb\t%.,%0"; break;
933 abort_with_insn (insn
, "Bad move");
937 if (delay
!= DELAY_NONE
)
938 return iq2000_fill_delay_slot (ret
, delay
, operands
, insn
);
943 /* Provide the costs of an addressing mode that contains ADDR. */
946 iq2000_address_cost (rtx addr
)
948 switch (GET_CODE (addr
))
958 rtx offset
= const0_rtx
;
960 addr
= eliminate_constant_term (XEXP (addr
, 0), & offset
);
961 if (GET_CODE (addr
) == LABEL_REF
)
964 if (GET_CODE (addr
) != SYMBOL_REF
)
967 if (! SMALL_INT (offset
))
974 return SYMBOL_REF_FLAG (addr
) ? 1 : 2;
978 rtx plus0
= XEXP (addr
, 0);
979 rtx plus1
= XEXP (addr
, 1);
981 if (GET_CODE (plus0
) != REG
&& GET_CODE (plus1
) == REG
)
982 plus0
= XEXP (addr
, 1), plus1
= XEXP (addr
, 0);
984 if (GET_CODE (plus0
) != REG
)
987 switch (GET_CODE (plus1
))
990 return SMALL_INT (plus1
) ? 1 : 2;
997 return iq2000_address_cost (plus1
) + 1;
1011 /* Make normal rtx_code into something we can index from an array. */
1013 static enum internal_test
1014 map_test_to_internal_test (enum rtx_code test_code
)
1016 enum internal_test test
= ITEST_MAX
;
1020 case EQ
: test
= ITEST_EQ
; break;
1021 case NE
: test
= ITEST_NE
; break;
1022 case GT
: test
= ITEST_GT
; break;
1023 case GE
: test
= ITEST_GE
; break;
1024 case LT
: test
= ITEST_LT
; break;
1025 case LE
: test
= ITEST_LE
; break;
1026 case GTU
: test
= ITEST_GTU
; break;
1027 case GEU
: test
= ITEST_GEU
; break;
1028 case LTU
: test
= ITEST_LTU
; break;
1029 case LEU
: test
= ITEST_LEU
; break;
1036 /* Generate the code to do a TEST_CODE comparison on two integer values CMP0
1037 and CMP1. P_INVERT is NULL or ptr if branch needs to reverse its test.
1038 The return value RESULT is:
1039 (reg:SI xx) The pseudo register the comparison is in
1040 0 No register, generate a simple branch. */
1043 gen_int_relational (enum rtx_code test_code
, rtx result
, rtx cmp0
, rtx cmp1
,
1048 enum rtx_code test_code
; /* Code to use in instruction (LT vs. LTU). */
1049 int const_low
; /* Low bound of constant we can accept. */
1050 int const_high
; /* High bound of constant we can accept. */
1051 int const_add
; /* Constant to add (convert LE -> LT). */
1052 int reverse_regs
; /* Reverse registers in test. */
1053 int invert_const
; /* != 0 if invert value if cmp1 is constant. */
1054 int invert_reg
; /* != 0 if invert value if cmp1 is register. */
1055 int unsignedp
; /* != 0 for unsigned comparisons. */
1058 static struct cmp_info info
[ (int)ITEST_MAX
] =
1060 { XOR
, 0, 65535, 0, 0, 0, 0, 0 }, /* EQ */
1061 { XOR
, 0, 65535, 0, 0, 1, 1, 0 }, /* NE */
1062 { LT
, -32769, 32766, 1, 1, 1, 0, 0 }, /* GT */
1063 { LT
, -32768, 32767, 0, 0, 1, 1, 0 }, /* GE */
1064 { LT
, -32768, 32767, 0, 0, 0, 0, 0 }, /* LT */
1065 { LT
, -32769, 32766, 1, 1, 0, 1, 0 }, /* LE */
1066 { LTU
, -32769, 32766, 1, 1, 1, 0, 1 }, /* GTU */
1067 { LTU
, -32768, 32767, 0, 0, 1, 1, 1 }, /* GEU */
1068 { LTU
, -32768, 32767, 0, 0, 0, 0, 1 }, /* LTU */
1069 { LTU
, -32769, 32766, 1, 1, 0, 1, 1 }, /* LEU */
1072 enum internal_test test
;
1073 enum machine_mode mode
;
1074 struct cmp_info
*p_info
;
1081 test
= map_test_to_internal_test (test_code
);
1082 if (test
== ITEST_MAX
)
1085 p_info
= &info
[(int) test
];
1086 eqne_p
= (p_info
->test_code
== XOR
);
1088 mode
= GET_MODE (cmp0
);
1089 if (mode
== VOIDmode
)
1090 mode
= GET_MODE (cmp1
);
1092 /* Eliminate simple branches. */
1093 branch_p
= (result
== 0);
1096 if (GET_CODE (cmp0
) == REG
|| GET_CODE (cmp0
) == SUBREG
)
1098 /* Comparisons against zero are simple branches. */
1099 if (GET_CODE (cmp1
) == CONST_INT
&& INTVAL (cmp1
) == 0)
1102 /* Test for beq/bne. */
1107 /* Allocate a pseudo to calculate the value in. */
1108 result
= gen_reg_rtx (mode
);
1111 /* Make sure we can handle any constants given to us. */
1112 if (GET_CODE (cmp0
) == CONST_INT
)
1113 cmp0
= force_reg (mode
, cmp0
);
1115 if (GET_CODE (cmp1
) == CONST_INT
)
1117 HOST_WIDE_INT value
= INTVAL (cmp1
);
1119 if (value
< p_info
->const_low
1120 || value
> p_info
->const_high
)
1121 cmp1
= force_reg (mode
, cmp1
);
1124 /* See if we need to invert the result. */
1125 invert
= (GET_CODE (cmp1
) == CONST_INT
1126 ? p_info
->invert_const
: p_info
->invert_reg
);
1128 if (p_invert
!= (int *)0)
1134 /* Comparison to constants, may involve adding 1 to change a LT into LE.
1135 Comparison between two registers, may involve switching operands. */
1136 if (GET_CODE (cmp1
) == CONST_INT
)
1138 if (p_info
->const_add
!= 0)
1140 HOST_WIDE_INT
new = INTVAL (cmp1
) + p_info
->const_add
;
1142 /* If modification of cmp1 caused overflow,
1143 we would get the wrong answer if we follow the usual path;
1144 thus, x > 0xffffffffU would turn into x > 0U. */
1145 if ((p_info
->unsignedp
1146 ? (unsigned HOST_WIDE_INT
) new >
1147 (unsigned HOST_WIDE_INT
) INTVAL (cmp1
)
1148 : new > INTVAL (cmp1
))
1149 != (p_info
->const_add
> 0))
1151 /* This test is always true, but if INVERT is true then
1152 the result of the test needs to be inverted so 0 should
1153 be returned instead. */
1154 emit_move_insn (result
, invert
? const0_rtx
: const_true_rtx
);
1158 cmp1
= GEN_INT (new);
1162 else if (p_info
->reverse_regs
)
1169 if (test
== ITEST_NE
&& GET_CODE (cmp1
) == CONST_INT
&& INTVAL (cmp1
) == 0)
1173 reg
= (invert
|| eqne_p
) ? gen_reg_rtx (mode
) : result
;
1174 convert_move (reg
, gen_rtx_fmt_ee (p_info
->test_code
, mode
, cmp0
, cmp1
), 0);
1177 if (test
== ITEST_NE
)
1179 convert_move (result
, gen_rtx_GTU (mode
, reg
, const0_rtx
), 0);
1180 if (p_invert
!= NULL
)
1185 else if (test
== ITEST_EQ
)
1187 reg2
= invert
? gen_reg_rtx (mode
) : result
;
1188 convert_move (reg2
, gen_rtx_LTU (mode
, reg
, const1_rtx
), 0);
1197 convert_move (result
, gen_rtx_XOR (mode
, reg
, one
), 0);
1203 /* Emit the common code for doing conditional branches.
1204 operand[0] is the label to jump to.
1205 The comparison operands are saved away by cmp{si,di,sf,df}. */
1208 gen_conditional_branch (rtx operands
[], enum rtx_code test_code
)
1210 enum cmp_type type
= branch_type
;
1211 rtx cmp0
= branch_cmp
[0];
1212 rtx cmp1
= branch_cmp
[1];
1213 enum machine_mode mode
;
1222 mode
= type
== CMP_SI
? SImode
: DImode
;
1224 reg
= gen_int_relational (test_code
, NULL_RTX
, cmp0
, cmp1
, &invert
);
1232 else if (GET_CODE (cmp1
) == CONST_INT
&& INTVAL (cmp1
) != 0)
1233 /* We don't want to build a comparison against a nonzero
1235 cmp1
= force_reg (mode
, cmp1
);
1241 reg
= gen_reg_rtx (CCmode
);
1243 /* For cmp0 != cmp1, build cmp0 == cmp1, and test for result == 0. */
1244 emit_insn (gen_rtx_SET (VOIDmode
, reg
,
1245 gen_rtx_fmt_ee (test_code
== NE
? EQ
: test_code
,
1246 CCmode
, cmp0
, cmp1
)));
1248 test_code
= test_code
== NE
? EQ
: NE
;
1256 abort_with_insn (gen_rtx_fmt_ee (test_code
, VOIDmode
, cmp0
, cmp1
),
1260 /* Generate the branch. */
1261 label1
= gen_rtx_LABEL_REF (VOIDmode
, operands
[0]);
1270 emit_jump_insn (gen_rtx_SET (VOIDmode
, pc_rtx
,
1271 gen_rtx_IF_THEN_ELSE (VOIDmode
,
1272 gen_rtx_fmt_ee (test_code
,
1278 /* Initialize CUM for a function FNTYPE. */
1281 init_cumulative_args (CUMULATIVE_ARGS
*cum
, tree fntype
,
1282 rtx libname ATTRIBUTE_UNUSED
)
1284 static CUMULATIVE_ARGS zero_cum
;
1288 if (TARGET_DEBUG_D_MODE
)
1291 "\ninit_cumulative_args, fntype = 0x%.8lx", (long) fntype
);
1294 fputc ('\n', stderr
);
1298 tree ret_type
= TREE_TYPE (fntype
);
1300 fprintf (stderr
, ", fntype code = %s, ret code = %s\n",
1301 tree_code_name
[(int)TREE_CODE (fntype
)],
1302 tree_code_name
[(int)TREE_CODE (ret_type
)]);
1308 /* Determine if this function has variable arguments. This is
1309 indicated by the last argument being 'void_type_mode' if there
1310 are no variable arguments. The standard IQ2000 calling sequence
1311 passes all arguments in the general purpose registers in this case. */
1313 for (param
= fntype
? TYPE_ARG_TYPES (fntype
) : 0;
1314 param
!= 0; param
= next_param
)
1316 next_param
= TREE_CHAIN (param
);
1317 if (next_param
== 0 && TREE_VALUE (param
) != void_type_node
)
1318 cum
->gp_reg_found
= 1;
1322 /* Advance the argument of type TYPE and mode MODE to the next argument
1326 function_arg_advance (CUMULATIVE_ARGS
*cum
, enum machine_mode mode
, tree type
,
1329 if (TARGET_DEBUG_D_MODE
)
1332 "function_adv({gp reg found = %d, arg # = %2d, words = %2d}, %4s, ",
1333 cum
->gp_reg_found
, cum
->arg_number
, cum
->arg_words
,
1334 GET_MODE_NAME (mode
));
1335 fprintf (stderr
, HOST_PTR_PRINTF
, (const PTR
) type
);
1336 fprintf (stderr
, ", %d )\n\n", named
);
1346 if (GET_MODE_CLASS (mode
) != MODE_COMPLEX_INT
1347 && GET_MODE_CLASS (mode
) != MODE_COMPLEX_FLOAT
)
1350 cum
->gp_reg_found
= 1;
1351 cum
->arg_words
+= ((GET_MODE_SIZE (mode
) + UNITS_PER_WORD
- 1)
1356 cum
->gp_reg_found
= 1;
1357 cum
->arg_words
+= ((int_size_in_bytes (type
) + UNITS_PER_WORD
- 1)
1363 if (! cum
->gp_reg_found
&& cum
->arg_number
<= 2)
1364 cum
->fp_code
+= 1 << ((cum
->arg_number
- 1) * 2);
1368 cum
->arg_words
+= 2;
1369 if (! cum
->gp_reg_found
&& cum
->arg_number
<= 2)
1370 cum
->fp_code
+= 2 << ((cum
->arg_number
- 1) * 2);
1374 cum
->gp_reg_found
= 1;
1375 cum
->arg_words
+= 2;
1381 cum
->gp_reg_found
= 1;
1387 /* Return an RTL expression containing the register for the given mode MODE
1388 and type TYPE in CUM, or 0 if the argument is to be passed on the stack. */
1391 function_arg (CUMULATIVE_ARGS
*cum
, enum machine_mode mode
, tree type
,
1397 unsigned int *arg_words
= &cum
->arg_words
;
1398 int struct_p
= (type
!= 0
1399 && (TREE_CODE (type
) == RECORD_TYPE
1400 || TREE_CODE (type
) == UNION_TYPE
1401 || TREE_CODE (type
) == QUAL_UNION_TYPE
));
1403 if (TARGET_DEBUG_D_MODE
)
1406 "function_arg( {gp reg found = %d, arg # = %2d, words = %2d}, %4s, ",
1407 cum
->gp_reg_found
, cum
->arg_number
, cum
->arg_words
,
1408 GET_MODE_NAME (mode
));
1409 fprintf (stderr
, HOST_PTR_PRINTF
, (const PTR
) type
);
1410 fprintf (stderr
, ", %d ) = ", named
);
1414 cum
->last_arg_fp
= 0;
1418 regbase
= GP_ARG_FIRST
;
1422 cum
->arg_words
+= cum
->arg_words
& 1;
1424 regbase
= GP_ARG_FIRST
;
1428 if (GET_MODE_CLASS (mode
) != MODE_COMPLEX_INT
1429 && GET_MODE_CLASS (mode
) != MODE_COMPLEX_FLOAT
)
1432 /* Drops through. */
1434 if (type
!= NULL_TREE
&& TYPE_ALIGN (type
) > (unsigned) BITS_PER_WORD
)
1435 cum
->arg_words
+= (cum
->arg_words
& 1);
1436 regbase
= GP_ARG_FIRST
;
1443 regbase
= GP_ARG_FIRST
;
1447 cum
->arg_words
+= (cum
->arg_words
& 1);
1448 regbase
= GP_ARG_FIRST
;
1451 if (*arg_words
>= (unsigned) MAX_ARGS_IN_REGISTERS
)
1453 if (TARGET_DEBUG_D_MODE
)
1454 fprintf (stderr
, "<stack>%s\n", struct_p
? ", [struct]" : "");
1463 if (! type
|| TREE_CODE (type
) != RECORD_TYPE
1464 || ! named
|| ! TYPE_SIZE_UNIT (type
)
1465 || ! host_integerp (TYPE_SIZE_UNIT (type
), 1))
1466 ret
= gen_rtx_REG (mode
, regbase
+ *arg_words
+ bias
);
1471 for (field
= TYPE_FIELDS (type
); field
; field
= TREE_CHAIN (field
))
1472 if (TREE_CODE (field
) == FIELD_DECL
1473 && TREE_CODE (TREE_TYPE (field
)) == REAL_TYPE
1474 && TYPE_PRECISION (TREE_TYPE (field
)) == BITS_PER_WORD
1475 && host_integerp (bit_position (field
), 0)
1476 && int_bit_position (field
) % BITS_PER_WORD
== 0)
1479 /* If the whole struct fits a DFmode register,
1480 we don't need the PARALLEL. */
1481 if (! field
|| mode
== DFmode
)
1482 ret
= gen_rtx_REG (mode
, regbase
+ *arg_words
+ bias
);
1485 unsigned int chunks
;
1486 HOST_WIDE_INT bitpos
;
1490 /* ??? If this is a packed structure, then the last hunk won't
1493 = tree_low_cst (TYPE_SIZE_UNIT (type
), 1) / UNITS_PER_WORD
;
1494 if (chunks
+ *arg_words
+ bias
> (unsigned) MAX_ARGS_IN_REGISTERS
)
1495 chunks
= MAX_ARGS_IN_REGISTERS
- *arg_words
- bias
;
1497 /* Assign_parms checks the mode of ENTRY_PARM, so we must
1498 use the actual mode here. */
1499 ret
= gen_rtx_PARALLEL (mode
, rtvec_alloc (chunks
));
1502 regno
= regbase
+ *arg_words
+ bias
;
1503 field
= TYPE_FIELDS (type
);
1504 for (i
= 0; i
< chunks
; i
++)
1508 for (; field
; field
= TREE_CHAIN (field
))
1509 if (TREE_CODE (field
) == FIELD_DECL
1510 && int_bit_position (field
) >= bitpos
)
1514 && int_bit_position (field
) == bitpos
1515 && TREE_CODE (TREE_TYPE (field
)) == REAL_TYPE
1516 && TYPE_PRECISION (TREE_TYPE (field
)) == BITS_PER_WORD
)
1517 reg
= gen_rtx_REG (DFmode
, regno
++);
1519 reg
= gen_rtx_REG (word_mode
, regno
);
1522 = gen_rtx_EXPR_LIST (VOIDmode
, reg
,
1523 GEN_INT (bitpos
/ BITS_PER_UNIT
));
1531 if (TARGET_DEBUG_D_MODE
)
1532 fprintf (stderr
, "%s%s\n", reg_names
[regbase
+ *arg_words
+ bias
],
1533 struct_p
? ", [struct]" : "");
1536 /* We will be called with a mode of VOIDmode after the last argument
1537 has been seen. Whatever we return will be passed to the call
1538 insn. If we need any shifts for small structures, return them in
1540 if (mode
== VOIDmode
)
1542 if (cum
->num_adjusts
> 0)
1543 ret
= gen_rtx_PARALLEL ((enum machine_mode
) cum
->fp_code
,
1544 gen_rtvec_v (cum
->num_adjusts
, cum
->adjust
));
1551 function_arg_partial_nregs (CUMULATIVE_ARGS
*cum
, enum machine_mode mode
,
1552 tree type ATTRIBUTE_UNUSED
,
1553 int named ATTRIBUTE_UNUSED
)
1556 && cum
->arg_words
== MAX_ARGS_IN_REGISTERS
- (unsigned)1)
1558 if (TARGET_DEBUG_D_MODE
)
1559 fprintf (stderr
, "function_arg_partial_nregs = 1\n");
1567 /* Implement va_start. */
1570 iq2000_va_start (tree valist
, rtx nextarg
)
1573 /* Find out how many non-float named formals. */
1574 int gpr_save_area_size
;
1575 /* Note UNITS_PER_WORD is 4 bytes. */
1576 int_arg_words
= current_function_args_info
.arg_words
;
1578 if (int_arg_words
< 8 )
1579 /* Adjust for the prologue's economy measure. */
1580 gpr_save_area_size
= (8 - int_arg_words
) * UNITS_PER_WORD
;
1582 gpr_save_area_size
= 0;
1584 /* Everything is in the GPR save area, or in the overflow
1585 area which is contiguous with it. */
1586 nextarg
= plus_constant (nextarg
, - gpr_save_area_size
);
1587 std_expand_builtin_va_start (valist
, nextarg
);
1590 /* Implement va_arg. */
1593 iq2000_va_arg (tree valist
, tree type
)
1595 HOST_WIDE_INT size
, rsize
;
1599 rtx r
, lab_over
= NULL_RTX
, lab_false
;
1600 tree f_ovfl
, f_gtop
, f_ftop
, f_goff
, f_foff
;
1601 tree ovfl
, gtop
, ftop
, goff
, foff
;
1603 size
= int_size_in_bytes (type
);
1604 rsize
= (size
+ UNITS_PER_WORD
- 1) & -UNITS_PER_WORD
;
1606 = function_arg_pass_by_reference (NULL
, TYPE_MODE (type
), type
, 0);
1609 size
= POINTER_SIZE
/ BITS_PER_UNIT
;
1610 rsize
= UNITS_PER_WORD
;
1613 addr_rtx
= gen_reg_rtx (Pmode
);
1616 /* Case of all args in a merged stack. No need to check bounds,
1617 just advance valist along the stack. */
1621 && TYPE_ALIGN (type
) > (unsigned) BITS_PER_WORD
)
1623 t
= build (PLUS_EXPR
, TREE_TYPE (gpr
), gpr
,
1624 build_int_2 (2*UNITS_PER_WORD
- 1, 0));
1625 t
= build (BIT_AND_EXPR
, TREE_TYPE (t
), t
,
1626 build_int_2 (-2*UNITS_PER_WORD
, -1));
1627 t
= build (MODIFY_EXPR
, TREE_TYPE (gpr
), gpr
, t
);
1628 expand_expr (t
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
1631 t
= build (POSTINCREMENT_EXPR
, TREE_TYPE (gpr
), gpr
,
1633 r
= expand_expr (t
, addr_rtx
, Pmode
, EXPAND_NORMAL
);
1635 emit_move_insn (addr_rtx
, r
);
1637 /* Flush the POSTINCREMENT. */
1642 r
= gen_rtx_MEM (Pmode
, addr_rtx
);
1643 set_mem_alias_set (r
, get_varargs_alias_set ());
1644 emit_move_insn (addr_rtx
, r
);
1648 if (BYTES_BIG_ENDIAN
&& rsize
!= size
)
1649 addr_rtx
= plus_constant (addr_rtx
, rsize
- size
);
1654 /* Not a simple merged stack. Need ptrs and indexes left by va_start. */
1655 f_ovfl
= TYPE_FIELDS (va_list_type_node
);
1656 f_gtop
= TREE_CHAIN (f_ovfl
);
1657 f_ftop
= TREE_CHAIN (f_gtop
);
1658 f_goff
= TREE_CHAIN (f_ftop
);
1659 f_foff
= TREE_CHAIN (f_goff
);
1661 ovfl
= build (COMPONENT_REF
, TREE_TYPE (f_ovfl
), valist
, f_ovfl
);
1662 gtop
= build (COMPONENT_REF
, TREE_TYPE (f_gtop
), valist
, f_gtop
);
1663 ftop
= build (COMPONENT_REF
, TREE_TYPE (f_ftop
), valist
, f_ftop
);
1664 goff
= build (COMPONENT_REF
, TREE_TYPE (f_goff
), valist
, f_goff
);
1665 foff
= build (COMPONENT_REF
, TREE_TYPE (f_foff
), valist
, f_foff
);
1667 lab_false
= gen_label_rtx ();
1668 lab_over
= gen_label_rtx ();
1670 if (TREE_CODE (type
) == REAL_TYPE
)
1672 /* Emit code to branch if foff == 0. */
1673 r
= expand_expr (foff
, NULL_RTX
, TYPE_MODE (TREE_TYPE (foff
)),
1675 emit_cmp_and_jump_insns (r
, const0_rtx
, EQ
,
1676 const1_rtx
, GET_MODE (r
), 1, lab_false
);
1678 /* Emit code for addr_rtx = ftop - foff. */
1679 t
= build (MINUS_EXPR
, TREE_TYPE (ftop
), ftop
, foff
);
1680 r
= expand_expr (t
, addr_rtx
, Pmode
, EXPAND_NORMAL
);
1682 emit_move_insn (addr_rtx
, r
);
1684 /* Emit code for foff-=8.
1685 Advances the offset up FPR save area by one double. */
1686 t
= build (MINUS_EXPR
, TREE_TYPE (foff
), foff
, build_int_2 (8, 0));
1687 t
= build (MODIFY_EXPR
, TREE_TYPE (foff
), foff
, t
);
1688 expand_expr (t
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
1691 emit_jump (lab_over
);
1693 emit_label (lab_false
);
1695 /* If a 4-byte int is followed by an 8-byte float, then
1696 natural alignment causes a 4 byte gap.
1697 So, dynamically adjust ovfl up to a multiple of 8. */
1698 t
= build (BIT_AND_EXPR
, TREE_TYPE (ovfl
), ovfl
,
1699 build_int_2 (7, 0));
1700 t
= build (PLUS_EXPR
, TREE_TYPE (ovfl
), ovfl
, t
);
1701 t
= build (MODIFY_EXPR
, TREE_TYPE (ovfl
), ovfl
, t
);
1702 expand_expr (t
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
1704 /* Emit code for addr_rtx = the ovfl pointer into overflow area.
1705 Postincrement the ovfl pointer by 8. */
1706 t
= build (POSTINCREMENT_EXPR
, TREE_TYPE(ovfl
), ovfl
,
1708 r
= expand_expr (t
, addr_rtx
, Pmode
, EXPAND_NORMAL
);
1710 emit_move_insn (addr_rtx
, r
);
1713 emit_label (lab_over
);
1718 /* Not REAL_TYPE. */
1721 if (TREE_CODE (type
) == INTEGER_TYPE
1722 && TYPE_PRECISION (type
) == 64)
1724 /* int takes 32 bits of the GPR save area, but
1725 longlong takes an aligned 64 bits. So, emit code
1726 to zero the low order bits of goff, thus aligning
1727 the later calculation of (gtop-goff) upwards. */
1728 t
= build (BIT_AND_EXPR
, TREE_TYPE (goff
), goff
,
1729 build_int_2 (-8, -1));
1730 t
= build (MODIFY_EXPR
, TREE_TYPE (goff
), goff
, t
);
1731 expand_expr (t
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
1734 /* Emit code to branch if goff == 0. */
1735 r
= expand_expr (goff
, NULL_RTX
, TYPE_MODE (TREE_TYPE (goff
)),
1737 emit_cmp_and_jump_insns (r
, const0_rtx
, EQ
,
1738 const1_rtx
, GET_MODE (r
), 1, lab_false
);
1740 /* Emit code for addr_rtx = gtop - goff. */
1741 t
= build (MINUS_EXPR
, TREE_TYPE (gtop
), gtop
, goff
);
1742 r
= expand_expr (t
, addr_rtx
, Pmode
, EXPAND_NORMAL
);
1744 emit_move_insn (addr_rtx
, r
);
1746 if (TYPE_PRECISION (type
) == 64)
1749 step_size
= UNITS_PER_WORD
;
1751 /* Emit code for goff = goff - step_size.
1752 Advances the offset up GPR save area over the item. */
1753 t
= build (MINUS_EXPR
, TREE_TYPE (goff
), goff
,
1754 build_int_2 (step_size
, 0));
1755 t
= build (MODIFY_EXPR
, TREE_TYPE (goff
), goff
, t
);
1756 expand_expr (t
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
1759 emit_jump (lab_over
);
1761 emit_label (lab_false
);
1763 /* Emit code for addr_rtx -> overflow area, postinc by step_size. */
1764 t
= build (POSTINCREMENT_EXPR
, TREE_TYPE(ovfl
), ovfl
,
1765 size_int (step_size
));
1766 r
= expand_expr (t
, addr_rtx
, Pmode
, EXPAND_NORMAL
);
1768 emit_move_insn (addr_rtx
, r
);
1771 emit_label (lab_over
);
1775 r
= gen_rtx_MEM (Pmode
, addr_rtx
);
1776 set_mem_alias_set (r
, get_varargs_alias_set ());
1777 emit_move_insn (addr_rtx
, r
);
1781 if (BYTES_BIG_ENDIAN
&& rsize
!= size
)
1782 addr_rtx
= plus_constant (addr_rtx
, rsize
- size
);
1788 /* Allocate a chunk of memory for per-function machine-dependent data. */
1790 static struct machine_function
*
1791 iq2000_init_machine_status (void)
1793 struct machine_function
*f
;
1795 f
= ggc_alloc_cleared (sizeof (struct machine_function
));
1800 static enum processor_type
1801 iq2000_parse_cpu (const char * cpu_string
)
1803 const char *p
= cpu_string
;
1804 enum processor_type cpu
;
1806 cpu
= PROCESSOR_DEFAULT
;
1810 if (!strcmp (p
, "iq10"))
1811 cpu
= PROCESSOR_IQ10
;
1814 if (!strcmp (p
, "iq2000"))
1815 cpu
= PROCESSOR_IQ2000
;
1822 /* Detect any conflicts in the switches. */
1825 override_options (void)
1827 enum processor_type iq2000_cpu
;
1829 target_flags
&= ~MASK_GPOPT
;
1831 iq2000_isa
= IQ2000_ISA_DEFAULT
;
1833 /* Identify the processor type. */
1835 if (iq2000_cpu_string
!= 0)
1837 iq2000_cpu
= iq2000_parse_cpu (iq2000_cpu_string
);
1838 if (iq2000_cpu
== PROCESSOR_DEFAULT
)
1840 error ("bad value (%s) for -mcpu= switch", iq2000_arch_string
);
1841 iq2000_cpu_string
= "default";
1843 iq2000_arch
= iq2000_cpu
;
1844 iq2000_tune
= iq2000_cpu
;
1847 if (iq2000_arch_string
== 0
1848 || ! strcmp (iq2000_arch_string
, "default")
1849 || ! strcmp (iq2000_arch_string
, "DEFAULT"))
1854 iq2000_arch_string
= "iq2000";
1855 iq2000_arch
= PROCESSOR_IQ2000
;
1861 iq2000_arch
= iq2000_parse_cpu (iq2000_arch_string
);
1862 if (iq2000_arch
== PROCESSOR_DEFAULT
)
1864 error ("bad value (%s) for -march= switch", iq2000_arch_string
);
1865 iq2000_arch_string
= "default";
1867 if (iq2000_arch
== PROCESSOR_IQ10
)
1869 error ("The compiler does not support -march=%s.", iq2000_arch_string
);
1870 iq2000_arch_string
= "default";
1874 iq2000_print_operand_punct
['?'] = 1;
1875 iq2000_print_operand_punct
['#'] = 1;
1876 iq2000_print_operand_punct
['&'] = 1;
1877 iq2000_print_operand_punct
['!'] = 1;
1878 iq2000_print_operand_punct
['*'] = 1;
1879 iq2000_print_operand_punct
['@'] = 1;
1880 iq2000_print_operand_punct
['.'] = 1;
1881 iq2000_print_operand_punct
['('] = 1;
1882 iq2000_print_operand_punct
[')'] = 1;
1883 iq2000_print_operand_punct
['['] = 1;
1884 iq2000_print_operand_punct
[']'] = 1;
1885 iq2000_print_operand_punct
['<'] = 1;
1886 iq2000_print_operand_punct
['>'] = 1;
1887 iq2000_print_operand_punct
['{'] = 1;
1888 iq2000_print_operand_punct
['}'] = 1;
1889 iq2000_print_operand_punct
['^'] = 1;
1890 iq2000_print_operand_punct
['$'] = 1;
1891 iq2000_print_operand_punct
['+'] = 1;
1892 iq2000_print_operand_punct
['~'] = 1;
1894 /* Save GPR registers in word_mode sized hunks. word_mode hasn't been
1895 initialized yet, so we can't use that here. */
1898 /* Function to allocate machine-dependent function status. */
1899 init_machine_status
= iq2000_init_machine_status
;
1902 /* The arg pointer (which is eliminated) points to the virtual frame pointer,
1903 while the frame pointer (which may be eliminated) points to the stack
1904 pointer after the initial adjustments. */
1907 iq2000_debugger_offset (rtx addr
, HOST_WIDE_INT offset
)
1909 rtx offset2
= const0_rtx
;
1910 rtx reg
= eliminate_constant_term (addr
, & offset2
);
1913 offset
= INTVAL (offset2
);
1915 if (reg
== stack_pointer_rtx
|| reg
== frame_pointer_rtx
1916 || reg
== hard_frame_pointer_rtx
)
1918 HOST_WIDE_INT frame_size
= (!cfun
->machine
->initialized
)
1919 ? compute_frame_size (get_frame_size ())
1920 : cfun
->machine
->total_size
;
1922 offset
= offset
- frame_size
;
1928 /* If defined, a C statement to be executed just prior to the output of
1929 assembler code for INSN, to modify the extracted operands so they will be
1932 Here the argument OPVEC is the vector containing the operands extracted
1933 from INSN, and NOPERANDS is the number of elements of the vector which
1934 contain meaningful data for this insn. The contents of this vector are
1935 what will be used to convert the insn template into assembler code, so you
1936 can change the assembler output by changing the contents of the vector.
1938 We use it to check if the current insn needs a nop in front of it because
1939 of load delays, and also to update the delay slot statistics. */
1942 final_prescan_insn (rtx insn
, rtx opvec
[] ATTRIBUTE_UNUSED
,
1943 int noperands ATTRIBUTE_UNUSED
)
1945 if (dslots_number_nops
> 0)
1947 rtx pattern
= PATTERN (insn
);
1948 int length
= get_attr_length (insn
);
1950 /* Do we need to emit a NOP? */
1952 || (iq2000_load_reg
!= 0 && reg_mentioned_p (iq2000_load_reg
, pattern
))
1953 || (iq2000_load_reg2
!= 0 && reg_mentioned_p (iq2000_load_reg2
, pattern
))
1954 || (iq2000_load_reg3
!= 0 && reg_mentioned_p (iq2000_load_reg3
, pattern
))
1955 || (iq2000_load_reg4
!= 0
1956 && reg_mentioned_p (iq2000_load_reg4
, pattern
)))
1957 fputs ("\tnop\n", asm_out_file
);
1960 dslots_load_filled
++;
1962 while (--dslots_number_nops
> 0)
1963 fputs ("\tnop\n", asm_out_file
);
1965 iq2000_load_reg
= 0;
1966 iq2000_load_reg2
= 0;
1967 iq2000_load_reg3
= 0;
1968 iq2000_load_reg4
= 0;
1971 if ( (GET_CODE (insn
) == JUMP_INSN
1972 || GET_CODE (insn
) == CALL_INSN
1973 || (GET_CODE (PATTERN (insn
)) == RETURN
))
1974 && NEXT_INSN (PREV_INSN (insn
)) == insn
)
1976 rtx nop_insn
= emit_insn_after (gen_nop (), insn
);
1978 INSN_ADDRESSES_NEW (nop_insn
, -1);
1982 && (GET_CODE (insn
) == JUMP_INSN
|| GET_CODE (insn
) == CALL_INSN
))
1983 dslots_jump_total
++;
1986 /* Return the bytes needed to compute the frame pointer from the current
1987 stack pointer where SIZE is the # of var. bytes allocated.
1989 IQ2000 stack frames look like:
1991 Before call After call
1992 +-----------------------+ +-----------------------+
1995 | caller's temps. | | caller's temps. |
1997 +-----------------------+ +-----------------------+
1999 | arguments on stack. | | arguments on stack. |
2001 +-----------------------+ +-----------------------+
2002 | 4 words to save | | 4 words to save |
2003 | arguments passed | | arguments passed |
2004 | in registers, even | | in registers, even |
2005 SP->| if not passed. | VFP->| if not passed. |
2006 +-----------------------+ +-----------------------+
2008 | fp register save |
2010 +-----------------------+
2012 | gp register save |
2014 +-----------------------+
2018 +-----------------------+
2020 | alloca allocations |
2022 +-----------------------+
2024 | GP save for V.4 abi |
2026 +-----------------------+
2028 | arguments on stack |
2030 +-----------------------+
2032 | arguments passed |
2033 | in registers, even |
2034 low SP->| if not passed. |
2035 memory +-----------------------+ */
2038 compute_frame_size (HOST_WIDE_INT size
)
2041 HOST_WIDE_INT total_size
; /* # bytes that the entire frame takes up. */
2042 HOST_WIDE_INT var_size
; /* # bytes that variables take up. */
2043 HOST_WIDE_INT args_size
; /* # bytes that outgoing arguments take up. */
2044 HOST_WIDE_INT extra_size
; /* # extra bytes. */
2045 HOST_WIDE_INT gp_reg_rounded
; /* # bytes needed to store gp after rounding. */
2046 HOST_WIDE_INT gp_reg_size
; /* # bytes needed to store gp regs. */
2047 HOST_WIDE_INT fp_reg_size
; /* # bytes needed to store fp regs. */
2048 long mask
; /* mask of saved gp registers. */
2049 int fp_inc
; /* 1 or 2 depending on the size of fp regs. */
2050 long fp_bits
; /* bitmask to use for each fp register. */
2055 extra_size
= IQ2000_STACK_ALIGN ((0));
2056 var_size
= IQ2000_STACK_ALIGN (size
);
2057 args_size
= IQ2000_STACK_ALIGN (current_function_outgoing_args_size
);
2059 /* If a function dynamically allocates the stack and
2060 has 0 for STACK_DYNAMIC_OFFSET then allocate some stack space. */
2061 if (args_size
== 0 && current_function_calls_alloca
)
2062 args_size
= 4 * UNITS_PER_WORD
;
2064 total_size
= var_size
+ args_size
+ extra_size
;
2066 /* Calculate space needed for gp registers. */
2067 for (regno
= GP_REG_FIRST
; regno
<= GP_REG_LAST
; regno
++)
2069 if (MUST_SAVE_REGISTER (regno
))
2071 gp_reg_size
+= GET_MODE_SIZE (gpr_mode
);
2072 mask
|= 1L << (regno
- GP_REG_FIRST
);
2076 /* We need to restore these for the handler. */
2077 if (current_function_calls_eh_return
)
2083 regno
= EH_RETURN_DATA_REGNO (i
);
2084 if (regno
== (int) INVALID_REGNUM
)
2086 gp_reg_size
+= GET_MODE_SIZE (gpr_mode
);
2087 mask
|= 1L << (regno
- GP_REG_FIRST
);
2093 gp_reg_rounded
= IQ2000_STACK_ALIGN (gp_reg_size
);
2094 total_size
+= gp_reg_rounded
+ IQ2000_STACK_ALIGN (fp_reg_size
);
2096 /* The gp reg is caller saved, so there is no need for leaf routines
2097 (total_size == extra_size) to save the gp reg. */
2098 if (total_size
== extra_size
2100 total_size
= extra_size
= 0;
2102 total_size
+= IQ2000_STACK_ALIGN (current_function_pretend_args_size
);
2104 /* Save other computed information. */
2105 cfun
->machine
->total_size
= total_size
;
2106 cfun
->machine
->var_size
= var_size
;
2107 cfun
->machine
->args_size
= args_size
;
2108 cfun
->machine
->extra_size
= extra_size
;
2109 cfun
->machine
->gp_reg_size
= gp_reg_size
;
2110 cfun
->machine
->fp_reg_size
= fp_reg_size
;
2111 cfun
->machine
->mask
= mask
;
2112 cfun
->machine
->initialized
= reload_completed
;
2113 cfun
->machine
->num_gp
= gp_reg_size
/ UNITS_PER_WORD
;
2117 unsigned long offset
;
2119 offset
= (args_size
+ extra_size
+ var_size
2120 + gp_reg_size
- GET_MODE_SIZE (gpr_mode
));
2122 cfun
->machine
->gp_sp_offset
= offset
;
2123 cfun
->machine
->gp_save_offset
= offset
- total_size
;
2127 cfun
->machine
->gp_sp_offset
= 0;
2128 cfun
->machine
->gp_save_offset
= 0;
2131 cfun
->machine
->fp_sp_offset
= 0;
2132 cfun
->machine
->fp_save_offset
= 0;
2134 /* Ok, we're done. */
2138 /* Implement INITIAL_ELIMINATION_OFFSET. FROM is either the frame
2139 pointer, argument pointer, or return address pointer. TO is either
2140 the stack pointer or hard frame pointer. */
2143 iq2000_initial_elimination_offset (int from
, int to ATTRIBUTE_UNUSED
)
2147 compute_frame_size (get_frame_size ());
2148 if ((from
) == FRAME_POINTER_REGNUM
)
2150 else if ((from
) == ARG_POINTER_REGNUM
)
2151 (offset
) = (cfun
->machine
->total_size
);
2152 else if ((from
) == RETURN_ADDRESS_POINTER_REGNUM
)
2154 if (leaf_function_p ())
2156 else (offset
) = cfun
->machine
->gp_sp_offset
2157 + ((UNITS_PER_WORD
- (POINTER_SIZE
/ BITS_PER_UNIT
))
2158 * (BYTES_BIG_ENDIAN
!= 0));
2164 /* Common code to emit the insns (or to write the instructions to a file)
2165 to save/restore registers.
2166 Other parts of the code assume that IQ2000_TEMP1_REGNUM (aka large_reg)
2167 is not modified within save_restore_insns. */
2169 #define BITSET_P(VALUE,BIT) (((VALUE) & (1L << (BIT))) != 0)
2171 /* Emit instructions to load the value (SP + OFFSET) into IQ2000_TEMP2_REGNUM
2172 and return an rtl expression for the register. Write the assembly
2173 instructions directly to FILE if it is not null, otherwise emit them as
2176 This function is a subroutine of save_restore_insns. It is used when
2177 OFFSET is too large to add in a single instruction. */
2180 iq2000_add_large_offset_to_sp (HOST_WIDE_INT offset
)
2182 rtx reg
= gen_rtx_REG (Pmode
, IQ2000_TEMP2_REGNUM
);
2183 rtx offset_rtx
= GEN_INT (offset
);
2185 emit_move_insn (reg
, offset_rtx
);
2186 emit_insn (gen_addsi3 (reg
, reg
, stack_pointer_rtx
));
2190 /* Make INSN frame related and note that it performs the frame-related
2191 operation DWARF_PATTERN. */
2194 iq2000_annotate_frame_insn (rtx insn
, rtx dwarf_pattern
)
2196 RTX_FRAME_RELATED_P (insn
) = 1;
2197 REG_NOTES (insn
) = alloc_EXPR_LIST (REG_FRAME_RELATED_EXPR
,
2202 /* Emit a move instruction that stores REG in MEM. Make the instruction
2203 frame related and note that it stores REG at (SP + OFFSET). */
2206 iq2000_emit_frame_related_store (rtx mem
, rtx reg
, HOST_WIDE_INT offset
)
2208 rtx dwarf_address
= plus_constant (stack_pointer_rtx
, offset
);
2209 rtx dwarf_mem
= gen_rtx_MEM (GET_MODE (reg
), dwarf_address
);
2211 iq2000_annotate_frame_insn (emit_move_insn (mem
, reg
),
2212 gen_rtx_SET (GET_MODE (reg
), dwarf_mem
, reg
));
2215 /* Emit instructions to save/restore registers, as determined by STORE_P. */
2218 save_restore_insns (int store_p
)
2220 long mask
= cfun
->machine
->mask
;
2223 HOST_WIDE_INT base_offset
;
2224 HOST_WIDE_INT gp_offset
;
2225 HOST_WIDE_INT end_offset
;
2227 if (frame_pointer_needed
2228 && ! BITSET_P (mask
, HARD_FRAME_POINTER_REGNUM
- GP_REG_FIRST
))
2233 base_reg_rtx
= 0, base_offset
= 0;
2237 /* Save registers starting from high to low. The debuggers prefer at least
2238 the return register be stored at func+4, and also it allows us not to
2239 need a nop in the epilog if at least one register is reloaded in
2240 addition to return address. */
2242 /* Save GP registers if needed. */
2243 /* Pick which pointer to use as a base register. For small frames, just
2244 use the stack pointer. Otherwise, use a temporary register. Save 2
2245 cycles if the save area is near the end of a large frame, by reusing
2246 the constant created in the prologue/epilogue to adjust the stack
2249 gp_offset
= cfun
->machine
->gp_sp_offset
;
2251 = gp_offset
- (cfun
->machine
->gp_reg_size
2252 - GET_MODE_SIZE (gpr_mode
));
2254 if (gp_offset
< 0 || end_offset
< 0)
2256 ("gp_offset (%ld) or end_offset (%ld) is less than zero.",
2257 (long) gp_offset
, (long) end_offset
);
2259 else if (gp_offset
< 32768)
2260 base_reg_rtx
= stack_pointer_rtx
, base_offset
= 0;
2264 int reg_save_count
= 0;
2266 for (regno
= GP_REG_LAST
; regno
>= GP_REG_FIRST
; regno
--)
2267 if (BITSET_P (mask
, regno
- GP_REG_FIRST
)) reg_save_count
+= 1;
2268 base_offset
= gp_offset
- ((reg_save_count
- 1) * 4);
2269 base_reg_rtx
= iq2000_add_large_offset_to_sp (base_offset
);
2272 for (regno
= GP_REG_LAST
; regno
>= GP_REG_FIRST
; regno
--)
2274 if (BITSET_P (mask
, regno
- GP_REG_FIRST
))
2278 = gen_rtx_MEM (gpr_mode
,
2279 gen_rtx_PLUS (Pmode
, base_reg_rtx
,
2280 GEN_INT (gp_offset
- base_offset
)));
2282 if (! current_function_calls_eh_return
)
2283 RTX_UNCHANGING_P (mem_rtx
) = 1;
2285 reg_rtx
= gen_rtx_REG (gpr_mode
, regno
);
2288 iq2000_emit_frame_related_store (mem_rtx
, reg_rtx
, gp_offset
);
2291 emit_move_insn (reg_rtx
, mem_rtx
);
2293 gp_offset
-= GET_MODE_SIZE (gpr_mode
);
2298 /* Expand the prologue into a bunch of separate insns. */
2301 iq2000_expand_prologue (void)
2304 HOST_WIDE_INT tsize
;
2305 int last_arg_is_vararg_marker
= 0;
2306 tree fndecl
= current_function_decl
;
2307 tree fntype
= TREE_TYPE (fndecl
);
2308 tree fnargs
= DECL_ARGUMENTS (fndecl
);
2313 CUMULATIVE_ARGS args_so_far
;
2314 int store_args_on_stack
= (iq2000_can_use_return_insn ());
2316 /* If struct value address is treated as the first argument. */
2317 if (aggregate_value_p (DECL_RESULT (fndecl
), fndecl
)
2318 && ! current_function_returns_pcc_struct
2319 && targetm
.calls
.struct_value_rtx (TREE_TYPE (fndecl
), 1) == 0)
2321 tree type
= build_pointer_type (fntype
);
2322 tree function_result_decl
= build_decl (PARM_DECL
, NULL_TREE
, type
);
2324 DECL_ARG_TYPE (function_result_decl
) = type
;
2325 TREE_CHAIN (function_result_decl
) = fnargs
;
2326 fnargs
= function_result_decl
;
2329 /* For arguments passed in registers, find the register number
2330 of the first argument in the variable part of the argument list,
2331 otherwise GP_ARG_LAST+1. Note also if the last argument is
2332 the varargs special argument, and treat it as part of the
2335 This is only needed if store_args_on_stack is true. */
2336 INIT_CUMULATIVE_ARGS (args_so_far
, fntype
, NULL_RTX
, 0, 0);
2337 regno
= GP_ARG_FIRST
;
2339 for (cur_arg
= fnargs
; cur_arg
!= 0; cur_arg
= next_arg
)
2341 tree passed_type
= DECL_ARG_TYPE (cur_arg
);
2342 enum machine_mode passed_mode
= TYPE_MODE (passed_type
);
2345 if (TREE_ADDRESSABLE (passed_type
))
2347 passed_type
= build_pointer_type (passed_type
);
2348 passed_mode
= Pmode
;
2351 entry_parm
= FUNCTION_ARG (args_so_far
, passed_mode
, passed_type
, 1);
2353 FUNCTION_ARG_ADVANCE (args_so_far
, passed_mode
, passed_type
, 1);
2354 next_arg
= TREE_CHAIN (cur_arg
);
2356 if (entry_parm
&& store_args_on_stack
)
2359 && DECL_NAME (cur_arg
)
2360 && ((0 == strcmp (IDENTIFIER_POINTER (DECL_NAME (cur_arg
)),
2361 "__builtin_va_alist"))
2362 || (0 == strcmp (IDENTIFIER_POINTER (DECL_NAME (cur_arg
)),
2365 last_arg_is_vararg_marker
= 1;
2372 if (GET_CODE (entry_parm
) != REG
)
2375 /* Passed in a register, so will get homed automatically. */
2376 if (GET_MODE (entry_parm
) == BLKmode
)
2377 words
= (int_size_in_bytes (passed_type
) + 3) / 4;
2379 words
= (GET_MODE_SIZE (GET_MODE (entry_parm
)) + 3) / 4;
2381 regno
= REGNO (entry_parm
) + words
- 1;
2386 regno
= GP_ARG_LAST
+1;
2391 /* In order to pass small structures by value in registers we need to
2392 shift the value into the high part of the register.
2393 Function_arg has encoded a PARALLEL rtx, holding a vector of
2394 adjustments to be made as the next_arg_reg variable, so we split up the
2395 insns, and emit them separately. */
2396 next_arg_reg
= FUNCTION_ARG (args_so_far
, VOIDmode
, void_type_node
, 1);
2397 if (next_arg_reg
!= 0 && GET_CODE (next_arg_reg
) == PARALLEL
)
2399 rtvec adjust
= XVEC (next_arg_reg
, 0);
2400 int num
= GET_NUM_ELEM (adjust
);
2402 for (i
= 0; i
< num
; i
++)
2406 pattern
= RTVEC_ELT (adjust
, i
);
2407 if (GET_CODE (pattern
) != SET
2408 || GET_CODE (SET_SRC (pattern
)) != ASHIFT
)
2409 abort_with_insn (pattern
, "Insn is not a shift");
2410 PUT_CODE (SET_SRC (pattern
), ASHIFTRT
);
2412 insn
= emit_insn (pattern
);
2414 /* Global life information isn't valid at this point, so we
2415 can't check whether these shifts are actually used. Mark
2416 them MAYBE_DEAD so that flow2 will remove them, and not
2417 complain about dead code in the prologue. */
2418 REG_NOTES(insn
) = gen_rtx_EXPR_LIST (REG_MAYBE_DEAD
, NULL_RTX
,
2423 tsize
= compute_frame_size (get_frame_size ());
2425 /* If this function is a varargs function, store any registers that
2426 would normally hold arguments ($4 - $7) on the stack. */
2427 if (store_args_on_stack
2428 && ((TYPE_ARG_TYPES (fntype
) != 0
2429 && (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype
)))
2431 || last_arg_is_vararg_marker
))
2433 int offset
= (regno
- GP_ARG_FIRST
) * UNITS_PER_WORD
;
2434 rtx ptr
= stack_pointer_rtx
;
2436 for (; regno
<= GP_ARG_LAST
; regno
++)
2439 ptr
= gen_rtx_PLUS (Pmode
, stack_pointer_rtx
, GEN_INT (offset
));
2440 emit_move_insn (gen_rtx_MEM (gpr_mode
, ptr
),
2441 gen_rtx_REG (gpr_mode
, regno
));
2443 offset
+= GET_MODE_SIZE (gpr_mode
);
2449 rtx tsize_rtx
= GEN_INT (tsize
);
2450 rtx adjustment_rtx
, insn
, dwarf_pattern
;
2454 adjustment_rtx
= gen_rtx_REG (Pmode
, IQ2000_TEMP1_REGNUM
);
2455 emit_move_insn (adjustment_rtx
, tsize_rtx
);
2458 adjustment_rtx
= tsize_rtx
;
2460 insn
= emit_insn (gen_subsi3 (stack_pointer_rtx
, stack_pointer_rtx
,
2463 dwarf_pattern
= gen_rtx_SET (Pmode
, stack_pointer_rtx
,
2464 plus_constant (stack_pointer_rtx
, -tsize
));
2466 iq2000_annotate_frame_insn (insn
, dwarf_pattern
);
2468 save_restore_insns (1);
2470 if (frame_pointer_needed
)
2474 insn
= emit_insn (gen_movsi (hard_frame_pointer_rtx
,
2475 stack_pointer_rtx
));
2478 RTX_FRAME_RELATED_P (insn
) = 1;
2482 emit_insn (gen_blockage ());
2485 /* Expand the epilogue into a bunch of separate insns. */
2488 iq2000_expand_epilogue (void)
2490 HOST_WIDE_INT tsize
= cfun
->machine
->total_size
;
2491 rtx tsize_rtx
= GEN_INT (tsize
);
2492 rtx tmp_rtx
= (rtx
)0;
2494 if (iq2000_can_use_return_insn ())
2496 emit_insn (gen_return ());
2502 tmp_rtx
= gen_rtx_REG (Pmode
, IQ2000_TEMP1_REGNUM
);
2503 emit_move_insn (tmp_rtx
, tsize_rtx
);
2504 tsize_rtx
= tmp_rtx
;
2509 if (frame_pointer_needed
)
2511 emit_insn (gen_blockage ());
2513 emit_insn (gen_movsi (stack_pointer_rtx
, hard_frame_pointer_rtx
));
2516 save_restore_insns (0);
2518 if (current_function_calls_eh_return
)
2520 rtx eh_ofs
= EH_RETURN_STACKADJ_RTX
;
2521 emit_insn (gen_addsi3 (eh_ofs
, eh_ofs
, tsize_rtx
));
2525 emit_insn (gen_blockage ());
2527 if (tsize
!= 0 || current_function_calls_eh_return
)
2529 emit_insn (gen_addsi3 (stack_pointer_rtx
, stack_pointer_rtx
,
2534 if (current_function_calls_eh_return
)
2536 /* Perform the additional bump for __throw. */
2537 emit_move_insn (gen_rtx_REG (Pmode
, HARD_FRAME_POINTER_REGNUM
),
2539 emit_insn (gen_rtx_USE (VOIDmode
, gen_rtx_REG (Pmode
,
2540 HARD_FRAME_POINTER_REGNUM
)));
2541 emit_jump_insn (gen_eh_return_internal ());
2544 emit_jump_insn (gen_return_internal (gen_rtx_REG (Pmode
,
2545 GP_REG_FIRST
+ 31)));
2549 iq2000_expand_eh_return (rtx address
)
2551 HOST_WIDE_INT gp_offset
= cfun
->machine
->gp_sp_offset
;
2554 scratch
= plus_constant (stack_pointer_rtx
, gp_offset
);
2555 emit_move_insn (gen_rtx_MEM (GET_MODE (address
), scratch
), address
);
2558 /* Return nonzero if this function is known to have a null epilogue.
2559 This allows the optimizer to omit jumps to jumps if no stack
2563 iq2000_can_use_return_insn (void)
2565 if (! reload_completed
)
2568 if (regs_ever_live
[31] || profile_flag
)
2571 if (cfun
->machine
->initialized
)
2572 return cfun
->machine
->total_size
== 0;
2574 return compute_frame_size (get_frame_size ()) == 0;
2577 /* Returns nonzero if X contains a SYMBOL_REF. */
2580 symbolic_expression_p (rtx x
)
2582 if (GET_CODE (x
) == SYMBOL_REF
)
2585 if (GET_CODE (x
) == CONST
)
2586 return symbolic_expression_p (XEXP (x
, 0));
2588 if (GET_RTX_CLASS (GET_CODE (x
)) == '1')
2589 return symbolic_expression_p (XEXP (x
, 0));
2591 if (GET_RTX_CLASS (GET_CODE (x
)) == 'c'
2592 || GET_RTX_CLASS (GET_CODE (x
)) == '2')
2593 return (symbolic_expression_p (XEXP (x
, 0))
2594 || symbolic_expression_p (XEXP (x
, 1)));
2599 /* Choose the section to use for the constant rtx expression X that has
2603 iq2000_select_rtx_section (enum machine_mode mode
, rtx x ATTRIBUTE_UNUSED
,
2604 unsigned HOST_WIDE_INT align
)
2606 /* For embedded applications, always put constants in read-only data,
2607 in order to reduce RAM usage. */
2608 /* For embedded applications, always put constants in read-only data,
2609 in order to reduce RAM usage. */
2610 mergeable_constant_section (mode
, align
, 0);
2613 /* Choose the section to use for DECL. RELOC is true if its value contains
2614 any relocatable expression.
2616 Some of the logic used here needs to be replicated in
2617 ENCODE_SECTION_INFO in iq2000.h so that references to these symbols
2618 are done correctly. */
2621 iq2000_select_section (tree decl
, int reloc ATTRIBUTE_UNUSED
,
2622 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED
)
2624 if (TARGET_EMBEDDED_DATA
)
2626 /* For embedded applications, always put an object in read-only data
2627 if possible, in order to reduce RAM usage. */
2628 if (((TREE_CODE (decl
) == VAR_DECL
2629 && TREE_READONLY (decl
) && !TREE_SIDE_EFFECTS (decl
)
2630 && DECL_INITIAL (decl
)
2631 && (DECL_INITIAL (decl
) == error_mark_node
2632 || TREE_CONSTANT (DECL_INITIAL (decl
))))
2633 /* Deal with calls from output_constant_def_contents. */
2634 || (TREE_CODE (decl
) != VAR_DECL
2635 && (TREE_CODE (decl
) != STRING_CST
2636 || !flag_writable_strings
))))
2637 readonly_data_section ();
2643 /* For hosted applications, always put an object in small data if
2644 possible, as this gives the best performance. */
2645 if (((TREE_CODE (decl
) == VAR_DECL
2646 && TREE_READONLY (decl
) && !TREE_SIDE_EFFECTS (decl
)
2647 && DECL_INITIAL (decl
)
2648 && (DECL_INITIAL (decl
) == error_mark_node
2649 || TREE_CONSTANT (DECL_INITIAL (decl
))))
2650 /* Deal with calls from output_constant_def_contents. */
2651 || (TREE_CODE (decl
) != VAR_DECL
2652 && (TREE_CODE (decl
) != STRING_CST
2653 || !flag_writable_strings
))))
2654 readonly_data_section ();
2659 /* Return register to use for a function return value with VALTYPE for function
2663 iq2000_function_value (tree valtype
, tree func ATTRIBUTE_UNUSED
)
2665 int reg
= GP_RETURN
;
2666 enum machine_mode mode
= TYPE_MODE (valtype
);
2667 int unsignedp
= TREE_UNSIGNED (valtype
);
2669 /* Since we define TARGET_PROMOTE_FUNCTION_RETURN that returns true,
2670 we must promote the mode just as PROMOTE_MODE does. */
2671 mode
= promote_mode (valtype
, mode
, &unsignedp
, 1);
2673 return gen_rtx_REG (mode
, reg
);
2676 /* The implementation of FUNCTION_ARG_PASS_BY_REFERENCE. Return
2677 nonzero when an argument must be passed by reference. */
2680 function_arg_pass_by_reference (CUMULATIVE_ARGS
*cum ATTRIBUTE_UNUSED
,
2681 enum machine_mode mode
, tree type
,
2682 int named ATTRIBUTE_UNUSED
)
2686 /* We must pass by reference if we would be both passing in registers
2687 and the stack. This is because any subsequent partial arg would be
2688 handled incorrectly in this case. */
2689 if (cum
&& MUST_PASS_IN_STACK (mode
, type
))
2691 /* Don't pass the actual CUM to FUNCTION_ARG, because we would
2692 get double copies of any offsets generated for small structs
2693 passed in registers. */
2694 CUMULATIVE_ARGS temp
;
2697 if (FUNCTION_ARG (temp
, mode
, type
, named
) != 0)
2701 if (type
== NULL_TREE
|| mode
== DImode
|| mode
== DFmode
)
2704 size
= int_size_in_bytes (type
);
2705 return size
== -1 || size
> UNITS_PER_WORD
;
2708 /* Return the length of INSN. LENGTH is the initial length computed by
2709 attributes in the machine-description file. */
2712 iq2000_adjust_insn_length (rtx insn
, int length
)
2714 /* A unconditional jump has an unfilled delay slot if it is not part
2715 of a sequence. A conditional jump normally has a delay slot. */
2716 if (simplejump_p (insn
)
2717 || ( (GET_CODE (insn
) == JUMP_INSN
2718 || GET_CODE (insn
) == CALL_INSN
)))
2724 /* Output assembly instructions to perform a conditional branch.
2726 INSN is the branch instruction. OPERANDS[0] is the condition.
2727 OPERANDS[1] is the target of the branch. OPERANDS[2] is the target
2728 of the first operand to the condition. If TWO_OPERANDS_P is
2729 nonzero the comparison takes two operands; OPERANDS[3] will be the
2732 If INVERTED_P is nonzero we are to branch if the condition does
2733 not hold. If FLOAT_P is nonzero this is a floating-point comparison.
2735 LENGTH is the length (in bytes) of the sequence we are to generate.
2736 That tells us whether to generate a simple conditional branch, or a
2737 reversed conditional branch around a `jr' instruction. */
2740 iq2000_output_conditional_branch (rtx insn
, rtx
* operands
, int two_operands_p
,
2741 int float_p
, int inverted_p
, int length
)
2743 static char buffer
[200];
2744 /* The kind of comparison we are doing. */
2745 enum rtx_code code
= GET_CODE (operands
[0]);
2746 /* Nonzero if the opcode for the comparison needs a `z' indicating
2747 that it is a comparison against zero. */
2749 /* A string to use in the assembly output to represent the first
2751 const char *op1
= "%z2";
2752 /* A string to use in the assembly output to represent the second
2753 operand. Use the hard-wired zero register if there's no second
2755 const char *op2
= (two_operands_p
? ",%z3" : ",%.");
2756 /* The operand-printing string for the comparison. */
2757 const char *comp
= (float_p
? "%F0" : "%C0");
2758 /* The operand-printing string for the inverted comparison. */
2759 const char *inverted_comp
= (float_p
? "%W0" : "%N0");
2761 /* Likely variants of each branch instruction annul the instruction
2762 in the delay slot if the branch is not taken. */
2763 iq2000_branch_likely
= (final_sequence
&& INSN_ANNULLED_BRANCH_P (insn
));
2765 if (!two_operands_p
)
2767 /* To compute whether than A > B, for example, we normally
2768 subtract B from A and then look at the sign bit. But, if we
2769 are doing an unsigned comparison, and B is zero, we don't
2770 have to do the subtraction. Instead, we can just check to
2771 see if A is nonzero. Thus, we change the CODE here to
2772 reflect the simpler comparison operation. */
2784 /* A condition which will always be true. */
2790 /* A condition which will always be false. */
2796 /* Not a special case. */
2801 /* Relative comparisons are always done against zero. But
2802 equality comparisons are done between two operands, and therefore
2803 do not require a `z' in the assembly language output. */
2804 need_z_p
= (!float_p
&& code
!= EQ
&& code
!= NE
);
2805 /* For comparisons against zero, the zero is not provided
2810 /* Begin by terminating the buffer. That way we can always use
2811 strcat to add to it. */
2818 /* Just a simple conditional branch. */
2820 sprintf (buffer
, "b%s%%?\t%%Z2%%1",
2821 inverted_p
? inverted_comp
: comp
);
2823 sprintf (buffer
, "b%s%s%%?\t%s%s,%%1",
2824 inverted_p
? inverted_comp
: comp
,
2825 need_z_p
? "z" : "",
2833 /* Generate a reversed conditional branch around ` j'
2845 Because we have to jump four bytes *past* the following
2846 instruction if this branch was annulled, we can't just use
2847 a label, as in the picture above; there's no way to put the
2848 label after the next instruction, as the assembler does not
2849 accept `.L+4' as the target of a branch. (We can't just
2850 wait until the next instruction is output; it might be a
2851 macro and take up more than four bytes. Once again, we see
2852 why we want to eliminate macros.)
2854 If the branch is annulled, we jump four more bytes that we
2855 would otherwise; that way we skip the annulled instruction
2856 in the delay slot. */
2859 = ((iq2000_branch_likely
|| length
== 16) ? ".+16" : ".+12");
2862 c
= strchr (buffer
, '\0');
2863 /* Generate the reversed comparison. This takes four
2866 sprintf (c
, "b%s\t%%Z2%s",
2867 inverted_p
? comp
: inverted_comp
,
2870 sprintf (c
, "b%s%s\t%s%s,%s",
2871 inverted_p
? comp
: inverted_comp
,
2872 need_z_p
? "z" : "",
2876 strcat (c
, "\n\tnop\n\tj\t%1");
2878 /* The delay slot was unfilled. Since we're inside
2879 .noreorder, the assembler will not fill in the NOP for
2880 us, so we must do it ourselves. */
2881 strcat (buffer
, "\n\tnop");
2893 #define def_builtin(NAME, TYPE, CODE) \
2894 builtin_function ((NAME), (TYPE), (CODE), BUILT_IN_MD, NULL, NULL_TREE)
2897 iq2000_init_builtins (void)
2899 tree endlink
= void_list_node
;
2900 tree void_ftype
, void_ftype_int
, void_ftype_int_int
;
2901 tree void_ftype_int_int_int
;
2902 tree int_ftype_int
, int_ftype_int_int
, int_ftype_int_int_int
;
2903 tree int_ftype_int_int_int_int
;
2907 = build_function_type (void_type_node
,
2908 tree_cons (NULL_TREE
, void_type_node
, endlink
));
2912 = build_function_type (void_type_node
,
2913 tree_cons (NULL_TREE
, integer_type_node
, endlink
));
2915 /* void func (int, int) */
2917 = build_function_type (void_type_node
,
2918 tree_cons (NULL_TREE
, integer_type_node
,
2919 tree_cons (NULL_TREE
, integer_type_node
,
2922 /* int func (int) */
2924 = build_function_type (integer_type_node
,
2925 tree_cons (NULL_TREE
, integer_type_node
, endlink
));
2927 /* int func (int, int) */
2929 = build_function_type (integer_type_node
,
2930 tree_cons (NULL_TREE
, integer_type_node
,
2931 tree_cons (NULL_TREE
, integer_type_node
,
2934 /* void func (int, int, int) */
2935 void_ftype_int_int_int
2936 = build_function_type
2938 tree_cons (NULL_TREE
, integer_type_node
,
2939 tree_cons (NULL_TREE
, integer_type_node
,
2940 tree_cons (NULL_TREE
,
2944 /* int func (int, int, int, int) */
2945 int_ftype_int_int_int_int
2946 = build_function_type
2948 tree_cons (NULL_TREE
, integer_type_node
,
2949 tree_cons (NULL_TREE
, integer_type_node
,
2950 tree_cons (NULL_TREE
,
2952 tree_cons (NULL_TREE
,
2956 /* int func (int, int, int) */
2957 int_ftype_int_int_int
2958 = build_function_type
2960 tree_cons (NULL_TREE
, integer_type_node
,
2961 tree_cons (NULL_TREE
, integer_type_node
,
2962 tree_cons (NULL_TREE
,
2966 /* int func (int, int, int, int) */
2967 int_ftype_int_int_int_int
2968 = build_function_type
2970 tree_cons (NULL_TREE
, integer_type_node
,
2971 tree_cons (NULL_TREE
, integer_type_node
,
2972 tree_cons (NULL_TREE
,
2974 tree_cons (NULL_TREE
,
2978 def_builtin ("__builtin_ado16", int_ftype_int_int
, IQ2000_BUILTIN_ADO16
);
2979 def_builtin ("__builtin_ram", int_ftype_int_int_int_int
, IQ2000_BUILTIN_RAM
);
2980 def_builtin ("__builtin_chkhdr", void_ftype_int_int
, IQ2000_BUILTIN_CHKHDR
);
2981 def_builtin ("__builtin_pkrl", void_ftype_int_int
, IQ2000_BUILTIN_PKRL
);
2982 def_builtin ("__builtin_cfc0", int_ftype_int
, IQ2000_BUILTIN_CFC0
);
2983 def_builtin ("__builtin_cfc1", int_ftype_int
, IQ2000_BUILTIN_CFC1
);
2984 def_builtin ("__builtin_cfc2", int_ftype_int
, IQ2000_BUILTIN_CFC2
);
2985 def_builtin ("__builtin_cfc3", int_ftype_int
, IQ2000_BUILTIN_CFC3
);
2986 def_builtin ("__builtin_ctc0", void_ftype_int_int
, IQ2000_BUILTIN_CTC0
);
2987 def_builtin ("__builtin_ctc1", void_ftype_int_int
, IQ2000_BUILTIN_CTC1
);
2988 def_builtin ("__builtin_ctc2", void_ftype_int_int
, IQ2000_BUILTIN_CTC2
);
2989 def_builtin ("__builtin_ctc3", void_ftype_int_int
, IQ2000_BUILTIN_CTC3
);
2990 def_builtin ("__builtin_mfc0", int_ftype_int
, IQ2000_BUILTIN_MFC0
);
2991 def_builtin ("__builtin_mfc1", int_ftype_int
, IQ2000_BUILTIN_MFC1
);
2992 def_builtin ("__builtin_mfc2", int_ftype_int
, IQ2000_BUILTIN_MFC2
);
2993 def_builtin ("__builtin_mfc3", int_ftype_int
, IQ2000_BUILTIN_MFC3
);
2994 def_builtin ("__builtin_mtc0", void_ftype_int_int
, IQ2000_BUILTIN_MTC0
);
2995 def_builtin ("__builtin_mtc1", void_ftype_int_int
, IQ2000_BUILTIN_MTC1
);
2996 def_builtin ("__builtin_mtc2", void_ftype_int_int
, IQ2000_BUILTIN_MTC2
);
2997 def_builtin ("__builtin_mtc3", void_ftype_int_int
, IQ2000_BUILTIN_MTC3
);
2998 def_builtin ("__builtin_lur", void_ftype_int_int
, IQ2000_BUILTIN_LUR
);
2999 def_builtin ("__builtin_rb", void_ftype_int_int
, IQ2000_BUILTIN_RB
);
3000 def_builtin ("__builtin_rx", void_ftype_int_int
, IQ2000_BUILTIN_RX
);
3001 def_builtin ("__builtin_srrd", void_ftype_int
, IQ2000_BUILTIN_SRRD
);
3002 def_builtin ("__builtin_srwr", void_ftype_int_int
, IQ2000_BUILTIN_SRWR
);
3003 def_builtin ("__builtin_wb", void_ftype_int_int
, IQ2000_BUILTIN_WB
);
3004 def_builtin ("__builtin_wx", void_ftype_int_int
, IQ2000_BUILTIN_WX
);
3005 def_builtin ("__builtin_luc32l", void_ftype_int_int
, IQ2000_BUILTIN_LUC32L
);
3006 def_builtin ("__builtin_luc64", void_ftype_int_int
, IQ2000_BUILTIN_LUC64
);
3007 def_builtin ("__builtin_luc64l", void_ftype_int_int
, IQ2000_BUILTIN_LUC64L
);
3008 def_builtin ("__builtin_luk", void_ftype_int_int
, IQ2000_BUILTIN_LUK
);
3009 def_builtin ("__builtin_lulck", void_ftype_int
, IQ2000_BUILTIN_LULCK
);
3010 def_builtin ("__builtin_lum32", void_ftype_int_int
, IQ2000_BUILTIN_LUM32
);
3011 def_builtin ("__builtin_lum32l", void_ftype_int_int
, IQ2000_BUILTIN_LUM32L
);
3012 def_builtin ("__builtin_lum64", void_ftype_int_int
, IQ2000_BUILTIN_LUM64
);
3013 def_builtin ("__builtin_lum64l", void_ftype_int_int
, IQ2000_BUILTIN_LUM64L
);
3014 def_builtin ("__builtin_lurl", void_ftype_int_int
, IQ2000_BUILTIN_LURL
);
3015 def_builtin ("__builtin_mrgb", int_ftype_int_int_int
, IQ2000_BUILTIN_MRGB
);
3016 def_builtin ("__builtin_srrdl", void_ftype_int
, IQ2000_BUILTIN_SRRDL
);
3017 def_builtin ("__builtin_srulck", void_ftype_int
, IQ2000_BUILTIN_SRULCK
);
3018 def_builtin ("__builtin_srwru", void_ftype_int_int
, IQ2000_BUILTIN_SRWRU
);
3019 def_builtin ("__builtin_trapqfl", void_ftype
, IQ2000_BUILTIN_TRAPQFL
);
3020 def_builtin ("__builtin_trapqne", void_ftype
, IQ2000_BUILTIN_TRAPQNE
);
3021 def_builtin ("__builtin_traprel", void_ftype_int
, IQ2000_BUILTIN_TRAPREL
);
3022 def_builtin ("__builtin_wbu", void_ftype_int_int_int
, IQ2000_BUILTIN_WBU
);
3023 def_builtin ("__builtin_syscall", void_ftype
, IQ2000_BUILTIN_SYSCALL
);
3026 /* Builtin for ICODE having ARGCOUNT args in ARGLIST where each arg
3030 expand_one_builtin (enum insn_code icode
, rtx target
, tree arglist
,
3031 enum rtx_code
*code
, int argcount
)
3036 enum machine_mode mode
[5];
3039 mode
[0] = insn_data
[icode
].operand
[0].mode
;
3040 for (i
= 0; i
< argcount
; i
++)
3042 arg
[i
] = TREE_VALUE (arglist
);
3043 arglist
= TREE_CHAIN (arglist
);
3044 op
[i
] = expand_expr (arg
[i
], NULL_RTX
, VOIDmode
, 0);
3045 mode
[i
] = insn_data
[icode
].operand
[i
].mode
;
3046 if (code
[i
] == CONST_INT
&& GET_CODE (op
[i
]) != CONST_INT
)
3047 error ("argument `%d' is not a constant", i
+ 1);
3049 && ! (*insn_data
[icode
].operand
[i
].predicate
) (op
[i
], mode
[i
]))
3050 op
[i
] = copy_to_mode_reg (mode
[i
], op
[i
]);
3053 if (insn_data
[icode
].operand
[0].constraint
[0] == '=')
3056 || GET_MODE (target
) != mode
[0]
3057 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, mode
[0]))
3058 target
= gen_reg_rtx (mode
[0]);
3066 pat
= GEN_FCN (icode
) (target
);
3069 pat
= GEN_FCN (icode
) (target
, op
[0]);
3071 pat
= GEN_FCN (icode
) (op
[0]);
3075 pat
= GEN_FCN (icode
) (target
, op
[0], op
[1]);
3077 pat
= GEN_FCN (icode
) (op
[0], op
[1]);
3081 pat
= GEN_FCN (icode
) (target
, op
[0], op
[1], op
[2]);
3083 pat
= GEN_FCN (icode
) (op
[0], op
[1], op
[2]);
3087 pat
= GEN_FCN (icode
) (target
, op
[0], op
[1], op
[2], op
[3]);
3089 pat
= GEN_FCN (icode
) (op
[0], op
[1], op
[2], op
[3]);
3101 /* Expand an expression EXP that calls a built-in function,
3102 with result going to TARGET if that's convenient
3103 (and in mode MODE if that's convenient).
3104 SUBTARGET may be used as the target for computing one of EXP's operands.
3105 IGNORE is nonzero if the value is to be ignored. */
3108 iq2000_expand_builtin (tree exp
, rtx target
, rtx subtarget ATTRIBUTE_UNUSED
,
3109 enum machine_mode mode ATTRIBUTE_UNUSED
,
3110 int ignore ATTRIBUTE_UNUSED
)
3112 tree fndecl
= TREE_OPERAND (TREE_OPERAND (exp
, 0), 0);
3113 tree arglist
= TREE_OPERAND (exp
, 1);
3114 int fcode
= DECL_FUNCTION_CODE (fndecl
);
3115 enum rtx_code code
[5];
3127 case IQ2000_BUILTIN_ADO16
:
3128 return expand_one_builtin (CODE_FOR_ado16
, target
, arglist
, code
, 2);
3130 case IQ2000_BUILTIN_RAM
:
3131 code
[1] = CONST_INT
;
3132 code
[2] = CONST_INT
;
3133 code
[3] = CONST_INT
;
3134 return expand_one_builtin (CODE_FOR_ram
, target
, arglist
, code
, 4);
3136 case IQ2000_BUILTIN_CHKHDR
:
3137 return expand_one_builtin (CODE_FOR_chkhdr
, target
, arglist
, code
, 2);
3139 case IQ2000_BUILTIN_PKRL
:
3140 return expand_one_builtin (CODE_FOR_pkrl
, target
, arglist
, code
, 2);
3142 case IQ2000_BUILTIN_CFC0
:
3143 code
[0] = CONST_INT
;
3144 return expand_one_builtin (CODE_FOR_cfc0
, target
, arglist
, code
, 1);
3146 case IQ2000_BUILTIN_CFC1
:
3147 code
[0] = CONST_INT
;
3148 return expand_one_builtin (CODE_FOR_cfc1
, target
, arglist
, code
, 1);
3150 case IQ2000_BUILTIN_CFC2
:
3151 code
[0] = CONST_INT
;
3152 return expand_one_builtin (CODE_FOR_cfc2
, target
, arglist
, code
, 1);
3154 case IQ2000_BUILTIN_CFC3
:
3155 code
[0] = CONST_INT
;
3156 return expand_one_builtin (CODE_FOR_cfc3
, target
, arglist
, code
, 1);
3158 case IQ2000_BUILTIN_CTC0
:
3159 code
[1] = CONST_INT
;
3160 return expand_one_builtin (CODE_FOR_ctc0
, target
, arglist
, code
, 2);
3162 case IQ2000_BUILTIN_CTC1
:
3163 code
[1] = CONST_INT
;
3164 return expand_one_builtin (CODE_FOR_ctc1
, target
, arglist
, code
, 2);
3166 case IQ2000_BUILTIN_CTC2
:
3167 code
[1] = CONST_INT
;
3168 return expand_one_builtin (CODE_FOR_ctc2
, target
, arglist
, code
, 2);
3170 case IQ2000_BUILTIN_CTC3
:
3171 code
[1] = CONST_INT
;
3172 return expand_one_builtin (CODE_FOR_ctc3
, target
, arglist
, code
, 2);
3174 case IQ2000_BUILTIN_MFC0
:
3175 code
[0] = CONST_INT
;
3176 return expand_one_builtin (CODE_FOR_mfc0
, target
, arglist
, code
, 1);
3178 case IQ2000_BUILTIN_MFC1
:
3179 code
[0] = CONST_INT
;
3180 return expand_one_builtin (CODE_FOR_mfc1
, target
, arglist
, code
, 1);
3182 case IQ2000_BUILTIN_MFC2
:
3183 code
[0] = CONST_INT
;
3184 return expand_one_builtin (CODE_FOR_mfc2
, target
, arglist
, code
, 1);
3186 case IQ2000_BUILTIN_MFC3
:
3187 code
[0] = CONST_INT
;
3188 return expand_one_builtin (CODE_FOR_mfc3
, target
, arglist
, code
, 1);
3190 case IQ2000_BUILTIN_MTC0
:
3191 code
[1] = CONST_INT
;
3192 return expand_one_builtin (CODE_FOR_mtc0
, target
, arglist
, code
, 2);
3194 case IQ2000_BUILTIN_MTC1
:
3195 code
[1] = CONST_INT
;
3196 return expand_one_builtin (CODE_FOR_mtc1
, target
, arglist
, code
, 2);
3198 case IQ2000_BUILTIN_MTC2
:
3199 code
[1] = CONST_INT
;
3200 return expand_one_builtin (CODE_FOR_mtc2
, target
, arglist
, code
, 2);
3202 case IQ2000_BUILTIN_MTC3
:
3203 code
[1] = CONST_INT
;
3204 return expand_one_builtin (CODE_FOR_mtc3
, target
, arglist
, code
, 2);
3206 case IQ2000_BUILTIN_LUR
:
3207 return expand_one_builtin (CODE_FOR_lur
, target
, arglist
, code
, 2);
3209 case IQ2000_BUILTIN_RB
:
3210 return expand_one_builtin (CODE_FOR_rb
, target
, arglist
, code
, 2);
3212 case IQ2000_BUILTIN_RX
:
3213 return expand_one_builtin (CODE_FOR_rx
, target
, arglist
, code
, 2);
3215 case IQ2000_BUILTIN_SRRD
:
3216 return expand_one_builtin (CODE_FOR_srrd
, target
, arglist
, code
, 1);
3218 case IQ2000_BUILTIN_SRWR
:
3219 return expand_one_builtin (CODE_FOR_srwr
, target
, arglist
, code
, 2);
3221 case IQ2000_BUILTIN_WB
:
3222 return expand_one_builtin (CODE_FOR_wb
, target
, arglist
, code
, 2);
3224 case IQ2000_BUILTIN_WX
:
3225 return expand_one_builtin (CODE_FOR_wx
, target
, arglist
, code
, 2);
3227 case IQ2000_BUILTIN_LUC32L
:
3228 return expand_one_builtin (CODE_FOR_luc32l
, target
, arglist
, code
, 2);
3230 case IQ2000_BUILTIN_LUC64
:
3231 return expand_one_builtin (CODE_FOR_luc64
, target
, arglist
, code
, 2);
3233 case IQ2000_BUILTIN_LUC64L
:
3234 return expand_one_builtin (CODE_FOR_luc64l
, target
, arglist
, code
, 2);
3236 case IQ2000_BUILTIN_LUK
:
3237 return expand_one_builtin (CODE_FOR_luk
, target
, arglist
, code
, 2);
3239 case IQ2000_BUILTIN_LULCK
:
3240 return expand_one_builtin (CODE_FOR_lulck
, target
, arglist
, code
, 1);
3242 case IQ2000_BUILTIN_LUM32
:
3243 return expand_one_builtin (CODE_FOR_lum32
, target
, arglist
, code
, 2);
3245 case IQ2000_BUILTIN_LUM32L
:
3246 return expand_one_builtin (CODE_FOR_lum32l
, target
, arglist
, code
, 2);
3248 case IQ2000_BUILTIN_LUM64
:
3249 return expand_one_builtin (CODE_FOR_lum64
, target
, arglist
, code
, 2);
3251 case IQ2000_BUILTIN_LUM64L
:
3252 return expand_one_builtin (CODE_FOR_lum64l
, target
, arglist
, code
, 2);
3254 case IQ2000_BUILTIN_LURL
:
3255 return expand_one_builtin (CODE_FOR_lurl
, target
, arglist
, code
, 2);
3257 case IQ2000_BUILTIN_MRGB
:
3258 code
[2] = CONST_INT
;
3259 return expand_one_builtin (CODE_FOR_mrgb
, target
, arglist
, code
, 3);
3261 case IQ2000_BUILTIN_SRRDL
:
3262 return expand_one_builtin (CODE_FOR_srrdl
, target
, arglist
, code
, 1);
3264 case IQ2000_BUILTIN_SRULCK
:
3265 return expand_one_builtin (CODE_FOR_srulck
, target
, arglist
, code
, 1);
3267 case IQ2000_BUILTIN_SRWRU
:
3268 return expand_one_builtin (CODE_FOR_srwru
, target
, arglist
, code
, 2);
3270 case IQ2000_BUILTIN_TRAPQFL
:
3271 return expand_one_builtin (CODE_FOR_trapqfl
, target
, arglist
, code
, 0);
3273 case IQ2000_BUILTIN_TRAPQNE
:
3274 return expand_one_builtin (CODE_FOR_trapqne
, target
, arglist
, code
, 0);
3276 case IQ2000_BUILTIN_TRAPREL
:
3277 return expand_one_builtin (CODE_FOR_traprel
, target
, arglist
, code
, 1);
3279 case IQ2000_BUILTIN_WBU
:
3280 return expand_one_builtin (CODE_FOR_wbu
, target
, arglist
, code
, 3);
3282 case IQ2000_BUILTIN_SYSCALL
:
3283 return expand_one_builtin (CODE_FOR_syscall
, target
, arglist
, code
, 0);
3289 /* Worker function for TARGET_RETURN_IN_MEMORY. */
3292 iq2000_return_in_memory (tree type
, tree fntype ATTRIBUTE_UNUSED
)
3294 return ((int_size_in_bytes (type
) > (2 * UNITS_PER_WORD
))
3295 || (int_size_in_bytes (type
) == -1));
3298 /* Worker function for TARGET_SETUP_INCOMING_VARARGS. */
3301 iq2000_setup_incoming_varargs (CUMULATIVE_ARGS
*cum
,
3302 enum machine_mode mode ATTRIBUTE_UNUSED
,
3303 tree type ATTRIBUTE_UNUSED
, int * pretend_size
,
3306 unsigned int iq2000_off
= ! cum
->last_arg_fp
;
3307 unsigned int iq2000_fp_off
= cum
->last_arg_fp
;
3309 if ((cum
->arg_words
< MAX_ARGS_IN_REGISTERS
- iq2000_off
))
3311 int iq2000_save_gp_regs
3312 = MAX_ARGS_IN_REGISTERS
- cum
->arg_words
- iq2000_off
;
3313 int iq2000_save_fp_regs
3314 = (MAX_ARGS_IN_REGISTERS
- cum
->fp_arg_words
- iq2000_fp_off
);
3316 if (iq2000_save_gp_regs
< 0)
3317 iq2000_save_gp_regs
= 0;
3318 if (iq2000_save_fp_regs
< 0)
3319 iq2000_save_fp_regs
= 0;
3321 *pretend_size
= ((iq2000_save_gp_regs
* UNITS_PER_WORD
)
3322 + (iq2000_save_fp_regs
* UNITS_PER_FPREG
));
3326 if (cum
->arg_words
< MAX_ARGS_IN_REGISTERS
- iq2000_off
)
3329 ptr
= plus_constant (virtual_incoming_args_rtx
,
3330 - (iq2000_save_gp_regs
3332 mem
= gen_rtx_MEM (BLKmode
, ptr
);
3334 (cum
->arg_words
+ GP_ARG_FIRST
+ iq2000_off
,
3336 iq2000_save_gp_regs
);
3342 /* A C compound statement to output to stdio stream STREAM the
3343 assembler syntax for an instruction operand that is a memory
3344 reference whose address is ADDR. ADDR is an RTL expression. */
3347 print_operand_address (FILE * file
, rtx addr
)
3350 error ("PRINT_OPERAND_ADDRESS, null pointer");
3353 switch (GET_CODE (addr
))
3356 if (REGNO (addr
) == ARG_POINTER_REGNUM
)
3357 abort_with_insn (addr
, "Arg pointer not eliminated.");
3359 fprintf (file
, "0(%s)", reg_names
[REGNO (addr
)]);
3364 rtx arg0
= XEXP (addr
, 0);
3365 rtx arg1
= XEXP (addr
, 1);
3367 if (GET_CODE (arg0
) != REG
)
3368 abort_with_insn (addr
,
3369 "PRINT_OPERAND_ADDRESS, LO_SUM with #1 not REG.");
3371 fprintf (file
, "%%lo(");
3372 print_operand_address (file
, arg1
);
3373 fprintf (file
, ")(%s)", reg_names
[REGNO (arg0
)]);
3381 rtx arg0
= XEXP (addr
, 0);
3382 rtx arg1
= XEXP (addr
, 1);
3384 if (GET_CODE (arg0
) == REG
)
3388 if (GET_CODE (offset
) == REG
)
3389 abort_with_insn (addr
, "PRINT_OPERAND_ADDRESS, 2 regs");
3392 else if (GET_CODE (arg1
) == REG
)
3393 reg
= arg1
, offset
= arg0
;
3394 else if (CONSTANT_P (arg0
) && CONSTANT_P (arg1
))
3396 output_addr_const (file
, addr
);
3400 abort_with_insn (addr
, "PRINT_OPERAND_ADDRESS, no regs");
3402 if (! CONSTANT_P (offset
))
3403 abort_with_insn (addr
, "PRINT_OPERAND_ADDRESS, invalid insn #2");
3405 if (REGNO (reg
) == ARG_POINTER_REGNUM
)
3406 abort_with_insn (addr
, "Arg pointer not eliminated.");
3408 output_addr_const (file
, offset
);
3409 fprintf (file
, "(%s)", reg_names
[REGNO (reg
)]);
3417 output_addr_const (file
, addr
);
3418 if (GET_CODE (addr
) == CONST_INT
)
3419 fprintf (file
, "(%s)", reg_names
[0]);
3423 abort_with_insn (addr
, "PRINT_OPERAND_ADDRESS, invalid insn #1");
3428 /* A C compound statement to output to stdio stream FILE the
3429 assembler syntax for an instruction operand OP.
3431 LETTER is a value that can be used to specify one of several ways
3432 of printing the operand. It is used when identical operands
3433 must be printed differently depending on the context. LETTER
3434 comes from the `%' specification that was used to request
3435 printing of the operand. If the specification was just `%DIGIT'
3436 then LETTER is 0; if the specification was `%LTR DIGIT' then LETTER
3437 is the ASCII code for LTR.
3439 If OP is a register, this macro should print the register's name.
3440 The names can be found in an array `reg_names' whose type is
3441 `char *[]'. `reg_names' is initialized from `REGISTER_NAMES'.
3443 When the machine description has a specification `%PUNCT' (a `%'
3444 followed by a punctuation character), this macro is called with
3445 a null pointer for X and the punctuation character for LETTER.
3447 The IQ2000 specific codes are:
3449 'X' X is CONST_INT, prints upper 16 bits in hexadecimal format = "0x%04x",
3450 'x' X is CONST_INT, prints lower 16 bits in hexadecimal format = "0x%04x",
3451 'd' output integer constant in decimal,
3452 'z' if the operand is 0, use $0 instead of normal operand.
3453 'D' print second part of double-word register or memory operand.
3454 'L' print low-order register of double-word register operand.
3455 'M' print high-order register of double-word register operand.
3456 'C' print part of opcode for a branch condition.
3457 'F' print part of opcode for a floating-point branch condition.
3458 'N' print part of opcode for a branch condition, inverted.
3459 'W' print part of opcode for a floating-point branch condition, inverted.
3460 'A' Print part of opcode for a bit test condition.
3461 'P' Print label for a bit test.
3462 'p' Print log for a bit test.
3463 'B' print 'z' for EQ, 'n' for NE
3464 'b' print 'n' for EQ, 'z' for NE
3465 'T' print 'f' for EQ, 't' for NE
3466 't' print 't' for EQ, 'f' for NE
3467 'Z' print register and a comma, but print nothing for $fcc0
3468 '?' Print 'l' if we are to use a branch likely instead of normal branch.
3469 '@' Print the name of the assembler temporary register (at or $1).
3470 '.' Print the name of the register with a hard-wired zero (zero or $0).
3471 '$' Print the name of the stack pointer register (sp or $29).
3472 '+' Print the name of the gp register (gp or $28). */
3475 print_operand (FILE *file
, rtx op
, int letter
)
3479 if (PRINT_OPERAND_PUNCT_VALID_P (letter
))
3484 if (iq2000_branch_likely
)
3489 fputs (reg_names
[GP_REG_FIRST
+ 1], file
);
3493 fputs (reg_names
[GP_REG_FIRST
+ 0], file
);
3497 fputs (reg_names
[STACK_POINTER_REGNUM
], file
);
3501 fputs (reg_names
[GP_REG_FIRST
+ 28], file
);
3505 error ("PRINT_OPERAND: Unknown punctuation '%c'", letter
);
3514 error ("PRINT_OPERAND null pointer");
3518 code
= GET_CODE (op
);
3520 if (code
== SIGN_EXTEND
)
3521 op
= XEXP (op
, 0), code
= GET_CODE (op
);
3526 case EQ
: fputs ("eq", file
); break;
3527 case NE
: fputs ("ne", file
); break;
3528 case GT
: fputs ("gt", file
); break;
3529 case GE
: fputs ("ge", file
); break;
3530 case LT
: fputs ("lt", file
); break;
3531 case LE
: fputs ("le", file
); break;
3532 case GTU
: fputs ("ne", file
); break;
3533 case GEU
: fputs ("geu", file
); break;
3534 case LTU
: fputs ("ltu", file
); break;
3535 case LEU
: fputs ("eq", file
); break;
3537 abort_with_insn (op
, "PRINT_OPERAND, invalid insn for %%C");
3540 else if (letter
== 'N')
3543 case EQ
: fputs ("ne", file
); break;
3544 case NE
: fputs ("eq", file
); break;
3545 case GT
: fputs ("le", file
); break;
3546 case GE
: fputs ("lt", file
); break;
3547 case LT
: fputs ("ge", file
); break;
3548 case LE
: fputs ("gt", file
); break;
3549 case GTU
: fputs ("leu", file
); break;
3550 case GEU
: fputs ("ltu", file
); break;
3551 case LTU
: fputs ("geu", file
); break;
3552 case LEU
: fputs ("gtu", file
); break;
3554 abort_with_insn (op
, "PRINT_OPERAND, invalid insn for %%N");
3557 else if (letter
== 'F')
3560 case EQ
: fputs ("c1f", file
); break;
3561 case NE
: fputs ("c1t", file
); break;
3563 abort_with_insn (op
, "PRINT_OPERAND, invalid insn for %%F");
3566 else if (letter
== 'W')
3569 case EQ
: fputs ("c1t", file
); break;
3570 case NE
: fputs ("c1f", file
); break;
3572 abort_with_insn (op
, "PRINT_OPERAND, invalid insn for %%W");
3575 else if (letter
== 'A')
3576 fputs (code
== LABEL_REF
? "i" : "in", file
);
3578 else if (letter
== 'P')
3580 if (code
== LABEL_REF
)
3581 output_addr_const (file
, op
);
3582 else if (code
!= PC
)
3583 output_operand_lossage ("invalid %%P operand");
3586 else if (letter
== 'p')
3589 if (code
!= CONST_INT
3590 || (value
= exact_log2 (INTVAL (op
))) < 0)
3591 output_operand_lossage ("invalid %%p value");
3592 fprintf (file
, "%d", value
);
3595 else if (letter
== 'Z')
3602 regnum
= REGNO (op
);
3605 fprintf (file
, "%s,", reg_names
[regnum
]);
3608 else if (code
== REG
|| code
== SUBREG
)
3613 regnum
= REGNO (op
);
3615 regnum
= true_regnum (op
);
3617 if ((letter
== 'M' && ! WORDS_BIG_ENDIAN
)
3618 || (letter
== 'L' && WORDS_BIG_ENDIAN
)
3622 fprintf (file
, "%s", reg_names
[regnum
]);
3625 else if (code
== MEM
)
3628 output_address (plus_constant (XEXP (op
, 0), 4));
3630 output_address (XEXP (op
, 0));
3633 else if (code
== CONST_DOUBLE
3634 && GET_MODE_CLASS (GET_MODE (op
)) == MODE_FLOAT
)
3638 real_to_decimal (s
, CONST_DOUBLE_REAL_VALUE (op
), sizeof (s
), 0, 1);
3642 else if (letter
== 'x' && GET_CODE (op
) == CONST_INT
)
3643 fprintf (file
, HOST_WIDE_INT_PRINT_HEX
, 0xffff & INTVAL(op
));
3645 else if (letter
== 'X' && GET_CODE(op
) == CONST_INT
)
3646 fprintf (file
, HOST_WIDE_INT_PRINT_HEX
, 0xffff & (INTVAL (op
) >> 16));
3648 else if (letter
== 'd' && GET_CODE(op
) == CONST_INT
)
3649 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, (INTVAL(op
)));
3651 else if (letter
== 'z' && GET_CODE (op
) == CONST_INT
&& INTVAL (op
) == 0)
3652 fputs (reg_names
[GP_REG_FIRST
], file
);
3654 else if (letter
== 'd' || letter
== 'x' || letter
== 'X')
3655 output_operand_lossage ("invalid use of %%d, %%x, or %%X");
3657 else if (letter
== 'B')
3658 fputs (code
== EQ
? "z" : "n", file
);
3659 else if (letter
== 'b')
3660 fputs (code
== EQ
? "n" : "z", file
);
3661 else if (letter
== 'T')
3662 fputs (code
== EQ
? "f" : "t", file
);
3663 else if (letter
== 't')
3664 fputs (code
== EQ
? "t" : "f", file
);
3666 else if (code
== CONST
&& GET_CODE (XEXP (op
, 0)) == REG
)
3668 print_operand (file
, XEXP (op
, 0), letter
);
3672 output_addr_const (file
, op
);
3676 iq2000_rtx_costs (rtx x
, int code
, int outer_code ATTRIBUTE_UNUSED
, int * total
)
3678 enum machine_mode mode
= GET_MODE (x
);
3684 int num_words
= (GET_MODE_SIZE (mode
) > UNITS_PER_WORD
) ? 2 : 1;
3686 if (simple_memory_operand (x
, mode
))
3687 return COSTS_N_INSNS (num_words
);
3689 * total
= COSTS_N_INSNS (2 * num_words
);
3694 * total
= COSTS_N_INSNS (6);
3701 * total
= COSTS_N_INSNS (mode
== DImode
? 2 : 1);
3708 * total
= COSTS_N_INSNS ((GET_CODE (XEXP (x
, 1)) == CONST_INT
) ? 4 : 12);
3710 * total
= COSTS_N_INSNS (1);
3714 if (mode
== SFmode
|| mode
== DFmode
)
3715 * total
= COSTS_N_INSNS (1);
3717 * total
= COSTS_N_INSNS (4);
3722 if (mode
== SFmode
|| mode
== DFmode
)
3723 * total
= COSTS_N_INSNS (6);
3724 else if (mode
== DImode
)
3725 * total
= COSTS_N_INSNS (4);
3727 * total
= COSTS_N_INSNS (1);
3731 * total
= (mode
== DImode
) ? 4 : 1;
3736 * total
= COSTS_N_INSNS (7);
3737 else if (mode
== DFmode
)
3738 * total
= COSTS_N_INSNS (8);
3740 * total
= COSTS_N_INSNS (10);
3746 * total
= COSTS_N_INSNS (23);
3747 else if (mode
== DFmode
)
3748 * total
= COSTS_N_INSNS (36);
3750 * total
= COSTS_N_INSNS (69);
3755 * total
= COSTS_N_INSNS (69);
3759 * total
= COSTS_N_INSNS (2);
3763 * total
= COSTS_N_INSNS (1);
3771 * total
= COSTS_N_INSNS (2);
3776 rtx offset
= const0_rtx
;
3777 rtx symref
= eliminate_constant_term (XEXP (x
, 0), & offset
);
3779 if (GET_CODE (symref
) == LABEL_REF
)
3780 * total
= COSTS_N_INSNS (2);
3781 else if (GET_CODE (symref
) != SYMBOL_REF
)
3782 * total
= COSTS_N_INSNS (4);
3783 /* Let's be paranoid.... */
3784 else if (INTVAL (offset
) < -32768 || INTVAL (offset
) > 32767)
3785 * total
= COSTS_N_INSNS (2);
3787 * total
= COSTS_N_INSNS (SYMBOL_REF_FLAG (symref
) ? 1 : 2);
3792 * total
= COSTS_N_INSNS (SYMBOL_REF_FLAG (x
) ? 1 : 2);
3799 split_double (x
, & high
, & low
);
3801 * total
= COSTS_N_INSNS ( (high
== CONST0_RTX (GET_MODE (high
))
3802 || low
== CONST0_RTX (GET_MODE (low
)))
3813 #include "gt-iq2000.h"