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 #undef TARGET_SCHED_USE_DFA_PIPELINE_INTERFACE
204 #define TARGET_SCHED_USE_DFA_PIPELINE_INTERFACE hook_int_void_1
206 struct gcc_target targetm = TARGET_INITIALIZER;
208 /* Return 1 if OP can be used as an operand where a register or 16 bit unsigned
209 integer is needed. */
212 uns_arith_operand (rtx op, enum machine_mode mode)
214 if (GET_CODE (op) == CONST_INT && SMALL_INT_UNSIGNED (op))
217 return register_operand (op, mode);
220 /* Return 1 if OP can be used as an operand where a 16 bit integer is needed. */
223 arith_operand (rtx op, enum machine_mode mode)
225 if (GET_CODE (op) == CONST_INT && SMALL_INT (op))
228 return register_operand (op, mode);
231 /* Return 1 if OP is a integer which fits in 16 bits. */
234 small_int (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
236 return (GET_CODE (op) == CONST_INT && SMALL_INT (op));
239 /* Return 1 if OP is a 32 bit integer which is too big to be loaded with one
243 large_int (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
247 if (GET_CODE (op) != CONST_INT)
252 /* IOR reg,$r0,value. */
253 if ((value & ~ ((HOST_WIDE_INT) 0x0000ffff)) == 0)
256 /* SUBU reg,$r0,value. */
257 if (((unsigned HOST_WIDE_INT) (value + 32768)) <= 32767)
260 /* LUI reg,value >> 16. */
261 if ((value & 0x0000ffff) == 0)
267 /* Return 1 if OP is a register or the constant 0. */
270 reg_or_0_operand (rtx op, enum machine_mode mode)
272 switch (GET_CODE (op))
275 return INTVAL (op) == 0;
278 return op == CONST0_RTX (mode);
282 return register_operand (op, mode);
291 /* Return 1 if OP is a memory operand that fits in a single instruction
292 (ie, register + small offset). */
295 simple_memory_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
297 rtx addr, plus0, plus1;
299 /* Eliminate non-memory operations. */
300 if (GET_CODE (op) != MEM)
303 /* Dword operations really put out 2 instructions, so eliminate them. */
304 if (GET_MODE_SIZE (GET_MODE (op)) > (unsigned) UNITS_PER_WORD)
307 /* Decode the address now. */
309 switch (GET_CODE (addr))
316 return SMALL_INT (addr);
319 plus0 = XEXP (addr, 0);
320 plus1 = XEXP (addr, 1);
321 if (GET_CODE (plus0) == REG
322 && GET_CODE (plus1) == CONST_INT && SMALL_INT (plus1)
323 && SMALL_INT_UNSIGNED (plus1) /* No negative offsets. */)
326 else if (GET_CODE (plus1) == REG
327 && GET_CODE (plus0) == CONST_INT && SMALL_INT (plus0)
328 && SMALL_INT_UNSIGNED (plus1) /* No negative offsets. */)
344 /* Return nonzero if the code of this rtx pattern is EQ or NE. */
347 equality_op (rtx op, enum machine_mode mode)
349 if (mode != GET_MODE (op))
352 return GET_CODE (op) == EQ || GET_CODE (op) == NE;
355 /* Return nonzero if the code is a relational operations (EQ, LE, etc). */
358 cmp_op (rtx op, enum machine_mode mode)
360 if (mode != GET_MODE (op))
363 return COMPARISON_P (op);
366 /* Return nonzero if the operand is either the PC or a label_ref. */
369 pc_or_label_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
374 if (GET_CODE (op) == LABEL_REF)
380 /* Return nonzero if OP is a valid operand for a call instruction. */
383 call_insn_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
385 return (CONSTANT_ADDRESS_P (op)
386 || (GET_CODE (op) == REG && op != arg_pointer_rtx
387 && ! (REGNO (op) >= FIRST_PSEUDO_REGISTER
388 && REGNO (op) <= LAST_VIRTUAL_REGISTER)));
391 /* Return nonzero if OP is valid as a source operand for a move instruction. */
394 move_operand (rtx op, enum machine_mode mode)
396 /* Accept any general operand after reload has started; doing so
397 avoids losing if reload does an in-place replacement of a register
398 with a SYMBOL_REF or CONST. */
399 return (general_operand (op, mode)
400 && (! (iq2000_check_split (op, mode))
401 || reload_in_progress || reload_completed));
404 /* Return nonzero if OP is a constant power of 2. */
407 power_of_2_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
411 if (GET_CODE (op) != CONST_INT)
414 intval = INTVAL (op);
416 return ((intval & ((unsigned)(intval) - 1)) == 0);
419 /* Return nonzero if we split the address into high and low parts. */
422 iq2000_check_split (rtx address, enum machine_mode mode)
424 /* This is the same check used in simple_memory_operand.
425 We use it here because LO_SUM is not offsettable. */
426 if (GET_MODE_SIZE (mode) > (unsigned) UNITS_PER_WORD)
429 if ((GET_CODE (address) == SYMBOL_REF)
430 || (GET_CODE (address) == CONST
431 && GET_CODE (XEXP (XEXP (address, 0), 0)) == SYMBOL_REF)
432 || GET_CODE (address) == LABEL_REF)
438 /* Return nonzero if REG is valid for MODE. */
441 iq2000_reg_mode_ok_for_base_p (rtx reg,
442 enum machine_mode mode ATTRIBUTE_UNUSED,
446 ? REGNO_MODE_OK_FOR_BASE_P (REGNO (reg), mode)
447 : GP_REG_OR_PSEUDO_NONSTRICT_P (REGNO (reg), mode));
450 /* Return a nonzero value if XINSN is a legitimate address for a
451 memory operand of the indicated MODE. STRICT is nonzero if this
452 function is called during reload. */
455 iq2000_legitimate_address_p (enum machine_mode mode, rtx xinsn, int strict)
457 if (TARGET_DEBUG_A_MODE)
459 GO_PRINTF2 ("\n========== GO_IF_LEGITIMATE_ADDRESS, %sstrict\n",
460 strict ? "" : "not ");
461 GO_DEBUG_RTX (xinsn);
464 /* Check for constant before stripping off SUBREG, so that we don't
465 accept (subreg (const_int)) which will fail to reload. */
466 if (CONSTANT_ADDRESS_P (xinsn)
467 && ! (iq2000_check_split (xinsn, mode))
468 && ! (GET_CODE (xinsn) == CONST_INT && ! SMALL_INT (xinsn)))
471 while (GET_CODE (xinsn) == SUBREG)
472 xinsn = SUBREG_REG (xinsn);
474 if (GET_CODE (xinsn) == REG
475 && iq2000_reg_mode_ok_for_base_p (xinsn, mode, strict))
478 if (GET_CODE (xinsn) == LO_SUM)
480 rtx xlow0 = XEXP (xinsn, 0);
481 rtx xlow1 = XEXP (xinsn, 1);
483 while (GET_CODE (xlow0) == SUBREG)
484 xlow0 = SUBREG_REG (xlow0);
485 if (GET_CODE (xlow0) == REG
486 && iq2000_reg_mode_ok_for_base_p (xlow0, mode, strict)
487 && iq2000_check_split (xlow1, mode))
491 if (GET_CODE (xinsn) == PLUS)
493 rtx xplus0 = XEXP (xinsn, 0);
494 rtx xplus1 = XEXP (xinsn, 1);
498 while (GET_CODE (xplus0) == SUBREG)
499 xplus0 = SUBREG_REG (xplus0);
500 code0 = GET_CODE (xplus0);
502 while (GET_CODE (xplus1) == SUBREG)
503 xplus1 = SUBREG_REG (xplus1);
504 code1 = GET_CODE (xplus1);
507 && iq2000_reg_mode_ok_for_base_p (xplus0, mode, strict))
509 if (code1 == CONST_INT && SMALL_INT (xplus1)
510 && SMALL_INT_UNSIGNED (xplus1) /* No negative offsets */)
515 if (TARGET_DEBUG_A_MODE)
516 GO_PRINTF ("Not a legitimate address\n");
518 /* The address was not legitimate. */
522 /* Returns an operand string for the given instruction's delay slot,
523 after updating filled delay slot statistics.
525 We assume that operands[0] is the target register that is set.
527 In order to check the next insn, most of this functionality is moved
528 to FINAL_PRESCAN_INSN, and we just set the global variables that
532 iq2000_fill_delay_slot (const char *ret, enum delay_type type, rtx operands[],
536 enum machine_mode mode;
537 rtx next_insn = cur_insn ? NEXT_INSN (cur_insn) : NULL_RTX;
540 if (type == DELAY_LOAD || type == DELAY_FCMP)
546 /* Make sure that we don't put nop's after labels. */
547 next_insn = NEXT_INSN (cur_insn);
548 while (next_insn != 0
549 && (GET_CODE (next_insn) == NOTE
550 || GET_CODE (next_insn) == CODE_LABEL))
551 next_insn = NEXT_INSN (next_insn);
553 dslots_load_total += num_nops;
554 if (TARGET_DEBUG_C_MODE
555 || type == DELAY_NONE
559 || GET_CODE (next_insn) == CODE_LABEL
560 || (set_reg = operands[0]) == 0)
562 dslots_number_nops = 0;
564 iq2000_load_reg2 = 0;
565 iq2000_load_reg3 = 0;
566 iq2000_load_reg4 = 0;
571 set_reg = operands[0];
575 while (GET_CODE (set_reg) == SUBREG)
576 set_reg = SUBREG_REG (set_reg);
578 mode = GET_MODE (set_reg);
579 dslots_number_nops = num_nops;
580 iq2000_load_reg = set_reg;
581 if (GET_MODE_SIZE (mode)
582 > (unsigned) (UNITS_PER_WORD))
583 iq2000_load_reg2 = gen_rtx_REG (SImode, REGNO (set_reg) + 1);
585 iq2000_load_reg2 = 0;
590 /* Determine whether a memory reference takes one (based off of the GP
591 pointer), two (normal), or three (label + reg) instructions, and bump the
592 appropriate counter for -mstats. */
595 iq2000_count_memory_refs (rtx op, int num)
599 rtx addr, plus0, plus1;
600 enum rtx_code code0, code1;
603 if (TARGET_DEBUG_B_MODE)
605 fprintf (stderr, "\n========== iq2000_count_memory_refs:\n");
609 /* Skip MEM if passed, otherwise handle movsi of address. */
610 addr = (GET_CODE (op) != MEM) ? op : XEXP (op, 0);
612 /* Loop, going through the address RTL. */
616 switch (GET_CODE (addr))
624 plus0 = XEXP (addr, 0);
625 plus1 = XEXP (addr, 1);
626 code0 = GET_CODE (plus0);
627 code1 = GET_CODE (plus1);
637 if (code0 == CONST_INT)
652 if (code1 == CONST_INT)
659 if (code0 == SYMBOL_REF || code0 == LABEL_REF || code0 == CONST)
666 if (code1 == SYMBOL_REF || code1 == LABEL_REF || code1 == CONST)
676 n_words = 2; /* Always 2 words. */
680 addr = XEXP (addr, 0);
685 n_words = SYMBOL_REF_FLAG (addr) ? 1 : 2;
697 n_words += additional;
701 num_refs[n_words-1] += num;
704 /* Abort after printing out a specific insn. */
707 abort_with_insn (rtx insn, const char * reason)
714 /* Return the appropriate instructions to move one operand to another. */
717 iq2000_move_1word (rtx operands[], rtx insn, int unsignedp)
720 rtx op0 = operands[0];
721 rtx op1 = operands[1];
722 enum rtx_code code0 = GET_CODE (op0);
723 enum rtx_code code1 = GET_CODE (op1);
724 enum machine_mode mode = GET_MODE (op0);
725 int subreg_offset0 = 0;
726 int subreg_offset1 = 0;
727 enum delay_type delay = DELAY_NONE;
729 while (code0 == SUBREG)
731 subreg_offset0 += subreg_regno_offset (REGNO (SUBREG_REG (op0)),
732 GET_MODE (SUBREG_REG (op0)),
735 op0 = SUBREG_REG (op0);
736 code0 = GET_CODE (op0);
739 while (code1 == SUBREG)
741 subreg_offset1 += subreg_regno_offset (REGNO (SUBREG_REG (op1)),
742 GET_MODE (SUBREG_REG (op1)),
745 op1 = SUBREG_REG (op1);
746 code1 = GET_CODE (op1);
749 /* For our purposes, a condition code mode is the same as SImode. */
755 int regno0 = REGNO (op0) + subreg_offset0;
759 int regno1 = REGNO (op1) + subreg_offset1;
761 /* Do not do anything for assigning a register to itself */
762 if (regno0 == regno1)
765 else if (GP_REG_P (regno0))
767 if (GP_REG_P (regno1))
768 ret = "or\t%0,%%0,%1";
773 else if (code1 == MEM)
778 iq2000_count_memory_refs (op1, 1);
780 if (GP_REG_P (regno0))
782 /* For loads, use the mode of the memory item, instead of the
783 target, so zero/sign extend can use this code as well. */
784 switch (GET_MODE (op1))
796 ret = (unsignedp) ? "lhu\t%0,%1" : "lh\t%0,%1";
799 ret = (unsignedp) ? "lbu\t%0,%1" : "lb\t%0,%1";
805 else if (code1 == CONST_INT
806 || (code1 == CONST_DOUBLE
807 && GET_MODE (op1) == VOIDmode))
809 if (code1 == CONST_DOUBLE)
811 /* This can happen when storing constants into long long
812 bitfields. Just store the least significant word of
814 operands[1] = op1 = GEN_INT (CONST_DOUBLE_LOW (op1));
817 if (INTVAL (op1) == 0)
819 if (GP_REG_P (regno0))
820 ret = "or\t%0,%%0,%z1";
822 else if (GP_REG_P (regno0))
824 if (SMALL_INT_UNSIGNED (op1))
825 ret = "ori\t%0,%%0,%x1\t\t\t# %1";
826 else if (SMALL_INT (op1))
827 ret = "addiu\t%0,%%0,%1\t\t\t# %1";
829 ret = "lui\t%0,%X1\t\t\t# %1\n\tori\t%0,%0,%x1";
833 else if (code1 == CONST_DOUBLE && mode == SFmode)
835 if (op1 == CONST0_RTX (SFmode))
837 if (GP_REG_P (regno0))
838 ret = "or\t%0,%%0,%.";
848 else if (code1 == LABEL_REF)
851 iq2000_count_memory_refs (op1, 1);
856 else if (code1 == SYMBOL_REF || code1 == CONST)
859 iq2000_count_memory_refs (op1, 1);
864 else if (code1 == PLUS)
866 rtx add_op0 = XEXP (op1, 0);
867 rtx add_op1 = XEXP (op1, 1);
869 if (GET_CODE (XEXP (op1, 1)) == REG
870 && GET_CODE (XEXP (op1, 0)) == CONST_INT)
871 add_op0 = XEXP (op1, 1), add_op1 = XEXP (op1, 0);
873 operands[2] = add_op0;
874 operands[3] = add_op1;
875 ret = "add%:\t%0,%2,%3";
878 else if (code1 == HIGH)
880 operands[1] = XEXP (op1, 0);
881 ret = "lui\t%0,%%hi(%1)";
885 else if (code0 == MEM)
888 iq2000_count_memory_refs (op0, 1);
892 int regno1 = REGNO (op1) + subreg_offset1;
894 if (GP_REG_P (regno1))
898 case SFmode: ret = "sw\t%1,%0"; break;
899 case SImode: ret = "sw\t%1,%0"; break;
900 case HImode: ret = "sh\t%1,%0"; break;
901 case QImode: ret = "sb\t%1,%0"; break;
907 else if (code1 == CONST_INT && INTVAL (op1) == 0)
911 case SFmode: ret = "sw\t%z1,%0"; break;
912 case SImode: ret = "sw\t%z1,%0"; break;
913 case HImode: ret = "sh\t%z1,%0"; break;
914 case QImode: ret = "sb\t%z1,%0"; break;
919 else if (code1 == CONST_DOUBLE && op1 == CONST0_RTX (mode))
923 case SFmode: ret = "sw\t%.,%0"; break;
924 case SImode: ret = "sw\t%.,%0"; break;
925 case HImode: ret = "sh\t%.,%0"; break;
926 case QImode: ret = "sb\t%.,%0"; break;
934 abort_with_insn (insn, "Bad move");
938 if (delay != DELAY_NONE)
939 return iq2000_fill_delay_slot (ret, delay, operands, insn);
944 /* Provide the costs of an addressing mode that contains ADDR. */
947 iq2000_address_cost (rtx addr)
949 switch (GET_CODE (addr))
959 rtx offset = const0_rtx;
961 addr = eliminate_constant_term (XEXP (addr, 0), & offset);
962 if (GET_CODE (addr) == LABEL_REF)
965 if (GET_CODE (addr) != SYMBOL_REF)
968 if (! SMALL_INT (offset))
975 return SYMBOL_REF_FLAG (addr) ? 1 : 2;
979 rtx plus0 = XEXP (addr, 0);
980 rtx plus1 = XEXP (addr, 1);
982 if (GET_CODE (plus0) != REG && GET_CODE (plus1) == REG)
983 plus0 = XEXP (addr, 1), plus1 = XEXP (addr, 0);
985 if (GET_CODE (plus0) != REG)
988 switch (GET_CODE (plus1))
991 return SMALL_INT (plus1) ? 1 : 2;
998 return iq2000_address_cost (plus1) + 1;
1012 /* Make normal rtx_code into something we can index from an array. */
1014 static enum internal_test
1015 map_test_to_internal_test (enum rtx_code test_code)
1017 enum internal_test test = ITEST_MAX;
1021 case EQ: test = ITEST_EQ; break;
1022 case NE: test = ITEST_NE; break;
1023 case GT: test = ITEST_GT; break;
1024 case GE: test = ITEST_GE; break;
1025 case LT: test = ITEST_LT; break;
1026 case LE: test = ITEST_LE; break;
1027 case GTU: test = ITEST_GTU; break;
1028 case GEU: test = ITEST_GEU; break;
1029 case LTU: test = ITEST_LTU; break;
1030 case LEU: test = ITEST_LEU; break;
1037 /* Generate the code to do a TEST_CODE comparison on two integer values CMP0
1038 and CMP1. P_INVERT is NULL or ptr if branch needs to reverse its test.
1039 The return value RESULT is:
1040 (reg:SI xx) The pseudo register the comparison is in
1041 0 No register, generate a simple branch. */
1044 gen_int_relational (enum rtx_code test_code, rtx result, rtx cmp0, rtx cmp1,
1049 enum rtx_code test_code; /* Code to use in instruction (LT vs. LTU). */
1050 int const_low; /* Low bound of constant we can accept. */
1051 int const_high; /* High bound of constant we can accept. */
1052 int const_add; /* Constant to add (convert LE -> LT). */
1053 int reverse_regs; /* Reverse registers in test. */
1054 int invert_const; /* != 0 if invert value if cmp1 is constant. */
1055 int invert_reg; /* != 0 if invert value if cmp1 is register. */
1056 int unsignedp; /* != 0 for unsigned comparisons. */
1059 static struct cmp_info info[ (int)ITEST_MAX ] =
1061 { XOR, 0, 65535, 0, 0, 0, 0, 0 }, /* EQ */
1062 { XOR, 0, 65535, 0, 0, 1, 1, 0 }, /* NE */
1063 { LT, -32769, 32766, 1, 1, 1, 0, 0 }, /* GT */
1064 { LT, -32768, 32767, 0, 0, 1, 1, 0 }, /* GE */
1065 { LT, -32768, 32767, 0, 0, 0, 0, 0 }, /* LT */
1066 { LT, -32769, 32766, 1, 1, 0, 1, 0 }, /* LE */
1067 { LTU, -32769, 32766, 1, 1, 1, 0, 1 }, /* GTU */
1068 { LTU, -32768, 32767, 0, 0, 1, 1, 1 }, /* GEU */
1069 { LTU, -32768, 32767, 0, 0, 0, 0, 1 }, /* LTU */
1070 { LTU, -32769, 32766, 1, 1, 0, 1, 1 }, /* LEU */
1073 enum internal_test test;
1074 enum machine_mode mode;
1075 struct cmp_info *p_info;
1082 test = map_test_to_internal_test (test_code);
1083 if (test == ITEST_MAX)
1086 p_info = &info[(int) test];
1087 eqne_p = (p_info->test_code == XOR);
1089 mode = GET_MODE (cmp0);
1090 if (mode == VOIDmode)
1091 mode = GET_MODE (cmp1);
1093 /* Eliminate simple branches. */
1094 branch_p = (result == 0);
1097 if (GET_CODE (cmp0) == REG || GET_CODE (cmp0) == SUBREG)
1099 /* Comparisons against zero are simple branches. */
1100 if (GET_CODE (cmp1) == CONST_INT && INTVAL (cmp1) == 0)
1103 /* Test for beq/bne. */
1108 /* Allocate a pseudo to calculate the value in. */
1109 result = gen_reg_rtx (mode);
1112 /* Make sure we can handle any constants given to us. */
1113 if (GET_CODE (cmp0) == CONST_INT)
1114 cmp0 = force_reg (mode, cmp0);
1116 if (GET_CODE (cmp1) == CONST_INT)
1118 HOST_WIDE_INT value = INTVAL (cmp1);
1120 if (value < p_info->const_low
1121 || value > p_info->const_high)
1122 cmp1 = force_reg (mode, cmp1);
1125 /* See if we need to invert the result. */
1126 invert = (GET_CODE (cmp1) == CONST_INT
1127 ? p_info->invert_const : p_info->invert_reg);
1129 if (p_invert != (int *)0)
1135 /* Comparison to constants, may involve adding 1 to change a LT into LE.
1136 Comparison between two registers, may involve switching operands. */
1137 if (GET_CODE (cmp1) == CONST_INT)
1139 if (p_info->const_add != 0)
1141 HOST_WIDE_INT new = INTVAL (cmp1) + p_info->const_add;
1143 /* If modification of cmp1 caused overflow,
1144 we would get the wrong answer if we follow the usual path;
1145 thus, x > 0xffffffffU would turn into x > 0U. */
1146 if ((p_info->unsignedp
1147 ? (unsigned HOST_WIDE_INT) new >
1148 (unsigned HOST_WIDE_INT) INTVAL (cmp1)
1149 : new > INTVAL (cmp1))
1150 != (p_info->const_add > 0))
1152 /* This test is always true, but if INVERT is true then
1153 the result of the test needs to be inverted so 0 should
1154 be returned instead. */
1155 emit_move_insn (result, invert ? const0_rtx : const_true_rtx);
1159 cmp1 = GEN_INT (new);
1163 else if (p_info->reverse_regs)
1170 if (test == ITEST_NE && GET_CODE (cmp1) == CONST_INT && INTVAL (cmp1) == 0)
1174 reg = (invert || eqne_p) ? gen_reg_rtx (mode) : result;
1175 convert_move (reg, gen_rtx_fmt_ee (p_info->test_code, mode, cmp0, cmp1), 0);
1178 if (test == ITEST_NE)
1180 convert_move (result, gen_rtx_GTU (mode, reg, const0_rtx), 0);
1181 if (p_invert != NULL)
1186 else if (test == ITEST_EQ)
1188 reg2 = invert ? gen_reg_rtx (mode) : result;
1189 convert_move (reg2, gen_rtx_LTU (mode, reg, const1_rtx), 0);
1198 convert_move (result, gen_rtx_XOR (mode, reg, one), 0);
1204 /* Emit the common code for doing conditional branches.
1205 operand[0] is the label to jump to.
1206 The comparison operands are saved away by cmp{si,di,sf,df}. */
1209 gen_conditional_branch (rtx operands[], enum rtx_code test_code)
1211 enum cmp_type type = branch_type;
1212 rtx cmp0 = branch_cmp[0];
1213 rtx cmp1 = branch_cmp[1];
1214 enum machine_mode mode;
1223 mode = type == CMP_SI ? SImode : DImode;
1225 reg = gen_int_relational (test_code, NULL_RTX, cmp0, cmp1, &invert);
1233 else if (GET_CODE (cmp1) == CONST_INT && INTVAL (cmp1) != 0)
1234 /* We don't want to build a comparison against a nonzero
1236 cmp1 = force_reg (mode, cmp1);
1242 reg = gen_reg_rtx (CCmode);
1244 /* For cmp0 != cmp1, build cmp0 == cmp1, and test for result == 0. */
1245 emit_insn (gen_rtx_SET (VOIDmode, reg,
1246 gen_rtx_fmt_ee (test_code == NE ? EQ : test_code,
1247 CCmode, cmp0, cmp1)));
1249 test_code = test_code == NE ? EQ : NE;
1257 abort_with_insn (gen_rtx_fmt_ee (test_code, VOIDmode, cmp0, cmp1),
1261 /* Generate the branch. */
1262 label1 = gen_rtx_LABEL_REF (VOIDmode, operands[0]);
1271 emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
1272 gen_rtx_IF_THEN_ELSE (VOIDmode,
1273 gen_rtx_fmt_ee (test_code,
1279 /* Initialize CUM for a function FNTYPE. */
1282 init_cumulative_args (CUMULATIVE_ARGS *cum, tree fntype,
1283 rtx libname ATTRIBUTE_UNUSED)
1285 static CUMULATIVE_ARGS zero_cum;
1289 if (TARGET_DEBUG_D_MODE)
1292 "\ninit_cumulative_args, fntype = 0x%.8lx", (long) fntype);
1295 fputc ('\n', stderr);
1299 tree ret_type = TREE_TYPE (fntype);
1301 fprintf (stderr, ", fntype code = %s, ret code = %s\n",
1302 tree_code_name[(int)TREE_CODE (fntype)],
1303 tree_code_name[(int)TREE_CODE (ret_type)]);
1309 /* Determine if this function has variable arguments. This is
1310 indicated by the last argument being 'void_type_mode' if there
1311 are no variable arguments. The standard IQ2000 calling sequence
1312 passes all arguments in the general purpose registers in this case. */
1314 for (param = fntype ? TYPE_ARG_TYPES (fntype) : 0;
1315 param != 0; param = next_param)
1317 next_param = TREE_CHAIN (param);
1318 if (next_param == 0 && TREE_VALUE (param) != void_type_node)
1319 cum->gp_reg_found = 1;
1323 /* Advance the argument of type TYPE and mode MODE to the next argument
1327 function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode, tree type,
1330 if (TARGET_DEBUG_D_MODE)
1333 "function_adv({gp reg found = %d, arg # = %2d, words = %2d}, %4s, ",
1334 cum->gp_reg_found, cum->arg_number, cum->arg_words,
1335 GET_MODE_NAME (mode));
1336 fprintf (stderr, HOST_PTR_PRINTF, (const PTR) type);
1337 fprintf (stderr, ", %d )\n\n", named);
1347 if (GET_MODE_CLASS (mode) != MODE_COMPLEX_INT
1348 && GET_MODE_CLASS (mode) != MODE_COMPLEX_FLOAT)
1351 cum->gp_reg_found = 1;
1352 cum->arg_words += ((GET_MODE_SIZE (mode) + UNITS_PER_WORD - 1)
1357 cum->gp_reg_found = 1;
1358 cum->arg_words += ((int_size_in_bytes (type) + UNITS_PER_WORD - 1)
1364 if (! cum->gp_reg_found && cum->arg_number <= 2)
1365 cum->fp_code += 1 << ((cum->arg_number - 1) * 2);
1369 cum->arg_words += 2;
1370 if (! cum->gp_reg_found && cum->arg_number <= 2)
1371 cum->fp_code += 2 << ((cum->arg_number - 1) * 2);
1375 cum->gp_reg_found = 1;
1376 cum->arg_words += 2;
1382 cum->gp_reg_found = 1;
1388 /* Return an RTL expression containing the register for the given mode MODE
1389 and type TYPE in CUM, or 0 if the argument is to be passed on the stack. */
1392 function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode, tree type,
1398 unsigned int *arg_words = &cum->arg_words;
1399 int struct_p = (type != 0
1400 && (TREE_CODE (type) == RECORD_TYPE
1401 || TREE_CODE (type) == UNION_TYPE
1402 || TREE_CODE (type) == QUAL_UNION_TYPE));
1404 if (TARGET_DEBUG_D_MODE)
1407 "function_arg( {gp reg found = %d, arg # = %2d, words = %2d}, %4s, ",
1408 cum->gp_reg_found, cum->arg_number, cum->arg_words,
1409 GET_MODE_NAME (mode));
1410 fprintf (stderr, HOST_PTR_PRINTF, (const PTR) type);
1411 fprintf (stderr, ", %d ) = ", named);
1415 cum->last_arg_fp = 0;
1419 regbase = GP_ARG_FIRST;
1423 cum->arg_words += cum->arg_words & 1;
1425 regbase = GP_ARG_FIRST;
1429 if (GET_MODE_CLASS (mode) != MODE_COMPLEX_INT
1430 && GET_MODE_CLASS (mode) != MODE_COMPLEX_FLOAT)
1433 /* Drops through. */
1435 if (type != NULL_TREE && TYPE_ALIGN (type) > (unsigned) BITS_PER_WORD)
1436 cum->arg_words += (cum->arg_words & 1);
1437 regbase = GP_ARG_FIRST;
1444 regbase = GP_ARG_FIRST;
1448 cum->arg_words += (cum->arg_words & 1);
1449 regbase = GP_ARG_FIRST;
1452 if (*arg_words >= (unsigned) MAX_ARGS_IN_REGISTERS)
1454 if (TARGET_DEBUG_D_MODE)
1455 fprintf (stderr, "<stack>%s\n", struct_p ? ", [struct]" : "");
1464 if (! type || TREE_CODE (type) != RECORD_TYPE
1465 || ! named || ! TYPE_SIZE_UNIT (type)
1466 || ! host_integerp (TYPE_SIZE_UNIT (type), 1))
1467 ret = gen_rtx_REG (mode, regbase + *arg_words + bias);
1472 for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field))
1473 if (TREE_CODE (field) == FIELD_DECL
1474 && TREE_CODE (TREE_TYPE (field)) == REAL_TYPE
1475 && TYPE_PRECISION (TREE_TYPE (field)) == BITS_PER_WORD
1476 && host_integerp (bit_position (field), 0)
1477 && int_bit_position (field) % BITS_PER_WORD == 0)
1480 /* If the whole struct fits a DFmode register,
1481 we don't need the PARALLEL. */
1482 if (! field || mode == DFmode)
1483 ret = gen_rtx_REG (mode, regbase + *arg_words + bias);
1486 unsigned int chunks;
1487 HOST_WIDE_INT bitpos;
1491 /* ??? If this is a packed structure, then the last hunk won't
1494 = tree_low_cst (TYPE_SIZE_UNIT (type), 1) / UNITS_PER_WORD;
1495 if (chunks + *arg_words + bias > (unsigned) MAX_ARGS_IN_REGISTERS)
1496 chunks = MAX_ARGS_IN_REGISTERS - *arg_words - bias;
1498 /* Assign_parms checks the mode of ENTRY_PARM, so we must
1499 use the actual mode here. */
1500 ret = gen_rtx_PARALLEL (mode, rtvec_alloc (chunks));
1503 regno = regbase + *arg_words + bias;
1504 field = TYPE_FIELDS (type);
1505 for (i = 0; i < chunks; i++)
1509 for (; field; field = TREE_CHAIN (field))
1510 if (TREE_CODE (field) == FIELD_DECL
1511 && int_bit_position (field) >= bitpos)
1515 && int_bit_position (field) == bitpos
1516 && TREE_CODE (TREE_TYPE (field)) == REAL_TYPE
1517 && TYPE_PRECISION (TREE_TYPE (field)) == BITS_PER_WORD)
1518 reg = gen_rtx_REG (DFmode, regno++);
1520 reg = gen_rtx_REG (word_mode, regno);
1523 = gen_rtx_EXPR_LIST (VOIDmode, reg,
1524 GEN_INT (bitpos / BITS_PER_UNIT));
1532 if (TARGET_DEBUG_D_MODE)
1533 fprintf (stderr, "%s%s\n", reg_names[regbase + *arg_words + bias],
1534 struct_p ? ", [struct]" : "");
1537 /* We will be called with a mode of VOIDmode after the last argument
1538 has been seen. Whatever we return will be passed to the call
1539 insn. If we need any shifts for small structures, return them in
1541 if (mode == VOIDmode)
1543 if (cum->num_adjusts > 0)
1544 ret = gen_rtx_PARALLEL ((enum machine_mode) cum->fp_code,
1545 gen_rtvec_v (cum->num_adjusts, cum->adjust));
1552 function_arg_partial_nregs (CUMULATIVE_ARGS *cum, enum machine_mode mode,
1553 tree type ATTRIBUTE_UNUSED,
1554 int named ATTRIBUTE_UNUSED)
1557 && cum->arg_words == MAX_ARGS_IN_REGISTERS - (unsigned)1)
1559 if (TARGET_DEBUG_D_MODE)
1560 fprintf (stderr, "function_arg_partial_nregs = 1\n");
1568 /* Implement va_start. */
1571 iq2000_va_start (tree valist, rtx nextarg)
1574 /* Find out how many non-float named formals. */
1575 int gpr_save_area_size;
1576 /* Note UNITS_PER_WORD is 4 bytes. */
1577 int_arg_words = current_function_args_info.arg_words;
1579 if (int_arg_words < 8 )
1580 /* Adjust for the prologue's economy measure. */
1581 gpr_save_area_size = (8 - int_arg_words) * UNITS_PER_WORD;
1583 gpr_save_area_size = 0;
1585 /* Everything is in the GPR save area, or in the overflow
1586 area which is contiguous with it. */
1587 nextarg = plus_constant (nextarg, - gpr_save_area_size);
1588 std_expand_builtin_va_start (valist, nextarg);
1591 /* Allocate a chunk of memory for per-function machine-dependent data. */
1593 static struct machine_function *
1594 iq2000_init_machine_status (void)
1596 struct machine_function *f;
1598 f = ggc_alloc_cleared (sizeof (struct machine_function));
1603 static enum processor_type
1604 iq2000_parse_cpu (const char * cpu_string)
1606 const char *p = cpu_string;
1607 enum processor_type cpu;
1609 cpu = PROCESSOR_DEFAULT;
1613 if (!strcmp (p, "iq10"))
1614 cpu = PROCESSOR_IQ10;
1617 if (!strcmp (p, "iq2000"))
1618 cpu = PROCESSOR_IQ2000;
1625 /* Detect any conflicts in the switches. */
1628 override_options (void)
1630 enum processor_type iq2000_cpu;
1632 target_flags &= ~MASK_GPOPT;
1634 iq2000_isa = IQ2000_ISA_DEFAULT;
1636 /* Identify the processor type. */
1638 if (iq2000_cpu_string != 0)
1640 iq2000_cpu = iq2000_parse_cpu (iq2000_cpu_string);
1641 if (iq2000_cpu == PROCESSOR_DEFAULT)
1643 error ("bad value (%s) for -mcpu= switch", iq2000_arch_string);
1644 iq2000_cpu_string = "default";
1646 iq2000_arch = iq2000_cpu;
1647 iq2000_tune = iq2000_cpu;
1650 if (iq2000_arch_string == 0
1651 || ! strcmp (iq2000_arch_string, "default")
1652 || ! strcmp (iq2000_arch_string, "DEFAULT"))
1657 iq2000_arch_string = "iq2000";
1658 iq2000_arch = PROCESSOR_IQ2000;
1664 iq2000_arch = iq2000_parse_cpu (iq2000_arch_string);
1665 if (iq2000_arch == PROCESSOR_DEFAULT)
1667 error ("bad value (%s) for -march= switch", iq2000_arch_string);
1668 iq2000_arch_string = "default";
1670 if (iq2000_arch == PROCESSOR_IQ10)
1672 error ("The compiler does not support -march=%s.", iq2000_arch_string);
1673 iq2000_arch_string = "default";
1677 iq2000_print_operand_punct['?'] = 1;
1678 iq2000_print_operand_punct['#'] = 1;
1679 iq2000_print_operand_punct['&'] = 1;
1680 iq2000_print_operand_punct['!'] = 1;
1681 iq2000_print_operand_punct['*'] = 1;
1682 iq2000_print_operand_punct['@'] = 1;
1683 iq2000_print_operand_punct['.'] = 1;
1684 iq2000_print_operand_punct['('] = 1;
1685 iq2000_print_operand_punct[')'] = 1;
1686 iq2000_print_operand_punct['['] = 1;
1687 iq2000_print_operand_punct[']'] = 1;
1688 iq2000_print_operand_punct['<'] = 1;
1689 iq2000_print_operand_punct['>'] = 1;
1690 iq2000_print_operand_punct['{'] = 1;
1691 iq2000_print_operand_punct['}'] = 1;
1692 iq2000_print_operand_punct['^'] = 1;
1693 iq2000_print_operand_punct['$'] = 1;
1694 iq2000_print_operand_punct['+'] = 1;
1695 iq2000_print_operand_punct['~'] = 1;
1697 /* Save GPR registers in word_mode sized hunks. word_mode hasn't been
1698 initialized yet, so we can't use that here. */
1701 /* Function to allocate machine-dependent function status. */
1702 init_machine_status = iq2000_init_machine_status;
1705 /* The arg pointer (which is eliminated) points to the virtual frame pointer,
1706 while the frame pointer (which may be eliminated) points to the stack
1707 pointer after the initial adjustments. */
1710 iq2000_debugger_offset (rtx addr, HOST_WIDE_INT offset)
1712 rtx offset2 = const0_rtx;
1713 rtx reg = eliminate_constant_term (addr, & offset2);
1716 offset = INTVAL (offset2);
1718 if (reg == stack_pointer_rtx || reg == frame_pointer_rtx
1719 || reg == hard_frame_pointer_rtx)
1721 HOST_WIDE_INT frame_size = (!cfun->machine->initialized)
1722 ? compute_frame_size (get_frame_size ())
1723 : cfun->machine->total_size;
1725 offset = offset - frame_size;
1731 /* If defined, a C statement to be executed just prior to the output of
1732 assembler code for INSN, to modify the extracted operands so they will be
1735 Here the argument OPVEC is the vector containing the operands extracted
1736 from INSN, and NOPERANDS is the number of elements of the vector which
1737 contain meaningful data for this insn. The contents of this vector are
1738 what will be used to convert the insn template into assembler code, so you
1739 can change the assembler output by changing the contents of the vector.
1741 We use it to check if the current insn needs a nop in front of it because
1742 of load delays, and also to update the delay slot statistics. */
1745 final_prescan_insn (rtx insn, rtx opvec[] ATTRIBUTE_UNUSED,
1746 int noperands ATTRIBUTE_UNUSED)
1748 if (dslots_number_nops > 0)
1750 rtx pattern = PATTERN (insn);
1751 int length = get_attr_length (insn);
1753 /* Do we need to emit a NOP? */
1755 || (iq2000_load_reg != 0 && reg_mentioned_p (iq2000_load_reg, pattern))
1756 || (iq2000_load_reg2 != 0 && reg_mentioned_p (iq2000_load_reg2, pattern))
1757 || (iq2000_load_reg3 != 0 && reg_mentioned_p (iq2000_load_reg3, pattern))
1758 || (iq2000_load_reg4 != 0
1759 && reg_mentioned_p (iq2000_load_reg4, pattern)))
1760 fputs ("\tnop\n", asm_out_file);
1763 dslots_load_filled ++;
1765 while (--dslots_number_nops > 0)
1766 fputs ("\tnop\n", asm_out_file);
1768 iq2000_load_reg = 0;
1769 iq2000_load_reg2 = 0;
1770 iq2000_load_reg3 = 0;
1771 iq2000_load_reg4 = 0;
1774 if ( (GET_CODE (insn) == JUMP_INSN
1775 || GET_CODE (insn) == CALL_INSN
1776 || (GET_CODE (PATTERN (insn)) == RETURN))
1777 && NEXT_INSN (PREV_INSN (insn)) == insn)
1779 rtx nop_insn = emit_insn_after (gen_nop (), insn);
1781 INSN_ADDRESSES_NEW (nop_insn, -1);
1785 && (GET_CODE (insn) == JUMP_INSN || GET_CODE (insn) == CALL_INSN))
1786 dslots_jump_total ++;
1789 /* Return the bytes needed to compute the frame pointer from the current
1790 stack pointer where SIZE is the # of var. bytes allocated.
1792 IQ2000 stack frames look like:
1794 Before call After call
1795 +-----------------------+ +-----------------------+
1798 | caller's temps. | | caller's temps. |
1800 +-----------------------+ +-----------------------+
1802 | arguments on stack. | | arguments on stack. |
1804 +-----------------------+ +-----------------------+
1805 | 4 words to save | | 4 words to save |
1806 | arguments passed | | arguments passed |
1807 | in registers, even | | in registers, even |
1808 SP->| if not passed. | VFP->| if not passed. |
1809 +-----------------------+ +-----------------------+
1811 | fp register save |
1813 +-----------------------+
1815 | gp register save |
1817 +-----------------------+
1821 +-----------------------+
1823 | alloca allocations |
1825 +-----------------------+
1827 | GP save for V.4 abi |
1829 +-----------------------+
1831 | arguments on stack |
1833 +-----------------------+
1835 | arguments passed |
1836 | in registers, even |
1837 low SP->| if not passed. |
1838 memory +-----------------------+ */
1841 compute_frame_size (HOST_WIDE_INT size)
1844 HOST_WIDE_INT total_size; /* # bytes that the entire frame takes up. */
1845 HOST_WIDE_INT var_size; /* # bytes that variables take up. */
1846 HOST_WIDE_INT args_size; /* # bytes that outgoing arguments take up. */
1847 HOST_WIDE_INT extra_size; /* # extra bytes. */
1848 HOST_WIDE_INT gp_reg_rounded; /* # bytes needed to store gp after rounding. */
1849 HOST_WIDE_INT gp_reg_size; /* # bytes needed to store gp regs. */
1850 HOST_WIDE_INT fp_reg_size; /* # bytes needed to store fp regs. */
1851 long mask; /* mask of saved gp registers. */
1852 int fp_inc; /* 1 or 2 depending on the size of fp regs. */
1853 long fp_bits; /* bitmask to use for each fp register. */
1858 extra_size = IQ2000_STACK_ALIGN ((0));
1859 var_size = IQ2000_STACK_ALIGN (size);
1860 args_size = IQ2000_STACK_ALIGN (current_function_outgoing_args_size);
1862 /* If a function dynamically allocates the stack and
1863 has 0 for STACK_DYNAMIC_OFFSET then allocate some stack space. */
1864 if (args_size == 0 && current_function_calls_alloca)
1865 args_size = 4 * UNITS_PER_WORD;
1867 total_size = var_size + args_size + extra_size;
1869 /* Calculate space needed for gp registers. */
1870 for (regno = GP_REG_FIRST; regno <= GP_REG_LAST; regno++)
1872 if (MUST_SAVE_REGISTER (regno))
1874 gp_reg_size += GET_MODE_SIZE (gpr_mode);
1875 mask |= 1L << (regno - GP_REG_FIRST);
1879 /* We need to restore these for the handler. */
1880 if (current_function_calls_eh_return)
1886 regno = EH_RETURN_DATA_REGNO (i);
1887 if (regno == (int) INVALID_REGNUM)
1889 gp_reg_size += GET_MODE_SIZE (gpr_mode);
1890 mask |= 1L << (regno - GP_REG_FIRST);
1896 gp_reg_rounded = IQ2000_STACK_ALIGN (gp_reg_size);
1897 total_size += gp_reg_rounded + IQ2000_STACK_ALIGN (fp_reg_size);
1899 /* The gp reg is caller saved, so there is no need for leaf routines
1900 (total_size == extra_size) to save the gp reg. */
1901 if (total_size == extra_size
1903 total_size = extra_size = 0;
1905 total_size += IQ2000_STACK_ALIGN (current_function_pretend_args_size);
1907 /* Save other computed information. */
1908 cfun->machine->total_size = total_size;
1909 cfun->machine->var_size = var_size;
1910 cfun->machine->args_size = args_size;
1911 cfun->machine->extra_size = extra_size;
1912 cfun->machine->gp_reg_size = gp_reg_size;
1913 cfun->machine->fp_reg_size = fp_reg_size;
1914 cfun->machine->mask = mask;
1915 cfun->machine->initialized = reload_completed;
1916 cfun->machine->num_gp = gp_reg_size / UNITS_PER_WORD;
1920 unsigned long offset;
1922 offset = (args_size + extra_size + var_size
1923 + gp_reg_size - GET_MODE_SIZE (gpr_mode));
1925 cfun->machine->gp_sp_offset = offset;
1926 cfun->machine->gp_save_offset = offset - total_size;
1930 cfun->machine->gp_sp_offset = 0;
1931 cfun->machine->gp_save_offset = 0;
1934 cfun->machine->fp_sp_offset = 0;
1935 cfun->machine->fp_save_offset = 0;
1937 /* Ok, we're done. */
1941 /* Implement INITIAL_ELIMINATION_OFFSET. FROM is either the frame
1942 pointer, argument pointer, or return address pointer. TO is either
1943 the stack pointer or hard frame pointer. */
1946 iq2000_initial_elimination_offset (int from, int to ATTRIBUTE_UNUSED)
1950 compute_frame_size (get_frame_size ());
1951 if ((from) == FRAME_POINTER_REGNUM)
1953 else if ((from) == ARG_POINTER_REGNUM)
1954 (offset) = (cfun->machine->total_size);
1955 else if ((from) == RETURN_ADDRESS_POINTER_REGNUM)
1957 if (leaf_function_p ())
1959 else (offset) = cfun->machine->gp_sp_offset
1960 + ((UNITS_PER_WORD - (POINTER_SIZE / BITS_PER_UNIT))
1961 * (BYTES_BIG_ENDIAN != 0));
1967 /* Common code to emit the insns (or to write the instructions to a file)
1968 to save/restore registers.
1969 Other parts of the code assume that IQ2000_TEMP1_REGNUM (aka large_reg)
1970 is not modified within save_restore_insns. */
1972 #define BITSET_P(VALUE,BIT) (((VALUE) & (1L << (BIT))) != 0)
1974 /* Emit instructions to load the value (SP + OFFSET) into IQ2000_TEMP2_REGNUM
1975 and return an rtl expression for the register. Write the assembly
1976 instructions directly to FILE if it is not null, otherwise emit them as
1979 This function is a subroutine of save_restore_insns. It is used when
1980 OFFSET is too large to add in a single instruction. */
1983 iq2000_add_large_offset_to_sp (HOST_WIDE_INT offset)
1985 rtx reg = gen_rtx_REG (Pmode, IQ2000_TEMP2_REGNUM);
1986 rtx offset_rtx = GEN_INT (offset);
1988 emit_move_insn (reg, offset_rtx);
1989 emit_insn (gen_addsi3 (reg, reg, stack_pointer_rtx));
1993 /* Make INSN frame related and note that it performs the frame-related
1994 operation DWARF_PATTERN. */
1997 iq2000_annotate_frame_insn (rtx insn, rtx dwarf_pattern)
1999 RTX_FRAME_RELATED_P (insn) = 1;
2000 REG_NOTES (insn) = alloc_EXPR_LIST (REG_FRAME_RELATED_EXPR,
2005 /* Emit a move instruction that stores REG in MEM. Make the instruction
2006 frame related and note that it stores REG at (SP + OFFSET). */
2009 iq2000_emit_frame_related_store (rtx mem, rtx reg, HOST_WIDE_INT offset)
2011 rtx dwarf_address = plus_constant (stack_pointer_rtx, offset);
2012 rtx dwarf_mem = gen_rtx_MEM (GET_MODE (reg), dwarf_address);
2014 iq2000_annotate_frame_insn (emit_move_insn (mem, reg),
2015 gen_rtx_SET (GET_MODE (reg), dwarf_mem, reg));
2018 /* Emit instructions to save/restore registers, as determined by STORE_P. */
2021 save_restore_insns (int store_p)
2023 long mask = cfun->machine->mask;
2026 HOST_WIDE_INT base_offset;
2027 HOST_WIDE_INT gp_offset;
2028 HOST_WIDE_INT end_offset;
2030 if (frame_pointer_needed
2031 && ! BITSET_P (mask, HARD_FRAME_POINTER_REGNUM - GP_REG_FIRST))
2036 base_reg_rtx = 0, base_offset = 0;
2040 /* Save registers starting from high to low. The debuggers prefer at least
2041 the return register be stored at func+4, and also it allows us not to
2042 need a nop in the epilog if at least one register is reloaded in
2043 addition to return address. */
2045 /* Save GP registers if needed. */
2046 /* Pick which pointer to use as a base register. For small frames, just
2047 use the stack pointer. Otherwise, use a temporary register. Save 2
2048 cycles if the save area is near the end of a large frame, by reusing
2049 the constant created in the prologue/epilogue to adjust the stack
2052 gp_offset = cfun->machine->gp_sp_offset;
2054 = gp_offset - (cfun->machine->gp_reg_size
2055 - GET_MODE_SIZE (gpr_mode));
2057 if (gp_offset < 0 || end_offset < 0)
2059 ("gp_offset (%ld) or end_offset (%ld) is less than zero.",
2060 (long) gp_offset, (long) end_offset);
2062 else if (gp_offset < 32768)
2063 base_reg_rtx = stack_pointer_rtx, base_offset = 0;
2067 int reg_save_count = 0;
2069 for (regno = GP_REG_LAST; regno >= GP_REG_FIRST; regno--)
2070 if (BITSET_P (mask, regno - GP_REG_FIRST)) reg_save_count += 1;
2071 base_offset = gp_offset - ((reg_save_count - 1) * 4);
2072 base_reg_rtx = iq2000_add_large_offset_to_sp (base_offset);
2075 for (regno = GP_REG_LAST; regno >= GP_REG_FIRST; regno--)
2077 if (BITSET_P (mask, regno - GP_REG_FIRST))
2081 = gen_rtx_MEM (gpr_mode,
2082 gen_rtx_PLUS (Pmode, base_reg_rtx,
2083 GEN_INT (gp_offset - base_offset)));
2085 if (! current_function_calls_eh_return)
2086 RTX_UNCHANGING_P (mem_rtx) = 1;
2088 reg_rtx = gen_rtx_REG (gpr_mode, regno);
2091 iq2000_emit_frame_related_store (mem_rtx, reg_rtx, gp_offset);
2094 emit_move_insn (reg_rtx, mem_rtx);
2096 gp_offset -= GET_MODE_SIZE (gpr_mode);
2101 /* Expand the prologue into a bunch of separate insns. */
2104 iq2000_expand_prologue (void)
2107 HOST_WIDE_INT tsize;
2108 int last_arg_is_vararg_marker = 0;
2109 tree fndecl = current_function_decl;
2110 tree fntype = TREE_TYPE (fndecl);
2111 tree fnargs = DECL_ARGUMENTS (fndecl);
2116 CUMULATIVE_ARGS args_so_far;
2117 int store_args_on_stack = (iq2000_can_use_return_insn ());
2119 /* If struct value address is treated as the first argument. */
2120 if (aggregate_value_p (DECL_RESULT (fndecl), fndecl)
2121 && ! current_function_returns_pcc_struct
2122 && targetm.calls.struct_value_rtx (TREE_TYPE (fndecl), 1) == 0)
2124 tree type = build_pointer_type (fntype);
2125 tree function_result_decl = build_decl (PARM_DECL, NULL_TREE, type);
2127 DECL_ARG_TYPE (function_result_decl) = type;
2128 TREE_CHAIN (function_result_decl) = fnargs;
2129 fnargs = function_result_decl;
2132 /* For arguments passed in registers, find the register number
2133 of the first argument in the variable part of the argument list,
2134 otherwise GP_ARG_LAST+1. Note also if the last argument is
2135 the varargs special argument, and treat it as part of the
2138 This is only needed if store_args_on_stack is true. */
2139 INIT_CUMULATIVE_ARGS (args_so_far, fntype, NULL_RTX, 0, 0);
2140 regno = GP_ARG_FIRST;
2142 for (cur_arg = fnargs; cur_arg != 0; cur_arg = next_arg)
2144 tree passed_type = DECL_ARG_TYPE (cur_arg);
2145 enum machine_mode passed_mode = TYPE_MODE (passed_type);
2148 if (TREE_ADDRESSABLE (passed_type))
2150 passed_type = build_pointer_type (passed_type);
2151 passed_mode = Pmode;
2154 entry_parm = FUNCTION_ARG (args_so_far, passed_mode, passed_type, 1);
2156 FUNCTION_ARG_ADVANCE (args_so_far, passed_mode, passed_type, 1);
2157 next_arg = TREE_CHAIN (cur_arg);
2159 if (entry_parm && store_args_on_stack)
2162 && DECL_NAME (cur_arg)
2163 && ((0 == strcmp (IDENTIFIER_POINTER (DECL_NAME (cur_arg)),
2164 "__builtin_va_alist"))
2165 || (0 == strcmp (IDENTIFIER_POINTER (DECL_NAME (cur_arg)),
2168 last_arg_is_vararg_marker = 1;
2175 if (GET_CODE (entry_parm) != REG)
2178 /* Passed in a register, so will get homed automatically. */
2179 if (GET_MODE (entry_parm) == BLKmode)
2180 words = (int_size_in_bytes (passed_type) + 3) / 4;
2182 words = (GET_MODE_SIZE (GET_MODE (entry_parm)) + 3) / 4;
2184 regno = REGNO (entry_parm) + words - 1;
2189 regno = GP_ARG_LAST+1;
2194 /* In order to pass small structures by value in registers we need to
2195 shift the value into the high part of the register.
2196 Function_arg has encoded a PARALLEL rtx, holding a vector of
2197 adjustments to be made as the next_arg_reg variable, so we split up the
2198 insns, and emit them separately. */
2199 next_arg_reg = FUNCTION_ARG (args_so_far, VOIDmode, void_type_node, 1);
2200 if (next_arg_reg != 0 && GET_CODE (next_arg_reg) == PARALLEL)
2202 rtvec adjust = XVEC (next_arg_reg, 0);
2203 int num = GET_NUM_ELEM (adjust);
2205 for (i = 0; i < num; i++)
2209 pattern = RTVEC_ELT (adjust, i);
2210 if (GET_CODE (pattern) != SET
2211 || GET_CODE (SET_SRC (pattern)) != ASHIFT)
2212 abort_with_insn (pattern, "Insn is not a shift");
2213 PUT_CODE (SET_SRC (pattern), ASHIFTRT);
2215 insn = emit_insn (pattern);
2217 /* Global life information isn't valid at this point, so we
2218 can't check whether these shifts are actually used. Mark
2219 them MAYBE_DEAD so that flow2 will remove them, and not
2220 complain about dead code in the prologue. */
2221 REG_NOTES(insn) = gen_rtx_EXPR_LIST (REG_MAYBE_DEAD, NULL_RTX,
2226 tsize = compute_frame_size (get_frame_size ());
2228 /* If this function is a varargs function, store any registers that
2229 would normally hold arguments ($4 - $7) on the stack. */
2230 if (store_args_on_stack
2231 && ((TYPE_ARG_TYPES (fntype) != 0
2232 && (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
2234 || last_arg_is_vararg_marker))
2236 int offset = (regno - GP_ARG_FIRST) * UNITS_PER_WORD;
2237 rtx ptr = stack_pointer_rtx;
2239 for (; regno <= GP_ARG_LAST; regno++)
2242 ptr = gen_rtx_PLUS (Pmode, stack_pointer_rtx, GEN_INT (offset));
2243 emit_move_insn (gen_rtx_MEM (gpr_mode, ptr),
2244 gen_rtx_REG (gpr_mode, regno));
2246 offset += GET_MODE_SIZE (gpr_mode);
2252 rtx tsize_rtx = GEN_INT (tsize);
2253 rtx adjustment_rtx, insn, dwarf_pattern;
2257 adjustment_rtx = gen_rtx_REG (Pmode, IQ2000_TEMP1_REGNUM);
2258 emit_move_insn (adjustment_rtx, tsize_rtx);
2261 adjustment_rtx = tsize_rtx;
2263 insn = emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
2266 dwarf_pattern = gen_rtx_SET (Pmode, stack_pointer_rtx,
2267 plus_constant (stack_pointer_rtx, -tsize));
2269 iq2000_annotate_frame_insn (insn, dwarf_pattern);
2271 save_restore_insns (1);
2273 if (frame_pointer_needed)
2277 insn = emit_insn (gen_movsi (hard_frame_pointer_rtx,
2278 stack_pointer_rtx));
2281 RTX_FRAME_RELATED_P (insn) = 1;
2285 emit_insn (gen_blockage ());
2288 /* Expand the epilogue into a bunch of separate insns. */
2291 iq2000_expand_epilogue (void)
2293 HOST_WIDE_INT tsize = cfun->machine->total_size;
2294 rtx tsize_rtx = GEN_INT (tsize);
2295 rtx tmp_rtx = (rtx)0;
2297 if (iq2000_can_use_return_insn ())
2299 emit_insn (gen_return ());
2305 tmp_rtx = gen_rtx_REG (Pmode, IQ2000_TEMP1_REGNUM);
2306 emit_move_insn (tmp_rtx, tsize_rtx);
2307 tsize_rtx = tmp_rtx;
2312 if (frame_pointer_needed)
2314 emit_insn (gen_blockage ());
2316 emit_insn (gen_movsi (stack_pointer_rtx, hard_frame_pointer_rtx));
2319 save_restore_insns (0);
2321 if (current_function_calls_eh_return)
2323 rtx eh_ofs = EH_RETURN_STACKADJ_RTX;
2324 emit_insn (gen_addsi3 (eh_ofs, eh_ofs, tsize_rtx));
2328 emit_insn (gen_blockage ());
2330 if (tsize != 0 || current_function_calls_eh_return)
2332 emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx,
2337 if (current_function_calls_eh_return)
2339 /* Perform the additional bump for __throw. */
2340 emit_move_insn (gen_rtx_REG (Pmode, HARD_FRAME_POINTER_REGNUM),
2342 emit_insn (gen_rtx_USE (VOIDmode, gen_rtx_REG (Pmode,
2343 HARD_FRAME_POINTER_REGNUM)));
2344 emit_jump_insn (gen_eh_return_internal ());
2347 emit_jump_insn (gen_return_internal (gen_rtx_REG (Pmode,
2348 GP_REG_FIRST + 31)));
2352 iq2000_expand_eh_return (rtx address)
2354 HOST_WIDE_INT gp_offset = cfun->machine->gp_sp_offset;
2357 scratch = plus_constant (stack_pointer_rtx, gp_offset);
2358 emit_move_insn (gen_rtx_MEM (GET_MODE (address), scratch), address);
2361 /* Return nonzero if this function is known to have a null epilogue.
2362 This allows the optimizer to omit jumps to jumps if no stack
2366 iq2000_can_use_return_insn (void)
2368 if (! reload_completed)
2371 if (regs_ever_live[31] || profile_flag)
2374 if (cfun->machine->initialized)
2375 return cfun->machine->total_size == 0;
2377 return compute_frame_size (get_frame_size ()) == 0;
2380 /* Returns nonzero if X contains a SYMBOL_REF. */
2383 symbolic_expression_p (rtx x)
2385 if (GET_CODE (x) == SYMBOL_REF)
2388 if (GET_CODE (x) == CONST)
2389 return symbolic_expression_p (XEXP (x, 0));
2392 return symbolic_expression_p (XEXP (x, 0));
2394 if (ARITHMETIC_P (x))
2395 return (symbolic_expression_p (XEXP (x, 0))
2396 || symbolic_expression_p (XEXP (x, 1)));
2401 /* Choose the section to use for the constant rtx expression X that has
2405 iq2000_select_rtx_section (enum machine_mode mode, rtx x ATTRIBUTE_UNUSED,
2406 unsigned HOST_WIDE_INT align)
2408 /* For embedded applications, always put constants in read-only data,
2409 in order to reduce RAM usage. */
2410 /* For embedded applications, always put constants in read-only data,
2411 in order to reduce RAM usage. */
2412 mergeable_constant_section (mode, align, 0);
2415 /* Choose the section to use for DECL. RELOC is true if its value contains
2416 any relocatable expression.
2418 Some of the logic used here needs to be replicated in
2419 ENCODE_SECTION_INFO in iq2000.h so that references to these symbols
2420 are done correctly. */
2423 iq2000_select_section (tree decl, int reloc ATTRIBUTE_UNUSED,
2424 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED)
2426 if (TARGET_EMBEDDED_DATA)
2428 /* For embedded applications, always put an object in read-only data
2429 if possible, in order to reduce RAM usage. */
2430 if ((TREE_CODE (decl) == VAR_DECL
2431 && TREE_READONLY (decl) && !TREE_SIDE_EFFECTS (decl)
2432 && DECL_INITIAL (decl)
2433 && (DECL_INITIAL (decl) == error_mark_node
2434 || TREE_CONSTANT (DECL_INITIAL (decl))))
2435 /* Deal with calls from output_constant_def_contents. */
2436 || TREE_CODE (decl) != VAR_DECL)
2437 readonly_data_section ();
2443 /* For hosted applications, always put an object in small data if
2444 possible, as this gives the best performance. */
2445 if ((TREE_CODE (decl) == VAR_DECL
2446 && TREE_READONLY (decl) && !TREE_SIDE_EFFECTS (decl)
2447 && DECL_INITIAL (decl)
2448 && (DECL_INITIAL (decl) == error_mark_node
2449 || TREE_CONSTANT (DECL_INITIAL (decl))))
2450 /* Deal with calls from output_constant_def_contents. */
2451 || TREE_CODE (decl) != VAR_DECL)
2452 readonly_data_section ();
2457 /* Return register to use for a function return value with VALTYPE for function
2461 iq2000_function_value (tree valtype, tree func ATTRIBUTE_UNUSED)
2463 int reg = GP_RETURN;
2464 enum machine_mode mode = TYPE_MODE (valtype);
2465 int unsignedp = TYPE_UNSIGNED (valtype);
2467 /* Since we define TARGET_PROMOTE_FUNCTION_RETURN that returns true,
2468 we must promote the mode just as PROMOTE_MODE does. */
2469 mode = promote_mode (valtype, mode, &unsignedp, 1);
2471 return gen_rtx_REG (mode, reg);
2474 /* The implementation of FUNCTION_ARG_PASS_BY_REFERENCE. Return
2475 nonzero when an argument must be passed by reference. */
2478 function_arg_pass_by_reference (CUMULATIVE_ARGS *cum ATTRIBUTE_UNUSED,
2479 enum machine_mode mode, tree type,
2480 int named ATTRIBUTE_UNUSED)
2484 /* We must pass by reference if we would be both passing in registers
2485 and the stack. This is because any subsequent partial arg would be
2486 handled incorrectly in this case. */
2487 if (cum && targetm.calls.must_pass_in_stack (mode, type))
2489 /* Don't pass the actual CUM to FUNCTION_ARG, because we would
2490 get double copies of any offsets generated for small structs
2491 passed in registers. */
2492 CUMULATIVE_ARGS temp;
2495 if (FUNCTION_ARG (temp, mode, type, named) != 0)
2499 if (type == NULL_TREE || mode == DImode || mode == DFmode)
2502 size = int_size_in_bytes (type);
2503 return size == -1 || size > UNITS_PER_WORD;
2506 /* Return the length of INSN. LENGTH is the initial length computed by
2507 attributes in the machine-description file. */
2510 iq2000_adjust_insn_length (rtx insn, int length)
2512 /* A unconditional jump has an unfilled delay slot if it is not part
2513 of a sequence. A conditional jump normally has a delay slot. */
2514 if (simplejump_p (insn)
2515 || ( (GET_CODE (insn) == JUMP_INSN
2516 || GET_CODE (insn) == CALL_INSN)))
2522 /* Output assembly instructions to perform a conditional branch.
2524 INSN is the branch instruction. OPERANDS[0] is the condition.
2525 OPERANDS[1] is the target of the branch. OPERANDS[2] is the target
2526 of the first operand to the condition. If TWO_OPERANDS_P is
2527 nonzero the comparison takes two operands; OPERANDS[3] will be the
2530 If INVERTED_P is nonzero we are to branch if the condition does
2531 not hold. If FLOAT_P is nonzero this is a floating-point comparison.
2533 LENGTH is the length (in bytes) of the sequence we are to generate.
2534 That tells us whether to generate a simple conditional branch, or a
2535 reversed conditional branch around a `jr' instruction. */
2538 iq2000_output_conditional_branch (rtx insn, rtx * operands, int two_operands_p,
2539 int float_p, int inverted_p, int length)
2541 static char buffer[200];
2542 /* The kind of comparison we are doing. */
2543 enum rtx_code code = GET_CODE (operands[0]);
2544 /* Nonzero if the opcode for the comparison needs a `z' indicating
2545 that it is a comparison against zero. */
2547 /* A string to use in the assembly output to represent the first
2549 const char *op1 = "%z2";
2550 /* A string to use in the assembly output to represent the second
2551 operand. Use the hard-wired zero register if there's no second
2553 const char *op2 = (two_operands_p ? ",%z3" : ",%.");
2554 /* The operand-printing string for the comparison. */
2555 const char *comp = (float_p ? "%F0" : "%C0");
2556 /* The operand-printing string for the inverted comparison. */
2557 const char *inverted_comp = (float_p ? "%W0" : "%N0");
2559 /* Likely variants of each branch instruction annul the instruction
2560 in the delay slot if the branch is not taken. */
2561 iq2000_branch_likely = (final_sequence && INSN_ANNULLED_BRANCH_P (insn));
2563 if (!two_operands_p)
2565 /* To compute whether than A > B, for example, we normally
2566 subtract B from A and then look at the sign bit. But, if we
2567 are doing an unsigned comparison, and B is zero, we don't
2568 have to do the subtraction. Instead, we can just check to
2569 see if A is nonzero. Thus, we change the CODE here to
2570 reflect the simpler comparison operation. */
2582 /* A condition which will always be true. */
2588 /* A condition which will always be false. */
2594 /* Not a special case. */
2599 /* Relative comparisons are always done against zero. But
2600 equality comparisons are done between two operands, and therefore
2601 do not require a `z' in the assembly language output. */
2602 need_z_p = (!float_p && code != EQ && code != NE);
2603 /* For comparisons against zero, the zero is not provided
2608 /* Begin by terminating the buffer. That way we can always use
2609 strcat to add to it. */
2616 /* Just a simple conditional branch. */
2618 sprintf (buffer, "b%s%%?\t%%Z2%%1",
2619 inverted_p ? inverted_comp : comp);
2621 sprintf (buffer, "b%s%s%%?\t%s%s,%%1",
2622 inverted_p ? inverted_comp : comp,
2623 need_z_p ? "z" : "",
2631 /* Generate a reversed conditional branch around ` j'
2643 Because we have to jump four bytes *past* the following
2644 instruction if this branch was annulled, we can't just use
2645 a label, as in the picture above; there's no way to put the
2646 label after the next instruction, as the assembler does not
2647 accept `.L+4' as the target of a branch. (We can't just
2648 wait until the next instruction is output; it might be a
2649 macro and take up more than four bytes. Once again, we see
2650 why we want to eliminate macros.)
2652 If the branch is annulled, we jump four more bytes that we
2653 would otherwise; that way we skip the annulled instruction
2654 in the delay slot. */
2657 = ((iq2000_branch_likely || length == 16) ? ".+16" : ".+12");
2660 c = strchr (buffer, '\0');
2661 /* Generate the reversed comparison. This takes four
2664 sprintf (c, "b%s\t%%Z2%s",
2665 inverted_p ? comp : inverted_comp,
2668 sprintf (c, "b%s%s\t%s%s,%s",
2669 inverted_p ? comp : inverted_comp,
2670 need_z_p ? "z" : "",
2674 strcat (c, "\n\tnop\n\tj\t%1");
2676 /* The delay slot was unfilled. Since we're inside
2677 .noreorder, the assembler will not fill in the NOP for
2678 us, so we must do it ourselves. */
2679 strcat (buffer, "\n\tnop");
2691 #define def_builtin(NAME, TYPE, CODE) \
2692 builtin_function ((NAME), (TYPE), (CODE), BUILT_IN_MD, NULL, NULL_TREE)
2695 iq2000_init_builtins (void)
2697 tree endlink = void_list_node;
2698 tree void_ftype, void_ftype_int, void_ftype_int_int;
2699 tree void_ftype_int_int_int;
2700 tree int_ftype_int, int_ftype_int_int, int_ftype_int_int_int;
2701 tree int_ftype_int_int_int_int;
2705 = build_function_type (void_type_node,
2706 tree_cons (NULL_TREE, void_type_node, endlink));
2710 = build_function_type (void_type_node,
2711 tree_cons (NULL_TREE, integer_type_node, endlink));
2713 /* void func (int, int) */
2715 = build_function_type (void_type_node,
2716 tree_cons (NULL_TREE, integer_type_node,
2717 tree_cons (NULL_TREE, integer_type_node,
2720 /* int func (int) */
2722 = build_function_type (integer_type_node,
2723 tree_cons (NULL_TREE, integer_type_node, endlink));
2725 /* int func (int, int) */
2727 = build_function_type (integer_type_node,
2728 tree_cons (NULL_TREE, integer_type_node,
2729 tree_cons (NULL_TREE, integer_type_node,
2732 /* void func (int, int, int) */
2733 void_ftype_int_int_int
2734 = build_function_type
2736 tree_cons (NULL_TREE, integer_type_node,
2737 tree_cons (NULL_TREE, integer_type_node,
2738 tree_cons (NULL_TREE,
2742 /* int func (int, int, int, int) */
2743 int_ftype_int_int_int_int
2744 = build_function_type
2746 tree_cons (NULL_TREE, integer_type_node,
2747 tree_cons (NULL_TREE, integer_type_node,
2748 tree_cons (NULL_TREE,
2750 tree_cons (NULL_TREE,
2754 /* int func (int, int, int) */
2755 int_ftype_int_int_int
2756 = build_function_type
2758 tree_cons (NULL_TREE, integer_type_node,
2759 tree_cons (NULL_TREE, integer_type_node,
2760 tree_cons (NULL_TREE,
2764 /* int func (int, int, int, int) */
2765 int_ftype_int_int_int_int
2766 = build_function_type
2768 tree_cons (NULL_TREE, integer_type_node,
2769 tree_cons (NULL_TREE, integer_type_node,
2770 tree_cons (NULL_TREE,
2772 tree_cons (NULL_TREE,
2776 def_builtin ("__builtin_ado16", int_ftype_int_int, IQ2000_BUILTIN_ADO16);
2777 def_builtin ("__builtin_ram", int_ftype_int_int_int_int, IQ2000_BUILTIN_RAM);
2778 def_builtin ("__builtin_chkhdr", void_ftype_int_int, IQ2000_BUILTIN_CHKHDR);
2779 def_builtin ("__builtin_pkrl", void_ftype_int_int, IQ2000_BUILTIN_PKRL);
2780 def_builtin ("__builtin_cfc0", int_ftype_int, IQ2000_BUILTIN_CFC0);
2781 def_builtin ("__builtin_cfc1", int_ftype_int, IQ2000_BUILTIN_CFC1);
2782 def_builtin ("__builtin_cfc2", int_ftype_int, IQ2000_BUILTIN_CFC2);
2783 def_builtin ("__builtin_cfc3", int_ftype_int, IQ2000_BUILTIN_CFC3);
2784 def_builtin ("__builtin_ctc0", void_ftype_int_int, IQ2000_BUILTIN_CTC0);
2785 def_builtin ("__builtin_ctc1", void_ftype_int_int, IQ2000_BUILTIN_CTC1);
2786 def_builtin ("__builtin_ctc2", void_ftype_int_int, IQ2000_BUILTIN_CTC2);
2787 def_builtin ("__builtin_ctc3", void_ftype_int_int, IQ2000_BUILTIN_CTC3);
2788 def_builtin ("__builtin_mfc0", int_ftype_int, IQ2000_BUILTIN_MFC0);
2789 def_builtin ("__builtin_mfc1", int_ftype_int, IQ2000_BUILTIN_MFC1);
2790 def_builtin ("__builtin_mfc2", int_ftype_int, IQ2000_BUILTIN_MFC2);
2791 def_builtin ("__builtin_mfc3", int_ftype_int, IQ2000_BUILTIN_MFC3);
2792 def_builtin ("__builtin_mtc0", void_ftype_int_int, IQ2000_BUILTIN_MTC0);
2793 def_builtin ("__builtin_mtc1", void_ftype_int_int, IQ2000_BUILTIN_MTC1);
2794 def_builtin ("__builtin_mtc2", void_ftype_int_int, IQ2000_BUILTIN_MTC2);
2795 def_builtin ("__builtin_mtc3", void_ftype_int_int, IQ2000_BUILTIN_MTC3);
2796 def_builtin ("__builtin_lur", void_ftype_int_int, IQ2000_BUILTIN_LUR);
2797 def_builtin ("__builtin_rb", void_ftype_int_int, IQ2000_BUILTIN_RB);
2798 def_builtin ("__builtin_rx", void_ftype_int_int, IQ2000_BUILTIN_RX);
2799 def_builtin ("__builtin_srrd", void_ftype_int, IQ2000_BUILTIN_SRRD);
2800 def_builtin ("__builtin_srwr", void_ftype_int_int, IQ2000_BUILTIN_SRWR);
2801 def_builtin ("__builtin_wb", void_ftype_int_int, IQ2000_BUILTIN_WB);
2802 def_builtin ("__builtin_wx", void_ftype_int_int, IQ2000_BUILTIN_WX);
2803 def_builtin ("__builtin_luc32l", void_ftype_int_int, IQ2000_BUILTIN_LUC32L);
2804 def_builtin ("__builtin_luc64", void_ftype_int_int, IQ2000_BUILTIN_LUC64);
2805 def_builtin ("__builtin_luc64l", void_ftype_int_int, IQ2000_BUILTIN_LUC64L);
2806 def_builtin ("__builtin_luk", void_ftype_int_int, IQ2000_BUILTIN_LUK);
2807 def_builtin ("__builtin_lulck", void_ftype_int, IQ2000_BUILTIN_LULCK);
2808 def_builtin ("__builtin_lum32", void_ftype_int_int, IQ2000_BUILTIN_LUM32);
2809 def_builtin ("__builtin_lum32l", void_ftype_int_int, IQ2000_BUILTIN_LUM32L);
2810 def_builtin ("__builtin_lum64", void_ftype_int_int, IQ2000_BUILTIN_LUM64);
2811 def_builtin ("__builtin_lum64l", void_ftype_int_int, IQ2000_BUILTIN_LUM64L);
2812 def_builtin ("__builtin_lurl", void_ftype_int_int, IQ2000_BUILTIN_LURL);
2813 def_builtin ("__builtin_mrgb", int_ftype_int_int_int, IQ2000_BUILTIN_MRGB);
2814 def_builtin ("__builtin_srrdl", void_ftype_int, IQ2000_BUILTIN_SRRDL);
2815 def_builtin ("__builtin_srulck", void_ftype_int, IQ2000_BUILTIN_SRULCK);
2816 def_builtin ("__builtin_srwru", void_ftype_int_int, IQ2000_BUILTIN_SRWRU);
2817 def_builtin ("__builtin_trapqfl", void_ftype, IQ2000_BUILTIN_TRAPQFL);
2818 def_builtin ("__builtin_trapqne", void_ftype, IQ2000_BUILTIN_TRAPQNE);
2819 def_builtin ("__builtin_traprel", void_ftype_int, IQ2000_BUILTIN_TRAPREL);
2820 def_builtin ("__builtin_wbu", void_ftype_int_int_int, IQ2000_BUILTIN_WBU);
2821 def_builtin ("__builtin_syscall", void_ftype, IQ2000_BUILTIN_SYSCALL);
2824 /* Builtin for ICODE having ARGCOUNT args in ARGLIST where each arg
2828 expand_one_builtin (enum insn_code icode, rtx target, tree arglist,
2829 enum rtx_code *code, int argcount)
2834 enum machine_mode mode [5];
2837 mode[0] = insn_data[icode].operand[0].mode;
2838 for (i = 0; i < argcount; i++)
2840 arg[i] = TREE_VALUE (arglist);
2841 arglist = TREE_CHAIN (arglist);
2842 op[i] = expand_expr (arg[i], NULL_RTX, VOIDmode, 0);
2843 mode[i] = insn_data[icode].operand[i].mode;
2844 if (code[i] == CONST_INT && GET_CODE (op[i]) != CONST_INT)
2845 error ("argument `%d' is not a constant", i + 1);
2847 && ! (*insn_data[icode].operand[i].predicate) (op[i], mode[i]))
2848 op[i] = copy_to_mode_reg (mode[i], op[i]);
2851 if (insn_data[icode].operand[0].constraint[0] == '=')
2854 || GET_MODE (target) != mode[0]
2855 || ! (*insn_data[icode].operand[0].predicate) (target, mode[0]))
2856 target = gen_reg_rtx (mode[0]);
2864 pat = GEN_FCN (icode) (target);
2867 pat = GEN_FCN (icode) (target, op[0]);
2869 pat = GEN_FCN (icode) (op[0]);
2873 pat = GEN_FCN (icode) (target, op[0], op[1]);
2875 pat = GEN_FCN (icode) (op[0], op[1]);
2879 pat = GEN_FCN (icode) (target, op[0], op[1], op[2]);
2881 pat = GEN_FCN (icode) (op[0], op[1], op[2]);
2885 pat = GEN_FCN (icode) (target, op[0], op[1], op[2], op[3]);
2887 pat = GEN_FCN (icode) (op[0], op[1], op[2], op[3]);
2899 /* Expand an expression EXP that calls a built-in function,
2900 with result going to TARGET if that's convenient
2901 (and in mode MODE if that's convenient).
2902 SUBTARGET may be used as the target for computing one of EXP's operands.
2903 IGNORE is nonzero if the value is to be ignored. */
2906 iq2000_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED,
2907 enum machine_mode mode ATTRIBUTE_UNUSED,
2908 int ignore ATTRIBUTE_UNUSED)
2910 tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
2911 tree arglist = TREE_OPERAND (exp, 1);
2912 int fcode = DECL_FUNCTION_CODE (fndecl);
2913 enum rtx_code code [5];
2925 case IQ2000_BUILTIN_ADO16:
2926 return expand_one_builtin (CODE_FOR_ado16, target, arglist, code, 2);
2928 case IQ2000_BUILTIN_RAM:
2929 code[1] = CONST_INT;
2930 code[2] = CONST_INT;
2931 code[3] = CONST_INT;
2932 return expand_one_builtin (CODE_FOR_ram, target, arglist, code, 4);
2934 case IQ2000_BUILTIN_CHKHDR:
2935 return expand_one_builtin (CODE_FOR_chkhdr, target, arglist, code, 2);
2937 case IQ2000_BUILTIN_PKRL:
2938 return expand_one_builtin (CODE_FOR_pkrl, target, arglist, code, 2);
2940 case IQ2000_BUILTIN_CFC0:
2941 code[0] = CONST_INT;
2942 return expand_one_builtin (CODE_FOR_cfc0, target, arglist, code, 1);
2944 case IQ2000_BUILTIN_CFC1:
2945 code[0] = CONST_INT;
2946 return expand_one_builtin (CODE_FOR_cfc1, target, arglist, code, 1);
2948 case IQ2000_BUILTIN_CFC2:
2949 code[0] = CONST_INT;
2950 return expand_one_builtin (CODE_FOR_cfc2, target, arglist, code, 1);
2952 case IQ2000_BUILTIN_CFC3:
2953 code[0] = CONST_INT;
2954 return expand_one_builtin (CODE_FOR_cfc3, target, arglist, code, 1);
2956 case IQ2000_BUILTIN_CTC0:
2957 code[1] = CONST_INT;
2958 return expand_one_builtin (CODE_FOR_ctc0, target, arglist, code, 2);
2960 case IQ2000_BUILTIN_CTC1:
2961 code[1] = CONST_INT;
2962 return expand_one_builtin (CODE_FOR_ctc1, target, arglist, code, 2);
2964 case IQ2000_BUILTIN_CTC2:
2965 code[1] = CONST_INT;
2966 return expand_one_builtin (CODE_FOR_ctc2, target, arglist, code, 2);
2968 case IQ2000_BUILTIN_CTC3:
2969 code[1] = CONST_INT;
2970 return expand_one_builtin (CODE_FOR_ctc3, target, arglist, code, 2);
2972 case IQ2000_BUILTIN_MFC0:
2973 code[0] = CONST_INT;
2974 return expand_one_builtin (CODE_FOR_mfc0, target, arglist, code, 1);
2976 case IQ2000_BUILTIN_MFC1:
2977 code[0] = CONST_INT;
2978 return expand_one_builtin (CODE_FOR_mfc1, target, arglist, code, 1);
2980 case IQ2000_BUILTIN_MFC2:
2981 code[0] = CONST_INT;
2982 return expand_one_builtin (CODE_FOR_mfc2, target, arglist, code, 1);
2984 case IQ2000_BUILTIN_MFC3:
2985 code[0] = CONST_INT;
2986 return expand_one_builtin (CODE_FOR_mfc3, target, arglist, code, 1);
2988 case IQ2000_BUILTIN_MTC0:
2989 code[1] = CONST_INT;
2990 return expand_one_builtin (CODE_FOR_mtc0, target, arglist, code, 2);
2992 case IQ2000_BUILTIN_MTC1:
2993 code[1] = CONST_INT;
2994 return expand_one_builtin (CODE_FOR_mtc1, target, arglist, code, 2);
2996 case IQ2000_BUILTIN_MTC2:
2997 code[1] = CONST_INT;
2998 return expand_one_builtin (CODE_FOR_mtc2, target, arglist, code, 2);
3000 case IQ2000_BUILTIN_MTC3:
3001 code[1] = CONST_INT;
3002 return expand_one_builtin (CODE_FOR_mtc3, target, arglist, code, 2);
3004 case IQ2000_BUILTIN_LUR:
3005 return expand_one_builtin (CODE_FOR_lur, target, arglist, code, 2);
3007 case IQ2000_BUILTIN_RB:
3008 return expand_one_builtin (CODE_FOR_rb, target, arglist, code, 2);
3010 case IQ2000_BUILTIN_RX:
3011 return expand_one_builtin (CODE_FOR_rx, target, arglist, code, 2);
3013 case IQ2000_BUILTIN_SRRD:
3014 return expand_one_builtin (CODE_FOR_srrd, target, arglist, code, 1);
3016 case IQ2000_BUILTIN_SRWR:
3017 return expand_one_builtin (CODE_FOR_srwr, target, arglist, code, 2);
3019 case IQ2000_BUILTIN_WB:
3020 return expand_one_builtin (CODE_FOR_wb, target, arglist, code, 2);
3022 case IQ2000_BUILTIN_WX:
3023 return expand_one_builtin (CODE_FOR_wx, target, arglist, code, 2);
3025 case IQ2000_BUILTIN_LUC32L:
3026 return expand_one_builtin (CODE_FOR_luc32l, target, arglist, code, 2);
3028 case IQ2000_BUILTIN_LUC64:
3029 return expand_one_builtin (CODE_FOR_luc64, target, arglist, code, 2);
3031 case IQ2000_BUILTIN_LUC64L:
3032 return expand_one_builtin (CODE_FOR_luc64l, target, arglist, code, 2);
3034 case IQ2000_BUILTIN_LUK:
3035 return expand_one_builtin (CODE_FOR_luk, target, arglist, code, 2);
3037 case IQ2000_BUILTIN_LULCK:
3038 return expand_one_builtin (CODE_FOR_lulck, target, arglist, code, 1);
3040 case IQ2000_BUILTIN_LUM32:
3041 return expand_one_builtin (CODE_FOR_lum32, target, arglist, code, 2);
3043 case IQ2000_BUILTIN_LUM32L:
3044 return expand_one_builtin (CODE_FOR_lum32l, target, arglist, code, 2);
3046 case IQ2000_BUILTIN_LUM64:
3047 return expand_one_builtin (CODE_FOR_lum64, target, arglist, code, 2);
3049 case IQ2000_BUILTIN_LUM64L:
3050 return expand_one_builtin (CODE_FOR_lum64l, target, arglist, code, 2);
3052 case IQ2000_BUILTIN_LURL:
3053 return expand_one_builtin (CODE_FOR_lurl, target, arglist, code, 2);
3055 case IQ2000_BUILTIN_MRGB:
3056 code[2] = CONST_INT;
3057 return expand_one_builtin (CODE_FOR_mrgb, target, arglist, code, 3);
3059 case IQ2000_BUILTIN_SRRDL:
3060 return expand_one_builtin (CODE_FOR_srrdl, target, arglist, code, 1);
3062 case IQ2000_BUILTIN_SRULCK:
3063 return expand_one_builtin (CODE_FOR_srulck, target, arglist, code, 1);
3065 case IQ2000_BUILTIN_SRWRU:
3066 return expand_one_builtin (CODE_FOR_srwru, target, arglist, code, 2);
3068 case IQ2000_BUILTIN_TRAPQFL:
3069 return expand_one_builtin (CODE_FOR_trapqfl, target, arglist, code, 0);
3071 case IQ2000_BUILTIN_TRAPQNE:
3072 return expand_one_builtin (CODE_FOR_trapqne, target, arglist, code, 0);
3074 case IQ2000_BUILTIN_TRAPREL:
3075 return expand_one_builtin (CODE_FOR_traprel, target, arglist, code, 1);
3077 case IQ2000_BUILTIN_WBU:
3078 return expand_one_builtin (CODE_FOR_wbu, target, arglist, code, 3);
3080 case IQ2000_BUILTIN_SYSCALL:
3081 return expand_one_builtin (CODE_FOR_syscall, target, arglist, code, 0);
3087 /* Worker function for TARGET_RETURN_IN_MEMORY. */
3090 iq2000_return_in_memory (tree type, tree fntype ATTRIBUTE_UNUSED)
3092 return ((int_size_in_bytes (type) > (2 * UNITS_PER_WORD))
3093 || (int_size_in_bytes (type) == -1));
3096 /* Worker function for TARGET_SETUP_INCOMING_VARARGS. */
3099 iq2000_setup_incoming_varargs (CUMULATIVE_ARGS *cum,
3100 enum machine_mode mode ATTRIBUTE_UNUSED,
3101 tree type ATTRIBUTE_UNUSED, int * pretend_size,
3104 unsigned int iq2000_off = ! cum->last_arg_fp;
3105 unsigned int iq2000_fp_off = cum->last_arg_fp;
3107 if ((cum->arg_words < MAX_ARGS_IN_REGISTERS - iq2000_off))
3109 int iq2000_save_gp_regs
3110 = MAX_ARGS_IN_REGISTERS - cum->arg_words - iq2000_off;
3111 int iq2000_save_fp_regs
3112 = (MAX_ARGS_IN_REGISTERS - cum->fp_arg_words - iq2000_fp_off);
3114 if (iq2000_save_gp_regs < 0)
3115 iq2000_save_gp_regs = 0;
3116 if (iq2000_save_fp_regs < 0)
3117 iq2000_save_fp_regs = 0;
3119 *pretend_size = ((iq2000_save_gp_regs * UNITS_PER_WORD)
3120 + (iq2000_save_fp_regs * UNITS_PER_FPREG));
3124 if (cum->arg_words < MAX_ARGS_IN_REGISTERS - iq2000_off)
3127 ptr = plus_constant (virtual_incoming_args_rtx,
3128 - (iq2000_save_gp_regs
3130 mem = gen_rtx_MEM (BLKmode, ptr);
3132 (cum->arg_words + GP_ARG_FIRST + iq2000_off,
3134 iq2000_save_gp_regs);
3140 /* A C compound statement to output to stdio stream STREAM the
3141 assembler syntax for an instruction operand that is a memory
3142 reference whose address is ADDR. ADDR is an RTL expression. */
3145 print_operand_address (FILE * file, rtx addr)
3148 error ("PRINT_OPERAND_ADDRESS, null pointer");
3151 switch (GET_CODE (addr))
3154 if (REGNO (addr) == ARG_POINTER_REGNUM)
3155 abort_with_insn (addr, "Arg pointer not eliminated.");
3157 fprintf (file, "0(%s)", reg_names [REGNO (addr)]);
3162 rtx arg0 = XEXP (addr, 0);
3163 rtx arg1 = XEXP (addr, 1);
3165 if (GET_CODE (arg0) != REG)
3166 abort_with_insn (addr,
3167 "PRINT_OPERAND_ADDRESS, LO_SUM with #1 not REG.");
3169 fprintf (file, "%%lo(");
3170 print_operand_address (file, arg1);
3171 fprintf (file, ")(%s)", reg_names [REGNO (arg0)]);
3179 rtx arg0 = XEXP (addr, 0);
3180 rtx arg1 = XEXP (addr, 1);
3182 if (GET_CODE (arg0) == REG)
3186 if (GET_CODE (offset) == REG)
3187 abort_with_insn (addr, "PRINT_OPERAND_ADDRESS, 2 regs");
3190 else if (GET_CODE (arg1) == REG)
3191 reg = arg1, offset = arg0;
3192 else if (CONSTANT_P (arg0) && CONSTANT_P (arg1))
3194 output_addr_const (file, addr);
3198 abort_with_insn (addr, "PRINT_OPERAND_ADDRESS, no regs");
3200 if (! CONSTANT_P (offset))
3201 abort_with_insn (addr, "PRINT_OPERAND_ADDRESS, invalid insn #2");
3203 if (REGNO (reg) == ARG_POINTER_REGNUM)
3204 abort_with_insn (addr, "Arg pointer not eliminated.");
3206 output_addr_const (file, offset);
3207 fprintf (file, "(%s)", reg_names [REGNO (reg)]);
3215 output_addr_const (file, addr);
3216 if (GET_CODE (addr) == CONST_INT)
3217 fprintf (file, "(%s)", reg_names [0]);
3221 abort_with_insn (addr, "PRINT_OPERAND_ADDRESS, invalid insn #1");
3226 /* A C compound statement to output to stdio stream FILE the
3227 assembler syntax for an instruction operand OP.
3229 LETTER is a value that can be used to specify one of several ways
3230 of printing the operand. It is used when identical operands
3231 must be printed differently depending on the context. LETTER
3232 comes from the `%' specification that was used to request
3233 printing of the operand. If the specification was just `%DIGIT'
3234 then LETTER is 0; if the specification was `%LTR DIGIT' then LETTER
3235 is the ASCII code for LTR.
3237 If OP is a register, this macro should print the register's name.
3238 The names can be found in an array `reg_names' whose type is
3239 `char *[]'. `reg_names' is initialized from `REGISTER_NAMES'.
3241 When the machine description has a specification `%PUNCT' (a `%'
3242 followed by a punctuation character), this macro is called with
3243 a null pointer for X and the punctuation character for LETTER.
3245 The IQ2000 specific codes are:
3247 'X' X is CONST_INT, prints upper 16 bits in hexadecimal format = "0x%04x",
3248 'x' X is CONST_INT, prints lower 16 bits in hexadecimal format = "0x%04x",
3249 'd' output integer constant in decimal,
3250 'z' if the operand is 0, use $0 instead of normal operand.
3251 'D' print second part of double-word register or memory operand.
3252 'L' print low-order register of double-word register operand.
3253 'M' print high-order register of double-word register operand.
3254 'C' print part of opcode for a branch condition.
3255 'F' print part of opcode for a floating-point branch condition.
3256 'N' print part of opcode for a branch condition, inverted.
3257 'W' print part of opcode for a floating-point branch condition, inverted.
3258 'A' Print part of opcode for a bit test condition.
3259 'P' Print label for a bit test.
3260 'p' Print log for a bit test.
3261 'B' print 'z' for EQ, 'n' for NE
3262 'b' print 'n' for EQ, 'z' for NE
3263 'T' print 'f' for EQ, 't' for NE
3264 't' print 't' for EQ, 'f' for NE
3265 'Z' print register and a comma, but print nothing for $fcc0
3266 '?' Print 'l' if we are to use a branch likely instead of normal branch.
3267 '@' Print the name of the assembler temporary register (at or $1).
3268 '.' Print the name of the register with a hard-wired zero (zero or $0).
3269 '$' Print the name of the stack pointer register (sp or $29).
3270 '+' Print the name of the gp register (gp or $28). */
3273 print_operand (FILE *file, rtx op, int letter)
3277 if (PRINT_OPERAND_PUNCT_VALID_P (letter))
3282 if (iq2000_branch_likely)
3287 fputs (reg_names [GP_REG_FIRST + 1], file);
3291 fputs (reg_names [GP_REG_FIRST + 0], file);
3295 fputs (reg_names[STACK_POINTER_REGNUM], file);
3299 fputs (reg_names[GP_REG_FIRST + 28], file);
3303 error ("PRINT_OPERAND: Unknown punctuation '%c'", letter);
3312 error ("PRINT_OPERAND null pointer");
3316 code = GET_CODE (op);
3318 if (code == SIGN_EXTEND)
3319 op = XEXP (op, 0), code = GET_CODE (op);
3324 case EQ: fputs ("eq", file); break;
3325 case NE: fputs ("ne", file); break;
3326 case GT: fputs ("gt", file); break;
3327 case GE: fputs ("ge", file); break;
3328 case LT: fputs ("lt", file); break;
3329 case LE: fputs ("le", file); break;
3330 case GTU: fputs ("ne", file); break;
3331 case GEU: fputs ("geu", file); break;
3332 case LTU: fputs ("ltu", file); break;
3333 case LEU: fputs ("eq", file); break;
3335 abort_with_insn (op, "PRINT_OPERAND, invalid insn for %%C");
3338 else if (letter == 'N')
3341 case EQ: fputs ("ne", file); break;
3342 case NE: fputs ("eq", file); break;
3343 case GT: fputs ("le", file); break;
3344 case GE: fputs ("lt", file); break;
3345 case LT: fputs ("ge", file); break;
3346 case LE: fputs ("gt", file); break;
3347 case GTU: fputs ("leu", file); break;
3348 case GEU: fputs ("ltu", file); break;
3349 case LTU: fputs ("geu", file); break;
3350 case LEU: fputs ("gtu", file); break;
3352 abort_with_insn (op, "PRINT_OPERAND, invalid insn for %%N");
3355 else if (letter == 'F')
3358 case EQ: fputs ("c1f", file); break;
3359 case NE: fputs ("c1t", file); break;
3361 abort_with_insn (op, "PRINT_OPERAND, invalid insn for %%F");
3364 else if (letter == 'W')
3367 case EQ: fputs ("c1t", file); break;
3368 case NE: fputs ("c1f", file); break;
3370 abort_with_insn (op, "PRINT_OPERAND, invalid insn for %%W");
3373 else if (letter == 'A')
3374 fputs (code == LABEL_REF ? "i" : "in", file);
3376 else if (letter == 'P')
3378 if (code == LABEL_REF)
3379 output_addr_const (file, op);
3380 else if (code != PC)
3381 output_operand_lossage ("invalid %%P operand");
3384 else if (letter == 'p')
3387 if (code != CONST_INT
3388 || (value = exact_log2 (INTVAL (op))) < 0)
3389 output_operand_lossage ("invalid %%p value");
3390 fprintf (file, "%d", value);
3393 else if (letter == 'Z')
3400 regnum = REGNO (op);
3403 fprintf (file, "%s,", reg_names[regnum]);
3406 else if (code == REG || code == SUBREG)
3411 regnum = REGNO (op);
3413 regnum = true_regnum (op);
3415 if ((letter == 'M' && ! WORDS_BIG_ENDIAN)
3416 || (letter == 'L' && WORDS_BIG_ENDIAN)
3420 fprintf (file, "%s", reg_names[regnum]);
3423 else if (code == MEM)
3426 output_address (plus_constant (XEXP (op, 0), 4));
3428 output_address (XEXP (op, 0));
3431 else if (code == CONST_DOUBLE
3432 && GET_MODE_CLASS (GET_MODE (op)) == MODE_FLOAT)
3436 real_to_decimal (s, CONST_DOUBLE_REAL_VALUE (op), sizeof (s), 0, 1);
3440 else if (letter == 'x' && GET_CODE (op) == CONST_INT)
3441 fprintf (file, HOST_WIDE_INT_PRINT_HEX, 0xffff & INTVAL(op));
3443 else if (letter == 'X' && GET_CODE(op) == CONST_INT)
3444 fprintf (file, HOST_WIDE_INT_PRINT_HEX, 0xffff & (INTVAL (op) >> 16));
3446 else if (letter == 'd' && GET_CODE(op) == CONST_INT)
3447 fprintf (file, HOST_WIDE_INT_PRINT_DEC, (INTVAL(op)));
3449 else if (letter == 'z' && GET_CODE (op) == CONST_INT && INTVAL (op) == 0)
3450 fputs (reg_names[GP_REG_FIRST], file);
3452 else if (letter == 'd' || letter == 'x' || letter == 'X')
3453 output_operand_lossage ("invalid use of %%d, %%x, or %%X");
3455 else if (letter == 'B')
3456 fputs (code == EQ ? "z" : "n", file);
3457 else if (letter == 'b')
3458 fputs (code == EQ ? "n" : "z", file);
3459 else if (letter == 'T')
3460 fputs (code == EQ ? "f" : "t", file);
3461 else if (letter == 't')
3462 fputs (code == EQ ? "t" : "f", file);
3464 else if (code == CONST && GET_CODE (XEXP (op, 0)) == REG)
3466 print_operand (file, XEXP (op, 0), letter);
3470 output_addr_const (file, op);
3474 iq2000_rtx_costs (rtx x, int code, int outer_code ATTRIBUTE_UNUSED, int * total)
3476 enum machine_mode mode = GET_MODE (x);
3482 int num_words = (GET_MODE_SIZE (mode) > UNITS_PER_WORD) ? 2 : 1;
3484 if (simple_memory_operand (x, mode))
3485 return COSTS_N_INSNS (num_words);
3487 * total = COSTS_N_INSNS (2 * num_words);
3492 * total = COSTS_N_INSNS (6);
3499 * total = COSTS_N_INSNS (mode == DImode ? 2 : 1);
3506 * total = COSTS_N_INSNS ((GET_CODE (XEXP (x, 1)) == CONST_INT) ? 4 : 12);
3508 * total = COSTS_N_INSNS (1);
3512 if (mode == SFmode || mode == DFmode)
3513 * total = COSTS_N_INSNS (1);
3515 * total = COSTS_N_INSNS (4);
3520 if (mode == SFmode || mode == DFmode)
3521 * total = COSTS_N_INSNS (6);
3522 else if (mode == DImode)
3523 * total = COSTS_N_INSNS (4);
3525 * total = COSTS_N_INSNS (1);
3529 * total = (mode == DImode) ? 4 : 1;
3534 * total = COSTS_N_INSNS (7);
3535 else if (mode == DFmode)
3536 * total = COSTS_N_INSNS (8);
3538 * total = COSTS_N_INSNS (10);
3544 * total = COSTS_N_INSNS (23);
3545 else if (mode == DFmode)
3546 * total = COSTS_N_INSNS (36);
3548 * total = COSTS_N_INSNS (69);
3553 * total = COSTS_N_INSNS (69);
3557 * total = COSTS_N_INSNS (2);
3561 * total = COSTS_N_INSNS (1);
3569 * total = COSTS_N_INSNS (2);
3574 rtx offset = const0_rtx;
3575 rtx symref = eliminate_constant_term (XEXP (x, 0), & offset);
3577 if (GET_CODE (symref) == LABEL_REF)
3578 * total = COSTS_N_INSNS (2);
3579 else if (GET_CODE (symref) != SYMBOL_REF)
3580 * total = COSTS_N_INSNS (4);
3581 /* Let's be paranoid.... */
3582 else if (INTVAL (offset) < -32768 || INTVAL (offset) > 32767)
3583 * total = COSTS_N_INSNS (2);
3585 * total = COSTS_N_INSNS (SYMBOL_REF_FLAG (symref) ? 1 : 2);
3590 * total = COSTS_N_INSNS (SYMBOL_REF_FLAG (x) ? 1 : 2);
3597 split_double (x, & high, & low);
3599 * total = COSTS_N_INSNS ( (high == CONST0_RTX (GET_MODE (high))
3600 || low == CONST0_RTX (GET_MODE (low)))
3611 #include "gt-iq2000.h"