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);
174 static tree iq2000_gimplify_va_arg_expr (tree, tree, tree *, tree *);
176 #undef TARGET_INIT_BUILTINS
177 #define TARGET_INIT_BUILTINS iq2000_init_builtins
178 #undef TARGET_EXPAND_BUILTIN
179 #define TARGET_EXPAND_BUILTIN iq2000_expand_builtin
180 #undef TARGET_ASM_SELECT_RTX_SECTION
181 #define TARGET_ASM_SELECT_RTX_SECTION iq2000_select_rtx_section
182 #undef TARGET_RTX_COSTS
183 #define TARGET_RTX_COSTS iq2000_rtx_costs
184 #undef TARGET_ADDRESS_COST
185 #define TARGET_ADDRESS_COST iq2000_address_cost
186 #undef TARGET_ASM_SELECT_SECTION
187 #define TARGET_ASM_SELECT_SECTION iq2000_select_section
189 #undef TARGET_PROMOTE_FUNCTION_ARGS
190 #define TARGET_PROMOTE_FUNCTION_ARGS hook_bool_tree_true
191 #undef TARGET_PROMOTE_FUNCTION_RETURN
192 #define TARGET_PROMOTE_FUNCTION_RETURN hook_bool_tree_true
193 #undef TARGET_PROMOTE_PROTOTYPES
194 #define TARGET_PROMOTE_PROTOTYPES hook_bool_tree_true
196 #undef TARGET_RETURN_IN_MEMORY
197 #define TARGET_RETURN_IN_MEMORY iq2000_return_in_memory
199 #undef TARGET_SETUP_INCOMING_VARARGS
200 #define TARGET_SETUP_INCOMING_VARARGS iq2000_setup_incoming_varargs
201 #undef TARGET_STRICT_ARGUMENT_NAMING
202 #define TARGET_STRICT_ARGUMENT_NAMING hook_bool_CUMULATIVE_ARGS_true
203 #undef TARGET_GIMPLIFY_VA_ARG_EXPR
204 #define TARGET_GIMPLIFY_VA_ARG_EXPR iq2000_gimplify_va_arg_expr
206 #undef TARGET_SCHED_USE_DFA_PIPELINE_INTERFACE
207 #define TARGET_SCHED_USE_DFA_PIPELINE_INTERFACE hook_int_void_1
209 struct gcc_target targetm = TARGET_INITIALIZER;
211 /* Return 1 if OP can be used as an operand where a register or 16 bit unsigned
212 integer is needed. */
215 uns_arith_operand (rtx op, enum machine_mode mode)
217 if (GET_CODE (op) == CONST_INT && SMALL_INT_UNSIGNED (op))
220 return register_operand (op, mode);
223 /* Return 1 if OP can be used as an operand where a 16 bit integer is needed. */
226 arith_operand (rtx op, enum machine_mode mode)
228 if (GET_CODE (op) == CONST_INT && SMALL_INT (op))
231 return register_operand (op, mode);
234 /* Return 1 if OP is a integer which fits in 16 bits. */
237 small_int (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
239 return (GET_CODE (op) == CONST_INT && SMALL_INT (op));
242 /* Return 1 if OP is a 32 bit integer which is too big to be loaded with one
246 large_int (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
250 if (GET_CODE (op) != CONST_INT)
255 /* IOR reg,$r0,value. */
256 if ((value & ~ ((HOST_WIDE_INT) 0x0000ffff)) == 0)
259 /* SUBU reg,$r0,value. */
260 if (((unsigned HOST_WIDE_INT) (value + 32768)) <= 32767)
263 /* LUI reg,value >> 16. */
264 if ((value & 0x0000ffff) == 0)
270 /* Return 1 if OP is a register or the constant 0. */
273 reg_or_0_operand (rtx op, enum machine_mode mode)
275 switch (GET_CODE (op))
278 return INTVAL (op) == 0;
281 return op == CONST0_RTX (mode);
285 return register_operand (op, mode);
294 /* Return 1 if OP is a memory operand that fits in a single instruction
295 (ie, register + small offset). */
298 simple_memory_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
300 rtx addr, plus0, plus1;
302 /* Eliminate non-memory operations. */
303 if (GET_CODE (op) != MEM)
306 /* Dword operations really put out 2 instructions, so eliminate them. */
307 if (GET_MODE_SIZE (GET_MODE (op)) > (unsigned) UNITS_PER_WORD)
310 /* Decode the address now. */
312 switch (GET_CODE (addr))
319 return SMALL_INT (addr);
322 plus0 = XEXP (addr, 0);
323 plus1 = XEXP (addr, 1);
324 if (GET_CODE (plus0) == REG
325 && GET_CODE (plus1) == CONST_INT && SMALL_INT (plus1)
326 && SMALL_INT_UNSIGNED (plus1) /* No negative offsets. */)
329 else if (GET_CODE (plus1) == REG
330 && GET_CODE (plus0) == CONST_INT && SMALL_INT (plus0)
331 && SMALL_INT_UNSIGNED (plus1) /* No negative offsets. */)
347 /* Return nonzero if the code of this rtx pattern is EQ or NE. */
350 equality_op (rtx op, enum machine_mode mode)
352 if (mode != GET_MODE (op))
355 return GET_CODE (op) == EQ || GET_CODE (op) == NE;
358 /* Return nonzero if the code is a relational operations (EQ, LE, etc). */
361 cmp_op (rtx op, enum machine_mode mode)
363 if (mode != GET_MODE (op))
366 return COMPARISON_P (op);
369 /* Return nonzero if the operand is either the PC or a label_ref. */
372 pc_or_label_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
377 if (GET_CODE (op) == LABEL_REF)
383 /* Return nonzero if OP is a valid operand for a call instruction. */
386 call_insn_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
388 return (CONSTANT_ADDRESS_P (op)
389 || (GET_CODE (op) == REG && op != arg_pointer_rtx
390 && ! (REGNO (op) >= FIRST_PSEUDO_REGISTER
391 && REGNO (op) <= LAST_VIRTUAL_REGISTER)));
394 /* Return nonzero if OP is valid as a source operand for a move instruction. */
397 move_operand (rtx op, enum machine_mode mode)
399 /* Accept any general operand after reload has started; doing so
400 avoids losing if reload does an in-place replacement of a register
401 with a SYMBOL_REF or CONST. */
402 return (general_operand (op, mode)
403 && (! (iq2000_check_split (op, mode))
404 || reload_in_progress || reload_completed));
407 /* Return nonzero if OP is a constant power of 2. */
410 power_of_2_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
414 if (GET_CODE (op) != CONST_INT)
417 intval = INTVAL (op);
419 return ((intval & ((unsigned)(intval) - 1)) == 0);
422 /* Return nonzero if we split the address into high and low parts. */
425 iq2000_check_split (rtx address, enum machine_mode mode)
427 /* This is the same check used in simple_memory_operand.
428 We use it here because LO_SUM is not offsettable. */
429 if (GET_MODE_SIZE (mode) > (unsigned) UNITS_PER_WORD)
432 if ((GET_CODE (address) == SYMBOL_REF)
433 || (GET_CODE (address) == CONST
434 && GET_CODE (XEXP (XEXP (address, 0), 0)) == SYMBOL_REF)
435 || GET_CODE (address) == LABEL_REF)
441 /* Return nonzero if REG is valid for MODE. */
444 iq2000_reg_mode_ok_for_base_p (rtx reg,
445 enum machine_mode mode ATTRIBUTE_UNUSED,
449 ? REGNO_MODE_OK_FOR_BASE_P (REGNO (reg), mode)
450 : GP_REG_OR_PSEUDO_NONSTRICT_P (REGNO (reg), mode));
453 /* Return a nonzero value if XINSN is a legitimate address for a
454 memory operand of the indicated MODE. STRICT is nonzero if this
455 function is called during reload. */
458 iq2000_legitimate_address_p (enum machine_mode mode, rtx xinsn, int strict)
460 if (TARGET_DEBUG_A_MODE)
462 GO_PRINTF2 ("\n========== GO_IF_LEGITIMATE_ADDRESS, %sstrict\n",
463 strict ? "" : "not ");
464 GO_DEBUG_RTX (xinsn);
467 /* Check for constant before stripping off SUBREG, so that we don't
468 accept (subreg (const_int)) which will fail to reload. */
469 if (CONSTANT_ADDRESS_P (xinsn)
470 && ! (iq2000_check_split (xinsn, mode))
471 && ! (GET_CODE (xinsn) == CONST_INT && ! SMALL_INT (xinsn)))
474 while (GET_CODE (xinsn) == SUBREG)
475 xinsn = SUBREG_REG (xinsn);
477 if (GET_CODE (xinsn) == REG
478 && iq2000_reg_mode_ok_for_base_p (xinsn, mode, strict))
481 if (GET_CODE (xinsn) == LO_SUM)
483 rtx xlow0 = XEXP (xinsn, 0);
484 rtx xlow1 = XEXP (xinsn, 1);
486 while (GET_CODE (xlow0) == SUBREG)
487 xlow0 = SUBREG_REG (xlow0);
488 if (GET_CODE (xlow0) == REG
489 && iq2000_reg_mode_ok_for_base_p (xlow0, mode, strict)
490 && iq2000_check_split (xlow1, mode))
494 if (GET_CODE (xinsn) == PLUS)
496 rtx xplus0 = XEXP (xinsn, 0);
497 rtx xplus1 = XEXP (xinsn, 1);
501 while (GET_CODE (xplus0) == SUBREG)
502 xplus0 = SUBREG_REG (xplus0);
503 code0 = GET_CODE (xplus0);
505 while (GET_CODE (xplus1) == SUBREG)
506 xplus1 = SUBREG_REG (xplus1);
507 code1 = GET_CODE (xplus1);
510 && iq2000_reg_mode_ok_for_base_p (xplus0, mode, strict))
512 if (code1 == CONST_INT && SMALL_INT (xplus1)
513 && SMALL_INT_UNSIGNED (xplus1) /* No negative offsets */)
518 if (TARGET_DEBUG_A_MODE)
519 GO_PRINTF ("Not a legitimate address\n");
521 /* The address was not legitimate. */
525 /* Returns an operand string for the given instruction's delay slot,
526 after updating filled delay slot statistics.
528 We assume that operands[0] is the target register that is set.
530 In order to check the next insn, most of this functionality is moved
531 to FINAL_PRESCAN_INSN, and we just set the global variables that
535 iq2000_fill_delay_slot (const char *ret, enum delay_type type, rtx operands[],
539 enum machine_mode mode;
540 rtx next_insn = cur_insn ? NEXT_INSN (cur_insn) : NULL_RTX;
543 if (type == DELAY_LOAD || type == DELAY_FCMP)
549 /* Make sure that we don't put nop's after labels. */
550 next_insn = NEXT_INSN (cur_insn);
551 while (next_insn != 0
552 && (GET_CODE (next_insn) == NOTE
553 || GET_CODE (next_insn) == CODE_LABEL))
554 next_insn = NEXT_INSN (next_insn);
556 dslots_load_total += num_nops;
557 if (TARGET_DEBUG_C_MODE
558 || type == DELAY_NONE
562 || GET_CODE (next_insn) == CODE_LABEL
563 || (set_reg = operands[0]) == 0)
565 dslots_number_nops = 0;
567 iq2000_load_reg2 = 0;
568 iq2000_load_reg3 = 0;
569 iq2000_load_reg4 = 0;
574 set_reg = operands[0];
578 while (GET_CODE (set_reg) == SUBREG)
579 set_reg = SUBREG_REG (set_reg);
581 mode = GET_MODE (set_reg);
582 dslots_number_nops = num_nops;
583 iq2000_load_reg = set_reg;
584 if (GET_MODE_SIZE (mode)
585 > (unsigned) (UNITS_PER_WORD))
586 iq2000_load_reg2 = gen_rtx_REG (SImode, REGNO (set_reg) + 1);
588 iq2000_load_reg2 = 0;
593 /* Determine whether a memory reference takes one (based off of the GP
594 pointer), two (normal), or three (label + reg) instructions, and bump the
595 appropriate counter for -mstats. */
598 iq2000_count_memory_refs (rtx op, int num)
602 rtx addr, plus0, plus1;
603 enum rtx_code code0, code1;
606 if (TARGET_DEBUG_B_MODE)
608 fprintf (stderr, "\n========== iq2000_count_memory_refs:\n");
612 /* Skip MEM if passed, otherwise handle movsi of address. */
613 addr = (GET_CODE (op) != MEM) ? op : XEXP (op, 0);
615 /* Loop, going through the address RTL. */
619 switch (GET_CODE (addr))
627 plus0 = XEXP (addr, 0);
628 plus1 = XEXP (addr, 1);
629 code0 = GET_CODE (plus0);
630 code1 = GET_CODE (plus1);
640 if (code0 == CONST_INT)
655 if (code1 == CONST_INT)
662 if (code0 == SYMBOL_REF || code0 == LABEL_REF || code0 == CONST)
669 if (code1 == SYMBOL_REF || code1 == LABEL_REF || code1 == CONST)
679 n_words = 2; /* Always 2 words. */
683 addr = XEXP (addr, 0);
688 n_words = SYMBOL_REF_FLAG (addr) ? 1 : 2;
700 n_words += additional;
704 num_refs[n_words-1] += num;
707 /* Abort after printing out a specific insn. */
710 abort_with_insn (rtx insn, const char * reason)
717 /* Return the appropriate instructions to move one operand to another. */
720 iq2000_move_1word (rtx operands[], rtx insn, int unsignedp)
723 rtx op0 = operands[0];
724 rtx op1 = operands[1];
725 enum rtx_code code0 = GET_CODE (op0);
726 enum rtx_code code1 = GET_CODE (op1);
727 enum machine_mode mode = GET_MODE (op0);
728 int subreg_offset0 = 0;
729 int subreg_offset1 = 0;
730 enum delay_type delay = DELAY_NONE;
732 while (code0 == SUBREG)
734 subreg_offset0 += subreg_regno_offset (REGNO (SUBREG_REG (op0)),
735 GET_MODE (SUBREG_REG (op0)),
738 op0 = SUBREG_REG (op0);
739 code0 = GET_CODE (op0);
742 while (code1 == SUBREG)
744 subreg_offset1 += subreg_regno_offset (REGNO (SUBREG_REG (op1)),
745 GET_MODE (SUBREG_REG (op1)),
748 op1 = SUBREG_REG (op1);
749 code1 = GET_CODE (op1);
752 /* For our purposes, a condition code mode is the same as SImode. */
758 int regno0 = REGNO (op0) + subreg_offset0;
762 int regno1 = REGNO (op1) + subreg_offset1;
764 /* Do not do anything for assigning a register to itself */
765 if (regno0 == regno1)
768 else if (GP_REG_P (regno0))
770 if (GP_REG_P (regno1))
771 ret = "or\t%0,%%0,%1";
776 else if (code1 == MEM)
781 iq2000_count_memory_refs (op1, 1);
783 if (GP_REG_P (regno0))
785 /* For loads, use the mode of the memory item, instead of the
786 target, so zero/sign extend can use this code as well. */
787 switch (GET_MODE (op1))
799 ret = (unsignedp) ? "lhu\t%0,%1" : "lh\t%0,%1";
802 ret = (unsignedp) ? "lbu\t%0,%1" : "lb\t%0,%1";
808 else if (code1 == CONST_INT
809 || (code1 == CONST_DOUBLE
810 && GET_MODE (op1) == VOIDmode))
812 if (code1 == CONST_DOUBLE)
814 /* This can happen when storing constants into long long
815 bitfields. Just store the least significant word of
817 operands[1] = op1 = GEN_INT (CONST_DOUBLE_LOW (op1));
820 if (INTVAL (op1) == 0)
822 if (GP_REG_P (regno0))
823 ret = "or\t%0,%%0,%z1";
825 else if (GP_REG_P (regno0))
827 if (SMALL_INT_UNSIGNED (op1))
828 ret = "ori\t%0,%%0,%x1\t\t\t# %1";
829 else if (SMALL_INT (op1))
830 ret = "addiu\t%0,%%0,%1\t\t\t# %1";
832 ret = "lui\t%0,%X1\t\t\t# %1\n\tori\t%0,%0,%x1";
836 else if (code1 == CONST_DOUBLE && mode == SFmode)
838 if (op1 == CONST0_RTX (SFmode))
840 if (GP_REG_P (regno0))
841 ret = "or\t%0,%%0,%.";
851 else if (code1 == LABEL_REF)
854 iq2000_count_memory_refs (op1, 1);
859 else if (code1 == SYMBOL_REF || code1 == CONST)
862 iq2000_count_memory_refs (op1, 1);
867 else if (code1 == PLUS)
869 rtx add_op0 = XEXP (op1, 0);
870 rtx add_op1 = XEXP (op1, 1);
872 if (GET_CODE (XEXP (op1, 1)) == REG
873 && GET_CODE (XEXP (op1, 0)) == CONST_INT)
874 add_op0 = XEXP (op1, 1), add_op1 = XEXP (op1, 0);
876 operands[2] = add_op0;
877 operands[3] = add_op1;
878 ret = "add%:\t%0,%2,%3";
881 else if (code1 == HIGH)
883 operands[1] = XEXP (op1, 0);
884 ret = "lui\t%0,%%hi(%1)";
888 else if (code0 == MEM)
891 iq2000_count_memory_refs (op0, 1);
895 int regno1 = REGNO (op1) + subreg_offset1;
897 if (GP_REG_P (regno1))
901 case SFmode: ret = "sw\t%1,%0"; break;
902 case SImode: ret = "sw\t%1,%0"; break;
903 case HImode: ret = "sh\t%1,%0"; break;
904 case QImode: ret = "sb\t%1,%0"; break;
910 else if (code1 == CONST_INT && INTVAL (op1) == 0)
914 case SFmode: ret = "sw\t%z1,%0"; break;
915 case SImode: ret = "sw\t%z1,%0"; break;
916 case HImode: ret = "sh\t%z1,%0"; break;
917 case QImode: ret = "sb\t%z1,%0"; break;
922 else if (code1 == CONST_DOUBLE && op1 == CONST0_RTX (mode))
926 case SFmode: ret = "sw\t%.,%0"; break;
927 case SImode: ret = "sw\t%.,%0"; break;
928 case HImode: ret = "sh\t%.,%0"; break;
929 case QImode: ret = "sb\t%.,%0"; break;
937 abort_with_insn (insn, "Bad move");
941 if (delay != DELAY_NONE)
942 return iq2000_fill_delay_slot (ret, delay, operands, insn);
947 /* Provide the costs of an addressing mode that contains ADDR. */
950 iq2000_address_cost (rtx addr)
952 switch (GET_CODE (addr))
962 rtx offset = const0_rtx;
964 addr = eliminate_constant_term (XEXP (addr, 0), & offset);
965 if (GET_CODE (addr) == LABEL_REF)
968 if (GET_CODE (addr) != SYMBOL_REF)
971 if (! SMALL_INT (offset))
978 return SYMBOL_REF_FLAG (addr) ? 1 : 2;
982 rtx plus0 = XEXP (addr, 0);
983 rtx plus1 = XEXP (addr, 1);
985 if (GET_CODE (plus0) != REG && GET_CODE (plus1) == REG)
986 plus0 = XEXP (addr, 1), plus1 = XEXP (addr, 0);
988 if (GET_CODE (plus0) != REG)
991 switch (GET_CODE (plus1))
994 return SMALL_INT (plus1) ? 1 : 2;
1001 return iq2000_address_cost (plus1) + 1;
1015 /* Make normal rtx_code into something we can index from an array. */
1017 static enum internal_test
1018 map_test_to_internal_test (enum rtx_code test_code)
1020 enum internal_test test = ITEST_MAX;
1024 case EQ: test = ITEST_EQ; break;
1025 case NE: test = ITEST_NE; break;
1026 case GT: test = ITEST_GT; break;
1027 case GE: test = ITEST_GE; break;
1028 case LT: test = ITEST_LT; break;
1029 case LE: test = ITEST_LE; break;
1030 case GTU: test = ITEST_GTU; break;
1031 case GEU: test = ITEST_GEU; break;
1032 case LTU: test = ITEST_LTU; break;
1033 case LEU: test = ITEST_LEU; break;
1040 /* Generate the code to do a TEST_CODE comparison on two integer values CMP0
1041 and CMP1. P_INVERT is NULL or ptr if branch needs to reverse its test.
1042 The return value RESULT is:
1043 (reg:SI xx) The pseudo register the comparison is in
1044 0 No register, generate a simple branch. */
1047 gen_int_relational (enum rtx_code test_code, rtx result, rtx cmp0, rtx cmp1,
1052 enum rtx_code test_code; /* Code to use in instruction (LT vs. LTU). */
1053 int const_low; /* Low bound of constant we can accept. */
1054 int const_high; /* High bound of constant we can accept. */
1055 int const_add; /* Constant to add (convert LE -> LT). */
1056 int reverse_regs; /* Reverse registers in test. */
1057 int invert_const; /* != 0 if invert value if cmp1 is constant. */
1058 int invert_reg; /* != 0 if invert value if cmp1 is register. */
1059 int unsignedp; /* != 0 for unsigned comparisons. */
1062 static struct cmp_info info[ (int)ITEST_MAX ] =
1064 { XOR, 0, 65535, 0, 0, 0, 0, 0 }, /* EQ */
1065 { XOR, 0, 65535, 0, 0, 1, 1, 0 }, /* NE */
1066 { LT, -32769, 32766, 1, 1, 1, 0, 0 }, /* GT */
1067 { LT, -32768, 32767, 0, 0, 1, 1, 0 }, /* GE */
1068 { LT, -32768, 32767, 0, 0, 0, 0, 0 }, /* LT */
1069 { LT, -32769, 32766, 1, 1, 0, 1, 0 }, /* LE */
1070 { LTU, -32769, 32766, 1, 1, 1, 0, 1 }, /* GTU */
1071 { LTU, -32768, 32767, 0, 0, 1, 1, 1 }, /* GEU */
1072 { LTU, -32768, 32767, 0, 0, 0, 0, 1 }, /* LTU */
1073 { LTU, -32769, 32766, 1, 1, 0, 1, 1 }, /* LEU */
1076 enum internal_test test;
1077 enum machine_mode mode;
1078 struct cmp_info *p_info;
1085 test = map_test_to_internal_test (test_code);
1086 if (test == ITEST_MAX)
1089 p_info = &info[(int) test];
1090 eqne_p = (p_info->test_code == XOR);
1092 mode = GET_MODE (cmp0);
1093 if (mode == VOIDmode)
1094 mode = GET_MODE (cmp1);
1096 /* Eliminate simple branches. */
1097 branch_p = (result == 0);
1100 if (GET_CODE (cmp0) == REG || GET_CODE (cmp0) == SUBREG)
1102 /* Comparisons against zero are simple branches. */
1103 if (GET_CODE (cmp1) == CONST_INT && INTVAL (cmp1) == 0)
1106 /* Test for beq/bne. */
1111 /* Allocate a pseudo to calculate the value in. */
1112 result = gen_reg_rtx (mode);
1115 /* Make sure we can handle any constants given to us. */
1116 if (GET_CODE (cmp0) == CONST_INT)
1117 cmp0 = force_reg (mode, cmp0);
1119 if (GET_CODE (cmp1) == CONST_INT)
1121 HOST_WIDE_INT value = INTVAL (cmp1);
1123 if (value < p_info->const_low
1124 || value > p_info->const_high)
1125 cmp1 = force_reg (mode, cmp1);
1128 /* See if we need to invert the result. */
1129 invert = (GET_CODE (cmp1) == CONST_INT
1130 ? p_info->invert_const : p_info->invert_reg);
1132 if (p_invert != (int *)0)
1138 /* Comparison to constants, may involve adding 1 to change a LT into LE.
1139 Comparison between two registers, may involve switching operands. */
1140 if (GET_CODE (cmp1) == CONST_INT)
1142 if (p_info->const_add != 0)
1144 HOST_WIDE_INT new = INTVAL (cmp1) + p_info->const_add;
1146 /* If modification of cmp1 caused overflow,
1147 we would get the wrong answer if we follow the usual path;
1148 thus, x > 0xffffffffU would turn into x > 0U. */
1149 if ((p_info->unsignedp
1150 ? (unsigned HOST_WIDE_INT) new >
1151 (unsigned HOST_WIDE_INT) INTVAL (cmp1)
1152 : new > INTVAL (cmp1))
1153 != (p_info->const_add > 0))
1155 /* This test is always true, but if INVERT is true then
1156 the result of the test needs to be inverted so 0 should
1157 be returned instead. */
1158 emit_move_insn (result, invert ? const0_rtx : const_true_rtx);
1162 cmp1 = GEN_INT (new);
1166 else if (p_info->reverse_regs)
1173 if (test == ITEST_NE && GET_CODE (cmp1) == CONST_INT && INTVAL (cmp1) == 0)
1177 reg = (invert || eqne_p) ? gen_reg_rtx (mode) : result;
1178 convert_move (reg, gen_rtx_fmt_ee (p_info->test_code, mode, cmp0, cmp1), 0);
1181 if (test == ITEST_NE)
1183 convert_move (result, gen_rtx_GTU (mode, reg, const0_rtx), 0);
1184 if (p_invert != NULL)
1189 else if (test == ITEST_EQ)
1191 reg2 = invert ? gen_reg_rtx (mode) : result;
1192 convert_move (reg2, gen_rtx_LTU (mode, reg, const1_rtx), 0);
1201 convert_move (result, gen_rtx_XOR (mode, reg, one), 0);
1207 /* Emit the common code for doing conditional branches.
1208 operand[0] is the label to jump to.
1209 The comparison operands are saved away by cmp{si,di,sf,df}. */
1212 gen_conditional_branch (rtx operands[], enum rtx_code test_code)
1214 enum cmp_type type = branch_type;
1215 rtx cmp0 = branch_cmp[0];
1216 rtx cmp1 = branch_cmp[1];
1217 enum machine_mode mode;
1226 mode = type == CMP_SI ? SImode : DImode;
1228 reg = gen_int_relational (test_code, NULL_RTX, cmp0, cmp1, &invert);
1236 else if (GET_CODE (cmp1) == CONST_INT && INTVAL (cmp1) != 0)
1237 /* We don't want to build a comparison against a nonzero
1239 cmp1 = force_reg (mode, cmp1);
1245 reg = gen_reg_rtx (CCmode);
1247 /* For cmp0 != cmp1, build cmp0 == cmp1, and test for result == 0. */
1248 emit_insn (gen_rtx_SET (VOIDmode, reg,
1249 gen_rtx_fmt_ee (test_code == NE ? EQ : test_code,
1250 CCmode, cmp0, cmp1)));
1252 test_code = test_code == NE ? EQ : NE;
1260 abort_with_insn (gen_rtx_fmt_ee (test_code, VOIDmode, cmp0, cmp1),
1264 /* Generate the branch. */
1265 label1 = gen_rtx_LABEL_REF (VOIDmode, operands[0]);
1274 emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
1275 gen_rtx_IF_THEN_ELSE (VOIDmode,
1276 gen_rtx_fmt_ee (test_code,
1282 /* Initialize CUM for a function FNTYPE. */
1285 init_cumulative_args (CUMULATIVE_ARGS *cum, tree fntype,
1286 rtx libname ATTRIBUTE_UNUSED)
1288 static CUMULATIVE_ARGS zero_cum;
1292 if (TARGET_DEBUG_D_MODE)
1295 "\ninit_cumulative_args, fntype = 0x%.8lx", (long) fntype);
1298 fputc ('\n', stderr);
1302 tree ret_type = TREE_TYPE (fntype);
1304 fprintf (stderr, ", fntype code = %s, ret code = %s\n",
1305 tree_code_name[(int)TREE_CODE (fntype)],
1306 tree_code_name[(int)TREE_CODE (ret_type)]);
1312 /* Determine if this function has variable arguments. This is
1313 indicated by the last argument being 'void_type_mode' if there
1314 are no variable arguments. The standard IQ2000 calling sequence
1315 passes all arguments in the general purpose registers in this case. */
1317 for (param = fntype ? TYPE_ARG_TYPES (fntype) : 0;
1318 param != 0; param = next_param)
1320 next_param = TREE_CHAIN (param);
1321 if (next_param == 0 && TREE_VALUE (param) != void_type_node)
1322 cum->gp_reg_found = 1;
1326 /* Advance the argument of type TYPE and mode MODE to the next argument
1330 function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode, tree type,
1333 if (TARGET_DEBUG_D_MODE)
1336 "function_adv({gp reg found = %d, arg # = %2d, words = %2d}, %4s, ",
1337 cum->gp_reg_found, cum->arg_number, cum->arg_words,
1338 GET_MODE_NAME (mode));
1339 fprintf (stderr, HOST_PTR_PRINTF, (const PTR) type);
1340 fprintf (stderr, ", %d )\n\n", named);
1350 if (GET_MODE_CLASS (mode) != MODE_COMPLEX_INT
1351 && GET_MODE_CLASS (mode) != MODE_COMPLEX_FLOAT)
1354 cum->gp_reg_found = 1;
1355 cum->arg_words += ((GET_MODE_SIZE (mode) + UNITS_PER_WORD - 1)
1360 cum->gp_reg_found = 1;
1361 cum->arg_words += ((int_size_in_bytes (type) + UNITS_PER_WORD - 1)
1367 if (! cum->gp_reg_found && cum->arg_number <= 2)
1368 cum->fp_code += 1 << ((cum->arg_number - 1) * 2);
1372 cum->arg_words += 2;
1373 if (! cum->gp_reg_found && cum->arg_number <= 2)
1374 cum->fp_code += 2 << ((cum->arg_number - 1) * 2);
1378 cum->gp_reg_found = 1;
1379 cum->arg_words += 2;
1385 cum->gp_reg_found = 1;
1391 /* Return an RTL expression containing the register for the given mode MODE
1392 and type TYPE in CUM, or 0 if the argument is to be passed on the stack. */
1395 function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode, tree type,
1401 unsigned int *arg_words = &cum->arg_words;
1402 int struct_p = (type != 0
1403 && (TREE_CODE (type) == RECORD_TYPE
1404 || TREE_CODE (type) == UNION_TYPE
1405 || TREE_CODE (type) == QUAL_UNION_TYPE));
1407 if (TARGET_DEBUG_D_MODE)
1410 "function_arg( {gp reg found = %d, arg # = %2d, words = %2d}, %4s, ",
1411 cum->gp_reg_found, cum->arg_number, cum->arg_words,
1412 GET_MODE_NAME (mode));
1413 fprintf (stderr, HOST_PTR_PRINTF, (const PTR) type);
1414 fprintf (stderr, ", %d ) = ", named);
1418 cum->last_arg_fp = 0;
1422 regbase = GP_ARG_FIRST;
1426 cum->arg_words += cum->arg_words & 1;
1428 regbase = GP_ARG_FIRST;
1432 if (GET_MODE_CLASS (mode) != MODE_COMPLEX_INT
1433 && GET_MODE_CLASS (mode) != MODE_COMPLEX_FLOAT)
1436 /* Drops through. */
1438 if (type != NULL_TREE && TYPE_ALIGN (type) > (unsigned) BITS_PER_WORD)
1439 cum->arg_words += (cum->arg_words & 1);
1440 regbase = GP_ARG_FIRST;
1447 regbase = GP_ARG_FIRST;
1451 cum->arg_words += (cum->arg_words & 1);
1452 regbase = GP_ARG_FIRST;
1455 if (*arg_words >= (unsigned) MAX_ARGS_IN_REGISTERS)
1457 if (TARGET_DEBUG_D_MODE)
1458 fprintf (stderr, "<stack>%s\n", struct_p ? ", [struct]" : "");
1467 if (! type || TREE_CODE (type) != RECORD_TYPE
1468 || ! named || ! TYPE_SIZE_UNIT (type)
1469 || ! host_integerp (TYPE_SIZE_UNIT (type), 1))
1470 ret = gen_rtx_REG (mode, regbase + *arg_words + bias);
1475 for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field))
1476 if (TREE_CODE (field) == FIELD_DECL
1477 && TREE_CODE (TREE_TYPE (field)) == REAL_TYPE
1478 && TYPE_PRECISION (TREE_TYPE (field)) == BITS_PER_WORD
1479 && host_integerp (bit_position (field), 0)
1480 && int_bit_position (field) % BITS_PER_WORD == 0)
1483 /* If the whole struct fits a DFmode register,
1484 we don't need the PARALLEL. */
1485 if (! field || mode == DFmode)
1486 ret = gen_rtx_REG (mode, regbase + *arg_words + bias);
1489 unsigned int chunks;
1490 HOST_WIDE_INT bitpos;
1494 /* ??? If this is a packed structure, then the last hunk won't
1497 = tree_low_cst (TYPE_SIZE_UNIT (type), 1) / UNITS_PER_WORD;
1498 if (chunks + *arg_words + bias > (unsigned) MAX_ARGS_IN_REGISTERS)
1499 chunks = MAX_ARGS_IN_REGISTERS - *arg_words - bias;
1501 /* Assign_parms checks the mode of ENTRY_PARM, so we must
1502 use the actual mode here. */
1503 ret = gen_rtx_PARALLEL (mode, rtvec_alloc (chunks));
1506 regno = regbase + *arg_words + bias;
1507 field = TYPE_FIELDS (type);
1508 for (i = 0; i < chunks; i++)
1512 for (; field; field = TREE_CHAIN (field))
1513 if (TREE_CODE (field) == FIELD_DECL
1514 && int_bit_position (field) >= bitpos)
1518 && int_bit_position (field) == bitpos
1519 && TREE_CODE (TREE_TYPE (field)) == REAL_TYPE
1520 && TYPE_PRECISION (TREE_TYPE (field)) == BITS_PER_WORD)
1521 reg = gen_rtx_REG (DFmode, regno++);
1523 reg = gen_rtx_REG (word_mode, regno);
1526 = gen_rtx_EXPR_LIST (VOIDmode, reg,
1527 GEN_INT (bitpos / BITS_PER_UNIT));
1535 if (TARGET_DEBUG_D_MODE)
1536 fprintf (stderr, "%s%s\n", reg_names[regbase + *arg_words + bias],
1537 struct_p ? ", [struct]" : "");
1540 /* We will be called with a mode of VOIDmode after the last argument
1541 has been seen. Whatever we return will be passed to the call
1542 insn. If we need any shifts for small structures, return them in
1544 if (mode == VOIDmode)
1546 if (cum->num_adjusts > 0)
1547 ret = gen_rtx_PARALLEL ((enum machine_mode) cum->fp_code,
1548 gen_rtvec_v (cum->num_adjusts, cum->adjust));
1555 function_arg_partial_nregs (CUMULATIVE_ARGS *cum, enum machine_mode mode,
1556 tree type ATTRIBUTE_UNUSED,
1557 int named ATTRIBUTE_UNUSED)
1560 && cum->arg_words == MAX_ARGS_IN_REGISTERS - (unsigned)1)
1562 if (TARGET_DEBUG_D_MODE)
1563 fprintf (stderr, "function_arg_partial_nregs = 1\n");
1571 /* Implement va_start. */
1574 iq2000_va_start (tree valist, rtx nextarg)
1577 /* Find out how many non-float named formals. */
1578 int gpr_save_area_size;
1579 /* Note UNITS_PER_WORD is 4 bytes. */
1580 int_arg_words = current_function_args_info.arg_words;
1582 if (int_arg_words < 8 )
1583 /* Adjust for the prologue's economy measure. */
1584 gpr_save_area_size = (8 - int_arg_words) * UNITS_PER_WORD;
1586 gpr_save_area_size = 0;
1588 /* Everything is in the GPR save area, or in the overflow
1589 area which is contiguous with it. */
1590 nextarg = plus_constant (nextarg, - gpr_save_area_size);
1591 std_expand_builtin_va_start (valist, nextarg);
1594 /* Implement va_arg. */
1597 iq2000_gimplify_va_arg_expr (tree valist, tree type, tree *pre_p, tree *post_p)
1599 if (function_arg_pass_by_reference (NULL, TYPE_MODE (type), type, 0))
1600 return ind_gimplify_va_arg_expr (valist, type, pre_p, post_p);
1602 return std_gimplify_va_arg_expr (valist, type, pre_p, post_p);
1605 /* Allocate a chunk of memory for per-function machine-dependent data. */
1607 static struct machine_function *
1608 iq2000_init_machine_status (void)
1610 struct machine_function *f;
1612 f = ggc_alloc_cleared (sizeof (struct machine_function));
1617 static enum processor_type
1618 iq2000_parse_cpu (const char * cpu_string)
1620 const char *p = cpu_string;
1621 enum processor_type cpu;
1623 cpu = PROCESSOR_DEFAULT;
1627 if (!strcmp (p, "iq10"))
1628 cpu = PROCESSOR_IQ10;
1631 if (!strcmp (p, "iq2000"))
1632 cpu = PROCESSOR_IQ2000;
1639 /* Detect any conflicts in the switches. */
1642 override_options (void)
1644 enum processor_type iq2000_cpu;
1646 target_flags &= ~MASK_GPOPT;
1648 iq2000_isa = IQ2000_ISA_DEFAULT;
1650 /* Identify the processor type. */
1652 if (iq2000_cpu_string != 0)
1654 iq2000_cpu = iq2000_parse_cpu (iq2000_cpu_string);
1655 if (iq2000_cpu == PROCESSOR_DEFAULT)
1657 error ("bad value (%s) for -mcpu= switch", iq2000_arch_string);
1658 iq2000_cpu_string = "default";
1660 iq2000_arch = iq2000_cpu;
1661 iq2000_tune = iq2000_cpu;
1664 if (iq2000_arch_string == 0
1665 || ! strcmp (iq2000_arch_string, "default")
1666 || ! strcmp (iq2000_arch_string, "DEFAULT"))
1671 iq2000_arch_string = "iq2000";
1672 iq2000_arch = PROCESSOR_IQ2000;
1678 iq2000_arch = iq2000_parse_cpu (iq2000_arch_string);
1679 if (iq2000_arch == PROCESSOR_DEFAULT)
1681 error ("bad value (%s) for -march= switch", iq2000_arch_string);
1682 iq2000_arch_string = "default";
1684 if (iq2000_arch == PROCESSOR_IQ10)
1686 error ("The compiler does not support -march=%s.", iq2000_arch_string);
1687 iq2000_arch_string = "default";
1691 iq2000_print_operand_punct['?'] = 1;
1692 iq2000_print_operand_punct['#'] = 1;
1693 iq2000_print_operand_punct['&'] = 1;
1694 iq2000_print_operand_punct['!'] = 1;
1695 iq2000_print_operand_punct['*'] = 1;
1696 iq2000_print_operand_punct['@'] = 1;
1697 iq2000_print_operand_punct['.'] = 1;
1698 iq2000_print_operand_punct['('] = 1;
1699 iq2000_print_operand_punct[')'] = 1;
1700 iq2000_print_operand_punct['['] = 1;
1701 iq2000_print_operand_punct[']'] = 1;
1702 iq2000_print_operand_punct['<'] = 1;
1703 iq2000_print_operand_punct['>'] = 1;
1704 iq2000_print_operand_punct['{'] = 1;
1705 iq2000_print_operand_punct['}'] = 1;
1706 iq2000_print_operand_punct['^'] = 1;
1707 iq2000_print_operand_punct['$'] = 1;
1708 iq2000_print_operand_punct['+'] = 1;
1709 iq2000_print_operand_punct['~'] = 1;
1711 /* Save GPR registers in word_mode sized hunks. word_mode hasn't been
1712 initialized yet, so we can't use that here. */
1715 /* Function to allocate machine-dependent function status. */
1716 init_machine_status = iq2000_init_machine_status;
1719 /* The arg pointer (which is eliminated) points to the virtual frame pointer,
1720 while the frame pointer (which may be eliminated) points to the stack
1721 pointer after the initial adjustments. */
1724 iq2000_debugger_offset (rtx addr, HOST_WIDE_INT offset)
1726 rtx offset2 = const0_rtx;
1727 rtx reg = eliminate_constant_term (addr, & offset2);
1730 offset = INTVAL (offset2);
1732 if (reg == stack_pointer_rtx || reg == frame_pointer_rtx
1733 || reg == hard_frame_pointer_rtx)
1735 HOST_WIDE_INT frame_size = (!cfun->machine->initialized)
1736 ? compute_frame_size (get_frame_size ())
1737 : cfun->machine->total_size;
1739 offset = offset - frame_size;
1745 /* If defined, a C statement to be executed just prior to the output of
1746 assembler code for INSN, to modify the extracted operands so they will be
1749 Here the argument OPVEC is the vector containing the operands extracted
1750 from INSN, and NOPERANDS is the number of elements of the vector which
1751 contain meaningful data for this insn. The contents of this vector are
1752 what will be used to convert the insn template into assembler code, so you
1753 can change the assembler output by changing the contents of the vector.
1755 We use it to check if the current insn needs a nop in front of it because
1756 of load delays, and also to update the delay slot statistics. */
1759 final_prescan_insn (rtx insn, rtx opvec[] ATTRIBUTE_UNUSED,
1760 int noperands ATTRIBUTE_UNUSED)
1762 if (dslots_number_nops > 0)
1764 rtx pattern = PATTERN (insn);
1765 int length = get_attr_length (insn);
1767 /* Do we need to emit a NOP? */
1769 || (iq2000_load_reg != 0 && reg_mentioned_p (iq2000_load_reg, pattern))
1770 || (iq2000_load_reg2 != 0 && reg_mentioned_p (iq2000_load_reg2, pattern))
1771 || (iq2000_load_reg3 != 0 && reg_mentioned_p (iq2000_load_reg3, pattern))
1772 || (iq2000_load_reg4 != 0
1773 && reg_mentioned_p (iq2000_load_reg4, pattern)))
1774 fputs ("\tnop\n", asm_out_file);
1777 dslots_load_filled ++;
1779 while (--dslots_number_nops > 0)
1780 fputs ("\tnop\n", asm_out_file);
1782 iq2000_load_reg = 0;
1783 iq2000_load_reg2 = 0;
1784 iq2000_load_reg3 = 0;
1785 iq2000_load_reg4 = 0;
1788 if ( (GET_CODE (insn) == JUMP_INSN
1789 || GET_CODE (insn) == CALL_INSN
1790 || (GET_CODE (PATTERN (insn)) == RETURN))
1791 && NEXT_INSN (PREV_INSN (insn)) == insn)
1793 rtx nop_insn = emit_insn_after (gen_nop (), insn);
1795 INSN_ADDRESSES_NEW (nop_insn, -1);
1799 && (GET_CODE (insn) == JUMP_INSN || GET_CODE (insn) == CALL_INSN))
1800 dslots_jump_total ++;
1803 /* Return the bytes needed to compute the frame pointer from the current
1804 stack pointer where SIZE is the # of var. bytes allocated.
1806 IQ2000 stack frames look like:
1808 Before call After call
1809 +-----------------------+ +-----------------------+
1812 | caller's temps. | | caller's temps. |
1814 +-----------------------+ +-----------------------+
1816 | arguments on stack. | | arguments on stack. |
1818 +-----------------------+ +-----------------------+
1819 | 4 words to save | | 4 words to save |
1820 | arguments passed | | arguments passed |
1821 | in registers, even | | in registers, even |
1822 SP->| if not passed. | VFP->| if not passed. |
1823 +-----------------------+ +-----------------------+
1825 | fp register save |
1827 +-----------------------+
1829 | gp register save |
1831 +-----------------------+
1835 +-----------------------+
1837 | alloca allocations |
1839 +-----------------------+
1841 | GP save for V.4 abi |
1843 +-----------------------+
1845 | arguments on stack |
1847 +-----------------------+
1849 | arguments passed |
1850 | in registers, even |
1851 low SP->| if not passed. |
1852 memory +-----------------------+ */
1855 compute_frame_size (HOST_WIDE_INT size)
1858 HOST_WIDE_INT total_size; /* # bytes that the entire frame takes up. */
1859 HOST_WIDE_INT var_size; /* # bytes that variables take up. */
1860 HOST_WIDE_INT args_size; /* # bytes that outgoing arguments take up. */
1861 HOST_WIDE_INT extra_size; /* # extra bytes. */
1862 HOST_WIDE_INT gp_reg_rounded; /* # bytes needed to store gp after rounding. */
1863 HOST_WIDE_INT gp_reg_size; /* # bytes needed to store gp regs. */
1864 HOST_WIDE_INT fp_reg_size; /* # bytes needed to store fp regs. */
1865 long mask; /* mask of saved gp registers. */
1866 int fp_inc; /* 1 or 2 depending on the size of fp regs. */
1867 long fp_bits; /* bitmask to use for each fp register. */
1872 extra_size = IQ2000_STACK_ALIGN ((0));
1873 var_size = IQ2000_STACK_ALIGN (size);
1874 args_size = IQ2000_STACK_ALIGN (current_function_outgoing_args_size);
1876 /* If a function dynamically allocates the stack and
1877 has 0 for STACK_DYNAMIC_OFFSET then allocate some stack space. */
1878 if (args_size == 0 && current_function_calls_alloca)
1879 args_size = 4 * UNITS_PER_WORD;
1881 total_size = var_size + args_size + extra_size;
1883 /* Calculate space needed for gp registers. */
1884 for (regno = GP_REG_FIRST; regno <= GP_REG_LAST; regno++)
1886 if (MUST_SAVE_REGISTER (regno))
1888 gp_reg_size += GET_MODE_SIZE (gpr_mode);
1889 mask |= 1L << (regno - GP_REG_FIRST);
1893 /* We need to restore these for the handler. */
1894 if (current_function_calls_eh_return)
1900 regno = EH_RETURN_DATA_REGNO (i);
1901 if (regno == (int) INVALID_REGNUM)
1903 gp_reg_size += GET_MODE_SIZE (gpr_mode);
1904 mask |= 1L << (regno - GP_REG_FIRST);
1910 gp_reg_rounded = IQ2000_STACK_ALIGN (gp_reg_size);
1911 total_size += gp_reg_rounded + IQ2000_STACK_ALIGN (fp_reg_size);
1913 /* The gp reg is caller saved, so there is no need for leaf routines
1914 (total_size == extra_size) to save the gp reg. */
1915 if (total_size == extra_size
1917 total_size = extra_size = 0;
1919 total_size += IQ2000_STACK_ALIGN (current_function_pretend_args_size);
1921 /* Save other computed information. */
1922 cfun->machine->total_size = total_size;
1923 cfun->machine->var_size = var_size;
1924 cfun->machine->args_size = args_size;
1925 cfun->machine->extra_size = extra_size;
1926 cfun->machine->gp_reg_size = gp_reg_size;
1927 cfun->machine->fp_reg_size = fp_reg_size;
1928 cfun->machine->mask = mask;
1929 cfun->machine->initialized = reload_completed;
1930 cfun->machine->num_gp = gp_reg_size / UNITS_PER_WORD;
1934 unsigned long offset;
1936 offset = (args_size + extra_size + var_size
1937 + gp_reg_size - GET_MODE_SIZE (gpr_mode));
1939 cfun->machine->gp_sp_offset = offset;
1940 cfun->machine->gp_save_offset = offset - total_size;
1944 cfun->machine->gp_sp_offset = 0;
1945 cfun->machine->gp_save_offset = 0;
1948 cfun->machine->fp_sp_offset = 0;
1949 cfun->machine->fp_save_offset = 0;
1951 /* Ok, we're done. */
1955 /* Implement INITIAL_ELIMINATION_OFFSET. FROM is either the frame
1956 pointer, argument pointer, or return address pointer. TO is either
1957 the stack pointer or hard frame pointer. */
1960 iq2000_initial_elimination_offset (int from, int to ATTRIBUTE_UNUSED)
1964 compute_frame_size (get_frame_size ());
1965 if ((from) == FRAME_POINTER_REGNUM)
1967 else if ((from) == ARG_POINTER_REGNUM)
1968 (offset) = (cfun->machine->total_size);
1969 else if ((from) == RETURN_ADDRESS_POINTER_REGNUM)
1971 if (leaf_function_p ())
1973 else (offset) = cfun->machine->gp_sp_offset
1974 + ((UNITS_PER_WORD - (POINTER_SIZE / BITS_PER_UNIT))
1975 * (BYTES_BIG_ENDIAN != 0));
1981 /* Common code to emit the insns (or to write the instructions to a file)
1982 to save/restore registers.
1983 Other parts of the code assume that IQ2000_TEMP1_REGNUM (aka large_reg)
1984 is not modified within save_restore_insns. */
1986 #define BITSET_P(VALUE,BIT) (((VALUE) & (1L << (BIT))) != 0)
1988 /* Emit instructions to load the value (SP + OFFSET) into IQ2000_TEMP2_REGNUM
1989 and return an rtl expression for the register. Write the assembly
1990 instructions directly to FILE if it is not null, otherwise emit them as
1993 This function is a subroutine of save_restore_insns. It is used when
1994 OFFSET is too large to add in a single instruction. */
1997 iq2000_add_large_offset_to_sp (HOST_WIDE_INT offset)
1999 rtx reg = gen_rtx_REG (Pmode, IQ2000_TEMP2_REGNUM);
2000 rtx offset_rtx = GEN_INT (offset);
2002 emit_move_insn (reg, offset_rtx);
2003 emit_insn (gen_addsi3 (reg, reg, stack_pointer_rtx));
2007 /* Make INSN frame related and note that it performs the frame-related
2008 operation DWARF_PATTERN. */
2011 iq2000_annotate_frame_insn (rtx insn, rtx dwarf_pattern)
2013 RTX_FRAME_RELATED_P (insn) = 1;
2014 REG_NOTES (insn) = alloc_EXPR_LIST (REG_FRAME_RELATED_EXPR,
2019 /* Emit a move instruction that stores REG in MEM. Make the instruction
2020 frame related and note that it stores REG at (SP + OFFSET). */
2023 iq2000_emit_frame_related_store (rtx mem, rtx reg, HOST_WIDE_INT offset)
2025 rtx dwarf_address = plus_constant (stack_pointer_rtx, offset);
2026 rtx dwarf_mem = gen_rtx_MEM (GET_MODE (reg), dwarf_address);
2028 iq2000_annotate_frame_insn (emit_move_insn (mem, reg),
2029 gen_rtx_SET (GET_MODE (reg), dwarf_mem, reg));
2032 /* Emit instructions to save/restore registers, as determined by STORE_P. */
2035 save_restore_insns (int store_p)
2037 long mask = cfun->machine->mask;
2040 HOST_WIDE_INT base_offset;
2041 HOST_WIDE_INT gp_offset;
2042 HOST_WIDE_INT end_offset;
2044 if (frame_pointer_needed
2045 && ! BITSET_P (mask, HARD_FRAME_POINTER_REGNUM - GP_REG_FIRST))
2050 base_reg_rtx = 0, base_offset = 0;
2054 /* Save registers starting from high to low. The debuggers prefer at least
2055 the return register be stored at func+4, and also it allows us not to
2056 need a nop in the epilog if at least one register is reloaded in
2057 addition to return address. */
2059 /* Save GP registers if needed. */
2060 /* Pick which pointer to use as a base register. For small frames, just
2061 use the stack pointer. Otherwise, use a temporary register. Save 2
2062 cycles if the save area is near the end of a large frame, by reusing
2063 the constant created in the prologue/epilogue to adjust the stack
2066 gp_offset = cfun->machine->gp_sp_offset;
2068 = gp_offset - (cfun->machine->gp_reg_size
2069 - GET_MODE_SIZE (gpr_mode));
2071 if (gp_offset < 0 || end_offset < 0)
2073 ("gp_offset (%ld) or end_offset (%ld) is less than zero.",
2074 (long) gp_offset, (long) end_offset);
2076 else if (gp_offset < 32768)
2077 base_reg_rtx = stack_pointer_rtx, base_offset = 0;
2081 int reg_save_count = 0;
2083 for (regno = GP_REG_LAST; regno >= GP_REG_FIRST; regno--)
2084 if (BITSET_P (mask, regno - GP_REG_FIRST)) reg_save_count += 1;
2085 base_offset = gp_offset - ((reg_save_count - 1) * 4);
2086 base_reg_rtx = iq2000_add_large_offset_to_sp (base_offset);
2089 for (regno = GP_REG_LAST; regno >= GP_REG_FIRST; regno--)
2091 if (BITSET_P (mask, regno - GP_REG_FIRST))
2095 = gen_rtx_MEM (gpr_mode,
2096 gen_rtx_PLUS (Pmode, base_reg_rtx,
2097 GEN_INT (gp_offset - base_offset)));
2099 if (! current_function_calls_eh_return)
2100 RTX_UNCHANGING_P (mem_rtx) = 1;
2102 reg_rtx = gen_rtx_REG (gpr_mode, regno);
2105 iq2000_emit_frame_related_store (mem_rtx, reg_rtx, gp_offset);
2108 emit_move_insn (reg_rtx, mem_rtx);
2110 gp_offset -= GET_MODE_SIZE (gpr_mode);
2115 /* Expand the prologue into a bunch of separate insns. */
2118 iq2000_expand_prologue (void)
2121 HOST_WIDE_INT tsize;
2122 int last_arg_is_vararg_marker = 0;
2123 tree fndecl = current_function_decl;
2124 tree fntype = TREE_TYPE (fndecl);
2125 tree fnargs = DECL_ARGUMENTS (fndecl);
2130 CUMULATIVE_ARGS args_so_far;
2131 int store_args_on_stack = (iq2000_can_use_return_insn ());
2133 /* If struct value address is treated as the first argument. */
2134 if (aggregate_value_p (DECL_RESULT (fndecl), fndecl)
2135 && ! current_function_returns_pcc_struct
2136 && targetm.calls.struct_value_rtx (TREE_TYPE (fndecl), 1) == 0)
2138 tree type = build_pointer_type (fntype);
2139 tree function_result_decl = build_decl (PARM_DECL, NULL_TREE, type);
2141 DECL_ARG_TYPE (function_result_decl) = type;
2142 TREE_CHAIN (function_result_decl) = fnargs;
2143 fnargs = function_result_decl;
2146 /* For arguments passed in registers, find the register number
2147 of the first argument in the variable part of the argument list,
2148 otherwise GP_ARG_LAST+1. Note also if the last argument is
2149 the varargs special argument, and treat it as part of the
2152 This is only needed if store_args_on_stack is true. */
2153 INIT_CUMULATIVE_ARGS (args_so_far, fntype, NULL_RTX, 0, 0);
2154 regno = GP_ARG_FIRST;
2156 for (cur_arg = fnargs; cur_arg != 0; cur_arg = next_arg)
2158 tree passed_type = DECL_ARG_TYPE (cur_arg);
2159 enum machine_mode passed_mode = TYPE_MODE (passed_type);
2162 if (TREE_ADDRESSABLE (passed_type))
2164 passed_type = build_pointer_type (passed_type);
2165 passed_mode = Pmode;
2168 entry_parm = FUNCTION_ARG (args_so_far, passed_mode, passed_type, 1);
2170 FUNCTION_ARG_ADVANCE (args_so_far, passed_mode, passed_type, 1);
2171 next_arg = TREE_CHAIN (cur_arg);
2173 if (entry_parm && store_args_on_stack)
2176 && DECL_NAME (cur_arg)
2177 && ((0 == strcmp (IDENTIFIER_POINTER (DECL_NAME (cur_arg)),
2178 "__builtin_va_alist"))
2179 || (0 == strcmp (IDENTIFIER_POINTER (DECL_NAME (cur_arg)),
2182 last_arg_is_vararg_marker = 1;
2189 if (GET_CODE (entry_parm) != REG)
2192 /* Passed in a register, so will get homed automatically. */
2193 if (GET_MODE (entry_parm) == BLKmode)
2194 words = (int_size_in_bytes (passed_type) + 3) / 4;
2196 words = (GET_MODE_SIZE (GET_MODE (entry_parm)) + 3) / 4;
2198 regno = REGNO (entry_parm) + words - 1;
2203 regno = GP_ARG_LAST+1;
2208 /* In order to pass small structures by value in registers we need to
2209 shift the value into the high part of the register.
2210 Function_arg has encoded a PARALLEL rtx, holding a vector of
2211 adjustments to be made as the next_arg_reg variable, so we split up the
2212 insns, and emit them separately. */
2213 next_arg_reg = FUNCTION_ARG (args_so_far, VOIDmode, void_type_node, 1);
2214 if (next_arg_reg != 0 && GET_CODE (next_arg_reg) == PARALLEL)
2216 rtvec adjust = XVEC (next_arg_reg, 0);
2217 int num = GET_NUM_ELEM (adjust);
2219 for (i = 0; i < num; i++)
2223 pattern = RTVEC_ELT (adjust, i);
2224 if (GET_CODE (pattern) != SET
2225 || GET_CODE (SET_SRC (pattern)) != ASHIFT)
2226 abort_with_insn (pattern, "Insn is not a shift");
2227 PUT_CODE (SET_SRC (pattern), ASHIFTRT);
2229 insn = emit_insn (pattern);
2231 /* Global life information isn't valid at this point, so we
2232 can't check whether these shifts are actually used. Mark
2233 them MAYBE_DEAD so that flow2 will remove them, and not
2234 complain about dead code in the prologue. */
2235 REG_NOTES(insn) = gen_rtx_EXPR_LIST (REG_MAYBE_DEAD, NULL_RTX,
2240 tsize = compute_frame_size (get_frame_size ());
2242 /* If this function is a varargs function, store any registers that
2243 would normally hold arguments ($4 - $7) on the stack. */
2244 if (store_args_on_stack
2245 && ((TYPE_ARG_TYPES (fntype) != 0
2246 && (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
2248 || last_arg_is_vararg_marker))
2250 int offset = (regno - GP_ARG_FIRST) * UNITS_PER_WORD;
2251 rtx ptr = stack_pointer_rtx;
2253 for (; regno <= GP_ARG_LAST; regno++)
2256 ptr = gen_rtx_PLUS (Pmode, stack_pointer_rtx, GEN_INT (offset));
2257 emit_move_insn (gen_rtx_MEM (gpr_mode, ptr),
2258 gen_rtx_REG (gpr_mode, regno));
2260 offset += GET_MODE_SIZE (gpr_mode);
2266 rtx tsize_rtx = GEN_INT (tsize);
2267 rtx adjustment_rtx, insn, dwarf_pattern;
2271 adjustment_rtx = gen_rtx_REG (Pmode, IQ2000_TEMP1_REGNUM);
2272 emit_move_insn (adjustment_rtx, tsize_rtx);
2275 adjustment_rtx = tsize_rtx;
2277 insn = emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
2280 dwarf_pattern = gen_rtx_SET (Pmode, stack_pointer_rtx,
2281 plus_constant (stack_pointer_rtx, -tsize));
2283 iq2000_annotate_frame_insn (insn, dwarf_pattern);
2285 save_restore_insns (1);
2287 if (frame_pointer_needed)
2291 insn = emit_insn (gen_movsi (hard_frame_pointer_rtx,
2292 stack_pointer_rtx));
2295 RTX_FRAME_RELATED_P (insn) = 1;
2299 emit_insn (gen_blockage ());
2302 /* Expand the epilogue into a bunch of separate insns. */
2305 iq2000_expand_epilogue (void)
2307 HOST_WIDE_INT tsize = cfun->machine->total_size;
2308 rtx tsize_rtx = GEN_INT (tsize);
2309 rtx tmp_rtx = (rtx)0;
2311 if (iq2000_can_use_return_insn ())
2313 emit_insn (gen_return ());
2319 tmp_rtx = gen_rtx_REG (Pmode, IQ2000_TEMP1_REGNUM);
2320 emit_move_insn (tmp_rtx, tsize_rtx);
2321 tsize_rtx = tmp_rtx;
2326 if (frame_pointer_needed)
2328 emit_insn (gen_blockage ());
2330 emit_insn (gen_movsi (stack_pointer_rtx, hard_frame_pointer_rtx));
2333 save_restore_insns (0);
2335 if (current_function_calls_eh_return)
2337 rtx eh_ofs = EH_RETURN_STACKADJ_RTX;
2338 emit_insn (gen_addsi3 (eh_ofs, eh_ofs, tsize_rtx));
2342 emit_insn (gen_blockage ());
2344 if (tsize != 0 || current_function_calls_eh_return)
2346 emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx,
2351 if (current_function_calls_eh_return)
2353 /* Perform the additional bump for __throw. */
2354 emit_move_insn (gen_rtx_REG (Pmode, HARD_FRAME_POINTER_REGNUM),
2356 emit_insn (gen_rtx_USE (VOIDmode, gen_rtx_REG (Pmode,
2357 HARD_FRAME_POINTER_REGNUM)));
2358 emit_jump_insn (gen_eh_return_internal ());
2361 emit_jump_insn (gen_return_internal (gen_rtx_REG (Pmode,
2362 GP_REG_FIRST + 31)));
2366 iq2000_expand_eh_return (rtx address)
2368 HOST_WIDE_INT gp_offset = cfun->machine->gp_sp_offset;
2371 scratch = plus_constant (stack_pointer_rtx, gp_offset);
2372 emit_move_insn (gen_rtx_MEM (GET_MODE (address), scratch), address);
2375 /* Return nonzero if this function is known to have a null epilogue.
2376 This allows the optimizer to omit jumps to jumps if no stack
2380 iq2000_can_use_return_insn (void)
2382 if (! reload_completed)
2385 if (regs_ever_live[31] || profile_flag)
2388 if (cfun->machine->initialized)
2389 return cfun->machine->total_size == 0;
2391 return compute_frame_size (get_frame_size ()) == 0;
2394 /* Returns nonzero if X contains a SYMBOL_REF. */
2397 symbolic_expression_p (rtx x)
2399 if (GET_CODE (x) == SYMBOL_REF)
2402 if (GET_CODE (x) == CONST)
2403 return symbolic_expression_p (XEXP (x, 0));
2406 return symbolic_expression_p (XEXP (x, 0));
2408 if (ARITHMETIC_P (x))
2409 return (symbolic_expression_p (XEXP (x, 0))
2410 || symbolic_expression_p (XEXP (x, 1)));
2415 /* Choose the section to use for the constant rtx expression X that has
2419 iq2000_select_rtx_section (enum machine_mode mode, rtx x ATTRIBUTE_UNUSED,
2420 unsigned HOST_WIDE_INT align)
2422 /* For embedded applications, always put constants in read-only data,
2423 in order to reduce RAM usage. */
2424 /* For embedded applications, always put constants in read-only data,
2425 in order to reduce RAM usage. */
2426 mergeable_constant_section (mode, align, 0);
2429 /* Choose the section to use for DECL. RELOC is true if its value contains
2430 any relocatable expression.
2432 Some of the logic used here needs to be replicated in
2433 ENCODE_SECTION_INFO in iq2000.h so that references to these symbols
2434 are done correctly. */
2437 iq2000_select_section (tree decl, int reloc ATTRIBUTE_UNUSED,
2438 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED)
2440 if (TARGET_EMBEDDED_DATA)
2442 /* For embedded applications, always put an object in read-only data
2443 if possible, in order to reduce RAM usage. */
2444 if ((TREE_CODE (decl) == VAR_DECL
2445 && TREE_READONLY (decl) && !TREE_SIDE_EFFECTS (decl)
2446 && DECL_INITIAL (decl)
2447 && (DECL_INITIAL (decl) == error_mark_node
2448 || TREE_CONSTANT (DECL_INITIAL (decl))))
2449 /* Deal with calls from output_constant_def_contents. */
2450 || TREE_CODE (decl) != VAR_DECL)
2451 readonly_data_section ();
2457 /* For hosted applications, always put an object in small data if
2458 possible, as this gives the best performance. */
2459 if ((TREE_CODE (decl) == VAR_DECL
2460 && TREE_READONLY (decl) && !TREE_SIDE_EFFECTS (decl)
2461 && DECL_INITIAL (decl)
2462 && (DECL_INITIAL (decl) == error_mark_node
2463 || TREE_CONSTANT (DECL_INITIAL (decl))))
2464 /* Deal with calls from output_constant_def_contents. */
2465 || TREE_CODE (decl) != VAR_DECL)
2466 readonly_data_section ();
2471 /* Return register to use for a function return value with VALTYPE for function
2475 iq2000_function_value (tree valtype, tree func ATTRIBUTE_UNUSED)
2477 int reg = GP_RETURN;
2478 enum machine_mode mode = TYPE_MODE (valtype);
2479 int unsignedp = TYPE_UNSIGNED (valtype);
2481 /* Since we define TARGET_PROMOTE_FUNCTION_RETURN that returns true,
2482 we must promote the mode just as PROMOTE_MODE does. */
2483 mode = promote_mode (valtype, mode, &unsignedp, 1);
2485 return gen_rtx_REG (mode, reg);
2488 /* The implementation of FUNCTION_ARG_PASS_BY_REFERENCE. Return
2489 nonzero when an argument must be passed by reference. */
2492 function_arg_pass_by_reference (CUMULATIVE_ARGS *cum ATTRIBUTE_UNUSED,
2493 enum machine_mode mode, tree type,
2494 int named ATTRIBUTE_UNUSED)
2498 /* We must pass by reference if we would be both passing in registers
2499 and the stack. This is because any subsequent partial arg would be
2500 handled incorrectly in this case. */
2501 if (cum && MUST_PASS_IN_STACK (mode, type))
2503 /* Don't pass the actual CUM to FUNCTION_ARG, because we would
2504 get double copies of any offsets generated for small structs
2505 passed in registers. */
2506 CUMULATIVE_ARGS temp;
2509 if (FUNCTION_ARG (temp, mode, type, named) != 0)
2513 if (type == NULL_TREE || mode == DImode || mode == DFmode)
2516 size = int_size_in_bytes (type);
2517 return size == -1 || size > UNITS_PER_WORD;
2520 /* Return the length of INSN. LENGTH is the initial length computed by
2521 attributes in the machine-description file. */
2524 iq2000_adjust_insn_length (rtx insn, int length)
2526 /* A unconditional jump has an unfilled delay slot if it is not part
2527 of a sequence. A conditional jump normally has a delay slot. */
2528 if (simplejump_p (insn)
2529 || ( (GET_CODE (insn) == JUMP_INSN
2530 || GET_CODE (insn) == CALL_INSN)))
2536 /* Output assembly instructions to perform a conditional branch.
2538 INSN is the branch instruction. OPERANDS[0] is the condition.
2539 OPERANDS[1] is the target of the branch. OPERANDS[2] is the target
2540 of the first operand to the condition. If TWO_OPERANDS_P is
2541 nonzero the comparison takes two operands; OPERANDS[3] will be the
2544 If INVERTED_P is nonzero we are to branch if the condition does
2545 not hold. If FLOAT_P is nonzero this is a floating-point comparison.
2547 LENGTH is the length (in bytes) of the sequence we are to generate.
2548 That tells us whether to generate a simple conditional branch, or a
2549 reversed conditional branch around a `jr' instruction. */
2552 iq2000_output_conditional_branch (rtx insn, rtx * operands, int two_operands_p,
2553 int float_p, int inverted_p, int length)
2555 static char buffer[200];
2556 /* The kind of comparison we are doing. */
2557 enum rtx_code code = GET_CODE (operands[0]);
2558 /* Nonzero if the opcode for the comparison needs a `z' indicating
2559 that it is a comparison against zero. */
2561 /* A string to use in the assembly output to represent the first
2563 const char *op1 = "%z2";
2564 /* A string to use in the assembly output to represent the second
2565 operand. Use the hard-wired zero register if there's no second
2567 const char *op2 = (two_operands_p ? ",%z3" : ",%.");
2568 /* The operand-printing string for the comparison. */
2569 const char *comp = (float_p ? "%F0" : "%C0");
2570 /* The operand-printing string for the inverted comparison. */
2571 const char *inverted_comp = (float_p ? "%W0" : "%N0");
2573 /* Likely variants of each branch instruction annul the instruction
2574 in the delay slot if the branch is not taken. */
2575 iq2000_branch_likely = (final_sequence && INSN_ANNULLED_BRANCH_P (insn));
2577 if (!two_operands_p)
2579 /* To compute whether than A > B, for example, we normally
2580 subtract B from A and then look at the sign bit. But, if we
2581 are doing an unsigned comparison, and B is zero, we don't
2582 have to do the subtraction. Instead, we can just check to
2583 see if A is nonzero. Thus, we change the CODE here to
2584 reflect the simpler comparison operation. */
2596 /* A condition which will always be true. */
2602 /* A condition which will always be false. */
2608 /* Not a special case. */
2613 /* Relative comparisons are always done against zero. But
2614 equality comparisons are done between two operands, and therefore
2615 do not require a `z' in the assembly language output. */
2616 need_z_p = (!float_p && code != EQ && code != NE);
2617 /* For comparisons against zero, the zero is not provided
2622 /* Begin by terminating the buffer. That way we can always use
2623 strcat to add to it. */
2630 /* Just a simple conditional branch. */
2632 sprintf (buffer, "b%s%%?\t%%Z2%%1",
2633 inverted_p ? inverted_comp : comp);
2635 sprintf (buffer, "b%s%s%%?\t%s%s,%%1",
2636 inverted_p ? inverted_comp : comp,
2637 need_z_p ? "z" : "",
2645 /* Generate a reversed conditional branch around ` j'
2657 Because we have to jump four bytes *past* the following
2658 instruction if this branch was annulled, we can't just use
2659 a label, as in the picture above; there's no way to put the
2660 label after the next instruction, as the assembler does not
2661 accept `.L+4' as the target of a branch. (We can't just
2662 wait until the next instruction is output; it might be a
2663 macro and take up more than four bytes. Once again, we see
2664 why we want to eliminate macros.)
2666 If the branch is annulled, we jump four more bytes that we
2667 would otherwise; that way we skip the annulled instruction
2668 in the delay slot. */
2671 = ((iq2000_branch_likely || length == 16) ? ".+16" : ".+12");
2674 c = strchr (buffer, '\0');
2675 /* Generate the reversed comparison. This takes four
2678 sprintf (c, "b%s\t%%Z2%s",
2679 inverted_p ? comp : inverted_comp,
2682 sprintf (c, "b%s%s\t%s%s,%s",
2683 inverted_p ? comp : inverted_comp,
2684 need_z_p ? "z" : "",
2688 strcat (c, "\n\tnop\n\tj\t%1");
2690 /* The delay slot was unfilled. Since we're inside
2691 .noreorder, the assembler will not fill in the NOP for
2692 us, so we must do it ourselves. */
2693 strcat (buffer, "\n\tnop");
2705 #define def_builtin(NAME, TYPE, CODE) \
2706 builtin_function ((NAME), (TYPE), (CODE), BUILT_IN_MD, NULL, NULL_TREE)
2709 iq2000_init_builtins (void)
2711 tree endlink = void_list_node;
2712 tree void_ftype, void_ftype_int, void_ftype_int_int;
2713 tree void_ftype_int_int_int;
2714 tree int_ftype_int, int_ftype_int_int, int_ftype_int_int_int;
2715 tree int_ftype_int_int_int_int;
2719 = build_function_type (void_type_node,
2720 tree_cons (NULL_TREE, void_type_node, endlink));
2724 = build_function_type (void_type_node,
2725 tree_cons (NULL_TREE, integer_type_node, endlink));
2727 /* void func (int, int) */
2729 = build_function_type (void_type_node,
2730 tree_cons (NULL_TREE, integer_type_node,
2731 tree_cons (NULL_TREE, integer_type_node,
2734 /* int func (int) */
2736 = build_function_type (integer_type_node,
2737 tree_cons (NULL_TREE, integer_type_node, endlink));
2739 /* int func (int, int) */
2741 = build_function_type (integer_type_node,
2742 tree_cons (NULL_TREE, integer_type_node,
2743 tree_cons (NULL_TREE, integer_type_node,
2746 /* void func (int, int, int) */
2747 void_ftype_int_int_int
2748 = build_function_type
2750 tree_cons (NULL_TREE, integer_type_node,
2751 tree_cons (NULL_TREE, integer_type_node,
2752 tree_cons (NULL_TREE,
2756 /* int func (int, int, int, int) */
2757 int_ftype_int_int_int_int
2758 = build_function_type
2760 tree_cons (NULL_TREE, integer_type_node,
2761 tree_cons (NULL_TREE, integer_type_node,
2762 tree_cons (NULL_TREE,
2764 tree_cons (NULL_TREE,
2768 /* int func (int, int, int) */
2769 int_ftype_int_int_int
2770 = build_function_type
2772 tree_cons (NULL_TREE, integer_type_node,
2773 tree_cons (NULL_TREE, integer_type_node,
2774 tree_cons (NULL_TREE,
2778 /* int func (int, int, int, int) */
2779 int_ftype_int_int_int_int
2780 = build_function_type
2782 tree_cons (NULL_TREE, integer_type_node,
2783 tree_cons (NULL_TREE, integer_type_node,
2784 tree_cons (NULL_TREE,
2786 tree_cons (NULL_TREE,
2790 def_builtin ("__builtin_ado16", int_ftype_int_int, IQ2000_BUILTIN_ADO16);
2791 def_builtin ("__builtin_ram", int_ftype_int_int_int_int, IQ2000_BUILTIN_RAM);
2792 def_builtin ("__builtin_chkhdr", void_ftype_int_int, IQ2000_BUILTIN_CHKHDR);
2793 def_builtin ("__builtin_pkrl", void_ftype_int_int, IQ2000_BUILTIN_PKRL);
2794 def_builtin ("__builtin_cfc0", int_ftype_int, IQ2000_BUILTIN_CFC0);
2795 def_builtin ("__builtin_cfc1", int_ftype_int, IQ2000_BUILTIN_CFC1);
2796 def_builtin ("__builtin_cfc2", int_ftype_int, IQ2000_BUILTIN_CFC2);
2797 def_builtin ("__builtin_cfc3", int_ftype_int, IQ2000_BUILTIN_CFC3);
2798 def_builtin ("__builtin_ctc0", void_ftype_int_int, IQ2000_BUILTIN_CTC0);
2799 def_builtin ("__builtin_ctc1", void_ftype_int_int, IQ2000_BUILTIN_CTC1);
2800 def_builtin ("__builtin_ctc2", void_ftype_int_int, IQ2000_BUILTIN_CTC2);
2801 def_builtin ("__builtin_ctc3", void_ftype_int_int, IQ2000_BUILTIN_CTC3);
2802 def_builtin ("__builtin_mfc0", int_ftype_int, IQ2000_BUILTIN_MFC0);
2803 def_builtin ("__builtin_mfc1", int_ftype_int, IQ2000_BUILTIN_MFC1);
2804 def_builtin ("__builtin_mfc2", int_ftype_int, IQ2000_BUILTIN_MFC2);
2805 def_builtin ("__builtin_mfc3", int_ftype_int, IQ2000_BUILTIN_MFC3);
2806 def_builtin ("__builtin_mtc0", void_ftype_int_int, IQ2000_BUILTIN_MTC0);
2807 def_builtin ("__builtin_mtc1", void_ftype_int_int, IQ2000_BUILTIN_MTC1);
2808 def_builtin ("__builtin_mtc2", void_ftype_int_int, IQ2000_BUILTIN_MTC2);
2809 def_builtin ("__builtin_mtc3", void_ftype_int_int, IQ2000_BUILTIN_MTC3);
2810 def_builtin ("__builtin_lur", void_ftype_int_int, IQ2000_BUILTIN_LUR);
2811 def_builtin ("__builtin_rb", void_ftype_int_int, IQ2000_BUILTIN_RB);
2812 def_builtin ("__builtin_rx", void_ftype_int_int, IQ2000_BUILTIN_RX);
2813 def_builtin ("__builtin_srrd", void_ftype_int, IQ2000_BUILTIN_SRRD);
2814 def_builtin ("__builtin_srwr", void_ftype_int_int, IQ2000_BUILTIN_SRWR);
2815 def_builtin ("__builtin_wb", void_ftype_int_int, IQ2000_BUILTIN_WB);
2816 def_builtin ("__builtin_wx", void_ftype_int_int, IQ2000_BUILTIN_WX);
2817 def_builtin ("__builtin_luc32l", void_ftype_int_int, IQ2000_BUILTIN_LUC32L);
2818 def_builtin ("__builtin_luc64", void_ftype_int_int, IQ2000_BUILTIN_LUC64);
2819 def_builtin ("__builtin_luc64l", void_ftype_int_int, IQ2000_BUILTIN_LUC64L);
2820 def_builtin ("__builtin_luk", void_ftype_int_int, IQ2000_BUILTIN_LUK);
2821 def_builtin ("__builtin_lulck", void_ftype_int, IQ2000_BUILTIN_LULCK);
2822 def_builtin ("__builtin_lum32", void_ftype_int_int, IQ2000_BUILTIN_LUM32);
2823 def_builtin ("__builtin_lum32l", void_ftype_int_int, IQ2000_BUILTIN_LUM32L);
2824 def_builtin ("__builtin_lum64", void_ftype_int_int, IQ2000_BUILTIN_LUM64);
2825 def_builtin ("__builtin_lum64l", void_ftype_int_int, IQ2000_BUILTIN_LUM64L);
2826 def_builtin ("__builtin_lurl", void_ftype_int_int, IQ2000_BUILTIN_LURL);
2827 def_builtin ("__builtin_mrgb", int_ftype_int_int_int, IQ2000_BUILTIN_MRGB);
2828 def_builtin ("__builtin_srrdl", void_ftype_int, IQ2000_BUILTIN_SRRDL);
2829 def_builtin ("__builtin_srulck", void_ftype_int, IQ2000_BUILTIN_SRULCK);
2830 def_builtin ("__builtin_srwru", void_ftype_int_int, IQ2000_BUILTIN_SRWRU);
2831 def_builtin ("__builtin_trapqfl", void_ftype, IQ2000_BUILTIN_TRAPQFL);
2832 def_builtin ("__builtin_trapqne", void_ftype, IQ2000_BUILTIN_TRAPQNE);
2833 def_builtin ("__builtin_traprel", void_ftype_int, IQ2000_BUILTIN_TRAPREL);
2834 def_builtin ("__builtin_wbu", void_ftype_int_int_int, IQ2000_BUILTIN_WBU);
2835 def_builtin ("__builtin_syscall", void_ftype, IQ2000_BUILTIN_SYSCALL);
2838 /* Builtin for ICODE having ARGCOUNT args in ARGLIST where each arg
2842 expand_one_builtin (enum insn_code icode, rtx target, tree arglist,
2843 enum rtx_code *code, int argcount)
2848 enum machine_mode mode [5];
2851 mode[0] = insn_data[icode].operand[0].mode;
2852 for (i = 0; i < argcount; i++)
2854 arg[i] = TREE_VALUE (arglist);
2855 arglist = TREE_CHAIN (arglist);
2856 op[i] = expand_expr (arg[i], NULL_RTX, VOIDmode, 0);
2857 mode[i] = insn_data[icode].operand[i].mode;
2858 if (code[i] == CONST_INT && GET_CODE (op[i]) != CONST_INT)
2859 error ("argument `%d' is not a constant", i + 1);
2861 && ! (*insn_data[icode].operand[i].predicate) (op[i], mode[i]))
2862 op[i] = copy_to_mode_reg (mode[i], op[i]);
2865 if (insn_data[icode].operand[0].constraint[0] == '=')
2868 || GET_MODE (target) != mode[0]
2869 || ! (*insn_data[icode].operand[0].predicate) (target, mode[0]))
2870 target = gen_reg_rtx (mode[0]);
2878 pat = GEN_FCN (icode) (target);
2881 pat = GEN_FCN (icode) (target, op[0]);
2883 pat = GEN_FCN (icode) (op[0]);
2887 pat = GEN_FCN (icode) (target, op[0], op[1]);
2889 pat = GEN_FCN (icode) (op[0], op[1]);
2893 pat = GEN_FCN (icode) (target, op[0], op[1], op[2]);
2895 pat = GEN_FCN (icode) (op[0], op[1], op[2]);
2899 pat = GEN_FCN (icode) (target, op[0], op[1], op[2], op[3]);
2901 pat = GEN_FCN (icode) (op[0], op[1], op[2], op[3]);
2913 /* Expand an expression EXP that calls a built-in function,
2914 with result going to TARGET if that's convenient
2915 (and in mode MODE if that's convenient).
2916 SUBTARGET may be used as the target for computing one of EXP's operands.
2917 IGNORE is nonzero if the value is to be ignored. */
2920 iq2000_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED,
2921 enum machine_mode mode ATTRIBUTE_UNUSED,
2922 int ignore ATTRIBUTE_UNUSED)
2924 tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
2925 tree arglist = TREE_OPERAND (exp, 1);
2926 int fcode = DECL_FUNCTION_CODE (fndecl);
2927 enum rtx_code code [5];
2939 case IQ2000_BUILTIN_ADO16:
2940 return expand_one_builtin (CODE_FOR_ado16, target, arglist, code, 2);
2942 case IQ2000_BUILTIN_RAM:
2943 code[1] = CONST_INT;
2944 code[2] = CONST_INT;
2945 code[3] = CONST_INT;
2946 return expand_one_builtin (CODE_FOR_ram, target, arglist, code, 4);
2948 case IQ2000_BUILTIN_CHKHDR:
2949 return expand_one_builtin (CODE_FOR_chkhdr, target, arglist, code, 2);
2951 case IQ2000_BUILTIN_PKRL:
2952 return expand_one_builtin (CODE_FOR_pkrl, target, arglist, code, 2);
2954 case IQ2000_BUILTIN_CFC0:
2955 code[0] = CONST_INT;
2956 return expand_one_builtin (CODE_FOR_cfc0, target, arglist, code, 1);
2958 case IQ2000_BUILTIN_CFC1:
2959 code[0] = CONST_INT;
2960 return expand_one_builtin (CODE_FOR_cfc1, target, arglist, code, 1);
2962 case IQ2000_BUILTIN_CFC2:
2963 code[0] = CONST_INT;
2964 return expand_one_builtin (CODE_FOR_cfc2, target, arglist, code, 1);
2966 case IQ2000_BUILTIN_CFC3:
2967 code[0] = CONST_INT;
2968 return expand_one_builtin (CODE_FOR_cfc3, target, arglist, code, 1);
2970 case IQ2000_BUILTIN_CTC0:
2971 code[1] = CONST_INT;
2972 return expand_one_builtin (CODE_FOR_ctc0, target, arglist, code, 2);
2974 case IQ2000_BUILTIN_CTC1:
2975 code[1] = CONST_INT;
2976 return expand_one_builtin (CODE_FOR_ctc1, target, arglist, code, 2);
2978 case IQ2000_BUILTIN_CTC2:
2979 code[1] = CONST_INT;
2980 return expand_one_builtin (CODE_FOR_ctc2, target, arglist, code, 2);
2982 case IQ2000_BUILTIN_CTC3:
2983 code[1] = CONST_INT;
2984 return expand_one_builtin (CODE_FOR_ctc3, target, arglist, code, 2);
2986 case IQ2000_BUILTIN_MFC0:
2987 code[0] = CONST_INT;
2988 return expand_one_builtin (CODE_FOR_mfc0, target, arglist, code, 1);
2990 case IQ2000_BUILTIN_MFC1:
2991 code[0] = CONST_INT;
2992 return expand_one_builtin (CODE_FOR_mfc1, target, arglist, code, 1);
2994 case IQ2000_BUILTIN_MFC2:
2995 code[0] = CONST_INT;
2996 return expand_one_builtin (CODE_FOR_mfc2, target, arglist, code, 1);
2998 case IQ2000_BUILTIN_MFC3:
2999 code[0] = CONST_INT;
3000 return expand_one_builtin (CODE_FOR_mfc3, target, arglist, code, 1);
3002 case IQ2000_BUILTIN_MTC0:
3003 code[1] = CONST_INT;
3004 return expand_one_builtin (CODE_FOR_mtc0, target, arglist, code, 2);
3006 case IQ2000_BUILTIN_MTC1:
3007 code[1] = CONST_INT;
3008 return expand_one_builtin (CODE_FOR_mtc1, target, arglist, code, 2);
3010 case IQ2000_BUILTIN_MTC2:
3011 code[1] = CONST_INT;
3012 return expand_one_builtin (CODE_FOR_mtc2, target, arglist, code, 2);
3014 case IQ2000_BUILTIN_MTC3:
3015 code[1] = CONST_INT;
3016 return expand_one_builtin (CODE_FOR_mtc3, target, arglist, code, 2);
3018 case IQ2000_BUILTIN_LUR:
3019 return expand_one_builtin (CODE_FOR_lur, target, arglist, code, 2);
3021 case IQ2000_BUILTIN_RB:
3022 return expand_one_builtin (CODE_FOR_rb, target, arglist, code, 2);
3024 case IQ2000_BUILTIN_RX:
3025 return expand_one_builtin (CODE_FOR_rx, target, arglist, code, 2);
3027 case IQ2000_BUILTIN_SRRD:
3028 return expand_one_builtin (CODE_FOR_srrd, target, arglist, code, 1);
3030 case IQ2000_BUILTIN_SRWR:
3031 return expand_one_builtin (CODE_FOR_srwr, target, arglist, code, 2);
3033 case IQ2000_BUILTIN_WB:
3034 return expand_one_builtin (CODE_FOR_wb, target, arglist, code, 2);
3036 case IQ2000_BUILTIN_WX:
3037 return expand_one_builtin (CODE_FOR_wx, target, arglist, code, 2);
3039 case IQ2000_BUILTIN_LUC32L:
3040 return expand_one_builtin (CODE_FOR_luc32l, target, arglist, code, 2);
3042 case IQ2000_BUILTIN_LUC64:
3043 return expand_one_builtin (CODE_FOR_luc64, target, arglist, code, 2);
3045 case IQ2000_BUILTIN_LUC64L:
3046 return expand_one_builtin (CODE_FOR_luc64l, target, arglist, code, 2);
3048 case IQ2000_BUILTIN_LUK:
3049 return expand_one_builtin (CODE_FOR_luk, target, arglist, code, 2);
3051 case IQ2000_BUILTIN_LULCK:
3052 return expand_one_builtin (CODE_FOR_lulck, target, arglist, code, 1);
3054 case IQ2000_BUILTIN_LUM32:
3055 return expand_one_builtin (CODE_FOR_lum32, target, arglist, code, 2);
3057 case IQ2000_BUILTIN_LUM32L:
3058 return expand_one_builtin (CODE_FOR_lum32l, target, arglist, code, 2);
3060 case IQ2000_BUILTIN_LUM64:
3061 return expand_one_builtin (CODE_FOR_lum64, target, arglist, code, 2);
3063 case IQ2000_BUILTIN_LUM64L:
3064 return expand_one_builtin (CODE_FOR_lum64l, target, arglist, code, 2);
3066 case IQ2000_BUILTIN_LURL:
3067 return expand_one_builtin (CODE_FOR_lurl, target, arglist, code, 2);
3069 case IQ2000_BUILTIN_MRGB:
3070 code[2] = CONST_INT;
3071 return expand_one_builtin (CODE_FOR_mrgb, target, arglist, code, 3);
3073 case IQ2000_BUILTIN_SRRDL:
3074 return expand_one_builtin (CODE_FOR_srrdl, target, arglist, code, 1);
3076 case IQ2000_BUILTIN_SRULCK:
3077 return expand_one_builtin (CODE_FOR_srulck, target, arglist, code, 1);
3079 case IQ2000_BUILTIN_SRWRU:
3080 return expand_one_builtin (CODE_FOR_srwru, target, arglist, code, 2);
3082 case IQ2000_BUILTIN_TRAPQFL:
3083 return expand_one_builtin (CODE_FOR_trapqfl, target, arglist, code, 0);
3085 case IQ2000_BUILTIN_TRAPQNE:
3086 return expand_one_builtin (CODE_FOR_trapqne, target, arglist, code, 0);
3088 case IQ2000_BUILTIN_TRAPREL:
3089 return expand_one_builtin (CODE_FOR_traprel, target, arglist, code, 1);
3091 case IQ2000_BUILTIN_WBU:
3092 return expand_one_builtin (CODE_FOR_wbu, target, arglist, code, 3);
3094 case IQ2000_BUILTIN_SYSCALL:
3095 return expand_one_builtin (CODE_FOR_syscall, target, arglist, code, 0);
3101 /* Worker function for TARGET_RETURN_IN_MEMORY. */
3104 iq2000_return_in_memory (tree type, tree fntype ATTRIBUTE_UNUSED)
3106 return ((int_size_in_bytes (type) > (2 * UNITS_PER_WORD))
3107 || (int_size_in_bytes (type) == -1));
3110 /* Worker function for TARGET_SETUP_INCOMING_VARARGS. */
3113 iq2000_setup_incoming_varargs (CUMULATIVE_ARGS *cum,
3114 enum machine_mode mode ATTRIBUTE_UNUSED,
3115 tree type ATTRIBUTE_UNUSED, int * pretend_size,
3118 unsigned int iq2000_off = ! cum->last_arg_fp;
3119 unsigned int iq2000_fp_off = cum->last_arg_fp;
3121 if ((cum->arg_words < MAX_ARGS_IN_REGISTERS - iq2000_off))
3123 int iq2000_save_gp_regs
3124 = MAX_ARGS_IN_REGISTERS - cum->arg_words - iq2000_off;
3125 int iq2000_save_fp_regs
3126 = (MAX_ARGS_IN_REGISTERS - cum->fp_arg_words - iq2000_fp_off);
3128 if (iq2000_save_gp_regs < 0)
3129 iq2000_save_gp_regs = 0;
3130 if (iq2000_save_fp_regs < 0)
3131 iq2000_save_fp_regs = 0;
3133 *pretend_size = ((iq2000_save_gp_regs * UNITS_PER_WORD)
3134 + (iq2000_save_fp_regs * UNITS_PER_FPREG));
3138 if (cum->arg_words < MAX_ARGS_IN_REGISTERS - iq2000_off)
3141 ptr = plus_constant (virtual_incoming_args_rtx,
3142 - (iq2000_save_gp_regs
3144 mem = gen_rtx_MEM (BLKmode, ptr);
3146 (cum->arg_words + GP_ARG_FIRST + iq2000_off,
3148 iq2000_save_gp_regs);
3154 /* A C compound statement to output to stdio stream STREAM the
3155 assembler syntax for an instruction operand that is a memory
3156 reference whose address is ADDR. ADDR is an RTL expression. */
3159 print_operand_address (FILE * file, rtx addr)
3162 error ("PRINT_OPERAND_ADDRESS, null pointer");
3165 switch (GET_CODE (addr))
3168 if (REGNO (addr) == ARG_POINTER_REGNUM)
3169 abort_with_insn (addr, "Arg pointer not eliminated.");
3171 fprintf (file, "0(%s)", reg_names [REGNO (addr)]);
3176 rtx arg0 = XEXP (addr, 0);
3177 rtx arg1 = XEXP (addr, 1);
3179 if (GET_CODE (arg0) != REG)
3180 abort_with_insn (addr,
3181 "PRINT_OPERAND_ADDRESS, LO_SUM with #1 not REG.");
3183 fprintf (file, "%%lo(");
3184 print_operand_address (file, arg1);
3185 fprintf (file, ")(%s)", reg_names [REGNO (arg0)]);
3193 rtx arg0 = XEXP (addr, 0);
3194 rtx arg1 = XEXP (addr, 1);
3196 if (GET_CODE (arg0) == REG)
3200 if (GET_CODE (offset) == REG)
3201 abort_with_insn (addr, "PRINT_OPERAND_ADDRESS, 2 regs");
3204 else if (GET_CODE (arg1) == REG)
3205 reg = arg1, offset = arg0;
3206 else if (CONSTANT_P (arg0) && CONSTANT_P (arg1))
3208 output_addr_const (file, addr);
3212 abort_with_insn (addr, "PRINT_OPERAND_ADDRESS, no regs");
3214 if (! CONSTANT_P (offset))
3215 abort_with_insn (addr, "PRINT_OPERAND_ADDRESS, invalid insn #2");
3217 if (REGNO (reg) == ARG_POINTER_REGNUM)
3218 abort_with_insn (addr, "Arg pointer not eliminated.");
3220 output_addr_const (file, offset);
3221 fprintf (file, "(%s)", reg_names [REGNO (reg)]);
3229 output_addr_const (file, addr);
3230 if (GET_CODE (addr) == CONST_INT)
3231 fprintf (file, "(%s)", reg_names [0]);
3235 abort_with_insn (addr, "PRINT_OPERAND_ADDRESS, invalid insn #1");
3240 /* A C compound statement to output to stdio stream FILE the
3241 assembler syntax for an instruction operand OP.
3243 LETTER is a value that can be used to specify one of several ways
3244 of printing the operand. It is used when identical operands
3245 must be printed differently depending on the context. LETTER
3246 comes from the `%' specification that was used to request
3247 printing of the operand. If the specification was just `%DIGIT'
3248 then LETTER is 0; if the specification was `%LTR DIGIT' then LETTER
3249 is the ASCII code for LTR.
3251 If OP is a register, this macro should print the register's name.
3252 The names can be found in an array `reg_names' whose type is
3253 `char *[]'. `reg_names' is initialized from `REGISTER_NAMES'.
3255 When the machine description has a specification `%PUNCT' (a `%'
3256 followed by a punctuation character), this macro is called with
3257 a null pointer for X and the punctuation character for LETTER.
3259 The IQ2000 specific codes are:
3261 'X' X is CONST_INT, prints upper 16 bits in hexadecimal format = "0x%04x",
3262 'x' X is CONST_INT, prints lower 16 bits in hexadecimal format = "0x%04x",
3263 'd' output integer constant in decimal,
3264 'z' if the operand is 0, use $0 instead of normal operand.
3265 'D' print second part of double-word register or memory operand.
3266 'L' print low-order register of double-word register operand.
3267 'M' print high-order register of double-word register operand.
3268 'C' print part of opcode for a branch condition.
3269 'F' print part of opcode for a floating-point branch condition.
3270 'N' print part of opcode for a branch condition, inverted.
3271 'W' print part of opcode for a floating-point branch condition, inverted.
3272 'A' Print part of opcode for a bit test condition.
3273 'P' Print label for a bit test.
3274 'p' Print log for a bit test.
3275 'B' print 'z' for EQ, 'n' for NE
3276 'b' print 'n' for EQ, 'z' for NE
3277 'T' print 'f' for EQ, 't' for NE
3278 't' print 't' for EQ, 'f' for NE
3279 'Z' print register and a comma, but print nothing for $fcc0
3280 '?' Print 'l' if we are to use a branch likely instead of normal branch.
3281 '@' Print the name of the assembler temporary register (at or $1).
3282 '.' Print the name of the register with a hard-wired zero (zero or $0).
3283 '$' Print the name of the stack pointer register (sp or $29).
3284 '+' Print the name of the gp register (gp or $28). */
3287 print_operand (FILE *file, rtx op, int letter)
3291 if (PRINT_OPERAND_PUNCT_VALID_P (letter))
3296 if (iq2000_branch_likely)
3301 fputs (reg_names [GP_REG_FIRST + 1], file);
3305 fputs (reg_names [GP_REG_FIRST + 0], file);
3309 fputs (reg_names[STACK_POINTER_REGNUM], file);
3313 fputs (reg_names[GP_REG_FIRST + 28], file);
3317 error ("PRINT_OPERAND: Unknown punctuation '%c'", letter);
3326 error ("PRINT_OPERAND null pointer");
3330 code = GET_CODE (op);
3332 if (code == SIGN_EXTEND)
3333 op = XEXP (op, 0), code = GET_CODE (op);
3338 case EQ: fputs ("eq", file); break;
3339 case NE: fputs ("ne", file); break;
3340 case GT: fputs ("gt", file); break;
3341 case GE: fputs ("ge", file); break;
3342 case LT: fputs ("lt", file); break;
3343 case LE: fputs ("le", file); break;
3344 case GTU: fputs ("ne", file); break;
3345 case GEU: fputs ("geu", file); break;
3346 case LTU: fputs ("ltu", file); break;
3347 case LEU: fputs ("eq", file); break;
3349 abort_with_insn (op, "PRINT_OPERAND, invalid insn for %%C");
3352 else if (letter == 'N')
3355 case EQ: fputs ("ne", file); break;
3356 case NE: fputs ("eq", file); break;
3357 case GT: fputs ("le", file); break;
3358 case GE: fputs ("lt", file); break;
3359 case LT: fputs ("ge", file); break;
3360 case LE: fputs ("gt", file); break;
3361 case GTU: fputs ("leu", file); break;
3362 case GEU: fputs ("ltu", file); break;
3363 case LTU: fputs ("geu", file); break;
3364 case LEU: fputs ("gtu", file); break;
3366 abort_with_insn (op, "PRINT_OPERAND, invalid insn for %%N");
3369 else if (letter == 'F')
3372 case EQ: fputs ("c1f", file); break;
3373 case NE: fputs ("c1t", file); break;
3375 abort_with_insn (op, "PRINT_OPERAND, invalid insn for %%F");
3378 else if (letter == 'W')
3381 case EQ: fputs ("c1t", file); break;
3382 case NE: fputs ("c1f", file); break;
3384 abort_with_insn (op, "PRINT_OPERAND, invalid insn for %%W");
3387 else if (letter == 'A')
3388 fputs (code == LABEL_REF ? "i" : "in", file);
3390 else if (letter == 'P')
3392 if (code == LABEL_REF)
3393 output_addr_const (file, op);
3394 else if (code != PC)
3395 output_operand_lossage ("invalid %%P operand");
3398 else if (letter == 'p')
3401 if (code != CONST_INT
3402 || (value = exact_log2 (INTVAL (op))) < 0)
3403 output_operand_lossage ("invalid %%p value");
3404 fprintf (file, "%d", value);
3407 else if (letter == 'Z')
3414 regnum = REGNO (op);
3417 fprintf (file, "%s,", reg_names[regnum]);
3420 else if (code == REG || code == SUBREG)
3425 regnum = REGNO (op);
3427 regnum = true_regnum (op);
3429 if ((letter == 'M' && ! WORDS_BIG_ENDIAN)
3430 || (letter == 'L' && WORDS_BIG_ENDIAN)
3434 fprintf (file, "%s", reg_names[regnum]);
3437 else if (code == MEM)
3440 output_address (plus_constant (XEXP (op, 0), 4));
3442 output_address (XEXP (op, 0));
3445 else if (code == CONST_DOUBLE
3446 && GET_MODE_CLASS (GET_MODE (op)) == MODE_FLOAT)
3450 real_to_decimal (s, CONST_DOUBLE_REAL_VALUE (op), sizeof (s), 0, 1);
3454 else if (letter == 'x' && GET_CODE (op) == CONST_INT)
3455 fprintf (file, HOST_WIDE_INT_PRINT_HEX, 0xffff & INTVAL(op));
3457 else if (letter == 'X' && GET_CODE(op) == CONST_INT)
3458 fprintf (file, HOST_WIDE_INT_PRINT_HEX, 0xffff & (INTVAL (op) >> 16));
3460 else if (letter == 'd' && GET_CODE(op) == CONST_INT)
3461 fprintf (file, HOST_WIDE_INT_PRINT_DEC, (INTVAL(op)));
3463 else if (letter == 'z' && GET_CODE (op) == CONST_INT && INTVAL (op) == 0)
3464 fputs (reg_names[GP_REG_FIRST], file);
3466 else if (letter == 'd' || letter == 'x' || letter == 'X')
3467 output_operand_lossage ("invalid use of %%d, %%x, or %%X");
3469 else if (letter == 'B')
3470 fputs (code == EQ ? "z" : "n", file);
3471 else if (letter == 'b')
3472 fputs (code == EQ ? "n" : "z", file);
3473 else if (letter == 'T')
3474 fputs (code == EQ ? "f" : "t", file);
3475 else if (letter == 't')
3476 fputs (code == EQ ? "t" : "f", file);
3478 else if (code == CONST && GET_CODE (XEXP (op, 0)) == REG)
3480 print_operand (file, XEXP (op, 0), letter);
3484 output_addr_const (file, op);
3488 iq2000_rtx_costs (rtx x, int code, int outer_code ATTRIBUTE_UNUSED, int * total)
3490 enum machine_mode mode = GET_MODE (x);
3496 int num_words = (GET_MODE_SIZE (mode) > UNITS_PER_WORD) ? 2 : 1;
3498 if (simple_memory_operand (x, mode))
3499 return COSTS_N_INSNS (num_words);
3501 * total = COSTS_N_INSNS (2 * num_words);
3506 * total = COSTS_N_INSNS (6);
3513 * total = COSTS_N_INSNS (mode == DImode ? 2 : 1);
3520 * total = COSTS_N_INSNS ((GET_CODE (XEXP (x, 1)) == CONST_INT) ? 4 : 12);
3522 * total = COSTS_N_INSNS (1);
3526 if (mode == SFmode || mode == DFmode)
3527 * total = COSTS_N_INSNS (1);
3529 * total = COSTS_N_INSNS (4);
3534 if (mode == SFmode || mode == DFmode)
3535 * total = COSTS_N_INSNS (6);
3536 else if (mode == DImode)
3537 * total = COSTS_N_INSNS (4);
3539 * total = COSTS_N_INSNS (1);
3543 * total = (mode == DImode) ? 4 : 1;
3548 * total = COSTS_N_INSNS (7);
3549 else if (mode == DFmode)
3550 * total = COSTS_N_INSNS (8);
3552 * total = COSTS_N_INSNS (10);
3558 * total = COSTS_N_INSNS (23);
3559 else if (mode == DFmode)
3560 * total = COSTS_N_INSNS (36);
3562 * total = COSTS_N_INSNS (69);
3567 * total = COSTS_N_INSNS (69);
3571 * total = COSTS_N_INSNS (2);
3575 * total = COSTS_N_INSNS (1);
3583 * total = COSTS_N_INSNS (2);
3588 rtx offset = const0_rtx;
3589 rtx symref = eliminate_constant_term (XEXP (x, 0), & offset);
3591 if (GET_CODE (symref) == LABEL_REF)
3592 * total = COSTS_N_INSNS (2);
3593 else if (GET_CODE (symref) != SYMBOL_REF)
3594 * total = COSTS_N_INSNS (4);
3595 /* Let's be paranoid.... */
3596 else if (INTVAL (offset) < -32768 || INTVAL (offset) > 32767)
3597 * total = COSTS_N_INSNS (2);
3599 * total = COSTS_N_INSNS (SYMBOL_REF_FLAG (symref) ? 1 : 2);
3604 * total = COSTS_N_INSNS (SYMBOL_REF_FLAG (x) ? 1 : 2);
3611 split_double (x, & high, & low);
3613 * total = COSTS_N_INSNS ( (high == CONST0_RTX (GET_MODE (high))
3614 || low == CONST0_RTX (GET_MODE (low)))
3625 #include "gt-iq2000.h"