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_RETURN_IN_MEMORY
196 #define TARGET_RETURN_IN_MEMORY iq2000_return_in_memory
198 #undef TARGET_SETUP_INCOMING_VARARGS
199 #define TARGET_SETUP_INCOMING_VARARGS iq2000_setup_incoming_varargs
200 #undef TARGET_STRICT_ARGUMENT_NAMING
201 #define TARGET_STRICT_ARGUMENT_NAMING hook_bool_CUMULATIVE_ARGS_true
203 struct gcc_target targetm = TARGET_INITIALIZER;
205 /* Return 1 if OP can be used as an operand where a register or 16 bit unsigned
206 integer is needed. */
209 uns_arith_operand (rtx op, enum machine_mode mode)
211 if (GET_CODE (op) == CONST_INT && SMALL_INT_UNSIGNED (op))
214 return register_operand (op, mode);
217 /* Return 1 if OP can be used as an operand where a 16 bit integer is needed. */
220 arith_operand (rtx op, enum machine_mode mode)
222 if (GET_CODE (op) == CONST_INT && SMALL_INT (op))
225 return register_operand (op, mode);
228 /* Return 1 if OP is a integer which fits in 16 bits. */
231 small_int (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
233 return (GET_CODE (op) == CONST_INT && SMALL_INT (op));
236 /* Return 1 if OP is a 32 bit integer which is too big to be loaded with one
240 large_int (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
244 if (GET_CODE (op) != CONST_INT)
249 /* IOR reg,$r0,value. */
250 if ((value & ~ ((HOST_WIDE_INT) 0x0000ffff)) == 0)
253 /* SUBU reg,$r0,value. */
254 if (((unsigned HOST_WIDE_INT) (value + 32768)) <= 32767)
257 /* LUI reg,value >> 16. */
258 if ((value & 0x0000ffff) == 0)
264 /* Return 1 if OP is a register or the constant 0. */
267 reg_or_0_operand (rtx op, enum machine_mode mode)
269 switch (GET_CODE (op))
272 return INTVAL (op) == 0;
275 return op == CONST0_RTX (mode);
279 return register_operand (op, mode);
288 /* Return 1 if OP is a memory operand that fits in a single instruction
289 (ie, register + small offset). */
292 simple_memory_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
294 rtx addr, plus0, plus1;
296 /* Eliminate non-memory operations. */
297 if (GET_CODE (op) != MEM)
300 /* Dword operations really put out 2 instructions, so eliminate them. */
301 if (GET_MODE_SIZE (GET_MODE (op)) > (unsigned) UNITS_PER_WORD)
304 /* Decode the address now. */
306 switch (GET_CODE (addr))
313 return SMALL_INT (addr);
316 plus0 = XEXP (addr, 0);
317 plus1 = XEXP (addr, 1);
318 if (GET_CODE (plus0) == REG
319 && GET_CODE (plus1) == CONST_INT && SMALL_INT (plus1)
320 && SMALL_INT_UNSIGNED (plus1) /* No negative offsets. */)
323 else if (GET_CODE (plus1) == REG
324 && GET_CODE (plus0) == CONST_INT && SMALL_INT (plus0)
325 && SMALL_INT_UNSIGNED (plus1) /* No negative offsets. */)
341 /* Return nonzero if the code of this rtx pattern is EQ or NE. */
344 equality_op (rtx op, enum machine_mode mode)
346 if (mode != GET_MODE (op))
349 return GET_CODE (op) == EQ || GET_CODE (op) == NE;
352 /* Return nonzero if the code is a relational operations (EQ, LE, etc). */
355 cmp_op (rtx op, enum machine_mode mode)
357 if (mode != GET_MODE (op))
360 return COMPARISON_P (op);
363 /* Return nonzero if the operand is either the PC or a label_ref. */
366 pc_or_label_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
371 if (GET_CODE (op) == LABEL_REF)
377 /* Return nonzero if OP is a valid operand for a call instruction. */
380 call_insn_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
382 return (CONSTANT_ADDRESS_P (op)
383 || (GET_CODE (op) == REG && op != arg_pointer_rtx
384 && ! (REGNO (op) >= FIRST_PSEUDO_REGISTER
385 && REGNO (op) <= LAST_VIRTUAL_REGISTER)));
388 /* Return nonzero if OP is valid as a source operand for a move instruction. */
391 move_operand (rtx op, enum machine_mode mode)
393 /* Accept any general operand after reload has started; doing so
394 avoids losing if reload does an in-place replacement of a register
395 with a SYMBOL_REF or CONST. */
396 return (general_operand (op, mode)
397 && (! (iq2000_check_split (op, mode))
398 || reload_in_progress || reload_completed));
401 /* Return nonzero if OP is a constant power of 2. */
404 power_of_2_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
408 if (GET_CODE (op) != CONST_INT)
411 intval = INTVAL (op);
413 return ((intval & ((unsigned)(intval) - 1)) == 0);
416 /* Return nonzero if we split the address into high and low parts. */
419 iq2000_check_split (rtx address, enum machine_mode mode)
421 /* This is the same check used in simple_memory_operand.
422 We use it here because LO_SUM is not offsettable. */
423 if (GET_MODE_SIZE (mode) > (unsigned) UNITS_PER_WORD)
426 if ((GET_CODE (address) == SYMBOL_REF)
427 || (GET_CODE (address) == CONST
428 && GET_CODE (XEXP (XEXP (address, 0), 0)) == SYMBOL_REF)
429 || GET_CODE (address) == LABEL_REF)
435 /* Return nonzero if REG is valid for MODE. */
438 iq2000_reg_mode_ok_for_base_p (rtx reg,
439 enum machine_mode mode ATTRIBUTE_UNUSED,
443 ? REGNO_MODE_OK_FOR_BASE_P (REGNO (reg), mode)
444 : GP_REG_OR_PSEUDO_NONSTRICT_P (REGNO (reg), mode));
447 /* Return a nonzero value if XINSN is a legitimate address for a
448 memory operand of the indicated MODE. STRICT is nonzero if this
449 function is called during reload. */
452 iq2000_legitimate_address_p (enum machine_mode mode, rtx xinsn, int strict)
454 if (TARGET_DEBUG_A_MODE)
456 GO_PRINTF2 ("\n========== GO_IF_LEGITIMATE_ADDRESS, %sstrict\n",
457 strict ? "" : "not ");
458 GO_DEBUG_RTX (xinsn);
461 /* Check for constant before stripping off SUBREG, so that we don't
462 accept (subreg (const_int)) which will fail to reload. */
463 if (CONSTANT_ADDRESS_P (xinsn)
464 && ! (iq2000_check_split (xinsn, mode))
465 && ! (GET_CODE (xinsn) == CONST_INT && ! SMALL_INT (xinsn)))
468 while (GET_CODE (xinsn) == SUBREG)
469 xinsn = SUBREG_REG (xinsn);
471 if (GET_CODE (xinsn) == REG
472 && iq2000_reg_mode_ok_for_base_p (xinsn, mode, strict))
475 if (GET_CODE (xinsn) == LO_SUM)
477 rtx xlow0 = XEXP (xinsn, 0);
478 rtx xlow1 = XEXP (xinsn, 1);
480 while (GET_CODE (xlow0) == SUBREG)
481 xlow0 = SUBREG_REG (xlow0);
482 if (GET_CODE (xlow0) == REG
483 && iq2000_reg_mode_ok_for_base_p (xlow0, mode, strict)
484 && iq2000_check_split (xlow1, mode))
488 if (GET_CODE (xinsn) == PLUS)
490 rtx xplus0 = XEXP (xinsn, 0);
491 rtx xplus1 = XEXP (xinsn, 1);
495 while (GET_CODE (xplus0) == SUBREG)
496 xplus0 = SUBREG_REG (xplus0);
497 code0 = GET_CODE (xplus0);
499 while (GET_CODE (xplus1) == SUBREG)
500 xplus1 = SUBREG_REG (xplus1);
501 code1 = GET_CODE (xplus1);
504 && iq2000_reg_mode_ok_for_base_p (xplus0, mode, strict))
506 if (code1 == CONST_INT && SMALL_INT (xplus1)
507 && SMALL_INT_UNSIGNED (xplus1) /* No negative offsets */)
512 if (TARGET_DEBUG_A_MODE)
513 GO_PRINTF ("Not a legitimate address\n");
515 /* The address was not legitimate. */
519 /* Returns an operand string for the given instruction's delay slot,
520 after updating filled delay slot statistics.
522 We assume that operands[0] is the target register that is set.
524 In order to check the next insn, most of this functionality is moved
525 to FINAL_PRESCAN_INSN, and we just set the global variables that
529 iq2000_fill_delay_slot (const char *ret, enum delay_type type, rtx operands[],
533 enum machine_mode mode;
534 rtx next_insn = cur_insn ? NEXT_INSN (cur_insn) : NULL_RTX;
537 if (type == DELAY_LOAD || type == DELAY_FCMP)
543 /* Make sure that we don't put nop's after labels. */
544 next_insn = NEXT_INSN (cur_insn);
545 while (next_insn != 0
546 && (GET_CODE (next_insn) == NOTE
547 || GET_CODE (next_insn) == CODE_LABEL))
548 next_insn = NEXT_INSN (next_insn);
550 dslots_load_total += num_nops;
551 if (TARGET_DEBUG_C_MODE
552 || type == DELAY_NONE
556 || GET_CODE (next_insn) == CODE_LABEL
557 || (set_reg = operands[0]) == 0)
559 dslots_number_nops = 0;
561 iq2000_load_reg2 = 0;
562 iq2000_load_reg3 = 0;
563 iq2000_load_reg4 = 0;
568 set_reg = operands[0];
572 while (GET_CODE (set_reg) == SUBREG)
573 set_reg = SUBREG_REG (set_reg);
575 mode = GET_MODE (set_reg);
576 dslots_number_nops = num_nops;
577 iq2000_load_reg = set_reg;
578 if (GET_MODE_SIZE (mode)
579 > (unsigned) (UNITS_PER_WORD))
580 iq2000_load_reg2 = gen_rtx_REG (SImode, REGNO (set_reg) + 1);
582 iq2000_load_reg2 = 0;
587 /* Determine whether a memory reference takes one (based off of the GP
588 pointer), two (normal), or three (label + reg) instructions, and bump the
589 appropriate counter for -mstats. */
592 iq2000_count_memory_refs (rtx op, int num)
596 rtx addr, plus0, plus1;
597 enum rtx_code code0, code1;
600 if (TARGET_DEBUG_B_MODE)
602 fprintf (stderr, "\n========== iq2000_count_memory_refs:\n");
606 /* Skip MEM if passed, otherwise handle movsi of address. */
607 addr = (GET_CODE (op) != MEM) ? op : XEXP (op, 0);
609 /* Loop, going through the address RTL. */
613 switch (GET_CODE (addr))
621 plus0 = XEXP (addr, 0);
622 plus1 = XEXP (addr, 1);
623 code0 = GET_CODE (plus0);
624 code1 = GET_CODE (plus1);
634 if (code0 == CONST_INT)
649 if (code1 == CONST_INT)
656 if (code0 == SYMBOL_REF || code0 == LABEL_REF || code0 == CONST)
663 if (code1 == SYMBOL_REF || code1 == LABEL_REF || code1 == CONST)
673 n_words = 2; /* Always 2 words. */
677 addr = XEXP (addr, 0);
682 n_words = SYMBOL_REF_FLAG (addr) ? 1 : 2;
694 n_words += additional;
698 num_refs[n_words-1] += num;
701 /* Abort after printing out a specific insn. */
704 abort_with_insn (rtx insn, const char * reason)
711 /* Return the appropriate instructions to move one operand to another. */
714 iq2000_move_1word (rtx operands[], rtx insn, int unsignedp)
717 rtx op0 = operands[0];
718 rtx op1 = operands[1];
719 enum rtx_code code0 = GET_CODE (op0);
720 enum rtx_code code1 = GET_CODE (op1);
721 enum machine_mode mode = GET_MODE (op0);
722 int subreg_offset0 = 0;
723 int subreg_offset1 = 0;
724 enum delay_type delay = DELAY_NONE;
726 while (code0 == SUBREG)
728 subreg_offset0 += subreg_regno_offset (REGNO (SUBREG_REG (op0)),
729 GET_MODE (SUBREG_REG (op0)),
732 op0 = SUBREG_REG (op0);
733 code0 = GET_CODE (op0);
736 while (code1 == SUBREG)
738 subreg_offset1 += subreg_regno_offset (REGNO (SUBREG_REG (op1)),
739 GET_MODE (SUBREG_REG (op1)),
742 op1 = SUBREG_REG (op1);
743 code1 = GET_CODE (op1);
746 /* For our purposes, a condition code mode is the same as SImode. */
752 int regno0 = REGNO (op0) + subreg_offset0;
756 int regno1 = REGNO (op1) + subreg_offset1;
758 /* Do not do anything for assigning a register to itself */
759 if (regno0 == regno1)
762 else if (GP_REG_P (regno0))
764 if (GP_REG_P (regno1))
765 ret = "or\t%0,%%0,%1";
770 else if (code1 == MEM)
775 iq2000_count_memory_refs (op1, 1);
777 if (GP_REG_P (regno0))
779 /* For loads, use the mode of the memory item, instead of the
780 target, so zero/sign extend can use this code as well. */
781 switch (GET_MODE (op1))
793 ret = (unsignedp) ? "lhu\t%0,%1" : "lh\t%0,%1";
796 ret = (unsignedp) ? "lbu\t%0,%1" : "lb\t%0,%1";
802 else if (code1 == CONST_INT
803 || (code1 == CONST_DOUBLE
804 && GET_MODE (op1) == VOIDmode))
806 if (code1 == CONST_DOUBLE)
808 /* This can happen when storing constants into long long
809 bitfields. Just store the least significant word of
811 operands[1] = op1 = GEN_INT (CONST_DOUBLE_LOW (op1));
814 if (INTVAL (op1) == 0)
816 if (GP_REG_P (regno0))
817 ret = "or\t%0,%%0,%z1";
819 else if (GP_REG_P (regno0))
821 if (SMALL_INT_UNSIGNED (op1))
822 ret = "ori\t%0,%%0,%x1\t\t\t# %1";
823 else if (SMALL_INT (op1))
824 ret = "addiu\t%0,%%0,%1\t\t\t# %1";
826 ret = "lui\t%0,%X1\t\t\t# %1\n\tori\t%0,%0,%x1";
830 else if (code1 == CONST_DOUBLE && mode == SFmode)
832 if (op1 == CONST0_RTX (SFmode))
834 if (GP_REG_P (regno0))
835 ret = "or\t%0,%%0,%.";
845 else if (code1 == LABEL_REF)
848 iq2000_count_memory_refs (op1, 1);
853 else if (code1 == SYMBOL_REF || code1 == CONST)
856 iq2000_count_memory_refs (op1, 1);
861 else if (code1 == PLUS)
863 rtx add_op0 = XEXP (op1, 0);
864 rtx add_op1 = XEXP (op1, 1);
866 if (GET_CODE (XEXP (op1, 1)) == REG
867 && GET_CODE (XEXP (op1, 0)) == CONST_INT)
868 add_op0 = XEXP (op1, 1), add_op1 = XEXP (op1, 0);
870 operands[2] = add_op0;
871 operands[3] = add_op1;
872 ret = "add%:\t%0,%2,%3";
875 else if (code1 == HIGH)
877 operands[1] = XEXP (op1, 0);
878 ret = "lui\t%0,%%hi(%1)";
882 else if (code0 == MEM)
885 iq2000_count_memory_refs (op0, 1);
889 int regno1 = REGNO (op1) + subreg_offset1;
891 if (GP_REG_P (regno1))
895 case SFmode: ret = "sw\t%1,%0"; break;
896 case SImode: ret = "sw\t%1,%0"; break;
897 case HImode: ret = "sh\t%1,%0"; break;
898 case QImode: ret = "sb\t%1,%0"; break;
904 else if (code1 == CONST_INT && INTVAL (op1) == 0)
908 case SFmode: ret = "sw\t%z1,%0"; break;
909 case SImode: ret = "sw\t%z1,%0"; break;
910 case HImode: ret = "sh\t%z1,%0"; break;
911 case QImode: ret = "sb\t%z1,%0"; break;
916 else if (code1 == CONST_DOUBLE && op1 == CONST0_RTX (mode))
920 case SFmode: ret = "sw\t%.,%0"; break;
921 case SImode: ret = "sw\t%.,%0"; break;
922 case HImode: ret = "sh\t%.,%0"; break;
923 case QImode: ret = "sb\t%.,%0"; break;
931 abort_with_insn (insn, "Bad move");
935 if (delay != DELAY_NONE)
936 return iq2000_fill_delay_slot (ret, delay, operands, insn);
941 /* Provide the costs of an addressing mode that contains ADDR. */
944 iq2000_address_cost (rtx addr)
946 switch (GET_CODE (addr))
956 rtx offset = const0_rtx;
958 addr = eliminate_constant_term (XEXP (addr, 0), & offset);
959 if (GET_CODE (addr) == LABEL_REF)
962 if (GET_CODE (addr) != SYMBOL_REF)
965 if (! SMALL_INT (offset))
972 return SYMBOL_REF_FLAG (addr) ? 1 : 2;
976 rtx plus0 = XEXP (addr, 0);
977 rtx plus1 = XEXP (addr, 1);
979 if (GET_CODE (plus0) != REG && GET_CODE (plus1) == REG)
980 plus0 = XEXP (addr, 1), plus1 = XEXP (addr, 0);
982 if (GET_CODE (plus0) != REG)
985 switch (GET_CODE (plus1))
988 return SMALL_INT (plus1) ? 1 : 2;
995 return iq2000_address_cost (plus1) + 1;
1009 /* Make normal rtx_code into something we can index from an array. */
1011 static enum internal_test
1012 map_test_to_internal_test (enum rtx_code test_code)
1014 enum internal_test test = ITEST_MAX;
1018 case EQ: test = ITEST_EQ; break;
1019 case NE: test = ITEST_NE; break;
1020 case GT: test = ITEST_GT; break;
1021 case GE: test = ITEST_GE; break;
1022 case LT: test = ITEST_LT; break;
1023 case LE: test = ITEST_LE; break;
1024 case GTU: test = ITEST_GTU; break;
1025 case GEU: test = ITEST_GEU; break;
1026 case LTU: test = ITEST_LTU; break;
1027 case LEU: test = ITEST_LEU; break;
1034 /* Generate the code to do a TEST_CODE comparison on two integer values CMP0
1035 and CMP1. P_INVERT is NULL or ptr if branch needs to reverse its test.
1036 The return value RESULT is:
1037 (reg:SI xx) The pseudo register the comparison is in
1038 0 No register, generate a simple branch. */
1041 gen_int_relational (enum rtx_code test_code, rtx result, rtx cmp0, rtx cmp1,
1046 enum rtx_code test_code; /* Code to use in instruction (LT vs. LTU). */
1047 int const_low; /* Low bound of constant we can accept. */
1048 int const_high; /* High bound of constant we can accept. */
1049 int const_add; /* Constant to add (convert LE -> LT). */
1050 int reverse_regs; /* Reverse registers in test. */
1051 int invert_const; /* != 0 if invert value if cmp1 is constant. */
1052 int invert_reg; /* != 0 if invert value if cmp1 is register. */
1053 int unsignedp; /* != 0 for unsigned comparisons. */
1056 static struct cmp_info info[ (int)ITEST_MAX ] =
1058 { XOR, 0, 65535, 0, 0, 0, 0, 0 }, /* EQ */
1059 { XOR, 0, 65535, 0, 0, 1, 1, 0 }, /* NE */
1060 { LT, -32769, 32766, 1, 1, 1, 0, 0 }, /* GT */
1061 { LT, -32768, 32767, 0, 0, 1, 1, 0 }, /* GE */
1062 { LT, -32768, 32767, 0, 0, 0, 0, 0 }, /* LT */
1063 { LT, -32769, 32766, 1, 1, 0, 1, 0 }, /* LE */
1064 { LTU, -32769, 32766, 1, 1, 1, 0, 1 }, /* GTU */
1065 { LTU, -32768, 32767, 0, 0, 1, 1, 1 }, /* GEU */
1066 { LTU, -32768, 32767, 0, 0, 0, 0, 1 }, /* LTU */
1067 { LTU, -32769, 32766, 1, 1, 0, 1, 1 }, /* LEU */
1070 enum internal_test test;
1071 enum machine_mode mode;
1072 struct cmp_info *p_info;
1079 test = map_test_to_internal_test (test_code);
1080 if (test == ITEST_MAX)
1083 p_info = &info[(int) test];
1084 eqne_p = (p_info->test_code == XOR);
1086 mode = GET_MODE (cmp0);
1087 if (mode == VOIDmode)
1088 mode = GET_MODE (cmp1);
1090 /* Eliminate simple branches. */
1091 branch_p = (result == 0);
1094 if (GET_CODE (cmp0) == REG || GET_CODE (cmp0) == SUBREG)
1096 /* Comparisons against zero are simple branches. */
1097 if (GET_CODE (cmp1) == CONST_INT && INTVAL (cmp1) == 0)
1100 /* Test for beq/bne. */
1105 /* Allocate a pseudo to calculate the value in. */
1106 result = gen_reg_rtx (mode);
1109 /* Make sure we can handle any constants given to us. */
1110 if (GET_CODE (cmp0) == CONST_INT)
1111 cmp0 = force_reg (mode, cmp0);
1113 if (GET_CODE (cmp1) == CONST_INT)
1115 HOST_WIDE_INT value = INTVAL (cmp1);
1117 if (value < p_info->const_low
1118 || value > p_info->const_high)
1119 cmp1 = force_reg (mode, cmp1);
1122 /* See if we need to invert the result. */
1123 invert = (GET_CODE (cmp1) == CONST_INT
1124 ? p_info->invert_const : p_info->invert_reg);
1126 if (p_invert != (int *)0)
1132 /* Comparison to constants, may involve adding 1 to change a LT into LE.
1133 Comparison between two registers, may involve switching operands. */
1134 if (GET_CODE (cmp1) == CONST_INT)
1136 if (p_info->const_add != 0)
1138 HOST_WIDE_INT new = INTVAL (cmp1) + p_info->const_add;
1140 /* If modification of cmp1 caused overflow,
1141 we would get the wrong answer if we follow the usual path;
1142 thus, x > 0xffffffffU would turn into x > 0U. */
1143 if ((p_info->unsignedp
1144 ? (unsigned HOST_WIDE_INT) new >
1145 (unsigned HOST_WIDE_INT) INTVAL (cmp1)
1146 : new > INTVAL (cmp1))
1147 != (p_info->const_add > 0))
1149 /* This test is always true, but if INVERT is true then
1150 the result of the test needs to be inverted so 0 should
1151 be returned instead. */
1152 emit_move_insn (result, invert ? const0_rtx : const_true_rtx);
1156 cmp1 = GEN_INT (new);
1160 else if (p_info->reverse_regs)
1167 if (test == ITEST_NE && GET_CODE (cmp1) == CONST_INT && INTVAL (cmp1) == 0)
1171 reg = (invert || eqne_p) ? gen_reg_rtx (mode) : result;
1172 convert_move (reg, gen_rtx_fmt_ee (p_info->test_code, mode, cmp0, cmp1), 0);
1175 if (test == ITEST_NE)
1177 convert_move (result, gen_rtx_GTU (mode, reg, const0_rtx), 0);
1178 if (p_invert != NULL)
1183 else if (test == ITEST_EQ)
1185 reg2 = invert ? gen_reg_rtx (mode) : result;
1186 convert_move (reg2, gen_rtx_LTU (mode, reg, const1_rtx), 0);
1195 convert_move (result, gen_rtx_XOR (mode, reg, one), 0);
1201 /* Emit the common code for doing conditional branches.
1202 operand[0] is the label to jump to.
1203 The comparison operands are saved away by cmp{si,di,sf,df}. */
1206 gen_conditional_branch (rtx operands[], enum rtx_code test_code)
1208 enum cmp_type type = branch_type;
1209 rtx cmp0 = branch_cmp[0];
1210 rtx cmp1 = branch_cmp[1];
1211 enum machine_mode mode;
1220 mode = type == CMP_SI ? SImode : DImode;
1222 reg = gen_int_relational (test_code, NULL_RTX, cmp0, cmp1, &invert);
1230 else if (GET_CODE (cmp1) == CONST_INT && INTVAL (cmp1) != 0)
1231 /* We don't want to build a comparison against a nonzero
1233 cmp1 = force_reg (mode, cmp1);
1239 reg = gen_reg_rtx (CCmode);
1241 /* For cmp0 != cmp1, build cmp0 == cmp1, and test for result == 0. */
1242 emit_insn (gen_rtx_SET (VOIDmode, reg,
1243 gen_rtx_fmt_ee (test_code == NE ? EQ : test_code,
1244 CCmode, cmp0, cmp1)));
1246 test_code = test_code == NE ? EQ : NE;
1254 abort_with_insn (gen_rtx_fmt_ee (test_code, VOIDmode, cmp0, cmp1),
1258 /* Generate the branch. */
1259 label1 = gen_rtx_LABEL_REF (VOIDmode, operands[0]);
1268 emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
1269 gen_rtx_IF_THEN_ELSE (VOIDmode,
1270 gen_rtx_fmt_ee (test_code,
1276 /* Initialize CUM for a function FNTYPE. */
1279 init_cumulative_args (CUMULATIVE_ARGS *cum, tree fntype,
1280 rtx libname ATTRIBUTE_UNUSED)
1282 static CUMULATIVE_ARGS zero_cum;
1286 if (TARGET_DEBUG_D_MODE)
1289 "\ninit_cumulative_args, fntype = 0x%.8lx", (long) fntype);
1292 fputc ('\n', stderr);
1296 tree ret_type = TREE_TYPE (fntype);
1298 fprintf (stderr, ", fntype code = %s, ret code = %s\n",
1299 tree_code_name[(int)TREE_CODE (fntype)],
1300 tree_code_name[(int)TREE_CODE (ret_type)]);
1306 /* Determine if this function has variable arguments. This is
1307 indicated by the last argument being 'void_type_mode' if there
1308 are no variable arguments. The standard IQ2000 calling sequence
1309 passes all arguments in the general purpose registers in this case. */
1311 for (param = fntype ? TYPE_ARG_TYPES (fntype) : 0;
1312 param != 0; param = next_param)
1314 next_param = TREE_CHAIN (param);
1315 if (next_param == 0 && TREE_VALUE (param) != void_type_node)
1316 cum->gp_reg_found = 1;
1320 /* Advance the argument of type TYPE and mode MODE to the next argument
1324 function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode, tree type,
1327 if (TARGET_DEBUG_D_MODE)
1330 "function_adv({gp reg found = %d, arg # = %2d, words = %2d}, %4s, ",
1331 cum->gp_reg_found, cum->arg_number, cum->arg_words,
1332 GET_MODE_NAME (mode));
1333 fprintf (stderr, HOST_PTR_PRINTF, (const PTR) type);
1334 fprintf (stderr, ", %d )\n\n", named);
1344 if (GET_MODE_CLASS (mode) != MODE_COMPLEX_INT
1345 && GET_MODE_CLASS (mode) != MODE_COMPLEX_FLOAT)
1348 cum->gp_reg_found = 1;
1349 cum->arg_words += ((GET_MODE_SIZE (mode) + UNITS_PER_WORD - 1)
1354 cum->gp_reg_found = 1;
1355 cum->arg_words += ((int_size_in_bytes (type) + UNITS_PER_WORD - 1)
1361 if (! cum->gp_reg_found && cum->arg_number <= 2)
1362 cum->fp_code += 1 << ((cum->arg_number - 1) * 2);
1366 cum->arg_words += 2;
1367 if (! cum->gp_reg_found && cum->arg_number <= 2)
1368 cum->fp_code += 2 << ((cum->arg_number - 1) * 2);
1372 cum->gp_reg_found = 1;
1373 cum->arg_words += 2;
1379 cum->gp_reg_found = 1;
1385 /* Return an RTL expression containing the register for the given mode MODE
1386 and type TYPE in CUM, or 0 if the argument is to be passed on the stack. */
1389 function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode, tree type,
1395 unsigned int *arg_words = &cum->arg_words;
1396 int struct_p = (type != 0
1397 && (TREE_CODE (type) == RECORD_TYPE
1398 || TREE_CODE (type) == UNION_TYPE
1399 || TREE_CODE (type) == QUAL_UNION_TYPE));
1401 if (TARGET_DEBUG_D_MODE)
1404 "function_arg( {gp reg found = %d, arg # = %2d, words = %2d}, %4s, ",
1405 cum->gp_reg_found, cum->arg_number, cum->arg_words,
1406 GET_MODE_NAME (mode));
1407 fprintf (stderr, HOST_PTR_PRINTF, (const PTR) type);
1408 fprintf (stderr, ", %d ) = ", named);
1412 cum->last_arg_fp = 0;
1416 regbase = GP_ARG_FIRST;
1420 cum->arg_words += cum->arg_words & 1;
1422 regbase = GP_ARG_FIRST;
1426 if (GET_MODE_CLASS (mode) != MODE_COMPLEX_INT
1427 && GET_MODE_CLASS (mode) != MODE_COMPLEX_FLOAT)
1430 /* Drops through. */
1432 if (type != NULL_TREE && TYPE_ALIGN (type) > (unsigned) BITS_PER_WORD)
1433 cum->arg_words += (cum->arg_words & 1);
1434 regbase = GP_ARG_FIRST;
1441 regbase = GP_ARG_FIRST;
1445 cum->arg_words += (cum->arg_words & 1);
1446 regbase = GP_ARG_FIRST;
1449 if (*arg_words >= (unsigned) MAX_ARGS_IN_REGISTERS)
1451 if (TARGET_DEBUG_D_MODE)
1452 fprintf (stderr, "<stack>%s\n", struct_p ? ", [struct]" : "");
1461 if (! type || TREE_CODE (type) != RECORD_TYPE
1462 || ! named || ! TYPE_SIZE_UNIT (type)
1463 || ! host_integerp (TYPE_SIZE_UNIT (type), 1))
1464 ret = gen_rtx_REG (mode, regbase + *arg_words + bias);
1469 for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field))
1470 if (TREE_CODE (field) == FIELD_DECL
1471 && TREE_CODE (TREE_TYPE (field)) == REAL_TYPE
1472 && TYPE_PRECISION (TREE_TYPE (field)) == BITS_PER_WORD
1473 && host_integerp (bit_position (field), 0)
1474 && int_bit_position (field) % BITS_PER_WORD == 0)
1477 /* If the whole struct fits a DFmode register,
1478 we don't need the PARALLEL. */
1479 if (! field || mode == DFmode)
1480 ret = gen_rtx_REG (mode, regbase + *arg_words + bias);
1483 unsigned int chunks;
1484 HOST_WIDE_INT bitpos;
1488 /* ??? If this is a packed structure, then the last hunk won't
1491 = tree_low_cst (TYPE_SIZE_UNIT (type), 1) / UNITS_PER_WORD;
1492 if (chunks + *arg_words + bias > (unsigned) MAX_ARGS_IN_REGISTERS)
1493 chunks = MAX_ARGS_IN_REGISTERS - *arg_words - bias;
1495 /* Assign_parms checks the mode of ENTRY_PARM, so we must
1496 use the actual mode here. */
1497 ret = gen_rtx_PARALLEL (mode, rtvec_alloc (chunks));
1500 regno = regbase + *arg_words + bias;
1501 field = TYPE_FIELDS (type);
1502 for (i = 0; i < chunks; i++)
1506 for (; field; field = TREE_CHAIN (field))
1507 if (TREE_CODE (field) == FIELD_DECL
1508 && int_bit_position (field) >= bitpos)
1512 && int_bit_position (field) == bitpos
1513 && TREE_CODE (TREE_TYPE (field)) == REAL_TYPE
1514 && TYPE_PRECISION (TREE_TYPE (field)) == BITS_PER_WORD)
1515 reg = gen_rtx_REG (DFmode, regno++);
1517 reg = gen_rtx_REG (word_mode, regno);
1520 = gen_rtx_EXPR_LIST (VOIDmode, reg,
1521 GEN_INT (bitpos / BITS_PER_UNIT));
1529 if (TARGET_DEBUG_D_MODE)
1530 fprintf (stderr, "%s%s\n", reg_names[regbase + *arg_words + bias],
1531 struct_p ? ", [struct]" : "");
1534 /* We will be called with a mode of VOIDmode after the last argument
1535 has been seen. Whatever we return will be passed to the call
1536 insn. If we need any shifts for small structures, return them in
1538 if (mode == VOIDmode)
1540 if (cum->num_adjusts > 0)
1541 ret = gen_rtx_PARALLEL ((enum machine_mode) cum->fp_code,
1542 gen_rtvec_v (cum->num_adjusts, cum->adjust));
1549 function_arg_partial_nregs (CUMULATIVE_ARGS *cum, enum machine_mode mode,
1550 tree type ATTRIBUTE_UNUSED,
1551 int named ATTRIBUTE_UNUSED)
1554 && cum->arg_words == MAX_ARGS_IN_REGISTERS - (unsigned)1)
1556 if (TARGET_DEBUG_D_MODE)
1557 fprintf (stderr, "function_arg_partial_nregs = 1\n");
1565 /* Implement va_start. */
1568 iq2000_va_start (tree valist, rtx nextarg)
1571 /* Find out how many non-float named formals. */
1572 int gpr_save_area_size;
1573 /* Note UNITS_PER_WORD is 4 bytes. */
1574 int_arg_words = current_function_args_info.arg_words;
1576 if (int_arg_words < 8 )
1577 /* Adjust for the prologue's economy measure. */
1578 gpr_save_area_size = (8 - int_arg_words) * UNITS_PER_WORD;
1580 gpr_save_area_size = 0;
1582 /* Everything is in the GPR save area, or in the overflow
1583 area which is contiguous with it. */
1584 nextarg = plus_constant (nextarg, - gpr_save_area_size);
1585 std_expand_builtin_va_start (valist, nextarg);
1588 /* Implement va_arg. */
1591 iq2000_va_arg (tree valist, tree type)
1593 HOST_WIDE_INT size, rsize;
1597 rtx r, lab_over = NULL_RTX, lab_false;
1598 tree f_ovfl, f_gtop, f_ftop, f_goff, f_foff;
1599 tree ovfl, gtop, ftop, goff, foff;
1601 size = int_size_in_bytes (type);
1602 rsize = (size + UNITS_PER_WORD - 1) & -UNITS_PER_WORD;
1604 = function_arg_pass_by_reference (NULL, TYPE_MODE (type), type, 0);
1607 size = POINTER_SIZE / BITS_PER_UNIT;
1608 rsize = UNITS_PER_WORD;
1611 addr_rtx = gen_reg_rtx (Pmode);
1614 /* Case of all args in a merged stack. No need to check bounds,
1615 just advance valist along the stack. */
1619 && TYPE_ALIGN (type) > (unsigned) BITS_PER_WORD)
1621 t = build (PLUS_EXPR, TREE_TYPE (gpr), gpr,
1622 build_int_2 (2*UNITS_PER_WORD - 1, 0));
1623 t = build (BIT_AND_EXPR, TREE_TYPE (t), t,
1624 build_int_2 (-2*UNITS_PER_WORD, -1));
1625 t = build (MODIFY_EXPR, TREE_TYPE (gpr), gpr, t);
1626 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
1629 t = build (POSTINCREMENT_EXPR, TREE_TYPE (gpr), gpr,
1631 r = expand_expr (t, addr_rtx, Pmode, EXPAND_NORMAL);
1633 emit_move_insn (addr_rtx, r);
1635 /* Flush the POSTINCREMENT. */
1640 r = gen_rtx_MEM (Pmode, addr_rtx);
1641 set_mem_alias_set (r, get_varargs_alias_set ());
1642 emit_move_insn (addr_rtx, r);
1646 if (BYTES_BIG_ENDIAN && rsize != size)
1647 addr_rtx = plus_constant (addr_rtx, rsize - size);
1652 /* Not a simple merged stack. Need ptrs and indexes left by va_start. */
1653 f_ovfl = TYPE_FIELDS (va_list_type_node);
1654 f_gtop = TREE_CHAIN (f_ovfl);
1655 f_ftop = TREE_CHAIN (f_gtop);
1656 f_goff = TREE_CHAIN (f_ftop);
1657 f_foff = TREE_CHAIN (f_goff);
1659 ovfl = build (COMPONENT_REF, TREE_TYPE (f_ovfl), valist, f_ovfl, NULL_TREE);
1660 gtop = build (COMPONENT_REF, TREE_TYPE (f_gtop), valist, f_gtop, NULL_TREE);
1661 ftop = build (COMPONENT_REF, TREE_TYPE (f_ftop), valist, f_ftop, NULL_TREE);
1662 goff = build (COMPONENT_REF, TREE_TYPE (f_goff), valist, f_goff, NULL_TREE);
1663 foff = build (COMPONENT_REF, TREE_TYPE (f_foff), valist, f_foff, NULL_TREE);
1665 lab_false = gen_label_rtx ();
1666 lab_over = gen_label_rtx ();
1668 if (TREE_CODE (type) == REAL_TYPE)
1670 /* Emit code to branch if foff == 0. */
1671 r = expand_expr (foff, NULL_RTX, TYPE_MODE (TREE_TYPE (foff)),
1673 emit_cmp_and_jump_insns (r, const0_rtx, EQ,
1674 const1_rtx, GET_MODE (r), 1, lab_false);
1676 /* Emit code for addr_rtx = ftop - foff. */
1677 t = build (MINUS_EXPR, TREE_TYPE (ftop), ftop, foff );
1678 r = expand_expr (t, addr_rtx, Pmode, EXPAND_NORMAL);
1680 emit_move_insn (addr_rtx, r);
1682 /* Emit code for foff-=8.
1683 Advances the offset up FPR save area by one double. */
1684 t = build (MINUS_EXPR, TREE_TYPE (foff), foff, build_int_2 (8, 0));
1685 t = build (MODIFY_EXPR, TREE_TYPE (foff), foff, t);
1686 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
1689 emit_jump (lab_over);
1691 emit_label (lab_false);
1693 /* If a 4-byte int is followed by an 8-byte float, then
1694 natural alignment causes a 4 byte gap.
1695 So, dynamically adjust ovfl up to a multiple of 8. */
1696 t = build (BIT_AND_EXPR, TREE_TYPE (ovfl), ovfl,
1697 build_int_2 (7, 0));
1698 t = build (PLUS_EXPR, TREE_TYPE (ovfl), ovfl, t);
1699 t = build (MODIFY_EXPR, TREE_TYPE (ovfl), ovfl, t);
1700 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
1702 /* Emit code for addr_rtx = the ovfl pointer into overflow area.
1703 Postincrement the ovfl pointer by 8. */
1704 t = build (POSTINCREMENT_EXPR, TREE_TYPE(ovfl), ovfl,
1706 r = expand_expr (t, addr_rtx, Pmode, EXPAND_NORMAL);
1708 emit_move_insn (addr_rtx, r);
1711 emit_label (lab_over);
1716 /* Not REAL_TYPE. */
1719 if (TREE_CODE (type) == INTEGER_TYPE
1720 && TYPE_PRECISION (type) == 64)
1722 /* int takes 32 bits of the GPR save area, but
1723 longlong takes an aligned 64 bits. So, emit code
1724 to zero the low order bits of goff, thus aligning
1725 the later calculation of (gtop-goff) upwards. */
1726 t = build (BIT_AND_EXPR, TREE_TYPE (goff), goff,
1727 build_int_2 (-8, -1));
1728 t = build (MODIFY_EXPR, TREE_TYPE (goff), goff, t);
1729 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
1732 /* Emit code to branch if goff == 0. */
1733 r = expand_expr (goff, NULL_RTX, TYPE_MODE (TREE_TYPE (goff)),
1735 emit_cmp_and_jump_insns (r, const0_rtx, EQ,
1736 const1_rtx, GET_MODE (r), 1, lab_false);
1738 /* Emit code for addr_rtx = gtop - goff. */
1739 t = build (MINUS_EXPR, TREE_TYPE (gtop), gtop, goff);
1740 r = expand_expr (t, addr_rtx, Pmode, EXPAND_NORMAL);
1742 emit_move_insn (addr_rtx, r);
1744 if (TYPE_PRECISION (type) == 64)
1747 step_size = UNITS_PER_WORD;
1749 /* Emit code for goff = goff - step_size.
1750 Advances the offset up GPR save area over the item. */
1751 t = build (MINUS_EXPR, TREE_TYPE (goff), goff,
1752 build_int_2 (step_size, 0));
1753 t = build (MODIFY_EXPR, TREE_TYPE (goff), goff, t);
1754 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
1757 emit_jump (lab_over);
1759 emit_label (lab_false);
1761 /* Emit code for addr_rtx -> overflow area, postinc by step_size. */
1762 t = build (POSTINCREMENT_EXPR, TREE_TYPE(ovfl), ovfl,
1763 size_int (step_size));
1764 r = expand_expr (t, addr_rtx, Pmode, EXPAND_NORMAL);
1766 emit_move_insn (addr_rtx, r);
1769 emit_label (lab_over);
1773 r = gen_rtx_MEM (Pmode, addr_rtx);
1774 set_mem_alias_set (r, get_varargs_alias_set ());
1775 emit_move_insn (addr_rtx, r);
1779 if (BYTES_BIG_ENDIAN && rsize != size)
1780 addr_rtx = plus_constant (addr_rtx, rsize - size);
1786 /* Allocate a chunk of memory for per-function machine-dependent data. */
1788 static struct machine_function *
1789 iq2000_init_machine_status (void)
1791 struct machine_function *f;
1793 f = ggc_alloc_cleared (sizeof (struct machine_function));
1798 static enum processor_type
1799 iq2000_parse_cpu (const char * cpu_string)
1801 const char *p = cpu_string;
1802 enum processor_type cpu;
1804 cpu = PROCESSOR_DEFAULT;
1808 if (!strcmp (p, "iq10"))
1809 cpu = PROCESSOR_IQ10;
1812 if (!strcmp (p, "iq2000"))
1813 cpu = PROCESSOR_IQ2000;
1820 /* Detect any conflicts in the switches. */
1823 override_options (void)
1825 enum processor_type iq2000_cpu;
1827 target_flags &= ~MASK_GPOPT;
1829 iq2000_isa = IQ2000_ISA_DEFAULT;
1831 /* Identify the processor type. */
1833 if (iq2000_cpu_string != 0)
1835 iq2000_cpu = iq2000_parse_cpu (iq2000_cpu_string);
1836 if (iq2000_cpu == PROCESSOR_DEFAULT)
1838 error ("bad value (%s) for -mcpu= switch", iq2000_arch_string);
1839 iq2000_cpu_string = "default";
1841 iq2000_arch = iq2000_cpu;
1842 iq2000_tune = iq2000_cpu;
1845 if (iq2000_arch_string == 0
1846 || ! strcmp (iq2000_arch_string, "default")
1847 || ! strcmp (iq2000_arch_string, "DEFAULT"))
1852 iq2000_arch_string = "iq2000";
1853 iq2000_arch = PROCESSOR_IQ2000;
1859 iq2000_arch = iq2000_parse_cpu (iq2000_arch_string);
1860 if (iq2000_arch == PROCESSOR_DEFAULT)
1862 error ("bad value (%s) for -march= switch", iq2000_arch_string);
1863 iq2000_arch_string = "default";
1865 if (iq2000_arch == PROCESSOR_IQ10)
1867 error ("The compiler does not support -march=%s.", iq2000_arch_string);
1868 iq2000_arch_string = "default";
1872 iq2000_print_operand_punct['?'] = 1;
1873 iq2000_print_operand_punct['#'] = 1;
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;
1892 /* Save GPR registers in word_mode sized hunks. word_mode hasn't been
1893 initialized yet, so we can't use that here. */
1896 /* Function to allocate machine-dependent function status. */
1897 init_machine_status = iq2000_init_machine_status;
1900 /* The arg pointer (which is eliminated) points to the virtual frame pointer,
1901 while the frame pointer (which may be eliminated) points to the stack
1902 pointer after the initial adjustments. */
1905 iq2000_debugger_offset (rtx addr, HOST_WIDE_INT offset)
1907 rtx offset2 = const0_rtx;
1908 rtx reg = eliminate_constant_term (addr, & offset2);
1911 offset = INTVAL (offset2);
1913 if (reg == stack_pointer_rtx || reg == frame_pointer_rtx
1914 || reg == hard_frame_pointer_rtx)
1916 HOST_WIDE_INT frame_size = (!cfun->machine->initialized)
1917 ? compute_frame_size (get_frame_size ())
1918 : cfun->machine->total_size;
1920 offset = offset - frame_size;
1926 /* If defined, a C statement to be executed just prior to the output of
1927 assembler code for INSN, to modify the extracted operands so they will be
1930 Here the argument OPVEC is the vector containing the operands extracted
1931 from INSN, and NOPERANDS is the number of elements of the vector which
1932 contain meaningful data for this insn. The contents of this vector are
1933 what will be used to convert the insn template into assembler code, so you
1934 can change the assembler output by changing the contents of the vector.
1936 We use it to check if the current insn needs a nop in front of it because
1937 of load delays, and also to update the delay slot statistics. */
1940 final_prescan_insn (rtx insn, rtx opvec[] ATTRIBUTE_UNUSED,
1941 int noperands ATTRIBUTE_UNUSED)
1943 if (dslots_number_nops > 0)
1945 rtx pattern = PATTERN (insn);
1946 int length = get_attr_length (insn);
1948 /* Do we need to emit a NOP? */
1950 || (iq2000_load_reg != 0 && reg_mentioned_p (iq2000_load_reg, pattern))
1951 || (iq2000_load_reg2 != 0 && reg_mentioned_p (iq2000_load_reg2, pattern))
1952 || (iq2000_load_reg3 != 0 && reg_mentioned_p (iq2000_load_reg3, pattern))
1953 || (iq2000_load_reg4 != 0
1954 && reg_mentioned_p (iq2000_load_reg4, pattern)))
1955 fputs ("\tnop\n", asm_out_file);
1958 dslots_load_filled ++;
1960 while (--dslots_number_nops > 0)
1961 fputs ("\tnop\n", asm_out_file);
1963 iq2000_load_reg = 0;
1964 iq2000_load_reg2 = 0;
1965 iq2000_load_reg3 = 0;
1966 iq2000_load_reg4 = 0;
1969 if ( (GET_CODE (insn) == JUMP_INSN
1970 || GET_CODE (insn) == CALL_INSN
1971 || (GET_CODE (PATTERN (insn)) == RETURN))
1972 && NEXT_INSN (PREV_INSN (insn)) == insn)
1974 rtx nop_insn = emit_insn_after (gen_nop (), insn);
1976 INSN_ADDRESSES_NEW (nop_insn, -1);
1980 && (GET_CODE (insn) == JUMP_INSN || GET_CODE (insn) == CALL_INSN))
1981 dslots_jump_total ++;
1984 /* Return the bytes needed to compute the frame pointer from the current
1985 stack pointer where SIZE is the # of var. bytes allocated.
1987 IQ2000 stack frames look like:
1989 Before call After call
1990 +-----------------------+ +-----------------------+
1993 | caller's temps. | | caller's temps. |
1995 +-----------------------+ +-----------------------+
1997 | arguments on stack. | | arguments on stack. |
1999 +-----------------------+ +-----------------------+
2000 | 4 words to save | | 4 words to save |
2001 | arguments passed | | arguments passed |
2002 | in registers, even | | in registers, even |
2003 SP->| if not passed. | VFP->| if not passed. |
2004 +-----------------------+ +-----------------------+
2006 | fp register save |
2008 +-----------------------+
2010 | gp register save |
2012 +-----------------------+
2016 +-----------------------+
2018 | alloca allocations |
2020 +-----------------------+
2022 | GP save for V.4 abi |
2024 +-----------------------+
2026 | arguments on stack |
2028 +-----------------------+
2030 | arguments passed |
2031 | in registers, even |
2032 low SP->| if not passed. |
2033 memory +-----------------------+ */
2036 compute_frame_size (HOST_WIDE_INT size)
2039 HOST_WIDE_INT total_size; /* # bytes that the entire frame takes up. */
2040 HOST_WIDE_INT var_size; /* # bytes that variables take up. */
2041 HOST_WIDE_INT args_size; /* # bytes that outgoing arguments take up. */
2042 HOST_WIDE_INT extra_size; /* # extra bytes. */
2043 HOST_WIDE_INT gp_reg_rounded; /* # bytes needed to store gp after rounding. */
2044 HOST_WIDE_INT gp_reg_size; /* # bytes needed to store gp regs. */
2045 HOST_WIDE_INT fp_reg_size; /* # bytes needed to store fp regs. */
2046 long mask; /* mask of saved gp registers. */
2047 int fp_inc; /* 1 or 2 depending on the size of fp regs. */
2048 long fp_bits; /* bitmask to use for each fp register. */
2053 extra_size = IQ2000_STACK_ALIGN ((0));
2054 var_size = IQ2000_STACK_ALIGN (size);
2055 args_size = IQ2000_STACK_ALIGN (current_function_outgoing_args_size);
2057 /* If a function dynamically allocates the stack and
2058 has 0 for STACK_DYNAMIC_OFFSET then allocate some stack space. */
2059 if (args_size == 0 && current_function_calls_alloca)
2060 args_size = 4 * UNITS_PER_WORD;
2062 total_size = var_size + args_size + extra_size;
2064 /* Calculate space needed for gp registers. */
2065 for (regno = GP_REG_FIRST; regno <= GP_REG_LAST; regno++)
2067 if (MUST_SAVE_REGISTER (regno))
2069 gp_reg_size += GET_MODE_SIZE (gpr_mode);
2070 mask |= 1L << (regno - GP_REG_FIRST);
2074 /* We need to restore these for the handler. */
2075 if (current_function_calls_eh_return)
2081 regno = EH_RETURN_DATA_REGNO (i);
2082 if (regno == (int) INVALID_REGNUM)
2084 gp_reg_size += GET_MODE_SIZE (gpr_mode);
2085 mask |= 1L << (regno - GP_REG_FIRST);
2091 gp_reg_rounded = IQ2000_STACK_ALIGN (gp_reg_size);
2092 total_size += gp_reg_rounded + IQ2000_STACK_ALIGN (fp_reg_size);
2094 /* The gp reg is caller saved, so there is no need for leaf routines
2095 (total_size == extra_size) to save the gp reg. */
2096 if (total_size == extra_size
2098 total_size = extra_size = 0;
2100 total_size += IQ2000_STACK_ALIGN (current_function_pretend_args_size);
2102 /* Save other computed information. */
2103 cfun->machine->total_size = total_size;
2104 cfun->machine->var_size = var_size;
2105 cfun->machine->args_size = args_size;
2106 cfun->machine->extra_size = extra_size;
2107 cfun->machine->gp_reg_size = gp_reg_size;
2108 cfun->machine->fp_reg_size = fp_reg_size;
2109 cfun->machine->mask = mask;
2110 cfun->machine->initialized = reload_completed;
2111 cfun->machine->num_gp = gp_reg_size / UNITS_PER_WORD;
2115 unsigned long offset;
2117 offset = (args_size + extra_size + var_size
2118 + gp_reg_size - GET_MODE_SIZE (gpr_mode));
2120 cfun->machine->gp_sp_offset = offset;
2121 cfun->machine->gp_save_offset = offset - total_size;
2125 cfun->machine->gp_sp_offset = 0;
2126 cfun->machine->gp_save_offset = 0;
2129 cfun->machine->fp_sp_offset = 0;
2130 cfun->machine->fp_save_offset = 0;
2132 /* Ok, we're done. */
2136 /* Implement INITIAL_ELIMINATION_OFFSET. FROM is either the frame
2137 pointer, argument pointer, or return address pointer. TO is either
2138 the stack pointer or hard frame pointer. */
2141 iq2000_initial_elimination_offset (int from, int to ATTRIBUTE_UNUSED)
2145 compute_frame_size (get_frame_size ());
2146 if ((from) == FRAME_POINTER_REGNUM)
2148 else if ((from) == ARG_POINTER_REGNUM)
2149 (offset) = (cfun->machine->total_size);
2150 else if ((from) == RETURN_ADDRESS_POINTER_REGNUM)
2152 if (leaf_function_p ())
2154 else (offset) = cfun->machine->gp_sp_offset
2155 + ((UNITS_PER_WORD - (POINTER_SIZE / BITS_PER_UNIT))
2156 * (BYTES_BIG_ENDIAN != 0));
2162 /* Common code to emit the insns (or to write the instructions to a file)
2163 to save/restore registers.
2164 Other parts of the code assume that IQ2000_TEMP1_REGNUM (aka large_reg)
2165 is not modified within save_restore_insns. */
2167 #define BITSET_P(VALUE,BIT) (((VALUE) & (1L << (BIT))) != 0)
2169 /* Emit instructions to load the value (SP + OFFSET) into IQ2000_TEMP2_REGNUM
2170 and return an rtl expression for the register. Write the assembly
2171 instructions directly to FILE if it is not null, otherwise emit them as
2174 This function is a subroutine of save_restore_insns. It is used when
2175 OFFSET is too large to add in a single instruction. */
2178 iq2000_add_large_offset_to_sp (HOST_WIDE_INT offset)
2180 rtx reg = gen_rtx_REG (Pmode, IQ2000_TEMP2_REGNUM);
2181 rtx offset_rtx = GEN_INT (offset);
2183 emit_move_insn (reg, offset_rtx);
2184 emit_insn (gen_addsi3 (reg, reg, stack_pointer_rtx));
2188 /* Make INSN frame related and note that it performs the frame-related
2189 operation DWARF_PATTERN. */
2192 iq2000_annotate_frame_insn (rtx insn, rtx dwarf_pattern)
2194 RTX_FRAME_RELATED_P (insn) = 1;
2195 REG_NOTES (insn) = alloc_EXPR_LIST (REG_FRAME_RELATED_EXPR,
2200 /* Emit a move instruction that stores REG in MEM. Make the instruction
2201 frame related and note that it stores REG at (SP + OFFSET). */
2204 iq2000_emit_frame_related_store (rtx mem, rtx reg, HOST_WIDE_INT offset)
2206 rtx dwarf_address = plus_constant (stack_pointer_rtx, offset);
2207 rtx dwarf_mem = gen_rtx_MEM (GET_MODE (reg), dwarf_address);
2209 iq2000_annotate_frame_insn (emit_move_insn (mem, reg),
2210 gen_rtx_SET (GET_MODE (reg), dwarf_mem, reg));
2213 /* Emit instructions to save/restore registers, as determined by STORE_P. */
2216 save_restore_insns (int store_p)
2218 long mask = cfun->machine->mask;
2221 HOST_WIDE_INT base_offset;
2222 HOST_WIDE_INT gp_offset;
2223 HOST_WIDE_INT end_offset;
2225 if (frame_pointer_needed
2226 && ! BITSET_P (mask, HARD_FRAME_POINTER_REGNUM - GP_REG_FIRST))
2231 base_reg_rtx = 0, base_offset = 0;
2235 /* Save registers starting from high to low. The debuggers prefer at least
2236 the return register be stored at func+4, and also it allows us not to
2237 need a nop in the epilog if at least one register is reloaded in
2238 addition to return address. */
2240 /* Save GP registers if needed. */
2241 /* Pick which pointer to use as a base register. For small frames, just
2242 use the stack pointer. Otherwise, use a temporary register. Save 2
2243 cycles if the save area is near the end of a large frame, by reusing
2244 the constant created in the prologue/epilogue to adjust the stack
2247 gp_offset = cfun->machine->gp_sp_offset;
2249 = gp_offset - (cfun->machine->gp_reg_size
2250 - GET_MODE_SIZE (gpr_mode));
2252 if (gp_offset < 0 || end_offset < 0)
2254 ("gp_offset (%ld) or end_offset (%ld) is less than zero.",
2255 (long) gp_offset, (long) end_offset);
2257 else if (gp_offset < 32768)
2258 base_reg_rtx = stack_pointer_rtx, base_offset = 0;
2262 int reg_save_count = 0;
2264 for (regno = GP_REG_LAST; regno >= GP_REG_FIRST; regno--)
2265 if (BITSET_P (mask, regno - GP_REG_FIRST)) reg_save_count += 1;
2266 base_offset = gp_offset - ((reg_save_count - 1) * 4);
2267 base_reg_rtx = iq2000_add_large_offset_to_sp (base_offset);
2270 for (regno = GP_REG_LAST; regno >= GP_REG_FIRST; regno--)
2272 if (BITSET_P (mask, regno - GP_REG_FIRST))
2276 = gen_rtx_MEM (gpr_mode,
2277 gen_rtx_PLUS (Pmode, base_reg_rtx,
2278 GEN_INT (gp_offset - base_offset)));
2280 if (! current_function_calls_eh_return)
2281 RTX_UNCHANGING_P (mem_rtx) = 1;
2283 reg_rtx = gen_rtx_REG (gpr_mode, regno);
2286 iq2000_emit_frame_related_store (mem_rtx, reg_rtx, gp_offset);
2289 emit_move_insn (reg_rtx, mem_rtx);
2291 gp_offset -= GET_MODE_SIZE (gpr_mode);
2296 /* Expand the prologue into a bunch of separate insns. */
2299 iq2000_expand_prologue (void)
2302 HOST_WIDE_INT tsize;
2303 int last_arg_is_vararg_marker = 0;
2304 tree fndecl = current_function_decl;
2305 tree fntype = TREE_TYPE (fndecl);
2306 tree fnargs = DECL_ARGUMENTS (fndecl);
2311 CUMULATIVE_ARGS args_so_far;
2312 int store_args_on_stack = (iq2000_can_use_return_insn ());
2314 /* If struct value address is treated as the first argument. */
2315 if (aggregate_value_p (DECL_RESULT (fndecl), fndecl)
2316 && ! current_function_returns_pcc_struct
2317 && targetm.calls.struct_value_rtx (TREE_TYPE (fndecl), 1) == 0)
2319 tree type = build_pointer_type (fntype);
2320 tree function_result_decl = build_decl (PARM_DECL, NULL_TREE, type);
2322 DECL_ARG_TYPE (function_result_decl) = type;
2323 TREE_CHAIN (function_result_decl) = fnargs;
2324 fnargs = function_result_decl;
2327 /* For arguments passed in registers, find the register number
2328 of the first argument in the variable part of the argument list,
2329 otherwise GP_ARG_LAST+1. Note also if the last argument is
2330 the varargs special argument, and treat it as part of the
2333 This is only needed if store_args_on_stack is true. */
2334 INIT_CUMULATIVE_ARGS (args_so_far, fntype, NULL_RTX, 0, 0);
2335 regno = GP_ARG_FIRST;
2337 for (cur_arg = fnargs; cur_arg != 0; cur_arg = next_arg)
2339 tree passed_type = DECL_ARG_TYPE (cur_arg);
2340 enum machine_mode passed_mode = TYPE_MODE (passed_type);
2343 if (TREE_ADDRESSABLE (passed_type))
2345 passed_type = build_pointer_type (passed_type);
2346 passed_mode = Pmode;
2349 entry_parm = FUNCTION_ARG (args_so_far, passed_mode, passed_type, 1);
2351 FUNCTION_ARG_ADVANCE (args_so_far, passed_mode, passed_type, 1);
2352 next_arg = TREE_CHAIN (cur_arg);
2354 if (entry_parm && store_args_on_stack)
2357 && DECL_NAME (cur_arg)
2358 && ((0 == strcmp (IDENTIFIER_POINTER (DECL_NAME (cur_arg)),
2359 "__builtin_va_alist"))
2360 || (0 == strcmp (IDENTIFIER_POINTER (DECL_NAME (cur_arg)),
2363 last_arg_is_vararg_marker = 1;
2370 if (GET_CODE (entry_parm) != REG)
2373 /* Passed in a register, so will get homed automatically. */
2374 if (GET_MODE (entry_parm) == BLKmode)
2375 words = (int_size_in_bytes (passed_type) + 3) / 4;
2377 words = (GET_MODE_SIZE (GET_MODE (entry_parm)) + 3) / 4;
2379 regno = REGNO (entry_parm) + words - 1;
2384 regno = GP_ARG_LAST+1;
2389 /* In order to pass small structures by value in registers we need to
2390 shift the value into the high part of the register.
2391 Function_arg has encoded a PARALLEL rtx, holding a vector of
2392 adjustments to be made as the next_arg_reg variable, so we split up the
2393 insns, and emit them separately. */
2394 next_arg_reg = FUNCTION_ARG (args_so_far, VOIDmode, void_type_node, 1);
2395 if (next_arg_reg != 0 && GET_CODE (next_arg_reg) == PARALLEL)
2397 rtvec adjust = XVEC (next_arg_reg, 0);
2398 int num = GET_NUM_ELEM (adjust);
2400 for (i = 0; i < num; i++)
2404 pattern = RTVEC_ELT (adjust, i);
2405 if (GET_CODE (pattern) != SET
2406 || GET_CODE (SET_SRC (pattern)) != ASHIFT)
2407 abort_with_insn (pattern, "Insn is not a shift");
2408 PUT_CODE (SET_SRC (pattern), ASHIFTRT);
2410 insn = emit_insn (pattern);
2412 /* Global life information isn't valid at this point, so we
2413 can't check whether these shifts are actually used. Mark
2414 them MAYBE_DEAD so that flow2 will remove them, and not
2415 complain about dead code in the prologue. */
2416 REG_NOTES(insn) = gen_rtx_EXPR_LIST (REG_MAYBE_DEAD, NULL_RTX,
2421 tsize = compute_frame_size (get_frame_size ());
2423 /* If this function is a varargs function, store any registers that
2424 would normally hold arguments ($4 - $7) on the stack. */
2425 if (store_args_on_stack
2426 && ((TYPE_ARG_TYPES (fntype) != 0
2427 && (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
2429 || last_arg_is_vararg_marker))
2431 int offset = (regno - GP_ARG_FIRST) * UNITS_PER_WORD;
2432 rtx ptr = stack_pointer_rtx;
2434 for (; regno <= GP_ARG_LAST; regno++)
2437 ptr = gen_rtx_PLUS (Pmode, stack_pointer_rtx, GEN_INT (offset));
2438 emit_move_insn (gen_rtx_MEM (gpr_mode, ptr),
2439 gen_rtx_REG (gpr_mode, regno));
2441 offset += GET_MODE_SIZE (gpr_mode);
2447 rtx tsize_rtx = GEN_INT (tsize);
2448 rtx adjustment_rtx, insn, dwarf_pattern;
2452 adjustment_rtx = gen_rtx_REG (Pmode, IQ2000_TEMP1_REGNUM);
2453 emit_move_insn (adjustment_rtx, tsize_rtx);
2456 adjustment_rtx = tsize_rtx;
2458 insn = emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
2461 dwarf_pattern = gen_rtx_SET (Pmode, stack_pointer_rtx,
2462 plus_constant (stack_pointer_rtx, -tsize));
2464 iq2000_annotate_frame_insn (insn, dwarf_pattern);
2466 save_restore_insns (1);
2468 if (frame_pointer_needed)
2472 insn = emit_insn (gen_movsi (hard_frame_pointer_rtx,
2473 stack_pointer_rtx));
2476 RTX_FRAME_RELATED_P (insn) = 1;
2480 emit_insn (gen_blockage ());
2483 /* Expand the epilogue into a bunch of separate insns. */
2486 iq2000_expand_epilogue (void)
2488 HOST_WIDE_INT tsize = cfun->machine->total_size;
2489 rtx tsize_rtx = GEN_INT (tsize);
2490 rtx tmp_rtx = (rtx)0;
2492 if (iq2000_can_use_return_insn ())
2494 emit_insn (gen_return ());
2500 tmp_rtx = gen_rtx_REG (Pmode, IQ2000_TEMP1_REGNUM);
2501 emit_move_insn (tmp_rtx, tsize_rtx);
2502 tsize_rtx = tmp_rtx;
2507 if (frame_pointer_needed)
2509 emit_insn (gen_blockage ());
2511 emit_insn (gen_movsi (stack_pointer_rtx, hard_frame_pointer_rtx));
2514 save_restore_insns (0);
2516 if (current_function_calls_eh_return)
2518 rtx eh_ofs = EH_RETURN_STACKADJ_RTX;
2519 emit_insn (gen_addsi3 (eh_ofs, eh_ofs, tsize_rtx));
2523 emit_insn (gen_blockage ());
2525 if (tsize != 0 || current_function_calls_eh_return)
2527 emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx,
2532 if (current_function_calls_eh_return)
2534 /* Perform the additional bump for __throw. */
2535 emit_move_insn (gen_rtx_REG (Pmode, HARD_FRAME_POINTER_REGNUM),
2537 emit_insn (gen_rtx_USE (VOIDmode, gen_rtx_REG (Pmode,
2538 HARD_FRAME_POINTER_REGNUM)));
2539 emit_jump_insn (gen_eh_return_internal ());
2542 emit_jump_insn (gen_return_internal (gen_rtx_REG (Pmode,
2543 GP_REG_FIRST + 31)));
2547 iq2000_expand_eh_return (rtx address)
2549 HOST_WIDE_INT gp_offset = cfun->machine->gp_sp_offset;
2552 scratch = plus_constant (stack_pointer_rtx, gp_offset);
2553 emit_move_insn (gen_rtx_MEM (GET_MODE (address), scratch), address);
2556 /* Return nonzero if this function is known to have a null epilogue.
2557 This allows the optimizer to omit jumps to jumps if no stack
2561 iq2000_can_use_return_insn (void)
2563 if (! reload_completed)
2566 if (regs_ever_live[31] || profile_flag)
2569 if (cfun->machine->initialized)
2570 return cfun->machine->total_size == 0;
2572 return compute_frame_size (get_frame_size ()) == 0;
2575 /* Returns nonzero if X contains a SYMBOL_REF. */
2578 symbolic_expression_p (rtx x)
2580 if (GET_CODE (x) == SYMBOL_REF)
2583 if (GET_CODE (x) == CONST)
2584 return symbolic_expression_p (XEXP (x, 0));
2587 return symbolic_expression_p (XEXP (x, 0));
2589 if (ARITHMETIC_P (x))
2590 return (symbolic_expression_p (XEXP (x, 0))
2591 || symbolic_expression_p (XEXP (x, 1)));
2596 /* Choose the section to use for the constant rtx expression X that has
2600 iq2000_select_rtx_section (enum machine_mode mode, rtx x ATTRIBUTE_UNUSED,
2601 unsigned HOST_WIDE_INT align)
2603 /* For embedded applications, always put constants in read-only data,
2604 in order to reduce RAM usage. */
2605 /* For embedded applications, always put constants in read-only data,
2606 in order to reduce RAM usage. */
2607 mergeable_constant_section (mode, align, 0);
2610 /* Choose the section to use for DECL. RELOC is true if its value contains
2611 any relocatable expression.
2613 Some of the logic used here needs to be replicated in
2614 ENCODE_SECTION_INFO in iq2000.h so that references to these symbols
2615 are done correctly. */
2618 iq2000_select_section (tree decl, int reloc ATTRIBUTE_UNUSED,
2619 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED)
2621 if (TARGET_EMBEDDED_DATA)
2623 /* For embedded applications, always put an object in read-only data
2624 if possible, in order to reduce RAM usage. */
2625 if ((TREE_CODE (decl) == VAR_DECL
2626 && TREE_READONLY (decl) && !TREE_SIDE_EFFECTS (decl)
2627 && DECL_INITIAL (decl)
2628 && (DECL_INITIAL (decl) == error_mark_node
2629 || TREE_CONSTANT (DECL_INITIAL (decl))))
2630 /* Deal with calls from output_constant_def_contents. */
2631 || TREE_CODE (decl) != VAR_DECL)
2632 readonly_data_section ();
2638 /* For hosted applications, always put an object in small data if
2639 possible, as this gives the best performance. */
2640 if ((TREE_CODE (decl) == VAR_DECL
2641 && TREE_READONLY (decl) && !TREE_SIDE_EFFECTS (decl)
2642 && DECL_INITIAL (decl)
2643 && (DECL_INITIAL (decl) == error_mark_node
2644 || TREE_CONSTANT (DECL_INITIAL (decl))))
2645 /* Deal with calls from output_constant_def_contents. */
2646 || TREE_CODE (decl) != VAR_DECL)
2647 readonly_data_section ();
2652 /* Return register to use for a function return value with VALTYPE for function
2656 iq2000_function_value (tree valtype, tree func ATTRIBUTE_UNUSED)
2658 int reg = GP_RETURN;
2659 enum machine_mode mode = TYPE_MODE (valtype);
2660 int unsignedp = TYPE_UNSIGNED (valtype);
2662 /* Since we define TARGET_PROMOTE_FUNCTION_RETURN that returns true,
2663 we must promote the mode just as PROMOTE_MODE does. */
2664 mode = promote_mode (valtype, mode, &unsignedp, 1);
2666 return gen_rtx_REG (mode, reg);
2669 /* The implementation of FUNCTION_ARG_PASS_BY_REFERENCE. Return
2670 nonzero when an argument must be passed by reference. */
2673 function_arg_pass_by_reference (CUMULATIVE_ARGS *cum ATTRIBUTE_UNUSED,
2674 enum machine_mode mode, tree type,
2675 int named ATTRIBUTE_UNUSED)
2679 /* We must pass by reference if we would be both passing in registers
2680 and the stack. This is because any subsequent partial arg would be
2681 handled incorrectly in this case. */
2682 if (cum && MUST_PASS_IN_STACK (mode, type))
2684 /* Don't pass the actual CUM to FUNCTION_ARG, because we would
2685 get double copies of any offsets generated for small structs
2686 passed in registers. */
2687 CUMULATIVE_ARGS temp;
2690 if (FUNCTION_ARG (temp, mode, type, named) != 0)
2694 if (type == NULL_TREE || mode == DImode || mode == DFmode)
2697 size = int_size_in_bytes (type);
2698 return size == -1 || size > UNITS_PER_WORD;
2701 /* Return the length of INSN. LENGTH is the initial length computed by
2702 attributes in the machine-description file. */
2705 iq2000_adjust_insn_length (rtx insn, int length)
2707 /* A unconditional jump has an unfilled delay slot if it is not part
2708 of a sequence. A conditional jump normally has a delay slot. */
2709 if (simplejump_p (insn)
2710 || ( (GET_CODE (insn) == JUMP_INSN
2711 || GET_CODE (insn) == CALL_INSN)))
2717 /* Output assembly instructions to perform a conditional branch.
2719 INSN is the branch instruction. OPERANDS[0] is the condition.
2720 OPERANDS[1] is the target of the branch. OPERANDS[2] is the target
2721 of the first operand to the condition. If TWO_OPERANDS_P is
2722 nonzero the comparison takes two operands; OPERANDS[3] will be the
2725 If INVERTED_P is nonzero we are to branch if the condition does
2726 not hold. If FLOAT_P is nonzero this is a floating-point comparison.
2728 LENGTH is the length (in bytes) of the sequence we are to generate.
2729 That tells us whether to generate a simple conditional branch, or a
2730 reversed conditional branch around a `jr' instruction. */
2733 iq2000_output_conditional_branch (rtx insn, rtx * operands, int two_operands_p,
2734 int float_p, int inverted_p, int length)
2736 static char buffer[200];
2737 /* The kind of comparison we are doing. */
2738 enum rtx_code code = GET_CODE (operands[0]);
2739 /* Nonzero if the opcode for the comparison needs a `z' indicating
2740 that it is a comparison against zero. */
2742 /* A string to use in the assembly output to represent the first
2744 const char *op1 = "%z2";
2745 /* A string to use in the assembly output to represent the second
2746 operand. Use the hard-wired zero register if there's no second
2748 const char *op2 = (two_operands_p ? ",%z3" : ",%.");
2749 /* The operand-printing string for the comparison. */
2750 const char *comp = (float_p ? "%F0" : "%C0");
2751 /* The operand-printing string for the inverted comparison. */
2752 const char *inverted_comp = (float_p ? "%W0" : "%N0");
2754 /* Likely variants of each branch instruction annul the instruction
2755 in the delay slot if the branch is not taken. */
2756 iq2000_branch_likely = (final_sequence && INSN_ANNULLED_BRANCH_P (insn));
2758 if (!two_operands_p)
2760 /* To compute whether than A > B, for example, we normally
2761 subtract B from A and then look at the sign bit. But, if we
2762 are doing an unsigned comparison, and B is zero, we don't
2763 have to do the subtraction. Instead, we can just check to
2764 see if A is nonzero. Thus, we change the CODE here to
2765 reflect the simpler comparison operation. */
2777 /* A condition which will always be true. */
2783 /* A condition which will always be false. */
2789 /* Not a special case. */
2794 /* Relative comparisons are always done against zero. But
2795 equality comparisons are done between two operands, and therefore
2796 do not require a `z' in the assembly language output. */
2797 need_z_p = (!float_p && code != EQ && code != NE);
2798 /* For comparisons against zero, the zero is not provided
2803 /* Begin by terminating the buffer. That way we can always use
2804 strcat to add to it. */
2811 /* Just a simple conditional branch. */
2813 sprintf (buffer, "b%s%%?\t%%Z2%%1",
2814 inverted_p ? inverted_comp : comp);
2816 sprintf (buffer, "b%s%s%%?\t%s%s,%%1",
2817 inverted_p ? inverted_comp : comp,
2818 need_z_p ? "z" : "",
2826 /* Generate a reversed conditional branch around ` j'
2838 Because we have to jump four bytes *past* the following
2839 instruction if this branch was annulled, we can't just use
2840 a label, as in the picture above; there's no way to put the
2841 label after the next instruction, as the assembler does not
2842 accept `.L+4' as the target of a branch. (We can't just
2843 wait until the next instruction is output; it might be a
2844 macro and take up more than four bytes. Once again, we see
2845 why we want to eliminate macros.)
2847 If the branch is annulled, we jump four more bytes that we
2848 would otherwise; that way we skip the annulled instruction
2849 in the delay slot. */
2852 = ((iq2000_branch_likely || length == 16) ? ".+16" : ".+12");
2855 c = strchr (buffer, '\0');
2856 /* Generate the reversed comparison. This takes four
2859 sprintf (c, "b%s\t%%Z2%s",
2860 inverted_p ? comp : inverted_comp,
2863 sprintf (c, "b%s%s\t%s%s,%s",
2864 inverted_p ? comp : inverted_comp,
2865 need_z_p ? "z" : "",
2869 strcat (c, "\n\tnop\n\tj\t%1");
2871 /* The delay slot was unfilled. Since we're inside
2872 .noreorder, the assembler will not fill in the NOP for
2873 us, so we must do it ourselves. */
2874 strcat (buffer, "\n\tnop");
2886 #define def_builtin(NAME, TYPE, CODE) \
2887 builtin_function ((NAME), (TYPE), (CODE), BUILT_IN_MD, NULL, NULL_TREE)
2890 iq2000_init_builtins (void)
2892 tree endlink = void_list_node;
2893 tree void_ftype, void_ftype_int, void_ftype_int_int;
2894 tree void_ftype_int_int_int;
2895 tree int_ftype_int, int_ftype_int_int, int_ftype_int_int_int;
2896 tree int_ftype_int_int_int_int;
2900 = build_function_type (void_type_node,
2901 tree_cons (NULL_TREE, void_type_node, endlink));
2905 = build_function_type (void_type_node,
2906 tree_cons (NULL_TREE, integer_type_node, endlink));
2908 /* void func (int, int) */
2910 = build_function_type (void_type_node,
2911 tree_cons (NULL_TREE, integer_type_node,
2912 tree_cons (NULL_TREE, integer_type_node,
2915 /* int func (int) */
2917 = build_function_type (integer_type_node,
2918 tree_cons (NULL_TREE, integer_type_node, endlink));
2920 /* int func (int, int) */
2922 = build_function_type (integer_type_node,
2923 tree_cons (NULL_TREE, integer_type_node,
2924 tree_cons (NULL_TREE, integer_type_node,
2927 /* void func (int, int, int) */
2928 void_ftype_int_int_int
2929 = build_function_type
2931 tree_cons (NULL_TREE, integer_type_node,
2932 tree_cons (NULL_TREE, integer_type_node,
2933 tree_cons (NULL_TREE,
2937 /* int func (int, int, int, int) */
2938 int_ftype_int_int_int_int
2939 = build_function_type
2941 tree_cons (NULL_TREE, integer_type_node,
2942 tree_cons (NULL_TREE, integer_type_node,
2943 tree_cons (NULL_TREE,
2945 tree_cons (NULL_TREE,
2949 /* int func (int, int, int) */
2950 int_ftype_int_int_int
2951 = build_function_type
2953 tree_cons (NULL_TREE, integer_type_node,
2954 tree_cons (NULL_TREE, integer_type_node,
2955 tree_cons (NULL_TREE,
2959 /* int func (int, int, int, int) */
2960 int_ftype_int_int_int_int
2961 = build_function_type
2963 tree_cons (NULL_TREE, integer_type_node,
2964 tree_cons (NULL_TREE, integer_type_node,
2965 tree_cons (NULL_TREE,
2967 tree_cons (NULL_TREE,
2971 def_builtin ("__builtin_ado16", int_ftype_int_int, IQ2000_BUILTIN_ADO16);
2972 def_builtin ("__builtin_ram", int_ftype_int_int_int_int, IQ2000_BUILTIN_RAM);
2973 def_builtin ("__builtin_chkhdr", void_ftype_int_int, IQ2000_BUILTIN_CHKHDR);
2974 def_builtin ("__builtin_pkrl", void_ftype_int_int, IQ2000_BUILTIN_PKRL);
2975 def_builtin ("__builtin_cfc0", int_ftype_int, IQ2000_BUILTIN_CFC0);
2976 def_builtin ("__builtin_cfc1", int_ftype_int, IQ2000_BUILTIN_CFC1);
2977 def_builtin ("__builtin_cfc2", int_ftype_int, IQ2000_BUILTIN_CFC2);
2978 def_builtin ("__builtin_cfc3", int_ftype_int, IQ2000_BUILTIN_CFC3);
2979 def_builtin ("__builtin_ctc0", void_ftype_int_int, IQ2000_BUILTIN_CTC0);
2980 def_builtin ("__builtin_ctc1", void_ftype_int_int, IQ2000_BUILTIN_CTC1);
2981 def_builtin ("__builtin_ctc2", void_ftype_int_int, IQ2000_BUILTIN_CTC2);
2982 def_builtin ("__builtin_ctc3", void_ftype_int_int, IQ2000_BUILTIN_CTC3);
2983 def_builtin ("__builtin_mfc0", int_ftype_int, IQ2000_BUILTIN_MFC0);
2984 def_builtin ("__builtin_mfc1", int_ftype_int, IQ2000_BUILTIN_MFC1);
2985 def_builtin ("__builtin_mfc2", int_ftype_int, IQ2000_BUILTIN_MFC2);
2986 def_builtin ("__builtin_mfc3", int_ftype_int, IQ2000_BUILTIN_MFC3);
2987 def_builtin ("__builtin_mtc0", void_ftype_int_int, IQ2000_BUILTIN_MTC0);
2988 def_builtin ("__builtin_mtc1", void_ftype_int_int, IQ2000_BUILTIN_MTC1);
2989 def_builtin ("__builtin_mtc2", void_ftype_int_int, IQ2000_BUILTIN_MTC2);
2990 def_builtin ("__builtin_mtc3", void_ftype_int_int, IQ2000_BUILTIN_MTC3);
2991 def_builtin ("__builtin_lur", void_ftype_int_int, IQ2000_BUILTIN_LUR);
2992 def_builtin ("__builtin_rb", void_ftype_int_int, IQ2000_BUILTIN_RB);
2993 def_builtin ("__builtin_rx", void_ftype_int_int, IQ2000_BUILTIN_RX);
2994 def_builtin ("__builtin_srrd", void_ftype_int, IQ2000_BUILTIN_SRRD);
2995 def_builtin ("__builtin_srwr", void_ftype_int_int, IQ2000_BUILTIN_SRWR);
2996 def_builtin ("__builtin_wb", void_ftype_int_int, IQ2000_BUILTIN_WB);
2997 def_builtin ("__builtin_wx", void_ftype_int_int, IQ2000_BUILTIN_WX);
2998 def_builtin ("__builtin_luc32l", void_ftype_int_int, IQ2000_BUILTIN_LUC32L);
2999 def_builtin ("__builtin_luc64", void_ftype_int_int, IQ2000_BUILTIN_LUC64);
3000 def_builtin ("__builtin_luc64l", void_ftype_int_int, IQ2000_BUILTIN_LUC64L);
3001 def_builtin ("__builtin_luk", void_ftype_int_int, IQ2000_BUILTIN_LUK);
3002 def_builtin ("__builtin_lulck", void_ftype_int, IQ2000_BUILTIN_LULCK);
3003 def_builtin ("__builtin_lum32", void_ftype_int_int, IQ2000_BUILTIN_LUM32);
3004 def_builtin ("__builtin_lum32l", void_ftype_int_int, IQ2000_BUILTIN_LUM32L);
3005 def_builtin ("__builtin_lum64", void_ftype_int_int, IQ2000_BUILTIN_LUM64);
3006 def_builtin ("__builtin_lum64l", void_ftype_int_int, IQ2000_BUILTIN_LUM64L);
3007 def_builtin ("__builtin_lurl", void_ftype_int_int, IQ2000_BUILTIN_LURL);
3008 def_builtin ("__builtin_mrgb", int_ftype_int_int_int, IQ2000_BUILTIN_MRGB);
3009 def_builtin ("__builtin_srrdl", void_ftype_int, IQ2000_BUILTIN_SRRDL);
3010 def_builtin ("__builtin_srulck", void_ftype_int, IQ2000_BUILTIN_SRULCK);
3011 def_builtin ("__builtin_srwru", void_ftype_int_int, IQ2000_BUILTIN_SRWRU);
3012 def_builtin ("__builtin_trapqfl", void_ftype, IQ2000_BUILTIN_TRAPQFL);
3013 def_builtin ("__builtin_trapqne", void_ftype, IQ2000_BUILTIN_TRAPQNE);
3014 def_builtin ("__builtin_traprel", void_ftype_int, IQ2000_BUILTIN_TRAPREL);
3015 def_builtin ("__builtin_wbu", void_ftype_int_int_int, IQ2000_BUILTIN_WBU);
3016 def_builtin ("__builtin_syscall", void_ftype, IQ2000_BUILTIN_SYSCALL);
3019 /* Builtin for ICODE having ARGCOUNT args in ARGLIST where each arg
3023 expand_one_builtin (enum insn_code icode, rtx target, tree arglist,
3024 enum rtx_code *code, int argcount)
3029 enum machine_mode mode [5];
3032 mode[0] = insn_data[icode].operand[0].mode;
3033 for (i = 0; i < argcount; i++)
3035 arg[i] = TREE_VALUE (arglist);
3036 arglist = TREE_CHAIN (arglist);
3037 op[i] = expand_expr (arg[i], NULL_RTX, VOIDmode, 0);
3038 mode[i] = insn_data[icode].operand[i].mode;
3039 if (code[i] == CONST_INT && GET_CODE (op[i]) != CONST_INT)
3040 error ("argument `%d' is not a constant", i + 1);
3042 && ! (*insn_data[icode].operand[i].predicate) (op[i], mode[i]))
3043 op[i] = copy_to_mode_reg (mode[i], op[i]);
3046 if (insn_data[icode].operand[0].constraint[0] == '=')
3049 || GET_MODE (target) != mode[0]
3050 || ! (*insn_data[icode].operand[0].predicate) (target, mode[0]))
3051 target = gen_reg_rtx (mode[0]);
3059 pat = GEN_FCN (icode) (target);
3062 pat = GEN_FCN (icode) (target, op[0]);
3064 pat = GEN_FCN (icode) (op[0]);
3068 pat = GEN_FCN (icode) (target, op[0], op[1]);
3070 pat = GEN_FCN (icode) (op[0], op[1]);
3074 pat = GEN_FCN (icode) (target, op[0], op[1], op[2]);
3076 pat = GEN_FCN (icode) (op[0], op[1], op[2]);
3080 pat = GEN_FCN (icode) (target, op[0], op[1], op[2], op[3]);
3082 pat = GEN_FCN (icode) (op[0], op[1], op[2], op[3]);
3094 /* Expand an expression EXP that calls a built-in function,
3095 with result going to TARGET if that's convenient
3096 (and in mode MODE if that's convenient).
3097 SUBTARGET may be used as the target for computing one of EXP's operands.
3098 IGNORE is nonzero if the value is to be ignored. */
3101 iq2000_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED,
3102 enum machine_mode mode ATTRIBUTE_UNUSED,
3103 int ignore ATTRIBUTE_UNUSED)
3105 tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
3106 tree arglist = TREE_OPERAND (exp, 1);
3107 int fcode = DECL_FUNCTION_CODE (fndecl);
3108 enum rtx_code code [5];
3120 case IQ2000_BUILTIN_ADO16:
3121 return expand_one_builtin (CODE_FOR_ado16, target, arglist, code, 2);
3123 case IQ2000_BUILTIN_RAM:
3124 code[1] = CONST_INT;
3125 code[2] = CONST_INT;
3126 code[3] = CONST_INT;
3127 return expand_one_builtin (CODE_FOR_ram, target, arglist, code, 4);
3129 case IQ2000_BUILTIN_CHKHDR:
3130 return expand_one_builtin (CODE_FOR_chkhdr, target, arglist, code, 2);
3132 case IQ2000_BUILTIN_PKRL:
3133 return expand_one_builtin (CODE_FOR_pkrl, target, arglist, code, 2);
3135 case IQ2000_BUILTIN_CFC0:
3136 code[0] = CONST_INT;
3137 return expand_one_builtin (CODE_FOR_cfc0, target, arglist, code, 1);
3139 case IQ2000_BUILTIN_CFC1:
3140 code[0] = CONST_INT;
3141 return expand_one_builtin (CODE_FOR_cfc1, target, arglist, code, 1);
3143 case IQ2000_BUILTIN_CFC2:
3144 code[0] = CONST_INT;
3145 return expand_one_builtin (CODE_FOR_cfc2, target, arglist, code, 1);
3147 case IQ2000_BUILTIN_CFC3:
3148 code[0] = CONST_INT;
3149 return expand_one_builtin (CODE_FOR_cfc3, target, arglist, code, 1);
3151 case IQ2000_BUILTIN_CTC0:
3152 code[1] = CONST_INT;
3153 return expand_one_builtin (CODE_FOR_ctc0, target, arglist, code, 2);
3155 case IQ2000_BUILTIN_CTC1:
3156 code[1] = CONST_INT;
3157 return expand_one_builtin (CODE_FOR_ctc1, target, arglist, code, 2);
3159 case IQ2000_BUILTIN_CTC2:
3160 code[1] = CONST_INT;
3161 return expand_one_builtin (CODE_FOR_ctc2, target, arglist, code, 2);
3163 case IQ2000_BUILTIN_CTC3:
3164 code[1] = CONST_INT;
3165 return expand_one_builtin (CODE_FOR_ctc3, target, arglist, code, 2);
3167 case IQ2000_BUILTIN_MFC0:
3168 code[0] = CONST_INT;
3169 return expand_one_builtin (CODE_FOR_mfc0, target, arglist, code, 1);
3171 case IQ2000_BUILTIN_MFC1:
3172 code[0] = CONST_INT;
3173 return expand_one_builtin (CODE_FOR_mfc1, target, arglist, code, 1);
3175 case IQ2000_BUILTIN_MFC2:
3176 code[0] = CONST_INT;
3177 return expand_one_builtin (CODE_FOR_mfc2, target, arglist, code, 1);
3179 case IQ2000_BUILTIN_MFC3:
3180 code[0] = CONST_INT;
3181 return expand_one_builtin (CODE_FOR_mfc3, target, arglist, code, 1);
3183 case IQ2000_BUILTIN_MTC0:
3184 code[1] = CONST_INT;
3185 return expand_one_builtin (CODE_FOR_mtc0, target, arglist, code, 2);
3187 case IQ2000_BUILTIN_MTC1:
3188 code[1] = CONST_INT;
3189 return expand_one_builtin (CODE_FOR_mtc1, target, arglist, code, 2);
3191 case IQ2000_BUILTIN_MTC2:
3192 code[1] = CONST_INT;
3193 return expand_one_builtin (CODE_FOR_mtc2, target, arglist, code, 2);
3195 case IQ2000_BUILTIN_MTC3:
3196 code[1] = CONST_INT;
3197 return expand_one_builtin (CODE_FOR_mtc3, target, arglist, code, 2);
3199 case IQ2000_BUILTIN_LUR:
3200 return expand_one_builtin (CODE_FOR_lur, target, arglist, code, 2);
3202 case IQ2000_BUILTIN_RB:
3203 return expand_one_builtin (CODE_FOR_rb, target, arglist, code, 2);
3205 case IQ2000_BUILTIN_RX:
3206 return expand_one_builtin (CODE_FOR_rx, target, arglist, code, 2);
3208 case IQ2000_BUILTIN_SRRD:
3209 return expand_one_builtin (CODE_FOR_srrd, target, arglist, code, 1);
3211 case IQ2000_BUILTIN_SRWR:
3212 return expand_one_builtin (CODE_FOR_srwr, target, arglist, code, 2);
3214 case IQ2000_BUILTIN_WB:
3215 return expand_one_builtin (CODE_FOR_wb, target, arglist, code, 2);
3217 case IQ2000_BUILTIN_WX:
3218 return expand_one_builtin (CODE_FOR_wx, target, arglist, code, 2);
3220 case IQ2000_BUILTIN_LUC32L:
3221 return expand_one_builtin (CODE_FOR_luc32l, target, arglist, code, 2);
3223 case IQ2000_BUILTIN_LUC64:
3224 return expand_one_builtin (CODE_FOR_luc64, target, arglist, code, 2);
3226 case IQ2000_BUILTIN_LUC64L:
3227 return expand_one_builtin (CODE_FOR_luc64l, target, arglist, code, 2);
3229 case IQ2000_BUILTIN_LUK:
3230 return expand_one_builtin (CODE_FOR_luk, target, arglist, code, 2);
3232 case IQ2000_BUILTIN_LULCK:
3233 return expand_one_builtin (CODE_FOR_lulck, target, arglist, code, 1);
3235 case IQ2000_BUILTIN_LUM32:
3236 return expand_one_builtin (CODE_FOR_lum32, target, arglist, code, 2);
3238 case IQ2000_BUILTIN_LUM32L:
3239 return expand_one_builtin (CODE_FOR_lum32l, target, arglist, code, 2);
3241 case IQ2000_BUILTIN_LUM64:
3242 return expand_one_builtin (CODE_FOR_lum64, target, arglist, code, 2);
3244 case IQ2000_BUILTIN_LUM64L:
3245 return expand_one_builtin (CODE_FOR_lum64l, target, arglist, code, 2);
3247 case IQ2000_BUILTIN_LURL:
3248 return expand_one_builtin (CODE_FOR_lurl, target, arglist, code, 2);
3250 case IQ2000_BUILTIN_MRGB:
3251 code[2] = CONST_INT;
3252 return expand_one_builtin (CODE_FOR_mrgb, target, arglist, code, 3);
3254 case IQ2000_BUILTIN_SRRDL:
3255 return expand_one_builtin (CODE_FOR_srrdl, target, arglist, code, 1);
3257 case IQ2000_BUILTIN_SRULCK:
3258 return expand_one_builtin (CODE_FOR_srulck, target, arglist, code, 1);
3260 case IQ2000_BUILTIN_SRWRU:
3261 return expand_one_builtin (CODE_FOR_srwru, target, arglist, code, 2);
3263 case IQ2000_BUILTIN_TRAPQFL:
3264 return expand_one_builtin (CODE_FOR_trapqfl, target, arglist, code, 0);
3266 case IQ2000_BUILTIN_TRAPQNE:
3267 return expand_one_builtin (CODE_FOR_trapqne, target, arglist, code, 0);
3269 case IQ2000_BUILTIN_TRAPREL:
3270 return expand_one_builtin (CODE_FOR_traprel, target, arglist, code, 1);
3272 case IQ2000_BUILTIN_WBU:
3273 return expand_one_builtin (CODE_FOR_wbu, target, arglist, code, 3);
3275 case IQ2000_BUILTIN_SYSCALL:
3276 return expand_one_builtin (CODE_FOR_syscall, target, arglist, code, 0);
3282 /* Worker function for TARGET_RETURN_IN_MEMORY. */
3285 iq2000_return_in_memory (tree type, tree fntype ATTRIBUTE_UNUSED)
3287 return ((int_size_in_bytes (type) > (2 * UNITS_PER_WORD))
3288 || (int_size_in_bytes (type) == -1));
3291 /* Worker function for TARGET_SETUP_INCOMING_VARARGS. */
3294 iq2000_setup_incoming_varargs (CUMULATIVE_ARGS *cum,
3295 enum machine_mode mode ATTRIBUTE_UNUSED,
3296 tree type ATTRIBUTE_UNUSED, int * pretend_size,
3299 unsigned int iq2000_off = ! cum->last_arg_fp;
3300 unsigned int iq2000_fp_off = cum->last_arg_fp;
3302 if ((cum->arg_words < MAX_ARGS_IN_REGISTERS - iq2000_off))
3304 int iq2000_save_gp_regs
3305 = MAX_ARGS_IN_REGISTERS - cum->arg_words - iq2000_off;
3306 int iq2000_save_fp_regs
3307 = (MAX_ARGS_IN_REGISTERS - cum->fp_arg_words - iq2000_fp_off);
3309 if (iq2000_save_gp_regs < 0)
3310 iq2000_save_gp_regs = 0;
3311 if (iq2000_save_fp_regs < 0)
3312 iq2000_save_fp_regs = 0;
3314 *pretend_size = ((iq2000_save_gp_regs * UNITS_PER_WORD)
3315 + (iq2000_save_fp_regs * UNITS_PER_FPREG));
3319 if (cum->arg_words < MAX_ARGS_IN_REGISTERS - iq2000_off)
3322 ptr = plus_constant (virtual_incoming_args_rtx,
3323 - (iq2000_save_gp_regs
3325 mem = gen_rtx_MEM (BLKmode, ptr);
3327 (cum->arg_words + GP_ARG_FIRST + iq2000_off,
3329 iq2000_save_gp_regs);
3335 /* A C compound statement to output to stdio stream STREAM the
3336 assembler syntax for an instruction operand that is a memory
3337 reference whose address is ADDR. ADDR is an RTL expression. */
3340 print_operand_address (FILE * file, rtx addr)
3343 error ("PRINT_OPERAND_ADDRESS, null pointer");
3346 switch (GET_CODE (addr))
3349 if (REGNO (addr) == ARG_POINTER_REGNUM)
3350 abort_with_insn (addr, "Arg pointer not eliminated.");
3352 fprintf (file, "0(%s)", reg_names [REGNO (addr)]);
3357 rtx arg0 = XEXP (addr, 0);
3358 rtx arg1 = XEXP (addr, 1);
3360 if (GET_CODE (arg0) != REG)
3361 abort_with_insn (addr,
3362 "PRINT_OPERAND_ADDRESS, LO_SUM with #1 not REG.");
3364 fprintf (file, "%%lo(");
3365 print_operand_address (file, arg1);
3366 fprintf (file, ")(%s)", reg_names [REGNO (arg0)]);
3374 rtx arg0 = XEXP (addr, 0);
3375 rtx arg1 = XEXP (addr, 1);
3377 if (GET_CODE (arg0) == REG)
3381 if (GET_CODE (offset) == REG)
3382 abort_with_insn (addr, "PRINT_OPERAND_ADDRESS, 2 regs");
3385 else if (GET_CODE (arg1) == REG)
3386 reg = arg1, offset = arg0;
3387 else if (CONSTANT_P (arg0) && CONSTANT_P (arg1))
3389 output_addr_const (file, addr);
3393 abort_with_insn (addr, "PRINT_OPERAND_ADDRESS, no regs");
3395 if (! CONSTANT_P (offset))
3396 abort_with_insn (addr, "PRINT_OPERAND_ADDRESS, invalid insn #2");
3398 if (REGNO (reg) == ARG_POINTER_REGNUM)
3399 abort_with_insn (addr, "Arg pointer not eliminated.");
3401 output_addr_const (file, offset);
3402 fprintf (file, "(%s)", reg_names [REGNO (reg)]);
3410 output_addr_const (file, addr);
3411 if (GET_CODE (addr) == CONST_INT)
3412 fprintf (file, "(%s)", reg_names [0]);
3416 abort_with_insn (addr, "PRINT_OPERAND_ADDRESS, invalid insn #1");
3421 /* A C compound statement to output to stdio stream FILE the
3422 assembler syntax for an instruction operand OP.
3424 LETTER is a value that can be used to specify one of several ways
3425 of printing the operand. It is used when identical operands
3426 must be printed differently depending on the context. LETTER
3427 comes from the `%' specification that was used to request
3428 printing of the operand. If the specification was just `%DIGIT'
3429 then LETTER is 0; if the specification was `%LTR DIGIT' then LETTER
3430 is the ASCII code for LTR.
3432 If OP is a register, this macro should print the register's name.
3433 The names can be found in an array `reg_names' whose type is
3434 `char *[]'. `reg_names' is initialized from `REGISTER_NAMES'.
3436 When the machine description has a specification `%PUNCT' (a `%'
3437 followed by a punctuation character), this macro is called with
3438 a null pointer for X and the punctuation character for LETTER.
3440 The IQ2000 specific codes are:
3442 'X' X is CONST_INT, prints upper 16 bits in hexadecimal format = "0x%04x",
3443 'x' X is CONST_INT, prints lower 16 bits in hexadecimal format = "0x%04x",
3444 'd' output integer constant in decimal,
3445 'z' if the operand is 0, use $0 instead of normal operand.
3446 'D' print second part of double-word register or memory operand.
3447 'L' print low-order register of double-word register operand.
3448 'M' print high-order register of double-word register operand.
3449 'C' print part of opcode for a branch condition.
3450 'F' print part of opcode for a floating-point branch condition.
3451 'N' print part of opcode for a branch condition, inverted.
3452 'W' print part of opcode for a floating-point branch condition, inverted.
3453 'A' Print part of opcode for a bit test condition.
3454 'P' Print label for a bit test.
3455 'p' Print log for a bit test.
3456 'B' print 'z' for EQ, 'n' for NE
3457 'b' print 'n' for EQ, 'z' for NE
3458 'T' print 'f' for EQ, 't' for NE
3459 't' print 't' for EQ, 'f' for NE
3460 'Z' print register and a comma, but print nothing for $fcc0
3461 '?' Print 'l' if we are to use a branch likely instead of normal branch.
3462 '@' Print the name of the assembler temporary register (at or $1).
3463 '.' Print the name of the register with a hard-wired zero (zero or $0).
3464 '$' Print the name of the stack pointer register (sp or $29).
3465 '+' Print the name of the gp register (gp or $28). */
3468 print_operand (FILE *file, rtx op, int letter)
3472 if (PRINT_OPERAND_PUNCT_VALID_P (letter))
3477 if (iq2000_branch_likely)
3482 fputs (reg_names [GP_REG_FIRST + 1], file);
3486 fputs (reg_names [GP_REG_FIRST + 0], file);
3490 fputs (reg_names[STACK_POINTER_REGNUM], file);
3494 fputs (reg_names[GP_REG_FIRST + 28], file);
3498 error ("PRINT_OPERAND: Unknown punctuation '%c'", letter);
3507 error ("PRINT_OPERAND null pointer");
3511 code = GET_CODE (op);
3513 if (code == SIGN_EXTEND)
3514 op = XEXP (op, 0), code = GET_CODE (op);
3519 case EQ: fputs ("eq", file); break;
3520 case NE: fputs ("ne", file); break;
3521 case GT: fputs ("gt", file); break;
3522 case GE: fputs ("ge", file); break;
3523 case LT: fputs ("lt", file); break;
3524 case LE: fputs ("le", file); break;
3525 case GTU: fputs ("ne", file); break;
3526 case GEU: fputs ("geu", file); break;
3527 case LTU: fputs ("ltu", file); break;
3528 case LEU: fputs ("eq", file); break;
3530 abort_with_insn (op, "PRINT_OPERAND, invalid insn for %%C");
3533 else if (letter == 'N')
3536 case EQ: fputs ("ne", file); break;
3537 case NE: fputs ("eq", file); break;
3538 case GT: fputs ("le", file); break;
3539 case GE: fputs ("lt", file); break;
3540 case LT: fputs ("ge", file); break;
3541 case LE: fputs ("gt", file); break;
3542 case GTU: fputs ("leu", file); break;
3543 case GEU: fputs ("ltu", file); break;
3544 case LTU: fputs ("geu", file); break;
3545 case LEU: fputs ("gtu", file); break;
3547 abort_with_insn (op, "PRINT_OPERAND, invalid insn for %%N");
3550 else if (letter == 'F')
3553 case EQ: fputs ("c1f", file); break;
3554 case NE: fputs ("c1t", file); break;
3556 abort_with_insn (op, "PRINT_OPERAND, invalid insn for %%F");
3559 else if (letter == 'W')
3562 case EQ: fputs ("c1t", file); break;
3563 case NE: fputs ("c1f", file); break;
3565 abort_with_insn (op, "PRINT_OPERAND, invalid insn for %%W");
3568 else if (letter == 'A')
3569 fputs (code == LABEL_REF ? "i" : "in", file);
3571 else if (letter == 'P')
3573 if (code == LABEL_REF)
3574 output_addr_const (file, op);
3575 else if (code != PC)
3576 output_operand_lossage ("invalid %%P operand");
3579 else if (letter == 'p')
3582 if (code != CONST_INT
3583 || (value = exact_log2 (INTVAL (op))) < 0)
3584 output_operand_lossage ("invalid %%p value");
3585 fprintf (file, "%d", value);
3588 else if (letter == 'Z')
3595 regnum = REGNO (op);
3598 fprintf (file, "%s,", reg_names[regnum]);
3601 else if (code == REG || code == SUBREG)
3606 regnum = REGNO (op);
3608 regnum = true_regnum (op);
3610 if ((letter == 'M' && ! WORDS_BIG_ENDIAN)
3611 || (letter == 'L' && WORDS_BIG_ENDIAN)
3615 fprintf (file, "%s", reg_names[regnum]);
3618 else if (code == MEM)
3621 output_address (plus_constant (XEXP (op, 0), 4));
3623 output_address (XEXP (op, 0));
3626 else if (code == CONST_DOUBLE
3627 && GET_MODE_CLASS (GET_MODE (op)) == MODE_FLOAT)
3631 real_to_decimal (s, CONST_DOUBLE_REAL_VALUE (op), sizeof (s), 0, 1);
3635 else if (letter == 'x' && GET_CODE (op) == CONST_INT)
3636 fprintf (file, HOST_WIDE_INT_PRINT_HEX, 0xffff & INTVAL(op));
3638 else if (letter == 'X' && GET_CODE(op) == CONST_INT)
3639 fprintf (file, HOST_WIDE_INT_PRINT_HEX, 0xffff & (INTVAL (op) >> 16));
3641 else if (letter == 'd' && GET_CODE(op) == CONST_INT)
3642 fprintf (file, HOST_WIDE_INT_PRINT_DEC, (INTVAL(op)));
3644 else if (letter == 'z' && GET_CODE (op) == CONST_INT && INTVAL (op) == 0)
3645 fputs (reg_names[GP_REG_FIRST], file);
3647 else if (letter == 'd' || letter == 'x' || letter == 'X')
3648 output_operand_lossage ("invalid use of %%d, %%x, or %%X");
3650 else if (letter == 'B')
3651 fputs (code == EQ ? "z" : "n", file);
3652 else if (letter == 'b')
3653 fputs (code == EQ ? "n" : "z", file);
3654 else if (letter == 'T')
3655 fputs (code == EQ ? "f" : "t", file);
3656 else if (letter == 't')
3657 fputs (code == EQ ? "t" : "f", file);
3659 else if (code == CONST && GET_CODE (XEXP (op, 0)) == REG)
3661 print_operand (file, XEXP (op, 0), letter);
3665 output_addr_const (file, op);
3669 iq2000_rtx_costs (rtx x, int code, int outer_code ATTRIBUTE_UNUSED, int * total)
3671 enum machine_mode mode = GET_MODE (x);
3677 int num_words = (GET_MODE_SIZE (mode) > UNITS_PER_WORD) ? 2 : 1;
3679 if (simple_memory_operand (x, mode))
3680 return COSTS_N_INSNS (num_words);
3682 * total = COSTS_N_INSNS (2 * num_words);
3687 * total = COSTS_N_INSNS (6);
3694 * total = COSTS_N_INSNS (mode == DImode ? 2 : 1);
3701 * total = COSTS_N_INSNS ((GET_CODE (XEXP (x, 1)) == CONST_INT) ? 4 : 12);
3703 * total = COSTS_N_INSNS (1);
3707 if (mode == SFmode || mode == DFmode)
3708 * total = COSTS_N_INSNS (1);
3710 * total = COSTS_N_INSNS (4);
3715 if (mode == SFmode || mode == DFmode)
3716 * total = COSTS_N_INSNS (6);
3717 else if (mode == DImode)
3718 * total = COSTS_N_INSNS (4);
3720 * total = COSTS_N_INSNS (1);
3724 * total = (mode == DImode) ? 4 : 1;
3729 * total = COSTS_N_INSNS (7);
3730 else if (mode == DFmode)
3731 * total = COSTS_N_INSNS (8);
3733 * total = COSTS_N_INSNS (10);
3739 * total = COSTS_N_INSNS (23);
3740 else if (mode == DFmode)
3741 * total = COSTS_N_INSNS (36);
3743 * total = COSTS_N_INSNS (69);
3748 * total = COSTS_N_INSNS (69);
3752 * total = COSTS_N_INSNS (2);
3756 * total = COSTS_N_INSNS (1);
3764 * total = COSTS_N_INSNS (2);
3769 rtx offset = const0_rtx;
3770 rtx symref = eliminate_constant_term (XEXP (x, 0), & offset);
3772 if (GET_CODE (symref) == LABEL_REF)
3773 * total = COSTS_N_INSNS (2);
3774 else if (GET_CODE (symref) != SYMBOL_REF)
3775 * total = COSTS_N_INSNS (4);
3776 /* Let's be paranoid.... */
3777 else if (INTVAL (offset) < -32768 || INTVAL (offset) > 32767)
3778 * total = COSTS_N_INSNS (2);
3780 * total = COSTS_N_INSNS (SYMBOL_REF_FLAG (symref) ? 1 : 2);
3785 * total = COSTS_N_INSNS (SYMBOL_REF_FLAG (x) ? 1 : 2);
3792 split_double (x, & high, & low);
3794 * total = COSTS_N_INSNS ( (high == CONST0_RTX (GET_MODE (high))
3795 || low == CONST0_RTX (GET_MODE (low)))
3806 #include "gt-iq2000.h"