* doc/tm.texi (INIT_CUMULATIVE_ARGS): Update doco.
[official-gcc.git] / gcc / config / iq2000 / iq2000.c
blobca48c915d1d7895ff92a45afc600031c130aa756
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)
9 any later version.
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. */
21 #include "config.h"
22 #include "system.h"
23 #include "coretypes.h"
24 #include <signal.h>
25 #include "tm.h"
26 #include "tree.h"
27 #include "rtl.h"
28 #include "regs.h"
29 #include "hard-reg-set.h"
30 #include "real.h"
31 #include "insn-config.h"
32 #include "conditions.h"
33 #include "output.h"
34 #include "insn-attr.h"
35 #include "flags.h"
36 #include "function.h"
37 #include "expr.h"
38 #include "optabs.h"
39 #include "libfuncs.h"
40 #include "recog.h"
41 #include "toplev.h"
42 #include "reload.h"
43 #include "ggc.h"
44 #include "tm_p.h"
45 #include "debug.h"
46 #include "target.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
51 of EQ, NE, etc. */
53 enum internal_test
55 ITEST_EQ,
56 ITEST_NE,
57 ITEST_GT,
58 ITEST_GE,
59 ITEST_LT,
60 ITEST_LE,
61 ITEST_GTU,
62 ITEST_GEU,
63 ITEST_LTU,
64 ITEST_LEU,
65 ITEST_MAX
68 struct constant;
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. */
89 } iq2000_frame_info;
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. */
118 int iq2000_isa;
120 /* Cached operands, and operator to compare for use in set/branch/trap
121 on condition codes. */
122 rtx branch_cmp[2];
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 *,
169 int);
170 static bool iq2000_rtx_costs (rtx, int, int, int *);
171 static int iq2000_address_cost (rtx);
172 static void iq2000_select_section (tree, int, unsigned HOST_WIDE_INT);
173 static bool iq2000_return_in_memory (tree, tree);
175 #undef TARGET_INIT_BUILTINS
176 #define TARGET_INIT_BUILTINS iq2000_init_builtins
177 #undef TARGET_EXPAND_BUILTIN
178 #define TARGET_EXPAND_BUILTIN iq2000_expand_builtin
179 #undef TARGET_ASM_SELECT_RTX_SECTION
180 #define TARGET_ASM_SELECT_RTX_SECTION iq2000_select_rtx_section
181 #undef TARGET_RTX_COSTS
182 #define TARGET_RTX_COSTS iq2000_rtx_costs
183 #undef TARGET_ADDRESS_COST
184 #define TARGET_ADDRESS_COST iq2000_address_cost
185 #undef TARGET_ASM_SELECT_SECTION
186 #define TARGET_ASM_SELECT_SECTION iq2000_select_section
188 #undef TARGET_PROMOTE_FUNCTION_ARGS
189 #define TARGET_PROMOTE_FUNCTION_ARGS hook_bool_tree_true
190 #undef TARGET_PROMOTE_FUNCTION_RETURN
191 #define TARGET_PROMOTE_FUNCTION_RETURN hook_bool_tree_true
192 #undef TARGET_PROMOTE_PROTOTYPES
193 #define TARGET_PROMOTE_PROTOTYPES hook_bool_tree_true
195 #undef TARGET_STRUCT_VALUE_RTX
196 #define TARGET_STRUCT_VALUE_RTX hook_rtx_tree_int_null
197 #undef TARGET_RETURN_IN_MEMORY
198 #define TARGET_RETURN_IN_MEMORY iq2000_return_in_memory
200 #undef TARGET_SETUP_INCOMING_VARARGS
201 #define TARGET_SETUP_INCOMING_VARARGS iq2000_setup_incoming_varargs
202 #undef TARGET_STRICT_ARGUMENT_NAMING
203 #define TARGET_STRICT_ARGUMENT_NAMING hook_bool_CUMULATIVE_ARGS_true
205 struct gcc_target targetm = TARGET_INITIALIZER;
207 /* Return 1 if OP can be used as an operand where a register or 16 bit unsigned
208 integer is needed. */
211 uns_arith_operand (rtx op, enum machine_mode mode)
213 if (GET_CODE (op) == CONST_INT && SMALL_INT_UNSIGNED (op))
214 return 1;
216 return register_operand (op, mode);
219 /* Return 1 if OP can be used as an operand where a 16 bit integer is needed. */
222 arith_operand (rtx op, enum machine_mode mode)
224 if (GET_CODE (op) == CONST_INT && SMALL_INT (op))
225 return 1;
227 return register_operand (op, mode);
230 /* Return 1 if OP is a integer which fits in 16 bits. */
233 small_int (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
235 return (GET_CODE (op) == CONST_INT && SMALL_INT (op));
238 /* Return 1 if OP is a 32 bit integer which is too big to be loaded with one
239 instruction. */
242 large_int (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
244 HOST_WIDE_INT value;
246 if (GET_CODE (op) != CONST_INT)
247 return 0;
249 value = INTVAL (op);
251 /* IOR reg,$r0,value. */
252 if ((value & ~ ((HOST_WIDE_INT) 0x0000ffff)) == 0)
253 return 0;
255 /* SUBU reg,$r0,value. */
256 if (((unsigned HOST_WIDE_INT) (value + 32768)) <= 32767)
257 return 0;
259 /* LUI reg,value >> 16. */
260 if ((value & 0x0000ffff) == 0)
261 return 0;
263 return 1;
266 /* Return 1 if OP is a register or the constant 0. */
269 reg_or_0_operand (rtx op, enum machine_mode mode)
271 switch (GET_CODE (op))
273 case CONST_INT:
274 return INTVAL (op) == 0;
276 case CONST_DOUBLE:
277 return op == CONST0_RTX (mode);
279 case REG:
280 case SUBREG:
281 return register_operand (op, mode);
283 default:
284 break;
287 return 0;
290 /* Return 1 if OP is a memory operand that fits in a single instruction
291 (ie, register + small offset). */
294 simple_memory_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
296 rtx addr, plus0, plus1;
298 /* Eliminate non-memory operations. */
299 if (GET_CODE (op) != MEM)
300 return 0;
302 /* Dword operations really put out 2 instructions, so eliminate them. */
303 if (GET_MODE_SIZE (GET_MODE (op)) > (unsigned) UNITS_PER_WORD)
304 return 0;
306 /* Decode the address now. */
307 addr = XEXP (op, 0);
308 switch (GET_CODE (addr))
310 case REG:
311 case LO_SUM:
312 return 1;
314 case CONST_INT:
315 return SMALL_INT (addr);
317 case PLUS:
318 plus0 = XEXP (addr, 0);
319 plus1 = XEXP (addr, 1);
320 if (GET_CODE (plus0) == REG
321 && GET_CODE (plus1) == CONST_INT && SMALL_INT (plus1)
322 && SMALL_INT_UNSIGNED (plus1) /* No negative offsets. */)
323 return 1;
325 else if (GET_CODE (plus1) == REG
326 && GET_CODE (plus0) == CONST_INT && SMALL_INT (plus0)
327 && SMALL_INT_UNSIGNED (plus1) /* No negative offsets. */)
328 return 1;
330 else
331 return 0;
333 case SYMBOL_REF:
334 return 0;
336 default:
337 break;
340 return 0;
343 /* Return nonzero if the code of this rtx pattern is EQ or NE. */
346 equality_op (rtx op, enum machine_mode mode)
348 if (mode != GET_MODE (op))
349 return 0;
351 return GET_CODE (op) == EQ || GET_CODE (op) == NE;
354 /* Return nonzero if the code is a relational operations (EQ, LE, etc). */
357 cmp_op (rtx op, enum machine_mode mode)
359 if (mode != GET_MODE (op))
360 return 0;
362 return GET_RTX_CLASS (GET_CODE (op)) == '<';
365 /* Return nonzero if the operand is either the PC or a label_ref. */
368 pc_or_label_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
370 if (op == pc_rtx)
371 return 1;
373 if (GET_CODE (op) == LABEL_REF)
374 return 1;
376 return 0;
379 /* Return nonzero if OP is a valid operand for a call instruction. */
382 call_insn_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
384 return (CONSTANT_ADDRESS_P (op)
385 || (GET_CODE (op) == REG && op != arg_pointer_rtx
386 && ! (REGNO (op) >= FIRST_PSEUDO_REGISTER
387 && REGNO (op) <= LAST_VIRTUAL_REGISTER)));
390 /* Return nonzero if OP is valid as a source operand for a move instruction. */
393 move_operand (rtx op, enum machine_mode mode)
395 /* Accept any general operand after reload has started; doing so
396 avoids losing if reload does an in-place replacement of a register
397 with a SYMBOL_REF or CONST. */
398 return (general_operand (op, mode)
399 && (! (iq2000_check_split (op, mode))
400 || reload_in_progress || reload_completed));
403 /* Return nonzero if OP is a constant power of 2. */
406 power_of_2_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
408 int intval;
410 if (GET_CODE (op) != CONST_INT)
411 return 0;
412 else
413 intval = INTVAL (op);
415 return ((intval & ((unsigned)(intval) - 1)) == 0);
418 /* Return nonzero if we split the address into high and low parts. */
421 iq2000_check_split (rtx address, enum machine_mode mode)
423 /* This is the same check used in simple_memory_operand.
424 We use it here because LO_SUM is not offsettable. */
425 if (GET_MODE_SIZE (mode) > (unsigned) UNITS_PER_WORD)
426 return 0;
428 if ((GET_CODE (address) == SYMBOL_REF)
429 || (GET_CODE (address) == CONST
430 && GET_CODE (XEXP (XEXP (address, 0), 0)) == SYMBOL_REF)
431 || GET_CODE (address) == LABEL_REF)
432 return 1;
434 return 0;
437 /* Return nonzero if REG is valid for MODE. */
440 iq2000_reg_mode_ok_for_base_p (rtx reg,
441 enum machine_mode mode ATTRIBUTE_UNUSED,
442 int strict)
444 return (strict
445 ? REGNO_MODE_OK_FOR_BASE_P (REGNO (reg), mode)
446 : GP_REG_OR_PSEUDO_NONSTRICT_P (REGNO (reg), mode));
449 /* Return a nonzero value if XINSN is a legitimate address for a
450 memory operand of the indicated MODE. STRICT is nonzero if this
451 function is called during reload. */
454 iq2000_legitimate_address_p (enum machine_mode mode, rtx xinsn, int strict)
456 if (TARGET_DEBUG_A_MODE)
458 GO_PRINTF2 ("\n========== GO_IF_LEGITIMATE_ADDRESS, %sstrict\n",
459 strict ? "" : "not ");
460 GO_DEBUG_RTX (xinsn);
463 /* Check for constant before stripping off SUBREG, so that we don't
464 accept (subreg (const_int)) which will fail to reload. */
465 if (CONSTANT_ADDRESS_P (xinsn)
466 && ! (iq2000_check_split (xinsn, mode))
467 && ! (GET_CODE (xinsn) == CONST_INT && ! SMALL_INT (xinsn)))
468 return 1;
470 while (GET_CODE (xinsn) == SUBREG)
471 xinsn = SUBREG_REG (xinsn);
473 if (GET_CODE (xinsn) == REG
474 && iq2000_reg_mode_ok_for_base_p (xinsn, mode, strict))
475 return 1;
477 if (GET_CODE (xinsn) == LO_SUM)
479 rtx xlow0 = XEXP (xinsn, 0);
480 rtx xlow1 = XEXP (xinsn, 1);
482 while (GET_CODE (xlow0) == SUBREG)
483 xlow0 = SUBREG_REG (xlow0);
484 if (GET_CODE (xlow0) == REG
485 && iq2000_reg_mode_ok_for_base_p (xlow0, mode, strict)
486 && iq2000_check_split (xlow1, mode))
487 return 1;
490 if (GET_CODE (xinsn) == PLUS)
492 rtx xplus0 = XEXP (xinsn, 0);
493 rtx xplus1 = XEXP (xinsn, 1);
494 enum rtx_code code0;
495 enum rtx_code code1;
497 while (GET_CODE (xplus0) == SUBREG)
498 xplus0 = SUBREG_REG (xplus0);
499 code0 = GET_CODE (xplus0);
501 while (GET_CODE (xplus1) == SUBREG)
502 xplus1 = SUBREG_REG (xplus1);
503 code1 = GET_CODE (xplus1);
505 if (code0 == REG
506 && iq2000_reg_mode_ok_for_base_p (xplus0, mode, strict))
508 if (code1 == CONST_INT && SMALL_INT (xplus1)
509 && SMALL_INT_UNSIGNED (xplus1) /* No negative offsets */)
510 return 1;
514 if (TARGET_DEBUG_A_MODE)
515 GO_PRINTF ("Not a legitimate address\n");
517 /* The address was not legitimate. */
518 return 0;
521 /* Returns an operand string for the given instruction's delay slot,
522 after updating filled delay slot statistics.
524 We assume that operands[0] is the target register that is set.
526 In order to check the next insn, most of this functionality is moved
527 to FINAL_PRESCAN_INSN, and we just set the global variables that
528 it needs. */
530 const char *
531 iq2000_fill_delay_slot (const char *ret, enum delay_type type, rtx operands[],
532 rtx cur_insn)
534 rtx set_reg;
535 enum machine_mode mode;
536 rtx next_insn = cur_insn ? NEXT_INSN (cur_insn) : NULL_RTX;
537 int num_nops;
539 if (type == DELAY_LOAD || type == DELAY_FCMP)
540 num_nops = 1;
542 else
543 num_nops = 0;
545 /* Make sure that we don't put nop's after labels. */
546 next_insn = NEXT_INSN (cur_insn);
547 while (next_insn != 0
548 && (GET_CODE (next_insn) == NOTE
549 || GET_CODE (next_insn) == CODE_LABEL))
550 next_insn = NEXT_INSN (next_insn);
552 dslots_load_total += num_nops;
553 if (TARGET_DEBUG_C_MODE
554 || type == DELAY_NONE
555 || operands == 0
556 || cur_insn == 0
557 || next_insn == 0
558 || GET_CODE (next_insn) == CODE_LABEL
559 || (set_reg = operands[0]) == 0)
561 dslots_number_nops = 0;
562 iq2000_load_reg = 0;
563 iq2000_load_reg2 = 0;
564 iq2000_load_reg3 = 0;
565 iq2000_load_reg4 = 0;
567 return ret;
570 set_reg = operands[0];
571 if (set_reg == 0)
572 return ret;
574 while (GET_CODE (set_reg) == SUBREG)
575 set_reg = SUBREG_REG (set_reg);
577 mode = GET_MODE (set_reg);
578 dslots_number_nops = num_nops;
579 iq2000_load_reg = set_reg;
580 if (GET_MODE_SIZE (mode)
581 > (unsigned) (UNITS_PER_WORD))
582 iq2000_load_reg2 = gen_rtx_REG (SImode, REGNO (set_reg) + 1);
583 else
584 iq2000_load_reg2 = 0;
586 return ret;
589 /* Determine whether a memory reference takes one (based off of the GP
590 pointer), two (normal), or three (label + reg) instructions, and bump the
591 appropriate counter for -mstats. */
593 static void
594 iq2000_count_memory_refs (rtx op, int num)
596 int additional = 0;
597 int n_words = 0;
598 rtx addr, plus0, plus1;
599 enum rtx_code code0, code1;
600 int looping;
602 if (TARGET_DEBUG_B_MODE)
604 fprintf (stderr, "\n========== iq2000_count_memory_refs:\n");
605 debug_rtx (op);
608 /* Skip MEM if passed, otherwise handle movsi of address. */
609 addr = (GET_CODE (op) != MEM) ? op : XEXP (op, 0);
611 /* Loop, going through the address RTL. */
614 looping = FALSE;
615 switch (GET_CODE (addr))
617 case REG:
618 case CONST_INT:
619 case LO_SUM:
620 break;
622 case PLUS:
623 plus0 = XEXP (addr, 0);
624 plus1 = XEXP (addr, 1);
625 code0 = GET_CODE (plus0);
626 code1 = GET_CODE (plus1);
628 if (code0 == REG)
630 additional++;
631 addr = plus1;
632 looping = 1;
633 continue;
636 if (code0 == CONST_INT)
638 addr = plus1;
639 looping = 1;
640 continue;
643 if (code1 == REG)
645 additional++;
646 addr = plus0;
647 looping = 1;
648 continue;
651 if (code1 == CONST_INT)
653 addr = plus0;
654 looping = 1;
655 continue;
658 if (code0 == SYMBOL_REF || code0 == LABEL_REF || code0 == CONST)
660 addr = plus0;
661 looping = 1;
662 continue;
665 if (code1 == SYMBOL_REF || code1 == LABEL_REF || code1 == CONST)
667 addr = plus1;
668 looping = 1;
669 continue;
672 break;
674 case LABEL_REF:
675 n_words = 2; /* Always 2 words. */
676 break;
678 case CONST:
679 addr = XEXP (addr, 0);
680 looping = 1;
681 continue;
683 case SYMBOL_REF:
684 n_words = SYMBOL_REF_FLAG (addr) ? 1 : 2;
685 break;
687 default:
688 break;
691 while (looping);
693 if (n_words == 0)
694 return;
696 n_words += additional;
697 if (n_words > 3)
698 n_words = 3;
700 num_refs[n_words-1] += num;
703 /* Abort after printing out a specific insn. */
705 static void
706 abort_with_insn (rtx insn, const char * reason)
708 error (reason);
709 debug_rtx (insn);
710 abort ();
713 /* Return the appropriate instructions to move one operand to another. */
715 const char *
716 iq2000_move_1word (rtx operands[], rtx insn, int unsignedp)
718 const char *ret = 0;
719 rtx op0 = operands[0];
720 rtx op1 = operands[1];
721 enum rtx_code code0 = GET_CODE (op0);
722 enum rtx_code code1 = GET_CODE (op1);
723 enum machine_mode mode = GET_MODE (op0);
724 int subreg_offset0 = 0;
725 int subreg_offset1 = 0;
726 enum delay_type delay = DELAY_NONE;
728 while (code0 == SUBREG)
730 subreg_offset0 += subreg_regno_offset (REGNO (SUBREG_REG (op0)),
731 GET_MODE (SUBREG_REG (op0)),
732 SUBREG_BYTE (op0),
733 GET_MODE (op0));
734 op0 = SUBREG_REG (op0);
735 code0 = GET_CODE (op0);
738 while (code1 == SUBREG)
740 subreg_offset1 += subreg_regno_offset (REGNO (SUBREG_REG (op1)),
741 GET_MODE (SUBREG_REG (op1)),
742 SUBREG_BYTE (op1),
743 GET_MODE (op1));
744 op1 = SUBREG_REG (op1);
745 code1 = GET_CODE (op1);
748 /* For our purposes, a condition code mode is the same as SImode. */
749 if (mode == CCmode)
750 mode = SImode;
752 if (code0 == REG)
754 int regno0 = REGNO (op0) + subreg_offset0;
756 if (code1 == REG)
758 int regno1 = REGNO (op1) + subreg_offset1;
760 /* Do not do anything for assigning a register to itself */
761 if (regno0 == regno1)
762 ret = "";
764 else if (GP_REG_P (regno0))
766 if (GP_REG_P (regno1))
767 ret = "or\t%0,%%0,%1";
772 else if (code1 == MEM)
774 delay = DELAY_LOAD;
776 if (TARGET_STATS)
777 iq2000_count_memory_refs (op1, 1);
779 if (GP_REG_P (regno0))
781 /* For loads, use the mode of the memory item, instead of the
782 target, so zero/sign extend can use this code as well. */
783 switch (GET_MODE (op1))
785 default:
786 break;
787 case SFmode:
788 ret = "lw\t%0,%1";
789 break;
790 case SImode:
791 case CCmode:
792 ret = "lw\t%0,%1";
793 break;
794 case HImode:
795 ret = (unsignedp) ? "lhu\t%0,%1" : "lh\t%0,%1";
796 break;
797 case QImode:
798 ret = (unsignedp) ? "lbu\t%0,%1" : "lb\t%0,%1";
799 break;
804 else if (code1 == CONST_INT
805 || (code1 == CONST_DOUBLE
806 && GET_MODE (op1) == VOIDmode))
808 if (code1 == CONST_DOUBLE)
810 /* This can happen when storing constants into long long
811 bitfields. Just store the least significant word of
812 the value. */
813 operands[1] = op1 = GEN_INT (CONST_DOUBLE_LOW (op1));
816 if (INTVAL (op1) == 0)
818 if (GP_REG_P (regno0))
819 ret = "or\t%0,%%0,%z1";
821 else if (GP_REG_P (regno0))
823 if (SMALL_INT_UNSIGNED (op1))
824 ret = "ori\t%0,%%0,%x1\t\t\t# %1";
825 else if (SMALL_INT (op1))
826 ret = "addiu\t%0,%%0,%1\t\t\t# %1";
827 else
828 ret = "lui\t%0,%X1\t\t\t# %1\n\tori\t%0,%0,%x1";
832 else if (code1 == CONST_DOUBLE && mode == SFmode)
834 if (op1 == CONST0_RTX (SFmode))
836 if (GP_REG_P (regno0))
837 ret = "or\t%0,%%0,%.";
840 else
842 delay = DELAY_LOAD;
843 ret = "li.s\t%0,%1";
847 else if (code1 == LABEL_REF)
849 if (TARGET_STATS)
850 iq2000_count_memory_refs (op1, 1);
852 ret = "la\t%0,%a1";
855 else if (code1 == SYMBOL_REF || code1 == CONST)
857 if (TARGET_STATS)
858 iq2000_count_memory_refs (op1, 1);
860 ret = "la\t%0,%a1";
863 else if (code1 == PLUS)
865 rtx add_op0 = XEXP (op1, 0);
866 rtx add_op1 = XEXP (op1, 1);
868 if (GET_CODE (XEXP (op1, 1)) == REG
869 && GET_CODE (XEXP (op1, 0)) == CONST_INT)
870 add_op0 = XEXP (op1, 1), add_op1 = XEXP (op1, 0);
872 operands[2] = add_op0;
873 operands[3] = add_op1;
874 ret = "add%:\t%0,%2,%3";
877 else if (code1 == HIGH)
879 operands[1] = XEXP (op1, 0);
880 ret = "lui\t%0,%%hi(%1)";
884 else if (code0 == MEM)
886 if (TARGET_STATS)
887 iq2000_count_memory_refs (op0, 1);
889 if (code1 == REG)
891 int regno1 = REGNO (op1) + subreg_offset1;
893 if (GP_REG_P (regno1))
895 switch (mode)
897 case SFmode: ret = "sw\t%1,%0"; break;
898 case SImode: ret = "sw\t%1,%0"; break;
899 case HImode: ret = "sh\t%1,%0"; break;
900 case QImode: ret = "sb\t%1,%0"; break;
901 default: break;
906 else if (code1 == CONST_INT && INTVAL (op1) == 0)
908 switch (mode)
910 case SFmode: ret = "sw\t%z1,%0"; break;
911 case SImode: ret = "sw\t%z1,%0"; break;
912 case HImode: ret = "sh\t%z1,%0"; break;
913 case QImode: ret = "sb\t%z1,%0"; break;
914 default: break;
918 else if (code1 == CONST_DOUBLE && op1 == CONST0_RTX (mode))
920 switch (mode)
922 case SFmode: ret = "sw\t%.,%0"; break;
923 case SImode: ret = "sw\t%.,%0"; break;
924 case HImode: ret = "sh\t%.,%0"; break;
925 case QImode: ret = "sb\t%.,%0"; break;
926 default: break;
931 if (ret == 0)
933 abort_with_insn (insn, "Bad move");
934 return 0;
937 if (delay != DELAY_NONE)
938 return iq2000_fill_delay_slot (ret, delay, operands, insn);
940 return ret;
943 /* Provide the costs of an addressing mode that contains ADDR. */
945 static int
946 iq2000_address_cost (rtx addr)
948 switch (GET_CODE (addr))
950 case LO_SUM:
951 return 1;
953 case LABEL_REF:
954 return 2;
956 case CONST:
958 rtx offset = const0_rtx;
960 addr = eliminate_constant_term (XEXP (addr, 0), & offset);
961 if (GET_CODE (addr) == LABEL_REF)
962 return 2;
964 if (GET_CODE (addr) != SYMBOL_REF)
965 return 4;
967 if (! SMALL_INT (offset))
968 return 2;
971 /* Fall through. */
973 case SYMBOL_REF:
974 return SYMBOL_REF_FLAG (addr) ? 1 : 2;
976 case PLUS:
978 rtx plus0 = XEXP (addr, 0);
979 rtx plus1 = XEXP (addr, 1);
981 if (GET_CODE (plus0) != REG && GET_CODE (plus1) == REG)
982 plus0 = XEXP (addr, 1), plus1 = XEXP (addr, 0);
984 if (GET_CODE (plus0) != REG)
985 break;
987 switch (GET_CODE (plus1))
989 case CONST_INT:
990 return SMALL_INT (plus1) ? 1 : 2;
992 case CONST:
993 case SYMBOL_REF:
994 case LABEL_REF:
995 case HIGH:
996 case LO_SUM:
997 return iq2000_address_cost (plus1) + 1;
999 default:
1000 break;
1004 default:
1005 break;
1008 return 4;
1011 /* Make normal rtx_code into something we can index from an array. */
1013 static enum internal_test
1014 map_test_to_internal_test (enum rtx_code test_code)
1016 enum internal_test test = ITEST_MAX;
1018 switch (test_code)
1020 case EQ: test = ITEST_EQ; break;
1021 case NE: test = ITEST_NE; break;
1022 case GT: test = ITEST_GT; break;
1023 case GE: test = ITEST_GE; break;
1024 case LT: test = ITEST_LT; break;
1025 case LE: test = ITEST_LE; break;
1026 case GTU: test = ITEST_GTU; break;
1027 case GEU: test = ITEST_GEU; break;
1028 case LTU: test = ITEST_LTU; break;
1029 case LEU: test = ITEST_LEU; break;
1030 default: break;
1033 return test;
1036 /* Generate the code to do a TEST_CODE comparison on two integer values CMP0
1037 and CMP1. P_INVERT is NULL or ptr if branch needs to reverse its test.
1038 The return value RESULT is:
1039 (reg:SI xx) The pseudo register the comparison is in
1040 0 No register, generate a simple branch. */
1043 gen_int_relational (enum rtx_code test_code, rtx result, rtx cmp0, rtx cmp1,
1044 int *p_invert)
1046 struct cmp_info
1048 enum rtx_code test_code; /* Code to use in instruction (LT vs. LTU). */
1049 int const_low; /* Low bound of constant we can accept. */
1050 int const_high; /* High bound of constant we can accept. */
1051 int const_add; /* Constant to add (convert LE -> LT). */
1052 int reverse_regs; /* Reverse registers in test. */
1053 int invert_const; /* != 0 if invert value if cmp1 is constant. */
1054 int invert_reg; /* != 0 if invert value if cmp1 is register. */
1055 int unsignedp; /* != 0 for unsigned comparisons. */
1058 static struct cmp_info info[ (int)ITEST_MAX ] =
1060 { XOR, 0, 65535, 0, 0, 0, 0, 0 }, /* EQ */
1061 { XOR, 0, 65535, 0, 0, 1, 1, 0 }, /* NE */
1062 { LT, -32769, 32766, 1, 1, 1, 0, 0 }, /* GT */
1063 { LT, -32768, 32767, 0, 0, 1, 1, 0 }, /* GE */
1064 { LT, -32768, 32767, 0, 0, 0, 0, 0 }, /* LT */
1065 { LT, -32769, 32766, 1, 1, 0, 1, 0 }, /* LE */
1066 { LTU, -32769, 32766, 1, 1, 1, 0, 1 }, /* GTU */
1067 { LTU, -32768, 32767, 0, 0, 1, 1, 1 }, /* GEU */
1068 { LTU, -32768, 32767, 0, 0, 0, 0, 1 }, /* LTU */
1069 { LTU, -32769, 32766, 1, 1, 0, 1, 1 }, /* LEU */
1072 enum internal_test test;
1073 enum machine_mode mode;
1074 struct cmp_info *p_info;
1075 int branch_p;
1076 int eqne_p;
1077 int invert;
1078 rtx reg;
1079 rtx reg2;
1081 test = map_test_to_internal_test (test_code);
1082 if (test == ITEST_MAX)
1083 abort ();
1085 p_info = &info[(int) test];
1086 eqne_p = (p_info->test_code == XOR);
1088 mode = GET_MODE (cmp0);
1089 if (mode == VOIDmode)
1090 mode = GET_MODE (cmp1);
1092 /* Eliminate simple branches. */
1093 branch_p = (result == 0);
1094 if (branch_p)
1096 if (GET_CODE (cmp0) == REG || GET_CODE (cmp0) == SUBREG)
1098 /* Comparisons against zero are simple branches. */
1099 if (GET_CODE (cmp1) == CONST_INT && INTVAL (cmp1) == 0)
1100 return 0;
1102 /* Test for beq/bne. */
1103 if (eqne_p)
1104 return 0;
1107 /* Allocate a pseudo to calculate the value in. */
1108 result = gen_reg_rtx (mode);
1111 /* Make sure we can handle any constants given to us. */
1112 if (GET_CODE (cmp0) == CONST_INT)
1113 cmp0 = force_reg (mode, cmp0);
1115 if (GET_CODE (cmp1) == CONST_INT)
1117 HOST_WIDE_INT value = INTVAL (cmp1);
1119 if (value < p_info->const_low
1120 || value > p_info->const_high)
1121 cmp1 = force_reg (mode, cmp1);
1124 /* See if we need to invert the result. */
1125 invert = (GET_CODE (cmp1) == CONST_INT
1126 ? p_info->invert_const : p_info->invert_reg);
1128 if (p_invert != (int *)0)
1130 *p_invert = invert;
1131 invert = 0;
1134 /* Comparison to constants, may involve adding 1 to change a LT into LE.
1135 Comparison between two registers, may involve switching operands. */
1136 if (GET_CODE (cmp1) == CONST_INT)
1138 if (p_info->const_add != 0)
1140 HOST_WIDE_INT new = INTVAL (cmp1) + p_info->const_add;
1142 /* If modification of cmp1 caused overflow,
1143 we would get the wrong answer if we follow the usual path;
1144 thus, x > 0xffffffffU would turn into x > 0U. */
1145 if ((p_info->unsignedp
1146 ? (unsigned HOST_WIDE_INT) new >
1147 (unsigned HOST_WIDE_INT) INTVAL (cmp1)
1148 : new > INTVAL (cmp1))
1149 != (p_info->const_add > 0))
1151 /* This test is always true, but if INVERT is true then
1152 the result of the test needs to be inverted so 0 should
1153 be returned instead. */
1154 emit_move_insn (result, invert ? const0_rtx : const_true_rtx);
1155 return result;
1157 else
1158 cmp1 = GEN_INT (new);
1162 else if (p_info->reverse_regs)
1164 rtx temp = cmp0;
1165 cmp0 = cmp1;
1166 cmp1 = temp;
1169 if (test == ITEST_NE && GET_CODE (cmp1) == CONST_INT && INTVAL (cmp1) == 0)
1170 reg = cmp0;
1171 else
1173 reg = (invert || eqne_p) ? gen_reg_rtx (mode) : result;
1174 convert_move (reg, gen_rtx_fmt_ee (p_info->test_code, mode, cmp0, cmp1), 0);
1177 if (test == ITEST_NE)
1179 convert_move (result, gen_rtx_GTU (mode, reg, const0_rtx), 0);
1180 if (p_invert != NULL)
1181 *p_invert = 0;
1182 invert = 0;
1185 else if (test == ITEST_EQ)
1187 reg2 = invert ? gen_reg_rtx (mode) : result;
1188 convert_move (reg2, gen_rtx_LTU (mode, reg, const1_rtx), 0);
1189 reg = reg2;
1192 if (invert)
1194 rtx one;
1196 one = const1_rtx;
1197 convert_move (result, gen_rtx_XOR (mode, reg, one), 0);
1200 return result;
1203 /* Emit the common code for doing conditional branches.
1204 operand[0] is the label to jump to.
1205 The comparison operands are saved away by cmp{si,di,sf,df}. */
1207 void
1208 gen_conditional_branch (rtx operands[], enum rtx_code test_code)
1210 enum cmp_type type = branch_type;
1211 rtx cmp0 = branch_cmp[0];
1212 rtx cmp1 = branch_cmp[1];
1213 enum machine_mode mode;
1214 rtx reg;
1215 int invert;
1216 rtx label1, label2;
1218 switch (type)
1220 case CMP_SI:
1221 case CMP_DI:
1222 mode = type == CMP_SI ? SImode : DImode;
1223 invert = 0;
1224 reg = gen_int_relational (test_code, NULL_RTX, cmp0, cmp1, &invert);
1226 if (reg)
1228 cmp0 = reg;
1229 cmp1 = const0_rtx;
1230 test_code = NE;
1232 else if (GET_CODE (cmp1) == CONST_INT && INTVAL (cmp1) != 0)
1233 /* We don't want to build a comparison against a nonzero
1234 constant. */
1235 cmp1 = force_reg (mode, cmp1);
1237 break;
1239 case CMP_SF:
1240 case CMP_DF:
1241 reg = gen_reg_rtx (CCmode);
1243 /* For cmp0 != cmp1, build cmp0 == cmp1, and test for result == 0. */
1244 emit_insn (gen_rtx_SET (VOIDmode, reg,
1245 gen_rtx_fmt_ee (test_code == NE ? EQ : test_code,
1246 CCmode, cmp0, cmp1)));
1248 test_code = test_code == NE ? EQ : NE;
1249 mode = CCmode;
1250 cmp0 = reg;
1251 cmp1 = const0_rtx;
1252 invert = 0;
1253 break;
1255 default:
1256 abort_with_insn (gen_rtx_fmt_ee (test_code, VOIDmode, cmp0, cmp1),
1257 "bad test");
1260 /* Generate the branch. */
1261 label1 = gen_rtx_LABEL_REF (VOIDmode, operands[0]);
1262 label2 = pc_rtx;
1264 if (invert)
1266 label2 = label1;
1267 label1 = pc_rtx;
1270 emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
1271 gen_rtx_IF_THEN_ELSE (VOIDmode,
1272 gen_rtx_fmt_ee (test_code,
1273 mode,
1274 cmp0, cmp1),
1275 label1, label2)));
1278 /* Initialize CUM for a function FNTYPE. */
1280 void
1281 init_cumulative_args (CUMULATIVE_ARGS *cum, tree fntype,
1282 rtx libname ATTRIBUTE_UNUSED)
1284 static CUMULATIVE_ARGS zero_cum;
1285 tree param;
1286 tree next_param;
1288 if (TARGET_DEBUG_D_MODE)
1290 fprintf (stderr,
1291 "\ninit_cumulative_args, fntype = 0x%.8lx", (long) fntype);
1293 if (!fntype)
1294 fputc ('\n', stderr);
1296 else
1298 tree ret_type = TREE_TYPE (fntype);
1300 fprintf (stderr, ", fntype code = %s, ret code = %s\n",
1301 tree_code_name[(int)TREE_CODE (fntype)],
1302 tree_code_name[(int)TREE_CODE (ret_type)]);
1306 *cum = zero_cum;
1308 /* Determine if this function has variable arguments. This is
1309 indicated by the last argument being 'void_type_mode' if there
1310 are no variable arguments. The standard IQ2000 calling sequence
1311 passes all arguments in the general purpose registers in this case. */
1313 for (param = fntype ? TYPE_ARG_TYPES (fntype) : 0;
1314 param != 0; param = next_param)
1316 next_param = TREE_CHAIN (param);
1317 if (next_param == 0 && TREE_VALUE (param) != void_type_node)
1318 cum->gp_reg_found = 1;
1322 /* Advance the argument of type TYPE and mode MODE to the next argument
1323 position in CUM. */
1325 void
1326 function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode, tree type,
1327 int named)
1329 if (TARGET_DEBUG_D_MODE)
1331 fprintf (stderr,
1332 "function_adv({gp reg found = %d, arg # = %2d, words = %2d}, %4s, ",
1333 cum->gp_reg_found, cum->arg_number, cum->arg_words,
1334 GET_MODE_NAME (mode));
1335 fprintf (stderr, HOST_PTR_PRINTF, (const PTR) type);
1336 fprintf (stderr, ", %d )\n\n", named);
1339 cum->arg_number++;
1340 switch (mode)
1342 case VOIDmode:
1343 break;
1345 default:
1346 if (GET_MODE_CLASS (mode) != MODE_COMPLEX_INT
1347 && GET_MODE_CLASS (mode) != MODE_COMPLEX_FLOAT)
1348 abort ();
1350 cum->gp_reg_found = 1;
1351 cum->arg_words += ((GET_MODE_SIZE (mode) + UNITS_PER_WORD - 1)
1352 / UNITS_PER_WORD);
1353 break;
1355 case BLKmode:
1356 cum->gp_reg_found = 1;
1357 cum->arg_words += ((int_size_in_bytes (type) + UNITS_PER_WORD - 1)
1358 / UNITS_PER_WORD);
1359 break;
1361 case SFmode:
1362 cum->arg_words ++;
1363 if (! cum->gp_reg_found && cum->arg_number <= 2)
1364 cum->fp_code += 1 << ((cum->arg_number - 1) * 2);
1365 break;
1367 case DFmode:
1368 cum->arg_words += 2;
1369 if (! cum->gp_reg_found && cum->arg_number <= 2)
1370 cum->fp_code += 2 << ((cum->arg_number - 1) * 2);
1371 break;
1373 case DImode:
1374 cum->gp_reg_found = 1;
1375 cum->arg_words += 2;
1376 break;
1378 case QImode:
1379 case HImode:
1380 case SImode:
1381 cum->gp_reg_found = 1;
1382 cum->arg_words ++;
1383 break;
1387 /* Return an RTL expression containing the register for the given mode MODE
1388 and type TYPE in CUM, or 0 if the argument is to be passed on the stack. */
1390 struct rtx_def *
1391 function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode, tree type,
1392 int named)
1394 rtx ret;
1395 int regbase = -1;
1396 int bias = 0;
1397 unsigned int *arg_words = &cum->arg_words;
1398 int struct_p = (type != 0
1399 && (TREE_CODE (type) == RECORD_TYPE
1400 || TREE_CODE (type) == UNION_TYPE
1401 || TREE_CODE (type) == QUAL_UNION_TYPE));
1403 if (TARGET_DEBUG_D_MODE)
1405 fprintf (stderr,
1406 "function_arg( {gp reg found = %d, arg # = %2d, words = %2d}, %4s, ",
1407 cum->gp_reg_found, cum->arg_number, cum->arg_words,
1408 GET_MODE_NAME (mode));
1409 fprintf (stderr, HOST_PTR_PRINTF, (const PTR) type);
1410 fprintf (stderr, ", %d ) = ", named);
1414 cum->last_arg_fp = 0;
1415 switch (mode)
1417 case SFmode:
1418 regbase = GP_ARG_FIRST;
1419 break;
1421 case DFmode:
1422 cum->arg_words += cum->arg_words & 1;
1424 regbase = GP_ARG_FIRST;
1425 break;
1427 default:
1428 if (GET_MODE_CLASS (mode) != MODE_COMPLEX_INT
1429 && GET_MODE_CLASS (mode) != MODE_COMPLEX_FLOAT)
1430 abort ();
1432 /* Drops through. */
1433 case BLKmode:
1434 if (type != NULL_TREE && TYPE_ALIGN (type) > (unsigned) BITS_PER_WORD)
1435 cum->arg_words += (cum->arg_words & 1);
1436 regbase = GP_ARG_FIRST;
1437 break;
1439 case VOIDmode:
1440 case QImode:
1441 case HImode:
1442 case SImode:
1443 regbase = GP_ARG_FIRST;
1444 break;
1446 case DImode:
1447 cum->arg_words += (cum->arg_words & 1);
1448 regbase = GP_ARG_FIRST;
1451 if (*arg_words >= (unsigned) MAX_ARGS_IN_REGISTERS)
1453 if (TARGET_DEBUG_D_MODE)
1454 fprintf (stderr, "<stack>%s\n", struct_p ? ", [struct]" : "");
1456 ret = 0;
1458 else
1460 if (regbase == -1)
1461 abort ();
1463 if (! type || TREE_CODE (type) != RECORD_TYPE
1464 || ! named || ! TYPE_SIZE_UNIT (type)
1465 || ! host_integerp (TYPE_SIZE_UNIT (type), 1))
1466 ret = gen_rtx_REG (mode, regbase + *arg_words + bias);
1467 else
1469 tree field;
1471 for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field))
1472 if (TREE_CODE (field) == FIELD_DECL
1473 && TREE_CODE (TREE_TYPE (field)) == REAL_TYPE
1474 && TYPE_PRECISION (TREE_TYPE (field)) == BITS_PER_WORD
1475 && host_integerp (bit_position (field), 0)
1476 && int_bit_position (field) % BITS_PER_WORD == 0)
1477 break;
1479 /* If the whole struct fits a DFmode register,
1480 we don't need the PARALLEL. */
1481 if (! field || mode == DFmode)
1482 ret = gen_rtx_REG (mode, regbase + *arg_words + bias);
1483 else
1485 unsigned int chunks;
1486 HOST_WIDE_INT bitpos;
1487 unsigned int regno;
1488 unsigned int i;
1490 /* ??? If this is a packed structure, then the last hunk won't
1491 be 64 bits. */
1492 chunks
1493 = tree_low_cst (TYPE_SIZE_UNIT (type), 1) / UNITS_PER_WORD;
1494 if (chunks + *arg_words + bias > (unsigned) MAX_ARGS_IN_REGISTERS)
1495 chunks = MAX_ARGS_IN_REGISTERS - *arg_words - bias;
1497 /* Assign_parms checks the mode of ENTRY_PARM, so we must
1498 use the actual mode here. */
1499 ret = gen_rtx_PARALLEL (mode, rtvec_alloc (chunks));
1501 bitpos = 0;
1502 regno = regbase + *arg_words + bias;
1503 field = TYPE_FIELDS (type);
1504 for (i = 0; i < chunks; i++)
1506 rtx reg;
1508 for (; field; field = TREE_CHAIN (field))
1509 if (TREE_CODE (field) == FIELD_DECL
1510 && int_bit_position (field) >= bitpos)
1511 break;
1513 if (field
1514 && int_bit_position (field) == bitpos
1515 && TREE_CODE (TREE_TYPE (field)) == REAL_TYPE
1516 && TYPE_PRECISION (TREE_TYPE (field)) == BITS_PER_WORD)
1517 reg = gen_rtx_REG (DFmode, regno++);
1518 else
1519 reg = gen_rtx_REG (word_mode, regno);
1521 XVECEXP (ret, 0, i)
1522 = gen_rtx_EXPR_LIST (VOIDmode, reg,
1523 GEN_INT (bitpos / BITS_PER_UNIT));
1525 bitpos += 64;
1526 regno++;
1531 if (TARGET_DEBUG_D_MODE)
1532 fprintf (stderr, "%s%s\n", reg_names[regbase + *arg_words + bias],
1533 struct_p ? ", [struct]" : "");
1536 /* We will be called with a mode of VOIDmode after the last argument
1537 has been seen. Whatever we return will be passed to the call
1538 insn. If we need any shifts for small structures, return them in
1539 a PARALLEL. */
1540 if (mode == VOIDmode)
1542 if (cum->num_adjusts > 0)
1543 ret = gen_rtx_PARALLEL ((enum machine_mode) cum->fp_code,
1544 gen_rtvec_v (cum->num_adjusts, cum->adjust));
1547 return ret;
1551 function_arg_partial_nregs (CUMULATIVE_ARGS *cum, enum machine_mode mode,
1552 tree type ATTRIBUTE_UNUSED,
1553 int named ATTRIBUTE_UNUSED)
1555 if (mode == DImode
1556 && cum->arg_words == MAX_ARGS_IN_REGISTERS - (unsigned)1)
1558 if (TARGET_DEBUG_D_MODE)
1559 fprintf (stderr, "function_arg_partial_nregs = 1\n");
1561 return 1;
1564 return 0;
1567 /* Implement va_start. */
1569 void
1570 iq2000_va_start (tree valist, rtx nextarg)
1572 int int_arg_words;
1573 /* Find out how many non-float named formals. */
1574 int gpr_save_area_size;
1575 /* Note UNITS_PER_WORD is 4 bytes. */
1576 int_arg_words = current_function_args_info.arg_words;
1578 if (int_arg_words < 8 )
1579 /* Adjust for the prologue's economy measure. */
1580 gpr_save_area_size = (8 - int_arg_words) * UNITS_PER_WORD;
1581 else
1582 gpr_save_area_size = 0;
1584 /* Everything is in the GPR save area, or in the overflow
1585 area which is contiguous with it. */
1586 nextarg = plus_constant (nextarg, - gpr_save_area_size);
1587 std_expand_builtin_va_start (valist, nextarg);
1590 /* Implement va_arg. */
1593 iq2000_va_arg (tree valist, tree type)
1595 HOST_WIDE_INT size, rsize;
1596 rtx addr_rtx;
1597 tree t;
1598 int indirect;
1599 rtx r, lab_over = NULL_RTX, lab_false;
1600 tree f_ovfl, f_gtop, f_ftop, f_goff, f_foff;
1601 tree ovfl, gtop, ftop, goff, foff;
1603 size = int_size_in_bytes (type);
1604 rsize = (size + UNITS_PER_WORD - 1) & -UNITS_PER_WORD;
1605 indirect
1606 = function_arg_pass_by_reference (NULL, TYPE_MODE (type), type, 0);
1607 if (indirect)
1609 size = POINTER_SIZE / BITS_PER_UNIT;
1610 rsize = UNITS_PER_WORD;
1613 addr_rtx = gen_reg_rtx (Pmode);
1616 /* Case of all args in a merged stack. No need to check bounds,
1617 just advance valist along the stack. */
1618 tree gpr = valist;
1620 if (! indirect
1621 && TYPE_ALIGN (type) > (unsigned) BITS_PER_WORD)
1623 t = build (PLUS_EXPR, TREE_TYPE (gpr), gpr,
1624 build_int_2 (2*UNITS_PER_WORD - 1, 0));
1625 t = build (BIT_AND_EXPR, TREE_TYPE (t), t,
1626 build_int_2 (-2*UNITS_PER_WORD, -1));
1627 t = build (MODIFY_EXPR, TREE_TYPE (gpr), gpr, t);
1628 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
1631 t = build (POSTINCREMENT_EXPR, TREE_TYPE (gpr), gpr,
1632 size_int (rsize));
1633 r = expand_expr (t, addr_rtx, Pmode, EXPAND_NORMAL);
1634 if (r != addr_rtx)
1635 emit_move_insn (addr_rtx, r);
1637 /* Flush the POSTINCREMENT. */
1638 emit_queue();
1640 if (indirect)
1642 r = gen_rtx_MEM (Pmode, addr_rtx);
1643 set_mem_alias_set (r, get_varargs_alias_set ());
1644 emit_move_insn (addr_rtx, r);
1646 else
1648 if (BYTES_BIG_ENDIAN && rsize != size)
1649 addr_rtx = plus_constant (addr_rtx, rsize - size);
1651 return addr_rtx;
1654 /* Not a simple merged stack. Need ptrs and indexes left by va_start. */
1655 f_ovfl = TYPE_FIELDS (va_list_type_node);
1656 f_gtop = TREE_CHAIN (f_ovfl);
1657 f_ftop = TREE_CHAIN (f_gtop);
1658 f_goff = TREE_CHAIN (f_ftop);
1659 f_foff = TREE_CHAIN (f_goff);
1661 ovfl = build (COMPONENT_REF, TREE_TYPE (f_ovfl), valist, f_ovfl);
1662 gtop = build (COMPONENT_REF, TREE_TYPE (f_gtop), valist, f_gtop);
1663 ftop = build (COMPONENT_REF, TREE_TYPE (f_ftop), valist, f_ftop);
1664 goff = build (COMPONENT_REF, TREE_TYPE (f_goff), valist, f_goff);
1665 foff = build (COMPONENT_REF, TREE_TYPE (f_foff), valist, f_foff);
1667 lab_false = gen_label_rtx ();
1668 lab_over = gen_label_rtx ();
1670 if (TREE_CODE (type) == REAL_TYPE)
1672 /* Emit code to branch if foff == 0. */
1673 r = expand_expr (foff, NULL_RTX, TYPE_MODE (TREE_TYPE (foff)),
1674 EXPAND_NORMAL);
1675 emit_cmp_and_jump_insns (r, const0_rtx, EQ,
1676 const1_rtx, GET_MODE (r), 1, lab_false);
1678 /* Emit code for addr_rtx = ftop - foff. */
1679 t = build (MINUS_EXPR, TREE_TYPE (ftop), ftop, foff );
1680 r = expand_expr (t, addr_rtx, Pmode, EXPAND_NORMAL);
1681 if (r != addr_rtx)
1682 emit_move_insn (addr_rtx, r);
1684 /* Emit code for foff-=8.
1685 Advances the offset up FPR save area by one double. */
1686 t = build (MINUS_EXPR, TREE_TYPE (foff), foff, build_int_2 (8, 0));
1687 t = build (MODIFY_EXPR, TREE_TYPE (foff), foff, t);
1688 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
1690 emit_queue ();
1691 emit_jump (lab_over);
1692 emit_barrier ();
1693 emit_label (lab_false);
1695 /* If a 4-byte int is followed by an 8-byte float, then
1696 natural alignment causes a 4 byte gap.
1697 So, dynamically adjust ovfl up to a multiple of 8. */
1698 t = build (BIT_AND_EXPR, TREE_TYPE (ovfl), ovfl,
1699 build_int_2 (7, 0));
1700 t = build (PLUS_EXPR, TREE_TYPE (ovfl), ovfl, t);
1701 t = build (MODIFY_EXPR, TREE_TYPE (ovfl), ovfl, t);
1702 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
1704 /* Emit code for addr_rtx = the ovfl pointer into overflow area.
1705 Postincrement the ovfl pointer by 8. */
1706 t = build (POSTINCREMENT_EXPR, TREE_TYPE(ovfl), ovfl,
1707 size_int (8));
1708 r = expand_expr (t, addr_rtx, Pmode, EXPAND_NORMAL);
1709 if (r != addr_rtx)
1710 emit_move_insn (addr_rtx, r);
1712 emit_queue();
1713 emit_label (lab_over);
1714 return addr_rtx;
1716 else
1718 /* Not REAL_TYPE. */
1719 int step_size;
1721 if (TREE_CODE (type) == INTEGER_TYPE
1722 && TYPE_PRECISION (type) == 64)
1724 /* int takes 32 bits of the GPR save area, but
1725 longlong takes an aligned 64 bits. So, emit code
1726 to zero the low order bits of goff, thus aligning
1727 the later calculation of (gtop-goff) upwards. */
1728 t = build (BIT_AND_EXPR, TREE_TYPE (goff), goff,
1729 build_int_2 (-8, -1));
1730 t = build (MODIFY_EXPR, TREE_TYPE (goff), goff, t);
1731 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
1734 /* Emit code to branch if goff == 0. */
1735 r = expand_expr (goff, NULL_RTX, TYPE_MODE (TREE_TYPE (goff)),
1736 EXPAND_NORMAL);
1737 emit_cmp_and_jump_insns (r, const0_rtx, EQ,
1738 const1_rtx, GET_MODE (r), 1, lab_false);
1740 /* Emit code for addr_rtx = gtop - goff. */
1741 t = build (MINUS_EXPR, TREE_TYPE (gtop), gtop, goff);
1742 r = expand_expr (t, addr_rtx, Pmode, EXPAND_NORMAL);
1743 if (r != addr_rtx)
1744 emit_move_insn (addr_rtx, r);
1746 if (TYPE_PRECISION (type) == 64)
1747 step_size = 8;
1748 else
1749 step_size = UNITS_PER_WORD;
1751 /* Emit code for goff = goff - step_size.
1752 Advances the offset up GPR save area over the item. */
1753 t = build (MINUS_EXPR, TREE_TYPE (goff), goff,
1754 build_int_2 (step_size, 0));
1755 t = build (MODIFY_EXPR, TREE_TYPE (goff), goff, t);
1756 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
1758 emit_queue();
1759 emit_jump (lab_over);
1760 emit_barrier ();
1761 emit_label (lab_false);
1763 /* Emit code for addr_rtx -> overflow area, postinc by step_size. */
1764 t = build (POSTINCREMENT_EXPR, TREE_TYPE(ovfl), ovfl,
1765 size_int (step_size));
1766 r = expand_expr (t, addr_rtx, Pmode, EXPAND_NORMAL);
1767 if (r != addr_rtx)
1768 emit_move_insn (addr_rtx, r);
1770 emit_queue();
1771 emit_label (lab_over);
1773 if (indirect)
1775 r = gen_rtx_MEM (Pmode, addr_rtx);
1776 set_mem_alias_set (r, get_varargs_alias_set ());
1777 emit_move_insn (addr_rtx, r);
1779 else
1781 if (BYTES_BIG_ENDIAN && rsize != size)
1782 addr_rtx = plus_constant (addr_rtx, rsize - size);
1784 return addr_rtx;
1788 /* Allocate a chunk of memory for per-function machine-dependent data. */
1790 static struct machine_function *
1791 iq2000_init_machine_status (void)
1793 struct machine_function *f;
1795 f = ggc_alloc_cleared (sizeof (struct machine_function));
1797 return f;
1800 static enum processor_type
1801 iq2000_parse_cpu (const char * cpu_string)
1803 const char *p = cpu_string;
1804 enum processor_type cpu;
1806 cpu = PROCESSOR_DEFAULT;
1807 switch (p[2])
1809 case '1':
1810 if (!strcmp (p, "iq10"))
1811 cpu = PROCESSOR_IQ10;
1812 break;
1813 case '2':
1814 if (!strcmp (p, "iq2000"))
1815 cpu = PROCESSOR_IQ2000;
1816 break;
1819 return cpu;
1822 /* Detect any conflicts in the switches. */
1824 void
1825 override_options (void)
1827 enum processor_type iq2000_cpu;
1829 target_flags &= ~MASK_GPOPT;
1831 iq2000_isa = IQ2000_ISA_DEFAULT;
1833 /* Identify the processor type. */
1835 if (iq2000_cpu_string != 0)
1837 iq2000_cpu = iq2000_parse_cpu (iq2000_cpu_string);
1838 if (iq2000_cpu == PROCESSOR_DEFAULT)
1840 error ("bad value (%s) for -mcpu= switch", iq2000_arch_string);
1841 iq2000_cpu_string = "default";
1843 iq2000_arch = iq2000_cpu;
1844 iq2000_tune = iq2000_cpu;
1847 if (iq2000_arch_string == 0
1848 || ! strcmp (iq2000_arch_string, "default")
1849 || ! strcmp (iq2000_arch_string, "DEFAULT"))
1851 switch (iq2000_isa)
1853 default:
1854 iq2000_arch_string = "iq2000";
1855 iq2000_arch = PROCESSOR_IQ2000;
1856 break;
1859 else
1861 iq2000_arch = iq2000_parse_cpu (iq2000_arch_string);
1862 if (iq2000_arch == PROCESSOR_DEFAULT)
1864 error ("bad value (%s) for -march= switch", iq2000_arch_string);
1865 iq2000_arch_string = "default";
1867 if (iq2000_arch == PROCESSOR_IQ10)
1869 error ("The compiler does not support -march=%s.", iq2000_arch_string);
1870 iq2000_arch_string = "default";
1874 iq2000_print_operand_punct['?'] = 1;
1875 iq2000_print_operand_punct['#'] = 1;
1876 iq2000_print_operand_punct['&'] = 1;
1877 iq2000_print_operand_punct['!'] = 1;
1878 iq2000_print_operand_punct['*'] = 1;
1879 iq2000_print_operand_punct['@'] = 1;
1880 iq2000_print_operand_punct['.'] = 1;
1881 iq2000_print_operand_punct['('] = 1;
1882 iq2000_print_operand_punct[')'] = 1;
1883 iq2000_print_operand_punct['['] = 1;
1884 iq2000_print_operand_punct[']'] = 1;
1885 iq2000_print_operand_punct['<'] = 1;
1886 iq2000_print_operand_punct['>'] = 1;
1887 iq2000_print_operand_punct['{'] = 1;
1888 iq2000_print_operand_punct['}'] = 1;
1889 iq2000_print_operand_punct['^'] = 1;
1890 iq2000_print_operand_punct['$'] = 1;
1891 iq2000_print_operand_punct['+'] = 1;
1892 iq2000_print_operand_punct['~'] = 1;
1894 /* Save GPR registers in word_mode sized hunks. word_mode hasn't been
1895 initialized yet, so we can't use that here. */
1896 gpr_mode = SImode;
1898 /* Function to allocate machine-dependent function status. */
1899 init_machine_status = iq2000_init_machine_status;
1902 /* The arg pointer (which is eliminated) points to the virtual frame pointer,
1903 while the frame pointer (which may be eliminated) points to the stack
1904 pointer after the initial adjustments. */
1906 HOST_WIDE_INT
1907 iq2000_debugger_offset (rtx addr, HOST_WIDE_INT offset)
1909 rtx offset2 = const0_rtx;
1910 rtx reg = eliminate_constant_term (addr, & offset2);
1912 if (offset == 0)
1913 offset = INTVAL (offset2);
1915 if (reg == stack_pointer_rtx || reg == frame_pointer_rtx
1916 || reg == hard_frame_pointer_rtx)
1918 HOST_WIDE_INT frame_size = (!cfun->machine->initialized)
1919 ? compute_frame_size (get_frame_size ())
1920 : cfun->machine->total_size;
1922 offset = offset - frame_size;
1925 return offset;
1928 /* If defined, a C statement to be executed just prior to the output of
1929 assembler code for INSN, to modify the extracted operands so they will be
1930 output differently.
1932 Here the argument OPVEC is the vector containing the operands extracted
1933 from INSN, and NOPERANDS is the number of elements of the vector which
1934 contain meaningful data for this insn. The contents of this vector are
1935 what will be used to convert the insn template into assembler code, so you
1936 can change the assembler output by changing the contents of the vector.
1938 We use it to check if the current insn needs a nop in front of it because
1939 of load delays, and also to update the delay slot statistics. */
1941 void
1942 final_prescan_insn (rtx insn, rtx opvec[] ATTRIBUTE_UNUSED,
1943 int noperands ATTRIBUTE_UNUSED)
1945 if (dslots_number_nops > 0)
1947 rtx pattern = PATTERN (insn);
1948 int length = get_attr_length (insn);
1950 /* Do we need to emit a NOP? */
1951 if (length == 0
1952 || (iq2000_load_reg != 0 && reg_mentioned_p (iq2000_load_reg, pattern))
1953 || (iq2000_load_reg2 != 0 && reg_mentioned_p (iq2000_load_reg2, pattern))
1954 || (iq2000_load_reg3 != 0 && reg_mentioned_p (iq2000_load_reg3, pattern))
1955 || (iq2000_load_reg4 != 0
1956 && reg_mentioned_p (iq2000_load_reg4, pattern)))
1957 fputs ("\tnop\n", asm_out_file);
1959 else
1960 dslots_load_filled ++;
1962 while (--dslots_number_nops > 0)
1963 fputs ("\tnop\n", asm_out_file);
1965 iq2000_load_reg = 0;
1966 iq2000_load_reg2 = 0;
1967 iq2000_load_reg3 = 0;
1968 iq2000_load_reg4 = 0;
1971 if ( (GET_CODE (insn) == JUMP_INSN
1972 || GET_CODE (insn) == CALL_INSN
1973 || (GET_CODE (PATTERN (insn)) == RETURN))
1974 && NEXT_INSN (PREV_INSN (insn)) == insn)
1976 rtx nop_insn = emit_insn_after (gen_nop (), insn);
1978 INSN_ADDRESSES_NEW (nop_insn, -1);
1981 if (TARGET_STATS
1982 && (GET_CODE (insn) == JUMP_INSN || GET_CODE (insn) == CALL_INSN))
1983 dslots_jump_total ++;
1986 /* Return the bytes needed to compute the frame pointer from the current
1987 stack pointer where SIZE is the # of var. bytes allocated.
1989 IQ2000 stack frames look like:
1991 Before call After call
1992 +-----------------------+ +-----------------------+
1993 high | | | |
1994 mem. | | | |
1995 | caller's temps. | | caller's temps. |
1996 | | | |
1997 +-----------------------+ +-----------------------+
1998 | | | |
1999 | arguments on stack. | | arguments on stack. |
2000 | | | |
2001 +-----------------------+ +-----------------------+
2002 | 4 words to save | | 4 words to save |
2003 | arguments passed | | arguments passed |
2004 | in registers, even | | in registers, even |
2005 SP->| if not passed. | VFP->| if not passed. |
2006 +-----------------------+ +-----------------------+
2008 | fp register save |
2010 +-----------------------+
2012 | gp register save |
2014 +-----------------------+
2016 | local variables |
2018 +-----------------------+
2020 | alloca allocations |
2022 +-----------------------+
2024 | GP save for V.4 abi |
2026 +-----------------------+
2028 | arguments on stack |
2030 +-----------------------+
2031 | 4 words to save |
2032 | arguments passed |
2033 | in registers, even |
2034 low SP->| if not passed. |
2035 memory +-----------------------+ */
2037 HOST_WIDE_INT
2038 compute_frame_size (HOST_WIDE_INT size)
2040 int regno;
2041 HOST_WIDE_INT total_size; /* # bytes that the entire frame takes up. */
2042 HOST_WIDE_INT var_size; /* # bytes that variables take up. */
2043 HOST_WIDE_INT args_size; /* # bytes that outgoing arguments take up. */
2044 HOST_WIDE_INT extra_size; /* # extra bytes. */
2045 HOST_WIDE_INT gp_reg_rounded; /* # bytes needed to store gp after rounding. */
2046 HOST_WIDE_INT gp_reg_size; /* # bytes needed to store gp regs. */
2047 HOST_WIDE_INT fp_reg_size; /* # bytes needed to store fp regs. */
2048 long mask; /* mask of saved gp registers. */
2049 int fp_inc; /* 1 or 2 depending on the size of fp regs. */
2050 long fp_bits; /* bitmask to use for each fp register. */
2052 gp_reg_size = 0;
2053 fp_reg_size = 0;
2054 mask = 0;
2055 extra_size = IQ2000_STACK_ALIGN ((0));
2056 var_size = IQ2000_STACK_ALIGN (size);
2057 args_size = IQ2000_STACK_ALIGN (current_function_outgoing_args_size);
2059 /* If a function dynamically allocates the stack and
2060 has 0 for STACK_DYNAMIC_OFFSET then allocate some stack space. */
2061 if (args_size == 0 && current_function_calls_alloca)
2062 args_size = 4 * UNITS_PER_WORD;
2064 total_size = var_size + args_size + extra_size;
2066 /* Calculate space needed for gp registers. */
2067 for (regno = GP_REG_FIRST; regno <= GP_REG_LAST; regno++)
2069 if (MUST_SAVE_REGISTER (regno))
2071 gp_reg_size += GET_MODE_SIZE (gpr_mode);
2072 mask |= 1L << (regno - GP_REG_FIRST);
2076 /* We need to restore these for the handler. */
2077 if (current_function_calls_eh_return)
2079 unsigned int i;
2081 for (i = 0; ; ++i)
2083 regno = EH_RETURN_DATA_REGNO (i);
2084 if (regno == (int) INVALID_REGNUM)
2085 break;
2086 gp_reg_size += GET_MODE_SIZE (gpr_mode);
2087 mask |= 1L << (regno - GP_REG_FIRST);
2091 fp_inc = 2;
2092 fp_bits = 3;
2093 gp_reg_rounded = IQ2000_STACK_ALIGN (gp_reg_size);
2094 total_size += gp_reg_rounded + IQ2000_STACK_ALIGN (fp_reg_size);
2096 /* The gp reg is caller saved, so there is no need for leaf routines
2097 (total_size == extra_size) to save the gp reg. */
2098 if (total_size == extra_size
2099 && ! profile_flag)
2100 total_size = extra_size = 0;
2102 total_size += IQ2000_STACK_ALIGN (current_function_pretend_args_size);
2104 /* Save other computed information. */
2105 cfun->machine->total_size = total_size;
2106 cfun->machine->var_size = var_size;
2107 cfun->machine->args_size = args_size;
2108 cfun->machine->extra_size = extra_size;
2109 cfun->machine->gp_reg_size = gp_reg_size;
2110 cfun->machine->fp_reg_size = fp_reg_size;
2111 cfun->machine->mask = mask;
2112 cfun->machine->initialized = reload_completed;
2113 cfun->machine->num_gp = gp_reg_size / UNITS_PER_WORD;
2115 if (mask)
2117 unsigned long offset;
2119 offset = (args_size + extra_size + var_size
2120 + gp_reg_size - GET_MODE_SIZE (gpr_mode));
2122 cfun->machine->gp_sp_offset = offset;
2123 cfun->machine->gp_save_offset = offset - total_size;
2125 else
2127 cfun->machine->gp_sp_offset = 0;
2128 cfun->machine->gp_save_offset = 0;
2131 cfun->machine->fp_sp_offset = 0;
2132 cfun->machine->fp_save_offset = 0;
2134 /* Ok, we're done. */
2135 return total_size;
2138 /* Implement INITIAL_ELIMINATION_OFFSET. FROM is either the frame
2139 pointer, argument pointer, or return address pointer. TO is either
2140 the stack pointer or hard frame pointer. */
2143 iq2000_initial_elimination_offset (int from, int to ATTRIBUTE_UNUSED)
2145 int offset;
2147 compute_frame_size (get_frame_size ());
2148 if ((from) == FRAME_POINTER_REGNUM)
2149 (offset) = 0;
2150 else if ((from) == ARG_POINTER_REGNUM)
2151 (offset) = (cfun->machine->total_size);
2152 else if ((from) == RETURN_ADDRESS_POINTER_REGNUM)
2154 if (leaf_function_p ())
2155 (offset) = 0;
2156 else (offset) = cfun->machine->gp_sp_offset
2157 + ((UNITS_PER_WORD - (POINTER_SIZE / BITS_PER_UNIT))
2158 * (BYTES_BIG_ENDIAN != 0));
2161 return offset;
2164 /* Common code to emit the insns (or to write the instructions to a file)
2165 to save/restore registers.
2166 Other parts of the code assume that IQ2000_TEMP1_REGNUM (aka large_reg)
2167 is not modified within save_restore_insns. */
2169 #define BITSET_P(VALUE,BIT) (((VALUE) & (1L << (BIT))) != 0)
2171 /* Emit instructions to load the value (SP + OFFSET) into IQ2000_TEMP2_REGNUM
2172 and return an rtl expression for the register. Write the assembly
2173 instructions directly to FILE if it is not null, otherwise emit them as
2174 rtl.
2176 This function is a subroutine of save_restore_insns. It is used when
2177 OFFSET is too large to add in a single instruction. */
2179 static rtx
2180 iq2000_add_large_offset_to_sp (HOST_WIDE_INT offset)
2182 rtx reg = gen_rtx_REG (Pmode, IQ2000_TEMP2_REGNUM);
2183 rtx offset_rtx = GEN_INT (offset);
2185 emit_move_insn (reg, offset_rtx);
2186 emit_insn (gen_addsi3 (reg, reg, stack_pointer_rtx));
2187 return reg;
2190 /* Make INSN frame related and note that it performs the frame-related
2191 operation DWARF_PATTERN. */
2193 static void
2194 iq2000_annotate_frame_insn (rtx insn, rtx dwarf_pattern)
2196 RTX_FRAME_RELATED_P (insn) = 1;
2197 REG_NOTES (insn) = alloc_EXPR_LIST (REG_FRAME_RELATED_EXPR,
2198 dwarf_pattern,
2199 REG_NOTES (insn));
2202 /* Emit a move instruction that stores REG in MEM. Make the instruction
2203 frame related and note that it stores REG at (SP + OFFSET). */
2205 static void
2206 iq2000_emit_frame_related_store (rtx mem, rtx reg, HOST_WIDE_INT offset)
2208 rtx dwarf_address = plus_constant (stack_pointer_rtx, offset);
2209 rtx dwarf_mem = gen_rtx_MEM (GET_MODE (reg), dwarf_address);
2211 iq2000_annotate_frame_insn (emit_move_insn (mem, reg),
2212 gen_rtx_SET (GET_MODE (reg), dwarf_mem, reg));
2215 /* Emit instructions to save/restore registers, as determined by STORE_P. */
2217 static void
2218 save_restore_insns (int store_p)
2220 long mask = cfun->machine->mask;
2221 int regno;
2222 rtx base_reg_rtx;
2223 HOST_WIDE_INT base_offset;
2224 HOST_WIDE_INT gp_offset;
2225 HOST_WIDE_INT end_offset;
2227 if (frame_pointer_needed
2228 && ! BITSET_P (mask, HARD_FRAME_POINTER_REGNUM - GP_REG_FIRST))
2229 abort ();
2231 if (mask == 0)
2233 base_reg_rtx = 0, base_offset = 0;
2234 return;
2237 /* Save registers starting from high to low. The debuggers prefer at least
2238 the return register be stored at func+4, and also it allows us not to
2239 need a nop in the epilog if at least one register is reloaded in
2240 addition to return address. */
2242 /* Save GP registers if needed. */
2243 /* Pick which pointer to use as a base register. For small frames, just
2244 use the stack pointer. Otherwise, use a temporary register. Save 2
2245 cycles if the save area is near the end of a large frame, by reusing
2246 the constant created in the prologue/epilogue to adjust the stack
2247 frame. */
2249 gp_offset = cfun->machine->gp_sp_offset;
2250 end_offset
2251 = gp_offset - (cfun->machine->gp_reg_size
2252 - GET_MODE_SIZE (gpr_mode));
2254 if (gp_offset < 0 || end_offset < 0)
2255 internal_error
2256 ("gp_offset (%ld) or end_offset (%ld) is less than zero.",
2257 (long) gp_offset, (long) end_offset);
2259 else if (gp_offset < 32768)
2260 base_reg_rtx = stack_pointer_rtx, base_offset = 0;
2261 else
2263 int regno;
2264 int reg_save_count = 0;
2266 for (regno = GP_REG_LAST; regno >= GP_REG_FIRST; regno--)
2267 if (BITSET_P (mask, regno - GP_REG_FIRST)) reg_save_count += 1;
2268 base_offset = gp_offset - ((reg_save_count - 1) * 4);
2269 base_reg_rtx = iq2000_add_large_offset_to_sp (base_offset);
2272 for (regno = GP_REG_LAST; regno >= GP_REG_FIRST; regno--)
2274 if (BITSET_P (mask, regno - GP_REG_FIRST))
2276 rtx reg_rtx;
2277 rtx mem_rtx
2278 = gen_rtx_MEM (gpr_mode,
2279 gen_rtx_PLUS (Pmode, base_reg_rtx,
2280 GEN_INT (gp_offset - base_offset)));
2282 if (! current_function_calls_eh_return)
2283 RTX_UNCHANGING_P (mem_rtx) = 1;
2285 reg_rtx = gen_rtx_REG (gpr_mode, regno);
2287 if (store_p)
2288 iq2000_emit_frame_related_store (mem_rtx, reg_rtx, gp_offset);
2289 else
2291 emit_move_insn (reg_rtx, mem_rtx);
2293 gp_offset -= GET_MODE_SIZE (gpr_mode);
2298 /* Expand the prologue into a bunch of separate insns. */
2300 void
2301 iq2000_expand_prologue (void)
2303 int regno;
2304 HOST_WIDE_INT tsize;
2305 int last_arg_is_vararg_marker = 0;
2306 tree fndecl = current_function_decl;
2307 tree fntype = TREE_TYPE (fndecl);
2308 tree fnargs = DECL_ARGUMENTS (fndecl);
2309 rtx next_arg_reg;
2310 int i;
2311 tree next_arg;
2312 tree cur_arg;
2313 CUMULATIVE_ARGS args_so_far;
2314 int store_args_on_stack = (iq2000_can_use_return_insn ());
2316 /* If struct value address is treated as the first argument. */
2317 if (aggregate_value_p (DECL_RESULT (fndecl), fndecl)
2318 && ! current_function_returns_pcc_struct
2319 && targetm.calls.struct_value_rtx (TREE_TYPE (fndecl), 1) == 0)
2321 tree type = build_pointer_type (fntype);
2322 tree function_result_decl = build_decl (PARM_DECL, NULL_TREE, type);
2324 DECL_ARG_TYPE (function_result_decl) = type;
2325 TREE_CHAIN (function_result_decl) = fnargs;
2326 fnargs = function_result_decl;
2329 /* For arguments passed in registers, find the register number
2330 of the first argument in the variable part of the argument list,
2331 otherwise GP_ARG_LAST+1. Note also if the last argument is
2332 the varargs special argument, and treat it as part of the
2333 variable arguments.
2335 This is only needed if store_args_on_stack is true. */
2336 INIT_CUMULATIVE_ARGS (args_so_far, fntype, NULL_RTX, 0, 0);
2337 regno = GP_ARG_FIRST;
2339 for (cur_arg = fnargs; cur_arg != 0; cur_arg = next_arg)
2341 tree passed_type = DECL_ARG_TYPE (cur_arg);
2342 enum machine_mode passed_mode = TYPE_MODE (passed_type);
2343 rtx entry_parm;
2345 if (TREE_ADDRESSABLE (passed_type))
2347 passed_type = build_pointer_type (passed_type);
2348 passed_mode = Pmode;
2351 entry_parm = FUNCTION_ARG (args_so_far, passed_mode, passed_type, 1);
2353 FUNCTION_ARG_ADVANCE (args_so_far, passed_mode, passed_type, 1);
2354 next_arg = TREE_CHAIN (cur_arg);
2356 if (entry_parm && store_args_on_stack)
2358 if (next_arg == 0
2359 && DECL_NAME (cur_arg)
2360 && ((0 == strcmp (IDENTIFIER_POINTER (DECL_NAME (cur_arg)),
2361 "__builtin_va_alist"))
2362 || (0 == strcmp (IDENTIFIER_POINTER (DECL_NAME (cur_arg)),
2363 "va_alist"))))
2365 last_arg_is_vararg_marker = 1;
2366 break;
2368 else
2370 int words;
2372 if (GET_CODE (entry_parm) != REG)
2373 abort ();
2375 /* Passed in a register, so will get homed automatically. */
2376 if (GET_MODE (entry_parm) == BLKmode)
2377 words = (int_size_in_bytes (passed_type) + 3) / 4;
2378 else
2379 words = (GET_MODE_SIZE (GET_MODE (entry_parm)) + 3) / 4;
2381 regno = REGNO (entry_parm) + words - 1;
2384 else
2386 regno = GP_ARG_LAST+1;
2387 break;
2391 /* In order to pass small structures by value in registers we need to
2392 shift the value into the high part of the register.
2393 Function_arg has encoded a PARALLEL rtx, holding a vector of
2394 adjustments to be made as the next_arg_reg variable, so we split up the
2395 insns, and emit them separately. */
2396 next_arg_reg = FUNCTION_ARG (args_so_far, VOIDmode, void_type_node, 1);
2397 if (next_arg_reg != 0 && GET_CODE (next_arg_reg) == PARALLEL)
2399 rtvec adjust = XVEC (next_arg_reg, 0);
2400 int num = GET_NUM_ELEM (adjust);
2402 for (i = 0; i < num; i++)
2404 rtx insn, pattern;
2406 pattern = RTVEC_ELT (adjust, i);
2407 if (GET_CODE (pattern) != SET
2408 || GET_CODE (SET_SRC (pattern)) != ASHIFT)
2409 abort_with_insn (pattern, "Insn is not a shift");
2410 PUT_CODE (SET_SRC (pattern), ASHIFTRT);
2412 insn = emit_insn (pattern);
2414 /* Global life information isn't valid at this point, so we
2415 can't check whether these shifts are actually used. Mark
2416 them MAYBE_DEAD so that flow2 will remove them, and not
2417 complain about dead code in the prologue. */
2418 REG_NOTES(insn) = gen_rtx_EXPR_LIST (REG_MAYBE_DEAD, NULL_RTX,
2419 REG_NOTES (insn));
2423 tsize = compute_frame_size (get_frame_size ());
2425 /* If this function is a varargs function, store any registers that
2426 would normally hold arguments ($4 - $7) on the stack. */
2427 if (store_args_on_stack
2428 && ((TYPE_ARG_TYPES (fntype) != 0
2429 && (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
2430 != void_type_node))
2431 || last_arg_is_vararg_marker))
2433 int offset = (regno - GP_ARG_FIRST) * UNITS_PER_WORD;
2434 rtx ptr = stack_pointer_rtx;
2436 for (; regno <= GP_ARG_LAST; regno++)
2438 if (offset != 0)
2439 ptr = gen_rtx_PLUS (Pmode, stack_pointer_rtx, GEN_INT (offset));
2440 emit_move_insn (gen_rtx_MEM (gpr_mode, ptr),
2441 gen_rtx_REG (gpr_mode, regno));
2443 offset += GET_MODE_SIZE (gpr_mode);
2447 if (tsize > 0)
2449 rtx tsize_rtx = GEN_INT (tsize);
2450 rtx adjustment_rtx, insn, dwarf_pattern;
2452 if (tsize > 32767)
2454 adjustment_rtx = gen_rtx_REG (Pmode, IQ2000_TEMP1_REGNUM);
2455 emit_move_insn (adjustment_rtx, tsize_rtx);
2457 else
2458 adjustment_rtx = tsize_rtx;
2460 insn = emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
2461 adjustment_rtx));
2463 dwarf_pattern = gen_rtx_SET (Pmode, stack_pointer_rtx,
2464 plus_constant (stack_pointer_rtx, -tsize));
2466 iq2000_annotate_frame_insn (insn, dwarf_pattern);
2468 save_restore_insns (1);
2470 if (frame_pointer_needed)
2472 rtx insn = 0;
2474 insn = emit_insn (gen_movsi (hard_frame_pointer_rtx,
2475 stack_pointer_rtx));
2477 if (insn)
2478 RTX_FRAME_RELATED_P (insn) = 1;
2482 emit_insn (gen_blockage ());
2485 /* Expand the epilogue into a bunch of separate insns. */
2487 void
2488 iq2000_expand_epilogue (void)
2490 HOST_WIDE_INT tsize = cfun->machine->total_size;
2491 rtx tsize_rtx = GEN_INT (tsize);
2492 rtx tmp_rtx = (rtx)0;
2494 if (iq2000_can_use_return_insn ())
2496 emit_insn (gen_return ());
2497 return;
2500 if (tsize > 32767)
2502 tmp_rtx = gen_rtx_REG (Pmode, IQ2000_TEMP1_REGNUM);
2503 emit_move_insn (tmp_rtx, tsize_rtx);
2504 tsize_rtx = tmp_rtx;
2507 if (tsize > 0)
2509 if (frame_pointer_needed)
2511 emit_insn (gen_blockage ());
2513 emit_insn (gen_movsi (stack_pointer_rtx, hard_frame_pointer_rtx));
2516 save_restore_insns (0);
2518 if (current_function_calls_eh_return)
2520 rtx eh_ofs = EH_RETURN_STACKADJ_RTX;
2521 emit_insn (gen_addsi3 (eh_ofs, eh_ofs, tsize_rtx));
2522 tsize_rtx = eh_ofs;
2525 emit_insn (gen_blockage ());
2527 if (tsize != 0 || current_function_calls_eh_return)
2529 emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx,
2530 tsize_rtx));
2534 if (current_function_calls_eh_return)
2536 /* Perform the additional bump for __throw. */
2537 emit_move_insn (gen_rtx_REG (Pmode, HARD_FRAME_POINTER_REGNUM),
2538 stack_pointer_rtx);
2539 emit_insn (gen_rtx_USE (VOIDmode, gen_rtx_REG (Pmode,
2540 HARD_FRAME_POINTER_REGNUM)));
2541 emit_jump_insn (gen_eh_return_internal ());
2543 else
2544 emit_jump_insn (gen_return_internal (gen_rtx_REG (Pmode,
2545 GP_REG_FIRST + 31)));
2548 void
2549 iq2000_expand_eh_return (rtx address)
2551 HOST_WIDE_INT gp_offset = cfun->machine->gp_sp_offset;
2552 rtx scratch;
2554 scratch = plus_constant (stack_pointer_rtx, gp_offset);
2555 emit_move_insn (gen_rtx_MEM (GET_MODE (address), scratch), address);
2558 /* Return nonzero if this function is known to have a null epilogue.
2559 This allows the optimizer to omit jumps to jumps if no stack
2560 was created. */
2563 iq2000_can_use_return_insn (void)
2565 if (! reload_completed)
2566 return 0;
2568 if (regs_ever_live[31] || profile_flag)
2569 return 0;
2571 if (cfun->machine->initialized)
2572 return cfun->machine->total_size == 0;
2574 return compute_frame_size (get_frame_size ()) == 0;
2577 /* Returns nonzero if X contains a SYMBOL_REF. */
2579 static int
2580 symbolic_expression_p (rtx x)
2582 if (GET_CODE (x) == SYMBOL_REF)
2583 return 1;
2585 if (GET_CODE (x) == CONST)
2586 return symbolic_expression_p (XEXP (x, 0));
2588 if (GET_RTX_CLASS (GET_CODE (x)) == '1')
2589 return symbolic_expression_p (XEXP (x, 0));
2591 if (GET_RTX_CLASS (GET_CODE (x)) == 'c'
2592 || GET_RTX_CLASS (GET_CODE (x)) == '2')
2593 return (symbolic_expression_p (XEXP (x, 0))
2594 || symbolic_expression_p (XEXP (x, 1)));
2596 return 0;
2599 /* Choose the section to use for the constant rtx expression X that has
2600 mode MODE. */
2602 static void
2603 iq2000_select_rtx_section (enum machine_mode mode, rtx x ATTRIBUTE_UNUSED,
2604 unsigned HOST_WIDE_INT align)
2606 /* For embedded applications, always put constants in read-only data,
2607 in order to reduce RAM usage. */
2608 /* For embedded applications, always put constants in read-only data,
2609 in order to reduce RAM usage. */
2610 mergeable_constant_section (mode, align, 0);
2613 /* Choose the section to use for DECL. RELOC is true if its value contains
2614 any relocatable expression.
2616 Some of the logic used here needs to be replicated in
2617 ENCODE_SECTION_INFO in iq2000.h so that references to these symbols
2618 are done correctly. */
2620 static void
2621 iq2000_select_section (tree decl, int reloc ATTRIBUTE_UNUSED,
2622 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED)
2624 if (TARGET_EMBEDDED_DATA)
2626 /* For embedded applications, always put an object in read-only data
2627 if possible, in order to reduce RAM usage. */
2628 if (((TREE_CODE (decl) == VAR_DECL
2629 && TREE_READONLY (decl) && !TREE_SIDE_EFFECTS (decl)
2630 && DECL_INITIAL (decl)
2631 && (DECL_INITIAL (decl) == error_mark_node
2632 || TREE_CONSTANT (DECL_INITIAL (decl))))
2633 /* Deal with calls from output_constant_def_contents. */
2634 || (TREE_CODE (decl) != VAR_DECL
2635 && (TREE_CODE (decl) != STRING_CST
2636 || !flag_writable_strings))))
2637 readonly_data_section ();
2638 else
2639 data_section ();
2641 else
2643 /* For hosted applications, always put an object in small data if
2644 possible, as this gives the best performance. */
2645 if (((TREE_CODE (decl) == VAR_DECL
2646 && TREE_READONLY (decl) && !TREE_SIDE_EFFECTS (decl)
2647 && DECL_INITIAL (decl)
2648 && (DECL_INITIAL (decl) == error_mark_node
2649 || TREE_CONSTANT (DECL_INITIAL (decl))))
2650 /* Deal with calls from output_constant_def_contents. */
2651 || (TREE_CODE (decl) != VAR_DECL
2652 && (TREE_CODE (decl) != STRING_CST
2653 || !flag_writable_strings))))
2654 readonly_data_section ();
2655 else
2656 data_section ();
2659 /* Return register to use for a function return value with VALTYPE for function
2660 FUNC. */
2663 iq2000_function_value (tree valtype, tree func ATTRIBUTE_UNUSED)
2665 int reg = GP_RETURN;
2666 enum machine_mode mode = TYPE_MODE (valtype);
2667 int unsignedp = TREE_UNSIGNED (valtype);
2669 /* Since we define TARGET_PROMOTE_FUNCTION_RETURN that returns true,
2670 we must promote the mode just as PROMOTE_MODE does. */
2671 mode = promote_mode (valtype, mode, &unsignedp, 1);
2673 return gen_rtx_REG (mode, reg);
2676 /* The implementation of FUNCTION_ARG_PASS_BY_REFERENCE. Return
2677 nonzero when an argument must be passed by reference. */
2680 function_arg_pass_by_reference (CUMULATIVE_ARGS *cum ATTRIBUTE_UNUSED,
2681 enum machine_mode mode, tree type,
2682 int named ATTRIBUTE_UNUSED)
2684 int size;
2686 /* We must pass by reference if we would be both passing in registers
2687 and the stack. This is because any subsequent partial arg would be
2688 handled incorrectly in this case. */
2689 if (cum && MUST_PASS_IN_STACK (mode, type))
2691 /* Don't pass the actual CUM to FUNCTION_ARG, because we would
2692 get double copies of any offsets generated for small structs
2693 passed in registers. */
2694 CUMULATIVE_ARGS temp;
2696 temp = *cum;
2697 if (FUNCTION_ARG (temp, mode, type, named) != 0)
2698 return 1;
2701 if (type == NULL_TREE || mode == DImode || mode == DFmode)
2702 return 0;
2704 size = int_size_in_bytes (type);
2705 return size == -1 || size > UNITS_PER_WORD;
2708 /* Return the length of INSN. LENGTH is the initial length computed by
2709 attributes in the machine-description file. */
2712 iq2000_adjust_insn_length (rtx insn, int length)
2714 /* A unconditional jump has an unfilled delay slot if it is not part
2715 of a sequence. A conditional jump normally has a delay slot. */
2716 if (simplejump_p (insn)
2717 || ( (GET_CODE (insn) == JUMP_INSN
2718 || GET_CODE (insn) == CALL_INSN)))
2719 length += 4;
2721 return length;
2724 /* Output assembly instructions to perform a conditional branch.
2726 INSN is the branch instruction. OPERANDS[0] is the condition.
2727 OPERANDS[1] is the target of the branch. OPERANDS[2] is the target
2728 of the first operand to the condition. If TWO_OPERANDS_P is
2729 nonzero the comparison takes two operands; OPERANDS[3] will be the
2730 second operand.
2732 If INVERTED_P is nonzero we are to branch if the condition does
2733 not hold. If FLOAT_P is nonzero this is a floating-point comparison.
2735 LENGTH is the length (in bytes) of the sequence we are to generate.
2736 That tells us whether to generate a simple conditional branch, or a
2737 reversed conditional branch around a `jr' instruction. */
2739 char *
2740 iq2000_output_conditional_branch (rtx insn, rtx * operands, int two_operands_p,
2741 int float_p, int inverted_p, int length)
2743 static char buffer[200];
2744 /* The kind of comparison we are doing. */
2745 enum rtx_code code = GET_CODE (operands[0]);
2746 /* Nonzero if the opcode for the comparison needs a `z' indicating
2747 that it is a comparison against zero. */
2748 int need_z_p;
2749 /* A string to use in the assembly output to represent the first
2750 operand. */
2751 const char *op1 = "%z2";
2752 /* A string to use in the assembly output to represent the second
2753 operand. Use the hard-wired zero register if there's no second
2754 operand. */
2755 const char *op2 = (two_operands_p ? ",%z3" : ",%.");
2756 /* The operand-printing string for the comparison. */
2757 const char *comp = (float_p ? "%F0" : "%C0");
2758 /* The operand-printing string for the inverted comparison. */
2759 const char *inverted_comp = (float_p ? "%W0" : "%N0");
2761 /* Likely variants of each branch instruction annul the instruction
2762 in the delay slot if the branch is not taken. */
2763 iq2000_branch_likely = (final_sequence && INSN_ANNULLED_BRANCH_P (insn));
2765 if (!two_operands_p)
2767 /* To compute whether than A > B, for example, we normally
2768 subtract B from A and then look at the sign bit. But, if we
2769 are doing an unsigned comparison, and B is zero, we don't
2770 have to do the subtraction. Instead, we can just check to
2771 see if A is nonzero. Thus, we change the CODE here to
2772 reflect the simpler comparison operation. */
2773 switch (code)
2775 case GTU:
2776 code = NE;
2777 break;
2779 case LEU:
2780 code = EQ;
2781 break;
2783 case GEU:
2784 /* A condition which will always be true. */
2785 code = EQ;
2786 op1 = "%.";
2787 break;
2789 case LTU:
2790 /* A condition which will always be false. */
2791 code = NE;
2792 op1 = "%.";
2793 break;
2795 default:
2796 /* Not a special case. */
2797 break;
2801 /* Relative comparisons are always done against zero. But
2802 equality comparisons are done between two operands, and therefore
2803 do not require a `z' in the assembly language output. */
2804 need_z_p = (!float_p && code != EQ && code != NE);
2805 /* For comparisons against zero, the zero is not provided
2806 explicitly. */
2807 if (need_z_p)
2808 op2 = "";
2810 /* Begin by terminating the buffer. That way we can always use
2811 strcat to add to it. */
2812 buffer[0] = '\0';
2814 switch (length)
2816 case 4:
2817 case 8:
2818 /* Just a simple conditional branch. */
2819 if (float_p)
2820 sprintf (buffer, "b%s%%?\t%%Z2%%1",
2821 inverted_p ? inverted_comp : comp);
2822 else
2823 sprintf (buffer, "b%s%s%%?\t%s%s,%%1",
2824 inverted_p ? inverted_comp : comp,
2825 need_z_p ? "z" : "",
2826 op1,
2827 op2);
2828 return buffer;
2830 case 12:
2831 case 16:
2833 /* Generate a reversed conditional branch around ` j'
2834 instruction:
2836 .set noreorder
2837 .set nomacro
2838 bc l
2840 j target
2841 .set macro
2842 .set reorder
2845 Because we have to jump four bytes *past* the following
2846 instruction if this branch was annulled, we can't just use
2847 a label, as in the picture above; there's no way to put the
2848 label after the next instruction, as the assembler does not
2849 accept `.L+4' as the target of a branch. (We can't just
2850 wait until the next instruction is output; it might be a
2851 macro and take up more than four bytes. Once again, we see
2852 why we want to eliminate macros.)
2854 If the branch is annulled, we jump four more bytes that we
2855 would otherwise; that way we skip the annulled instruction
2856 in the delay slot. */
2858 const char *target
2859 = ((iq2000_branch_likely || length == 16) ? ".+16" : ".+12");
2860 char *c;
2862 c = strchr (buffer, '\0');
2863 /* Generate the reversed comparison. This takes four
2864 bytes. */
2865 if (float_p)
2866 sprintf (c, "b%s\t%%Z2%s",
2867 inverted_p ? comp : inverted_comp,
2868 target);
2869 else
2870 sprintf (c, "b%s%s\t%s%s,%s",
2871 inverted_p ? comp : inverted_comp,
2872 need_z_p ? "z" : "",
2873 op1,
2874 op2,
2875 target);
2876 strcat (c, "\n\tnop\n\tj\t%1");
2877 if (length == 16)
2878 /* The delay slot was unfilled. Since we're inside
2879 .noreorder, the assembler will not fill in the NOP for
2880 us, so we must do it ourselves. */
2881 strcat (buffer, "\n\tnop");
2882 return buffer;
2885 default:
2886 abort ();
2889 /* NOTREACHED */
2890 return 0;
2893 #define def_builtin(NAME, TYPE, CODE) \
2894 builtin_function ((NAME), (TYPE), (CODE), BUILT_IN_MD, NULL, NULL_TREE)
2896 static void
2897 iq2000_init_builtins (void)
2899 tree endlink = void_list_node;
2900 tree void_ftype, void_ftype_int, void_ftype_int_int;
2901 tree void_ftype_int_int_int;
2902 tree int_ftype_int, int_ftype_int_int, int_ftype_int_int_int;
2903 tree int_ftype_int_int_int_int;
2905 /* func () */
2906 void_ftype
2907 = build_function_type (void_type_node,
2908 tree_cons (NULL_TREE, void_type_node, endlink));
2910 /* func (int) */
2911 void_ftype_int
2912 = build_function_type (void_type_node,
2913 tree_cons (NULL_TREE, integer_type_node, endlink));
2915 /* void func (int, int) */
2916 void_ftype_int_int
2917 = build_function_type (void_type_node,
2918 tree_cons (NULL_TREE, integer_type_node,
2919 tree_cons (NULL_TREE, integer_type_node,
2920 endlink)));
2922 /* int func (int) */
2923 int_ftype_int
2924 = build_function_type (integer_type_node,
2925 tree_cons (NULL_TREE, integer_type_node, endlink));
2927 /* int func (int, int) */
2928 int_ftype_int_int
2929 = build_function_type (integer_type_node,
2930 tree_cons (NULL_TREE, integer_type_node,
2931 tree_cons (NULL_TREE, integer_type_node,
2932 endlink)));
2934 /* void func (int, int, int) */
2935 void_ftype_int_int_int
2936 = build_function_type
2937 (void_type_node,
2938 tree_cons (NULL_TREE, integer_type_node,
2939 tree_cons (NULL_TREE, integer_type_node,
2940 tree_cons (NULL_TREE,
2941 integer_type_node,
2942 endlink))));
2944 /* int func (int, int, int, int) */
2945 int_ftype_int_int_int_int
2946 = build_function_type
2947 (integer_type_node,
2948 tree_cons (NULL_TREE, integer_type_node,
2949 tree_cons (NULL_TREE, integer_type_node,
2950 tree_cons (NULL_TREE,
2951 integer_type_node,
2952 tree_cons (NULL_TREE,
2953 integer_type_node,
2954 endlink)))));
2956 /* int func (int, int, int) */
2957 int_ftype_int_int_int
2958 = build_function_type
2959 (integer_type_node,
2960 tree_cons (NULL_TREE, integer_type_node,
2961 tree_cons (NULL_TREE, integer_type_node,
2962 tree_cons (NULL_TREE,
2963 integer_type_node,
2964 endlink))));
2966 /* int func (int, int, int, int) */
2967 int_ftype_int_int_int_int
2968 = build_function_type
2969 (integer_type_node,
2970 tree_cons (NULL_TREE, integer_type_node,
2971 tree_cons (NULL_TREE, integer_type_node,
2972 tree_cons (NULL_TREE,
2973 integer_type_node,
2974 tree_cons (NULL_TREE,
2975 integer_type_node,
2976 endlink)))));
2978 def_builtin ("__builtin_ado16", int_ftype_int_int, IQ2000_BUILTIN_ADO16);
2979 def_builtin ("__builtin_ram", int_ftype_int_int_int_int, IQ2000_BUILTIN_RAM);
2980 def_builtin ("__builtin_chkhdr", void_ftype_int_int, IQ2000_BUILTIN_CHKHDR);
2981 def_builtin ("__builtin_pkrl", void_ftype_int_int, IQ2000_BUILTIN_PKRL);
2982 def_builtin ("__builtin_cfc0", int_ftype_int, IQ2000_BUILTIN_CFC0);
2983 def_builtin ("__builtin_cfc1", int_ftype_int, IQ2000_BUILTIN_CFC1);
2984 def_builtin ("__builtin_cfc2", int_ftype_int, IQ2000_BUILTIN_CFC2);
2985 def_builtin ("__builtin_cfc3", int_ftype_int, IQ2000_BUILTIN_CFC3);
2986 def_builtin ("__builtin_ctc0", void_ftype_int_int, IQ2000_BUILTIN_CTC0);
2987 def_builtin ("__builtin_ctc1", void_ftype_int_int, IQ2000_BUILTIN_CTC1);
2988 def_builtin ("__builtin_ctc2", void_ftype_int_int, IQ2000_BUILTIN_CTC2);
2989 def_builtin ("__builtin_ctc3", void_ftype_int_int, IQ2000_BUILTIN_CTC3);
2990 def_builtin ("__builtin_mfc0", int_ftype_int, IQ2000_BUILTIN_MFC0);
2991 def_builtin ("__builtin_mfc1", int_ftype_int, IQ2000_BUILTIN_MFC1);
2992 def_builtin ("__builtin_mfc2", int_ftype_int, IQ2000_BUILTIN_MFC2);
2993 def_builtin ("__builtin_mfc3", int_ftype_int, IQ2000_BUILTIN_MFC3);
2994 def_builtin ("__builtin_mtc0", void_ftype_int_int, IQ2000_BUILTIN_MTC0);
2995 def_builtin ("__builtin_mtc1", void_ftype_int_int, IQ2000_BUILTIN_MTC1);
2996 def_builtin ("__builtin_mtc2", void_ftype_int_int, IQ2000_BUILTIN_MTC2);
2997 def_builtin ("__builtin_mtc3", void_ftype_int_int, IQ2000_BUILTIN_MTC3);
2998 def_builtin ("__builtin_lur", void_ftype_int_int, IQ2000_BUILTIN_LUR);
2999 def_builtin ("__builtin_rb", void_ftype_int_int, IQ2000_BUILTIN_RB);
3000 def_builtin ("__builtin_rx", void_ftype_int_int, IQ2000_BUILTIN_RX);
3001 def_builtin ("__builtin_srrd", void_ftype_int, IQ2000_BUILTIN_SRRD);
3002 def_builtin ("__builtin_srwr", void_ftype_int_int, IQ2000_BUILTIN_SRWR);
3003 def_builtin ("__builtin_wb", void_ftype_int_int, IQ2000_BUILTIN_WB);
3004 def_builtin ("__builtin_wx", void_ftype_int_int, IQ2000_BUILTIN_WX);
3005 def_builtin ("__builtin_luc32l", void_ftype_int_int, IQ2000_BUILTIN_LUC32L);
3006 def_builtin ("__builtin_luc64", void_ftype_int_int, IQ2000_BUILTIN_LUC64);
3007 def_builtin ("__builtin_luc64l", void_ftype_int_int, IQ2000_BUILTIN_LUC64L);
3008 def_builtin ("__builtin_luk", void_ftype_int_int, IQ2000_BUILTIN_LUK);
3009 def_builtin ("__builtin_lulck", void_ftype_int, IQ2000_BUILTIN_LULCK);
3010 def_builtin ("__builtin_lum32", void_ftype_int_int, IQ2000_BUILTIN_LUM32);
3011 def_builtin ("__builtin_lum32l", void_ftype_int_int, IQ2000_BUILTIN_LUM32L);
3012 def_builtin ("__builtin_lum64", void_ftype_int_int, IQ2000_BUILTIN_LUM64);
3013 def_builtin ("__builtin_lum64l", void_ftype_int_int, IQ2000_BUILTIN_LUM64L);
3014 def_builtin ("__builtin_lurl", void_ftype_int_int, IQ2000_BUILTIN_LURL);
3015 def_builtin ("__builtin_mrgb", int_ftype_int_int_int, IQ2000_BUILTIN_MRGB);
3016 def_builtin ("__builtin_srrdl", void_ftype_int, IQ2000_BUILTIN_SRRDL);
3017 def_builtin ("__builtin_srulck", void_ftype_int, IQ2000_BUILTIN_SRULCK);
3018 def_builtin ("__builtin_srwru", void_ftype_int_int, IQ2000_BUILTIN_SRWRU);
3019 def_builtin ("__builtin_trapqfl", void_ftype, IQ2000_BUILTIN_TRAPQFL);
3020 def_builtin ("__builtin_trapqne", void_ftype, IQ2000_BUILTIN_TRAPQNE);
3021 def_builtin ("__builtin_traprel", void_ftype_int, IQ2000_BUILTIN_TRAPREL);
3022 def_builtin ("__builtin_wbu", void_ftype_int_int_int, IQ2000_BUILTIN_WBU);
3023 def_builtin ("__builtin_syscall", void_ftype, IQ2000_BUILTIN_SYSCALL);
3026 /* Builtin for ICODE having ARGCOUNT args in ARGLIST where each arg
3027 has an rtx CODE. */
3029 static rtx
3030 expand_one_builtin (enum insn_code icode, rtx target, tree arglist,
3031 enum rtx_code *code, int argcount)
3033 rtx pat;
3034 tree arg [5];
3035 rtx op [5];
3036 enum machine_mode mode [5];
3037 int i;
3039 mode[0] = insn_data[icode].operand[0].mode;
3040 for (i = 0; i < argcount; i++)
3042 arg[i] = TREE_VALUE (arglist);
3043 arglist = TREE_CHAIN (arglist);
3044 op[i] = expand_expr (arg[i], NULL_RTX, VOIDmode, 0);
3045 mode[i] = insn_data[icode].operand[i].mode;
3046 if (code[i] == CONST_INT && GET_CODE (op[i]) != CONST_INT)
3047 error ("argument `%d' is not a constant", i + 1);
3048 if (code[i] == REG
3049 && ! (*insn_data[icode].operand[i].predicate) (op[i], mode[i]))
3050 op[i] = copy_to_mode_reg (mode[i], op[i]);
3053 if (insn_data[icode].operand[0].constraint[0] == '=')
3055 if (target == 0
3056 || GET_MODE (target) != mode[0]
3057 || ! (*insn_data[icode].operand[0].predicate) (target, mode[0]))
3058 target = gen_reg_rtx (mode[0]);
3060 else
3061 target = 0;
3063 switch (argcount)
3065 case 0:
3066 pat = GEN_FCN (icode) (target);
3067 case 1:
3068 if (target)
3069 pat = GEN_FCN (icode) (target, op[0]);
3070 else
3071 pat = GEN_FCN (icode) (op[0]);
3072 break;
3073 case 2:
3074 if (target)
3075 pat = GEN_FCN (icode) (target, op[0], op[1]);
3076 else
3077 pat = GEN_FCN (icode) (op[0], op[1]);
3078 break;
3079 case 3:
3080 if (target)
3081 pat = GEN_FCN (icode) (target, op[0], op[1], op[2]);
3082 else
3083 pat = GEN_FCN (icode) (op[0], op[1], op[2]);
3084 break;
3085 case 4:
3086 if (target)
3087 pat = GEN_FCN (icode) (target, op[0], op[1], op[2], op[3]);
3088 else
3089 pat = GEN_FCN (icode) (op[0], op[1], op[2], op[3]);
3090 break;
3091 default:
3092 abort ();
3095 if (! pat)
3096 return 0;
3097 emit_insn (pat);
3098 return target;
3101 /* Expand an expression EXP that calls a built-in function,
3102 with result going to TARGET if that's convenient
3103 (and in mode MODE if that's convenient).
3104 SUBTARGET may be used as the target for computing one of EXP's operands.
3105 IGNORE is nonzero if the value is to be ignored. */
3107 static rtx
3108 iq2000_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED,
3109 enum machine_mode mode ATTRIBUTE_UNUSED,
3110 int ignore ATTRIBUTE_UNUSED)
3112 tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
3113 tree arglist = TREE_OPERAND (exp, 1);
3114 int fcode = DECL_FUNCTION_CODE (fndecl);
3115 enum rtx_code code [5];
3117 code[0] = REG;
3118 code[1] = REG;
3119 code[2] = REG;
3120 code[3] = REG;
3121 code[4] = REG;
3122 switch (fcode)
3124 default:
3125 break;
3127 case IQ2000_BUILTIN_ADO16:
3128 return expand_one_builtin (CODE_FOR_ado16, target, arglist, code, 2);
3130 case IQ2000_BUILTIN_RAM:
3131 code[1] = CONST_INT;
3132 code[2] = CONST_INT;
3133 code[3] = CONST_INT;
3134 return expand_one_builtin (CODE_FOR_ram, target, arglist, code, 4);
3136 case IQ2000_BUILTIN_CHKHDR:
3137 return expand_one_builtin (CODE_FOR_chkhdr, target, arglist, code, 2);
3139 case IQ2000_BUILTIN_PKRL:
3140 return expand_one_builtin (CODE_FOR_pkrl, target, arglist, code, 2);
3142 case IQ2000_BUILTIN_CFC0:
3143 code[0] = CONST_INT;
3144 return expand_one_builtin (CODE_FOR_cfc0, target, arglist, code, 1);
3146 case IQ2000_BUILTIN_CFC1:
3147 code[0] = CONST_INT;
3148 return expand_one_builtin (CODE_FOR_cfc1, target, arglist, code, 1);
3150 case IQ2000_BUILTIN_CFC2:
3151 code[0] = CONST_INT;
3152 return expand_one_builtin (CODE_FOR_cfc2, target, arglist, code, 1);
3154 case IQ2000_BUILTIN_CFC3:
3155 code[0] = CONST_INT;
3156 return expand_one_builtin (CODE_FOR_cfc3, target, arglist, code, 1);
3158 case IQ2000_BUILTIN_CTC0:
3159 code[1] = CONST_INT;
3160 return expand_one_builtin (CODE_FOR_ctc0, target, arglist, code, 2);
3162 case IQ2000_BUILTIN_CTC1:
3163 code[1] = CONST_INT;
3164 return expand_one_builtin (CODE_FOR_ctc1, target, arglist, code, 2);
3166 case IQ2000_BUILTIN_CTC2:
3167 code[1] = CONST_INT;
3168 return expand_one_builtin (CODE_FOR_ctc2, target, arglist, code, 2);
3170 case IQ2000_BUILTIN_CTC3:
3171 code[1] = CONST_INT;
3172 return expand_one_builtin (CODE_FOR_ctc3, target, arglist, code, 2);
3174 case IQ2000_BUILTIN_MFC0:
3175 code[0] = CONST_INT;
3176 return expand_one_builtin (CODE_FOR_mfc0, target, arglist, code, 1);
3178 case IQ2000_BUILTIN_MFC1:
3179 code[0] = CONST_INT;
3180 return expand_one_builtin (CODE_FOR_mfc1, target, arglist, code, 1);
3182 case IQ2000_BUILTIN_MFC2:
3183 code[0] = CONST_INT;
3184 return expand_one_builtin (CODE_FOR_mfc2, target, arglist, code, 1);
3186 case IQ2000_BUILTIN_MFC3:
3187 code[0] = CONST_INT;
3188 return expand_one_builtin (CODE_FOR_mfc3, target, arglist, code, 1);
3190 case IQ2000_BUILTIN_MTC0:
3191 code[1] = CONST_INT;
3192 return expand_one_builtin (CODE_FOR_mtc0, target, arglist, code, 2);
3194 case IQ2000_BUILTIN_MTC1:
3195 code[1] = CONST_INT;
3196 return expand_one_builtin (CODE_FOR_mtc1, target, arglist, code, 2);
3198 case IQ2000_BUILTIN_MTC2:
3199 code[1] = CONST_INT;
3200 return expand_one_builtin (CODE_FOR_mtc2, target, arglist, code, 2);
3202 case IQ2000_BUILTIN_MTC3:
3203 code[1] = CONST_INT;
3204 return expand_one_builtin (CODE_FOR_mtc3, target, arglist, code, 2);
3206 case IQ2000_BUILTIN_LUR:
3207 return expand_one_builtin (CODE_FOR_lur, target, arglist, code, 2);
3209 case IQ2000_BUILTIN_RB:
3210 return expand_one_builtin (CODE_FOR_rb, target, arglist, code, 2);
3212 case IQ2000_BUILTIN_RX:
3213 return expand_one_builtin (CODE_FOR_rx, target, arglist, code, 2);
3215 case IQ2000_BUILTIN_SRRD:
3216 return expand_one_builtin (CODE_FOR_srrd, target, arglist, code, 1);
3218 case IQ2000_BUILTIN_SRWR:
3219 return expand_one_builtin (CODE_FOR_srwr, target, arglist, code, 2);
3221 case IQ2000_BUILTIN_WB:
3222 return expand_one_builtin (CODE_FOR_wb, target, arglist, code, 2);
3224 case IQ2000_BUILTIN_WX:
3225 return expand_one_builtin (CODE_FOR_wx, target, arglist, code, 2);
3227 case IQ2000_BUILTIN_LUC32L:
3228 return expand_one_builtin (CODE_FOR_luc32l, target, arglist, code, 2);
3230 case IQ2000_BUILTIN_LUC64:
3231 return expand_one_builtin (CODE_FOR_luc64, target, arglist, code, 2);
3233 case IQ2000_BUILTIN_LUC64L:
3234 return expand_one_builtin (CODE_FOR_luc64l, target, arglist, code, 2);
3236 case IQ2000_BUILTIN_LUK:
3237 return expand_one_builtin (CODE_FOR_luk, target, arglist, code, 2);
3239 case IQ2000_BUILTIN_LULCK:
3240 return expand_one_builtin (CODE_FOR_lulck, target, arglist, code, 1);
3242 case IQ2000_BUILTIN_LUM32:
3243 return expand_one_builtin (CODE_FOR_lum32, target, arglist, code, 2);
3245 case IQ2000_BUILTIN_LUM32L:
3246 return expand_one_builtin (CODE_FOR_lum32l, target, arglist, code, 2);
3248 case IQ2000_BUILTIN_LUM64:
3249 return expand_one_builtin (CODE_FOR_lum64, target, arglist, code, 2);
3251 case IQ2000_BUILTIN_LUM64L:
3252 return expand_one_builtin (CODE_FOR_lum64l, target, arglist, code, 2);
3254 case IQ2000_BUILTIN_LURL:
3255 return expand_one_builtin (CODE_FOR_lurl, target, arglist, code, 2);
3257 case IQ2000_BUILTIN_MRGB:
3258 code[2] = CONST_INT;
3259 return expand_one_builtin (CODE_FOR_mrgb, target, arglist, code, 3);
3261 case IQ2000_BUILTIN_SRRDL:
3262 return expand_one_builtin (CODE_FOR_srrdl, target, arglist, code, 1);
3264 case IQ2000_BUILTIN_SRULCK:
3265 return expand_one_builtin (CODE_FOR_srulck, target, arglist, code, 1);
3267 case IQ2000_BUILTIN_SRWRU:
3268 return expand_one_builtin (CODE_FOR_srwru, target, arglist, code, 2);
3270 case IQ2000_BUILTIN_TRAPQFL:
3271 return expand_one_builtin (CODE_FOR_trapqfl, target, arglist, code, 0);
3273 case IQ2000_BUILTIN_TRAPQNE:
3274 return expand_one_builtin (CODE_FOR_trapqne, target, arglist, code, 0);
3276 case IQ2000_BUILTIN_TRAPREL:
3277 return expand_one_builtin (CODE_FOR_traprel, target, arglist, code, 1);
3279 case IQ2000_BUILTIN_WBU:
3280 return expand_one_builtin (CODE_FOR_wbu, target, arglist, code, 3);
3282 case IQ2000_BUILTIN_SYSCALL:
3283 return expand_one_builtin (CODE_FOR_syscall, target, arglist, code, 0);
3286 return NULL_RTX;
3289 /* Worker function for TARGET_RETURN_IN_MEMORY. */
3291 static bool
3292 iq2000_return_in_memory (tree type, tree fntype ATTRIBUTE_UNUSED)
3294 return ((int_size_in_bytes (type) > (2 * UNITS_PER_WORD))
3295 || (int_size_in_bytes (type) == -1));
3298 /* Worker function for TARGET_SETUP_INCOMING_VARARGS. */
3300 static void
3301 iq2000_setup_incoming_varargs (CUMULATIVE_ARGS *cum,
3302 enum machine_mode mode ATTRIBUTE_UNUSED,
3303 tree type ATTRIBUTE_UNUSED, int * pretend_size,
3304 int no_rtl)
3306 unsigned int iq2000_off = ! cum->last_arg_fp;
3307 unsigned int iq2000_fp_off = cum->last_arg_fp;
3309 if ((cum->arg_words < MAX_ARGS_IN_REGISTERS - iq2000_off))
3311 int iq2000_save_gp_regs
3312 = MAX_ARGS_IN_REGISTERS - cum->arg_words - iq2000_off;
3313 int iq2000_save_fp_regs
3314 = (MAX_ARGS_IN_REGISTERS - cum->fp_arg_words - iq2000_fp_off);
3316 if (iq2000_save_gp_regs < 0)
3317 iq2000_save_gp_regs = 0;
3318 if (iq2000_save_fp_regs < 0)
3319 iq2000_save_fp_regs = 0;
3321 *pretend_size = ((iq2000_save_gp_regs * UNITS_PER_WORD)
3322 + (iq2000_save_fp_regs * UNITS_PER_FPREG));
3324 if (! (no_rtl))
3326 if (cum->arg_words < MAX_ARGS_IN_REGISTERS - iq2000_off)
3328 rtx ptr, mem;
3329 ptr = plus_constant (virtual_incoming_args_rtx,
3330 - (iq2000_save_gp_regs
3331 * UNITS_PER_WORD));
3332 mem = gen_rtx_MEM (BLKmode, ptr);
3333 move_block_from_reg
3334 (cum->arg_words + GP_ARG_FIRST + iq2000_off,
3335 mem,
3336 iq2000_save_gp_regs);
3342 /* A C compound statement to output to stdio stream STREAM the
3343 assembler syntax for an instruction operand that is a memory
3344 reference whose address is ADDR. ADDR is an RTL expression. */
3346 void
3347 print_operand_address (FILE * file, rtx addr)
3349 if (!addr)
3350 error ("PRINT_OPERAND_ADDRESS, null pointer");
3352 else
3353 switch (GET_CODE (addr))
3355 case REG:
3356 if (REGNO (addr) == ARG_POINTER_REGNUM)
3357 abort_with_insn (addr, "Arg pointer not eliminated.");
3359 fprintf (file, "0(%s)", reg_names [REGNO (addr)]);
3360 break;
3362 case LO_SUM:
3364 rtx arg0 = XEXP (addr, 0);
3365 rtx arg1 = XEXP (addr, 1);
3367 if (GET_CODE (arg0) != REG)
3368 abort_with_insn (addr,
3369 "PRINT_OPERAND_ADDRESS, LO_SUM with #1 not REG.");
3371 fprintf (file, "%%lo(");
3372 print_operand_address (file, arg1);
3373 fprintf (file, ")(%s)", reg_names [REGNO (arg0)]);
3375 break;
3377 case PLUS:
3379 rtx reg = 0;
3380 rtx offset = 0;
3381 rtx arg0 = XEXP (addr, 0);
3382 rtx arg1 = XEXP (addr, 1);
3384 if (GET_CODE (arg0) == REG)
3386 reg = arg0;
3387 offset = arg1;
3388 if (GET_CODE (offset) == REG)
3389 abort_with_insn (addr, "PRINT_OPERAND_ADDRESS, 2 regs");
3392 else if (GET_CODE (arg1) == REG)
3393 reg = arg1, offset = arg0;
3394 else if (CONSTANT_P (arg0) && CONSTANT_P (arg1))
3396 output_addr_const (file, addr);
3397 break;
3399 else
3400 abort_with_insn (addr, "PRINT_OPERAND_ADDRESS, no regs");
3402 if (! CONSTANT_P (offset))
3403 abort_with_insn (addr, "PRINT_OPERAND_ADDRESS, invalid insn #2");
3405 if (REGNO (reg) == ARG_POINTER_REGNUM)
3406 abort_with_insn (addr, "Arg pointer not eliminated.");
3408 output_addr_const (file, offset);
3409 fprintf (file, "(%s)", reg_names [REGNO (reg)]);
3411 break;
3413 case LABEL_REF:
3414 case SYMBOL_REF:
3415 case CONST_INT:
3416 case CONST:
3417 output_addr_const (file, addr);
3418 if (GET_CODE (addr) == CONST_INT)
3419 fprintf (file, "(%s)", reg_names [0]);
3420 break;
3422 default:
3423 abort_with_insn (addr, "PRINT_OPERAND_ADDRESS, invalid insn #1");
3424 break;
3428 /* A C compound statement to output to stdio stream FILE the
3429 assembler syntax for an instruction operand OP.
3431 LETTER is a value that can be used to specify one of several ways
3432 of printing the operand. It is used when identical operands
3433 must be printed differently depending on the context. LETTER
3434 comes from the `%' specification that was used to request
3435 printing of the operand. If the specification was just `%DIGIT'
3436 then LETTER is 0; if the specification was `%LTR DIGIT' then LETTER
3437 is the ASCII code for LTR.
3439 If OP is a register, this macro should print the register's name.
3440 The names can be found in an array `reg_names' whose type is
3441 `char *[]'. `reg_names' is initialized from `REGISTER_NAMES'.
3443 When the machine description has a specification `%PUNCT' (a `%'
3444 followed by a punctuation character), this macro is called with
3445 a null pointer for X and the punctuation character for LETTER.
3447 The IQ2000 specific codes are:
3449 'X' X is CONST_INT, prints upper 16 bits in hexadecimal format = "0x%04x",
3450 'x' X is CONST_INT, prints lower 16 bits in hexadecimal format = "0x%04x",
3451 'd' output integer constant in decimal,
3452 'z' if the operand is 0, use $0 instead of normal operand.
3453 'D' print second part of double-word register or memory operand.
3454 'L' print low-order register of double-word register operand.
3455 'M' print high-order register of double-word register operand.
3456 'C' print part of opcode for a branch condition.
3457 'F' print part of opcode for a floating-point branch condition.
3458 'N' print part of opcode for a branch condition, inverted.
3459 'W' print part of opcode for a floating-point branch condition, inverted.
3460 'A' Print part of opcode for a bit test condition.
3461 'P' Print label for a bit test.
3462 'p' Print log for a bit test.
3463 'B' print 'z' for EQ, 'n' for NE
3464 'b' print 'n' for EQ, 'z' for NE
3465 'T' print 'f' for EQ, 't' for NE
3466 't' print 't' for EQ, 'f' for NE
3467 'Z' print register and a comma, but print nothing for $fcc0
3468 '?' Print 'l' if we are to use a branch likely instead of normal branch.
3469 '@' Print the name of the assembler temporary register (at or $1).
3470 '.' Print the name of the register with a hard-wired zero (zero or $0).
3471 '$' Print the name of the stack pointer register (sp or $29).
3472 '+' Print the name of the gp register (gp or $28). */
3474 void
3475 print_operand (FILE *file, rtx op, int letter)
3477 enum rtx_code code;
3479 if (PRINT_OPERAND_PUNCT_VALID_P (letter))
3481 switch (letter)
3483 case '?':
3484 if (iq2000_branch_likely)
3485 putc ('l', file);
3486 break;
3488 case '@':
3489 fputs (reg_names [GP_REG_FIRST + 1], file);
3490 break;
3492 case '.':
3493 fputs (reg_names [GP_REG_FIRST + 0], file);
3494 break;
3496 case '$':
3497 fputs (reg_names[STACK_POINTER_REGNUM], file);
3498 break;
3500 case '+':
3501 fputs (reg_names[GP_REG_FIRST + 28], file);
3502 break;
3504 default:
3505 error ("PRINT_OPERAND: Unknown punctuation '%c'", letter);
3506 break;
3509 return;
3512 if (! op)
3514 error ("PRINT_OPERAND null pointer");
3515 return;
3518 code = GET_CODE (op);
3520 if (code == SIGN_EXTEND)
3521 op = XEXP (op, 0), code = GET_CODE (op);
3523 if (letter == 'C')
3524 switch (code)
3526 case EQ: fputs ("eq", file); break;
3527 case NE: fputs ("ne", file); break;
3528 case GT: fputs ("gt", file); break;
3529 case GE: fputs ("ge", file); break;
3530 case LT: fputs ("lt", file); break;
3531 case LE: fputs ("le", file); break;
3532 case GTU: fputs ("ne", file); break;
3533 case GEU: fputs ("geu", file); break;
3534 case LTU: fputs ("ltu", file); break;
3535 case LEU: fputs ("eq", file); break;
3536 default:
3537 abort_with_insn (op, "PRINT_OPERAND, invalid insn for %%C");
3540 else if (letter == 'N')
3541 switch (code)
3543 case EQ: fputs ("ne", file); break;
3544 case NE: fputs ("eq", file); break;
3545 case GT: fputs ("le", file); break;
3546 case GE: fputs ("lt", file); break;
3547 case LT: fputs ("ge", file); break;
3548 case LE: fputs ("gt", file); break;
3549 case GTU: fputs ("leu", file); break;
3550 case GEU: fputs ("ltu", file); break;
3551 case LTU: fputs ("geu", file); break;
3552 case LEU: fputs ("gtu", file); break;
3553 default:
3554 abort_with_insn (op, "PRINT_OPERAND, invalid insn for %%N");
3557 else if (letter == 'F')
3558 switch (code)
3560 case EQ: fputs ("c1f", file); break;
3561 case NE: fputs ("c1t", file); break;
3562 default:
3563 abort_with_insn (op, "PRINT_OPERAND, invalid insn for %%F");
3566 else if (letter == 'W')
3567 switch (code)
3569 case EQ: fputs ("c1t", file); break;
3570 case NE: fputs ("c1f", file); break;
3571 default:
3572 abort_with_insn (op, "PRINT_OPERAND, invalid insn for %%W");
3575 else if (letter == 'A')
3576 fputs (code == LABEL_REF ? "i" : "in", file);
3578 else if (letter == 'P')
3580 if (code == LABEL_REF)
3581 output_addr_const (file, op);
3582 else if (code != PC)
3583 output_operand_lossage ("invalid %%P operand");
3586 else if (letter == 'p')
3588 int value;
3589 if (code != CONST_INT
3590 || (value = exact_log2 (INTVAL (op))) < 0)
3591 output_operand_lossage ("invalid %%p value");
3592 fprintf (file, "%d", value);
3595 else if (letter == 'Z')
3597 int regnum;
3599 if (code != REG)
3600 abort ();
3602 regnum = REGNO (op);
3603 abort ();
3605 fprintf (file, "%s,", reg_names[regnum]);
3608 else if (code == REG || code == SUBREG)
3610 int regnum;
3612 if (code == REG)
3613 regnum = REGNO (op);
3614 else
3615 regnum = true_regnum (op);
3617 if ((letter == 'M' && ! WORDS_BIG_ENDIAN)
3618 || (letter == 'L' && WORDS_BIG_ENDIAN)
3619 || letter == 'D')
3620 regnum++;
3622 fprintf (file, "%s", reg_names[regnum]);
3625 else if (code == MEM)
3627 if (letter == 'D')
3628 output_address (plus_constant (XEXP (op, 0), 4));
3629 else
3630 output_address (XEXP (op, 0));
3633 else if (code == CONST_DOUBLE
3634 && GET_MODE_CLASS (GET_MODE (op)) == MODE_FLOAT)
3636 char s[60];
3638 real_to_decimal (s, CONST_DOUBLE_REAL_VALUE (op), sizeof (s), 0, 1);
3639 fputs (s, file);
3642 else if (letter == 'x' && GET_CODE (op) == CONST_INT)
3643 fprintf (file, HOST_WIDE_INT_PRINT_HEX, 0xffff & INTVAL(op));
3645 else if (letter == 'X' && GET_CODE(op) == CONST_INT)
3646 fprintf (file, HOST_WIDE_INT_PRINT_HEX, 0xffff & (INTVAL (op) >> 16));
3648 else if (letter == 'd' && GET_CODE(op) == CONST_INT)
3649 fprintf (file, HOST_WIDE_INT_PRINT_DEC, (INTVAL(op)));
3651 else if (letter == 'z' && GET_CODE (op) == CONST_INT && INTVAL (op) == 0)
3652 fputs (reg_names[GP_REG_FIRST], file);
3654 else if (letter == 'd' || letter == 'x' || letter == 'X')
3655 output_operand_lossage ("invalid use of %%d, %%x, or %%X");
3657 else if (letter == 'B')
3658 fputs (code == EQ ? "z" : "n", file);
3659 else if (letter == 'b')
3660 fputs (code == EQ ? "n" : "z", file);
3661 else if (letter == 'T')
3662 fputs (code == EQ ? "f" : "t", file);
3663 else if (letter == 't')
3664 fputs (code == EQ ? "t" : "f", file);
3666 else if (code == CONST && GET_CODE (XEXP (op, 0)) == REG)
3668 print_operand (file, XEXP (op, 0), letter);
3671 else
3672 output_addr_const (file, op);
3675 static bool
3676 iq2000_rtx_costs (rtx x, int code, int outer_code ATTRIBUTE_UNUSED, int * total)
3678 enum machine_mode mode = GET_MODE (x);
3680 switch (code)
3682 case MEM:
3684 int num_words = (GET_MODE_SIZE (mode) > UNITS_PER_WORD) ? 2 : 1;
3686 if (simple_memory_operand (x, mode))
3687 return COSTS_N_INSNS (num_words);
3689 * total = COSTS_N_INSNS (2 * num_words);
3690 break;
3693 case FFS:
3694 * total = COSTS_N_INSNS (6);
3695 break;
3697 case AND:
3698 case IOR:
3699 case XOR:
3700 case NOT:
3701 * total = COSTS_N_INSNS (mode == DImode ? 2 : 1);
3702 break;
3704 case ASHIFT:
3705 case ASHIFTRT:
3706 case LSHIFTRT:
3707 if (mode == DImode)
3708 * total = COSTS_N_INSNS ((GET_CODE (XEXP (x, 1)) == CONST_INT) ? 4 : 12);
3709 else
3710 * total = COSTS_N_INSNS (1);
3711 break;
3713 case ABS:
3714 if (mode == SFmode || mode == DFmode)
3715 * total = COSTS_N_INSNS (1);
3716 else
3717 * total = COSTS_N_INSNS (4);
3718 break;
3720 case PLUS:
3721 case MINUS:
3722 if (mode == SFmode || mode == DFmode)
3723 * total = COSTS_N_INSNS (6);
3724 else if (mode == DImode)
3725 * total = COSTS_N_INSNS (4);
3726 else
3727 * total = COSTS_N_INSNS (1);
3728 break;
3730 case NEG:
3731 * total = (mode == DImode) ? 4 : 1;
3732 break;
3734 case MULT:
3735 if (mode == SFmode)
3736 * total = COSTS_N_INSNS (7);
3737 else if (mode == DFmode)
3738 * total = COSTS_N_INSNS (8);
3739 else
3740 * total = COSTS_N_INSNS (10);
3741 break;
3743 case DIV:
3744 case MOD:
3745 if (mode == SFmode)
3746 * total = COSTS_N_INSNS (23);
3747 else if (mode == DFmode)
3748 * total = COSTS_N_INSNS (36);
3749 else
3750 * total = COSTS_N_INSNS (69);
3751 break;
3753 case UDIV:
3754 case UMOD:
3755 * total = COSTS_N_INSNS (69);
3756 break;
3758 case SIGN_EXTEND:
3759 * total = COSTS_N_INSNS (2);
3760 break;
3762 case ZERO_EXTEND:
3763 * total = COSTS_N_INSNS (1);
3764 break;
3766 case CONST_INT:
3767 * total = 0;
3768 break;
3770 case LABEL_REF:
3771 * total = COSTS_N_INSNS (2);
3772 break;
3774 case CONST:
3776 rtx offset = const0_rtx;
3777 rtx symref = eliminate_constant_term (XEXP (x, 0), & offset);
3779 if (GET_CODE (symref) == LABEL_REF)
3780 * total = COSTS_N_INSNS (2);
3781 else if (GET_CODE (symref) != SYMBOL_REF)
3782 * total = COSTS_N_INSNS (4);
3783 /* Let's be paranoid.... */
3784 else if (INTVAL (offset) < -32768 || INTVAL (offset) > 32767)
3785 * total = COSTS_N_INSNS (2);
3786 else
3787 * total = COSTS_N_INSNS (SYMBOL_REF_FLAG (symref) ? 1 : 2);
3788 break;
3791 case SYMBOL_REF:
3792 * total = COSTS_N_INSNS (SYMBOL_REF_FLAG (x) ? 1 : 2);
3793 break;
3795 case CONST_DOUBLE:
3797 rtx high, low;
3799 split_double (x, & high, & low);
3801 * total = COSTS_N_INSNS ( (high == CONST0_RTX (GET_MODE (high))
3802 || low == CONST0_RTX (GET_MODE (low)))
3803 ? 2 : 4);
3804 break;
3807 default:
3808 return false;
3810 return true;
3813 #include "gt-iq2000.h"