Merge from mainline (gomp-merge-2005-02-26).
[official-gcc.git] / gcc / config / iq2000 / iq2000.c
blob80f5a4cd7cb20675ead1cf37cc2d05ad8c007be1
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"
48 #include "langhooks.h"
50 /* Enumeration for all of the relational tests, so that we can build
51 arrays indexed by the test type, and not worry about the order
52 of EQ, NE, etc. */
54 enum internal_test
56 ITEST_EQ,
57 ITEST_NE,
58 ITEST_GT,
59 ITEST_GE,
60 ITEST_LT,
61 ITEST_LE,
62 ITEST_GTU,
63 ITEST_GEU,
64 ITEST_LTU,
65 ITEST_LEU,
66 ITEST_MAX
69 struct constant;
72 /* Structure to be filled in by compute_frame_size with register
73 save masks, and offsets for the current function. */
75 struct iq2000_frame_info
77 long total_size; /* # bytes that the entire frame takes up. */
78 long var_size; /* # bytes that variables take up. */
79 long args_size; /* # bytes that outgoing arguments take up. */
80 long extra_size; /* # bytes of extra gunk. */
81 int gp_reg_size; /* # bytes needed to store gp regs. */
82 int fp_reg_size; /* # bytes needed to store fp regs. */
83 long mask; /* Mask of saved gp registers. */
84 long gp_save_offset; /* Offset from vfp to store gp registers. */
85 long fp_save_offset; /* Offset from vfp to store fp registers. */
86 long gp_sp_offset; /* Offset from new sp to store gp registers. */
87 long fp_sp_offset; /* Offset from new sp to store fp registers. */
88 int initialized; /* != 0 if frame size already calculated. */
89 int num_gp; /* Number of gp registers saved. */
90 } iq2000_frame_info;
92 struct machine_function GTY(())
94 /* Current frame information, calculated by compute_frame_size. */
95 long total_size; /* # bytes that the entire frame takes up. */
96 long var_size; /* # bytes that variables take up. */
97 long args_size; /* # bytes that outgoing arguments take up. */
98 long extra_size; /* # bytes of extra gunk. */
99 int gp_reg_size; /* # bytes needed to store gp regs. */
100 int fp_reg_size; /* # bytes needed to store fp regs. */
101 long mask; /* Mask of saved gp registers. */
102 long gp_save_offset; /* Offset from vfp to store gp registers. */
103 long fp_save_offset; /* Offset from vfp to store fp registers. */
104 long gp_sp_offset; /* Offset from new sp to store gp registers. */
105 long fp_sp_offset; /* Offset from new sp to store fp registers. */
106 int initialized; /* != 0 if frame size already calculated. */
107 int num_gp; /* Number of gp registers saved. */
110 /* Global variables for machine-dependent things. */
112 /* List of all IQ2000 punctuation characters used by print_operand. */
113 char iq2000_print_operand_punct[256];
115 /* The target cpu for optimization and scheduling. */
116 enum processor_type iq2000_tune;
118 /* Which instruction set architecture to use. */
119 int iq2000_isa;
121 /* Cached operands, and operator to compare for use in set/branch/trap
122 on condition codes. */
123 rtx branch_cmp[2];
125 /* What type of branch to use. */
126 enum cmp_type branch_type;
128 /* Strings to hold which cpu and instruction set architecture to use. */
129 const char * iq2000_cpu_string; /* For -mcpu=<xxx>. */
130 const char * iq2000_arch_string; /* For -march=<xxx>. */
133 /* Local variables. */
135 /* The next branch instruction is a branch likely, not branch normal. */
136 static int iq2000_branch_likely;
138 /* Count of delay slots and how many are filled. */
139 static int dslots_load_total;
140 static int dslots_load_filled;
141 static int dslots_jump_total;
143 /* # of nops needed by previous insn. */
144 static int dslots_number_nops;
146 /* Number of 1/2/3 word references to data items (i.e., not jal's). */
147 static int num_refs[3];
149 /* Registers to check for load delay. */
150 static rtx iq2000_load_reg;
151 static rtx iq2000_load_reg2;
152 static rtx iq2000_load_reg3;
153 static rtx iq2000_load_reg4;
155 /* The target cpu for code generation. */
156 static enum processor_type iq2000_arch;
158 /* Mode used for saving/restoring general purpose registers. */
159 static enum machine_mode gpr_mode;
162 /* Initialize the GCC target structure. */
163 static struct machine_function* iq2000_init_machine_status (void);
164 static void iq2000_select_rtx_section (enum machine_mode, rtx, unsigned HOST_WIDE_INT);
165 static void iq2000_init_builtins (void);
166 static rtx iq2000_expand_builtin (tree, rtx, rtx, enum machine_mode, int);
167 static bool iq2000_return_in_memory (tree, tree);
168 static void iq2000_setup_incoming_varargs (CUMULATIVE_ARGS *,
169 enum machine_mode, tree, int *,
170 int);
171 static bool iq2000_rtx_costs (rtx, int, int, int *);
172 static int iq2000_address_cost (rtx);
173 static void iq2000_select_section (tree, int, unsigned HOST_WIDE_INT);
174 static bool iq2000_return_in_memory (tree, tree);
175 static bool iq2000_pass_by_reference (CUMULATIVE_ARGS *, enum machine_mode,
176 tree, bool);
177 static int iq2000_arg_partial_bytes (CUMULATIVE_ARGS *, enum machine_mode,
178 tree, bool);
180 #undef TARGET_INIT_BUILTINS
181 #define TARGET_INIT_BUILTINS iq2000_init_builtins
182 #undef TARGET_EXPAND_BUILTIN
183 #define TARGET_EXPAND_BUILTIN iq2000_expand_builtin
184 #undef TARGET_ASM_SELECT_RTX_SECTION
185 #define TARGET_ASM_SELECT_RTX_SECTION iq2000_select_rtx_section
186 #undef TARGET_RTX_COSTS
187 #define TARGET_RTX_COSTS iq2000_rtx_costs
188 #undef TARGET_ADDRESS_COST
189 #define TARGET_ADDRESS_COST iq2000_address_cost
190 #undef TARGET_ASM_SELECT_SECTION
191 #define TARGET_ASM_SELECT_SECTION iq2000_select_section
193 #undef TARGET_PROMOTE_FUNCTION_ARGS
194 #define TARGET_PROMOTE_FUNCTION_ARGS hook_bool_tree_true
195 #undef TARGET_PROMOTE_FUNCTION_RETURN
196 #define TARGET_PROMOTE_FUNCTION_RETURN hook_bool_tree_true
197 #undef TARGET_PROMOTE_PROTOTYPES
198 #define TARGET_PROMOTE_PROTOTYPES hook_bool_tree_true
200 #undef TARGET_RETURN_IN_MEMORY
201 #define TARGET_RETURN_IN_MEMORY iq2000_return_in_memory
202 #undef TARGET_PASS_BY_REFERENCE
203 #define TARGET_PASS_BY_REFERENCE iq2000_pass_by_reference
204 #undef TARGET_CALLEE_COPIES
205 #define TARGET_CALLEE_COPIES hook_callee_copies_named
206 #undef TARGET_ARG_PARTIAL_BYTES
207 #define TARGET_ARG_PARTIAL_BYTES iq2000_arg_partial_bytes
209 #undef TARGET_SETUP_INCOMING_VARARGS
210 #define TARGET_SETUP_INCOMING_VARARGS iq2000_setup_incoming_varargs
211 #undef TARGET_STRICT_ARGUMENT_NAMING
212 #define TARGET_STRICT_ARGUMENT_NAMING hook_bool_CUMULATIVE_ARGS_true
214 struct gcc_target targetm = TARGET_INITIALIZER;
216 /* Return 1 if OP can be used as an operand where a register or 16 bit unsigned
217 integer is needed. */
220 uns_arith_operand (rtx op, enum machine_mode mode)
222 if (GET_CODE (op) == CONST_INT && SMALL_INT_UNSIGNED (op))
223 return 1;
225 return register_operand (op, mode);
228 /* Return 1 if OP can be used as an operand where a 16 bit integer is needed. */
231 arith_operand (rtx op, enum machine_mode mode)
233 if (GET_CODE (op) == CONST_INT && SMALL_INT (op))
234 return 1;
236 return register_operand (op, mode);
239 /* Return 1 if OP is a integer which fits in 16 bits. */
242 small_int (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
244 return (GET_CODE (op) == CONST_INT && SMALL_INT (op));
247 /* Return 1 if OP is a 32 bit integer which is too big to be loaded with one
248 instruction. */
251 large_int (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
253 HOST_WIDE_INT value;
255 if (GET_CODE (op) != CONST_INT)
256 return 0;
258 value = INTVAL (op);
260 /* IOR reg,$r0,value. */
261 if ((value & ~ ((HOST_WIDE_INT) 0x0000ffff)) == 0)
262 return 0;
264 /* SUBU reg,$r0,value. */
265 if (((unsigned HOST_WIDE_INT) (value + 32768)) <= 32767)
266 return 0;
268 /* LUI reg,value >> 16. */
269 if ((value & 0x0000ffff) == 0)
270 return 0;
272 return 1;
275 /* Return 1 if OP is a register or the constant 0. */
278 reg_or_0_operand (rtx op, enum machine_mode mode)
280 switch (GET_CODE (op))
282 case CONST_INT:
283 return INTVAL (op) == 0;
285 case CONST_DOUBLE:
286 return op == CONST0_RTX (mode);
288 case REG:
289 case SUBREG:
290 return register_operand (op, mode);
292 default:
293 break;
296 return 0;
299 /* Return 1 if OP is a memory operand that fits in a single instruction
300 (i.e., register + small offset). */
303 simple_memory_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
305 rtx addr, plus0, plus1;
307 /* Eliminate non-memory operations. */
308 if (GET_CODE (op) != MEM)
309 return 0;
311 /* Dword operations really put out 2 instructions, so eliminate them. */
312 if (GET_MODE_SIZE (GET_MODE (op)) > (unsigned) UNITS_PER_WORD)
313 return 0;
315 /* Decode the address now. */
316 addr = XEXP (op, 0);
317 switch (GET_CODE (addr))
319 case REG:
320 case LO_SUM:
321 return 1;
323 case CONST_INT:
324 return SMALL_INT (addr);
326 case PLUS:
327 plus0 = XEXP (addr, 0);
328 plus1 = XEXP (addr, 1);
329 if (GET_CODE (plus0) == REG
330 && GET_CODE (plus1) == CONST_INT && SMALL_INT (plus1)
331 && SMALL_INT_UNSIGNED (plus1) /* No negative offsets. */)
332 return 1;
334 else if (GET_CODE (plus1) == REG
335 && GET_CODE (plus0) == CONST_INT && SMALL_INT (plus0)
336 && SMALL_INT_UNSIGNED (plus1) /* No negative offsets. */)
337 return 1;
339 else
340 return 0;
342 case SYMBOL_REF:
343 return 0;
345 default:
346 break;
349 return 0;
352 /* Return nonzero if the code of this rtx pattern is EQ or NE. */
355 equality_op (rtx op, enum machine_mode mode)
357 if (mode != GET_MODE (op))
358 return 0;
360 return GET_CODE (op) == EQ || GET_CODE (op) == NE;
363 /* Return nonzero if the code is a relational operations (EQ, LE, etc). */
366 cmp_op (rtx op, enum machine_mode mode)
368 if (mode != GET_MODE (op))
369 return 0;
371 return COMPARISON_P (op);
374 /* Return nonzero if the operand is either the PC or a label_ref. */
377 pc_or_label_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
379 if (op == pc_rtx)
380 return 1;
382 if (GET_CODE (op) == LABEL_REF)
383 return 1;
385 return 0;
388 /* Return nonzero if OP is a valid operand for a call instruction. */
391 call_insn_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
393 return (CONSTANT_ADDRESS_P (op)
394 || (GET_CODE (op) == REG && op != arg_pointer_rtx
395 && ! (REGNO (op) >= FIRST_PSEUDO_REGISTER
396 && REGNO (op) <= LAST_VIRTUAL_REGISTER)));
399 /* Return nonzero if OP is valid as a source operand for a move instruction. */
402 move_operand (rtx op, enum machine_mode mode)
404 /* Accept any general operand after reload has started; doing so
405 avoids losing if reload does an in-place replacement of a register
406 with a SYMBOL_REF or CONST. */
407 return (general_operand (op, mode)
408 && (! (iq2000_check_split (op, mode))
409 || reload_in_progress || reload_completed));
412 /* Return nonzero if OP is a constant power of 2. */
415 power_of_2_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
417 int intval;
419 if (GET_CODE (op) != CONST_INT)
420 return 0;
421 else
422 intval = INTVAL (op);
424 return ((intval & ((unsigned)(intval) - 1)) == 0);
427 /* Return nonzero if we split the address into high and low parts. */
430 iq2000_check_split (rtx address, enum machine_mode mode)
432 /* This is the same check used in simple_memory_operand.
433 We use it here because LO_SUM is not offsettable. */
434 if (GET_MODE_SIZE (mode) > (unsigned) UNITS_PER_WORD)
435 return 0;
437 if ((GET_CODE (address) == SYMBOL_REF)
438 || (GET_CODE (address) == CONST
439 && GET_CODE (XEXP (XEXP (address, 0), 0)) == SYMBOL_REF)
440 || GET_CODE (address) == LABEL_REF)
441 return 1;
443 return 0;
446 /* Return nonzero if REG is valid for MODE. */
449 iq2000_reg_mode_ok_for_base_p (rtx reg,
450 enum machine_mode mode ATTRIBUTE_UNUSED,
451 int strict)
453 return (strict
454 ? REGNO_MODE_OK_FOR_BASE_P (REGNO (reg), mode)
455 : GP_REG_OR_PSEUDO_NONSTRICT_P (REGNO (reg), mode));
458 /* Return a nonzero value if XINSN is a legitimate address for a
459 memory operand of the indicated MODE. STRICT is nonzero if this
460 function is called during reload. */
463 iq2000_legitimate_address_p (enum machine_mode mode, rtx xinsn, int strict)
465 if (TARGET_DEBUG_A_MODE)
467 GO_PRINTF2 ("\n========== GO_IF_LEGITIMATE_ADDRESS, %sstrict\n",
468 strict ? "" : "not ");
469 GO_DEBUG_RTX (xinsn);
472 /* Check for constant before stripping off SUBREG, so that we don't
473 accept (subreg (const_int)) which will fail to reload. */
474 if (CONSTANT_ADDRESS_P (xinsn)
475 && ! (iq2000_check_split (xinsn, mode))
476 && ! (GET_CODE (xinsn) == CONST_INT && ! SMALL_INT (xinsn)))
477 return 1;
479 while (GET_CODE (xinsn) == SUBREG)
480 xinsn = SUBREG_REG (xinsn);
482 if (GET_CODE (xinsn) == REG
483 && iq2000_reg_mode_ok_for_base_p (xinsn, mode, strict))
484 return 1;
486 if (GET_CODE (xinsn) == LO_SUM)
488 rtx xlow0 = XEXP (xinsn, 0);
489 rtx xlow1 = XEXP (xinsn, 1);
491 while (GET_CODE (xlow0) == SUBREG)
492 xlow0 = SUBREG_REG (xlow0);
493 if (GET_CODE (xlow0) == REG
494 && iq2000_reg_mode_ok_for_base_p (xlow0, mode, strict)
495 && iq2000_check_split (xlow1, mode))
496 return 1;
499 if (GET_CODE (xinsn) == PLUS)
501 rtx xplus0 = XEXP (xinsn, 0);
502 rtx xplus1 = XEXP (xinsn, 1);
503 enum rtx_code code0;
504 enum rtx_code code1;
506 while (GET_CODE (xplus0) == SUBREG)
507 xplus0 = SUBREG_REG (xplus0);
508 code0 = GET_CODE (xplus0);
510 while (GET_CODE (xplus1) == SUBREG)
511 xplus1 = SUBREG_REG (xplus1);
512 code1 = GET_CODE (xplus1);
514 if (code0 == REG
515 && iq2000_reg_mode_ok_for_base_p (xplus0, mode, strict))
517 if (code1 == CONST_INT && SMALL_INT (xplus1)
518 && SMALL_INT_UNSIGNED (xplus1) /* No negative offsets */)
519 return 1;
523 if (TARGET_DEBUG_A_MODE)
524 GO_PRINTF ("Not a legitimate address\n");
526 /* The address was not legitimate. */
527 return 0;
530 /* Returns an operand string for the given instruction's delay slot,
531 after updating filled delay slot statistics.
533 We assume that operands[0] is the target register that is set.
535 In order to check the next insn, most of this functionality is moved
536 to FINAL_PRESCAN_INSN, and we just set the global variables that
537 it needs. */
539 const char *
540 iq2000_fill_delay_slot (const char *ret, enum delay_type type, rtx operands[],
541 rtx cur_insn)
543 rtx set_reg;
544 enum machine_mode mode;
545 rtx next_insn = cur_insn ? NEXT_INSN (cur_insn) : NULL_RTX;
546 int num_nops;
548 if (type == DELAY_LOAD || type == DELAY_FCMP)
549 num_nops = 1;
551 else
552 num_nops = 0;
554 /* Make sure that we don't put nop's after labels. */
555 next_insn = NEXT_INSN (cur_insn);
556 while (next_insn != 0
557 && (GET_CODE (next_insn) == NOTE
558 || GET_CODE (next_insn) == CODE_LABEL))
559 next_insn = NEXT_INSN (next_insn);
561 dslots_load_total += num_nops;
562 if (TARGET_DEBUG_C_MODE
563 || type == DELAY_NONE
564 || operands == 0
565 || cur_insn == 0
566 || next_insn == 0
567 || GET_CODE (next_insn) == CODE_LABEL
568 || (set_reg = operands[0]) == 0)
570 dslots_number_nops = 0;
571 iq2000_load_reg = 0;
572 iq2000_load_reg2 = 0;
573 iq2000_load_reg3 = 0;
574 iq2000_load_reg4 = 0;
576 return ret;
579 set_reg = operands[0];
580 if (set_reg == 0)
581 return ret;
583 while (GET_CODE (set_reg) == SUBREG)
584 set_reg = SUBREG_REG (set_reg);
586 mode = GET_MODE (set_reg);
587 dslots_number_nops = num_nops;
588 iq2000_load_reg = set_reg;
589 if (GET_MODE_SIZE (mode)
590 > (unsigned) (UNITS_PER_WORD))
591 iq2000_load_reg2 = gen_rtx_REG (SImode, REGNO (set_reg) + 1);
592 else
593 iq2000_load_reg2 = 0;
595 return ret;
598 /* Determine whether a memory reference takes one (based off of the GP
599 pointer), two (normal), or three (label + reg) instructions, and bump the
600 appropriate counter for -mstats. */
602 static void
603 iq2000_count_memory_refs (rtx op, int num)
605 int additional = 0;
606 int n_words = 0;
607 rtx addr, plus0, plus1;
608 enum rtx_code code0, code1;
609 int looping;
611 if (TARGET_DEBUG_B_MODE)
613 fprintf (stderr, "\n========== iq2000_count_memory_refs:\n");
614 debug_rtx (op);
617 /* Skip MEM if passed, otherwise handle movsi of address. */
618 addr = (GET_CODE (op) != MEM) ? op : XEXP (op, 0);
620 /* Loop, going through the address RTL. */
623 looping = FALSE;
624 switch (GET_CODE (addr))
626 case REG:
627 case CONST_INT:
628 case LO_SUM:
629 break;
631 case PLUS:
632 plus0 = XEXP (addr, 0);
633 plus1 = XEXP (addr, 1);
634 code0 = GET_CODE (plus0);
635 code1 = GET_CODE (plus1);
637 if (code0 == REG)
639 additional++;
640 addr = plus1;
641 looping = 1;
642 continue;
645 if (code0 == CONST_INT)
647 addr = plus1;
648 looping = 1;
649 continue;
652 if (code1 == REG)
654 additional++;
655 addr = plus0;
656 looping = 1;
657 continue;
660 if (code1 == CONST_INT)
662 addr = plus0;
663 looping = 1;
664 continue;
667 if (code0 == SYMBOL_REF || code0 == LABEL_REF || code0 == CONST)
669 addr = plus0;
670 looping = 1;
671 continue;
674 if (code1 == SYMBOL_REF || code1 == LABEL_REF || code1 == CONST)
676 addr = plus1;
677 looping = 1;
678 continue;
681 break;
683 case LABEL_REF:
684 n_words = 2; /* Always 2 words. */
685 break;
687 case CONST:
688 addr = XEXP (addr, 0);
689 looping = 1;
690 continue;
692 case SYMBOL_REF:
693 n_words = SYMBOL_REF_FLAG (addr) ? 1 : 2;
694 break;
696 default:
697 break;
700 while (looping);
702 if (n_words == 0)
703 return;
705 n_words += additional;
706 if (n_words > 3)
707 n_words = 3;
709 num_refs[n_words-1] += num;
712 /* Abort after printing out a specific insn. */
714 static void
715 abort_with_insn (rtx insn, const char * reason)
717 error (reason);
718 debug_rtx (insn);
719 abort ();
722 /* Return the appropriate instructions to move one operand to another. */
724 const char *
725 iq2000_move_1word (rtx operands[], rtx insn, int unsignedp)
727 const char *ret = 0;
728 rtx op0 = operands[0];
729 rtx op1 = operands[1];
730 enum rtx_code code0 = GET_CODE (op0);
731 enum rtx_code code1 = GET_CODE (op1);
732 enum machine_mode mode = GET_MODE (op0);
733 int subreg_offset0 = 0;
734 int subreg_offset1 = 0;
735 enum delay_type delay = DELAY_NONE;
737 while (code0 == SUBREG)
739 subreg_offset0 += subreg_regno_offset (REGNO (SUBREG_REG (op0)),
740 GET_MODE (SUBREG_REG (op0)),
741 SUBREG_BYTE (op0),
742 GET_MODE (op0));
743 op0 = SUBREG_REG (op0);
744 code0 = GET_CODE (op0);
747 while (code1 == SUBREG)
749 subreg_offset1 += subreg_regno_offset (REGNO (SUBREG_REG (op1)),
750 GET_MODE (SUBREG_REG (op1)),
751 SUBREG_BYTE (op1),
752 GET_MODE (op1));
753 op1 = SUBREG_REG (op1);
754 code1 = GET_CODE (op1);
757 /* For our purposes, a condition code mode is the same as SImode. */
758 if (mode == CCmode)
759 mode = SImode;
761 if (code0 == REG)
763 int regno0 = REGNO (op0) + subreg_offset0;
765 if (code1 == REG)
767 int regno1 = REGNO (op1) + subreg_offset1;
769 /* Do not do anything for assigning a register to itself */
770 if (regno0 == regno1)
771 ret = "";
773 else if (GP_REG_P (regno0))
775 if (GP_REG_P (regno1))
776 ret = "or\t%0,%%0,%1";
781 else if (code1 == MEM)
783 delay = DELAY_LOAD;
785 if (TARGET_STATS)
786 iq2000_count_memory_refs (op1, 1);
788 if (GP_REG_P (regno0))
790 /* For loads, use the mode of the memory item, instead of the
791 target, so zero/sign extend can use this code as well. */
792 switch (GET_MODE (op1))
794 default:
795 break;
796 case SFmode:
797 ret = "lw\t%0,%1";
798 break;
799 case SImode:
800 case CCmode:
801 ret = "lw\t%0,%1";
802 break;
803 case HImode:
804 ret = (unsignedp) ? "lhu\t%0,%1" : "lh\t%0,%1";
805 break;
806 case QImode:
807 ret = (unsignedp) ? "lbu\t%0,%1" : "lb\t%0,%1";
808 break;
813 else if (code1 == CONST_INT
814 || (code1 == CONST_DOUBLE
815 && GET_MODE (op1) == VOIDmode))
817 if (code1 == CONST_DOUBLE)
819 /* This can happen when storing constants into long long
820 bitfields. Just store the least significant word of
821 the value. */
822 operands[1] = op1 = GEN_INT (CONST_DOUBLE_LOW (op1));
825 if (INTVAL (op1) == 0)
827 if (GP_REG_P (regno0))
828 ret = "or\t%0,%%0,%z1";
830 else if (GP_REG_P (regno0))
832 if (SMALL_INT_UNSIGNED (op1))
833 ret = "ori\t%0,%%0,%x1\t\t\t# %1";
834 else if (SMALL_INT (op1))
835 ret = "addiu\t%0,%%0,%1\t\t\t# %1";
836 else
837 ret = "lui\t%0,%X1\t\t\t# %1\n\tori\t%0,%0,%x1";
841 else if (code1 == CONST_DOUBLE && mode == SFmode)
843 if (op1 == CONST0_RTX (SFmode))
845 if (GP_REG_P (regno0))
846 ret = "or\t%0,%%0,%.";
849 else
851 delay = DELAY_LOAD;
852 ret = "li.s\t%0,%1";
856 else if (code1 == LABEL_REF)
858 if (TARGET_STATS)
859 iq2000_count_memory_refs (op1, 1);
861 ret = "la\t%0,%a1";
864 else if (code1 == SYMBOL_REF || code1 == CONST)
866 if (TARGET_STATS)
867 iq2000_count_memory_refs (op1, 1);
869 ret = "la\t%0,%a1";
872 else if (code1 == PLUS)
874 rtx add_op0 = XEXP (op1, 0);
875 rtx add_op1 = XEXP (op1, 1);
877 if (GET_CODE (XEXP (op1, 1)) == REG
878 && GET_CODE (XEXP (op1, 0)) == CONST_INT)
879 add_op0 = XEXP (op1, 1), add_op1 = XEXP (op1, 0);
881 operands[2] = add_op0;
882 operands[3] = add_op1;
883 ret = "add%:\t%0,%2,%3";
886 else if (code1 == HIGH)
888 operands[1] = XEXP (op1, 0);
889 ret = "lui\t%0,%%hi(%1)";
893 else if (code0 == MEM)
895 if (TARGET_STATS)
896 iq2000_count_memory_refs (op0, 1);
898 if (code1 == REG)
900 int regno1 = REGNO (op1) + subreg_offset1;
902 if (GP_REG_P (regno1))
904 switch (mode)
906 case SFmode: ret = "sw\t%1,%0"; break;
907 case SImode: ret = "sw\t%1,%0"; break;
908 case HImode: ret = "sh\t%1,%0"; break;
909 case QImode: ret = "sb\t%1,%0"; break;
910 default: break;
915 else if (code1 == CONST_INT && INTVAL (op1) == 0)
917 switch (mode)
919 case SFmode: ret = "sw\t%z1,%0"; break;
920 case SImode: ret = "sw\t%z1,%0"; break;
921 case HImode: ret = "sh\t%z1,%0"; break;
922 case QImode: ret = "sb\t%z1,%0"; break;
923 default: break;
927 else if (code1 == CONST_DOUBLE && op1 == CONST0_RTX (mode))
929 switch (mode)
931 case SFmode: ret = "sw\t%.,%0"; break;
932 case SImode: ret = "sw\t%.,%0"; break;
933 case HImode: ret = "sh\t%.,%0"; break;
934 case QImode: ret = "sb\t%.,%0"; break;
935 default: break;
940 if (ret == 0)
942 abort_with_insn (insn, "Bad move");
943 return 0;
946 if (delay != DELAY_NONE)
947 return iq2000_fill_delay_slot (ret, delay, operands, insn);
949 return ret;
952 /* Provide the costs of an addressing mode that contains ADDR. */
954 static int
955 iq2000_address_cost (rtx addr)
957 switch (GET_CODE (addr))
959 case LO_SUM:
960 return 1;
962 case LABEL_REF:
963 return 2;
965 case CONST:
967 rtx offset = const0_rtx;
969 addr = eliminate_constant_term (XEXP (addr, 0), & offset);
970 if (GET_CODE (addr) == LABEL_REF)
971 return 2;
973 if (GET_CODE (addr) != SYMBOL_REF)
974 return 4;
976 if (! SMALL_INT (offset))
977 return 2;
980 /* Fall through. */
982 case SYMBOL_REF:
983 return SYMBOL_REF_FLAG (addr) ? 1 : 2;
985 case PLUS:
987 rtx plus0 = XEXP (addr, 0);
988 rtx plus1 = XEXP (addr, 1);
990 if (GET_CODE (plus0) != REG && GET_CODE (plus1) == REG)
991 plus0 = XEXP (addr, 1), plus1 = XEXP (addr, 0);
993 if (GET_CODE (plus0) != REG)
994 break;
996 switch (GET_CODE (plus1))
998 case CONST_INT:
999 return SMALL_INT (plus1) ? 1 : 2;
1001 case CONST:
1002 case SYMBOL_REF:
1003 case LABEL_REF:
1004 case HIGH:
1005 case LO_SUM:
1006 return iq2000_address_cost (plus1) + 1;
1008 default:
1009 break;
1013 default:
1014 break;
1017 return 4;
1020 /* Make normal rtx_code into something we can index from an array. */
1022 static enum internal_test
1023 map_test_to_internal_test (enum rtx_code test_code)
1025 enum internal_test test = ITEST_MAX;
1027 switch (test_code)
1029 case EQ: test = ITEST_EQ; break;
1030 case NE: test = ITEST_NE; break;
1031 case GT: test = ITEST_GT; break;
1032 case GE: test = ITEST_GE; break;
1033 case LT: test = ITEST_LT; break;
1034 case LE: test = ITEST_LE; break;
1035 case GTU: test = ITEST_GTU; break;
1036 case GEU: test = ITEST_GEU; break;
1037 case LTU: test = ITEST_LTU; break;
1038 case LEU: test = ITEST_LEU; break;
1039 default: break;
1042 return test;
1045 /* Generate the code to do a TEST_CODE comparison on two integer values CMP0
1046 and CMP1. P_INVERT is NULL or ptr if branch needs to reverse its test.
1047 The return value RESULT is:
1048 (reg:SI xx) The pseudo register the comparison is in
1049 0 No register, generate a simple branch. */
1052 gen_int_relational (enum rtx_code test_code, rtx result, rtx cmp0, rtx cmp1,
1053 int *p_invert)
1055 struct cmp_info
1057 enum rtx_code test_code; /* Code to use in instruction (LT vs. LTU). */
1058 int const_low; /* Low bound of constant we can accept. */
1059 int const_high; /* High bound of constant we can accept. */
1060 int const_add; /* Constant to add (convert LE -> LT). */
1061 int reverse_regs; /* Reverse registers in test. */
1062 int invert_const; /* != 0 if invert value if cmp1 is constant. */
1063 int invert_reg; /* != 0 if invert value if cmp1 is register. */
1064 int unsignedp; /* != 0 for unsigned comparisons. */
1067 static struct cmp_info info[ (int)ITEST_MAX ] =
1069 { XOR, 0, 65535, 0, 0, 0, 0, 0 }, /* EQ */
1070 { XOR, 0, 65535, 0, 0, 1, 1, 0 }, /* NE */
1071 { LT, -32769, 32766, 1, 1, 1, 0, 0 }, /* GT */
1072 { LT, -32768, 32767, 0, 0, 1, 1, 0 }, /* GE */
1073 { LT, -32768, 32767, 0, 0, 0, 0, 0 }, /* LT */
1074 { LT, -32769, 32766, 1, 1, 0, 1, 0 }, /* LE */
1075 { LTU, -32769, 32766, 1, 1, 1, 0, 1 }, /* GTU */
1076 { LTU, -32768, 32767, 0, 0, 1, 1, 1 }, /* GEU */
1077 { LTU, -32768, 32767, 0, 0, 0, 0, 1 }, /* LTU */
1078 { LTU, -32769, 32766, 1, 1, 0, 1, 1 }, /* LEU */
1081 enum internal_test test;
1082 enum machine_mode mode;
1083 struct cmp_info *p_info;
1084 int branch_p;
1085 int eqne_p;
1086 int invert;
1087 rtx reg;
1088 rtx reg2;
1090 test = map_test_to_internal_test (test_code);
1091 if (test == ITEST_MAX)
1092 abort ();
1094 p_info = &info[(int) test];
1095 eqne_p = (p_info->test_code == XOR);
1097 mode = GET_MODE (cmp0);
1098 if (mode == VOIDmode)
1099 mode = GET_MODE (cmp1);
1101 /* Eliminate simple branches. */
1102 branch_p = (result == 0);
1103 if (branch_p)
1105 if (GET_CODE (cmp0) == REG || GET_CODE (cmp0) == SUBREG)
1107 /* Comparisons against zero are simple branches. */
1108 if (GET_CODE (cmp1) == CONST_INT && INTVAL (cmp1) == 0)
1109 return 0;
1111 /* Test for beq/bne. */
1112 if (eqne_p)
1113 return 0;
1116 /* Allocate a pseudo to calculate the value in. */
1117 result = gen_reg_rtx (mode);
1120 /* Make sure we can handle any constants given to us. */
1121 if (GET_CODE (cmp0) == CONST_INT)
1122 cmp0 = force_reg (mode, cmp0);
1124 if (GET_CODE (cmp1) == CONST_INT)
1126 HOST_WIDE_INT value = INTVAL (cmp1);
1128 if (value < p_info->const_low
1129 || value > p_info->const_high)
1130 cmp1 = force_reg (mode, cmp1);
1133 /* See if we need to invert the result. */
1134 invert = (GET_CODE (cmp1) == CONST_INT
1135 ? p_info->invert_const : p_info->invert_reg);
1137 if (p_invert != (int *)0)
1139 *p_invert = invert;
1140 invert = 0;
1143 /* Comparison to constants, may involve adding 1 to change a LT into LE.
1144 Comparison between two registers, may involve switching operands. */
1145 if (GET_CODE (cmp1) == CONST_INT)
1147 if (p_info->const_add != 0)
1149 HOST_WIDE_INT new = INTVAL (cmp1) + p_info->const_add;
1151 /* If modification of cmp1 caused overflow,
1152 we would get the wrong answer if we follow the usual path;
1153 thus, x > 0xffffffffU would turn into x > 0U. */
1154 if ((p_info->unsignedp
1155 ? (unsigned HOST_WIDE_INT) new >
1156 (unsigned HOST_WIDE_INT) INTVAL (cmp1)
1157 : new > INTVAL (cmp1))
1158 != (p_info->const_add > 0))
1160 /* This test is always true, but if INVERT is true then
1161 the result of the test needs to be inverted so 0 should
1162 be returned instead. */
1163 emit_move_insn (result, invert ? const0_rtx : const_true_rtx);
1164 return result;
1166 else
1167 cmp1 = GEN_INT (new);
1171 else if (p_info->reverse_regs)
1173 rtx temp = cmp0;
1174 cmp0 = cmp1;
1175 cmp1 = temp;
1178 if (test == ITEST_NE && GET_CODE (cmp1) == CONST_INT && INTVAL (cmp1) == 0)
1179 reg = cmp0;
1180 else
1182 reg = (invert || eqne_p) ? gen_reg_rtx (mode) : result;
1183 convert_move (reg, gen_rtx_fmt_ee (p_info->test_code, mode, cmp0, cmp1), 0);
1186 if (test == ITEST_NE)
1188 convert_move (result, gen_rtx_GTU (mode, reg, const0_rtx), 0);
1189 if (p_invert != NULL)
1190 *p_invert = 0;
1191 invert = 0;
1194 else if (test == ITEST_EQ)
1196 reg2 = invert ? gen_reg_rtx (mode) : result;
1197 convert_move (reg2, gen_rtx_LTU (mode, reg, const1_rtx), 0);
1198 reg = reg2;
1201 if (invert)
1203 rtx one;
1205 one = const1_rtx;
1206 convert_move (result, gen_rtx_XOR (mode, reg, one), 0);
1209 return result;
1212 /* Emit the common code for doing conditional branches.
1213 operand[0] is the label to jump to.
1214 The comparison operands are saved away by cmp{si,di,sf,df}. */
1216 void
1217 gen_conditional_branch (rtx operands[], enum rtx_code test_code)
1219 enum cmp_type type = branch_type;
1220 rtx cmp0 = branch_cmp[0];
1221 rtx cmp1 = branch_cmp[1];
1222 enum machine_mode mode;
1223 rtx reg;
1224 int invert;
1225 rtx label1, label2;
1227 switch (type)
1229 case CMP_SI:
1230 case CMP_DI:
1231 mode = type == CMP_SI ? SImode : DImode;
1232 invert = 0;
1233 reg = gen_int_relational (test_code, NULL_RTX, cmp0, cmp1, &invert);
1235 if (reg)
1237 cmp0 = reg;
1238 cmp1 = const0_rtx;
1239 test_code = NE;
1241 else if (GET_CODE (cmp1) == CONST_INT && INTVAL (cmp1) != 0)
1242 /* We don't want to build a comparison against a nonzero
1243 constant. */
1244 cmp1 = force_reg (mode, cmp1);
1246 break;
1248 case CMP_SF:
1249 case CMP_DF:
1250 reg = gen_reg_rtx (CCmode);
1252 /* For cmp0 != cmp1, build cmp0 == cmp1, and test for result == 0. */
1253 emit_insn (gen_rtx_SET (VOIDmode, reg,
1254 gen_rtx_fmt_ee (test_code == NE ? EQ : test_code,
1255 CCmode, cmp0, cmp1)));
1257 test_code = test_code == NE ? EQ : NE;
1258 mode = CCmode;
1259 cmp0 = reg;
1260 cmp1 = const0_rtx;
1261 invert = 0;
1262 break;
1264 default:
1265 abort_with_insn (gen_rtx_fmt_ee (test_code, VOIDmode, cmp0, cmp1),
1266 "bad test");
1269 /* Generate the branch. */
1270 label1 = gen_rtx_LABEL_REF (VOIDmode, operands[0]);
1271 label2 = pc_rtx;
1273 if (invert)
1275 label2 = label1;
1276 label1 = pc_rtx;
1279 emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
1280 gen_rtx_IF_THEN_ELSE (VOIDmode,
1281 gen_rtx_fmt_ee (test_code,
1282 mode,
1283 cmp0, cmp1),
1284 label1, label2)));
1287 /* Initialize CUM for a function FNTYPE. */
1289 void
1290 init_cumulative_args (CUMULATIVE_ARGS *cum, tree fntype,
1291 rtx libname ATTRIBUTE_UNUSED)
1293 static CUMULATIVE_ARGS zero_cum;
1294 tree param;
1295 tree next_param;
1297 if (TARGET_DEBUG_D_MODE)
1299 fprintf (stderr,
1300 "\ninit_cumulative_args, fntype = 0x%.8lx", (long) fntype);
1302 if (!fntype)
1303 fputc ('\n', stderr);
1305 else
1307 tree ret_type = TREE_TYPE (fntype);
1309 fprintf (stderr, ", fntype code = %s, ret code = %s\n",
1310 tree_code_name[(int)TREE_CODE (fntype)],
1311 tree_code_name[(int)TREE_CODE (ret_type)]);
1315 *cum = zero_cum;
1317 /* Determine if this function has variable arguments. This is
1318 indicated by the last argument being 'void_type_mode' if there
1319 are no variable arguments. The standard IQ2000 calling sequence
1320 passes all arguments in the general purpose registers in this case. */
1322 for (param = fntype ? TYPE_ARG_TYPES (fntype) : 0;
1323 param != 0; param = next_param)
1325 next_param = TREE_CHAIN (param);
1326 if (next_param == 0 && TREE_VALUE (param) != void_type_node)
1327 cum->gp_reg_found = 1;
1331 /* Advance the argument of type TYPE and mode MODE to the next argument
1332 position in CUM. */
1334 void
1335 function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode, tree type,
1336 int named)
1338 if (TARGET_DEBUG_D_MODE)
1340 fprintf (stderr,
1341 "function_adv({gp reg found = %d, arg # = %2d, words = %2d}, %4s, ",
1342 cum->gp_reg_found, cum->arg_number, cum->arg_words,
1343 GET_MODE_NAME (mode));
1344 fprintf (stderr, HOST_PTR_PRINTF, (const PTR) type);
1345 fprintf (stderr, ", %d )\n\n", named);
1348 cum->arg_number++;
1349 switch (mode)
1351 case VOIDmode:
1352 break;
1354 default:
1355 if (GET_MODE_CLASS (mode) != MODE_COMPLEX_INT
1356 && GET_MODE_CLASS (mode) != MODE_COMPLEX_FLOAT)
1357 abort ();
1359 cum->gp_reg_found = 1;
1360 cum->arg_words += ((GET_MODE_SIZE (mode) + UNITS_PER_WORD - 1)
1361 / UNITS_PER_WORD);
1362 break;
1364 case BLKmode:
1365 cum->gp_reg_found = 1;
1366 cum->arg_words += ((int_size_in_bytes (type) + UNITS_PER_WORD - 1)
1367 / UNITS_PER_WORD);
1368 break;
1370 case SFmode:
1371 cum->arg_words ++;
1372 if (! cum->gp_reg_found && cum->arg_number <= 2)
1373 cum->fp_code += 1 << ((cum->arg_number - 1) * 2);
1374 break;
1376 case DFmode:
1377 cum->arg_words += 2;
1378 if (! cum->gp_reg_found && cum->arg_number <= 2)
1379 cum->fp_code += 2 << ((cum->arg_number - 1) * 2);
1380 break;
1382 case DImode:
1383 cum->gp_reg_found = 1;
1384 cum->arg_words += 2;
1385 break;
1387 case QImode:
1388 case HImode:
1389 case SImode:
1390 cum->gp_reg_found = 1;
1391 cum->arg_words ++;
1392 break;
1396 /* Return an RTL expression containing the register for the given mode MODE
1397 and type TYPE in CUM, or 0 if the argument is to be passed on the stack. */
1399 struct rtx_def *
1400 function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode, tree type,
1401 int named)
1403 rtx ret;
1404 int regbase = -1;
1405 int bias = 0;
1406 unsigned int *arg_words = &cum->arg_words;
1407 int struct_p = (type != 0
1408 && (TREE_CODE (type) == RECORD_TYPE
1409 || TREE_CODE (type) == UNION_TYPE
1410 || TREE_CODE (type) == QUAL_UNION_TYPE));
1412 if (TARGET_DEBUG_D_MODE)
1414 fprintf (stderr,
1415 "function_arg( {gp reg found = %d, arg # = %2d, words = %2d}, %4s, ",
1416 cum->gp_reg_found, cum->arg_number, cum->arg_words,
1417 GET_MODE_NAME (mode));
1418 fprintf (stderr, HOST_PTR_PRINTF, (const PTR) type);
1419 fprintf (stderr, ", %d ) = ", named);
1423 cum->last_arg_fp = 0;
1424 switch (mode)
1426 case SFmode:
1427 regbase = GP_ARG_FIRST;
1428 break;
1430 case DFmode:
1431 cum->arg_words += cum->arg_words & 1;
1433 regbase = GP_ARG_FIRST;
1434 break;
1436 default:
1437 if (GET_MODE_CLASS (mode) != MODE_COMPLEX_INT
1438 && GET_MODE_CLASS (mode) != MODE_COMPLEX_FLOAT)
1439 abort ();
1441 /* Drops through. */
1442 case BLKmode:
1443 if (type != NULL_TREE && TYPE_ALIGN (type) > (unsigned) BITS_PER_WORD)
1444 cum->arg_words += (cum->arg_words & 1);
1445 regbase = GP_ARG_FIRST;
1446 break;
1448 case VOIDmode:
1449 case QImode:
1450 case HImode:
1451 case SImode:
1452 regbase = GP_ARG_FIRST;
1453 break;
1455 case DImode:
1456 cum->arg_words += (cum->arg_words & 1);
1457 regbase = GP_ARG_FIRST;
1460 if (*arg_words >= (unsigned) MAX_ARGS_IN_REGISTERS)
1462 if (TARGET_DEBUG_D_MODE)
1463 fprintf (stderr, "<stack>%s\n", struct_p ? ", [struct]" : "");
1465 ret = 0;
1467 else
1469 if (regbase == -1)
1470 abort ();
1472 if (! type || TREE_CODE (type) != RECORD_TYPE
1473 || ! named || ! TYPE_SIZE_UNIT (type)
1474 || ! host_integerp (TYPE_SIZE_UNIT (type), 1))
1475 ret = gen_rtx_REG (mode, regbase + *arg_words + bias);
1476 else
1478 tree field;
1480 for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field))
1481 if (TREE_CODE (field) == FIELD_DECL
1482 && TREE_CODE (TREE_TYPE (field)) == REAL_TYPE
1483 && TYPE_PRECISION (TREE_TYPE (field)) == BITS_PER_WORD
1484 && host_integerp (bit_position (field), 0)
1485 && int_bit_position (field) % BITS_PER_WORD == 0)
1486 break;
1488 /* If the whole struct fits a DFmode register,
1489 we don't need the PARALLEL. */
1490 if (! field || mode == DFmode)
1491 ret = gen_rtx_REG (mode, regbase + *arg_words + bias);
1492 else
1494 unsigned int chunks;
1495 HOST_WIDE_INT bitpos;
1496 unsigned int regno;
1497 unsigned int i;
1499 /* ??? If this is a packed structure, then the last hunk won't
1500 be 64 bits. */
1501 chunks
1502 = tree_low_cst (TYPE_SIZE_UNIT (type), 1) / UNITS_PER_WORD;
1503 if (chunks + *arg_words + bias > (unsigned) MAX_ARGS_IN_REGISTERS)
1504 chunks = MAX_ARGS_IN_REGISTERS - *arg_words - bias;
1506 /* Assign_parms checks the mode of ENTRY_PARM, so we must
1507 use the actual mode here. */
1508 ret = gen_rtx_PARALLEL (mode, rtvec_alloc (chunks));
1510 bitpos = 0;
1511 regno = regbase + *arg_words + bias;
1512 field = TYPE_FIELDS (type);
1513 for (i = 0; i < chunks; i++)
1515 rtx reg;
1517 for (; field; field = TREE_CHAIN (field))
1518 if (TREE_CODE (field) == FIELD_DECL
1519 && int_bit_position (field) >= bitpos)
1520 break;
1522 if (field
1523 && int_bit_position (field) == bitpos
1524 && TREE_CODE (TREE_TYPE (field)) == REAL_TYPE
1525 && TYPE_PRECISION (TREE_TYPE (field)) == BITS_PER_WORD)
1526 reg = gen_rtx_REG (DFmode, regno++);
1527 else
1528 reg = gen_rtx_REG (word_mode, regno);
1530 XVECEXP (ret, 0, i)
1531 = gen_rtx_EXPR_LIST (VOIDmode, reg,
1532 GEN_INT (bitpos / BITS_PER_UNIT));
1534 bitpos += 64;
1535 regno++;
1540 if (TARGET_DEBUG_D_MODE)
1541 fprintf (stderr, "%s%s\n", reg_names[regbase + *arg_words + bias],
1542 struct_p ? ", [struct]" : "");
1545 /* We will be called with a mode of VOIDmode after the last argument
1546 has been seen. Whatever we return will be passed to the call
1547 insn. If we need any shifts for small structures, return them in
1548 a PARALLEL. */
1549 if (mode == VOIDmode)
1551 if (cum->num_adjusts > 0)
1552 ret = gen_rtx_PARALLEL ((enum machine_mode) cum->fp_code,
1553 gen_rtvec_v (cum->num_adjusts, cum->adjust));
1556 return ret;
1559 static int
1560 iq2000_arg_partial_bytes (CUMULATIVE_ARGS *cum, enum machine_mode mode,
1561 tree type ATTRIBUTE_UNUSED,
1562 bool named ATTRIBUTE_UNUSED)
1564 if (mode == DImode && cum->arg_words == MAX_ARGS_IN_REGISTERS - 1)
1566 if (TARGET_DEBUG_D_MODE)
1567 fprintf (stderr, "iq2000_arg_partial_bytes=%d\n", UNITS_PER_WORD);
1568 return UNITS_PER_WORD;
1571 return 0;
1574 /* Implement va_start. */
1576 void
1577 iq2000_va_start (tree valist, rtx nextarg)
1579 int int_arg_words;
1580 /* Find out how many non-float named formals. */
1581 int gpr_save_area_size;
1582 /* Note UNITS_PER_WORD is 4 bytes. */
1583 int_arg_words = current_function_args_info.arg_words;
1585 if (int_arg_words < 8 )
1586 /* Adjust for the prologue's economy measure. */
1587 gpr_save_area_size = (8 - int_arg_words) * UNITS_PER_WORD;
1588 else
1589 gpr_save_area_size = 0;
1591 /* Everything is in the GPR save area, or in the overflow
1592 area which is contiguous with it. */
1593 nextarg = plus_constant (nextarg, - gpr_save_area_size);
1594 std_expand_builtin_va_start (valist, nextarg);
1597 /* Allocate a chunk of memory for per-function machine-dependent data. */
1599 static struct machine_function *
1600 iq2000_init_machine_status (void)
1602 struct machine_function *f;
1604 f = ggc_alloc_cleared (sizeof (struct machine_function));
1606 return f;
1609 static enum processor_type
1610 iq2000_parse_cpu (const char * cpu_string)
1612 const char *p = cpu_string;
1613 enum processor_type cpu;
1615 cpu = PROCESSOR_DEFAULT;
1616 switch (p[2])
1618 case '1':
1619 if (!strcmp (p, "iq10"))
1620 cpu = PROCESSOR_IQ10;
1621 break;
1622 case '2':
1623 if (!strcmp (p, "iq2000"))
1624 cpu = PROCESSOR_IQ2000;
1625 break;
1628 return cpu;
1631 /* Detect any conflicts in the switches. */
1633 void
1634 override_options (void)
1636 enum processor_type iq2000_cpu;
1638 target_flags &= ~MASK_GPOPT;
1640 iq2000_isa = IQ2000_ISA_DEFAULT;
1642 /* Identify the processor type. */
1644 if (iq2000_cpu_string != 0)
1646 iq2000_cpu = iq2000_parse_cpu (iq2000_cpu_string);
1647 if (iq2000_cpu == PROCESSOR_DEFAULT)
1649 error ("bad value (%s) for -mcpu= switch", iq2000_arch_string);
1650 iq2000_cpu_string = "default";
1652 iq2000_arch = iq2000_cpu;
1653 iq2000_tune = iq2000_cpu;
1656 if (iq2000_arch_string == 0
1657 || ! strcmp (iq2000_arch_string, "default")
1658 || ! strcmp (iq2000_arch_string, "DEFAULT"))
1660 switch (iq2000_isa)
1662 default:
1663 iq2000_arch_string = "iq2000";
1664 iq2000_arch = PROCESSOR_IQ2000;
1665 break;
1668 else
1670 iq2000_arch = iq2000_parse_cpu (iq2000_arch_string);
1671 if (iq2000_arch == PROCESSOR_DEFAULT)
1673 error ("bad value (%s) for -march= switch", iq2000_arch_string);
1674 iq2000_arch_string = "default";
1676 if (iq2000_arch == PROCESSOR_IQ10)
1678 error ("The compiler does not support -march=%s.", iq2000_arch_string);
1679 iq2000_arch_string = "default";
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;
1700 iq2000_print_operand_punct['+'] = 1;
1701 iq2000_print_operand_punct['~'] = 1;
1703 /* Save GPR registers in word_mode sized hunks. word_mode hasn't been
1704 initialized yet, so we can't use that here. */
1705 gpr_mode = SImode;
1707 /* Function to allocate machine-dependent function status. */
1708 init_machine_status = iq2000_init_machine_status;
1711 /* The arg pointer (which is eliminated) points to the virtual frame pointer,
1712 while the frame pointer (which may be eliminated) points to the stack
1713 pointer after the initial adjustments. */
1715 HOST_WIDE_INT
1716 iq2000_debugger_offset (rtx addr, HOST_WIDE_INT offset)
1718 rtx offset2 = const0_rtx;
1719 rtx reg = eliminate_constant_term (addr, & offset2);
1721 if (offset == 0)
1722 offset = INTVAL (offset2);
1724 if (reg == stack_pointer_rtx || reg == frame_pointer_rtx
1725 || reg == hard_frame_pointer_rtx)
1727 HOST_WIDE_INT frame_size = (!cfun->machine->initialized)
1728 ? compute_frame_size (get_frame_size ())
1729 : cfun->machine->total_size;
1731 offset = offset - frame_size;
1734 return offset;
1737 /* If defined, a C statement to be executed just prior to the output of
1738 assembler code for INSN, to modify the extracted operands so they will be
1739 output differently.
1741 Here the argument OPVEC is the vector containing the operands extracted
1742 from INSN, and NOPERANDS is the number of elements of the vector which
1743 contain meaningful data for this insn. The contents of this vector are
1744 what will be used to convert the insn template into assembler code, so you
1745 can change the assembler output by changing the contents of the vector.
1747 We use it to check if the current insn needs a nop in front of it because
1748 of load delays, and also to update the delay slot statistics. */
1750 void
1751 final_prescan_insn (rtx insn, rtx opvec[] ATTRIBUTE_UNUSED,
1752 int noperands ATTRIBUTE_UNUSED)
1754 if (dslots_number_nops > 0)
1756 rtx pattern = PATTERN (insn);
1757 int length = get_attr_length (insn);
1759 /* Do we need to emit a NOP? */
1760 if (length == 0
1761 || (iq2000_load_reg != 0 && reg_mentioned_p (iq2000_load_reg, pattern))
1762 || (iq2000_load_reg2 != 0 && reg_mentioned_p (iq2000_load_reg2, pattern))
1763 || (iq2000_load_reg3 != 0 && reg_mentioned_p (iq2000_load_reg3, pattern))
1764 || (iq2000_load_reg4 != 0
1765 && reg_mentioned_p (iq2000_load_reg4, pattern)))
1766 fputs ("\tnop\n", asm_out_file);
1768 else
1769 dslots_load_filled ++;
1771 while (--dslots_number_nops > 0)
1772 fputs ("\tnop\n", asm_out_file);
1774 iq2000_load_reg = 0;
1775 iq2000_load_reg2 = 0;
1776 iq2000_load_reg3 = 0;
1777 iq2000_load_reg4 = 0;
1780 if ( (GET_CODE (insn) == JUMP_INSN
1781 || GET_CODE (insn) == CALL_INSN
1782 || (GET_CODE (PATTERN (insn)) == RETURN))
1783 && NEXT_INSN (PREV_INSN (insn)) == insn)
1785 rtx nop_insn = emit_insn_after (gen_nop (), insn);
1787 INSN_ADDRESSES_NEW (nop_insn, -1);
1790 if (TARGET_STATS
1791 && (GET_CODE (insn) == JUMP_INSN || GET_CODE (insn) == CALL_INSN))
1792 dslots_jump_total ++;
1795 /* Return the bytes needed to compute the frame pointer from the current
1796 stack pointer where SIZE is the # of var. bytes allocated.
1798 IQ2000 stack frames look like:
1800 Before call After call
1801 +-----------------------+ +-----------------------+
1802 high | | | |
1803 mem. | | | |
1804 | caller's temps. | | caller's temps. |
1805 | | | |
1806 +-----------------------+ +-----------------------+
1807 | | | |
1808 | arguments on stack. | | arguments on stack. |
1809 | | | |
1810 +-----------------------+ +-----------------------+
1811 | 4 words to save | | 4 words to save |
1812 | arguments passed | | arguments passed |
1813 | in registers, even | | in registers, even |
1814 SP->| if not passed. | VFP->| if not passed. |
1815 +-----------------------+ +-----------------------+
1817 | fp register save |
1819 +-----------------------+
1821 | gp register save |
1823 +-----------------------+
1825 | local variables |
1827 +-----------------------+
1829 | alloca allocations |
1831 +-----------------------+
1833 | GP save for V.4 abi |
1835 +-----------------------+
1837 | arguments on stack |
1839 +-----------------------+
1840 | 4 words to save |
1841 | arguments passed |
1842 | in registers, even |
1843 low SP->| if not passed. |
1844 memory +-----------------------+ */
1846 HOST_WIDE_INT
1847 compute_frame_size (HOST_WIDE_INT size)
1849 int regno;
1850 HOST_WIDE_INT total_size; /* # bytes that the entire frame takes up. */
1851 HOST_WIDE_INT var_size; /* # bytes that variables take up. */
1852 HOST_WIDE_INT args_size; /* # bytes that outgoing arguments take up. */
1853 HOST_WIDE_INT extra_size; /* # extra bytes. */
1854 HOST_WIDE_INT gp_reg_rounded; /* # bytes needed to store gp after rounding. */
1855 HOST_WIDE_INT gp_reg_size; /* # bytes needed to store gp regs. */
1856 HOST_WIDE_INT fp_reg_size; /* # bytes needed to store fp regs. */
1857 long mask; /* mask of saved gp registers. */
1858 int fp_inc; /* 1 or 2 depending on the size of fp regs. */
1859 long fp_bits; /* bitmask to use for each fp register. */
1861 gp_reg_size = 0;
1862 fp_reg_size = 0;
1863 mask = 0;
1864 extra_size = IQ2000_STACK_ALIGN ((0));
1865 var_size = IQ2000_STACK_ALIGN (size);
1866 args_size = IQ2000_STACK_ALIGN (current_function_outgoing_args_size);
1868 /* If a function dynamically allocates the stack and
1869 has 0 for STACK_DYNAMIC_OFFSET then allocate some stack space. */
1870 if (args_size == 0 && current_function_calls_alloca)
1871 args_size = 4 * UNITS_PER_WORD;
1873 total_size = var_size + args_size + extra_size;
1875 /* Calculate space needed for gp registers. */
1876 for (regno = GP_REG_FIRST; regno <= GP_REG_LAST; regno++)
1878 if (MUST_SAVE_REGISTER (regno))
1880 gp_reg_size += GET_MODE_SIZE (gpr_mode);
1881 mask |= 1L << (regno - GP_REG_FIRST);
1885 /* We need to restore these for the handler. */
1886 if (current_function_calls_eh_return)
1888 unsigned int i;
1890 for (i = 0; ; ++i)
1892 regno = EH_RETURN_DATA_REGNO (i);
1893 if (regno == (int) INVALID_REGNUM)
1894 break;
1895 gp_reg_size += GET_MODE_SIZE (gpr_mode);
1896 mask |= 1L << (regno - GP_REG_FIRST);
1900 fp_inc = 2;
1901 fp_bits = 3;
1902 gp_reg_rounded = IQ2000_STACK_ALIGN (gp_reg_size);
1903 total_size += gp_reg_rounded + IQ2000_STACK_ALIGN (fp_reg_size);
1905 /* The gp reg is caller saved, so there is no need for leaf routines
1906 (total_size == extra_size) to save the gp reg. */
1907 if (total_size == extra_size
1908 && ! profile_flag)
1909 total_size = extra_size = 0;
1911 total_size += IQ2000_STACK_ALIGN (current_function_pretend_args_size);
1913 /* Save other computed information. */
1914 cfun->machine->total_size = total_size;
1915 cfun->machine->var_size = var_size;
1916 cfun->machine->args_size = args_size;
1917 cfun->machine->extra_size = extra_size;
1918 cfun->machine->gp_reg_size = gp_reg_size;
1919 cfun->machine->fp_reg_size = fp_reg_size;
1920 cfun->machine->mask = mask;
1921 cfun->machine->initialized = reload_completed;
1922 cfun->machine->num_gp = gp_reg_size / UNITS_PER_WORD;
1924 if (mask)
1926 unsigned long offset;
1928 offset = (args_size + extra_size + var_size
1929 + gp_reg_size - GET_MODE_SIZE (gpr_mode));
1931 cfun->machine->gp_sp_offset = offset;
1932 cfun->machine->gp_save_offset = offset - total_size;
1934 else
1936 cfun->machine->gp_sp_offset = 0;
1937 cfun->machine->gp_save_offset = 0;
1940 cfun->machine->fp_sp_offset = 0;
1941 cfun->machine->fp_save_offset = 0;
1943 /* Ok, we're done. */
1944 return total_size;
1947 /* Implement INITIAL_ELIMINATION_OFFSET. FROM is either the frame
1948 pointer, argument pointer, or return address pointer. TO is either
1949 the stack pointer or hard frame pointer. */
1952 iq2000_initial_elimination_offset (int from, int to ATTRIBUTE_UNUSED)
1954 int offset;
1956 compute_frame_size (get_frame_size ());
1957 if ((from) == FRAME_POINTER_REGNUM)
1958 (offset) = 0;
1959 else if ((from) == ARG_POINTER_REGNUM)
1960 (offset) = (cfun->machine->total_size);
1961 else if ((from) == RETURN_ADDRESS_POINTER_REGNUM)
1963 if (leaf_function_p ())
1964 (offset) = 0;
1965 else (offset) = cfun->machine->gp_sp_offset
1966 + ((UNITS_PER_WORD - (POINTER_SIZE / BITS_PER_UNIT))
1967 * (BYTES_BIG_ENDIAN != 0));
1970 return offset;
1973 /* Common code to emit the insns (or to write the instructions to a file)
1974 to save/restore registers.
1975 Other parts of the code assume that IQ2000_TEMP1_REGNUM (aka large_reg)
1976 is not modified within save_restore_insns. */
1978 #define BITSET_P(VALUE,BIT) (((VALUE) & (1L << (BIT))) != 0)
1980 /* Emit instructions to load the value (SP + OFFSET) into IQ2000_TEMP2_REGNUM
1981 and return an rtl expression for the register. Write the assembly
1982 instructions directly to FILE if it is not null, otherwise emit them as
1983 rtl.
1985 This function is a subroutine of save_restore_insns. It is used when
1986 OFFSET is too large to add in a single instruction. */
1988 static rtx
1989 iq2000_add_large_offset_to_sp (HOST_WIDE_INT offset)
1991 rtx reg = gen_rtx_REG (Pmode, IQ2000_TEMP2_REGNUM);
1992 rtx offset_rtx = GEN_INT (offset);
1994 emit_move_insn (reg, offset_rtx);
1995 emit_insn (gen_addsi3 (reg, reg, stack_pointer_rtx));
1996 return reg;
1999 /* Make INSN frame related and note that it performs the frame-related
2000 operation DWARF_PATTERN. */
2002 static void
2003 iq2000_annotate_frame_insn (rtx insn, rtx dwarf_pattern)
2005 RTX_FRAME_RELATED_P (insn) = 1;
2006 REG_NOTES (insn) = alloc_EXPR_LIST (REG_FRAME_RELATED_EXPR,
2007 dwarf_pattern,
2008 REG_NOTES (insn));
2011 /* Emit a move instruction that stores REG in MEM. Make the instruction
2012 frame related and note that it stores REG at (SP + OFFSET). */
2014 static void
2015 iq2000_emit_frame_related_store (rtx mem, rtx reg, HOST_WIDE_INT offset)
2017 rtx dwarf_address = plus_constant (stack_pointer_rtx, offset);
2018 rtx dwarf_mem = gen_rtx_MEM (GET_MODE (reg), dwarf_address);
2020 iq2000_annotate_frame_insn (emit_move_insn (mem, reg),
2021 gen_rtx_SET (GET_MODE (reg), dwarf_mem, reg));
2024 /* Emit instructions to save/restore registers, as determined by STORE_P. */
2026 static void
2027 save_restore_insns (int store_p)
2029 long mask = cfun->machine->mask;
2030 int regno;
2031 rtx base_reg_rtx;
2032 HOST_WIDE_INT base_offset;
2033 HOST_WIDE_INT gp_offset;
2034 HOST_WIDE_INT end_offset;
2036 if (frame_pointer_needed
2037 && ! BITSET_P (mask, HARD_FRAME_POINTER_REGNUM - GP_REG_FIRST))
2038 abort ();
2040 if (mask == 0)
2042 base_reg_rtx = 0, base_offset = 0;
2043 return;
2046 /* Save registers starting from high to low. The debuggers prefer at least
2047 the return register be stored at func+4, and also it allows us not to
2048 need a nop in the epilog if at least one register is reloaded in
2049 addition to return address. */
2051 /* Save GP registers if needed. */
2052 /* Pick which pointer to use as a base register. For small frames, just
2053 use the stack pointer. Otherwise, use a temporary register. Save 2
2054 cycles if the save area is near the end of a large frame, by reusing
2055 the constant created in the prologue/epilogue to adjust the stack
2056 frame. */
2058 gp_offset = cfun->machine->gp_sp_offset;
2059 end_offset
2060 = gp_offset - (cfun->machine->gp_reg_size
2061 - GET_MODE_SIZE (gpr_mode));
2063 if (gp_offset < 0 || end_offset < 0)
2064 internal_error
2065 ("gp_offset (%ld) or end_offset (%ld) is less than zero.",
2066 (long) gp_offset, (long) end_offset);
2068 else if (gp_offset < 32768)
2069 base_reg_rtx = stack_pointer_rtx, base_offset = 0;
2070 else
2072 int regno;
2073 int reg_save_count = 0;
2075 for (regno = GP_REG_LAST; regno >= GP_REG_FIRST; regno--)
2076 if (BITSET_P (mask, regno - GP_REG_FIRST)) reg_save_count += 1;
2077 base_offset = gp_offset - ((reg_save_count - 1) * 4);
2078 base_reg_rtx = iq2000_add_large_offset_to_sp (base_offset);
2081 for (regno = GP_REG_LAST; regno >= GP_REG_FIRST; regno--)
2083 if (BITSET_P (mask, regno - GP_REG_FIRST))
2085 rtx reg_rtx;
2086 rtx mem_rtx
2087 = gen_rtx_MEM (gpr_mode,
2088 gen_rtx_PLUS (Pmode, base_reg_rtx,
2089 GEN_INT (gp_offset - base_offset)));
2091 reg_rtx = gen_rtx_REG (gpr_mode, regno);
2093 if (store_p)
2094 iq2000_emit_frame_related_store (mem_rtx, reg_rtx, gp_offset);
2095 else
2097 emit_move_insn (reg_rtx, mem_rtx);
2099 gp_offset -= GET_MODE_SIZE (gpr_mode);
2104 /* Expand the prologue into a bunch of separate insns. */
2106 void
2107 iq2000_expand_prologue (void)
2109 int regno;
2110 HOST_WIDE_INT tsize;
2111 int last_arg_is_vararg_marker = 0;
2112 tree fndecl = current_function_decl;
2113 tree fntype = TREE_TYPE (fndecl);
2114 tree fnargs = DECL_ARGUMENTS (fndecl);
2115 rtx next_arg_reg;
2116 int i;
2117 tree next_arg;
2118 tree cur_arg;
2119 CUMULATIVE_ARGS args_so_far;
2120 int store_args_on_stack = (iq2000_can_use_return_insn ());
2122 /* If struct value address is treated as the first argument. */
2123 if (aggregate_value_p (DECL_RESULT (fndecl), fndecl)
2124 && ! current_function_returns_pcc_struct
2125 && targetm.calls.struct_value_rtx (TREE_TYPE (fndecl), 1) == 0)
2127 tree type = build_pointer_type (fntype);
2128 tree function_result_decl = build_decl (PARM_DECL, NULL_TREE, type);
2130 DECL_ARG_TYPE (function_result_decl) = type;
2131 TREE_CHAIN (function_result_decl) = fnargs;
2132 fnargs = function_result_decl;
2135 /* For arguments passed in registers, find the register number
2136 of the first argument in the variable part of the argument list,
2137 otherwise GP_ARG_LAST+1. Note also if the last argument is
2138 the varargs special argument, and treat it as part of the
2139 variable arguments.
2141 This is only needed if store_args_on_stack is true. */
2142 INIT_CUMULATIVE_ARGS (args_so_far, fntype, NULL_RTX, 0, 0);
2143 regno = GP_ARG_FIRST;
2145 for (cur_arg = fnargs; cur_arg != 0; cur_arg = next_arg)
2147 tree passed_type = DECL_ARG_TYPE (cur_arg);
2148 enum machine_mode passed_mode = TYPE_MODE (passed_type);
2149 rtx entry_parm;
2151 if (TREE_ADDRESSABLE (passed_type))
2153 passed_type = build_pointer_type (passed_type);
2154 passed_mode = Pmode;
2157 entry_parm = FUNCTION_ARG (args_so_far, passed_mode, passed_type, 1);
2159 FUNCTION_ARG_ADVANCE (args_so_far, passed_mode, passed_type, 1);
2160 next_arg = TREE_CHAIN (cur_arg);
2162 if (entry_parm && store_args_on_stack)
2164 if (next_arg == 0
2165 && DECL_NAME (cur_arg)
2166 && ((0 == strcmp (IDENTIFIER_POINTER (DECL_NAME (cur_arg)),
2167 "__builtin_va_alist"))
2168 || (0 == strcmp (IDENTIFIER_POINTER (DECL_NAME (cur_arg)),
2169 "va_alist"))))
2171 last_arg_is_vararg_marker = 1;
2172 break;
2174 else
2176 int words;
2178 if (GET_CODE (entry_parm) != REG)
2179 abort ();
2181 /* Passed in a register, so will get homed automatically. */
2182 if (GET_MODE (entry_parm) == BLKmode)
2183 words = (int_size_in_bytes (passed_type) + 3) / 4;
2184 else
2185 words = (GET_MODE_SIZE (GET_MODE (entry_parm)) + 3) / 4;
2187 regno = REGNO (entry_parm) + words - 1;
2190 else
2192 regno = GP_ARG_LAST+1;
2193 break;
2197 /* In order to pass small structures by value in registers we need to
2198 shift the value into the high part of the register.
2199 Function_arg has encoded a PARALLEL rtx, holding a vector of
2200 adjustments to be made as the next_arg_reg variable, so we split up the
2201 insns, and emit them separately. */
2202 next_arg_reg = FUNCTION_ARG (args_so_far, VOIDmode, void_type_node, 1);
2203 if (next_arg_reg != 0 && GET_CODE (next_arg_reg) == PARALLEL)
2205 rtvec adjust = XVEC (next_arg_reg, 0);
2206 int num = GET_NUM_ELEM (adjust);
2208 for (i = 0; i < num; i++)
2210 rtx insn, pattern;
2212 pattern = RTVEC_ELT (adjust, i);
2213 if (GET_CODE (pattern) != SET
2214 || GET_CODE (SET_SRC (pattern)) != ASHIFT)
2215 abort_with_insn (pattern, "Insn is not a shift");
2216 PUT_CODE (SET_SRC (pattern), ASHIFTRT);
2218 insn = emit_insn (pattern);
2220 /* Global life information isn't valid at this point, so we
2221 can't check whether these shifts are actually used. Mark
2222 them MAYBE_DEAD so that flow2 will remove them, and not
2223 complain about dead code in the prologue. */
2224 REG_NOTES(insn) = gen_rtx_EXPR_LIST (REG_MAYBE_DEAD, NULL_RTX,
2225 REG_NOTES (insn));
2229 tsize = compute_frame_size (get_frame_size ());
2231 /* If this function is a varargs function, store any registers that
2232 would normally hold arguments ($4 - $7) on the stack. */
2233 if (store_args_on_stack
2234 && ((TYPE_ARG_TYPES (fntype) != 0
2235 && (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
2236 != void_type_node))
2237 || last_arg_is_vararg_marker))
2239 int offset = (regno - GP_ARG_FIRST) * UNITS_PER_WORD;
2240 rtx ptr = stack_pointer_rtx;
2242 for (; regno <= GP_ARG_LAST; regno++)
2244 if (offset != 0)
2245 ptr = gen_rtx_PLUS (Pmode, stack_pointer_rtx, GEN_INT (offset));
2246 emit_move_insn (gen_rtx_MEM (gpr_mode, ptr),
2247 gen_rtx_REG (gpr_mode, regno));
2249 offset += GET_MODE_SIZE (gpr_mode);
2253 if (tsize > 0)
2255 rtx tsize_rtx = GEN_INT (tsize);
2256 rtx adjustment_rtx, insn, dwarf_pattern;
2258 if (tsize > 32767)
2260 adjustment_rtx = gen_rtx_REG (Pmode, IQ2000_TEMP1_REGNUM);
2261 emit_move_insn (adjustment_rtx, tsize_rtx);
2263 else
2264 adjustment_rtx = tsize_rtx;
2266 insn = emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
2267 adjustment_rtx));
2269 dwarf_pattern = gen_rtx_SET (Pmode, stack_pointer_rtx,
2270 plus_constant (stack_pointer_rtx, -tsize));
2272 iq2000_annotate_frame_insn (insn, dwarf_pattern);
2274 save_restore_insns (1);
2276 if (frame_pointer_needed)
2278 rtx insn = 0;
2280 insn = emit_insn (gen_movsi (hard_frame_pointer_rtx,
2281 stack_pointer_rtx));
2283 if (insn)
2284 RTX_FRAME_RELATED_P (insn) = 1;
2288 emit_insn (gen_blockage ());
2291 /* Expand the epilogue into a bunch of separate insns. */
2293 void
2294 iq2000_expand_epilogue (void)
2296 HOST_WIDE_INT tsize = cfun->machine->total_size;
2297 rtx tsize_rtx = GEN_INT (tsize);
2298 rtx tmp_rtx = (rtx)0;
2300 if (iq2000_can_use_return_insn ())
2302 emit_jump_insn (gen_return ());
2303 return;
2306 if (tsize > 32767)
2308 tmp_rtx = gen_rtx_REG (Pmode, IQ2000_TEMP1_REGNUM);
2309 emit_move_insn (tmp_rtx, tsize_rtx);
2310 tsize_rtx = tmp_rtx;
2313 if (tsize > 0)
2315 if (frame_pointer_needed)
2317 emit_insn (gen_blockage ());
2319 emit_insn (gen_movsi (stack_pointer_rtx, hard_frame_pointer_rtx));
2322 save_restore_insns (0);
2324 if (current_function_calls_eh_return)
2326 rtx eh_ofs = EH_RETURN_STACKADJ_RTX;
2327 emit_insn (gen_addsi3 (eh_ofs, eh_ofs, tsize_rtx));
2328 tsize_rtx = eh_ofs;
2331 emit_insn (gen_blockage ());
2333 if (tsize != 0 || current_function_calls_eh_return)
2335 emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx,
2336 tsize_rtx));
2340 if (current_function_calls_eh_return)
2342 /* Perform the additional bump for __throw. */
2343 emit_move_insn (gen_rtx_REG (Pmode, HARD_FRAME_POINTER_REGNUM),
2344 stack_pointer_rtx);
2345 emit_insn (gen_rtx_USE (VOIDmode, gen_rtx_REG (Pmode,
2346 HARD_FRAME_POINTER_REGNUM)));
2347 emit_jump_insn (gen_eh_return_internal ());
2349 else
2350 emit_jump_insn (gen_return_internal (gen_rtx_REG (Pmode,
2351 GP_REG_FIRST + 31)));
2354 void
2355 iq2000_expand_eh_return (rtx address)
2357 HOST_WIDE_INT gp_offset = cfun->machine->gp_sp_offset;
2358 rtx scratch;
2360 scratch = plus_constant (stack_pointer_rtx, gp_offset);
2361 emit_move_insn (gen_rtx_MEM (GET_MODE (address), scratch), address);
2364 /* Return nonzero if this function is known to have a null epilogue.
2365 This allows the optimizer to omit jumps to jumps if no stack
2366 was created. */
2369 iq2000_can_use_return_insn (void)
2371 if (! reload_completed)
2372 return 0;
2374 if (regs_ever_live[31] || profile_flag)
2375 return 0;
2377 if (cfun->machine->initialized)
2378 return cfun->machine->total_size == 0;
2380 return compute_frame_size (get_frame_size ()) == 0;
2383 /* Returns nonzero if X contains a SYMBOL_REF. */
2385 static int
2386 symbolic_expression_p (rtx x)
2388 if (GET_CODE (x) == SYMBOL_REF)
2389 return 1;
2391 if (GET_CODE (x) == CONST)
2392 return symbolic_expression_p (XEXP (x, 0));
2394 if (UNARY_P (x))
2395 return symbolic_expression_p (XEXP (x, 0));
2397 if (ARITHMETIC_P (x))
2398 return (symbolic_expression_p (XEXP (x, 0))
2399 || symbolic_expression_p (XEXP (x, 1)));
2401 return 0;
2404 /* Choose the section to use for the constant rtx expression X that has
2405 mode MODE. */
2407 static void
2408 iq2000_select_rtx_section (enum machine_mode mode, rtx x ATTRIBUTE_UNUSED,
2409 unsigned HOST_WIDE_INT align)
2411 /* For embedded applications, always put constants in read-only data,
2412 in order to reduce RAM usage. */
2413 /* For embedded applications, always put constants in read-only data,
2414 in order to reduce RAM usage. */
2415 mergeable_constant_section (mode, align, 0);
2418 /* Choose the section to use for DECL. RELOC is true if its value contains
2419 any relocatable expression.
2421 Some of the logic used here needs to be replicated in
2422 ENCODE_SECTION_INFO in iq2000.h so that references to these symbols
2423 are done correctly. */
2425 static void
2426 iq2000_select_section (tree decl, int reloc ATTRIBUTE_UNUSED,
2427 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED)
2429 if (TARGET_EMBEDDED_DATA)
2431 /* For embedded applications, always put an object in read-only data
2432 if possible, in order to reduce RAM usage. */
2433 if ((TREE_CODE (decl) == VAR_DECL
2434 && TREE_READONLY (decl) && !TREE_SIDE_EFFECTS (decl)
2435 && DECL_INITIAL (decl)
2436 && (DECL_INITIAL (decl) == error_mark_node
2437 || TREE_CONSTANT (DECL_INITIAL (decl))))
2438 /* Deal with calls from output_constant_def_contents. */
2439 || TREE_CODE (decl) != VAR_DECL)
2440 readonly_data_section ();
2441 else
2442 data_section ();
2444 else
2446 /* For hosted applications, always put an object in small data if
2447 possible, as this gives the best performance. */
2448 if ((TREE_CODE (decl) == VAR_DECL
2449 && TREE_READONLY (decl) && !TREE_SIDE_EFFECTS (decl)
2450 && DECL_INITIAL (decl)
2451 && (DECL_INITIAL (decl) == error_mark_node
2452 || TREE_CONSTANT (DECL_INITIAL (decl))))
2453 /* Deal with calls from output_constant_def_contents. */
2454 || TREE_CODE (decl) != VAR_DECL)
2455 readonly_data_section ();
2456 else
2457 data_section ();
2460 /* Return register to use for a function return value with VALTYPE for function
2461 FUNC. */
2464 iq2000_function_value (tree valtype, tree func ATTRIBUTE_UNUSED)
2466 int reg = GP_RETURN;
2467 enum machine_mode mode = TYPE_MODE (valtype);
2468 int unsignedp = TYPE_UNSIGNED (valtype);
2470 /* Since we define TARGET_PROMOTE_FUNCTION_RETURN that returns true,
2471 we must promote the mode just as PROMOTE_MODE does. */
2472 mode = promote_mode (valtype, mode, &unsignedp, 1);
2474 return gen_rtx_REG (mode, reg);
2477 /* Return true when an argument must be passed by reference. */
2479 static bool
2480 iq2000_pass_by_reference (CUMULATIVE_ARGS *cum, enum machine_mode mode,
2481 tree type, bool named ATTRIBUTE_UNUSED)
2483 int size;
2485 /* We must pass by reference if we would be both passing in registers
2486 and the stack. This is because any subsequent partial arg would be
2487 handled incorrectly in this case. */
2488 if (cum && targetm.calls.must_pass_in_stack (mode, type))
2490 /* Don't pass the actual CUM to FUNCTION_ARG, because we would
2491 get double copies of any offsets generated for small structs
2492 passed in registers. */
2493 CUMULATIVE_ARGS temp;
2495 temp = *cum;
2496 if (FUNCTION_ARG (temp, mode, type, named) != 0)
2497 return 1;
2500 if (type == NULL_TREE || mode == DImode || mode == DFmode)
2501 return 0;
2503 size = int_size_in_bytes (type);
2504 return size == -1 || size > UNITS_PER_WORD;
2507 /* Return the length of INSN. LENGTH is the initial length computed by
2508 attributes in the machine-description file. */
2511 iq2000_adjust_insn_length (rtx insn, int length)
2513 /* A unconditional jump has an unfilled delay slot if it is not part
2514 of a sequence. A conditional jump normally has a delay slot. */
2515 if (simplejump_p (insn)
2516 || ( (GET_CODE (insn) == JUMP_INSN
2517 || GET_CODE (insn) == CALL_INSN)))
2518 length += 4;
2520 return length;
2523 /* Output assembly instructions to perform a conditional branch.
2525 INSN is the branch instruction. OPERANDS[0] is the condition.
2526 OPERANDS[1] is the target of the branch. OPERANDS[2] is the target
2527 of the first operand to the condition. If TWO_OPERANDS_P is
2528 nonzero the comparison takes two operands; OPERANDS[3] will be the
2529 second operand.
2531 If INVERTED_P is nonzero we are to branch if the condition does
2532 not hold. If FLOAT_P is nonzero this is a floating-point comparison.
2534 LENGTH is the length (in bytes) of the sequence we are to generate.
2535 That tells us whether to generate a simple conditional branch, or a
2536 reversed conditional branch around a `jr' instruction. */
2538 char *
2539 iq2000_output_conditional_branch (rtx insn, rtx * operands, int two_operands_p,
2540 int float_p, int inverted_p, int length)
2542 static char buffer[200];
2543 /* The kind of comparison we are doing. */
2544 enum rtx_code code = GET_CODE (operands[0]);
2545 /* Nonzero if the opcode for the comparison needs a `z' indicating
2546 that it is a comparison against zero. */
2547 int need_z_p;
2548 /* A string to use in the assembly output to represent the first
2549 operand. */
2550 const char *op1 = "%z2";
2551 /* A string to use in the assembly output to represent the second
2552 operand. Use the hard-wired zero register if there's no second
2553 operand. */
2554 const char *op2 = (two_operands_p ? ",%z3" : ",%.");
2555 /* The operand-printing string for the comparison. */
2556 const char *comp = (float_p ? "%F0" : "%C0");
2557 /* The operand-printing string for the inverted comparison. */
2558 const char *inverted_comp = (float_p ? "%W0" : "%N0");
2560 /* Likely variants of each branch instruction annul the instruction
2561 in the delay slot if the branch is not taken. */
2562 iq2000_branch_likely = (final_sequence && INSN_ANNULLED_BRANCH_P (insn));
2564 if (!two_operands_p)
2566 /* To compute whether than A > B, for example, we normally
2567 subtract B from A and then look at the sign bit. But, if we
2568 are doing an unsigned comparison, and B is zero, we don't
2569 have to do the subtraction. Instead, we can just check to
2570 see if A is nonzero. Thus, we change the CODE here to
2571 reflect the simpler comparison operation. */
2572 switch (code)
2574 case GTU:
2575 code = NE;
2576 break;
2578 case LEU:
2579 code = EQ;
2580 break;
2582 case GEU:
2583 /* A condition which will always be true. */
2584 code = EQ;
2585 op1 = "%.";
2586 break;
2588 case LTU:
2589 /* A condition which will always be false. */
2590 code = NE;
2591 op1 = "%.";
2592 break;
2594 default:
2595 /* Not a special case. */
2596 break;
2600 /* Relative comparisons are always done against zero. But
2601 equality comparisons are done between two operands, and therefore
2602 do not require a `z' in the assembly language output. */
2603 need_z_p = (!float_p && code != EQ && code != NE);
2604 /* For comparisons against zero, the zero is not provided
2605 explicitly. */
2606 if (need_z_p)
2607 op2 = "";
2609 /* Begin by terminating the buffer. That way we can always use
2610 strcat to add to it. */
2611 buffer[0] = '\0';
2613 switch (length)
2615 case 4:
2616 case 8:
2617 /* Just a simple conditional branch. */
2618 if (float_p)
2619 sprintf (buffer, "b%s%%?\t%%Z2%%1",
2620 inverted_p ? inverted_comp : comp);
2621 else
2622 sprintf (buffer, "b%s%s%%?\t%s%s,%%1",
2623 inverted_p ? inverted_comp : comp,
2624 need_z_p ? "z" : "",
2625 op1,
2626 op2);
2627 return buffer;
2629 case 12:
2630 case 16:
2632 /* Generate a reversed conditional branch around ` j'
2633 instruction:
2635 .set noreorder
2636 .set nomacro
2637 bc l
2639 j target
2640 .set macro
2641 .set reorder
2644 Because we have to jump four bytes *past* the following
2645 instruction if this branch was annulled, we can't just use
2646 a label, as in the picture above; there's no way to put the
2647 label after the next instruction, as the assembler does not
2648 accept `.L+4' as the target of a branch. (We can't just
2649 wait until the next instruction is output; it might be a
2650 macro and take up more than four bytes. Once again, we see
2651 why we want to eliminate macros.)
2653 If the branch is annulled, we jump four more bytes that we
2654 would otherwise; that way we skip the annulled instruction
2655 in the delay slot. */
2657 const char *target
2658 = ((iq2000_branch_likely || length == 16) ? ".+16" : ".+12");
2659 char *c;
2661 c = strchr (buffer, '\0');
2662 /* Generate the reversed comparison. This takes four
2663 bytes. */
2664 if (float_p)
2665 sprintf (c, "b%s\t%%Z2%s",
2666 inverted_p ? comp : inverted_comp,
2667 target);
2668 else
2669 sprintf (c, "b%s%s\t%s%s,%s",
2670 inverted_p ? comp : inverted_comp,
2671 need_z_p ? "z" : "",
2672 op1,
2673 op2,
2674 target);
2675 strcat (c, "\n\tnop\n\tj\t%1");
2676 if (length == 16)
2677 /* The delay slot was unfilled. Since we're inside
2678 .noreorder, the assembler will not fill in the NOP for
2679 us, so we must do it ourselves. */
2680 strcat (buffer, "\n\tnop");
2681 return buffer;
2684 default:
2685 abort ();
2688 /* NOTREACHED */
2689 return 0;
2692 #define def_builtin(NAME, TYPE, CODE) \
2693 lang_hooks.builtin_function ((NAME), (TYPE), (CODE), BUILT_IN_MD, \
2694 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 %qd 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"