Turn HARD_REGNO_MODE_OK into a target hook
[official-gcc.git] / gcc / config / iq2000 / iq2000.c
blobb57f4184db6cf6f1ee745efe0e6588bb75d71dd9
1 /* Subroutines used for code generation on Vitesse IQ2000 processors
2 Copyright (C) 2003-2017 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 3, 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 COPYING3. If not see
18 <http://www.gnu.org/licenses/>. */
20 #include "config.h"
21 #include "system.h"
22 #include "coretypes.h"
23 #include "backend.h"
24 #include "target.h"
25 #include "rtl.h"
26 #include "tree.h"
27 #include "stringpool.h"
28 #include "attribs.h"
29 #include "df.h"
30 #include "memmodel.h"
31 #include "tm_p.h"
32 #include "optabs.h"
33 #include "regs.h"
34 #include "emit-rtl.h"
35 #include "recog.h"
36 #include "diagnostic-core.h"
37 #include "stor-layout.h"
38 #include "calls.h"
39 #include "varasm.h"
40 #include "output.h"
41 #include "insn-attr.h"
42 #include "explow.h"
43 #include "expr.h"
44 #include "langhooks.h"
45 #include "builtins.h"
47 /* This file should be included last. */
48 #include "target-def.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 GTY(()) machine_function
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 iq2000_print_operand. */
113 static char iq2000_print_operand_punct[256];
115 /* Which instruction set architecture to use. */
116 int iq2000_isa;
118 /* Local variables. */
120 /* The next branch instruction is a branch likely, not branch normal. */
121 static int iq2000_branch_likely;
123 /* Count of delay slots and how many are filled. */
124 static int dslots_load_total;
125 static int dslots_load_filled;
126 static int dslots_jump_total;
128 /* # of nops needed by previous insn. */
129 static int dslots_number_nops;
131 /* Number of 1/2/3 word references to data items (i.e., not jal's). */
132 static int num_refs[3];
134 /* Registers to check for load delay. */
135 static rtx iq2000_load_reg;
136 static rtx iq2000_load_reg2;
137 static rtx iq2000_load_reg3;
138 static rtx iq2000_load_reg4;
140 /* Mode used for saving/restoring general purpose registers. */
141 static machine_mode gpr_mode;
144 /* Initialize the GCC target structure. */
145 static struct machine_function* iq2000_init_machine_status (void);
146 static void iq2000_option_override (void);
147 static section *iq2000_select_rtx_section (machine_mode, rtx,
148 unsigned HOST_WIDE_INT);
149 static void iq2000_init_builtins (void);
150 static rtx iq2000_expand_builtin (tree, rtx, rtx, machine_mode, int);
151 static bool iq2000_return_in_memory (const_tree, const_tree);
152 static void iq2000_setup_incoming_varargs (cumulative_args_t,
153 machine_mode, tree, int *,
154 int);
155 static bool iq2000_rtx_costs (rtx, machine_mode, int, int, int *, bool);
156 static int iq2000_address_cost (rtx, machine_mode, addr_space_t,
157 bool);
158 static section *iq2000_select_section (tree, int, unsigned HOST_WIDE_INT);
159 static rtx iq2000_legitimize_address (rtx, rtx, machine_mode);
160 static bool iq2000_pass_by_reference (cumulative_args_t, machine_mode,
161 const_tree, bool);
162 static int iq2000_arg_partial_bytes (cumulative_args_t, machine_mode,
163 tree, bool);
164 static rtx iq2000_function_arg (cumulative_args_t,
165 machine_mode, const_tree, bool);
166 static void iq2000_function_arg_advance (cumulative_args_t,
167 machine_mode, const_tree, bool);
168 static unsigned int iq2000_function_arg_boundary (machine_mode,
169 const_tree);
170 static void iq2000_va_start (tree, rtx);
171 static bool iq2000_legitimate_address_p (machine_mode, rtx, bool);
172 static bool iq2000_can_eliminate (const int, const int);
173 static void iq2000_asm_trampoline_template (FILE *);
174 static void iq2000_trampoline_init (rtx, tree, rtx);
175 static rtx iq2000_function_value (const_tree, const_tree, bool);
176 static rtx iq2000_libcall_value (machine_mode, const_rtx);
177 static void iq2000_print_operand (FILE *, rtx, int);
178 static void iq2000_print_operand_address (FILE *, machine_mode, rtx);
179 static bool iq2000_print_operand_punct_valid_p (unsigned char code);
180 static bool iq2000_hard_regno_mode_ok (unsigned int, machine_mode);
182 #undef TARGET_INIT_BUILTINS
183 #define TARGET_INIT_BUILTINS iq2000_init_builtins
184 #undef TARGET_EXPAND_BUILTIN
185 #define TARGET_EXPAND_BUILTIN iq2000_expand_builtin
186 #undef TARGET_ASM_SELECT_RTX_SECTION
187 #define TARGET_ASM_SELECT_RTX_SECTION iq2000_select_rtx_section
188 #undef TARGET_OPTION_OVERRIDE
189 #define TARGET_OPTION_OVERRIDE iq2000_option_override
190 #undef TARGET_RTX_COSTS
191 #define TARGET_RTX_COSTS iq2000_rtx_costs
192 #undef TARGET_ADDRESS_COST
193 #define TARGET_ADDRESS_COST iq2000_address_cost
194 #undef TARGET_ASM_SELECT_SECTION
195 #define TARGET_ASM_SELECT_SECTION iq2000_select_section
197 #undef TARGET_LEGITIMIZE_ADDRESS
198 #define TARGET_LEGITIMIZE_ADDRESS iq2000_legitimize_address
200 /* The assembler supports switchable .bss sections, but
201 iq2000_select_section doesn't yet make use of them. */
202 #undef TARGET_HAVE_SWITCHABLE_BSS_SECTIONS
203 #define TARGET_HAVE_SWITCHABLE_BSS_SECTIONS false
205 #undef TARGET_PRINT_OPERAND
206 #define TARGET_PRINT_OPERAND iq2000_print_operand
207 #undef TARGET_PRINT_OPERAND_ADDRESS
208 #define TARGET_PRINT_OPERAND_ADDRESS iq2000_print_operand_address
209 #undef TARGET_PRINT_OPERAND_PUNCT_VALID_P
210 #define TARGET_PRINT_OPERAND_PUNCT_VALID_P iq2000_print_operand_punct_valid_p
212 #undef TARGET_PROMOTE_FUNCTION_MODE
213 #define TARGET_PROMOTE_FUNCTION_MODE default_promote_function_mode_always_promote
214 #undef TARGET_PROMOTE_PROTOTYPES
215 #define TARGET_PROMOTE_PROTOTYPES hook_bool_const_tree_true
217 #undef TARGET_FUNCTION_VALUE
218 #define TARGET_FUNCTION_VALUE iq2000_function_value
219 #undef TARGET_LIBCALL_VALUE
220 #define TARGET_LIBCALL_VALUE iq2000_libcall_value
221 #undef TARGET_RETURN_IN_MEMORY
222 #define TARGET_RETURN_IN_MEMORY iq2000_return_in_memory
223 #undef TARGET_PASS_BY_REFERENCE
224 #define TARGET_PASS_BY_REFERENCE iq2000_pass_by_reference
225 #undef TARGET_CALLEE_COPIES
226 #define TARGET_CALLEE_COPIES hook_callee_copies_named
227 #undef TARGET_ARG_PARTIAL_BYTES
228 #define TARGET_ARG_PARTIAL_BYTES iq2000_arg_partial_bytes
229 #undef TARGET_FUNCTION_ARG
230 #define TARGET_FUNCTION_ARG iq2000_function_arg
231 #undef TARGET_FUNCTION_ARG_ADVANCE
232 #define TARGET_FUNCTION_ARG_ADVANCE iq2000_function_arg_advance
233 #undef TARGET_FUNCTION_ARG_BOUNDARY
234 #define TARGET_FUNCTION_ARG_BOUNDARY iq2000_function_arg_boundary
236 #undef TARGET_SETUP_INCOMING_VARARGS
237 #define TARGET_SETUP_INCOMING_VARARGS iq2000_setup_incoming_varargs
238 #undef TARGET_STRICT_ARGUMENT_NAMING
239 #define TARGET_STRICT_ARGUMENT_NAMING hook_bool_CUMULATIVE_ARGS_true
241 #undef TARGET_EXPAND_BUILTIN_VA_START
242 #define TARGET_EXPAND_BUILTIN_VA_START iq2000_va_start
244 #undef TARGET_LRA_P
245 #define TARGET_LRA_P hook_bool_void_false
247 #undef TARGET_LEGITIMATE_ADDRESS_P
248 #define TARGET_LEGITIMATE_ADDRESS_P iq2000_legitimate_address_p
250 #undef TARGET_CAN_ELIMINATE
251 #define TARGET_CAN_ELIMINATE iq2000_can_eliminate
253 #undef TARGET_ASM_TRAMPOLINE_TEMPLATE
254 #define TARGET_ASM_TRAMPOLINE_TEMPLATE iq2000_asm_trampoline_template
255 #undef TARGET_TRAMPOLINE_INIT
256 #define TARGET_TRAMPOLINE_INIT iq2000_trampoline_init
258 #undef TARGET_HARD_REGNO_MODE_OK
259 #define TARGET_HARD_REGNO_MODE_OK iq2000_hard_regno_mode_ok
261 struct gcc_target targetm = TARGET_INITIALIZER;
263 /* Return nonzero if we split the address into high and low parts. */
266 iq2000_check_split (rtx address, machine_mode mode)
268 /* This is the same check used in simple_memory_operand.
269 We use it here because LO_SUM is not offsettable. */
270 if (GET_MODE_SIZE (mode) > (unsigned) UNITS_PER_WORD)
271 return 0;
273 if ((GET_CODE (address) == SYMBOL_REF)
274 || (GET_CODE (address) == CONST
275 && GET_CODE (XEXP (XEXP (address, 0), 0)) == SYMBOL_REF)
276 || GET_CODE (address) == LABEL_REF)
277 return 1;
279 return 0;
282 /* Return nonzero if REG is valid for MODE. */
285 iq2000_reg_mode_ok_for_base_p (rtx reg,
286 machine_mode mode ATTRIBUTE_UNUSED,
287 int strict)
289 return (strict
290 ? REGNO_MODE_OK_FOR_BASE_P (REGNO (reg), mode)
291 : GP_REG_OR_PSEUDO_NONSTRICT_P (REGNO (reg), mode));
294 /* Return a nonzero value if XINSN is a legitimate address for a
295 memory operand of the indicated MODE. STRICT is nonzero if this
296 function is called during reload. */
298 bool
299 iq2000_legitimate_address_p (machine_mode mode, rtx xinsn, bool strict)
301 if (TARGET_DEBUG_A_MODE)
303 GO_PRINTF2 ("\n========== legitimate_address_p, %sstrict\n",
304 strict ? "" : "not ");
305 GO_DEBUG_RTX (xinsn);
308 /* Check for constant before stripping off SUBREG, so that we don't
309 accept (subreg (const_int)) which will fail to reload. */
310 if (CONSTANT_ADDRESS_P (xinsn)
311 && ! (iq2000_check_split (xinsn, mode))
312 && ! (GET_CODE (xinsn) == CONST_INT && ! SMALL_INT (xinsn)))
313 return 1;
315 while (GET_CODE (xinsn) == SUBREG)
316 xinsn = SUBREG_REG (xinsn);
318 if (GET_CODE (xinsn) == REG
319 && iq2000_reg_mode_ok_for_base_p (xinsn, mode, strict))
320 return 1;
322 if (GET_CODE (xinsn) == LO_SUM)
324 rtx xlow0 = XEXP (xinsn, 0);
325 rtx xlow1 = XEXP (xinsn, 1);
327 while (GET_CODE (xlow0) == SUBREG)
328 xlow0 = SUBREG_REG (xlow0);
329 if (GET_CODE (xlow0) == REG
330 && iq2000_reg_mode_ok_for_base_p (xlow0, mode, strict)
331 && iq2000_check_split (xlow1, mode))
332 return 1;
335 if (GET_CODE (xinsn) == PLUS)
337 rtx xplus0 = XEXP (xinsn, 0);
338 rtx xplus1 = XEXP (xinsn, 1);
339 enum rtx_code code0;
340 enum rtx_code code1;
342 while (GET_CODE (xplus0) == SUBREG)
343 xplus0 = SUBREG_REG (xplus0);
344 code0 = GET_CODE (xplus0);
346 while (GET_CODE (xplus1) == SUBREG)
347 xplus1 = SUBREG_REG (xplus1);
348 code1 = GET_CODE (xplus1);
350 if (code0 == REG
351 && iq2000_reg_mode_ok_for_base_p (xplus0, mode, strict))
353 if (code1 == CONST_INT && SMALL_INT (xplus1)
354 && SMALL_INT_UNSIGNED (xplus1) /* No negative offsets */)
355 return 1;
359 if (TARGET_DEBUG_A_MODE)
360 GO_PRINTF ("Not a machine_mode mode, legitimate address\n");
362 /* The address was not legitimate. */
363 return 0;
366 /* Returns an operand string for the given instruction's delay slot,
367 after updating filled delay slot statistics.
369 We assume that operands[0] is the target register that is set.
371 In order to check the next insn, most of this functionality is moved
372 to FINAL_PRESCAN_INSN, and we just set the global variables that
373 it needs. */
375 const char *
376 iq2000_fill_delay_slot (const char *ret, enum delay_type type, rtx operands[],
377 rtx_insn *cur_insn)
379 rtx set_reg;
380 machine_mode mode;
381 rtx_insn *next_insn = cur_insn ? NEXT_INSN (cur_insn) : NULL;
382 int num_nops;
384 if (type == DELAY_LOAD || type == DELAY_FCMP)
385 num_nops = 1;
387 else
388 num_nops = 0;
390 /* Make sure that we don't put nop's after labels. */
391 next_insn = NEXT_INSN (cur_insn);
392 while (next_insn != 0
393 && (NOTE_P (next_insn) || LABEL_P (next_insn)))
394 next_insn = NEXT_INSN (next_insn);
396 dslots_load_total += num_nops;
397 if (TARGET_DEBUG_C_MODE
398 || type == DELAY_NONE
399 || operands == 0
400 || cur_insn == 0
401 || next_insn == 0
402 || LABEL_P (next_insn)
403 || (set_reg = operands[0]) == 0)
405 dslots_number_nops = 0;
406 iq2000_load_reg = 0;
407 iq2000_load_reg2 = 0;
408 iq2000_load_reg3 = 0;
409 iq2000_load_reg4 = 0;
411 return ret;
414 set_reg = operands[0];
415 if (set_reg == 0)
416 return ret;
418 while (GET_CODE (set_reg) == SUBREG)
419 set_reg = SUBREG_REG (set_reg);
421 mode = GET_MODE (set_reg);
422 dslots_number_nops = num_nops;
423 iq2000_load_reg = set_reg;
424 if (GET_MODE_SIZE (mode)
425 > (unsigned) (UNITS_PER_WORD))
426 iq2000_load_reg2 = gen_rtx_REG (SImode, REGNO (set_reg) + 1);
427 else
428 iq2000_load_reg2 = 0;
430 return ret;
433 /* Determine whether a memory reference takes one (based off of the GP
434 pointer), two (normal), or three (label + reg) instructions, and bump the
435 appropriate counter for -mstats. */
437 static void
438 iq2000_count_memory_refs (rtx op, int num)
440 int additional = 0;
441 int n_words = 0;
442 rtx addr, plus0, plus1;
443 enum rtx_code code0, code1;
444 int looping;
446 if (TARGET_DEBUG_B_MODE)
448 fprintf (stderr, "\n========== iq2000_count_memory_refs:\n");
449 debug_rtx (op);
452 /* Skip MEM if passed, otherwise handle movsi of address. */
453 addr = (GET_CODE (op) != MEM) ? op : XEXP (op, 0);
455 /* Loop, going through the address RTL. */
458 looping = FALSE;
459 switch (GET_CODE (addr))
461 case REG:
462 case CONST_INT:
463 case LO_SUM:
464 break;
466 case PLUS:
467 plus0 = XEXP (addr, 0);
468 plus1 = XEXP (addr, 1);
469 code0 = GET_CODE (plus0);
470 code1 = GET_CODE (plus1);
472 if (code0 == REG)
474 additional++;
475 addr = plus1;
476 looping = 1;
477 continue;
480 if (code0 == CONST_INT)
482 addr = plus1;
483 looping = 1;
484 continue;
487 if (code1 == REG)
489 additional++;
490 addr = plus0;
491 looping = 1;
492 continue;
495 if (code1 == CONST_INT)
497 addr = plus0;
498 looping = 1;
499 continue;
502 if (code0 == SYMBOL_REF || code0 == LABEL_REF || code0 == CONST)
504 addr = plus0;
505 looping = 1;
506 continue;
509 if (code1 == SYMBOL_REF || code1 == LABEL_REF || code1 == CONST)
511 addr = plus1;
512 looping = 1;
513 continue;
516 break;
518 case LABEL_REF:
519 n_words = 2; /* Always 2 words. */
520 break;
522 case CONST:
523 addr = XEXP (addr, 0);
524 looping = 1;
525 continue;
527 case SYMBOL_REF:
528 n_words = SYMBOL_REF_FLAG (addr) ? 1 : 2;
529 break;
531 default:
532 break;
535 while (looping);
537 if (n_words == 0)
538 return;
540 n_words += additional;
541 if (n_words > 3)
542 n_words = 3;
544 num_refs[n_words-1] += num;
547 /* Abort after printing out a specific insn. */
549 static void
550 abort_with_insn (rtx insn, const char * reason)
552 error (reason);
553 debug_rtx (insn);
554 fancy_abort (__FILE__, __LINE__, __FUNCTION__);
557 /* Return the appropriate instructions to move one operand to another. */
559 const char *
560 iq2000_move_1word (rtx operands[], rtx_insn *insn, int unsignedp)
562 const char *ret = 0;
563 rtx op0 = operands[0];
564 rtx op1 = operands[1];
565 enum rtx_code code0 = GET_CODE (op0);
566 enum rtx_code code1 = GET_CODE (op1);
567 machine_mode mode = GET_MODE (op0);
568 int subreg_offset0 = 0;
569 int subreg_offset1 = 0;
570 enum delay_type delay = DELAY_NONE;
572 while (code0 == SUBREG)
574 subreg_offset0 += subreg_regno_offset (REGNO (SUBREG_REG (op0)),
575 GET_MODE (SUBREG_REG (op0)),
576 SUBREG_BYTE (op0),
577 GET_MODE (op0));
578 op0 = SUBREG_REG (op0);
579 code0 = GET_CODE (op0);
582 while (code1 == SUBREG)
584 subreg_offset1 += subreg_regno_offset (REGNO (SUBREG_REG (op1)),
585 GET_MODE (SUBREG_REG (op1)),
586 SUBREG_BYTE (op1),
587 GET_MODE (op1));
588 op1 = SUBREG_REG (op1);
589 code1 = GET_CODE (op1);
592 /* For our purposes, a condition code mode is the same as SImode. */
593 if (mode == CCmode)
594 mode = SImode;
596 if (code0 == REG)
598 int regno0 = REGNO (op0) + subreg_offset0;
600 if (code1 == REG)
602 int regno1 = REGNO (op1) + subreg_offset1;
604 /* Do not do anything for assigning a register to itself */
605 if (regno0 == regno1)
606 ret = "";
608 else if (GP_REG_P (regno0))
610 if (GP_REG_P (regno1))
611 ret = "or\t%0,%%0,%1";
616 else if (code1 == MEM)
618 delay = DELAY_LOAD;
620 if (TARGET_STATS)
621 iq2000_count_memory_refs (op1, 1);
623 if (GP_REG_P (regno0))
625 /* For loads, use the mode of the memory item, instead of the
626 target, so zero/sign extend can use this code as well. */
627 switch (GET_MODE (op1))
629 default:
630 break;
631 case E_SFmode:
632 ret = "lw\t%0,%1";
633 break;
634 case E_SImode:
635 case E_CCmode:
636 ret = "lw\t%0,%1";
637 break;
638 case E_HImode:
639 ret = (unsignedp) ? "lhu\t%0,%1" : "lh\t%0,%1";
640 break;
641 case E_QImode:
642 ret = (unsignedp) ? "lbu\t%0,%1" : "lb\t%0,%1";
643 break;
648 else if (code1 == CONST_INT
649 || (code1 == CONST_DOUBLE
650 && GET_MODE (op1) == VOIDmode))
652 if (code1 == CONST_DOUBLE)
654 /* This can happen when storing constants into long long
655 bitfields. Just store the least significant word of
656 the value. */
657 operands[1] = op1 = GEN_INT (CONST_DOUBLE_LOW (op1));
660 if (INTVAL (op1) == 0)
662 if (GP_REG_P (regno0))
663 ret = "or\t%0,%%0,%z1";
665 else if (GP_REG_P (regno0))
667 if (SMALL_INT_UNSIGNED (op1))
668 ret = "ori\t%0,%%0,%x1\t\t\t# %1";
669 else if (SMALL_INT (op1))
670 ret = "addiu\t%0,%%0,%1\t\t\t# %1";
671 else
672 ret = "lui\t%0,%X1\t\t\t# %1\n\tori\t%0,%0,%x1";
676 else if (code1 == CONST_DOUBLE && mode == SFmode)
678 if (op1 == CONST0_RTX (SFmode))
680 if (GP_REG_P (regno0))
681 ret = "or\t%0,%%0,%.";
684 else
686 delay = DELAY_LOAD;
687 ret = "li.s\t%0,%1";
691 else if (code1 == LABEL_REF)
693 if (TARGET_STATS)
694 iq2000_count_memory_refs (op1, 1);
696 ret = "la\t%0,%a1";
699 else if (code1 == SYMBOL_REF || code1 == CONST)
701 if (TARGET_STATS)
702 iq2000_count_memory_refs (op1, 1);
704 ret = "la\t%0,%a1";
707 else if (code1 == PLUS)
709 rtx add_op0 = XEXP (op1, 0);
710 rtx add_op1 = XEXP (op1, 1);
712 if (GET_CODE (XEXP (op1, 1)) == REG
713 && GET_CODE (XEXP (op1, 0)) == CONST_INT)
714 add_op0 = XEXP (op1, 1), add_op1 = XEXP (op1, 0);
716 operands[2] = add_op0;
717 operands[3] = add_op1;
718 ret = "add%:\t%0,%2,%3";
721 else if (code1 == HIGH)
723 operands[1] = XEXP (op1, 0);
724 ret = "lui\t%0,%%hi(%1)";
728 else if (code0 == MEM)
730 if (TARGET_STATS)
731 iq2000_count_memory_refs (op0, 1);
733 if (code1 == REG)
735 int regno1 = REGNO (op1) + subreg_offset1;
737 if (GP_REG_P (regno1))
739 switch (mode)
741 case E_SFmode: ret = "sw\t%1,%0"; break;
742 case E_SImode: ret = "sw\t%1,%0"; break;
743 case E_HImode: ret = "sh\t%1,%0"; break;
744 case E_QImode: ret = "sb\t%1,%0"; break;
745 default: break;
750 else if (code1 == CONST_INT && INTVAL (op1) == 0)
752 switch (mode)
754 case E_SFmode: ret = "sw\t%z1,%0"; break;
755 case E_SImode: ret = "sw\t%z1,%0"; break;
756 case E_HImode: ret = "sh\t%z1,%0"; break;
757 case E_QImode: ret = "sb\t%z1,%0"; break;
758 default: break;
762 else if (code1 == CONST_DOUBLE && op1 == CONST0_RTX (mode))
764 switch (mode)
766 case E_SFmode: ret = "sw\t%.,%0"; break;
767 case E_SImode: ret = "sw\t%.,%0"; break;
768 case E_HImode: ret = "sh\t%.,%0"; break;
769 case E_QImode: ret = "sb\t%.,%0"; break;
770 default: break;
775 if (ret == 0)
777 abort_with_insn (insn, "Bad move");
778 return 0;
781 if (delay != DELAY_NONE)
782 return iq2000_fill_delay_slot (ret, delay, operands, insn);
784 return ret;
787 /* Provide the costs of an addressing mode that contains ADDR. */
789 static int
790 iq2000_address_cost (rtx addr, machine_mode mode, addr_space_t as,
791 bool speed)
793 switch (GET_CODE (addr))
795 case LO_SUM:
796 return 1;
798 case LABEL_REF:
799 return 2;
801 case CONST:
803 rtx offset = const0_rtx;
805 addr = eliminate_constant_term (XEXP (addr, 0), & offset);
806 if (GET_CODE (addr) == LABEL_REF)
807 return 2;
809 if (GET_CODE (addr) != SYMBOL_REF)
810 return 4;
812 if (! SMALL_INT (offset))
813 return 2;
816 /* Fall through. */
818 case SYMBOL_REF:
819 return SYMBOL_REF_FLAG (addr) ? 1 : 2;
821 case PLUS:
823 rtx plus0 = XEXP (addr, 0);
824 rtx plus1 = XEXP (addr, 1);
826 if (GET_CODE (plus0) != REG && GET_CODE (plus1) == REG)
827 plus0 = XEXP (addr, 1), plus1 = XEXP (addr, 0);
829 if (GET_CODE (plus0) != REG)
830 break;
832 switch (GET_CODE (plus1))
834 case CONST_INT:
835 return SMALL_INT (plus1) ? 1 : 2;
837 case CONST:
838 case SYMBOL_REF:
839 case LABEL_REF:
840 case HIGH:
841 case LO_SUM:
842 return iq2000_address_cost (plus1, mode, as, speed) + 1;
844 default:
845 break;
849 default:
850 break;
853 return 4;
856 /* Make normal rtx_code into something we can index from an array. */
858 static enum internal_test
859 map_test_to_internal_test (enum rtx_code test_code)
861 enum internal_test test = ITEST_MAX;
863 switch (test_code)
865 case EQ: test = ITEST_EQ; break;
866 case NE: test = ITEST_NE; break;
867 case GT: test = ITEST_GT; break;
868 case GE: test = ITEST_GE; break;
869 case LT: test = ITEST_LT; break;
870 case LE: test = ITEST_LE; break;
871 case GTU: test = ITEST_GTU; break;
872 case GEU: test = ITEST_GEU; break;
873 case LTU: test = ITEST_LTU; break;
874 case LEU: test = ITEST_LEU; break;
875 default: break;
878 return test;
881 /* Generate the code to do a TEST_CODE comparison on two integer values CMP0
882 and CMP1. P_INVERT is NULL or ptr if branch needs to reverse its test.
883 The return value RESULT is:
884 (reg:SI xx) The pseudo register the comparison is in
885 0 No register, generate a simple branch. */
888 gen_int_relational (enum rtx_code test_code, rtx result, rtx cmp0, rtx cmp1,
889 int *p_invert)
891 struct cmp_info
893 enum rtx_code test_code; /* Code to use in instruction (LT vs. LTU). */
894 int const_low; /* Low bound of constant we can accept. */
895 int const_high; /* High bound of constant we can accept. */
896 int const_add; /* Constant to add (convert LE -> LT). */
897 int reverse_regs; /* Reverse registers in test. */
898 int invert_const; /* != 0 if invert value if cmp1 is constant. */
899 int invert_reg; /* != 0 if invert value if cmp1 is register. */
900 int unsignedp; /* != 0 for unsigned comparisons. */
903 static struct cmp_info info[ (int)ITEST_MAX ] =
905 { XOR, 0, 65535, 0, 0, 0, 0, 0 }, /* EQ */
906 { XOR, 0, 65535, 0, 0, 1, 1, 0 }, /* NE */
907 { LT, -32769, 32766, 1, 1, 1, 0, 0 }, /* GT */
908 { LT, -32768, 32767, 0, 0, 1, 1, 0 }, /* GE */
909 { LT, -32768, 32767, 0, 0, 0, 0, 0 }, /* LT */
910 { LT, -32769, 32766, 1, 1, 0, 1, 0 }, /* LE */
911 { LTU, -32769, 32766, 1, 1, 1, 0, 1 }, /* GTU */
912 { LTU, -32768, 32767, 0, 0, 1, 1, 1 }, /* GEU */
913 { LTU, -32768, 32767, 0, 0, 0, 0, 1 }, /* LTU */
914 { LTU, -32769, 32766, 1, 1, 0, 1, 1 }, /* LEU */
917 enum internal_test test;
918 machine_mode mode;
919 struct cmp_info *p_info;
920 int branch_p;
921 int eqne_p;
922 int invert;
923 rtx reg;
924 rtx reg2;
926 test = map_test_to_internal_test (test_code);
927 gcc_assert (test != ITEST_MAX);
929 p_info = &info[(int) test];
930 eqne_p = (p_info->test_code == XOR);
932 mode = GET_MODE (cmp0);
933 if (mode == VOIDmode)
934 mode = GET_MODE (cmp1);
936 /* Eliminate simple branches. */
937 branch_p = (result == 0);
938 if (branch_p)
940 if (GET_CODE (cmp0) == REG || GET_CODE (cmp0) == SUBREG)
942 /* Comparisons against zero are simple branches. */
943 if (GET_CODE (cmp1) == CONST_INT && INTVAL (cmp1) == 0)
944 return 0;
946 /* Test for beq/bne. */
947 if (eqne_p)
948 return 0;
951 /* Allocate a pseudo to calculate the value in. */
952 result = gen_reg_rtx (mode);
955 /* Make sure we can handle any constants given to us. */
956 if (GET_CODE (cmp0) == CONST_INT)
957 cmp0 = force_reg (mode, cmp0);
959 if (GET_CODE (cmp1) == CONST_INT)
961 HOST_WIDE_INT value = INTVAL (cmp1);
963 if (value < p_info->const_low
964 || value > p_info->const_high)
965 cmp1 = force_reg (mode, cmp1);
968 /* See if we need to invert the result. */
969 invert = (GET_CODE (cmp1) == CONST_INT
970 ? p_info->invert_const : p_info->invert_reg);
972 if (p_invert != (int *)0)
974 *p_invert = invert;
975 invert = 0;
978 /* Comparison to constants, may involve adding 1 to change a LT into LE.
979 Comparison between two registers, may involve switching operands. */
980 if (GET_CODE (cmp1) == CONST_INT)
982 if (p_info->const_add != 0)
984 HOST_WIDE_INT new_const = INTVAL (cmp1) + p_info->const_add;
986 /* If modification of cmp1 caused overflow,
987 we would get the wrong answer if we follow the usual path;
988 thus, x > 0xffffffffU would turn into x > 0U. */
989 if ((p_info->unsignedp
990 ? (unsigned HOST_WIDE_INT) new_const >
991 (unsigned HOST_WIDE_INT) INTVAL (cmp1)
992 : new_const > INTVAL (cmp1))
993 != (p_info->const_add > 0))
995 /* This test is always true, but if INVERT is true then
996 the result of the test needs to be inverted so 0 should
997 be returned instead. */
998 emit_move_insn (result, invert ? const0_rtx : const_true_rtx);
999 return result;
1001 else
1002 cmp1 = GEN_INT (new_const);
1006 else if (p_info->reverse_regs)
1008 rtx temp = cmp0;
1009 cmp0 = cmp1;
1010 cmp1 = temp;
1013 if (test == ITEST_NE && GET_CODE (cmp1) == CONST_INT && INTVAL (cmp1) == 0)
1014 reg = cmp0;
1015 else
1017 reg = (invert || eqne_p) ? gen_reg_rtx (mode) : result;
1018 convert_move (reg, gen_rtx_fmt_ee (p_info->test_code, mode, cmp0, cmp1), 0);
1021 if (test == ITEST_NE)
1023 convert_move (result, gen_rtx_GTU (mode, reg, const0_rtx), 0);
1024 if (p_invert != NULL)
1025 *p_invert = 0;
1026 invert = 0;
1029 else if (test == ITEST_EQ)
1031 reg2 = invert ? gen_reg_rtx (mode) : result;
1032 convert_move (reg2, gen_rtx_LTU (mode, reg, const1_rtx), 0);
1033 reg = reg2;
1036 if (invert)
1038 rtx one;
1040 one = const1_rtx;
1041 convert_move (result, gen_rtx_XOR (mode, reg, one), 0);
1044 return result;
1047 /* Emit the common code for doing conditional branches.
1048 operand[0] is the label to jump to.
1049 The comparison operands are saved away by cmp{si,di,sf,df}. */
1051 void
1052 gen_conditional_branch (rtx operands[], machine_mode mode)
1054 enum rtx_code test_code = GET_CODE (operands[0]);
1055 rtx cmp0 = operands[1];
1056 rtx cmp1 = operands[2];
1057 rtx reg;
1058 int invert;
1059 rtx label1, label2;
1061 invert = 0;
1062 reg = gen_int_relational (test_code, NULL_RTX, cmp0, cmp1, &invert);
1064 if (reg)
1066 cmp0 = reg;
1067 cmp1 = const0_rtx;
1068 test_code = NE;
1070 else if (GET_CODE (cmp1) == CONST_INT && INTVAL (cmp1) != 0)
1071 /* We don't want to build a comparison against a nonzero
1072 constant. */
1073 cmp1 = force_reg (mode, cmp1);
1075 /* Generate the branch. */
1076 label1 = gen_rtx_LABEL_REF (VOIDmode, operands[3]);
1077 label2 = pc_rtx;
1079 if (invert)
1081 label2 = label1;
1082 label1 = pc_rtx;
1085 emit_jump_insn (gen_rtx_SET (pc_rtx,
1086 gen_rtx_IF_THEN_ELSE (VOIDmode,
1087 gen_rtx_fmt_ee (test_code,
1088 VOIDmode,
1089 cmp0, cmp1),
1090 label1, label2)));
1093 /* Initialize CUM for a function FNTYPE. */
1095 void
1096 init_cumulative_args (CUMULATIVE_ARGS *cum, tree fntype,
1097 rtx libname ATTRIBUTE_UNUSED)
1099 static CUMULATIVE_ARGS zero_cum;
1100 tree param;
1101 tree next_param;
1103 if (TARGET_DEBUG_D_MODE)
1105 fprintf (stderr,
1106 "\ninit_cumulative_args, fntype = 0x%.8lx", (long) fntype);
1108 if (!fntype)
1109 fputc ('\n', stderr);
1111 else
1113 tree ret_type = TREE_TYPE (fntype);
1115 fprintf (stderr, ", fntype code = %s, ret code = %s\n",
1116 get_tree_code_name (TREE_CODE (fntype)),
1117 get_tree_code_name (TREE_CODE (ret_type)));
1121 *cum = zero_cum;
1123 /* Determine if this function has variable arguments. This is
1124 indicated by the last argument being 'void_type_mode' if there
1125 are no variable arguments. The standard IQ2000 calling sequence
1126 passes all arguments in the general purpose registers in this case. */
1128 for (param = fntype ? TYPE_ARG_TYPES (fntype) : 0;
1129 param != 0; param = next_param)
1131 next_param = TREE_CHAIN (param);
1132 if (next_param == 0 && TREE_VALUE (param) != void_type_node)
1133 cum->gp_reg_found = 1;
1137 /* Advance the argument of type TYPE and mode MODE to the next argument
1138 position in CUM. */
1140 static void
1141 iq2000_function_arg_advance (cumulative_args_t cum_v, machine_mode mode,
1142 const_tree type, bool named)
1144 CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
1146 if (TARGET_DEBUG_D_MODE)
1148 fprintf (stderr,
1149 "function_adv({gp reg found = %d, arg # = %2d, words = %2d}, %4s, ",
1150 cum->gp_reg_found, cum->arg_number, cum->arg_words,
1151 GET_MODE_NAME (mode));
1152 fprintf (stderr, "%p", (const void *) type);
1153 fprintf (stderr, ", %d )\n\n", named);
1156 cum->arg_number++;
1157 switch (mode)
1159 case E_VOIDmode:
1160 break;
1162 default:
1163 gcc_assert (GET_MODE_CLASS (mode) == MODE_COMPLEX_INT
1164 || GET_MODE_CLASS (mode) == MODE_COMPLEX_FLOAT);
1166 cum->gp_reg_found = 1;
1167 cum->arg_words += ((GET_MODE_SIZE (mode) + UNITS_PER_WORD - 1)
1168 / UNITS_PER_WORD);
1169 break;
1171 case E_BLKmode:
1172 cum->gp_reg_found = 1;
1173 cum->arg_words += ((int_size_in_bytes (type) + UNITS_PER_WORD - 1)
1174 / UNITS_PER_WORD);
1175 break;
1177 case E_SFmode:
1178 cum->arg_words ++;
1179 if (! cum->gp_reg_found && cum->arg_number <= 2)
1180 cum->fp_code += 1 << ((cum->arg_number - 1) * 2);
1181 break;
1183 case E_DFmode:
1184 cum->arg_words += 2;
1185 if (! cum->gp_reg_found && cum->arg_number <= 2)
1186 cum->fp_code += 2 << ((cum->arg_number - 1) * 2);
1187 break;
1189 case E_DImode:
1190 cum->gp_reg_found = 1;
1191 cum->arg_words += 2;
1192 break;
1194 case E_TImode:
1195 cum->gp_reg_found = 1;
1196 cum->arg_words += 4;
1197 break;
1199 case E_QImode:
1200 case E_HImode:
1201 case E_SImode:
1202 cum->gp_reg_found = 1;
1203 cum->arg_words ++;
1204 break;
1208 /* Return an RTL expression containing the register for the given mode MODE
1209 and type TYPE in CUM, or 0 if the argument is to be passed on the stack. */
1211 static rtx
1212 iq2000_function_arg (cumulative_args_t cum_v, machine_mode mode,
1213 const_tree type, bool named)
1215 CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
1216 rtx ret;
1217 int regbase = -1;
1218 int bias = 0;
1219 unsigned int *arg_words = &cum->arg_words;
1220 int struct_p = (type != 0
1221 && (TREE_CODE (type) == RECORD_TYPE
1222 || TREE_CODE (type) == UNION_TYPE
1223 || TREE_CODE (type) == QUAL_UNION_TYPE));
1225 if (TARGET_DEBUG_D_MODE)
1227 fprintf (stderr,
1228 "function_arg( {gp reg found = %d, arg # = %2d, words = %2d}, %4s, ",
1229 cum->gp_reg_found, cum->arg_number, cum->arg_words,
1230 GET_MODE_NAME (mode));
1231 fprintf (stderr, "%p", (const void *) type);
1232 fprintf (stderr, ", %d ) = ", named);
1236 cum->last_arg_fp = 0;
1237 switch (mode)
1239 case E_SFmode:
1240 regbase = GP_ARG_FIRST;
1241 break;
1243 case E_DFmode:
1244 cum->arg_words += cum->arg_words & 1;
1246 regbase = GP_ARG_FIRST;
1247 break;
1249 default:
1250 gcc_assert (GET_MODE_CLASS (mode) == MODE_COMPLEX_INT
1251 || GET_MODE_CLASS (mode) == MODE_COMPLEX_FLOAT);
1253 /* FALLTHRU */
1254 case E_BLKmode:
1255 if (type != NULL_TREE && TYPE_ALIGN (type) > (unsigned) BITS_PER_WORD)
1256 cum->arg_words += (cum->arg_words & 1);
1257 regbase = GP_ARG_FIRST;
1258 break;
1260 case E_VOIDmode:
1261 case E_QImode:
1262 case E_HImode:
1263 case E_SImode:
1264 regbase = GP_ARG_FIRST;
1265 break;
1267 case E_DImode:
1268 cum->arg_words += (cum->arg_words & 1);
1269 regbase = GP_ARG_FIRST;
1270 break;
1272 case E_TImode:
1273 cum->arg_words += (cum->arg_words & 3);
1274 regbase = GP_ARG_FIRST;
1275 break;
1278 if (*arg_words >= (unsigned) MAX_ARGS_IN_REGISTERS)
1280 if (TARGET_DEBUG_D_MODE)
1281 fprintf (stderr, "<stack>%s\n", struct_p ? ", [struct]" : "");
1283 ret = 0;
1285 else
1287 gcc_assert (regbase != -1);
1289 if (! type || TREE_CODE (type) != RECORD_TYPE
1290 || ! named || ! TYPE_SIZE_UNIT (type)
1291 || ! tree_fits_uhwi_p (TYPE_SIZE_UNIT (type)))
1292 ret = gen_rtx_REG (mode, regbase + *arg_words + bias);
1293 else
1295 tree field;
1297 for (field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
1298 if (TREE_CODE (field) == FIELD_DECL
1299 && TREE_CODE (TREE_TYPE (field)) == REAL_TYPE
1300 && TYPE_PRECISION (TREE_TYPE (field)) == BITS_PER_WORD
1301 && tree_fits_shwi_p (bit_position (field))
1302 && int_bit_position (field) % BITS_PER_WORD == 0)
1303 break;
1305 /* If the whole struct fits a DFmode register,
1306 we don't need the PARALLEL. */
1307 if (! field || mode == DFmode)
1308 ret = gen_rtx_REG (mode, regbase + *arg_words + bias);
1309 else
1311 unsigned int chunks;
1312 HOST_WIDE_INT bitpos;
1313 unsigned int regno;
1314 unsigned int i;
1316 /* ??? If this is a packed structure, then the last hunk won't
1317 be 64 bits. */
1318 chunks
1319 = tree_to_uhwi (TYPE_SIZE_UNIT (type)) / UNITS_PER_WORD;
1320 if (chunks + *arg_words + bias > (unsigned) MAX_ARGS_IN_REGISTERS)
1321 chunks = MAX_ARGS_IN_REGISTERS - *arg_words - bias;
1323 /* Assign_parms checks the mode of ENTRY_PARM, so we must
1324 use the actual mode here. */
1325 ret = gen_rtx_PARALLEL (mode, rtvec_alloc (chunks));
1327 bitpos = 0;
1328 regno = regbase + *arg_words + bias;
1329 field = TYPE_FIELDS (type);
1330 for (i = 0; i < chunks; i++)
1332 rtx reg;
1334 for (; field; field = DECL_CHAIN (field))
1335 if (TREE_CODE (field) == FIELD_DECL
1336 && int_bit_position (field) >= bitpos)
1337 break;
1339 if (field
1340 && int_bit_position (field) == bitpos
1341 && TREE_CODE (TREE_TYPE (field)) == REAL_TYPE
1342 && TYPE_PRECISION (TREE_TYPE (field)) == BITS_PER_WORD)
1343 reg = gen_rtx_REG (DFmode, regno++);
1344 else
1345 reg = gen_rtx_REG (word_mode, regno);
1347 XVECEXP (ret, 0, i)
1348 = gen_rtx_EXPR_LIST (VOIDmode, reg,
1349 GEN_INT (bitpos / BITS_PER_UNIT));
1351 bitpos += 64;
1352 regno++;
1357 if (TARGET_DEBUG_D_MODE)
1358 fprintf (stderr, "%s%s\n", reg_names[regbase + *arg_words + bias],
1359 struct_p ? ", [struct]" : "");
1362 /* We will be called with a mode of VOIDmode after the last argument
1363 has been seen. Whatever we return will be passed to the call
1364 insn. If we need any shifts for small structures, return them in
1365 a PARALLEL. */
1366 if (mode == VOIDmode)
1368 if (cum->num_adjusts > 0)
1369 ret = gen_rtx_PARALLEL ((machine_mode) cum->fp_code,
1370 gen_rtvec_v (cum->num_adjusts, cum->adjust));
1373 return ret;
1376 static unsigned int
1377 iq2000_function_arg_boundary (machine_mode mode, const_tree type)
1379 return (type != NULL_TREE
1380 ? (TYPE_ALIGN (type) <= PARM_BOUNDARY
1381 ? PARM_BOUNDARY
1382 : TYPE_ALIGN (type))
1383 : (GET_MODE_ALIGNMENT (mode) <= PARM_BOUNDARY
1384 ? PARM_BOUNDARY
1385 : GET_MODE_ALIGNMENT (mode)));
1388 static int
1389 iq2000_arg_partial_bytes (cumulative_args_t cum_v, machine_mode mode,
1390 tree type ATTRIBUTE_UNUSED,
1391 bool named ATTRIBUTE_UNUSED)
1393 CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
1395 if (mode == DImode && cum->arg_words == MAX_ARGS_IN_REGISTERS - 1)
1397 if (TARGET_DEBUG_D_MODE)
1398 fprintf (stderr, "iq2000_arg_partial_bytes=%d\n", UNITS_PER_WORD);
1399 return UNITS_PER_WORD;
1402 return 0;
1405 /* Implement va_start. */
1407 static void
1408 iq2000_va_start (tree valist, rtx nextarg)
1410 int int_arg_words;
1411 /* Find out how many non-float named formals. */
1412 int gpr_save_area_size;
1413 /* Note UNITS_PER_WORD is 4 bytes. */
1414 int_arg_words = crtl->args.info.arg_words;
1416 if (int_arg_words < 8 )
1417 /* Adjust for the prologue's economy measure. */
1418 gpr_save_area_size = (8 - int_arg_words) * UNITS_PER_WORD;
1419 else
1420 gpr_save_area_size = 0;
1422 /* Everything is in the GPR save area, or in the overflow
1423 area which is contiguous with it. */
1424 nextarg = plus_constant (Pmode, nextarg, - gpr_save_area_size);
1425 std_expand_builtin_va_start (valist, nextarg);
1428 /* Allocate a chunk of memory for per-function machine-dependent data. */
1430 static struct machine_function *
1431 iq2000_init_machine_status (void)
1433 return ggc_cleared_alloc<machine_function> ();
1436 /* Detect any conflicts in the switches. */
1438 static void
1439 iq2000_option_override (void)
1441 target_flags &= ~MASK_GPOPT;
1443 iq2000_isa = IQ2000_ISA_DEFAULT;
1445 /* Identify the processor type. */
1447 iq2000_print_operand_punct['?'] = 1;
1448 iq2000_print_operand_punct['#'] = 1;
1449 iq2000_print_operand_punct['&'] = 1;
1450 iq2000_print_operand_punct['!'] = 1;
1451 iq2000_print_operand_punct['*'] = 1;
1452 iq2000_print_operand_punct['@'] = 1;
1453 iq2000_print_operand_punct['.'] = 1;
1454 iq2000_print_operand_punct['('] = 1;
1455 iq2000_print_operand_punct[')'] = 1;
1456 iq2000_print_operand_punct['['] = 1;
1457 iq2000_print_operand_punct[']'] = 1;
1458 iq2000_print_operand_punct['<'] = 1;
1459 iq2000_print_operand_punct['>'] = 1;
1460 iq2000_print_operand_punct['{'] = 1;
1461 iq2000_print_operand_punct['}'] = 1;
1462 iq2000_print_operand_punct['^'] = 1;
1463 iq2000_print_operand_punct['$'] = 1;
1464 iq2000_print_operand_punct['+'] = 1;
1465 iq2000_print_operand_punct['~'] = 1;
1467 /* Save GPR registers in word_mode sized hunks. word_mode hasn't been
1468 initialized yet, so we can't use that here. */
1469 gpr_mode = SImode;
1471 /* Function to allocate machine-dependent function status. */
1472 init_machine_status = iq2000_init_machine_status;
1475 /* The arg pointer (which is eliminated) points to the virtual frame pointer,
1476 while the frame pointer (which may be eliminated) points to the stack
1477 pointer after the initial adjustments. */
1479 HOST_WIDE_INT
1480 iq2000_debugger_offset (rtx addr, HOST_WIDE_INT offset)
1482 rtx offset2 = const0_rtx;
1483 rtx reg = eliminate_constant_term (addr, & offset2);
1485 if (offset == 0)
1486 offset = INTVAL (offset2);
1488 if (reg == stack_pointer_rtx || reg == frame_pointer_rtx
1489 || reg == hard_frame_pointer_rtx)
1491 HOST_WIDE_INT frame_size = (!cfun->machine->initialized)
1492 ? compute_frame_size (get_frame_size ())
1493 : cfun->machine->total_size;
1495 offset = offset - frame_size;
1498 return offset;
1501 /* If defined, a C statement to be executed just prior to the output of
1502 assembler code for INSN, to modify the extracted operands so they will be
1503 output differently.
1505 Here the argument OPVEC is the vector containing the operands extracted
1506 from INSN, and NOPERANDS is the number of elements of the vector which
1507 contain meaningful data for this insn. The contents of this vector are
1508 what will be used to convert the insn template into assembler code, so you
1509 can change the assembler output by changing the contents of the vector.
1511 We use it to check if the current insn needs a nop in front of it because
1512 of load delays, and also to update the delay slot statistics. */
1514 void
1515 final_prescan_insn (rtx_insn *insn, rtx opvec[] ATTRIBUTE_UNUSED,
1516 int noperands ATTRIBUTE_UNUSED)
1518 if (dslots_number_nops > 0)
1520 rtx pattern = PATTERN (insn);
1521 int length = get_attr_length (insn);
1523 /* Do we need to emit a NOP? */
1524 if (length == 0
1525 || (iq2000_load_reg != 0 && reg_mentioned_p (iq2000_load_reg, pattern))
1526 || (iq2000_load_reg2 != 0 && reg_mentioned_p (iq2000_load_reg2, pattern))
1527 || (iq2000_load_reg3 != 0 && reg_mentioned_p (iq2000_load_reg3, pattern))
1528 || (iq2000_load_reg4 != 0
1529 && reg_mentioned_p (iq2000_load_reg4, pattern)))
1530 fputs ("\tnop\n", asm_out_file);
1532 else
1533 dslots_load_filled ++;
1535 while (--dslots_number_nops > 0)
1536 fputs ("\tnop\n", asm_out_file);
1538 iq2000_load_reg = 0;
1539 iq2000_load_reg2 = 0;
1540 iq2000_load_reg3 = 0;
1541 iq2000_load_reg4 = 0;
1544 if ( (JUMP_P (insn)
1545 || CALL_P (insn)
1546 || (GET_CODE (PATTERN (insn)) == RETURN))
1547 && NEXT_INSN (PREV_INSN (insn)) == insn)
1549 rtx_insn *tmp = insn;
1550 while (NEXT_INSN (tmp)
1551 && NOTE_P (NEXT_INSN (tmp))
1552 && NOTE_KIND (NEXT_INSN (tmp)) == NOTE_INSN_CALL_ARG_LOCATION)
1553 tmp = NEXT_INSN (tmp);
1555 rtx_insn *nop_insn = emit_insn_after (gen_nop (), tmp);
1556 INSN_ADDRESSES_NEW (nop_insn, -1);
1559 if (TARGET_STATS
1560 && (JUMP_P (insn) || CALL_P (insn)))
1561 dslots_jump_total ++;
1564 /* Return the bytes needed to compute the frame pointer from the current
1565 stack pointer where SIZE is the # of var. bytes allocated.
1567 IQ2000 stack frames look like:
1569 Before call After call
1570 +-----------------------+ +-----------------------+
1571 high | | | |
1572 mem. | | | |
1573 | caller's temps. | | caller's temps. |
1574 | | | |
1575 +-----------------------+ +-----------------------+
1576 | | | |
1577 | arguments on stack. | | arguments on stack. |
1578 | | | |
1579 +-----------------------+ +-----------------------+
1580 | 4 words to save | | 4 words to save |
1581 | arguments passed | | arguments passed |
1582 | in registers, even | | in registers, even |
1583 SP->| if not passed. | VFP->| if not passed. |
1584 +-----------------------+ +-----------------------+
1586 | fp register save |
1588 +-----------------------+
1590 | gp register save |
1592 +-----------------------+
1594 | local variables |
1596 +-----------------------+
1598 | alloca allocations |
1600 +-----------------------+
1602 | GP save for V.4 abi |
1604 +-----------------------+
1606 | arguments on stack |
1608 +-----------------------+
1609 | 4 words to save |
1610 | arguments passed |
1611 | in registers, even |
1612 low SP->| if not passed. |
1613 memory +-----------------------+ */
1615 HOST_WIDE_INT
1616 compute_frame_size (HOST_WIDE_INT size)
1618 int regno;
1619 HOST_WIDE_INT total_size; /* # bytes that the entire frame takes up. */
1620 HOST_WIDE_INT var_size; /* # bytes that variables take up. */
1621 HOST_WIDE_INT args_size; /* # bytes that outgoing arguments take up. */
1622 HOST_WIDE_INT extra_size; /* # extra bytes. */
1623 HOST_WIDE_INT gp_reg_rounded; /* # bytes needed to store gp after rounding. */
1624 HOST_WIDE_INT gp_reg_size; /* # bytes needed to store gp regs. */
1625 HOST_WIDE_INT fp_reg_size; /* # bytes needed to store fp regs. */
1626 long mask; /* mask of saved gp registers. */
1628 gp_reg_size = 0;
1629 fp_reg_size = 0;
1630 mask = 0;
1631 extra_size = IQ2000_STACK_ALIGN ((0));
1632 var_size = IQ2000_STACK_ALIGN (size);
1633 args_size = IQ2000_STACK_ALIGN (crtl->outgoing_args_size);
1635 /* If a function dynamically allocates the stack and
1636 has 0 for STACK_DYNAMIC_OFFSET then allocate some stack space. */
1637 if (args_size == 0 && cfun->calls_alloca)
1638 args_size = 4 * UNITS_PER_WORD;
1640 total_size = var_size + args_size + extra_size;
1642 /* Calculate space needed for gp registers. */
1643 for (regno = GP_REG_FIRST; regno <= GP_REG_LAST; regno++)
1645 if (MUST_SAVE_REGISTER (regno))
1647 gp_reg_size += GET_MODE_SIZE (gpr_mode);
1648 mask |= 1L << (regno - GP_REG_FIRST);
1652 /* We need to restore these for the handler. */
1653 if (crtl->calls_eh_return)
1655 unsigned int i;
1657 for (i = 0; ; ++i)
1659 regno = EH_RETURN_DATA_REGNO (i);
1660 if (regno == (int) INVALID_REGNUM)
1661 break;
1662 gp_reg_size += GET_MODE_SIZE (gpr_mode);
1663 mask |= 1L << (regno - GP_REG_FIRST);
1667 gp_reg_rounded = IQ2000_STACK_ALIGN (gp_reg_size);
1668 total_size += gp_reg_rounded + IQ2000_STACK_ALIGN (fp_reg_size);
1670 /* The gp reg is caller saved, so there is no need for leaf routines
1671 (total_size == extra_size) to save the gp reg. */
1672 if (total_size == extra_size
1673 && ! profile_flag)
1674 total_size = extra_size = 0;
1676 total_size += IQ2000_STACK_ALIGN (crtl->args.pretend_args_size);
1678 /* Save other computed information. */
1679 cfun->machine->total_size = total_size;
1680 cfun->machine->var_size = var_size;
1681 cfun->machine->args_size = args_size;
1682 cfun->machine->extra_size = extra_size;
1683 cfun->machine->gp_reg_size = gp_reg_size;
1684 cfun->machine->fp_reg_size = fp_reg_size;
1685 cfun->machine->mask = mask;
1686 cfun->machine->initialized = reload_completed;
1687 cfun->machine->num_gp = gp_reg_size / UNITS_PER_WORD;
1689 if (mask)
1691 unsigned long offset;
1693 offset = (args_size + extra_size + var_size
1694 + gp_reg_size - GET_MODE_SIZE (gpr_mode));
1696 cfun->machine->gp_sp_offset = offset;
1697 cfun->machine->gp_save_offset = offset - total_size;
1699 else
1701 cfun->machine->gp_sp_offset = 0;
1702 cfun->machine->gp_save_offset = 0;
1705 cfun->machine->fp_sp_offset = 0;
1706 cfun->machine->fp_save_offset = 0;
1708 /* Ok, we're done. */
1709 return total_size;
1713 /* We can always eliminate to the frame pointer. We can eliminate to the
1714 stack pointer unless a frame pointer is needed. */
1716 bool
1717 iq2000_can_eliminate (const int from, const int to)
1719 return (from == RETURN_ADDRESS_POINTER_REGNUM
1720 && (! leaf_function_p ()
1721 || (to == GP_REG_FIRST + 31 && leaf_function_p ())))
1722 || (from != RETURN_ADDRESS_POINTER_REGNUM
1723 && (to == HARD_FRAME_POINTER_REGNUM
1724 || (to == STACK_POINTER_REGNUM
1725 && ! frame_pointer_needed)));
1728 /* Implement INITIAL_ELIMINATION_OFFSET. FROM is either the frame
1729 pointer, argument pointer, or return address pointer. TO is either
1730 the stack pointer or hard frame pointer. */
1733 iq2000_initial_elimination_offset (int from, int to ATTRIBUTE_UNUSED)
1735 int offset;
1737 compute_frame_size (get_frame_size ());
1738 if ((from) == FRAME_POINTER_REGNUM)
1739 (offset) = 0;
1740 else if ((from) == ARG_POINTER_REGNUM)
1741 (offset) = (cfun->machine->total_size);
1742 else if ((from) == RETURN_ADDRESS_POINTER_REGNUM)
1744 if (leaf_function_p ())
1745 (offset) = 0;
1746 else (offset) = cfun->machine->gp_sp_offset
1747 + ((UNITS_PER_WORD - (POINTER_SIZE / BITS_PER_UNIT))
1748 * (BYTES_BIG_ENDIAN != 0));
1750 else
1751 gcc_unreachable ();
1753 return offset;
1756 /* Common code to emit the insns (or to write the instructions to a file)
1757 to save/restore registers.
1758 Other parts of the code assume that IQ2000_TEMP1_REGNUM (aka large_reg)
1759 is not modified within save_restore_insns. */
1761 #define BITSET_P(VALUE,BIT) (((VALUE) & (1L << (BIT))) != 0)
1763 /* Emit instructions to load the value (SP + OFFSET) into IQ2000_TEMP2_REGNUM
1764 and return an rtl expression for the register. Write the assembly
1765 instructions directly to FILE if it is not null, otherwise emit them as
1766 rtl.
1768 This function is a subroutine of save_restore_insns. It is used when
1769 OFFSET is too large to add in a single instruction. */
1771 static rtx
1772 iq2000_add_large_offset_to_sp (HOST_WIDE_INT offset)
1774 rtx reg = gen_rtx_REG (Pmode, IQ2000_TEMP2_REGNUM);
1775 rtx offset_rtx = GEN_INT (offset);
1777 emit_move_insn (reg, offset_rtx);
1778 emit_insn (gen_addsi3 (reg, reg, stack_pointer_rtx));
1779 return reg;
1782 /* Make INSN frame related and note that it performs the frame-related
1783 operation DWARF_PATTERN. */
1785 static void
1786 iq2000_annotate_frame_insn (rtx_insn *insn, rtx dwarf_pattern)
1788 RTX_FRAME_RELATED_P (insn) = 1;
1789 REG_NOTES (insn) = alloc_EXPR_LIST (REG_FRAME_RELATED_EXPR,
1790 dwarf_pattern,
1791 REG_NOTES (insn));
1794 /* Emit a move instruction that stores REG in MEM. Make the instruction
1795 frame related and note that it stores REG at (SP + OFFSET). */
1797 static void
1798 iq2000_emit_frame_related_store (rtx mem, rtx reg, HOST_WIDE_INT offset)
1800 rtx dwarf_address = plus_constant (Pmode, stack_pointer_rtx, offset);
1801 rtx dwarf_mem = gen_rtx_MEM (GET_MODE (reg), dwarf_address);
1803 iq2000_annotate_frame_insn (emit_move_insn (mem, reg),
1804 gen_rtx_SET (dwarf_mem, reg));
1807 /* Emit instructions to save/restore registers, as determined by STORE_P. */
1809 static void
1810 save_restore_insns (int store_p)
1812 long mask = cfun->machine->mask;
1813 int regno;
1814 rtx base_reg_rtx;
1815 HOST_WIDE_INT base_offset;
1816 HOST_WIDE_INT gp_offset;
1817 HOST_WIDE_INT end_offset;
1819 gcc_assert (!frame_pointer_needed
1820 || BITSET_P (mask, HARD_FRAME_POINTER_REGNUM - GP_REG_FIRST));
1822 if (mask == 0)
1824 base_reg_rtx = 0, base_offset = 0;
1825 return;
1828 /* Save registers starting from high to low. The debuggers prefer at least
1829 the return register be stored at func+4, and also it allows us not to
1830 need a nop in the epilog if at least one register is reloaded in
1831 addition to return address. */
1833 /* Save GP registers if needed. */
1834 /* Pick which pointer to use as a base register. For small frames, just
1835 use the stack pointer. Otherwise, use a temporary register. Save 2
1836 cycles if the save area is near the end of a large frame, by reusing
1837 the constant created in the prologue/epilogue to adjust the stack
1838 frame. */
1840 gp_offset = cfun->machine->gp_sp_offset;
1841 end_offset
1842 = gp_offset - (cfun->machine->gp_reg_size
1843 - GET_MODE_SIZE (gpr_mode));
1845 if (gp_offset < 0 || end_offset < 0)
1846 internal_error
1847 ("gp_offset (%ld) or end_offset (%ld) is less than zero",
1848 (long) gp_offset, (long) end_offset);
1850 else if (gp_offset < 32768)
1851 base_reg_rtx = stack_pointer_rtx, base_offset = 0;
1852 else
1854 int regno;
1855 int reg_save_count = 0;
1857 for (regno = GP_REG_LAST; regno >= GP_REG_FIRST; regno--)
1858 if (BITSET_P (mask, regno - GP_REG_FIRST)) reg_save_count += 1;
1859 base_offset = gp_offset - ((reg_save_count - 1) * 4);
1860 base_reg_rtx = iq2000_add_large_offset_to_sp (base_offset);
1863 for (regno = GP_REG_LAST; regno >= GP_REG_FIRST; regno--)
1865 if (BITSET_P (mask, regno - GP_REG_FIRST))
1867 rtx reg_rtx;
1868 rtx mem_rtx
1869 = gen_rtx_MEM (gpr_mode,
1870 gen_rtx_PLUS (Pmode, base_reg_rtx,
1871 GEN_INT (gp_offset - base_offset)));
1873 reg_rtx = gen_rtx_REG (gpr_mode, regno);
1875 if (store_p)
1876 iq2000_emit_frame_related_store (mem_rtx, reg_rtx, gp_offset);
1877 else
1879 emit_move_insn (reg_rtx, mem_rtx);
1881 gp_offset -= GET_MODE_SIZE (gpr_mode);
1886 /* Expand the prologue into a bunch of separate insns. */
1888 void
1889 iq2000_expand_prologue (void)
1891 int regno;
1892 HOST_WIDE_INT tsize;
1893 int last_arg_is_vararg_marker = 0;
1894 tree fndecl = current_function_decl;
1895 tree fntype = TREE_TYPE (fndecl);
1896 tree fnargs = DECL_ARGUMENTS (fndecl);
1897 rtx next_arg_reg;
1898 int i;
1899 tree next_arg;
1900 tree cur_arg;
1901 CUMULATIVE_ARGS args_so_far_v;
1902 cumulative_args_t args_so_far;
1903 int store_args_on_stack = (iq2000_can_use_return_insn ());
1905 /* If struct value address is treated as the first argument. */
1906 if (aggregate_value_p (DECL_RESULT (fndecl), fndecl)
1907 && !cfun->returns_pcc_struct
1908 && targetm.calls.struct_value_rtx (TREE_TYPE (fndecl), 1) == 0)
1910 tree type = build_pointer_type (fntype);
1911 tree function_result_decl = build_decl (BUILTINS_LOCATION,
1912 PARM_DECL, NULL_TREE, type);
1914 DECL_ARG_TYPE (function_result_decl) = type;
1915 DECL_CHAIN (function_result_decl) = fnargs;
1916 fnargs = function_result_decl;
1919 /* For arguments passed in registers, find the register number
1920 of the first argument in the variable part of the argument list,
1921 otherwise GP_ARG_LAST+1. Note also if the last argument is
1922 the varargs special argument, and treat it as part of the
1923 variable arguments.
1925 This is only needed if store_args_on_stack is true. */
1926 INIT_CUMULATIVE_ARGS (args_so_far_v, fntype, NULL_RTX, 0, 0);
1927 args_so_far = pack_cumulative_args (&args_so_far_v);
1928 regno = GP_ARG_FIRST;
1930 for (cur_arg = fnargs; cur_arg != 0; cur_arg = next_arg)
1932 tree passed_type = DECL_ARG_TYPE (cur_arg);
1933 machine_mode passed_mode = TYPE_MODE (passed_type);
1934 rtx entry_parm;
1936 if (TREE_ADDRESSABLE (passed_type))
1938 passed_type = build_pointer_type (passed_type);
1939 passed_mode = Pmode;
1942 entry_parm = iq2000_function_arg (args_so_far, passed_mode,
1943 passed_type, true);
1945 iq2000_function_arg_advance (args_so_far, passed_mode,
1946 passed_type, true);
1947 next_arg = DECL_CHAIN (cur_arg);
1949 if (entry_parm && store_args_on_stack)
1951 if (next_arg == 0
1952 && DECL_NAME (cur_arg)
1953 && ((0 == strcmp (IDENTIFIER_POINTER (DECL_NAME (cur_arg)),
1954 "__builtin_va_alist"))
1955 || (0 == strcmp (IDENTIFIER_POINTER (DECL_NAME (cur_arg)),
1956 "va_alist"))))
1958 last_arg_is_vararg_marker = 1;
1959 break;
1961 else
1963 int words;
1965 gcc_assert (GET_CODE (entry_parm) == REG);
1967 /* Passed in a register, so will get homed automatically. */
1968 if (GET_MODE (entry_parm) == BLKmode)
1969 words = (int_size_in_bytes (passed_type) + 3) / 4;
1970 else
1971 words = (GET_MODE_SIZE (GET_MODE (entry_parm)) + 3) / 4;
1973 regno = REGNO (entry_parm) + words - 1;
1976 else
1978 regno = GP_ARG_LAST+1;
1979 break;
1983 /* In order to pass small structures by value in registers we need to
1984 shift the value into the high part of the register.
1985 iq2000_unction_arg has encoded a PARALLEL rtx, holding a vector of
1986 adjustments to be made as the next_arg_reg variable, so we split up
1987 the insns, and emit them separately. */
1988 next_arg_reg = iq2000_function_arg (args_so_far, VOIDmode,
1989 void_type_node, true);
1990 if (next_arg_reg != 0 && GET_CODE (next_arg_reg) == PARALLEL)
1992 rtvec adjust = XVEC (next_arg_reg, 0);
1993 int num = GET_NUM_ELEM (adjust);
1995 for (i = 0; i < num; i++)
1997 rtx pattern;
1999 pattern = RTVEC_ELT (adjust, i);
2000 if (GET_CODE (pattern) != SET
2001 || GET_CODE (SET_SRC (pattern)) != ASHIFT)
2002 abort_with_insn (pattern, "Insn is not a shift");
2003 PUT_CODE (SET_SRC (pattern), ASHIFTRT);
2005 emit_insn (pattern);
2009 tsize = compute_frame_size (get_frame_size ());
2011 /* If this function is a varargs function, store any registers that
2012 would normally hold arguments ($4 - $7) on the stack. */
2013 if (store_args_on_stack
2014 && (stdarg_p (fntype)
2015 || last_arg_is_vararg_marker))
2017 int offset = (regno - GP_ARG_FIRST) * UNITS_PER_WORD;
2018 rtx ptr = stack_pointer_rtx;
2020 for (; regno <= GP_ARG_LAST; regno++)
2022 if (offset != 0)
2023 ptr = gen_rtx_PLUS (Pmode, stack_pointer_rtx, GEN_INT (offset));
2024 emit_move_insn (gen_rtx_MEM (gpr_mode, ptr),
2025 gen_rtx_REG (gpr_mode, regno));
2027 offset += GET_MODE_SIZE (gpr_mode);
2031 if (tsize > 0)
2033 rtx tsize_rtx = GEN_INT (tsize);
2034 rtx adjustment_rtx, dwarf_pattern;
2035 rtx_insn *insn;
2037 if (tsize > 32767)
2039 adjustment_rtx = gen_rtx_REG (Pmode, IQ2000_TEMP1_REGNUM);
2040 emit_move_insn (adjustment_rtx, tsize_rtx);
2042 else
2043 adjustment_rtx = tsize_rtx;
2045 insn = emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
2046 adjustment_rtx));
2048 dwarf_pattern = gen_rtx_SET (stack_pointer_rtx,
2049 plus_constant (Pmode, stack_pointer_rtx,
2050 -tsize));
2052 iq2000_annotate_frame_insn (insn, dwarf_pattern);
2054 save_restore_insns (1);
2056 if (frame_pointer_needed)
2058 rtx_insn *insn = 0;
2060 insn = emit_insn (gen_movsi (hard_frame_pointer_rtx,
2061 stack_pointer_rtx));
2063 if (insn)
2064 RTX_FRAME_RELATED_P (insn) = 1;
2068 if (flag_stack_usage_info)
2069 current_function_static_stack_size = cfun->machine->total_size;
2071 emit_insn (gen_blockage ());
2074 /* Expand the epilogue into a bunch of separate insns. */
2076 void
2077 iq2000_expand_epilogue (void)
2079 HOST_WIDE_INT tsize = cfun->machine->total_size;
2080 rtx tsize_rtx = GEN_INT (tsize);
2081 rtx tmp_rtx = (rtx)0;
2083 if (iq2000_can_use_return_insn ())
2085 emit_jump_insn (gen_return ());
2086 return;
2089 if (tsize > 32767)
2091 tmp_rtx = gen_rtx_REG (Pmode, IQ2000_TEMP1_REGNUM);
2092 emit_move_insn (tmp_rtx, tsize_rtx);
2093 tsize_rtx = tmp_rtx;
2096 if (tsize > 0)
2098 if (frame_pointer_needed)
2100 emit_insn (gen_blockage ());
2102 emit_insn (gen_movsi (stack_pointer_rtx, hard_frame_pointer_rtx));
2105 save_restore_insns (0);
2107 if (crtl->calls_eh_return)
2109 rtx eh_ofs = EH_RETURN_STACKADJ_RTX;
2110 emit_insn (gen_addsi3 (eh_ofs, eh_ofs, tsize_rtx));
2111 tsize_rtx = eh_ofs;
2114 emit_insn (gen_blockage ());
2116 if (tsize != 0 || crtl->calls_eh_return)
2118 emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx,
2119 tsize_rtx));
2123 if (crtl->calls_eh_return)
2125 /* Perform the additional bump for __throw. */
2126 emit_move_insn (gen_rtx_REG (Pmode, HARD_FRAME_POINTER_REGNUM),
2127 stack_pointer_rtx);
2128 emit_use (gen_rtx_REG (Pmode, HARD_FRAME_POINTER_REGNUM));
2129 emit_jump_insn (gen_eh_return_internal ());
2131 else
2132 emit_jump_insn (gen_return_internal (gen_rtx_REG (Pmode,
2133 GP_REG_FIRST + 31)));
2136 void
2137 iq2000_expand_eh_return (rtx address)
2139 HOST_WIDE_INT gp_offset = cfun->machine->gp_sp_offset;
2140 rtx scratch;
2142 scratch = plus_constant (Pmode, stack_pointer_rtx, gp_offset);
2143 emit_move_insn (gen_rtx_MEM (GET_MODE (address), scratch), address);
2146 /* Return nonzero if this function is known to have a null epilogue.
2147 This allows the optimizer to omit jumps to jumps if no stack
2148 was created. */
2151 iq2000_can_use_return_insn (void)
2153 if (! reload_completed)
2154 return 0;
2156 if (df_regs_ever_live_p (31) || profile_flag)
2157 return 0;
2159 if (cfun->machine->initialized)
2160 return cfun->machine->total_size == 0;
2162 return compute_frame_size (get_frame_size ()) == 0;
2165 /* Choose the section to use for the constant rtx expression X that has
2166 mode MODE. */
2168 static section *
2169 iq2000_select_rtx_section (machine_mode mode, rtx x ATTRIBUTE_UNUSED,
2170 unsigned HOST_WIDE_INT align)
2172 /* For embedded applications, always put constants in read-only data,
2173 in order to reduce RAM usage. */
2174 return mergeable_constant_section (mode, align, 0);
2177 /* Choose the section to use for DECL. RELOC is true if its value contains
2178 any relocatable expression.
2180 Some of the logic used here needs to be replicated in
2181 ENCODE_SECTION_INFO in iq2000.h so that references to these symbols
2182 are done correctly. */
2184 static section *
2185 iq2000_select_section (tree decl, int reloc ATTRIBUTE_UNUSED,
2186 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED)
2188 if (TARGET_EMBEDDED_DATA)
2190 /* For embedded applications, always put an object in read-only data
2191 if possible, in order to reduce RAM usage. */
2192 if ((TREE_CODE (decl) == VAR_DECL
2193 && TREE_READONLY (decl) && !TREE_SIDE_EFFECTS (decl)
2194 && DECL_INITIAL (decl)
2195 && (DECL_INITIAL (decl) == error_mark_node
2196 || TREE_CONSTANT (DECL_INITIAL (decl))))
2197 /* Deal with calls from output_constant_def_contents. */
2198 || TREE_CODE (decl) != VAR_DECL)
2199 return readonly_data_section;
2200 else
2201 return data_section;
2203 else
2205 /* For hosted applications, always put an object in small data if
2206 possible, as this gives the best performance. */
2207 if ((TREE_CODE (decl) == VAR_DECL
2208 && TREE_READONLY (decl) && !TREE_SIDE_EFFECTS (decl)
2209 && DECL_INITIAL (decl)
2210 && (DECL_INITIAL (decl) == error_mark_node
2211 || TREE_CONSTANT (DECL_INITIAL (decl))))
2212 /* Deal with calls from output_constant_def_contents. */
2213 || TREE_CODE (decl) != VAR_DECL)
2214 return readonly_data_section;
2215 else
2216 return data_section;
2219 /* Return register to use for a function return value with VALTYPE for function
2220 FUNC. */
2222 static rtx
2223 iq2000_function_value (const_tree valtype,
2224 const_tree fn_decl_or_type,
2225 bool outgoing ATTRIBUTE_UNUSED)
2227 int reg = GP_RETURN;
2228 machine_mode mode = TYPE_MODE (valtype);
2229 int unsignedp = TYPE_UNSIGNED (valtype);
2230 const_tree func = fn_decl_or_type;
2232 if (fn_decl_or_type
2233 && !DECL_P (fn_decl_or_type))
2234 fn_decl_or_type = NULL;
2236 /* Since we promote return types, we must promote the mode here too. */
2237 mode = promote_function_mode (valtype, mode, &unsignedp, func, 1);
2239 return gen_rtx_REG (mode, reg);
2242 /* Worker function for TARGET_LIBCALL_VALUE. */
2244 static rtx
2245 iq2000_libcall_value (machine_mode mode, const_rtx fun ATTRIBUTE_UNUSED)
2247 return gen_rtx_REG (((GET_MODE_CLASS (mode) != MODE_INT
2248 || GET_MODE_SIZE (mode) >= 4)
2249 ? mode : SImode),
2250 GP_RETURN);
2253 /* Worker function for FUNCTION_VALUE_REGNO_P.
2255 On the IQ2000, R2 and R3 are the only register thus used. */
2257 bool
2258 iq2000_function_value_regno_p (const unsigned int regno)
2260 return (regno == GP_RETURN);
2264 /* Return true when an argument must be passed by reference. */
2266 static bool
2267 iq2000_pass_by_reference (cumulative_args_t cum_v, machine_mode mode,
2268 const_tree type, bool named ATTRIBUTE_UNUSED)
2270 CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
2271 int size;
2273 /* We must pass by reference if we would be both passing in registers
2274 and the stack. This is because any subsequent partial arg would be
2275 handled incorrectly in this case. */
2276 if (cum && targetm.calls.must_pass_in_stack (mode, type))
2278 /* Don't pass the actual CUM to FUNCTION_ARG, because we would
2279 get double copies of any offsets generated for small structs
2280 passed in registers. */
2281 CUMULATIVE_ARGS temp;
2283 temp = *cum;
2284 if (iq2000_function_arg (pack_cumulative_args (&temp), mode, type, named)
2285 != 0)
2286 return 1;
2289 if (type == NULL_TREE || mode == DImode || mode == DFmode)
2290 return 0;
2292 size = int_size_in_bytes (type);
2293 return size == -1 || size > UNITS_PER_WORD;
2296 /* Return the length of INSN. LENGTH is the initial length computed by
2297 attributes in the machine-description file. */
2300 iq2000_adjust_insn_length (rtx_insn *insn, int length)
2302 /* A unconditional jump has an unfilled delay slot if it is not part
2303 of a sequence. A conditional jump normally has a delay slot. */
2304 if (simplejump_p (insn)
2305 || ( (JUMP_P (insn)
2306 || CALL_P (insn))))
2307 length += 4;
2309 return length;
2312 /* Output assembly instructions to perform a conditional branch.
2314 INSN is the branch instruction. OPERANDS[0] is the condition.
2315 OPERANDS[1] is the target of the branch. OPERANDS[2] is the target
2316 of the first operand to the condition. If TWO_OPERANDS_P is
2317 nonzero the comparison takes two operands; OPERANDS[3] will be the
2318 second operand.
2320 If INVERTED_P is nonzero we are to branch if the condition does
2321 not hold. If FLOAT_P is nonzero this is a floating-point comparison.
2323 LENGTH is the length (in bytes) of the sequence we are to generate.
2324 That tells us whether to generate a simple conditional branch, or a
2325 reversed conditional branch around a `jr' instruction. */
2327 char *
2328 iq2000_output_conditional_branch (rtx_insn *insn, rtx * operands,
2329 int two_operands_p, int float_p,
2330 int inverted_p, int length)
2332 static char buffer[200];
2333 /* The kind of comparison we are doing. */
2334 enum rtx_code code = GET_CODE (operands[0]);
2335 /* Nonzero if the opcode for the comparison needs a `z' indicating
2336 that it is a comparison against zero. */
2337 int need_z_p;
2338 /* A string to use in the assembly output to represent the first
2339 operand. */
2340 const char *op1 = "%z2";
2341 /* A string to use in the assembly output to represent the second
2342 operand. Use the hard-wired zero register if there's no second
2343 operand. */
2344 const char *op2 = (two_operands_p ? ",%z3" : ",%.");
2345 /* The operand-printing string for the comparison. */
2346 const char *comp = (float_p ? "%F0" : "%C0");
2347 /* The operand-printing string for the inverted comparison. */
2348 const char *inverted_comp = (float_p ? "%W0" : "%N0");
2350 /* Likely variants of each branch instruction annul the instruction
2351 in the delay slot if the branch is not taken. */
2352 iq2000_branch_likely = (final_sequence && INSN_ANNULLED_BRANCH_P (insn));
2354 if (!two_operands_p)
2356 /* To compute whether than A > B, for example, we normally
2357 subtract B from A and then look at the sign bit. But, if we
2358 are doing an unsigned comparison, and B is zero, we don't
2359 have to do the subtraction. Instead, we can just check to
2360 see if A is nonzero. Thus, we change the CODE here to
2361 reflect the simpler comparison operation. */
2362 switch (code)
2364 case GTU:
2365 code = NE;
2366 break;
2368 case LEU:
2369 code = EQ;
2370 break;
2372 case GEU:
2373 /* A condition which will always be true. */
2374 code = EQ;
2375 op1 = "%.";
2376 break;
2378 case LTU:
2379 /* A condition which will always be false. */
2380 code = NE;
2381 op1 = "%.";
2382 break;
2384 default:
2385 /* Not a special case. */
2386 break;
2390 /* Relative comparisons are always done against zero. But
2391 equality comparisons are done between two operands, and therefore
2392 do not require a `z' in the assembly language output. */
2393 need_z_p = (!float_p && code != EQ && code != NE);
2394 /* For comparisons against zero, the zero is not provided
2395 explicitly. */
2396 if (need_z_p)
2397 op2 = "";
2399 /* Begin by terminating the buffer. That way we can always use
2400 strcat to add to it. */
2401 buffer[0] = '\0';
2403 switch (length)
2405 case 4:
2406 case 8:
2407 /* Just a simple conditional branch. */
2408 if (float_p)
2409 sprintf (buffer, "b%s%%?\t%%Z2%%1",
2410 inverted_p ? inverted_comp : comp);
2411 else
2412 sprintf (buffer, "b%s%s%%?\t%s%s,%%1",
2413 inverted_p ? inverted_comp : comp,
2414 need_z_p ? "z" : "",
2415 op1,
2416 op2);
2417 return buffer;
2419 case 12:
2420 case 16:
2422 /* Generate a reversed conditional branch around ` j'
2423 instruction:
2425 .set noreorder
2426 .set nomacro
2427 bc l
2429 j target
2430 .set macro
2431 .set reorder
2434 Because we have to jump four bytes *past* the following
2435 instruction if this branch was annulled, we can't just use
2436 a label, as in the picture above; there's no way to put the
2437 label after the next instruction, as the assembler does not
2438 accept `.L+4' as the target of a branch. (We can't just
2439 wait until the next instruction is output; it might be a
2440 macro and take up more than four bytes. Once again, we see
2441 why we want to eliminate macros.)
2443 If the branch is annulled, we jump four more bytes that we
2444 would otherwise; that way we skip the annulled instruction
2445 in the delay slot. */
2447 const char *target
2448 = ((iq2000_branch_likely || length == 16) ? ".+16" : ".+12");
2449 char *c;
2451 c = strchr (buffer, '\0');
2452 /* Generate the reversed comparison. This takes four
2453 bytes. */
2454 if (float_p)
2455 sprintf (c, "b%s\t%%Z2%s",
2456 inverted_p ? comp : inverted_comp,
2457 target);
2458 else
2459 sprintf (c, "b%s%s\t%s%s,%s",
2460 inverted_p ? comp : inverted_comp,
2461 need_z_p ? "z" : "",
2462 op1,
2463 op2,
2464 target);
2465 strcat (c, "\n\tnop\n\tj\t%1");
2466 if (length == 16)
2467 /* The delay slot was unfilled. Since we're inside
2468 .noreorder, the assembler will not fill in the NOP for
2469 us, so we must do it ourselves. */
2470 strcat (buffer, "\n\tnop");
2471 return buffer;
2474 default:
2475 gcc_unreachable ();
2478 /* NOTREACHED */
2479 return 0;
2482 #define def_builtin(NAME, TYPE, CODE) \
2483 add_builtin_function ((NAME), (TYPE), (CODE), BUILT_IN_MD, \
2484 NULL, NULL_TREE)
2486 static void
2487 iq2000_init_builtins (void)
2489 tree void_ftype, void_ftype_int, void_ftype_int_int;
2490 tree void_ftype_int_int_int;
2491 tree int_ftype_int, int_ftype_int_int, int_ftype_int_int_int;
2492 tree int_ftype_int_int_int_int;
2494 /* func () */
2495 void_ftype
2496 = build_function_type_list (void_type_node, NULL_TREE);
2498 /* func (int) */
2499 void_ftype_int
2500 = build_function_type_list (void_type_node, integer_type_node, NULL_TREE);
2502 /* void func (int, int) */
2503 void_ftype_int_int
2504 = build_function_type_list (void_type_node,
2505 integer_type_node,
2506 integer_type_node,
2507 NULL_TREE);
2509 /* int func (int) */
2510 int_ftype_int
2511 = build_function_type_list (integer_type_node,
2512 integer_type_node, NULL_TREE);
2514 /* int func (int, int) */
2515 int_ftype_int_int
2516 = build_function_type_list (integer_type_node,
2517 integer_type_node,
2518 integer_type_node,
2519 NULL_TREE);
2521 /* void func (int, int, int) */
2522 void_ftype_int_int_int
2523 = build_function_type_list (void_type_node,
2524 integer_type_node,
2525 integer_type_node,
2526 integer_type_node,
2527 NULL_TREE);
2529 /* int func (int, int, int) */
2530 int_ftype_int_int_int
2531 = build_function_type_list (integer_type_node,
2532 integer_type_node,
2533 integer_type_node,
2534 integer_type_node,
2535 NULL_TREE);
2537 /* int func (int, int, int, int) */
2538 int_ftype_int_int_int_int
2539 = build_function_type_list (integer_type_node,
2540 integer_type_node,
2541 integer_type_node,
2542 integer_type_node,
2543 integer_type_node,
2544 NULL_TREE);
2546 def_builtin ("__builtin_ado16", int_ftype_int_int, IQ2000_BUILTIN_ADO16);
2547 def_builtin ("__builtin_ram", int_ftype_int_int_int_int, IQ2000_BUILTIN_RAM);
2548 def_builtin ("__builtin_chkhdr", void_ftype_int_int, IQ2000_BUILTIN_CHKHDR);
2549 def_builtin ("__builtin_pkrl", void_ftype_int_int, IQ2000_BUILTIN_PKRL);
2550 def_builtin ("__builtin_cfc0", int_ftype_int, IQ2000_BUILTIN_CFC0);
2551 def_builtin ("__builtin_cfc1", int_ftype_int, IQ2000_BUILTIN_CFC1);
2552 def_builtin ("__builtin_cfc2", int_ftype_int, IQ2000_BUILTIN_CFC2);
2553 def_builtin ("__builtin_cfc3", int_ftype_int, IQ2000_BUILTIN_CFC3);
2554 def_builtin ("__builtin_ctc0", void_ftype_int_int, IQ2000_BUILTIN_CTC0);
2555 def_builtin ("__builtin_ctc1", void_ftype_int_int, IQ2000_BUILTIN_CTC1);
2556 def_builtin ("__builtin_ctc2", void_ftype_int_int, IQ2000_BUILTIN_CTC2);
2557 def_builtin ("__builtin_ctc3", void_ftype_int_int, IQ2000_BUILTIN_CTC3);
2558 def_builtin ("__builtin_mfc0", int_ftype_int, IQ2000_BUILTIN_MFC0);
2559 def_builtin ("__builtin_mfc1", int_ftype_int, IQ2000_BUILTIN_MFC1);
2560 def_builtin ("__builtin_mfc2", int_ftype_int, IQ2000_BUILTIN_MFC2);
2561 def_builtin ("__builtin_mfc3", int_ftype_int, IQ2000_BUILTIN_MFC3);
2562 def_builtin ("__builtin_mtc0", void_ftype_int_int, IQ2000_BUILTIN_MTC0);
2563 def_builtin ("__builtin_mtc1", void_ftype_int_int, IQ2000_BUILTIN_MTC1);
2564 def_builtin ("__builtin_mtc2", void_ftype_int_int, IQ2000_BUILTIN_MTC2);
2565 def_builtin ("__builtin_mtc3", void_ftype_int_int, IQ2000_BUILTIN_MTC3);
2566 def_builtin ("__builtin_lur", void_ftype_int_int, IQ2000_BUILTIN_LUR);
2567 def_builtin ("__builtin_rb", void_ftype_int_int, IQ2000_BUILTIN_RB);
2568 def_builtin ("__builtin_rx", void_ftype_int_int, IQ2000_BUILTIN_RX);
2569 def_builtin ("__builtin_srrd", void_ftype_int, IQ2000_BUILTIN_SRRD);
2570 def_builtin ("__builtin_srwr", void_ftype_int_int, IQ2000_BUILTIN_SRWR);
2571 def_builtin ("__builtin_wb", void_ftype_int_int, IQ2000_BUILTIN_WB);
2572 def_builtin ("__builtin_wx", void_ftype_int_int, IQ2000_BUILTIN_WX);
2573 def_builtin ("__builtin_luc32l", void_ftype_int_int, IQ2000_BUILTIN_LUC32L);
2574 def_builtin ("__builtin_luc64", void_ftype_int_int, IQ2000_BUILTIN_LUC64);
2575 def_builtin ("__builtin_luc64l", void_ftype_int_int, IQ2000_BUILTIN_LUC64L);
2576 def_builtin ("__builtin_luk", void_ftype_int_int, IQ2000_BUILTIN_LUK);
2577 def_builtin ("__builtin_lulck", void_ftype_int, IQ2000_BUILTIN_LULCK);
2578 def_builtin ("__builtin_lum32", void_ftype_int_int, IQ2000_BUILTIN_LUM32);
2579 def_builtin ("__builtin_lum32l", void_ftype_int_int, IQ2000_BUILTIN_LUM32L);
2580 def_builtin ("__builtin_lum64", void_ftype_int_int, IQ2000_BUILTIN_LUM64);
2581 def_builtin ("__builtin_lum64l", void_ftype_int_int, IQ2000_BUILTIN_LUM64L);
2582 def_builtin ("__builtin_lurl", void_ftype_int_int, IQ2000_BUILTIN_LURL);
2583 def_builtin ("__builtin_mrgb", int_ftype_int_int_int, IQ2000_BUILTIN_MRGB);
2584 def_builtin ("__builtin_srrdl", void_ftype_int, IQ2000_BUILTIN_SRRDL);
2585 def_builtin ("__builtin_srulck", void_ftype_int, IQ2000_BUILTIN_SRULCK);
2586 def_builtin ("__builtin_srwru", void_ftype_int_int, IQ2000_BUILTIN_SRWRU);
2587 def_builtin ("__builtin_trapqfl", void_ftype, IQ2000_BUILTIN_TRAPQFL);
2588 def_builtin ("__builtin_trapqne", void_ftype, IQ2000_BUILTIN_TRAPQNE);
2589 def_builtin ("__builtin_traprel", void_ftype_int, IQ2000_BUILTIN_TRAPREL);
2590 def_builtin ("__builtin_wbu", void_ftype_int_int_int, IQ2000_BUILTIN_WBU);
2591 def_builtin ("__builtin_syscall", void_ftype, IQ2000_BUILTIN_SYSCALL);
2594 /* Builtin for ICODE having ARGCOUNT args in EXP where each arg
2595 has an rtx CODE. */
2597 static rtx
2598 expand_one_builtin (enum insn_code icode, rtx target, tree exp,
2599 enum rtx_code *code, int argcount)
2601 rtx pat;
2602 tree arg [5];
2603 rtx op [5];
2604 machine_mode mode [5];
2605 int i;
2607 mode[0] = insn_data[icode].operand[0].mode;
2608 for (i = 0; i < argcount; i++)
2610 arg[i] = CALL_EXPR_ARG (exp, i);
2611 op[i] = expand_normal (arg[i]);
2612 mode[i] = insn_data[icode].operand[i].mode;
2613 if (code[i] == CONST_INT && GET_CODE (op[i]) != CONST_INT)
2614 error ("argument %qd is not a constant", i + 1);
2615 if (code[i] == REG
2616 && ! (*insn_data[icode].operand[i].predicate) (op[i], mode[i]))
2617 op[i] = copy_to_mode_reg (mode[i], op[i]);
2620 if (insn_data[icode].operand[0].constraint[0] == '=')
2622 if (target == 0
2623 || GET_MODE (target) != mode[0]
2624 || ! (*insn_data[icode].operand[0].predicate) (target, mode[0]))
2625 target = gen_reg_rtx (mode[0]);
2627 else
2628 target = 0;
2630 switch (argcount)
2632 case 0:
2633 pat = GEN_FCN (icode) (target);
2634 break;
2635 case 1:
2636 if (target)
2637 pat = GEN_FCN (icode) (target, op[0]);
2638 else
2639 pat = GEN_FCN (icode) (op[0]);
2640 break;
2641 case 2:
2642 if (target)
2643 pat = GEN_FCN (icode) (target, op[0], op[1]);
2644 else
2645 pat = GEN_FCN (icode) (op[0], op[1]);
2646 break;
2647 case 3:
2648 if (target)
2649 pat = GEN_FCN (icode) (target, op[0], op[1], op[2]);
2650 else
2651 pat = GEN_FCN (icode) (op[0], op[1], op[2]);
2652 break;
2653 case 4:
2654 if (target)
2655 pat = GEN_FCN (icode) (target, op[0], op[1], op[2], op[3]);
2656 else
2657 pat = GEN_FCN (icode) (op[0], op[1], op[2], op[3]);
2658 break;
2659 default:
2660 gcc_unreachable ();
2663 if (! pat)
2664 return 0;
2665 emit_insn (pat);
2666 return target;
2669 /* Expand an expression EXP that calls a built-in function,
2670 with result going to TARGET if that's convenient
2671 (and in mode MODE if that's convenient).
2672 SUBTARGET may be used as the target for computing one of EXP's operands.
2673 IGNORE is nonzero if the value is to be ignored. */
2675 static rtx
2676 iq2000_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED,
2677 machine_mode mode ATTRIBUTE_UNUSED,
2678 int ignore ATTRIBUTE_UNUSED)
2680 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
2681 int fcode = DECL_FUNCTION_CODE (fndecl);
2682 enum rtx_code code [5];
2684 code[0] = REG;
2685 code[1] = REG;
2686 code[2] = REG;
2687 code[3] = REG;
2688 code[4] = REG;
2689 switch (fcode)
2691 default:
2692 break;
2694 case IQ2000_BUILTIN_ADO16:
2695 return expand_one_builtin (CODE_FOR_ado16, target, exp, code, 2);
2697 case IQ2000_BUILTIN_RAM:
2698 code[1] = CONST_INT;
2699 code[2] = CONST_INT;
2700 code[3] = CONST_INT;
2701 return expand_one_builtin (CODE_FOR_ram, target, exp, code, 4);
2703 case IQ2000_BUILTIN_CHKHDR:
2704 return expand_one_builtin (CODE_FOR_chkhdr, target, exp, code, 2);
2706 case IQ2000_BUILTIN_PKRL:
2707 return expand_one_builtin (CODE_FOR_pkrl, target, exp, code, 2);
2709 case IQ2000_BUILTIN_CFC0:
2710 code[0] = CONST_INT;
2711 return expand_one_builtin (CODE_FOR_cfc0, target, exp, code, 1);
2713 case IQ2000_BUILTIN_CFC1:
2714 code[0] = CONST_INT;
2715 return expand_one_builtin (CODE_FOR_cfc1, target, exp, code, 1);
2717 case IQ2000_BUILTIN_CFC2:
2718 code[0] = CONST_INT;
2719 return expand_one_builtin (CODE_FOR_cfc2, target, exp, code, 1);
2721 case IQ2000_BUILTIN_CFC3:
2722 code[0] = CONST_INT;
2723 return expand_one_builtin (CODE_FOR_cfc3, target, exp, code, 1);
2725 case IQ2000_BUILTIN_CTC0:
2726 code[1] = CONST_INT;
2727 return expand_one_builtin (CODE_FOR_ctc0, target, exp, code, 2);
2729 case IQ2000_BUILTIN_CTC1:
2730 code[1] = CONST_INT;
2731 return expand_one_builtin (CODE_FOR_ctc1, target, exp, code, 2);
2733 case IQ2000_BUILTIN_CTC2:
2734 code[1] = CONST_INT;
2735 return expand_one_builtin (CODE_FOR_ctc2, target, exp, code, 2);
2737 case IQ2000_BUILTIN_CTC3:
2738 code[1] = CONST_INT;
2739 return expand_one_builtin (CODE_FOR_ctc3, target, exp, code, 2);
2741 case IQ2000_BUILTIN_MFC0:
2742 code[0] = CONST_INT;
2743 return expand_one_builtin (CODE_FOR_mfc0, target, exp, code, 1);
2745 case IQ2000_BUILTIN_MFC1:
2746 code[0] = CONST_INT;
2747 return expand_one_builtin (CODE_FOR_mfc1, target, exp, code, 1);
2749 case IQ2000_BUILTIN_MFC2:
2750 code[0] = CONST_INT;
2751 return expand_one_builtin (CODE_FOR_mfc2, target, exp, code, 1);
2753 case IQ2000_BUILTIN_MFC3:
2754 code[0] = CONST_INT;
2755 return expand_one_builtin (CODE_FOR_mfc3, target, exp, code, 1);
2757 case IQ2000_BUILTIN_MTC0:
2758 code[1] = CONST_INT;
2759 return expand_one_builtin (CODE_FOR_mtc0, target, exp, code, 2);
2761 case IQ2000_BUILTIN_MTC1:
2762 code[1] = CONST_INT;
2763 return expand_one_builtin (CODE_FOR_mtc1, target, exp, code, 2);
2765 case IQ2000_BUILTIN_MTC2:
2766 code[1] = CONST_INT;
2767 return expand_one_builtin (CODE_FOR_mtc2, target, exp, code, 2);
2769 case IQ2000_BUILTIN_MTC3:
2770 code[1] = CONST_INT;
2771 return expand_one_builtin (CODE_FOR_mtc3, target, exp, code, 2);
2773 case IQ2000_BUILTIN_LUR:
2774 return expand_one_builtin (CODE_FOR_lur, target, exp, code, 2);
2776 case IQ2000_BUILTIN_RB:
2777 return expand_one_builtin (CODE_FOR_rb, target, exp, code, 2);
2779 case IQ2000_BUILTIN_RX:
2780 return expand_one_builtin (CODE_FOR_rx, target, exp, code, 2);
2782 case IQ2000_BUILTIN_SRRD:
2783 return expand_one_builtin (CODE_FOR_srrd, target, exp, code, 1);
2785 case IQ2000_BUILTIN_SRWR:
2786 return expand_one_builtin (CODE_FOR_srwr, target, exp, code, 2);
2788 case IQ2000_BUILTIN_WB:
2789 return expand_one_builtin (CODE_FOR_wb, target, exp, code, 2);
2791 case IQ2000_BUILTIN_WX:
2792 return expand_one_builtin (CODE_FOR_wx, target, exp, code, 2);
2794 case IQ2000_BUILTIN_LUC32L:
2795 return expand_one_builtin (CODE_FOR_luc32l, target, exp, code, 2);
2797 case IQ2000_BUILTIN_LUC64:
2798 return expand_one_builtin (CODE_FOR_luc64, target, exp, code, 2);
2800 case IQ2000_BUILTIN_LUC64L:
2801 return expand_one_builtin (CODE_FOR_luc64l, target, exp, code, 2);
2803 case IQ2000_BUILTIN_LUK:
2804 return expand_one_builtin (CODE_FOR_luk, target, exp, code, 2);
2806 case IQ2000_BUILTIN_LULCK:
2807 return expand_one_builtin (CODE_FOR_lulck, target, exp, code, 1);
2809 case IQ2000_BUILTIN_LUM32:
2810 return expand_one_builtin (CODE_FOR_lum32, target, exp, code, 2);
2812 case IQ2000_BUILTIN_LUM32L:
2813 return expand_one_builtin (CODE_FOR_lum32l, target, exp, code, 2);
2815 case IQ2000_BUILTIN_LUM64:
2816 return expand_one_builtin (CODE_FOR_lum64, target, exp, code, 2);
2818 case IQ2000_BUILTIN_LUM64L:
2819 return expand_one_builtin (CODE_FOR_lum64l, target, exp, code, 2);
2821 case IQ2000_BUILTIN_LURL:
2822 return expand_one_builtin (CODE_FOR_lurl, target, exp, code, 2);
2824 case IQ2000_BUILTIN_MRGB:
2825 code[2] = CONST_INT;
2826 return expand_one_builtin (CODE_FOR_mrgb, target, exp, code, 3);
2828 case IQ2000_BUILTIN_SRRDL:
2829 return expand_one_builtin (CODE_FOR_srrdl, target, exp, code, 1);
2831 case IQ2000_BUILTIN_SRULCK:
2832 return expand_one_builtin (CODE_FOR_srulck, target, exp, code, 1);
2834 case IQ2000_BUILTIN_SRWRU:
2835 return expand_one_builtin (CODE_FOR_srwru, target, exp, code, 2);
2837 case IQ2000_BUILTIN_TRAPQFL:
2838 return expand_one_builtin (CODE_FOR_trapqfl, target, exp, code, 0);
2840 case IQ2000_BUILTIN_TRAPQNE:
2841 return expand_one_builtin (CODE_FOR_trapqne, target, exp, code, 0);
2843 case IQ2000_BUILTIN_TRAPREL:
2844 return expand_one_builtin (CODE_FOR_traprel, target, exp, code, 1);
2846 case IQ2000_BUILTIN_WBU:
2847 return expand_one_builtin (CODE_FOR_wbu, target, exp, code, 3);
2849 case IQ2000_BUILTIN_SYSCALL:
2850 return expand_one_builtin (CODE_FOR_syscall, target, exp, code, 0);
2853 return NULL_RTX;
2856 /* Worker function for TARGET_RETURN_IN_MEMORY. */
2858 static bool
2859 iq2000_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED)
2861 return ((int_size_in_bytes (type) > (2 * UNITS_PER_WORD))
2862 || (int_size_in_bytes (type) == -1));
2865 /* Worker function for TARGET_SETUP_INCOMING_VARARGS. */
2867 static void
2868 iq2000_setup_incoming_varargs (cumulative_args_t cum_v,
2869 machine_mode mode ATTRIBUTE_UNUSED,
2870 tree type ATTRIBUTE_UNUSED, int * pretend_size,
2871 int no_rtl)
2873 CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
2874 unsigned int iq2000_off = ! cum->last_arg_fp;
2875 unsigned int iq2000_fp_off = cum->last_arg_fp;
2877 if ((cum->arg_words < MAX_ARGS_IN_REGISTERS - iq2000_off))
2879 int iq2000_save_gp_regs
2880 = MAX_ARGS_IN_REGISTERS - cum->arg_words - iq2000_off;
2881 int iq2000_save_fp_regs
2882 = (MAX_ARGS_IN_REGISTERS - cum->fp_arg_words - iq2000_fp_off);
2884 if (iq2000_save_gp_regs < 0)
2885 iq2000_save_gp_regs = 0;
2886 if (iq2000_save_fp_regs < 0)
2887 iq2000_save_fp_regs = 0;
2889 *pretend_size = ((iq2000_save_gp_regs * UNITS_PER_WORD)
2890 + (iq2000_save_fp_regs * UNITS_PER_FPREG));
2892 if (! (no_rtl))
2894 if (cum->arg_words < MAX_ARGS_IN_REGISTERS - iq2000_off)
2896 rtx ptr, mem;
2897 ptr = plus_constant (Pmode, virtual_incoming_args_rtx,
2898 - (iq2000_save_gp_regs
2899 * UNITS_PER_WORD));
2900 mem = gen_rtx_MEM (BLKmode, ptr);
2901 move_block_from_reg
2902 (cum->arg_words + GP_ARG_FIRST + iq2000_off,
2903 mem,
2904 iq2000_save_gp_regs);
2910 /* A C compound statement to output to stdio stream STREAM the
2911 assembler syntax for an instruction operand that is a memory
2912 reference whose address is ADDR. ADDR is an RTL expression. */
2914 static void
2915 iq2000_print_operand_address (FILE * file, machine_mode mode, rtx addr)
2917 if (!addr)
2918 error ("PRINT_OPERAND_ADDRESS, null pointer");
2920 else
2921 switch (GET_CODE (addr))
2923 case REG:
2924 if (REGNO (addr) == ARG_POINTER_REGNUM)
2925 abort_with_insn (addr, "Arg pointer not eliminated.");
2927 fprintf (file, "0(%s)", reg_names [REGNO (addr)]);
2928 break;
2930 case LO_SUM:
2932 rtx arg0 = XEXP (addr, 0);
2933 rtx arg1 = XEXP (addr, 1);
2935 if (GET_CODE (arg0) != REG)
2936 abort_with_insn (addr,
2937 "PRINT_OPERAND_ADDRESS, LO_SUM with #1 not REG.");
2939 fprintf (file, "%%lo(");
2940 iq2000_print_operand_address (file, mode, arg1);
2941 fprintf (file, ")(%s)", reg_names [REGNO (arg0)]);
2943 break;
2945 case PLUS:
2947 rtx reg = 0;
2948 rtx offset = 0;
2949 rtx arg0 = XEXP (addr, 0);
2950 rtx arg1 = XEXP (addr, 1);
2952 if (GET_CODE (arg0) == REG)
2954 reg = arg0;
2955 offset = arg1;
2956 if (GET_CODE (offset) == REG)
2957 abort_with_insn (addr, "PRINT_OPERAND_ADDRESS, 2 regs");
2960 else if (GET_CODE (arg1) == REG)
2961 reg = arg1, offset = arg0;
2962 else if (CONSTANT_P (arg0) && CONSTANT_P (arg1))
2964 output_addr_const (file, addr);
2965 break;
2967 else
2968 abort_with_insn (addr, "PRINT_OPERAND_ADDRESS, no regs");
2970 if (! CONSTANT_P (offset))
2971 abort_with_insn (addr, "PRINT_OPERAND_ADDRESS, invalid insn #2");
2973 if (REGNO (reg) == ARG_POINTER_REGNUM)
2974 abort_with_insn (addr, "Arg pointer not eliminated.");
2976 output_addr_const (file, offset);
2977 fprintf (file, "(%s)", reg_names [REGNO (reg)]);
2979 break;
2981 case LABEL_REF:
2982 case SYMBOL_REF:
2983 case CONST_INT:
2984 case CONST:
2985 output_addr_const (file, addr);
2986 if (GET_CODE (addr) == CONST_INT)
2987 fprintf (file, "(%s)", reg_names [0]);
2988 break;
2990 default:
2991 abort_with_insn (addr, "PRINT_OPERAND_ADDRESS, invalid insn #1");
2992 break;
2996 /* A C compound statement to output to stdio stream FILE the
2997 assembler syntax for an instruction operand OP.
2999 LETTER is a value that can be used to specify one of several ways
3000 of printing the operand. It is used when identical operands
3001 must be printed differently depending on the context. LETTER
3002 comes from the `%' specification that was used to request
3003 printing of the operand. If the specification was just `%DIGIT'
3004 then LETTER is 0; if the specification was `%LTR DIGIT' then LETTER
3005 is the ASCII code for LTR.
3007 If OP is a register, this macro should print the register's name.
3008 The names can be found in an array `reg_names' whose type is
3009 `char *[]'. `reg_names' is initialized from `REGISTER_NAMES'.
3011 When the machine description has a specification `%PUNCT' (a `%'
3012 followed by a punctuation character), this macro is called with
3013 a null pointer for X and the punctuation character for LETTER.
3015 The IQ2000 specific codes are:
3017 'X' X is CONST_INT, prints upper 16 bits in hexadecimal format = "0x%04x",
3018 'x' X is CONST_INT, prints lower 16 bits in hexadecimal format = "0x%04x",
3019 'd' output integer constant in decimal,
3020 'z' if the operand is 0, use $0 instead of normal operand.
3021 'D' print second part of double-word register or memory operand.
3022 'L' print low-order register of double-word register operand.
3023 'M' print high-order register of double-word register operand.
3024 'C' print part of opcode for a branch condition.
3025 'F' print part of opcode for a floating-point branch condition.
3026 'N' print part of opcode for a branch condition, inverted.
3027 'W' print part of opcode for a floating-point branch condition, inverted.
3028 'A' Print part of opcode for a bit test condition.
3029 'P' Print label for a bit test.
3030 'p' Print log for a bit test.
3031 'B' print 'z' for EQ, 'n' for NE
3032 'b' print 'n' for EQ, 'z' for NE
3033 'T' print 'f' for EQ, 't' for NE
3034 't' print 't' for EQ, 'f' for NE
3035 'Z' print register and a comma, but print nothing for $fcc0
3036 '?' Print 'l' if we are to use a branch likely instead of normal branch.
3037 '@' Print the name of the assembler temporary register (at or $1).
3038 '.' Print the name of the register with a hard-wired zero (zero or $0).
3039 '$' Print the name of the stack pointer register (sp or $29).
3040 '+' Print the name of the gp register (gp or $28). */
3042 static void
3043 iq2000_print_operand (FILE *file, rtx op, int letter)
3045 enum rtx_code code;
3047 if (iq2000_print_operand_punct_valid_p (letter))
3049 switch (letter)
3051 case '?':
3052 if (iq2000_branch_likely)
3053 putc ('l', file);
3054 break;
3056 case '@':
3057 fputs (reg_names [GP_REG_FIRST + 1], file);
3058 break;
3060 case '.':
3061 fputs (reg_names [GP_REG_FIRST + 0], file);
3062 break;
3064 case '$':
3065 fputs (reg_names[STACK_POINTER_REGNUM], file);
3066 break;
3068 case '+':
3069 fputs (reg_names[GP_REG_FIRST + 28], file);
3070 break;
3072 default:
3073 error ("PRINT_OPERAND: Unknown punctuation '%c'", letter);
3074 break;
3077 return;
3080 if (! op)
3082 error ("PRINT_OPERAND null pointer");
3083 return;
3086 code = GET_CODE (op);
3088 if (code == SIGN_EXTEND)
3089 op = XEXP (op, 0), code = GET_CODE (op);
3091 if (letter == 'C')
3092 switch (code)
3094 case EQ: fputs ("eq", file); break;
3095 case NE: fputs ("ne", file); break;
3096 case GT: fputs ("gt", file); break;
3097 case GE: fputs ("ge", file); break;
3098 case LT: fputs ("lt", file); break;
3099 case LE: fputs ("le", file); break;
3100 case GTU: fputs ("ne", file); break;
3101 case GEU: fputs ("geu", file); break;
3102 case LTU: fputs ("ltu", file); break;
3103 case LEU: fputs ("eq", file); break;
3104 default:
3105 abort_with_insn (op, "PRINT_OPERAND, invalid insn for %%C");
3108 else if (letter == 'N')
3109 switch (code)
3111 case EQ: fputs ("ne", file); break;
3112 case NE: fputs ("eq", file); break;
3113 case GT: fputs ("le", file); break;
3114 case GE: fputs ("lt", file); break;
3115 case LT: fputs ("ge", file); break;
3116 case LE: fputs ("gt", file); break;
3117 case GTU: fputs ("leu", file); break;
3118 case GEU: fputs ("ltu", file); break;
3119 case LTU: fputs ("geu", file); break;
3120 case LEU: fputs ("gtu", file); break;
3121 default:
3122 abort_with_insn (op, "PRINT_OPERAND, invalid insn for %%N");
3125 else if (letter == 'F')
3126 switch (code)
3128 case EQ: fputs ("c1f", file); break;
3129 case NE: fputs ("c1t", file); break;
3130 default:
3131 abort_with_insn (op, "PRINT_OPERAND, invalid insn for %%F");
3134 else if (letter == 'W')
3135 switch (code)
3137 case EQ: fputs ("c1t", file); break;
3138 case NE: fputs ("c1f", file); break;
3139 default:
3140 abort_with_insn (op, "PRINT_OPERAND, invalid insn for %%W");
3143 else if (letter == 'A')
3144 fputs (code == LABEL_REF ? "i" : "in", file);
3146 else if (letter == 'P')
3148 if (code == LABEL_REF)
3149 output_addr_const (file, op);
3150 else if (code != PC)
3151 output_operand_lossage ("invalid %%P operand");
3154 else if (letter == 'p')
3156 int value;
3157 if (code != CONST_INT
3158 || (value = exact_log2 (INTVAL (op))) < 0)
3159 output_operand_lossage ("invalid %%p value");
3160 else
3161 fprintf (file, "%d", value);
3164 else if (letter == 'Z')
3166 gcc_unreachable ();
3169 else if (code == REG || code == SUBREG)
3171 int regnum;
3173 if (code == REG)
3174 regnum = REGNO (op);
3175 else
3176 regnum = true_regnum (op);
3178 if ((letter == 'M' && ! WORDS_BIG_ENDIAN)
3179 || (letter == 'L' && WORDS_BIG_ENDIAN)
3180 || letter == 'D')
3181 regnum++;
3183 fprintf (file, "%s", reg_names[regnum]);
3186 else if (code == MEM)
3188 machine_mode mode = GET_MODE (op);
3190 if (letter == 'D')
3191 output_address (mode, plus_constant (Pmode, XEXP (op, 0), 4));
3192 else
3193 output_address (mode, XEXP (op, 0));
3196 else if (code == CONST_DOUBLE
3197 && GET_MODE_CLASS (GET_MODE (op)) == MODE_FLOAT)
3199 char s[60];
3201 real_to_decimal (s, CONST_DOUBLE_REAL_VALUE (op), sizeof (s), 0, 1);
3202 fputs (s, file);
3205 else if (letter == 'x' && GET_CODE (op) == CONST_INT)
3206 fprintf (file, HOST_WIDE_INT_PRINT_HEX, 0xffff & INTVAL(op));
3208 else if (letter == 'X' && GET_CODE(op) == CONST_INT)
3209 fprintf (file, HOST_WIDE_INT_PRINT_HEX, 0xffff & (INTVAL (op) >> 16));
3211 else if (letter == 'd' && GET_CODE(op) == CONST_INT)
3212 fprintf (file, HOST_WIDE_INT_PRINT_DEC, (INTVAL(op)));
3214 else if (letter == 'z' && GET_CODE (op) == CONST_INT && INTVAL (op) == 0)
3215 fputs (reg_names[GP_REG_FIRST], file);
3217 else if (letter == 'd' || letter == 'x' || letter == 'X')
3218 output_operand_lossage ("invalid use of %%d, %%x, or %%X");
3220 else if (letter == 'B')
3221 fputs (code == EQ ? "z" : "n", file);
3222 else if (letter == 'b')
3223 fputs (code == EQ ? "n" : "z", file);
3224 else if (letter == 'T')
3225 fputs (code == EQ ? "f" : "t", file);
3226 else if (letter == 't')
3227 fputs (code == EQ ? "t" : "f", file);
3229 else if (code == CONST && GET_CODE (XEXP (op, 0)) == REG)
3231 iq2000_print_operand (file, XEXP (op, 0), letter);
3234 else
3235 output_addr_const (file, op);
3238 static bool
3239 iq2000_print_operand_punct_valid_p (unsigned char code)
3241 return iq2000_print_operand_punct[code];
3244 /* For the IQ2000, transform:
3246 memory(X + <large int>)
3247 into:
3248 Y = <large int> & ~0x7fff;
3249 Z = X + Y
3250 memory (Z + (<large int> & 0x7fff));
3254 iq2000_legitimize_address (rtx xinsn, rtx old_x ATTRIBUTE_UNUSED,
3255 machine_mode mode)
3257 if (TARGET_DEBUG_B_MODE)
3259 GO_PRINTF ("\n========== LEGITIMIZE_ADDRESS\n");
3260 GO_DEBUG_RTX (xinsn);
3263 if (iq2000_check_split (xinsn, mode))
3265 return gen_rtx_LO_SUM (Pmode,
3266 copy_to_mode_reg (Pmode,
3267 gen_rtx_HIGH (Pmode, xinsn)),
3268 xinsn);
3271 if (GET_CODE (xinsn) == PLUS)
3273 rtx xplus0 = XEXP (xinsn, 0);
3274 rtx xplus1 = XEXP (xinsn, 1);
3275 enum rtx_code code0 = GET_CODE (xplus0);
3276 enum rtx_code code1 = GET_CODE (xplus1);
3278 if (code0 != REG && code1 == REG)
3280 xplus0 = XEXP (xinsn, 1);
3281 xplus1 = XEXP (xinsn, 0);
3282 code0 = GET_CODE (xplus0);
3283 code1 = GET_CODE (xplus1);
3286 if (code0 == REG && REG_MODE_OK_FOR_BASE_P (xplus0, mode)
3287 && code1 == CONST_INT && !SMALL_INT (xplus1))
3289 rtx int_reg = gen_reg_rtx (Pmode);
3290 rtx ptr_reg = gen_reg_rtx (Pmode);
3292 emit_move_insn (int_reg,
3293 GEN_INT (INTVAL (xplus1) & ~ 0x7fff));
3295 emit_insn (gen_rtx_SET (ptr_reg,
3296 gen_rtx_PLUS (Pmode, xplus0, int_reg)));
3298 return plus_constant (Pmode, ptr_reg, INTVAL (xplus1) & 0x7fff);
3302 if (TARGET_DEBUG_B_MODE)
3303 GO_PRINTF ("LEGITIMIZE_ADDRESS could not fix.\n");
3305 return xinsn;
3309 static bool
3310 iq2000_rtx_costs (rtx x, machine_mode mode, int outer_code ATTRIBUTE_UNUSED,
3311 int opno ATTRIBUTE_UNUSED, int * total,
3312 bool speed ATTRIBUTE_UNUSED)
3314 int code = GET_CODE (x);
3316 switch (code)
3318 case MEM:
3320 int num_words = (GET_MODE_SIZE (mode) > UNITS_PER_WORD) ? 2 : 1;
3322 if (simple_memory_operand (x, mode))
3323 return COSTS_N_INSNS (num_words) != 0;
3325 * total = COSTS_N_INSNS (2 * num_words);
3326 break;
3329 case FFS:
3330 * total = COSTS_N_INSNS (6);
3331 break;
3333 case AND:
3334 case IOR:
3335 case XOR:
3336 case NOT:
3337 * total = COSTS_N_INSNS (mode == DImode ? 2 : 1);
3338 break;
3340 case ASHIFT:
3341 case ASHIFTRT:
3342 case LSHIFTRT:
3343 if (mode == DImode)
3344 * total = COSTS_N_INSNS ((GET_CODE (XEXP (x, 1)) == CONST_INT) ? 4 : 12);
3345 else
3346 * total = COSTS_N_INSNS (1);
3347 break;
3349 case ABS:
3350 if (mode == SFmode || mode == DFmode)
3351 * total = COSTS_N_INSNS (1);
3352 else
3353 * total = COSTS_N_INSNS (4);
3354 break;
3356 case PLUS:
3357 case MINUS:
3358 if (mode == SFmode || mode == DFmode)
3359 * total = COSTS_N_INSNS (6);
3360 else if (mode == DImode)
3361 * total = COSTS_N_INSNS (4);
3362 else
3363 * total = COSTS_N_INSNS (1);
3364 break;
3366 case NEG:
3367 * total = (mode == DImode) ? 4 : 1;
3368 break;
3370 case MULT:
3371 if (mode == SFmode)
3372 * total = COSTS_N_INSNS (7);
3373 else if (mode == DFmode)
3374 * total = COSTS_N_INSNS (8);
3375 else
3376 * total = COSTS_N_INSNS (10);
3377 break;
3379 case DIV:
3380 case MOD:
3381 if (mode == SFmode)
3382 * total = COSTS_N_INSNS (23);
3383 else if (mode == DFmode)
3384 * total = COSTS_N_INSNS (36);
3385 else
3386 * total = COSTS_N_INSNS (69);
3387 break;
3389 case UDIV:
3390 case UMOD:
3391 * total = COSTS_N_INSNS (69);
3392 break;
3394 case SIGN_EXTEND:
3395 * total = COSTS_N_INSNS (2);
3396 break;
3398 case ZERO_EXTEND:
3399 * total = COSTS_N_INSNS (1);
3400 break;
3402 case CONST_INT:
3403 * total = 0;
3404 break;
3406 case LABEL_REF:
3407 * total = COSTS_N_INSNS (2);
3408 break;
3410 case CONST:
3412 rtx offset = const0_rtx;
3413 rtx symref = eliminate_constant_term (XEXP (x, 0), & offset);
3415 if (GET_CODE (symref) == LABEL_REF)
3416 * total = COSTS_N_INSNS (2);
3417 else if (GET_CODE (symref) != SYMBOL_REF)
3418 * total = COSTS_N_INSNS (4);
3419 /* Let's be paranoid.... */
3420 else if (INTVAL (offset) < -32768 || INTVAL (offset) > 32767)
3421 * total = COSTS_N_INSNS (2);
3422 else
3423 * total = COSTS_N_INSNS (SYMBOL_REF_FLAG (symref) ? 1 : 2);
3424 break;
3427 case SYMBOL_REF:
3428 * total = COSTS_N_INSNS (SYMBOL_REF_FLAG (x) ? 1 : 2);
3429 break;
3431 case CONST_DOUBLE:
3433 rtx high, low;
3435 split_double (x, & high, & low);
3437 * total = COSTS_N_INSNS ( (high == CONST0_RTX (GET_MODE (high))
3438 || low == CONST0_RTX (GET_MODE (low)))
3439 ? 2 : 4);
3440 break;
3443 default:
3444 return false;
3446 return true;
3449 /* Worker for TARGET_ASM_TRAMPOLINE_TEMPLATE. */
3451 static void
3452 iq2000_asm_trampoline_template (FILE *f)
3454 fprintf (f, "\t.word\t0x03e00821\t\t# move $1,$31\n");
3455 fprintf (f, "\t.word\t0x04110001\t\t# bgezal $0,.+8\n");
3456 fprintf (f, "\t.word\t0x00000000\t\t# nop\n");
3457 if (Pmode == DImode)
3459 fprintf (f, "\t.word\t0xdfe30014\t\t# ld $3,20($31)\n");
3460 fprintf (f, "\t.word\t0xdfe2001c\t\t# ld $2,28($31)\n");
3462 else
3464 fprintf (f, "\t.word\t0x8fe30014\t\t# lw $3,20($31)\n");
3465 fprintf (f, "\t.word\t0x8fe20018\t\t# lw $2,24($31)\n");
3467 fprintf (f, "\t.word\t0x0060c821\t\t# move $25,$3 (abicalls)\n");
3468 fprintf (f, "\t.word\t0x00600008\t\t# jr $3\n");
3469 fprintf (f, "\t.word\t0x0020f821\t\t# move $31,$1\n");
3470 fprintf (f, "\t.word\t0x00000000\t\t# <function address>\n");
3471 fprintf (f, "\t.word\t0x00000000\t\t# <static chain value>\n");
3474 /* Worker for TARGET_TRAMPOLINE_INIT. */
3476 static void
3477 iq2000_trampoline_init (rtx m_tramp, tree fndecl, rtx chain_value)
3479 rtx fnaddr = XEXP (DECL_RTL (fndecl), 0);
3480 rtx mem;
3482 emit_block_move (m_tramp, assemble_trampoline_template (),
3483 GEN_INT (TRAMPOLINE_CODE_SIZE), BLOCK_OP_NORMAL);
3485 mem = adjust_address (m_tramp, Pmode, TRAMPOLINE_CODE_SIZE);
3486 emit_move_insn (mem, fnaddr);
3487 mem = adjust_address (m_tramp, Pmode,
3488 TRAMPOLINE_CODE_SIZE + GET_MODE_SIZE (Pmode));
3489 emit_move_insn (mem, chain_value);
3492 /* Implement TARGET_HARD_REGNO_MODE_OK. */
3494 static bool
3495 iq2000_hard_regno_mode_ok (unsigned int regno, machine_mode mode)
3497 return (REGNO_REG_CLASS (regno) == GR_REGS
3498 ? (regno & 1) == 0 || GET_MODE_SIZE (mode) <= 4
3499 : (regno & 1) == 0 || GET_MODE_SIZE (mode) == 4);
3502 #include "gt-iq2000.h"