* target.h (struct gcc_target): Add calls.pass_by_reference.
[official-gcc.git] / gcc / config / iq2000 / iq2000.c
blob0e2f7c146f6360632afed4c3acff28db7f074fb7
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);
174 static bool iq2000_pass_by_reference (CUMULATIVE_ARGS *, enum machine_mode,
175 tree, bool);
177 #undef TARGET_INIT_BUILTINS
178 #define TARGET_INIT_BUILTINS iq2000_init_builtins
179 #undef TARGET_EXPAND_BUILTIN
180 #define TARGET_EXPAND_BUILTIN iq2000_expand_builtin
181 #undef TARGET_ASM_SELECT_RTX_SECTION
182 #define TARGET_ASM_SELECT_RTX_SECTION iq2000_select_rtx_section
183 #undef TARGET_RTX_COSTS
184 #define TARGET_RTX_COSTS iq2000_rtx_costs
185 #undef TARGET_ADDRESS_COST
186 #define TARGET_ADDRESS_COST iq2000_address_cost
187 #undef TARGET_ASM_SELECT_SECTION
188 #define TARGET_ASM_SELECT_SECTION iq2000_select_section
190 #undef TARGET_PROMOTE_FUNCTION_ARGS
191 #define TARGET_PROMOTE_FUNCTION_ARGS hook_bool_tree_true
192 #undef TARGET_PROMOTE_FUNCTION_RETURN
193 #define TARGET_PROMOTE_FUNCTION_RETURN hook_bool_tree_true
194 #undef TARGET_PROMOTE_PROTOTYPES
195 #define TARGET_PROMOTE_PROTOTYPES hook_bool_tree_true
197 #undef TARGET_RETURN_IN_MEMORY
198 #define TARGET_RETURN_IN_MEMORY iq2000_return_in_memory
199 #undef TARGET_PASS_BY_REFERENCE
200 #define TARGET_PASS_BY_REFERENCE iq2000_pass_by_reference
202 #undef TARGET_SETUP_INCOMING_VARARGS
203 #define TARGET_SETUP_INCOMING_VARARGS iq2000_setup_incoming_varargs
204 #undef TARGET_STRICT_ARGUMENT_NAMING
205 #define TARGET_STRICT_ARGUMENT_NAMING hook_bool_CUMULATIVE_ARGS_true
207 #undef TARGET_SCHED_USE_DFA_PIPELINE_INTERFACE
208 #define TARGET_SCHED_USE_DFA_PIPELINE_INTERFACE hook_int_void_1
210 struct gcc_target targetm = TARGET_INITIALIZER;
212 /* Return 1 if OP can be used as an operand where a register or 16 bit unsigned
213 integer is needed. */
216 uns_arith_operand (rtx op, enum machine_mode mode)
218 if (GET_CODE (op) == CONST_INT && SMALL_INT_UNSIGNED (op))
219 return 1;
221 return register_operand (op, mode);
224 /* Return 1 if OP can be used as an operand where a 16 bit integer is needed. */
227 arith_operand (rtx op, enum machine_mode mode)
229 if (GET_CODE (op) == CONST_INT && SMALL_INT (op))
230 return 1;
232 return register_operand (op, mode);
235 /* Return 1 if OP is a integer which fits in 16 bits. */
238 small_int (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
240 return (GET_CODE (op) == CONST_INT && SMALL_INT (op));
243 /* Return 1 if OP is a 32 bit integer which is too big to be loaded with one
244 instruction. */
247 large_int (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
249 HOST_WIDE_INT value;
251 if (GET_CODE (op) != CONST_INT)
252 return 0;
254 value = INTVAL (op);
256 /* IOR reg,$r0,value. */
257 if ((value & ~ ((HOST_WIDE_INT) 0x0000ffff)) == 0)
258 return 0;
260 /* SUBU reg,$r0,value. */
261 if (((unsigned HOST_WIDE_INT) (value + 32768)) <= 32767)
262 return 0;
264 /* LUI reg,value >> 16. */
265 if ((value & 0x0000ffff) == 0)
266 return 0;
268 return 1;
271 /* Return 1 if OP is a register or the constant 0. */
274 reg_or_0_operand (rtx op, enum machine_mode mode)
276 switch (GET_CODE (op))
278 case CONST_INT:
279 return INTVAL (op) == 0;
281 case CONST_DOUBLE:
282 return op == CONST0_RTX (mode);
284 case REG:
285 case SUBREG:
286 return register_operand (op, mode);
288 default:
289 break;
292 return 0;
295 /* Return 1 if OP is a memory operand that fits in a single instruction
296 (ie, register + small offset). */
299 simple_memory_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
301 rtx addr, plus0, plus1;
303 /* Eliminate non-memory operations. */
304 if (GET_CODE (op) != MEM)
305 return 0;
307 /* Dword operations really put out 2 instructions, so eliminate them. */
308 if (GET_MODE_SIZE (GET_MODE (op)) > (unsigned) UNITS_PER_WORD)
309 return 0;
311 /* Decode the address now. */
312 addr = XEXP (op, 0);
313 switch (GET_CODE (addr))
315 case REG:
316 case LO_SUM:
317 return 1;
319 case CONST_INT:
320 return SMALL_INT (addr);
322 case PLUS:
323 plus0 = XEXP (addr, 0);
324 plus1 = XEXP (addr, 1);
325 if (GET_CODE (plus0) == REG
326 && GET_CODE (plus1) == CONST_INT && SMALL_INT (plus1)
327 && SMALL_INT_UNSIGNED (plus1) /* No negative offsets. */)
328 return 1;
330 else if (GET_CODE (plus1) == REG
331 && GET_CODE (plus0) == CONST_INT && SMALL_INT (plus0)
332 && SMALL_INT_UNSIGNED (plus1) /* No negative offsets. */)
333 return 1;
335 else
336 return 0;
338 case SYMBOL_REF:
339 return 0;
341 default:
342 break;
345 return 0;
348 /* Return nonzero if the code of this rtx pattern is EQ or NE. */
351 equality_op (rtx op, enum machine_mode mode)
353 if (mode != GET_MODE (op))
354 return 0;
356 return GET_CODE (op) == EQ || GET_CODE (op) == NE;
359 /* Return nonzero if the code is a relational operations (EQ, LE, etc). */
362 cmp_op (rtx op, enum machine_mode mode)
364 if (mode != GET_MODE (op))
365 return 0;
367 return COMPARISON_P (op);
370 /* Return nonzero if the operand is either the PC or a label_ref. */
373 pc_or_label_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
375 if (op == pc_rtx)
376 return 1;
378 if (GET_CODE (op) == LABEL_REF)
379 return 1;
381 return 0;
384 /* Return nonzero if OP is a valid operand for a call instruction. */
387 call_insn_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
389 return (CONSTANT_ADDRESS_P (op)
390 || (GET_CODE (op) == REG && op != arg_pointer_rtx
391 && ! (REGNO (op) >= FIRST_PSEUDO_REGISTER
392 && REGNO (op) <= LAST_VIRTUAL_REGISTER)));
395 /* Return nonzero if OP is valid as a source operand for a move instruction. */
398 move_operand (rtx op, enum machine_mode mode)
400 /* Accept any general operand after reload has started; doing so
401 avoids losing if reload does an in-place replacement of a register
402 with a SYMBOL_REF or CONST. */
403 return (general_operand (op, mode)
404 && (! (iq2000_check_split (op, mode))
405 || reload_in_progress || reload_completed));
408 /* Return nonzero if OP is a constant power of 2. */
411 power_of_2_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
413 int intval;
415 if (GET_CODE (op) != CONST_INT)
416 return 0;
417 else
418 intval = INTVAL (op);
420 return ((intval & ((unsigned)(intval) - 1)) == 0);
423 /* Return nonzero if we split the address into high and low parts. */
426 iq2000_check_split (rtx address, enum machine_mode mode)
428 /* This is the same check used in simple_memory_operand.
429 We use it here because LO_SUM is not offsettable. */
430 if (GET_MODE_SIZE (mode) > (unsigned) UNITS_PER_WORD)
431 return 0;
433 if ((GET_CODE (address) == SYMBOL_REF)
434 || (GET_CODE (address) == CONST
435 && GET_CODE (XEXP (XEXP (address, 0), 0)) == SYMBOL_REF)
436 || GET_CODE (address) == LABEL_REF)
437 return 1;
439 return 0;
442 /* Return nonzero if REG is valid for MODE. */
445 iq2000_reg_mode_ok_for_base_p (rtx reg,
446 enum machine_mode mode ATTRIBUTE_UNUSED,
447 int strict)
449 return (strict
450 ? REGNO_MODE_OK_FOR_BASE_P (REGNO (reg), mode)
451 : GP_REG_OR_PSEUDO_NONSTRICT_P (REGNO (reg), mode));
454 /* Return a nonzero value if XINSN is a legitimate address for a
455 memory operand of the indicated MODE. STRICT is nonzero if this
456 function is called during reload. */
459 iq2000_legitimate_address_p (enum machine_mode mode, rtx xinsn, int strict)
461 if (TARGET_DEBUG_A_MODE)
463 GO_PRINTF2 ("\n========== GO_IF_LEGITIMATE_ADDRESS, %sstrict\n",
464 strict ? "" : "not ");
465 GO_DEBUG_RTX (xinsn);
468 /* Check for constant before stripping off SUBREG, so that we don't
469 accept (subreg (const_int)) which will fail to reload. */
470 if (CONSTANT_ADDRESS_P (xinsn)
471 && ! (iq2000_check_split (xinsn, mode))
472 && ! (GET_CODE (xinsn) == CONST_INT && ! SMALL_INT (xinsn)))
473 return 1;
475 while (GET_CODE (xinsn) == SUBREG)
476 xinsn = SUBREG_REG (xinsn);
478 if (GET_CODE (xinsn) == REG
479 && iq2000_reg_mode_ok_for_base_p (xinsn, mode, strict))
480 return 1;
482 if (GET_CODE (xinsn) == LO_SUM)
484 rtx xlow0 = XEXP (xinsn, 0);
485 rtx xlow1 = XEXP (xinsn, 1);
487 while (GET_CODE (xlow0) == SUBREG)
488 xlow0 = SUBREG_REG (xlow0);
489 if (GET_CODE (xlow0) == REG
490 && iq2000_reg_mode_ok_for_base_p (xlow0, mode, strict)
491 && iq2000_check_split (xlow1, mode))
492 return 1;
495 if (GET_CODE (xinsn) == PLUS)
497 rtx xplus0 = XEXP (xinsn, 0);
498 rtx xplus1 = XEXP (xinsn, 1);
499 enum rtx_code code0;
500 enum rtx_code code1;
502 while (GET_CODE (xplus0) == SUBREG)
503 xplus0 = SUBREG_REG (xplus0);
504 code0 = GET_CODE (xplus0);
506 while (GET_CODE (xplus1) == SUBREG)
507 xplus1 = SUBREG_REG (xplus1);
508 code1 = GET_CODE (xplus1);
510 if (code0 == REG
511 && iq2000_reg_mode_ok_for_base_p (xplus0, mode, strict))
513 if (code1 == CONST_INT && SMALL_INT (xplus1)
514 && SMALL_INT_UNSIGNED (xplus1) /* No negative offsets */)
515 return 1;
519 if (TARGET_DEBUG_A_MODE)
520 GO_PRINTF ("Not a legitimate address\n");
522 /* The address was not legitimate. */
523 return 0;
526 /* Returns an operand string for the given instruction's delay slot,
527 after updating filled delay slot statistics.
529 We assume that operands[0] is the target register that is set.
531 In order to check the next insn, most of this functionality is moved
532 to FINAL_PRESCAN_INSN, and we just set the global variables that
533 it needs. */
535 const char *
536 iq2000_fill_delay_slot (const char *ret, enum delay_type type, rtx operands[],
537 rtx cur_insn)
539 rtx set_reg;
540 enum machine_mode mode;
541 rtx next_insn = cur_insn ? NEXT_INSN (cur_insn) : NULL_RTX;
542 int num_nops;
544 if (type == DELAY_LOAD || type == DELAY_FCMP)
545 num_nops = 1;
547 else
548 num_nops = 0;
550 /* Make sure that we don't put nop's after labels. */
551 next_insn = NEXT_INSN (cur_insn);
552 while (next_insn != 0
553 && (GET_CODE (next_insn) == NOTE
554 || GET_CODE (next_insn) == CODE_LABEL))
555 next_insn = NEXT_INSN (next_insn);
557 dslots_load_total += num_nops;
558 if (TARGET_DEBUG_C_MODE
559 || type == DELAY_NONE
560 || operands == 0
561 || cur_insn == 0
562 || next_insn == 0
563 || GET_CODE (next_insn) == CODE_LABEL
564 || (set_reg = operands[0]) == 0)
566 dslots_number_nops = 0;
567 iq2000_load_reg = 0;
568 iq2000_load_reg2 = 0;
569 iq2000_load_reg3 = 0;
570 iq2000_load_reg4 = 0;
572 return ret;
575 set_reg = operands[0];
576 if (set_reg == 0)
577 return ret;
579 while (GET_CODE (set_reg) == SUBREG)
580 set_reg = SUBREG_REG (set_reg);
582 mode = GET_MODE (set_reg);
583 dslots_number_nops = num_nops;
584 iq2000_load_reg = set_reg;
585 if (GET_MODE_SIZE (mode)
586 > (unsigned) (UNITS_PER_WORD))
587 iq2000_load_reg2 = gen_rtx_REG (SImode, REGNO (set_reg) + 1);
588 else
589 iq2000_load_reg2 = 0;
591 return ret;
594 /* Determine whether a memory reference takes one (based off of the GP
595 pointer), two (normal), or three (label + reg) instructions, and bump the
596 appropriate counter for -mstats. */
598 static void
599 iq2000_count_memory_refs (rtx op, int num)
601 int additional = 0;
602 int n_words = 0;
603 rtx addr, plus0, plus1;
604 enum rtx_code code0, code1;
605 int looping;
607 if (TARGET_DEBUG_B_MODE)
609 fprintf (stderr, "\n========== iq2000_count_memory_refs:\n");
610 debug_rtx (op);
613 /* Skip MEM if passed, otherwise handle movsi of address. */
614 addr = (GET_CODE (op) != MEM) ? op : XEXP (op, 0);
616 /* Loop, going through the address RTL. */
619 looping = FALSE;
620 switch (GET_CODE (addr))
622 case REG:
623 case CONST_INT:
624 case LO_SUM:
625 break;
627 case PLUS:
628 plus0 = XEXP (addr, 0);
629 plus1 = XEXP (addr, 1);
630 code0 = GET_CODE (plus0);
631 code1 = GET_CODE (plus1);
633 if (code0 == REG)
635 additional++;
636 addr = plus1;
637 looping = 1;
638 continue;
641 if (code0 == CONST_INT)
643 addr = plus1;
644 looping = 1;
645 continue;
648 if (code1 == REG)
650 additional++;
651 addr = plus0;
652 looping = 1;
653 continue;
656 if (code1 == CONST_INT)
658 addr = plus0;
659 looping = 1;
660 continue;
663 if (code0 == SYMBOL_REF || code0 == LABEL_REF || code0 == CONST)
665 addr = plus0;
666 looping = 1;
667 continue;
670 if (code1 == SYMBOL_REF || code1 == LABEL_REF || code1 == CONST)
672 addr = plus1;
673 looping = 1;
674 continue;
677 break;
679 case LABEL_REF:
680 n_words = 2; /* Always 2 words. */
681 break;
683 case CONST:
684 addr = XEXP (addr, 0);
685 looping = 1;
686 continue;
688 case SYMBOL_REF:
689 n_words = SYMBOL_REF_FLAG (addr) ? 1 : 2;
690 break;
692 default:
693 break;
696 while (looping);
698 if (n_words == 0)
699 return;
701 n_words += additional;
702 if (n_words > 3)
703 n_words = 3;
705 num_refs[n_words-1] += num;
708 /* Abort after printing out a specific insn. */
710 static void
711 abort_with_insn (rtx insn, const char * reason)
713 error (reason);
714 debug_rtx (insn);
715 abort ();
718 /* Return the appropriate instructions to move one operand to another. */
720 const char *
721 iq2000_move_1word (rtx operands[], rtx insn, int unsignedp)
723 const char *ret = 0;
724 rtx op0 = operands[0];
725 rtx op1 = operands[1];
726 enum rtx_code code0 = GET_CODE (op0);
727 enum rtx_code code1 = GET_CODE (op1);
728 enum machine_mode mode = GET_MODE (op0);
729 int subreg_offset0 = 0;
730 int subreg_offset1 = 0;
731 enum delay_type delay = DELAY_NONE;
733 while (code0 == SUBREG)
735 subreg_offset0 += subreg_regno_offset (REGNO (SUBREG_REG (op0)),
736 GET_MODE (SUBREG_REG (op0)),
737 SUBREG_BYTE (op0),
738 GET_MODE (op0));
739 op0 = SUBREG_REG (op0);
740 code0 = GET_CODE (op0);
743 while (code1 == SUBREG)
745 subreg_offset1 += subreg_regno_offset (REGNO (SUBREG_REG (op1)),
746 GET_MODE (SUBREG_REG (op1)),
747 SUBREG_BYTE (op1),
748 GET_MODE (op1));
749 op1 = SUBREG_REG (op1);
750 code1 = GET_CODE (op1);
753 /* For our purposes, a condition code mode is the same as SImode. */
754 if (mode == CCmode)
755 mode = SImode;
757 if (code0 == REG)
759 int regno0 = REGNO (op0) + subreg_offset0;
761 if (code1 == REG)
763 int regno1 = REGNO (op1) + subreg_offset1;
765 /* Do not do anything for assigning a register to itself */
766 if (regno0 == regno1)
767 ret = "";
769 else if (GP_REG_P (regno0))
771 if (GP_REG_P (regno1))
772 ret = "or\t%0,%%0,%1";
777 else if (code1 == MEM)
779 delay = DELAY_LOAD;
781 if (TARGET_STATS)
782 iq2000_count_memory_refs (op1, 1);
784 if (GP_REG_P (regno0))
786 /* For loads, use the mode of the memory item, instead of the
787 target, so zero/sign extend can use this code as well. */
788 switch (GET_MODE (op1))
790 default:
791 break;
792 case SFmode:
793 ret = "lw\t%0,%1";
794 break;
795 case SImode:
796 case CCmode:
797 ret = "lw\t%0,%1";
798 break;
799 case HImode:
800 ret = (unsignedp) ? "lhu\t%0,%1" : "lh\t%0,%1";
801 break;
802 case QImode:
803 ret = (unsignedp) ? "lbu\t%0,%1" : "lb\t%0,%1";
804 break;
809 else if (code1 == CONST_INT
810 || (code1 == CONST_DOUBLE
811 && GET_MODE (op1) == VOIDmode))
813 if (code1 == CONST_DOUBLE)
815 /* This can happen when storing constants into long long
816 bitfields. Just store the least significant word of
817 the value. */
818 operands[1] = op1 = GEN_INT (CONST_DOUBLE_LOW (op1));
821 if (INTVAL (op1) == 0)
823 if (GP_REG_P (regno0))
824 ret = "or\t%0,%%0,%z1";
826 else if (GP_REG_P (regno0))
828 if (SMALL_INT_UNSIGNED (op1))
829 ret = "ori\t%0,%%0,%x1\t\t\t# %1";
830 else if (SMALL_INT (op1))
831 ret = "addiu\t%0,%%0,%1\t\t\t# %1";
832 else
833 ret = "lui\t%0,%X1\t\t\t# %1\n\tori\t%0,%0,%x1";
837 else if (code1 == CONST_DOUBLE && mode == SFmode)
839 if (op1 == CONST0_RTX (SFmode))
841 if (GP_REG_P (regno0))
842 ret = "or\t%0,%%0,%.";
845 else
847 delay = DELAY_LOAD;
848 ret = "li.s\t%0,%1";
852 else if (code1 == LABEL_REF)
854 if (TARGET_STATS)
855 iq2000_count_memory_refs (op1, 1);
857 ret = "la\t%0,%a1";
860 else if (code1 == SYMBOL_REF || code1 == CONST)
862 if (TARGET_STATS)
863 iq2000_count_memory_refs (op1, 1);
865 ret = "la\t%0,%a1";
868 else if (code1 == PLUS)
870 rtx add_op0 = XEXP (op1, 0);
871 rtx add_op1 = XEXP (op1, 1);
873 if (GET_CODE (XEXP (op1, 1)) == REG
874 && GET_CODE (XEXP (op1, 0)) == CONST_INT)
875 add_op0 = XEXP (op1, 1), add_op1 = XEXP (op1, 0);
877 operands[2] = add_op0;
878 operands[3] = add_op1;
879 ret = "add%:\t%0,%2,%3";
882 else if (code1 == HIGH)
884 operands[1] = XEXP (op1, 0);
885 ret = "lui\t%0,%%hi(%1)";
889 else if (code0 == MEM)
891 if (TARGET_STATS)
892 iq2000_count_memory_refs (op0, 1);
894 if (code1 == REG)
896 int regno1 = REGNO (op1) + subreg_offset1;
898 if (GP_REG_P (regno1))
900 switch (mode)
902 case SFmode: ret = "sw\t%1,%0"; break;
903 case SImode: ret = "sw\t%1,%0"; break;
904 case HImode: ret = "sh\t%1,%0"; break;
905 case QImode: ret = "sb\t%1,%0"; break;
906 default: break;
911 else if (code1 == CONST_INT && INTVAL (op1) == 0)
913 switch (mode)
915 case SFmode: ret = "sw\t%z1,%0"; break;
916 case SImode: ret = "sw\t%z1,%0"; break;
917 case HImode: ret = "sh\t%z1,%0"; break;
918 case QImode: ret = "sb\t%z1,%0"; break;
919 default: break;
923 else if (code1 == CONST_DOUBLE && op1 == CONST0_RTX (mode))
925 switch (mode)
927 case SFmode: ret = "sw\t%.,%0"; break;
928 case SImode: ret = "sw\t%.,%0"; break;
929 case HImode: ret = "sh\t%.,%0"; break;
930 case QImode: ret = "sb\t%.,%0"; break;
931 default: break;
936 if (ret == 0)
938 abort_with_insn (insn, "Bad move");
939 return 0;
942 if (delay != DELAY_NONE)
943 return iq2000_fill_delay_slot (ret, delay, operands, insn);
945 return ret;
948 /* Provide the costs of an addressing mode that contains ADDR. */
950 static int
951 iq2000_address_cost (rtx addr)
953 switch (GET_CODE (addr))
955 case LO_SUM:
956 return 1;
958 case LABEL_REF:
959 return 2;
961 case CONST:
963 rtx offset = const0_rtx;
965 addr = eliminate_constant_term (XEXP (addr, 0), & offset);
966 if (GET_CODE (addr) == LABEL_REF)
967 return 2;
969 if (GET_CODE (addr) != SYMBOL_REF)
970 return 4;
972 if (! SMALL_INT (offset))
973 return 2;
976 /* Fall through. */
978 case SYMBOL_REF:
979 return SYMBOL_REF_FLAG (addr) ? 1 : 2;
981 case PLUS:
983 rtx plus0 = XEXP (addr, 0);
984 rtx plus1 = XEXP (addr, 1);
986 if (GET_CODE (plus0) != REG && GET_CODE (plus1) == REG)
987 plus0 = XEXP (addr, 1), plus1 = XEXP (addr, 0);
989 if (GET_CODE (plus0) != REG)
990 break;
992 switch (GET_CODE (plus1))
994 case CONST_INT:
995 return SMALL_INT (plus1) ? 1 : 2;
997 case CONST:
998 case SYMBOL_REF:
999 case LABEL_REF:
1000 case HIGH:
1001 case LO_SUM:
1002 return iq2000_address_cost (plus1) + 1;
1004 default:
1005 break;
1009 default:
1010 break;
1013 return 4;
1016 /* Make normal rtx_code into something we can index from an array. */
1018 static enum internal_test
1019 map_test_to_internal_test (enum rtx_code test_code)
1021 enum internal_test test = ITEST_MAX;
1023 switch (test_code)
1025 case EQ: test = ITEST_EQ; break;
1026 case NE: test = ITEST_NE; break;
1027 case GT: test = ITEST_GT; break;
1028 case GE: test = ITEST_GE; break;
1029 case LT: test = ITEST_LT; break;
1030 case LE: test = ITEST_LE; break;
1031 case GTU: test = ITEST_GTU; break;
1032 case GEU: test = ITEST_GEU; break;
1033 case LTU: test = ITEST_LTU; break;
1034 case LEU: test = ITEST_LEU; break;
1035 default: break;
1038 return test;
1041 /* Generate the code to do a TEST_CODE comparison on two integer values CMP0
1042 and CMP1. P_INVERT is NULL or ptr if branch needs to reverse its test.
1043 The return value RESULT is:
1044 (reg:SI xx) The pseudo register the comparison is in
1045 0 No register, generate a simple branch. */
1048 gen_int_relational (enum rtx_code test_code, rtx result, rtx cmp0, rtx cmp1,
1049 int *p_invert)
1051 struct cmp_info
1053 enum rtx_code test_code; /* Code to use in instruction (LT vs. LTU). */
1054 int const_low; /* Low bound of constant we can accept. */
1055 int const_high; /* High bound of constant we can accept. */
1056 int const_add; /* Constant to add (convert LE -> LT). */
1057 int reverse_regs; /* Reverse registers in test. */
1058 int invert_const; /* != 0 if invert value if cmp1 is constant. */
1059 int invert_reg; /* != 0 if invert value if cmp1 is register. */
1060 int unsignedp; /* != 0 for unsigned comparisons. */
1063 static struct cmp_info info[ (int)ITEST_MAX ] =
1065 { XOR, 0, 65535, 0, 0, 0, 0, 0 }, /* EQ */
1066 { XOR, 0, 65535, 0, 0, 1, 1, 0 }, /* NE */
1067 { LT, -32769, 32766, 1, 1, 1, 0, 0 }, /* GT */
1068 { LT, -32768, 32767, 0, 0, 1, 1, 0 }, /* GE */
1069 { LT, -32768, 32767, 0, 0, 0, 0, 0 }, /* LT */
1070 { LT, -32769, 32766, 1, 1, 0, 1, 0 }, /* LE */
1071 { LTU, -32769, 32766, 1, 1, 1, 0, 1 }, /* GTU */
1072 { LTU, -32768, 32767, 0, 0, 1, 1, 1 }, /* GEU */
1073 { LTU, -32768, 32767, 0, 0, 0, 0, 1 }, /* LTU */
1074 { LTU, -32769, 32766, 1, 1, 0, 1, 1 }, /* LEU */
1077 enum internal_test test;
1078 enum machine_mode mode;
1079 struct cmp_info *p_info;
1080 int branch_p;
1081 int eqne_p;
1082 int invert;
1083 rtx reg;
1084 rtx reg2;
1086 test = map_test_to_internal_test (test_code);
1087 if (test == ITEST_MAX)
1088 abort ();
1090 p_info = &info[(int) test];
1091 eqne_p = (p_info->test_code == XOR);
1093 mode = GET_MODE (cmp0);
1094 if (mode == VOIDmode)
1095 mode = GET_MODE (cmp1);
1097 /* Eliminate simple branches. */
1098 branch_p = (result == 0);
1099 if (branch_p)
1101 if (GET_CODE (cmp0) == REG || GET_CODE (cmp0) == SUBREG)
1103 /* Comparisons against zero are simple branches. */
1104 if (GET_CODE (cmp1) == CONST_INT && INTVAL (cmp1) == 0)
1105 return 0;
1107 /* Test for beq/bne. */
1108 if (eqne_p)
1109 return 0;
1112 /* Allocate a pseudo to calculate the value in. */
1113 result = gen_reg_rtx (mode);
1116 /* Make sure we can handle any constants given to us. */
1117 if (GET_CODE (cmp0) == CONST_INT)
1118 cmp0 = force_reg (mode, cmp0);
1120 if (GET_CODE (cmp1) == CONST_INT)
1122 HOST_WIDE_INT value = INTVAL (cmp1);
1124 if (value < p_info->const_low
1125 || value > p_info->const_high)
1126 cmp1 = force_reg (mode, cmp1);
1129 /* See if we need to invert the result. */
1130 invert = (GET_CODE (cmp1) == CONST_INT
1131 ? p_info->invert_const : p_info->invert_reg);
1133 if (p_invert != (int *)0)
1135 *p_invert = invert;
1136 invert = 0;
1139 /* Comparison to constants, may involve adding 1 to change a LT into LE.
1140 Comparison between two registers, may involve switching operands. */
1141 if (GET_CODE (cmp1) == CONST_INT)
1143 if (p_info->const_add != 0)
1145 HOST_WIDE_INT new = INTVAL (cmp1) + p_info->const_add;
1147 /* If modification of cmp1 caused overflow,
1148 we would get the wrong answer if we follow the usual path;
1149 thus, x > 0xffffffffU would turn into x > 0U. */
1150 if ((p_info->unsignedp
1151 ? (unsigned HOST_WIDE_INT) new >
1152 (unsigned HOST_WIDE_INT) INTVAL (cmp1)
1153 : new > INTVAL (cmp1))
1154 != (p_info->const_add > 0))
1156 /* This test is always true, but if INVERT is true then
1157 the result of the test needs to be inverted so 0 should
1158 be returned instead. */
1159 emit_move_insn (result, invert ? const0_rtx : const_true_rtx);
1160 return result;
1162 else
1163 cmp1 = GEN_INT (new);
1167 else if (p_info->reverse_regs)
1169 rtx temp = cmp0;
1170 cmp0 = cmp1;
1171 cmp1 = temp;
1174 if (test == ITEST_NE && GET_CODE (cmp1) == CONST_INT && INTVAL (cmp1) == 0)
1175 reg = cmp0;
1176 else
1178 reg = (invert || eqne_p) ? gen_reg_rtx (mode) : result;
1179 convert_move (reg, gen_rtx_fmt_ee (p_info->test_code, mode, cmp0, cmp1), 0);
1182 if (test == ITEST_NE)
1184 convert_move (result, gen_rtx_GTU (mode, reg, const0_rtx), 0);
1185 if (p_invert != NULL)
1186 *p_invert = 0;
1187 invert = 0;
1190 else if (test == ITEST_EQ)
1192 reg2 = invert ? gen_reg_rtx (mode) : result;
1193 convert_move (reg2, gen_rtx_LTU (mode, reg, const1_rtx), 0);
1194 reg = reg2;
1197 if (invert)
1199 rtx one;
1201 one = const1_rtx;
1202 convert_move (result, gen_rtx_XOR (mode, reg, one), 0);
1205 return result;
1208 /* Emit the common code for doing conditional branches.
1209 operand[0] is the label to jump to.
1210 The comparison operands are saved away by cmp{si,di,sf,df}. */
1212 void
1213 gen_conditional_branch (rtx operands[], enum rtx_code test_code)
1215 enum cmp_type type = branch_type;
1216 rtx cmp0 = branch_cmp[0];
1217 rtx cmp1 = branch_cmp[1];
1218 enum machine_mode mode;
1219 rtx reg;
1220 int invert;
1221 rtx label1, label2;
1223 switch (type)
1225 case CMP_SI:
1226 case CMP_DI:
1227 mode = type == CMP_SI ? SImode : DImode;
1228 invert = 0;
1229 reg = gen_int_relational (test_code, NULL_RTX, cmp0, cmp1, &invert);
1231 if (reg)
1233 cmp0 = reg;
1234 cmp1 = const0_rtx;
1235 test_code = NE;
1237 else if (GET_CODE (cmp1) == CONST_INT && INTVAL (cmp1) != 0)
1238 /* We don't want to build a comparison against a nonzero
1239 constant. */
1240 cmp1 = force_reg (mode, cmp1);
1242 break;
1244 case CMP_SF:
1245 case CMP_DF:
1246 reg = gen_reg_rtx (CCmode);
1248 /* For cmp0 != cmp1, build cmp0 == cmp1, and test for result == 0. */
1249 emit_insn (gen_rtx_SET (VOIDmode, reg,
1250 gen_rtx_fmt_ee (test_code == NE ? EQ : test_code,
1251 CCmode, cmp0, cmp1)));
1253 test_code = test_code == NE ? EQ : NE;
1254 mode = CCmode;
1255 cmp0 = reg;
1256 cmp1 = const0_rtx;
1257 invert = 0;
1258 break;
1260 default:
1261 abort_with_insn (gen_rtx_fmt_ee (test_code, VOIDmode, cmp0, cmp1),
1262 "bad test");
1265 /* Generate the branch. */
1266 label1 = gen_rtx_LABEL_REF (VOIDmode, operands[0]);
1267 label2 = pc_rtx;
1269 if (invert)
1271 label2 = label1;
1272 label1 = pc_rtx;
1275 emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
1276 gen_rtx_IF_THEN_ELSE (VOIDmode,
1277 gen_rtx_fmt_ee (test_code,
1278 mode,
1279 cmp0, cmp1),
1280 label1, label2)));
1283 /* Initialize CUM for a function FNTYPE. */
1285 void
1286 init_cumulative_args (CUMULATIVE_ARGS *cum, tree fntype,
1287 rtx libname ATTRIBUTE_UNUSED)
1289 static CUMULATIVE_ARGS zero_cum;
1290 tree param;
1291 tree next_param;
1293 if (TARGET_DEBUG_D_MODE)
1295 fprintf (stderr,
1296 "\ninit_cumulative_args, fntype = 0x%.8lx", (long) fntype);
1298 if (!fntype)
1299 fputc ('\n', stderr);
1301 else
1303 tree ret_type = TREE_TYPE (fntype);
1305 fprintf (stderr, ", fntype code = %s, ret code = %s\n",
1306 tree_code_name[(int)TREE_CODE (fntype)],
1307 tree_code_name[(int)TREE_CODE (ret_type)]);
1311 *cum = zero_cum;
1313 /* Determine if this function has variable arguments. This is
1314 indicated by the last argument being 'void_type_mode' if there
1315 are no variable arguments. The standard IQ2000 calling sequence
1316 passes all arguments in the general purpose registers in this case. */
1318 for (param = fntype ? TYPE_ARG_TYPES (fntype) : 0;
1319 param != 0; param = next_param)
1321 next_param = TREE_CHAIN (param);
1322 if (next_param == 0 && TREE_VALUE (param) != void_type_node)
1323 cum->gp_reg_found = 1;
1327 /* Advance the argument of type TYPE and mode MODE to the next argument
1328 position in CUM. */
1330 void
1331 function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode, tree type,
1332 int named)
1334 if (TARGET_DEBUG_D_MODE)
1336 fprintf (stderr,
1337 "function_adv({gp reg found = %d, arg # = %2d, words = %2d}, %4s, ",
1338 cum->gp_reg_found, cum->arg_number, cum->arg_words,
1339 GET_MODE_NAME (mode));
1340 fprintf (stderr, HOST_PTR_PRINTF, (const PTR) type);
1341 fprintf (stderr, ", %d )\n\n", named);
1344 cum->arg_number++;
1345 switch (mode)
1347 case VOIDmode:
1348 break;
1350 default:
1351 if (GET_MODE_CLASS (mode) != MODE_COMPLEX_INT
1352 && GET_MODE_CLASS (mode) != MODE_COMPLEX_FLOAT)
1353 abort ();
1355 cum->gp_reg_found = 1;
1356 cum->arg_words += ((GET_MODE_SIZE (mode) + UNITS_PER_WORD - 1)
1357 / UNITS_PER_WORD);
1358 break;
1360 case BLKmode:
1361 cum->gp_reg_found = 1;
1362 cum->arg_words += ((int_size_in_bytes (type) + UNITS_PER_WORD - 1)
1363 / UNITS_PER_WORD);
1364 break;
1366 case SFmode:
1367 cum->arg_words ++;
1368 if (! cum->gp_reg_found && cum->arg_number <= 2)
1369 cum->fp_code += 1 << ((cum->arg_number - 1) * 2);
1370 break;
1372 case DFmode:
1373 cum->arg_words += 2;
1374 if (! cum->gp_reg_found && cum->arg_number <= 2)
1375 cum->fp_code += 2 << ((cum->arg_number - 1) * 2);
1376 break;
1378 case DImode:
1379 cum->gp_reg_found = 1;
1380 cum->arg_words += 2;
1381 break;
1383 case QImode:
1384 case HImode:
1385 case SImode:
1386 cum->gp_reg_found = 1;
1387 cum->arg_words ++;
1388 break;
1392 /* Return an RTL expression containing the register for the given mode MODE
1393 and type TYPE in CUM, or 0 if the argument is to be passed on the stack. */
1395 struct rtx_def *
1396 function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode, tree type,
1397 int named)
1399 rtx ret;
1400 int regbase = -1;
1401 int bias = 0;
1402 unsigned int *arg_words = &cum->arg_words;
1403 int struct_p = (type != 0
1404 && (TREE_CODE (type) == RECORD_TYPE
1405 || TREE_CODE (type) == UNION_TYPE
1406 || TREE_CODE (type) == QUAL_UNION_TYPE));
1408 if (TARGET_DEBUG_D_MODE)
1410 fprintf (stderr,
1411 "function_arg( {gp reg found = %d, arg # = %2d, words = %2d}, %4s, ",
1412 cum->gp_reg_found, cum->arg_number, cum->arg_words,
1413 GET_MODE_NAME (mode));
1414 fprintf (stderr, HOST_PTR_PRINTF, (const PTR) type);
1415 fprintf (stderr, ", %d ) = ", named);
1419 cum->last_arg_fp = 0;
1420 switch (mode)
1422 case SFmode:
1423 regbase = GP_ARG_FIRST;
1424 break;
1426 case DFmode:
1427 cum->arg_words += cum->arg_words & 1;
1429 regbase = GP_ARG_FIRST;
1430 break;
1432 default:
1433 if (GET_MODE_CLASS (mode) != MODE_COMPLEX_INT
1434 && GET_MODE_CLASS (mode) != MODE_COMPLEX_FLOAT)
1435 abort ();
1437 /* Drops through. */
1438 case BLKmode:
1439 if (type != NULL_TREE && TYPE_ALIGN (type) > (unsigned) BITS_PER_WORD)
1440 cum->arg_words += (cum->arg_words & 1);
1441 regbase = GP_ARG_FIRST;
1442 break;
1444 case VOIDmode:
1445 case QImode:
1446 case HImode:
1447 case SImode:
1448 regbase = GP_ARG_FIRST;
1449 break;
1451 case DImode:
1452 cum->arg_words += (cum->arg_words & 1);
1453 regbase = GP_ARG_FIRST;
1456 if (*arg_words >= (unsigned) MAX_ARGS_IN_REGISTERS)
1458 if (TARGET_DEBUG_D_MODE)
1459 fprintf (stderr, "<stack>%s\n", struct_p ? ", [struct]" : "");
1461 ret = 0;
1463 else
1465 if (regbase == -1)
1466 abort ();
1468 if (! type || TREE_CODE (type) != RECORD_TYPE
1469 || ! named || ! TYPE_SIZE_UNIT (type)
1470 || ! host_integerp (TYPE_SIZE_UNIT (type), 1))
1471 ret = gen_rtx_REG (mode, regbase + *arg_words + bias);
1472 else
1474 tree field;
1476 for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field))
1477 if (TREE_CODE (field) == FIELD_DECL
1478 && TREE_CODE (TREE_TYPE (field)) == REAL_TYPE
1479 && TYPE_PRECISION (TREE_TYPE (field)) == BITS_PER_WORD
1480 && host_integerp (bit_position (field), 0)
1481 && int_bit_position (field) % BITS_PER_WORD == 0)
1482 break;
1484 /* If the whole struct fits a DFmode register,
1485 we don't need the PARALLEL. */
1486 if (! field || mode == DFmode)
1487 ret = gen_rtx_REG (mode, regbase + *arg_words + bias);
1488 else
1490 unsigned int chunks;
1491 HOST_WIDE_INT bitpos;
1492 unsigned int regno;
1493 unsigned int i;
1495 /* ??? If this is a packed structure, then the last hunk won't
1496 be 64 bits. */
1497 chunks
1498 = tree_low_cst (TYPE_SIZE_UNIT (type), 1) / UNITS_PER_WORD;
1499 if (chunks + *arg_words + bias > (unsigned) MAX_ARGS_IN_REGISTERS)
1500 chunks = MAX_ARGS_IN_REGISTERS - *arg_words - bias;
1502 /* Assign_parms checks the mode of ENTRY_PARM, so we must
1503 use the actual mode here. */
1504 ret = gen_rtx_PARALLEL (mode, rtvec_alloc (chunks));
1506 bitpos = 0;
1507 regno = regbase + *arg_words + bias;
1508 field = TYPE_FIELDS (type);
1509 for (i = 0; i < chunks; i++)
1511 rtx reg;
1513 for (; field; field = TREE_CHAIN (field))
1514 if (TREE_CODE (field) == FIELD_DECL
1515 && int_bit_position (field) >= bitpos)
1516 break;
1518 if (field
1519 && int_bit_position (field) == bitpos
1520 && TREE_CODE (TREE_TYPE (field)) == REAL_TYPE
1521 && TYPE_PRECISION (TREE_TYPE (field)) == BITS_PER_WORD)
1522 reg = gen_rtx_REG (DFmode, regno++);
1523 else
1524 reg = gen_rtx_REG (word_mode, regno);
1526 XVECEXP (ret, 0, i)
1527 = gen_rtx_EXPR_LIST (VOIDmode, reg,
1528 GEN_INT (bitpos / BITS_PER_UNIT));
1530 bitpos += 64;
1531 regno++;
1536 if (TARGET_DEBUG_D_MODE)
1537 fprintf (stderr, "%s%s\n", reg_names[regbase + *arg_words + bias],
1538 struct_p ? ", [struct]" : "");
1541 /* We will be called with a mode of VOIDmode after the last argument
1542 has been seen. Whatever we return will be passed to the call
1543 insn. If we need any shifts for small structures, return them in
1544 a PARALLEL. */
1545 if (mode == VOIDmode)
1547 if (cum->num_adjusts > 0)
1548 ret = gen_rtx_PARALLEL ((enum machine_mode) cum->fp_code,
1549 gen_rtvec_v (cum->num_adjusts, cum->adjust));
1552 return ret;
1556 function_arg_partial_nregs (CUMULATIVE_ARGS *cum, enum machine_mode mode,
1557 tree type ATTRIBUTE_UNUSED,
1558 int named ATTRIBUTE_UNUSED)
1560 if (mode == DImode
1561 && cum->arg_words == MAX_ARGS_IN_REGISTERS - (unsigned)1)
1563 if (TARGET_DEBUG_D_MODE)
1564 fprintf (stderr, "function_arg_partial_nregs = 1\n");
1566 return 1;
1569 return 0;
1572 /* Implement va_start. */
1574 void
1575 iq2000_va_start (tree valist, rtx nextarg)
1577 int int_arg_words;
1578 /* Find out how many non-float named formals. */
1579 int gpr_save_area_size;
1580 /* Note UNITS_PER_WORD is 4 bytes. */
1581 int_arg_words = current_function_args_info.arg_words;
1583 if (int_arg_words < 8 )
1584 /* Adjust for the prologue's economy measure. */
1585 gpr_save_area_size = (8 - int_arg_words) * UNITS_PER_WORD;
1586 else
1587 gpr_save_area_size = 0;
1589 /* Everything is in the GPR save area, or in the overflow
1590 area which is contiguous with it. */
1591 nextarg = plus_constant (nextarg, - gpr_save_area_size);
1592 std_expand_builtin_va_start (valist, nextarg);
1595 /* Allocate a chunk of memory for per-function machine-dependent data. */
1597 static struct machine_function *
1598 iq2000_init_machine_status (void)
1600 struct machine_function *f;
1602 f = ggc_alloc_cleared (sizeof (struct machine_function));
1604 return f;
1607 static enum processor_type
1608 iq2000_parse_cpu (const char * cpu_string)
1610 const char *p = cpu_string;
1611 enum processor_type cpu;
1613 cpu = PROCESSOR_DEFAULT;
1614 switch (p[2])
1616 case '1':
1617 if (!strcmp (p, "iq10"))
1618 cpu = PROCESSOR_IQ10;
1619 break;
1620 case '2':
1621 if (!strcmp (p, "iq2000"))
1622 cpu = PROCESSOR_IQ2000;
1623 break;
1626 return cpu;
1629 /* Detect any conflicts in the switches. */
1631 void
1632 override_options (void)
1634 enum processor_type iq2000_cpu;
1636 target_flags &= ~MASK_GPOPT;
1638 iq2000_isa = IQ2000_ISA_DEFAULT;
1640 /* Identify the processor type. */
1642 if (iq2000_cpu_string != 0)
1644 iq2000_cpu = iq2000_parse_cpu (iq2000_cpu_string);
1645 if (iq2000_cpu == PROCESSOR_DEFAULT)
1647 error ("bad value (%s) for -mcpu= switch", iq2000_arch_string);
1648 iq2000_cpu_string = "default";
1650 iq2000_arch = iq2000_cpu;
1651 iq2000_tune = iq2000_cpu;
1654 if (iq2000_arch_string == 0
1655 || ! strcmp (iq2000_arch_string, "default")
1656 || ! strcmp (iq2000_arch_string, "DEFAULT"))
1658 switch (iq2000_isa)
1660 default:
1661 iq2000_arch_string = "iq2000";
1662 iq2000_arch = PROCESSOR_IQ2000;
1663 break;
1666 else
1668 iq2000_arch = iq2000_parse_cpu (iq2000_arch_string);
1669 if (iq2000_arch == PROCESSOR_DEFAULT)
1671 error ("bad value (%s) for -march= switch", iq2000_arch_string);
1672 iq2000_arch_string = "default";
1674 if (iq2000_arch == PROCESSOR_IQ10)
1676 error ("The compiler does not support -march=%s.", iq2000_arch_string);
1677 iq2000_arch_string = "default";
1681 iq2000_print_operand_punct['?'] = 1;
1682 iq2000_print_operand_punct['#'] = 1;
1683 iq2000_print_operand_punct['&'] = 1;
1684 iq2000_print_operand_punct['!'] = 1;
1685 iq2000_print_operand_punct['*'] = 1;
1686 iq2000_print_operand_punct['@'] = 1;
1687 iq2000_print_operand_punct['.'] = 1;
1688 iq2000_print_operand_punct['('] = 1;
1689 iq2000_print_operand_punct[')'] = 1;
1690 iq2000_print_operand_punct['['] = 1;
1691 iq2000_print_operand_punct[']'] = 1;
1692 iq2000_print_operand_punct['<'] = 1;
1693 iq2000_print_operand_punct['>'] = 1;
1694 iq2000_print_operand_punct['{'] = 1;
1695 iq2000_print_operand_punct['}'] = 1;
1696 iq2000_print_operand_punct['^'] = 1;
1697 iq2000_print_operand_punct['$'] = 1;
1698 iq2000_print_operand_punct['+'] = 1;
1699 iq2000_print_operand_punct['~'] = 1;
1701 /* Save GPR registers in word_mode sized hunks. word_mode hasn't been
1702 initialized yet, so we can't use that here. */
1703 gpr_mode = SImode;
1705 /* Function to allocate machine-dependent function status. */
1706 init_machine_status = iq2000_init_machine_status;
1709 /* The arg pointer (which is eliminated) points to the virtual frame pointer,
1710 while the frame pointer (which may be eliminated) points to the stack
1711 pointer after the initial adjustments. */
1713 HOST_WIDE_INT
1714 iq2000_debugger_offset (rtx addr, HOST_WIDE_INT offset)
1716 rtx offset2 = const0_rtx;
1717 rtx reg = eliminate_constant_term (addr, & offset2);
1719 if (offset == 0)
1720 offset = INTVAL (offset2);
1722 if (reg == stack_pointer_rtx || reg == frame_pointer_rtx
1723 || reg == hard_frame_pointer_rtx)
1725 HOST_WIDE_INT frame_size = (!cfun->machine->initialized)
1726 ? compute_frame_size (get_frame_size ())
1727 : cfun->machine->total_size;
1729 offset = offset - frame_size;
1732 return offset;
1735 /* If defined, a C statement to be executed just prior to the output of
1736 assembler code for INSN, to modify the extracted operands so they will be
1737 output differently.
1739 Here the argument OPVEC is the vector containing the operands extracted
1740 from INSN, and NOPERANDS is the number of elements of the vector which
1741 contain meaningful data for this insn. The contents of this vector are
1742 what will be used to convert the insn template into assembler code, so you
1743 can change the assembler output by changing the contents of the vector.
1745 We use it to check if the current insn needs a nop in front of it because
1746 of load delays, and also to update the delay slot statistics. */
1748 void
1749 final_prescan_insn (rtx insn, rtx opvec[] ATTRIBUTE_UNUSED,
1750 int noperands ATTRIBUTE_UNUSED)
1752 if (dslots_number_nops > 0)
1754 rtx pattern = PATTERN (insn);
1755 int length = get_attr_length (insn);
1757 /* Do we need to emit a NOP? */
1758 if (length == 0
1759 || (iq2000_load_reg != 0 && reg_mentioned_p (iq2000_load_reg, pattern))
1760 || (iq2000_load_reg2 != 0 && reg_mentioned_p (iq2000_load_reg2, pattern))
1761 || (iq2000_load_reg3 != 0 && reg_mentioned_p (iq2000_load_reg3, pattern))
1762 || (iq2000_load_reg4 != 0
1763 && reg_mentioned_p (iq2000_load_reg4, pattern)))
1764 fputs ("\tnop\n", asm_out_file);
1766 else
1767 dslots_load_filled ++;
1769 while (--dslots_number_nops > 0)
1770 fputs ("\tnop\n", asm_out_file);
1772 iq2000_load_reg = 0;
1773 iq2000_load_reg2 = 0;
1774 iq2000_load_reg3 = 0;
1775 iq2000_load_reg4 = 0;
1778 if ( (GET_CODE (insn) == JUMP_INSN
1779 || GET_CODE (insn) == CALL_INSN
1780 || (GET_CODE (PATTERN (insn)) == RETURN))
1781 && NEXT_INSN (PREV_INSN (insn)) == insn)
1783 rtx nop_insn = emit_insn_after (gen_nop (), insn);
1785 INSN_ADDRESSES_NEW (nop_insn, -1);
1788 if (TARGET_STATS
1789 && (GET_CODE (insn) == JUMP_INSN || GET_CODE (insn) == CALL_INSN))
1790 dslots_jump_total ++;
1793 /* Return the bytes needed to compute the frame pointer from the current
1794 stack pointer where SIZE is the # of var. bytes allocated.
1796 IQ2000 stack frames look like:
1798 Before call After call
1799 +-----------------------+ +-----------------------+
1800 high | | | |
1801 mem. | | | |
1802 | caller's temps. | | caller's temps. |
1803 | | | |
1804 +-----------------------+ +-----------------------+
1805 | | | |
1806 | arguments on stack. | | arguments on stack. |
1807 | | | |
1808 +-----------------------+ +-----------------------+
1809 | 4 words to save | | 4 words to save |
1810 | arguments passed | | arguments passed |
1811 | in registers, even | | in registers, even |
1812 SP->| if not passed. | VFP->| if not passed. |
1813 +-----------------------+ +-----------------------+
1815 | fp register save |
1817 +-----------------------+
1819 | gp register save |
1821 +-----------------------+
1823 | local variables |
1825 +-----------------------+
1827 | alloca allocations |
1829 +-----------------------+
1831 | GP save for V.4 abi |
1833 +-----------------------+
1835 | arguments on stack |
1837 +-----------------------+
1838 | 4 words to save |
1839 | arguments passed |
1840 | in registers, even |
1841 low SP->| if not passed. |
1842 memory +-----------------------+ */
1844 HOST_WIDE_INT
1845 compute_frame_size (HOST_WIDE_INT size)
1847 int regno;
1848 HOST_WIDE_INT total_size; /* # bytes that the entire frame takes up. */
1849 HOST_WIDE_INT var_size; /* # bytes that variables take up. */
1850 HOST_WIDE_INT args_size; /* # bytes that outgoing arguments take up. */
1851 HOST_WIDE_INT extra_size; /* # extra bytes. */
1852 HOST_WIDE_INT gp_reg_rounded; /* # bytes needed to store gp after rounding. */
1853 HOST_WIDE_INT gp_reg_size; /* # bytes needed to store gp regs. */
1854 HOST_WIDE_INT fp_reg_size; /* # bytes needed to store fp regs. */
1855 long mask; /* mask of saved gp registers. */
1856 int fp_inc; /* 1 or 2 depending on the size of fp regs. */
1857 long fp_bits; /* bitmask to use for each fp register. */
1859 gp_reg_size = 0;
1860 fp_reg_size = 0;
1861 mask = 0;
1862 extra_size = IQ2000_STACK_ALIGN ((0));
1863 var_size = IQ2000_STACK_ALIGN (size);
1864 args_size = IQ2000_STACK_ALIGN (current_function_outgoing_args_size);
1866 /* If a function dynamically allocates the stack and
1867 has 0 for STACK_DYNAMIC_OFFSET then allocate some stack space. */
1868 if (args_size == 0 && current_function_calls_alloca)
1869 args_size = 4 * UNITS_PER_WORD;
1871 total_size = var_size + args_size + extra_size;
1873 /* Calculate space needed for gp registers. */
1874 for (regno = GP_REG_FIRST; regno <= GP_REG_LAST; regno++)
1876 if (MUST_SAVE_REGISTER (regno))
1878 gp_reg_size += GET_MODE_SIZE (gpr_mode);
1879 mask |= 1L << (regno - GP_REG_FIRST);
1883 /* We need to restore these for the handler. */
1884 if (current_function_calls_eh_return)
1886 unsigned int i;
1888 for (i = 0; ; ++i)
1890 regno = EH_RETURN_DATA_REGNO (i);
1891 if (regno == (int) INVALID_REGNUM)
1892 break;
1893 gp_reg_size += GET_MODE_SIZE (gpr_mode);
1894 mask |= 1L << (regno - GP_REG_FIRST);
1898 fp_inc = 2;
1899 fp_bits = 3;
1900 gp_reg_rounded = IQ2000_STACK_ALIGN (gp_reg_size);
1901 total_size += gp_reg_rounded + IQ2000_STACK_ALIGN (fp_reg_size);
1903 /* The gp reg is caller saved, so there is no need for leaf routines
1904 (total_size == extra_size) to save the gp reg. */
1905 if (total_size == extra_size
1906 && ! profile_flag)
1907 total_size = extra_size = 0;
1909 total_size += IQ2000_STACK_ALIGN (current_function_pretend_args_size);
1911 /* Save other computed information. */
1912 cfun->machine->total_size = total_size;
1913 cfun->machine->var_size = var_size;
1914 cfun->machine->args_size = args_size;
1915 cfun->machine->extra_size = extra_size;
1916 cfun->machine->gp_reg_size = gp_reg_size;
1917 cfun->machine->fp_reg_size = fp_reg_size;
1918 cfun->machine->mask = mask;
1919 cfun->machine->initialized = reload_completed;
1920 cfun->machine->num_gp = gp_reg_size / UNITS_PER_WORD;
1922 if (mask)
1924 unsigned long offset;
1926 offset = (args_size + extra_size + var_size
1927 + gp_reg_size - GET_MODE_SIZE (gpr_mode));
1929 cfun->machine->gp_sp_offset = offset;
1930 cfun->machine->gp_save_offset = offset - total_size;
1932 else
1934 cfun->machine->gp_sp_offset = 0;
1935 cfun->machine->gp_save_offset = 0;
1938 cfun->machine->fp_sp_offset = 0;
1939 cfun->machine->fp_save_offset = 0;
1941 /* Ok, we're done. */
1942 return total_size;
1945 /* Implement INITIAL_ELIMINATION_OFFSET. FROM is either the frame
1946 pointer, argument pointer, or return address pointer. TO is either
1947 the stack pointer or hard frame pointer. */
1950 iq2000_initial_elimination_offset (int from, int to ATTRIBUTE_UNUSED)
1952 int offset;
1954 compute_frame_size (get_frame_size ());
1955 if ((from) == FRAME_POINTER_REGNUM)
1956 (offset) = 0;
1957 else if ((from) == ARG_POINTER_REGNUM)
1958 (offset) = (cfun->machine->total_size);
1959 else if ((from) == RETURN_ADDRESS_POINTER_REGNUM)
1961 if (leaf_function_p ())
1962 (offset) = 0;
1963 else (offset) = cfun->machine->gp_sp_offset
1964 + ((UNITS_PER_WORD - (POINTER_SIZE / BITS_PER_UNIT))
1965 * (BYTES_BIG_ENDIAN != 0));
1968 return offset;
1971 /* Common code to emit the insns (or to write the instructions to a file)
1972 to save/restore registers.
1973 Other parts of the code assume that IQ2000_TEMP1_REGNUM (aka large_reg)
1974 is not modified within save_restore_insns. */
1976 #define BITSET_P(VALUE,BIT) (((VALUE) & (1L << (BIT))) != 0)
1978 /* Emit instructions to load the value (SP + OFFSET) into IQ2000_TEMP2_REGNUM
1979 and return an rtl expression for the register. Write the assembly
1980 instructions directly to FILE if it is not null, otherwise emit them as
1981 rtl.
1983 This function is a subroutine of save_restore_insns. It is used when
1984 OFFSET is too large to add in a single instruction. */
1986 static rtx
1987 iq2000_add_large_offset_to_sp (HOST_WIDE_INT offset)
1989 rtx reg = gen_rtx_REG (Pmode, IQ2000_TEMP2_REGNUM);
1990 rtx offset_rtx = GEN_INT (offset);
1992 emit_move_insn (reg, offset_rtx);
1993 emit_insn (gen_addsi3 (reg, reg, stack_pointer_rtx));
1994 return reg;
1997 /* Make INSN frame related and note that it performs the frame-related
1998 operation DWARF_PATTERN. */
2000 static void
2001 iq2000_annotate_frame_insn (rtx insn, rtx dwarf_pattern)
2003 RTX_FRAME_RELATED_P (insn) = 1;
2004 REG_NOTES (insn) = alloc_EXPR_LIST (REG_FRAME_RELATED_EXPR,
2005 dwarf_pattern,
2006 REG_NOTES (insn));
2009 /* Emit a move instruction that stores REG in MEM. Make the instruction
2010 frame related and note that it stores REG at (SP + OFFSET). */
2012 static void
2013 iq2000_emit_frame_related_store (rtx mem, rtx reg, HOST_WIDE_INT offset)
2015 rtx dwarf_address = plus_constant (stack_pointer_rtx, offset);
2016 rtx dwarf_mem = gen_rtx_MEM (GET_MODE (reg), dwarf_address);
2018 iq2000_annotate_frame_insn (emit_move_insn (mem, reg),
2019 gen_rtx_SET (GET_MODE (reg), dwarf_mem, reg));
2022 /* Emit instructions to save/restore registers, as determined by STORE_P. */
2024 static void
2025 save_restore_insns (int store_p)
2027 long mask = cfun->machine->mask;
2028 int regno;
2029 rtx base_reg_rtx;
2030 HOST_WIDE_INT base_offset;
2031 HOST_WIDE_INT gp_offset;
2032 HOST_WIDE_INT end_offset;
2034 if (frame_pointer_needed
2035 && ! BITSET_P (mask, HARD_FRAME_POINTER_REGNUM - GP_REG_FIRST))
2036 abort ();
2038 if (mask == 0)
2040 base_reg_rtx = 0, base_offset = 0;
2041 return;
2044 /* Save registers starting from high to low. The debuggers prefer at least
2045 the return register be stored at func+4, and also it allows us not to
2046 need a nop in the epilog if at least one register is reloaded in
2047 addition to return address. */
2049 /* Save GP registers if needed. */
2050 /* Pick which pointer to use as a base register. For small frames, just
2051 use the stack pointer. Otherwise, use a temporary register. Save 2
2052 cycles if the save area is near the end of a large frame, by reusing
2053 the constant created in the prologue/epilogue to adjust the stack
2054 frame. */
2056 gp_offset = cfun->machine->gp_sp_offset;
2057 end_offset
2058 = gp_offset - (cfun->machine->gp_reg_size
2059 - GET_MODE_SIZE (gpr_mode));
2061 if (gp_offset < 0 || end_offset < 0)
2062 internal_error
2063 ("gp_offset (%ld) or end_offset (%ld) is less than zero.",
2064 (long) gp_offset, (long) end_offset);
2066 else if (gp_offset < 32768)
2067 base_reg_rtx = stack_pointer_rtx, base_offset = 0;
2068 else
2070 int regno;
2071 int reg_save_count = 0;
2073 for (regno = GP_REG_LAST; regno >= GP_REG_FIRST; regno--)
2074 if (BITSET_P (mask, regno - GP_REG_FIRST)) reg_save_count += 1;
2075 base_offset = gp_offset - ((reg_save_count - 1) * 4);
2076 base_reg_rtx = iq2000_add_large_offset_to_sp (base_offset);
2079 for (regno = GP_REG_LAST; regno >= GP_REG_FIRST; regno--)
2081 if (BITSET_P (mask, regno - GP_REG_FIRST))
2083 rtx reg_rtx;
2084 rtx mem_rtx
2085 = gen_rtx_MEM (gpr_mode,
2086 gen_rtx_PLUS (Pmode, base_reg_rtx,
2087 GEN_INT (gp_offset - base_offset)));
2089 if (! current_function_calls_eh_return)
2090 RTX_UNCHANGING_P (mem_rtx) = 1;
2092 reg_rtx = gen_rtx_REG (gpr_mode, regno);
2094 if (store_p)
2095 iq2000_emit_frame_related_store (mem_rtx, reg_rtx, gp_offset);
2096 else
2098 emit_move_insn (reg_rtx, mem_rtx);
2100 gp_offset -= GET_MODE_SIZE (gpr_mode);
2105 /* Expand the prologue into a bunch of separate insns. */
2107 void
2108 iq2000_expand_prologue (void)
2110 int regno;
2111 HOST_WIDE_INT tsize;
2112 int last_arg_is_vararg_marker = 0;
2113 tree fndecl = current_function_decl;
2114 tree fntype = TREE_TYPE (fndecl);
2115 tree fnargs = DECL_ARGUMENTS (fndecl);
2116 rtx next_arg_reg;
2117 int i;
2118 tree next_arg;
2119 tree cur_arg;
2120 CUMULATIVE_ARGS args_so_far;
2121 int store_args_on_stack = (iq2000_can_use_return_insn ());
2123 /* If struct value address is treated as the first argument. */
2124 if (aggregate_value_p (DECL_RESULT (fndecl), fndecl)
2125 && ! current_function_returns_pcc_struct
2126 && targetm.calls.struct_value_rtx (TREE_TYPE (fndecl), 1) == 0)
2128 tree type = build_pointer_type (fntype);
2129 tree function_result_decl = build_decl (PARM_DECL, NULL_TREE, type);
2131 DECL_ARG_TYPE (function_result_decl) = type;
2132 TREE_CHAIN (function_result_decl) = fnargs;
2133 fnargs = function_result_decl;
2136 /* For arguments passed in registers, find the register number
2137 of the first argument in the variable part of the argument list,
2138 otherwise GP_ARG_LAST+1. Note also if the last argument is
2139 the varargs special argument, and treat it as part of the
2140 variable arguments.
2142 This is only needed if store_args_on_stack is true. */
2143 INIT_CUMULATIVE_ARGS (args_so_far, fntype, NULL_RTX, 0, 0);
2144 regno = GP_ARG_FIRST;
2146 for (cur_arg = fnargs; cur_arg != 0; cur_arg = next_arg)
2148 tree passed_type = DECL_ARG_TYPE (cur_arg);
2149 enum machine_mode passed_mode = TYPE_MODE (passed_type);
2150 rtx entry_parm;
2152 if (TREE_ADDRESSABLE (passed_type))
2154 passed_type = build_pointer_type (passed_type);
2155 passed_mode = Pmode;
2158 entry_parm = FUNCTION_ARG (args_so_far, passed_mode, passed_type, 1);
2160 FUNCTION_ARG_ADVANCE (args_so_far, passed_mode, passed_type, 1);
2161 next_arg = TREE_CHAIN (cur_arg);
2163 if (entry_parm && store_args_on_stack)
2165 if (next_arg == 0
2166 && DECL_NAME (cur_arg)
2167 && ((0 == strcmp (IDENTIFIER_POINTER (DECL_NAME (cur_arg)),
2168 "__builtin_va_alist"))
2169 || (0 == strcmp (IDENTIFIER_POINTER (DECL_NAME (cur_arg)),
2170 "va_alist"))))
2172 last_arg_is_vararg_marker = 1;
2173 break;
2175 else
2177 int words;
2179 if (GET_CODE (entry_parm) != REG)
2180 abort ();
2182 /* Passed in a register, so will get homed automatically. */
2183 if (GET_MODE (entry_parm) == BLKmode)
2184 words = (int_size_in_bytes (passed_type) + 3) / 4;
2185 else
2186 words = (GET_MODE_SIZE (GET_MODE (entry_parm)) + 3) / 4;
2188 regno = REGNO (entry_parm) + words - 1;
2191 else
2193 regno = GP_ARG_LAST+1;
2194 break;
2198 /* In order to pass small structures by value in registers we need to
2199 shift the value into the high part of the register.
2200 Function_arg has encoded a PARALLEL rtx, holding a vector of
2201 adjustments to be made as the next_arg_reg variable, so we split up the
2202 insns, and emit them separately. */
2203 next_arg_reg = FUNCTION_ARG (args_so_far, VOIDmode, void_type_node, 1);
2204 if (next_arg_reg != 0 && GET_CODE (next_arg_reg) == PARALLEL)
2206 rtvec adjust = XVEC (next_arg_reg, 0);
2207 int num = GET_NUM_ELEM (adjust);
2209 for (i = 0; i < num; i++)
2211 rtx insn, pattern;
2213 pattern = RTVEC_ELT (adjust, i);
2214 if (GET_CODE (pattern) != SET
2215 || GET_CODE (SET_SRC (pattern)) != ASHIFT)
2216 abort_with_insn (pattern, "Insn is not a shift");
2217 PUT_CODE (SET_SRC (pattern), ASHIFTRT);
2219 insn = emit_insn (pattern);
2221 /* Global life information isn't valid at this point, so we
2222 can't check whether these shifts are actually used. Mark
2223 them MAYBE_DEAD so that flow2 will remove them, and not
2224 complain about dead code in the prologue. */
2225 REG_NOTES(insn) = gen_rtx_EXPR_LIST (REG_MAYBE_DEAD, NULL_RTX,
2226 REG_NOTES (insn));
2230 tsize = compute_frame_size (get_frame_size ());
2232 /* If this function is a varargs function, store any registers that
2233 would normally hold arguments ($4 - $7) on the stack. */
2234 if (store_args_on_stack
2235 && ((TYPE_ARG_TYPES (fntype) != 0
2236 && (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
2237 != void_type_node))
2238 || last_arg_is_vararg_marker))
2240 int offset = (regno - GP_ARG_FIRST) * UNITS_PER_WORD;
2241 rtx ptr = stack_pointer_rtx;
2243 for (; regno <= GP_ARG_LAST; regno++)
2245 if (offset != 0)
2246 ptr = gen_rtx_PLUS (Pmode, stack_pointer_rtx, GEN_INT (offset));
2247 emit_move_insn (gen_rtx_MEM (gpr_mode, ptr),
2248 gen_rtx_REG (gpr_mode, regno));
2250 offset += GET_MODE_SIZE (gpr_mode);
2254 if (tsize > 0)
2256 rtx tsize_rtx = GEN_INT (tsize);
2257 rtx adjustment_rtx, insn, dwarf_pattern;
2259 if (tsize > 32767)
2261 adjustment_rtx = gen_rtx_REG (Pmode, IQ2000_TEMP1_REGNUM);
2262 emit_move_insn (adjustment_rtx, tsize_rtx);
2264 else
2265 adjustment_rtx = tsize_rtx;
2267 insn = emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
2268 adjustment_rtx));
2270 dwarf_pattern = gen_rtx_SET (Pmode, stack_pointer_rtx,
2271 plus_constant (stack_pointer_rtx, -tsize));
2273 iq2000_annotate_frame_insn (insn, dwarf_pattern);
2275 save_restore_insns (1);
2277 if (frame_pointer_needed)
2279 rtx insn = 0;
2281 insn = emit_insn (gen_movsi (hard_frame_pointer_rtx,
2282 stack_pointer_rtx));
2284 if (insn)
2285 RTX_FRAME_RELATED_P (insn) = 1;
2289 emit_insn (gen_blockage ());
2292 /* Expand the epilogue into a bunch of separate insns. */
2294 void
2295 iq2000_expand_epilogue (void)
2297 HOST_WIDE_INT tsize = cfun->machine->total_size;
2298 rtx tsize_rtx = GEN_INT (tsize);
2299 rtx tmp_rtx = (rtx)0;
2301 if (iq2000_can_use_return_insn ())
2303 emit_insn (gen_return ());
2304 return;
2307 if (tsize > 32767)
2309 tmp_rtx = gen_rtx_REG (Pmode, IQ2000_TEMP1_REGNUM);
2310 emit_move_insn (tmp_rtx, tsize_rtx);
2311 tsize_rtx = tmp_rtx;
2314 if (tsize > 0)
2316 if (frame_pointer_needed)
2318 emit_insn (gen_blockage ());
2320 emit_insn (gen_movsi (stack_pointer_rtx, hard_frame_pointer_rtx));
2323 save_restore_insns (0);
2325 if (current_function_calls_eh_return)
2327 rtx eh_ofs = EH_RETURN_STACKADJ_RTX;
2328 emit_insn (gen_addsi3 (eh_ofs, eh_ofs, tsize_rtx));
2329 tsize_rtx = eh_ofs;
2332 emit_insn (gen_blockage ());
2334 if (tsize != 0 || current_function_calls_eh_return)
2336 emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx,
2337 tsize_rtx));
2341 if (current_function_calls_eh_return)
2343 /* Perform the additional bump for __throw. */
2344 emit_move_insn (gen_rtx_REG (Pmode, HARD_FRAME_POINTER_REGNUM),
2345 stack_pointer_rtx);
2346 emit_insn (gen_rtx_USE (VOIDmode, gen_rtx_REG (Pmode,
2347 HARD_FRAME_POINTER_REGNUM)));
2348 emit_jump_insn (gen_eh_return_internal ());
2350 else
2351 emit_jump_insn (gen_return_internal (gen_rtx_REG (Pmode,
2352 GP_REG_FIRST + 31)));
2355 void
2356 iq2000_expand_eh_return (rtx address)
2358 HOST_WIDE_INT gp_offset = cfun->machine->gp_sp_offset;
2359 rtx scratch;
2361 scratch = plus_constant (stack_pointer_rtx, gp_offset);
2362 emit_move_insn (gen_rtx_MEM (GET_MODE (address), scratch), address);
2365 /* Return nonzero if this function is known to have a null epilogue.
2366 This allows the optimizer to omit jumps to jumps if no stack
2367 was created. */
2370 iq2000_can_use_return_insn (void)
2372 if (! reload_completed)
2373 return 0;
2375 if (regs_ever_live[31] || profile_flag)
2376 return 0;
2378 if (cfun->machine->initialized)
2379 return cfun->machine->total_size == 0;
2381 return compute_frame_size (get_frame_size ()) == 0;
2384 /* Returns nonzero if X contains a SYMBOL_REF. */
2386 static int
2387 symbolic_expression_p (rtx x)
2389 if (GET_CODE (x) == SYMBOL_REF)
2390 return 1;
2392 if (GET_CODE (x) == CONST)
2393 return symbolic_expression_p (XEXP (x, 0));
2395 if (UNARY_P (x))
2396 return symbolic_expression_p (XEXP (x, 0));
2398 if (ARITHMETIC_P (x))
2399 return (symbolic_expression_p (XEXP (x, 0))
2400 || symbolic_expression_p (XEXP (x, 1)));
2402 return 0;
2405 /* Choose the section to use for the constant rtx expression X that has
2406 mode MODE. */
2408 static void
2409 iq2000_select_rtx_section (enum machine_mode mode, rtx x ATTRIBUTE_UNUSED,
2410 unsigned HOST_WIDE_INT align)
2412 /* For embedded applications, always put constants in read-only data,
2413 in order to reduce RAM usage. */
2414 /* For embedded applications, always put constants in read-only data,
2415 in order to reduce RAM usage. */
2416 mergeable_constant_section (mode, align, 0);
2419 /* Choose the section to use for DECL. RELOC is true if its value contains
2420 any relocatable expression.
2422 Some of the logic used here needs to be replicated in
2423 ENCODE_SECTION_INFO in iq2000.h so that references to these symbols
2424 are done correctly. */
2426 static void
2427 iq2000_select_section (tree decl, int reloc ATTRIBUTE_UNUSED,
2428 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED)
2430 if (TARGET_EMBEDDED_DATA)
2432 /* For embedded applications, always put an object in read-only data
2433 if possible, in order to reduce RAM usage. */
2434 if ((TREE_CODE (decl) == VAR_DECL
2435 && TREE_READONLY (decl) && !TREE_SIDE_EFFECTS (decl)
2436 && DECL_INITIAL (decl)
2437 && (DECL_INITIAL (decl) == error_mark_node
2438 || TREE_CONSTANT (DECL_INITIAL (decl))))
2439 /* Deal with calls from output_constant_def_contents. */
2440 || TREE_CODE (decl) != VAR_DECL)
2441 readonly_data_section ();
2442 else
2443 data_section ();
2445 else
2447 /* For hosted applications, always put an object in small data if
2448 possible, as this gives the best performance. */
2449 if ((TREE_CODE (decl) == VAR_DECL
2450 && TREE_READONLY (decl) && !TREE_SIDE_EFFECTS (decl)
2451 && DECL_INITIAL (decl)
2452 && (DECL_INITIAL (decl) == error_mark_node
2453 || TREE_CONSTANT (DECL_INITIAL (decl))))
2454 /* Deal with calls from output_constant_def_contents. */
2455 || TREE_CODE (decl) != VAR_DECL)
2456 readonly_data_section ();
2457 else
2458 data_section ();
2461 /* Return register to use for a function return value with VALTYPE for function
2462 FUNC. */
2465 iq2000_function_value (tree valtype, tree func ATTRIBUTE_UNUSED)
2467 int reg = GP_RETURN;
2468 enum machine_mode mode = TYPE_MODE (valtype);
2469 int unsignedp = TYPE_UNSIGNED (valtype);
2471 /* Since we define TARGET_PROMOTE_FUNCTION_RETURN that returns true,
2472 we must promote the mode just as PROMOTE_MODE does. */
2473 mode = promote_mode (valtype, mode, &unsignedp, 1);
2475 return gen_rtx_REG (mode, reg);
2478 /* Return true when an argument must be passed by reference. */
2480 static bool
2481 iq2000_pass_by_reference (CUMULATIVE_ARGS *cum, enum machine_mode mode,
2482 tree type, bool named ATTRIBUTE_UNUSED)
2484 int size;
2486 /* We must pass by reference if we would be both passing in registers
2487 and the stack. This is because any subsequent partial arg would be
2488 handled incorrectly in this case. */
2489 if (cum && targetm.calls.must_pass_in_stack (mode, type))
2491 /* Don't pass the actual CUM to FUNCTION_ARG, because we would
2492 get double copies of any offsets generated for small structs
2493 passed in registers. */
2494 CUMULATIVE_ARGS temp;
2496 temp = *cum;
2497 if (FUNCTION_ARG (temp, mode, type, named) != 0)
2498 return 1;
2501 if (type == NULL_TREE || mode == DImode || mode == DFmode)
2502 return 0;
2504 size = int_size_in_bytes (type);
2505 return size == -1 || size > UNITS_PER_WORD;
2508 /* Return the length of INSN. LENGTH is the initial length computed by
2509 attributes in the machine-description file. */
2512 iq2000_adjust_insn_length (rtx insn, int length)
2514 /* A unconditional jump has an unfilled delay slot if it is not part
2515 of a sequence. A conditional jump normally has a delay slot. */
2516 if (simplejump_p (insn)
2517 || ( (GET_CODE (insn) == JUMP_INSN
2518 || GET_CODE (insn) == CALL_INSN)))
2519 length += 4;
2521 return length;
2524 /* Output assembly instructions to perform a conditional branch.
2526 INSN is the branch instruction. OPERANDS[0] is the condition.
2527 OPERANDS[1] is the target of the branch. OPERANDS[2] is the target
2528 of the first operand to the condition. If TWO_OPERANDS_P is
2529 nonzero the comparison takes two operands; OPERANDS[3] will be the
2530 second operand.
2532 If INVERTED_P is nonzero we are to branch if the condition does
2533 not hold. If FLOAT_P is nonzero this is a floating-point comparison.
2535 LENGTH is the length (in bytes) of the sequence we are to generate.
2536 That tells us whether to generate a simple conditional branch, or a
2537 reversed conditional branch around a `jr' instruction. */
2539 char *
2540 iq2000_output_conditional_branch (rtx insn, rtx * operands, int two_operands_p,
2541 int float_p, int inverted_p, int length)
2543 static char buffer[200];
2544 /* The kind of comparison we are doing. */
2545 enum rtx_code code = GET_CODE (operands[0]);
2546 /* Nonzero if the opcode for the comparison needs a `z' indicating
2547 that it is a comparison against zero. */
2548 int need_z_p;
2549 /* A string to use in the assembly output to represent the first
2550 operand. */
2551 const char *op1 = "%z2";
2552 /* A string to use in the assembly output to represent the second
2553 operand. Use the hard-wired zero register if there's no second
2554 operand. */
2555 const char *op2 = (two_operands_p ? ",%z3" : ",%.");
2556 /* The operand-printing string for the comparison. */
2557 const char *comp = (float_p ? "%F0" : "%C0");
2558 /* The operand-printing string for the inverted comparison. */
2559 const char *inverted_comp = (float_p ? "%W0" : "%N0");
2561 /* Likely variants of each branch instruction annul the instruction
2562 in the delay slot if the branch is not taken. */
2563 iq2000_branch_likely = (final_sequence && INSN_ANNULLED_BRANCH_P (insn));
2565 if (!two_operands_p)
2567 /* To compute whether than A > B, for example, we normally
2568 subtract B from A and then look at the sign bit. But, if we
2569 are doing an unsigned comparison, and B is zero, we don't
2570 have to do the subtraction. Instead, we can just check to
2571 see if A is nonzero. Thus, we change the CODE here to
2572 reflect the simpler comparison operation. */
2573 switch (code)
2575 case GTU:
2576 code = NE;
2577 break;
2579 case LEU:
2580 code = EQ;
2581 break;
2583 case GEU:
2584 /* A condition which will always be true. */
2585 code = EQ;
2586 op1 = "%.";
2587 break;
2589 case LTU:
2590 /* A condition which will always be false. */
2591 code = NE;
2592 op1 = "%.";
2593 break;
2595 default:
2596 /* Not a special case. */
2597 break;
2601 /* Relative comparisons are always done against zero. But
2602 equality comparisons are done between two operands, and therefore
2603 do not require a `z' in the assembly language output. */
2604 need_z_p = (!float_p && code != EQ && code != NE);
2605 /* For comparisons against zero, the zero is not provided
2606 explicitly. */
2607 if (need_z_p)
2608 op2 = "";
2610 /* Begin by terminating the buffer. That way we can always use
2611 strcat to add to it. */
2612 buffer[0] = '\0';
2614 switch (length)
2616 case 4:
2617 case 8:
2618 /* Just a simple conditional branch. */
2619 if (float_p)
2620 sprintf (buffer, "b%s%%?\t%%Z2%%1",
2621 inverted_p ? inverted_comp : comp);
2622 else
2623 sprintf (buffer, "b%s%s%%?\t%s%s,%%1",
2624 inverted_p ? inverted_comp : comp,
2625 need_z_p ? "z" : "",
2626 op1,
2627 op2);
2628 return buffer;
2630 case 12:
2631 case 16:
2633 /* Generate a reversed conditional branch around ` j'
2634 instruction:
2636 .set noreorder
2637 .set nomacro
2638 bc l
2640 j target
2641 .set macro
2642 .set reorder
2645 Because we have to jump four bytes *past* the following
2646 instruction if this branch was annulled, we can't just use
2647 a label, as in the picture above; there's no way to put the
2648 label after the next instruction, as the assembler does not
2649 accept `.L+4' as the target of a branch. (We can't just
2650 wait until the next instruction is output; it might be a
2651 macro and take up more than four bytes. Once again, we see
2652 why we want to eliminate macros.)
2654 If the branch is annulled, we jump four more bytes that we
2655 would otherwise; that way we skip the annulled instruction
2656 in the delay slot. */
2658 const char *target
2659 = ((iq2000_branch_likely || length == 16) ? ".+16" : ".+12");
2660 char *c;
2662 c = strchr (buffer, '\0');
2663 /* Generate the reversed comparison. This takes four
2664 bytes. */
2665 if (float_p)
2666 sprintf (c, "b%s\t%%Z2%s",
2667 inverted_p ? comp : inverted_comp,
2668 target);
2669 else
2670 sprintf (c, "b%s%s\t%s%s,%s",
2671 inverted_p ? comp : inverted_comp,
2672 need_z_p ? "z" : "",
2673 op1,
2674 op2,
2675 target);
2676 strcat (c, "\n\tnop\n\tj\t%1");
2677 if (length == 16)
2678 /* The delay slot was unfilled. Since we're inside
2679 .noreorder, the assembler will not fill in the NOP for
2680 us, so we must do it ourselves. */
2681 strcat (buffer, "\n\tnop");
2682 return buffer;
2685 default:
2686 abort ();
2689 /* NOTREACHED */
2690 return 0;
2693 #define def_builtin(NAME, TYPE, CODE) \
2694 builtin_function ((NAME), (TYPE), (CODE), BUILT_IN_MD, NULL, NULL_TREE)
2696 static void
2697 iq2000_init_builtins (void)
2699 tree endlink = void_list_node;
2700 tree void_ftype, void_ftype_int, void_ftype_int_int;
2701 tree void_ftype_int_int_int;
2702 tree int_ftype_int, int_ftype_int_int, int_ftype_int_int_int;
2703 tree int_ftype_int_int_int_int;
2705 /* func () */
2706 void_ftype
2707 = build_function_type (void_type_node,
2708 tree_cons (NULL_TREE, void_type_node, endlink));
2710 /* func (int) */
2711 void_ftype_int
2712 = build_function_type (void_type_node,
2713 tree_cons (NULL_TREE, integer_type_node, endlink));
2715 /* void func (int, int) */
2716 void_ftype_int_int
2717 = build_function_type (void_type_node,
2718 tree_cons (NULL_TREE, integer_type_node,
2719 tree_cons (NULL_TREE, integer_type_node,
2720 endlink)));
2722 /* int func (int) */
2723 int_ftype_int
2724 = build_function_type (integer_type_node,
2725 tree_cons (NULL_TREE, integer_type_node, endlink));
2727 /* int func (int, int) */
2728 int_ftype_int_int
2729 = build_function_type (integer_type_node,
2730 tree_cons (NULL_TREE, integer_type_node,
2731 tree_cons (NULL_TREE, integer_type_node,
2732 endlink)));
2734 /* void func (int, int, int) */
2735 void_ftype_int_int_int
2736 = build_function_type
2737 (void_type_node,
2738 tree_cons (NULL_TREE, integer_type_node,
2739 tree_cons (NULL_TREE, integer_type_node,
2740 tree_cons (NULL_TREE,
2741 integer_type_node,
2742 endlink))));
2744 /* int func (int, int, int, int) */
2745 int_ftype_int_int_int_int
2746 = build_function_type
2747 (integer_type_node,
2748 tree_cons (NULL_TREE, integer_type_node,
2749 tree_cons (NULL_TREE, integer_type_node,
2750 tree_cons (NULL_TREE,
2751 integer_type_node,
2752 tree_cons (NULL_TREE,
2753 integer_type_node,
2754 endlink)))));
2756 /* int func (int, int, int) */
2757 int_ftype_int_int_int
2758 = build_function_type
2759 (integer_type_node,
2760 tree_cons (NULL_TREE, integer_type_node,
2761 tree_cons (NULL_TREE, integer_type_node,
2762 tree_cons (NULL_TREE,
2763 integer_type_node,
2764 endlink))));
2766 /* int func (int, int, int, int) */
2767 int_ftype_int_int_int_int
2768 = build_function_type
2769 (integer_type_node,
2770 tree_cons (NULL_TREE, integer_type_node,
2771 tree_cons (NULL_TREE, integer_type_node,
2772 tree_cons (NULL_TREE,
2773 integer_type_node,
2774 tree_cons (NULL_TREE,
2775 integer_type_node,
2776 endlink)))));
2778 def_builtin ("__builtin_ado16", int_ftype_int_int, IQ2000_BUILTIN_ADO16);
2779 def_builtin ("__builtin_ram", int_ftype_int_int_int_int, IQ2000_BUILTIN_RAM);
2780 def_builtin ("__builtin_chkhdr", void_ftype_int_int, IQ2000_BUILTIN_CHKHDR);
2781 def_builtin ("__builtin_pkrl", void_ftype_int_int, IQ2000_BUILTIN_PKRL);
2782 def_builtin ("__builtin_cfc0", int_ftype_int, IQ2000_BUILTIN_CFC0);
2783 def_builtin ("__builtin_cfc1", int_ftype_int, IQ2000_BUILTIN_CFC1);
2784 def_builtin ("__builtin_cfc2", int_ftype_int, IQ2000_BUILTIN_CFC2);
2785 def_builtin ("__builtin_cfc3", int_ftype_int, IQ2000_BUILTIN_CFC3);
2786 def_builtin ("__builtin_ctc0", void_ftype_int_int, IQ2000_BUILTIN_CTC0);
2787 def_builtin ("__builtin_ctc1", void_ftype_int_int, IQ2000_BUILTIN_CTC1);
2788 def_builtin ("__builtin_ctc2", void_ftype_int_int, IQ2000_BUILTIN_CTC2);
2789 def_builtin ("__builtin_ctc3", void_ftype_int_int, IQ2000_BUILTIN_CTC3);
2790 def_builtin ("__builtin_mfc0", int_ftype_int, IQ2000_BUILTIN_MFC0);
2791 def_builtin ("__builtin_mfc1", int_ftype_int, IQ2000_BUILTIN_MFC1);
2792 def_builtin ("__builtin_mfc2", int_ftype_int, IQ2000_BUILTIN_MFC2);
2793 def_builtin ("__builtin_mfc3", int_ftype_int, IQ2000_BUILTIN_MFC3);
2794 def_builtin ("__builtin_mtc0", void_ftype_int_int, IQ2000_BUILTIN_MTC0);
2795 def_builtin ("__builtin_mtc1", void_ftype_int_int, IQ2000_BUILTIN_MTC1);
2796 def_builtin ("__builtin_mtc2", void_ftype_int_int, IQ2000_BUILTIN_MTC2);
2797 def_builtin ("__builtin_mtc3", void_ftype_int_int, IQ2000_BUILTIN_MTC3);
2798 def_builtin ("__builtin_lur", void_ftype_int_int, IQ2000_BUILTIN_LUR);
2799 def_builtin ("__builtin_rb", void_ftype_int_int, IQ2000_BUILTIN_RB);
2800 def_builtin ("__builtin_rx", void_ftype_int_int, IQ2000_BUILTIN_RX);
2801 def_builtin ("__builtin_srrd", void_ftype_int, IQ2000_BUILTIN_SRRD);
2802 def_builtin ("__builtin_srwr", void_ftype_int_int, IQ2000_BUILTIN_SRWR);
2803 def_builtin ("__builtin_wb", void_ftype_int_int, IQ2000_BUILTIN_WB);
2804 def_builtin ("__builtin_wx", void_ftype_int_int, IQ2000_BUILTIN_WX);
2805 def_builtin ("__builtin_luc32l", void_ftype_int_int, IQ2000_BUILTIN_LUC32L);
2806 def_builtin ("__builtin_luc64", void_ftype_int_int, IQ2000_BUILTIN_LUC64);
2807 def_builtin ("__builtin_luc64l", void_ftype_int_int, IQ2000_BUILTIN_LUC64L);
2808 def_builtin ("__builtin_luk", void_ftype_int_int, IQ2000_BUILTIN_LUK);
2809 def_builtin ("__builtin_lulck", void_ftype_int, IQ2000_BUILTIN_LULCK);
2810 def_builtin ("__builtin_lum32", void_ftype_int_int, IQ2000_BUILTIN_LUM32);
2811 def_builtin ("__builtin_lum32l", void_ftype_int_int, IQ2000_BUILTIN_LUM32L);
2812 def_builtin ("__builtin_lum64", void_ftype_int_int, IQ2000_BUILTIN_LUM64);
2813 def_builtin ("__builtin_lum64l", void_ftype_int_int, IQ2000_BUILTIN_LUM64L);
2814 def_builtin ("__builtin_lurl", void_ftype_int_int, IQ2000_BUILTIN_LURL);
2815 def_builtin ("__builtin_mrgb", int_ftype_int_int_int, IQ2000_BUILTIN_MRGB);
2816 def_builtin ("__builtin_srrdl", void_ftype_int, IQ2000_BUILTIN_SRRDL);
2817 def_builtin ("__builtin_srulck", void_ftype_int, IQ2000_BUILTIN_SRULCK);
2818 def_builtin ("__builtin_srwru", void_ftype_int_int, IQ2000_BUILTIN_SRWRU);
2819 def_builtin ("__builtin_trapqfl", void_ftype, IQ2000_BUILTIN_TRAPQFL);
2820 def_builtin ("__builtin_trapqne", void_ftype, IQ2000_BUILTIN_TRAPQNE);
2821 def_builtin ("__builtin_traprel", void_ftype_int, IQ2000_BUILTIN_TRAPREL);
2822 def_builtin ("__builtin_wbu", void_ftype_int_int_int, IQ2000_BUILTIN_WBU);
2823 def_builtin ("__builtin_syscall", void_ftype, IQ2000_BUILTIN_SYSCALL);
2826 /* Builtin for ICODE having ARGCOUNT args in ARGLIST where each arg
2827 has an rtx CODE. */
2829 static rtx
2830 expand_one_builtin (enum insn_code icode, rtx target, tree arglist,
2831 enum rtx_code *code, int argcount)
2833 rtx pat;
2834 tree arg [5];
2835 rtx op [5];
2836 enum machine_mode mode [5];
2837 int i;
2839 mode[0] = insn_data[icode].operand[0].mode;
2840 for (i = 0; i < argcount; i++)
2842 arg[i] = TREE_VALUE (arglist);
2843 arglist = TREE_CHAIN (arglist);
2844 op[i] = expand_expr (arg[i], NULL_RTX, VOIDmode, 0);
2845 mode[i] = insn_data[icode].operand[i].mode;
2846 if (code[i] == CONST_INT && GET_CODE (op[i]) != CONST_INT)
2847 error ("argument `%d' is not a constant", i + 1);
2848 if (code[i] == REG
2849 && ! (*insn_data[icode].operand[i].predicate) (op[i], mode[i]))
2850 op[i] = copy_to_mode_reg (mode[i], op[i]);
2853 if (insn_data[icode].operand[0].constraint[0] == '=')
2855 if (target == 0
2856 || GET_MODE (target) != mode[0]
2857 || ! (*insn_data[icode].operand[0].predicate) (target, mode[0]))
2858 target = gen_reg_rtx (mode[0]);
2860 else
2861 target = 0;
2863 switch (argcount)
2865 case 0:
2866 pat = GEN_FCN (icode) (target);
2867 case 1:
2868 if (target)
2869 pat = GEN_FCN (icode) (target, op[0]);
2870 else
2871 pat = GEN_FCN (icode) (op[0]);
2872 break;
2873 case 2:
2874 if (target)
2875 pat = GEN_FCN (icode) (target, op[0], op[1]);
2876 else
2877 pat = GEN_FCN (icode) (op[0], op[1]);
2878 break;
2879 case 3:
2880 if (target)
2881 pat = GEN_FCN (icode) (target, op[0], op[1], op[2]);
2882 else
2883 pat = GEN_FCN (icode) (op[0], op[1], op[2]);
2884 break;
2885 case 4:
2886 if (target)
2887 pat = GEN_FCN (icode) (target, op[0], op[1], op[2], op[3]);
2888 else
2889 pat = GEN_FCN (icode) (op[0], op[1], op[2], op[3]);
2890 break;
2891 default:
2892 abort ();
2895 if (! pat)
2896 return 0;
2897 emit_insn (pat);
2898 return target;
2901 /* Expand an expression EXP that calls a built-in function,
2902 with result going to TARGET if that's convenient
2903 (and in mode MODE if that's convenient).
2904 SUBTARGET may be used as the target for computing one of EXP's operands.
2905 IGNORE is nonzero if the value is to be ignored. */
2907 static rtx
2908 iq2000_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED,
2909 enum machine_mode mode ATTRIBUTE_UNUSED,
2910 int ignore ATTRIBUTE_UNUSED)
2912 tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
2913 tree arglist = TREE_OPERAND (exp, 1);
2914 int fcode = DECL_FUNCTION_CODE (fndecl);
2915 enum rtx_code code [5];
2917 code[0] = REG;
2918 code[1] = REG;
2919 code[2] = REG;
2920 code[3] = REG;
2921 code[4] = REG;
2922 switch (fcode)
2924 default:
2925 break;
2927 case IQ2000_BUILTIN_ADO16:
2928 return expand_one_builtin (CODE_FOR_ado16, target, arglist, code, 2);
2930 case IQ2000_BUILTIN_RAM:
2931 code[1] = CONST_INT;
2932 code[2] = CONST_INT;
2933 code[3] = CONST_INT;
2934 return expand_one_builtin (CODE_FOR_ram, target, arglist, code, 4);
2936 case IQ2000_BUILTIN_CHKHDR:
2937 return expand_one_builtin (CODE_FOR_chkhdr, target, arglist, code, 2);
2939 case IQ2000_BUILTIN_PKRL:
2940 return expand_one_builtin (CODE_FOR_pkrl, target, arglist, code, 2);
2942 case IQ2000_BUILTIN_CFC0:
2943 code[0] = CONST_INT;
2944 return expand_one_builtin (CODE_FOR_cfc0, target, arglist, code, 1);
2946 case IQ2000_BUILTIN_CFC1:
2947 code[0] = CONST_INT;
2948 return expand_one_builtin (CODE_FOR_cfc1, target, arglist, code, 1);
2950 case IQ2000_BUILTIN_CFC2:
2951 code[0] = CONST_INT;
2952 return expand_one_builtin (CODE_FOR_cfc2, target, arglist, code, 1);
2954 case IQ2000_BUILTIN_CFC3:
2955 code[0] = CONST_INT;
2956 return expand_one_builtin (CODE_FOR_cfc3, target, arglist, code, 1);
2958 case IQ2000_BUILTIN_CTC0:
2959 code[1] = CONST_INT;
2960 return expand_one_builtin (CODE_FOR_ctc0, target, arglist, code, 2);
2962 case IQ2000_BUILTIN_CTC1:
2963 code[1] = CONST_INT;
2964 return expand_one_builtin (CODE_FOR_ctc1, target, arglist, code, 2);
2966 case IQ2000_BUILTIN_CTC2:
2967 code[1] = CONST_INT;
2968 return expand_one_builtin (CODE_FOR_ctc2, target, arglist, code, 2);
2970 case IQ2000_BUILTIN_CTC3:
2971 code[1] = CONST_INT;
2972 return expand_one_builtin (CODE_FOR_ctc3, target, arglist, code, 2);
2974 case IQ2000_BUILTIN_MFC0:
2975 code[0] = CONST_INT;
2976 return expand_one_builtin (CODE_FOR_mfc0, target, arglist, code, 1);
2978 case IQ2000_BUILTIN_MFC1:
2979 code[0] = CONST_INT;
2980 return expand_one_builtin (CODE_FOR_mfc1, target, arglist, code, 1);
2982 case IQ2000_BUILTIN_MFC2:
2983 code[0] = CONST_INT;
2984 return expand_one_builtin (CODE_FOR_mfc2, target, arglist, code, 1);
2986 case IQ2000_BUILTIN_MFC3:
2987 code[0] = CONST_INT;
2988 return expand_one_builtin (CODE_FOR_mfc3, target, arglist, code, 1);
2990 case IQ2000_BUILTIN_MTC0:
2991 code[1] = CONST_INT;
2992 return expand_one_builtin (CODE_FOR_mtc0, target, arglist, code, 2);
2994 case IQ2000_BUILTIN_MTC1:
2995 code[1] = CONST_INT;
2996 return expand_one_builtin (CODE_FOR_mtc1, target, arglist, code, 2);
2998 case IQ2000_BUILTIN_MTC2:
2999 code[1] = CONST_INT;
3000 return expand_one_builtin (CODE_FOR_mtc2, target, arglist, code, 2);
3002 case IQ2000_BUILTIN_MTC3:
3003 code[1] = CONST_INT;
3004 return expand_one_builtin (CODE_FOR_mtc3, target, arglist, code, 2);
3006 case IQ2000_BUILTIN_LUR:
3007 return expand_one_builtin (CODE_FOR_lur, target, arglist, code, 2);
3009 case IQ2000_BUILTIN_RB:
3010 return expand_one_builtin (CODE_FOR_rb, target, arglist, code, 2);
3012 case IQ2000_BUILTIN_RX:
3013 return expand_one_builtin (CODE_FOR_rx, target, arglist, code, 2);
3015 case IQ2000_BUILTIN_SRRD:
3016 return expand_one_builtin (CODE_FOR_srrd, target, arglist, code, 1);
3018 case IQ2000_BUILTIN_SRWR:
3019 return expand_one_builtin (CODE_FOR_srwr, target, arglist, code, 2);
3021 case IQ2000_BUILTIN_WB:
3022 return expand_one_builtin (CODE_FOR_wb, target, arglist, code, 2);
3024 case IQ2000_BUILTIN_WX:
3025 return expand_one_builtin (CODE_FOR_wx, target, arglist, code, 2);
3027 case IQ2000_BUILTIN_LUC32L:
3028 return expand_one_builtin (CODE_FOR_luc32l, target, arglist, code, 2);
3030 case IQ2000_BUILTIN_LUC64:
3031 return expand_one_builtin (CODE_FOR_luc64, target, arglist, code, 2);
3033 case IQ2000_BUILTIN_LUC64L:
3034 return expand_one_builtin (CODE_FOR_luc64l, target, arglist, code, 2);
3036 case IQ2000_BUILTIN_LUK:
3037 return expand_one_builtin (CODE_FOR_luk, target, arglist, code, 2);
3039 case IQ2000_BUILTIN_LULCK:
3040 return expand_one_builtin (CODE_FOR_lulck, target, arglist, code, 1);
3042 case IQ2000_BUILTIN_LUM32:
3043 return expand_one_builtin (CODE_FOR_lum32, target, arglist, code, 2);
3045 case IQ2000_BUILTIN_LUM32L:
3046 return expand_one_builtin (CODE_FOR_lum32l, target, arglist, code, 2);
3048 case IQ2000_BUILTIN_LUM64:
3049 return expand_one_builtin (CODE_FOR_lum64, target, arglist, code, 2);
3051 case IQ2000_BUILTIN_LUM64L:
3052 return expand_one_builtin (CODE_FOR_lum64l, target, arglist, code, 2);
3054 case IQ2000_BUILTIN_LURL:
3055 return expand_one_builtin (CODE_FOR_lurl, target, arglist, code, 2);
3057 case IQ2000_BUILTIN_MRGB:
3058 code[2] = CONST_INT;
3059 return expand_one_builtin (CODE_FOR_mrgb, target, arglist, code, 3);
3061 case IQ2000_BUILTIN_SRRDL:
3062 return expand_one_builtin (CODE_FOR_srrdl, target, arglist, code, 1);
3064 case IQ2000_BUILTIN_SRULCK:
3065 return expand_one_builtin (CODE_FOR_srulck, target, arglist, code, 1);
3067 case IQ2000_BUILTIN_SRWRU:
3068 return expand_one_builtin (CODE_FOR_srwru, target, arglist, code, 2);
3070 case IQ2000_BUILTIN_TRAPQFL:
3071 return expand_one_builtin (CODE_FOR_trapqfl, target, arglist, code, 0);
3073 case IQ2000_BUILTIN_TRAPQNE:
3074 return expand_one_builtin (CODE_FOR_trapqne, target, arglist, code, 0);
3076 case IQ2000_BUILTIN_TRAPREL:
3077 return expand_one_builtin (CODE_FOR_traprel, target, arglist, code, 1);
3079 case IQ2000_BUILTIN_WBU:
3080 return expand_one_builtin (CODE_FOR_wbu, target, arglist, code, 3);
3082 case IQ2000_BUILTIN_SYSCALL:
3083 return expand_one_builtin (CODE_FOR_syscall, target, arglist, code, 0);
3086 return NULL_RTX;
3089 /* Worker function for TARGET_RETURN_IN_MEMORY. */
3091 static bool
3092 iq2000_return_in_memory (tree type, tree fntype ATTRIBUTE_UNUSED)
3094 return ((int_size_in_bytes (type) > (2 * UNITS_PER_WORD))
3095 || (int_size_in_bytes (type) == -1));
3098 /* Worker function for TARGET_SETUP_INCOMING_VARARGS. */
3100 static void
3101 iq2000_setup_incoming_varargs (CUMULATIVE_ARGS *cum,
3102 enum machine_mode mode ATTRIBUTE_UNUSED,
3103 tree type ATTRIBUTE_UNUSED, int * pretend_size,
3104 int no_rtl)
3106 unsigned int iq2000_off = ! cum->last_arg_fp;
3107 unsigned int iq2000_fp_off = cum->last_arg_fp;
3109 if ((cum->arg_words < MAX_ARGS_IN_REGISTERS - iq2000_off))
3111 int iq2000_save_gp_regs
3112 = MAX_ARGS_IN_REGISTERS - cum->arg_words - iq2000_off;
3113 int iq2000_save_fp_regs
3114 = (MAX_ARGS_IN_REGISTERS - cum->fp_arg_words - iq2000_fp_off);
3116 if (iq2000_save_gp_regs < 0)
3117 iq2000_save_gp_regs = 0;
3118 if (iq2000_save_fp_regs < 0)
3119 iq2000_save_fp_regs = 0;
3121 *pretend_size = ((iq2000_save_gp_regs * UNITS_PER_WORD)
3122 + (iq2000_save_fp_regs * UNITS_PER_FPREG));
3124 if (! (no_rtl))
3126 if (cum->arg_words < MAX_ARGS_IN_REGISTERS - iq2000_off)
3128 rtx ptr, mem;
3129 ptr = plus_constant (virtual_incoming_args_rtx,
3130 - (iq2000_save_gp_regs
3131 * UNITS_PER_WORD));
3132 mem = gen_rtx_MEM (BLKmode, ptr);
3133 move_block_from_reg
3134 (cum->arg_words + GP_ARG_FIRST + iq2000_off,
3135 mem,
3136 iq2000_save_gp_regs);
3142 /* A C compound statement to output to stdio stream STREAM the
3143 assembler syntax for an instruction operand that is a memory
3144 reference whose address is ADDR. ADDR is an RTL expression. */
3146 void
3147 print_operand_address (FILE * file, rtx addr)
3149 if (!addr)
3150 error ("PRINT_OPERAND_ADDRESS, null pointer");
3152 else
3153 switch (GET_CODE (addr))
3155 case REG:
3156 if (REGNO (addr) == ARG_POINTER_REGNUM)
3157 abort_with_insn (addr, "Arg pointer not eliminated.");
3159 fprintf (file, "0(%s)", reg_names [REGNO (addr)]);
3160 break;
3162 case LO_SUM:
3164 rtx arg0 = XEXP (addr, 0);
3165 rtx arg1 = XEXP (addr, 1);
3167 if (GET_CODE (arg0) != REG)
3168 abort_with_insn (addr,
3169 "PRINT_OPERAND_ADDRESS, LO_SUM with #1 not REG.");
3171 fprintf (file, "%%lo(");
3172 print_operand_address (file, arg1);
3173 fprintf (file, ")(%s)", reg_names [REGNO (arg0)]);
3175 break;
3177 case PLUS:
3179 rtx reg = 0;
3180 rtx offset = 0;
3181 rtx arg0 = XEXP (addr, 0);
3182 rtx arg1 = XEXP (addr, 1);
3184 if (GET_CODE (arg0) == REG)
3186 reg = arg0;
3187 offset = arg1;
3188 if (GET_CODE (offset) == REG)
3189 abort_with_insn (addr, "PRINT_OPERAND_ADDRESS, 2 regs");
3192 else if (GET_CODE (arg1) == REG)
3193 reg = arg1, offset = arg0;
3194 else if (CONSTANT_P (arg0) && CONSTANT_P (arg1))
3196 output_addr_const (file, addr);
3197 break;
3199 else
3200 abort_with_insn (addr, "PRINT_OPERAND_ADDRESS, no regs");
3202 if (! CONSTANT_P (offset))
3203 abort_with_insn (addr, "PRINT_OPERAND_ADDRESS, invalid insn #2");
3205 if (REGNO (reg) == ARG_POINTER_REGNUM)
3206 abort_with_insn (addr, "Arg pointer not eliminated.");
3208 output_addr_const (file, offset);
3209 fprintf (file, "(%s)", reg_names [REGNO (reg)]);
3211 break;
3213 case LABEL_REF:
3214 case SYMBOL_REF:
3215 case CONST_INT:
3216 case CONST:
3217 output_addr_const (file, addr);
3218 if (GET_CODE (addr) == CONST_INT)
3219 fprintf (file, "(%s)", reg_names [0]);
3220 break;
3222 default:
3223 abort_with_insn (addr, "PRINT_OPERAND_ADDRESS, invalid insn #1");
3224 break;
3228 /* A C compound statement to output to stdio stream FILE the
3229 assembler syntax for an instruction operand OP.
3231 LETTER is a value that can be used to specify one of several ways
3232 of printing the operand. It is used when identical operands
3233 must be printed differently depending on the context. LETTER
3234 comes from the `%' specification that was used to request
3235 printing of the operand. If the specification was just `%DIGIT'
3236 then LETTER is 0; if the specification was `%LTR DIGIT' then LETTER
3237 is the ASCII code for LTR.
3239 If OP is a register, this macro should print the register's name.
3240 The names can be found in an array `reg_names' whose type is
3241 `char *[]'. `reg_names' is initialized from `REGISTER_NAMES'.
3243 When the machine description has a specification `%PUNCT' (a `%'
3244 followed by a punctuation character), this macro is called with
3245 a null pointer for X and the punctuation character for LETTER.
3247 The IQ2000 specific codes are:
3249 'X' X is CONST_INT, prints upper 16 bits in hexadecimal format = "0x%04x",
3250 'x' X is CONST_INT, prints lower 16 bits in hexadecimal format = "0x%04x",
3251 'd' output integer constant in decimal,
3252 'z' if the operand is 0, use $0 instead of normal operand.
3253 'D' print second part of double-word register or memory operand.
3254 'L' print low-order register of double-word register operand.
3255 'M' print high-order register of double-word register operand.
3256 'C' print part of opcode for a branch condition.
3257 'F' print part of opcode for a floating-point branch condition.
3258 'N' print part of opcode for a branch condition, inverted.
3259 'W' print part of opcode for a floating-point branch condition, inverted.
3260 'A' Print part of opcode for a bit test condition.
3261 'P' Print label for a bit test.
3262 'p' Print log for a bit test.
3263 'B' print 'z' for EQ, 'n' for NE
3264 'b' print 'n' for EQ, 'z' for NE
3265 'T' print 'f' for EQ, 't' for NE
3266 't' print 't' for EQ, 'f' for NE
3267 'Z' print register and a comma, but print nothing for $fcc0
3268 '?' Print 'l' if we are to use a branch likely instead of normal branch.
3269 '@' Print the name of the assembler temporary register (at or $1).
3270 '.' Print the name of the register with a hard-wired zero (zero or $0).
3271 '$' Print the name of the stack pointer register (sp or $29).
3272 '+' Print the name of the gp register (gp or $28). */
3274 void
3275 print_operand (FILE *file, rtx op, int letter)
3277 enum rtx_code code;
3279 if (PRINT_OPERAND_PUNCT_VALID_P (letter))
3281 switch (letter)
3283 case '?':
3284 if (iq2000_branch_likely)
3285 putc ('l', file);
3286 break;
3288 case '@':
3289 fputs (reg_names [GP_REG_FIRST + 1], file);
3290 break;
3292 case '.':
3293 fputs (reg_names [GP_REG_FIRST + 0], file);
3294 break;
3296 case '$':
3297 fputs (reg_names[STACK_POINTER_REGNUM], file);
3298 break;
3300 case '+':
3301 fputs (reg_names[GP_REG_FIRST + 28], file);
3302 break;
3304 default:
3305 error ("PRINT_OPERAND: Unknown punctuation '%c'", letter);
3306 break;
3309 return;
3312 if (! op)
3314 error ("PRINT_OPERAND null pointer");
3315 return;
3318 code = GET_CODE (op);
3320 if (code == SIGN_EXTEND)
3321 op = XEXP (op, 0), code = GET_CODE (op);
3323 if (letter == 'C')
3324 switch (code)
3326 case EQ: fputs ("eq", file); break;
3327 case NE: fputs ("ne", file); break;
3328 case GT: fputs ("gt", file); break;
3329 case GE: fputs ("ge", file); break;
3330 case LT: fputs ("lt", file); break;
3331 case LE: fputs ("le", file); break;
3332 case GTU: fputs ("ne", file); break;
3333 case GEU: fputs ("geu", file); break;
3334 case LTU: fputs ("ltu", file); break;
3335 case LEU: fputs ("eq", file); break;
3336 default:
3337 abort_with_insn (op, "PRINT_OPERAND, invalid insn for %%C");
3340 else if (letter == 'N')
3341 switch (code)
3343 case EQ: fputs ("ne", file); break;
3344 case NE: fputs ("eq", file); break;
3345 case GT: fputs ("le", file); break;
3346 case GE: fputs ("lt", file); break;
3347 case LT: fputs ("ge", file); break;
3348 case LE: fputs ("gt", file); break;
3349 case GTU: fputs ("leu", file); break;
3350 case GEU: fputs ("ltu", file); break;
3351 case LTU: fputs ("geu", file); break;
3352 case LEU: fputs ("gtu", file); break;
3353 default:
3354 abort_with_insn (op, "PRINT_OPERAND, invalid insn for %%N");
3357 else if (letter == 'F')
3358 switch (code)
3360 case EQ: fputs ("c1f", file); break;
3361 case NE: fputs ("c1t", file); break;
3362 default:
3363 abort_with_insn (op, "PRINT_OPERAND, invalid insn for %%F");
3366 else if (letter == 'W')
3367 switch (code)
3369 case EQ: fputs ("c1t", file); break;
3370 case NE: fputs ("c1f", file); break;
3371 default:
3372 abort_with_insn (op, "PRINT_OPERAND, invalid insn for %%W");
3375 else if (letter == 'A')
3376 fputs (code == LABEL_REF ? "i" : "in", file);
3378 else if (letter == 'P')
3380 if (code == LABEL_REF)
3381 output_addr_const (file, op);
3382 else if (code != PC)
3383 output_operand_lossage ("invalid %%P operand");
3386 else if (letter == 'p')
3388 int value;
3389 if (code != CONST_INT
3390 || (value = exact_log2 (INTVAL (op))) < 0)
3391 output_operand_lossage ("invalid %%p value");
3392 fprintf (file, "%d", value);
3395 else if (letter == 'Z')
3397 int regnum;
3399 if (code != REG)
3400 abort ();
3402 regnum = REGNO (op);
3403 abort ();
3405 fprintf (file, "%s,", reg_names[regnum]);
3408 else if (code == REG || code == SUBREG)
3410 int regnum;
3412 if (code == REG)
3413 regnum = REGNO (op);
3414 else
3415 regnum = true_regnum (op);
3417 if ((letter == 'M' && ! WORDS_BIG_ENDIAN)
3418 || (letter == 'L' && WORDS_BIG_ENDIAN)
3419 || letter == 'D')
3420 regnum++;
3422 fprintf (file, "%s", reg_names[regnum]);
3425 else if (code == MEM)
3427 if (letter == 'D')
3428 output_address (plus_constant (XEXP (op, 0), 4));
3429 else
3430 output_address (XEXP (op, 0));
3433 else if (code == CONST_DOUBLE
3434 && GET_MODE_CLASS (GET_MODE (op)) == MODE_FLOAT)
3436 char s[60];
3438 real_to_decimal (s, CONST_DOUBLE_REAL_VALUE (op), sizeof (s), 0, 1);
3439 fputs (s, file);
3442 else if (letter == 'x' && GET_CODE (op) == CONST_INT)
3443 fprintf (file, HOST_WIDE_INT_PRINT_HEX, 0xffff & INTVAL(op));
3445 else if (letter == 'X' && GET_CODE(op) == CONST_INT)
3446 fprintf (file, HOST_WIDE_INT_PRINT_HEX, 0xffff & (INTVAL (op) >> 16));
3448 else if (letter == 'd' && GET_CODE(op) == CONST_INT)
3449 fprintf (file, HOST_WIDE_INT_PRINT_DEC, (INTVAL(op)));
3451 else if (letter == 'z' && GET_CODE (op) == CONST_INT && INTVAL (op) == 0)
3452 fputs (reg_names[GP_REG_FIRST], file);
3454 else if (letter == 'd' || letter == 'x' || letter == 'X')
3455 output_operand_lossage ("invalid use of %%d, %%x, or %%X");
3457 else if (letter == 'B')
3458 fputs (code == EQ ? "z" : "n", file);
3459 else if (letter == 'b')
3460 fputs (code == EQ ? "n" : "z", file);
3461 else if (letter == 'T')
3462 fputs (code == EQ ? "f" : "t", file);
3463 else if (letter == 't')
3464 fputs (code == EQ ? "t" : "f", file);
3466 else if (code == CONST && GET_CODE (XEXP (op, 0)) == REG)
3468 print_operand (file, XEXP (op, 0), letter);
3471 else
3472 output_addr_const (file, op);
3475 static bool
3476 iq2000_rtx_costs (rtx x, int code, int outer_code ATTRIBUTE_UNUSED, int * total)
3478 enum machine_mode mode = GET_MODE (x);
3480 switch (code)
3482 case MEM:
3484 int num_words = (GET_MODE_SIZE (mode) > UNITS_PER_WORD) ? 2 : 1;
3486 if (simple_memory_operand (x, mode))
3487 return COSTS_N_INSNS (num_words);
3489 * total = COSTS_N_INSNS (2 * num_words);
3490 break;
3493 case FFS:
3494 * total = COSTS_N_INSNS (6);
3495 break;
3497 case AND:
3498 case IOR:
3499 case XOR:
3500 case NOT:
3501 * total = COSTS_N_INSNS (mode == DImode ? 2 : 1);
3502 break;
3504 case ASHIFT:
3505 case ASHIFTRT:
3506 case LSHIFTRT:
3507 if (mode == DImode)
3508 * total = COSTS_N_INSNS ((GET_CODE (XEXP (x, 1)) == CONST_INT) ? 4 : 12);
3509 else
3510 * total = COSTS_N_INSNS (1);
3511 break;
3513 case ABS:
3514 if (mode == SFmode || mode == DFmode)
3515 * total = COSTS_N_INSNS (1);
3516 else
3517 * total = COSTS_N_INSNS (4);
3518 break;
3520 case PLUS:
3521 case MINUS:
3522 if (mode == SFmode || mode == DFmode)
3523 * total = COSTS_N_INSNS (6);
3524 else if (mode == DImode)
3525 * total = COSTS_N_INSNS (4);
3526 else
3527 * total = COSTS_N_INSNS (1);
3528 break;
3530 case NEG:
3531 * total = (mode == DImode) ? 4 : 1;
3532 break;
3534 case MULT:
3535 if (mode == SFmode)
3536 * total = COSTS_N_INSNS (7);
3537 else if (mode == DFmode)
3538 * total = COSTS_N_INSNS (8);
3539 else
3540 * total = COSTS_N_INSNS (10);
3541 break;
3543 case DIV:
3544 case MOD:
3545 if (mode == SFmode)
3546 * total = COSTS_N_INSNS (23);
3547 else if (mode == DFmode)
3548 * total = COSTS_N_INSNS (36);
3549 else
3550 * total = COSTS_N_INSNS (69);
3551 break;
3553 case UDIV:
3554 case UMOD:
3555 * total = COSTS_N_INSNS (69);
3556 break;
3558 case SIGN_EXTEND:
3559 * total = COSTS_N_INSNS (2);
3560 break;
3562 case ZERO_EXTEND:
3563 * total = COSTS_N_INSNS (1);
3564 break;
3566 case CONST_INT:
3567 * total = 0;
3568 break;
3570 case LABEL_REF:
3571 * total = COSTS_N_INSNS (2);
3572 break;
3574 case CONST:
3576 rtx offset = const0_rtx;
3577 rtx symref = eliminate_constant_term (XEXP (x, 0), & offset);
3579 if (GET_CODE (symref) == LABEL_REF)
3580 * total = COSTS_N_INSNS (2);
3581 else if (GET_CODE (symref) != SYMBOL_REF)
3582 * total = COSTS_N_INSNS (4);
3583 /* Let's be paranoid.... */
3584 else if (INTVAL (offset) < -32768 || INTVAL (offset) > 32767)
3585 * total = COSTS_N_INSNS (2);
3586 else
3587 * total = COSTS_N_INSNS (SYMBOL_REF_FLAG (symref) ? 1 : 2);
3588 break;
3591 case SYMBOL_REF:
3592 * total = COSTS_N_INSNS (SYMBOL_REF_FLAG (x) ? 1 : 2);
3593 break;
3595 case CONST_DOUBLE:
3597 rtx high, low;
3599 split_double (x, & high, & low);
3601 * total = COSTS_N_INSNS ( (high == CONST0_RTX (GET_MODE (high))
3602 || low == CONST0_RTX (GET_MODE (low)))
3603 ? 2 : 4);
3604 break;
3607 default:
3608 return false;
3610 return true;
3613 #include "gt-iq2000.h"