PR preprocessor/63831
[official-gcc.git] / gcc / config / iq2000 / iq2000.c
blob161eaf639c0d6197a2f8ca983ceae63c0fb845a4
1 /* Subroutines used for code generation on Vitesse IQ2000 processors
2 Copyright (C) 2003-2014 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 "tm.h"
24 #include "tree.h"
25 #include "stor-layout.h"
26 #include "calls.h"
27 #include "varasm.h"
28 #include "rtl.h"
29 #include "regs.h"
30 #include "hard-reg-set.h"
31 #include "insn-config.h"
32 #include "conditions.h"
33 #include "output.h"
34 #include "insn-attr.h"
35 #include "flags.h"
36 #include "hashtab.h"
37 #include "hash-set.h"
38 #include "vec.h"
39 #include "machmode.h"
40 #include "input.h"
41 #include "function.h"
42 #include "expr.h"
43 #include "insn-codes.h"
44 #include "optabs.h"
45 #include "libfuncs.h"
46 #include "recog.h"
47 #include "diagnostic-core.h"
48 #include "reload.h"
49 #include "ggc.h"
50 #include "tm_p.h"
51 #include "debug.h"
52 #include "target.h"
53 #include "target-def.h"
54 #include "langhooks.h"
55 #include "dominance.h"
56 #include "cfg.h"
57 #include "cfgrtl.h"
58 #include "cfganal.h"
59 #include "lcm.h"
60 #include "cfgbuild.h"
61 #include "cfgcleanup.h"
62 #include "predict.h"
63 #include "basic-block.h"
64 #include "df.h"
65 #include "builtins.h"
67 /* Enumeration for all of the relational tests, so that we can build
68 arrays indexed by the test type, and not worry about the order
69 of EQ, NE, etc. */
71 enum internal_test
73 ITEST_EQ,
74 ITEST_NE,
75 ITEST_GT,
76 ITEST_GE,
77 ITEST_LT,
78 ITEST_LE,
79 ITEST_GTU,
80 ITEST_GEU,
81 ITEST_LTU,
82 ITEST_LEU,
83 ITEST_MAX
86 struct constant;
89 /* Structure to be filled in by compute_frame_size with register
90 save masks, and offsets for the current function. */
92 struct iq2000_frame_info
94 long total_size; /* # bytes that the entire frame takes up. */
95 long var_size; /* # bytes that variables take up. */
96 long args_size; /* # bytes that outgoing arguments take up. */
97 long extra_size; /* # bytes of extra gunk. */
98 int gp_reg_size; /* # bytes needed to store gp regs. */
99 int fp_reg_size; /* # bytes needed to store fp regs. */
100 long mask; /* Mask of saved gp registers. */
101 long gp_save_offset; /* Offset from vfp to store gp registers. */
102 long fp_save_offset; /* Offset from vfp to store fp registers. */
103 long gp_sp_offset; /* Offset from new sp to store gp registers. */
104 long fp_sp_offset; /* Offset from new sp to store fp registers. */
105 int initialized; /* != 0 if frame size already calculated. */
106 int num_gp; /* Number of gp registers saved. */
107 } iq2000_frame_info;
109 struct GTY(()) machine_function
111 /* Current frame information, calculated by compute_frame_size. */
112 long total_size; /* # bytes that the entire frame takes up. */
113 long var_size; /* # bytes that variables take up. */
114 long args_size; /* # bytes that outgoing arguments take up. */
115 long extra_size; /* # bytes of extra gunk. */
116 int gp_reg_size; /* # bytes needed to store gp regs. */
117 int fp_reg_size; /* # bytes needed to store fp regs. */
118 long mask; /* Mask of saved gp registers. */
119 long gp_save_offset; /* Offset from vfp to store gp registers. */
120 long fp_save_offset; /* Offset from vfp to store fp registers. */
121 long gp_sp_offset; /* Offset from new sp to store gp registers. */
122 long fp_sp_offset; /* Offset from new sp to store fp registers. */
123 int initialized; /* != 0 if frame size already calculated. */
124 int num_gp; /* Number of gp registers saved. */
127 /* Global variables for machine-dependent things. */
129 /* List of all IQ2000 punctuation characters used by iq2000_print_operand. */
130 static char iq2000_print_operand_punct[256];
132 /* Which instruction set architecture to use. */
133 int iq2000_isa;
135 /* Local variables. */
137 /* The next branch instruction is a branch likely, not branch normal. */
138 static int iq2000_branch_likely;
140 /* Count of delay slots and how many are filled. */
141 static int dslots_load_total;
142 static int dslots_load_filled;
143 static int dslots_jump_total;
145 /* # of nops needed by previous insn. */
146 static int dslots_number_nops;
148 /* Number of 1/2/3 word references to data items (i.e., not jal's). */
149 static int num_refs[3];
151 /* Registers to check for load delay. */
152 static rtx iq2000_load_reg;
153 static rtx iq2000_load_reg2;
154 static rtx iq2000_load_reg3;
155 static rtx iq2000_load_reg4;
157 /* Mode used for saving/restoring general purpose registers. */
158 static machine_mode gpr_mode;
161 /* Initialize the GCC target structure. */
162 static struct machine_function* iq2000_init_machine_status (void);
163 static void iq2000_option_override (void);
164 static section *iq2000_select_rtx_section (machine_mode, rtx,
165 unsigned HOST_WIDE_INT);
166 static void iq2000_init_builtins (void);
167 static rtx iq2000_expand_builtin (tree, rtx, rtx, machine_mode, int);
168 static bool iq2000_return_in_memory (const_tree, const_tree);
169 static void iq2000_setup_incoming_varargs (cumulative_args_t,
170 machine_mode, tree, int *,
171 int);
172 static bool iq2000_rtx_costs (rtx, int, int, int, int *, bool);
173 static int iq2000_address_cost (rtx, machine_mode, addr_space_t,
174 bool);
175 static section *iq2000_select_section (tree, int, unsigned HOST_WIDE_INT);
176 static rtx iq2000_legitimize_address (rtx, rtx, machine_mode);
177 static bool iq2000_pass_by_reference (cumulative_args_t, machine_mode,
178 const_tree, bool);
179 static int iq2000_arg_partial_bytes (cumulative_args_t, machine_mode,
180 tree, bool);
181 static rtx iq2000_function_arg (cumulative_args_t,
182 machine_mode, const_tree, bool);
183 static void iq2000_function_arg_advance (cumulative_args_t,
184 machine_mode, const_tree, bool);
185 static unsigned int iq2000_function_arg_boundary (machine_mode,
186 const_tree);
187 static void iq2000_va_start (tree, rtx);
188 static bool iq2000_legitimate_address_p (machine_mode, rtx, bool);
189 static bool iq2000_can_eliminate (const int, const int);
190 static void iq2000_asm_trampoline_template (FILE *);
191 static void iq2000_trampoline_init (rtx, tree, rtx);
192 static rtx iq2000_function_value (const_tree, const_tree, bool);
193 static rtx iq2000_libcall_value (machine_mode, const_rtx);
194 static void iq2000_print_operand (FILE *, rtx, int);
195 static void iq2000_print_operand_address (FILE *, rtx);
196 static bool iq2000_print_operand_punct_valid_p (unsigned char code);
198 #undef TARGET_INIT_BUILTINS
199 #define TARGET_INIT_BUILTINS iq2000_init_builtins
200 #undef TARGET_EXPAND_BUILTIN
201 #define TARGET_EXPAND_BUILTIN iq2000_expand_builtin
202 #undef TARGET_ASM_SELECT_RTX_SECTION
203 #define TARGET_ASM_SELECT_RTX_SECTION iq2000_select_rtx_section
204 #undef TARGET_OPTION_OVERRIDE
205 #define TARGET_OPTION_OVERRIDE iq2000_option_override
206 #undef TARGET_RTX_COSTS
207 #define TARGET_RTX_COSTS iq2000_rtx_costs
208 #undef TARGET_ADDRESS_COST
209 #define TARGET_ADDRESS_COST iq2000_address_cost
210 #undef TARGET_ASM_SELECT_SECTION
211 #define TARGET_ASM_SELECT_SECTION iq2000_select_section
213 #undef TARGET_LEGITIMIZE_ADDRESS
214 #define TARGET_LEGITIMIZE_ADDRESS iq2000_legitimize_address
216 /* The assembler supports switchable .bss sections, but
217 iq2000_select_section doesn't yet make use of them. */
218 #undef TARGET_HAVE_SWITCHABLE_BSS_SECTIONS
219 #define TARGET_HAVE_SWITCHABLE_BSS_SECTIONS false
221 #undef TARGET_PRINT_OPERAND
222 #define TARGET_PRINT_OPERAND iq2000_print_operand
223 #undef TARGET_PRINT_OPERAND_ADDRESS
224 #define TARGET_PRINT_OPERAND_ADDRESS iq2000_print_operand_address
225 #undef TARGET_PRINT_OPERAND_PUNCT_VALID_P
226 #define TARGET_PRINT_OPERAND_PUNCT_VALID_P iq2000_print_operand_punct_valid_p
228 #undef TARGET_PROMOTE_FUNCTION_MODE
229 #define TARGET_PROMOTE_FUNCTION_MODE default_promote_function_mode_always_promote
230 #undef TARGET_PROMOTE_PROTOTYPES
231 #define TARGET_PROMOTE_PROTOTYPES hook_bool_const_tree_true
233 #undef TARGET_FUNCTION_VALUE
234 #define TARGET_FUNCTION_VALUE iq2000_function_value
235 #undef TARGET_LIBCALL_VALUE
236 #define TARGET_LIBCALL_VALUE iq2000_libcall_value
237 #undef TARGET_RETURN_IN_MEMORY
238 #define TARGET_RETURN_IN_MEMORY iq2000_return_in_memory
239 #undef TARGET_PASS_BY_REFERENCE
240 #define TARGET_PASS_BY_REFERENCE iq2000_pass_by_reference
241 #undef TARGET_CALLEE_COPIES
242 #define TARGET_CALLEE_COPIES hook_callee_copies_named
243 #undef TARGET_ARG_PARTIAL_BYTES
244 #define TARGET_ARG_PARTIAL_BYTES iq2000_arg_partial_bytes
245 #undef TARGET_FUNCTION_ARG
246 #define TARGET_FUNCTION_ARG iq2000_function_arg
247 #undef TARGET_FUNCTION_ARG_ADVANCE
248 #define TARGET_FUNCTION_ARG_ADVANCE iq2000_function_arg_advance
249 #undef TARGET_FUNCTION_ARG_BOUNDARY
250 #define TARGET_FUNCTION_ARG_BOUNDARY iq2000_function_arg_boundary
252 #undef TARGET_SETUP_INCOMING_VARARGS
253 #define TARGET_SETUP_INCOMING_VARARGS iq2000_setup_incoming_varargs
254 #undef TARGET_STRICT_ARGUMENT_NAMING
255 #define TARGET_STRICT_ARGUMENT_NAMING hook_bool_CUMULATIVE_ARGS_true
257 #undef TARGET_EXPAND_BUILTIN_VA_START
258 #define TARGET_EXPAND_BUILTIN_VA_START iq2000_va_start
260 #undef TARGET_LEGITIMATE_ADDRESS_P
261 #define TARGET_LEGITIMATE_ADDRESS_P iq2000_legitimate_address_p
263 #undef TARGET_CAN_ELIMINATE
264 #define TARGET_CAN_ELIMINATE iq2000_can_eliminate
266 #undef TARGET_ASM_TRAMPOLINE_TEMPLATE
267 #define TARGET_ASM_TRAMPOLINE_TEMPLATE iq2000_asm_trampoline_template
268 #undef TARGET_TRAMPOLINE_INIT
269 #define TARGET_TRAMPOLINE_INIT iq2000_trampoline_init
271 struct gcc_target targetm = TARGET_INITIALIZER;
273 /* Return nonzero if we split the address into high and low parts. */
276 iq2000_check_split (rtx address, machine_mode mode)
278 /* This is the same check used in simple_memory_operand.
279 We use it here because LO_SUM is not offsettable. */
280 if (GET_MODE_SIZE (mode) > (unsigned) UNITS_PER_WORD)
281 return 0;
283 if ((GET_CODE (address) == SYMBOL_REF)
284 || (GET_CODE (address) == CONST
285 && GET_CODE (XEXP (XEXP (address, 0), 0)) == SYMBOL_REF)
286 || GET_CODE (address) == LABEL_REF)
287 return 1;
289 return 0;
292 /* Return nonzero if REG is valid for MODE. */
295 iq2000_reg_mode_ok_for_base_p (rtx reg,
296 machine_mode mode ATTRIBUTE_UNUSED,
297 int strict)
299 return (strict
300 ? REGNO_MODE_OK_FOR_BASE_P (REGNO (reg), mode)
301 : GP_REG_OR_PSEUDO_NONSTRICT_P (REGNO (reg), mode));
304 /* Return a nonzero value if XINSN is a legitimate address for a
305 memory operand of the indicated MODE. STRICT is nonzero if this
306 function is called during reload. */
308 bool
309 iq2000_legitimate_address_p (machine_mode mode, rtx xinsn, bool strict)
311 if (TARGET_DEBUG_A_MODE)
313 GO_PRINTF2 ("\n========== legitimate_address_p, %sstrict\n",
314 strict ? "" : "not ");
315 GO_DEBUG_RTX (xinsn);
318 /* Check for constant before stripping off SUBREG, so that we don't
319 accept (subreg (const_int)) which will fail to reload. */
320 if (CONSTANT_ADDRESS_P (xinsn)
321 && ! (iq2000_check_split (xinsn, mode))
322 && ! (GET_CODE (xinsn) == CONST_INT && ! SMALL_INT (xinsn)))
323 return 1;
325 while (GET_CODE (xinsn) == SUBREG)
326 xinsn = SUBREG_REG (xinsn);
328 if (GET_CODE (xinsn) == REG
329 && iq2000_reg_mode_ok_for_base_p (xinsn, mode, strict))
330 return 1;
332 if (GET_CODE (xinsn) == LO_SUM)
334 rtx xlow0 = XEXP (xinsn, 0);
335 rtx xlow1 = XEXP (xinsn, 1);
337 while (GET_CODE (xlow0) == SUBREG)
338 xlow0 = SUBREG_REG (xlow0);
339 if (GET_CODE (xlow0) == REG
340 && iq2000_reg_mode_ok_for_base_p (xlow0, mode, strict)
341 && iq2000_check_split (xlow1, mode))
342 return 1;
345 if (GET_CODE (xinsn) == PLUS)
347 rtx xplus0 = XEXP (xinsn, 0);
348 rtx xplus1 = XEXP (xinsn, 1);
349 enum rtx_code code0;
350 enum rtx_code code1;
352 while (GET_CODE (xplus0) == SUBREG)
353 xplus0 = SUBREG_REG (xplus0);
354 code0 = GET_CODE (xplus0);
356 while (GET_CODE (xplus1) == SUBREG)
357 xplus1 = SUBREG_REG (xplus1);
358 code1 = GET_CODE (xplus1);
360 if (code0 == REG
361 && iq2000_reg_mode_ok_for_base_p (xplus0, mode, strict))
363 if (code1 == CONST_INT && SMALL_INT (xplus1)
364 && SMALL_INT_UNSIGNED (xplus1) /* No negative offsets */)
365 return 1;
369 if (TARGET_DEBUG_A_MODE)
370 GO_PRINTF ("Not a machine_mode mode, legitimate address\n");
372 /* The address was not legitimate. */
373 return 0;
376 /* Returns an operand string for the given instruction's delay slot,
377 after updating filled delay slot statistics.
379 We assume that operands[0] is the target register that is set.
381 In order to check the next insn, most of this functionality is moved
382 to FINAL_PRESCAN_INSN, and we just set the global variables that
383 it needs. */
385 const char *
386 iq2000_fill_delay_slot (const char *ret, enum delay_type type, rtx operands[],
387 rtx_insn *cur_insn)
389 rtx set_reg;
390 machine_mode mode;
391 rtx_insn *next_insn = cur_insn ? NEXT_INSN (cur_insn) : NULL;
392 int num_nops;
394 if (type == DELAY_LOAD || type == DELAY_FCMP)
395 num_nops = 1;
397 else
398 num_nops = 0;
400 /* Make sure that we don't put nop's after labels. */
401 next_insn = NEXT_INSN (cur_insn);
402 while (next_insn != 0
403 && (NOTE_P (next_insn) || LABEL_P (next_insn)))
404 next_insn = NEXT_INSN (next_insn);
406 dslots_load_total += num_nops;
407 if (TARGET_DEBUG_C_MODE
408 || type == DELAY_NONE
409 || operands == 0
410 || cur_insn == 0
411 || next_insn == 0
412 || LABEL_P (next_insn)
413 || (set_reg = operands[0]) == 0)
415 dslots_number_nops = 0;
416 iq2000_load_reg = 0;
417 iq2000_load_reg2 = 0;
418 iq2000_load_reg3 = 0;
419 iq2000_load_reg4 = 0;
421 return ret;
424 set_reg = operands[0];
425 if (set_reg == 0)
426 return ret;
428 while (GET_CODE (set_reg) == SUBREG)
429 set_reg = SUBREG_REG (set_reg);
431 mode = GET_MODE (set_reg);
432 dslots_number_nops = num_nops;
433 iq2000_load_reg = set_reg;
434 if (GET_MODE_SIZE (mode)
435 > (unsigned) (UNITS_PER_WORD))
436 iq2000_load_reg2 = gen_rtx_REG (SImode, REGNO (set_reg) + 1);
437 else
438 iq2000_load_reg2 = 0;
440 return ret;
443 /* Determine whether a memory reference takes one (based off of the GP
444 pointer), two (normal), or three (label + reg) instructions, and bump the
445 appropriate counter for -mstats. */
447 static void
448 iq2000_count_memory_refs (rtx op, int num)
450 int additional = 0;
451 int n_words = 0;
452 rtx addr, plus0, plus1;
453 enum rtx_code code0, code1;
454 int looping;
456 if (TARGET_DEBUG_B_MODE)
458 fprintf (stderr, "\n========== iq2000_count_memory_refs:\n");
459 debug_rtx (op);
462 /* Skip MEM if passed, otherwise handle movsi of address. */
463 addr = (GET_CODE (op) != MEM) ? op : XEXP (op, 0);
465 /* Loop, going through the address RTL. */
468 looping = FALSE;
469 switch (GET_CODE (addr))
471 case REG:
472 case CONST_INT:
473 case LO_SUM:
474 break;
476 case PLUS:
477 plus0 = XEXP (addr, 0);
478 plus1 = XEXP (addr, 1);
479 code0 = GET_CODE (plus0);
480 code1 = GET_CODE (plus1);
482 if (code0 == REG)
484 additional++;
485 addr = plus1;
486 looping = 1;
487 continue;
490 if (code0 == CONST_INT)
492 addr = plus1;
493 looping = 1;
494 continue;
497 if (code1 == REG)
499 additional++;
500 addr = plus0;
501 looping = 1;
502 continue;
505 if (code1 == CONST_INT)
507 addr = plus0;
508 looping = 1;
509 continue;
512 if (code0 == SYMBOL_REF || code0 == LABEL_REF || code0 == CONST)
514 addr = plus0;
515 looping = 1;
516 continue;
519 if (code1 == SYMBOL_REF || code1 == LABEL_REF || code1 == CONST)
521 addr = plus1;
522 looping = 1;
523 continue;
526 break;
528 case LABEL_REF:
529 n_words = 2; /* Always 2 words. */
530 break;
532 case CONST:
533 addr = XEXP (addr, 0);
534 looping = 1;
535 continue;
537 case SYMBOL_REF:
538 n_words = SYMBOL_REF_FLAG (addr) ? 1 : 2;
539 break;
541 default:
542 break;
545 while (looping);
547 if (n_words == 0)
548 return;
550 n_words += additional;
551 if (n_words > 3)
552 n_words = 3;
554 num_refs[n_words-1] += num;
557 /* Abort after printing out a specific insn. */
559 static void
560 abort_with_insn (rtx insn, const char * reason)
562 error (reason);
563 debug_rtx (insn);
564 fancy_abort (__FILE__, __LINE__, __FUNCTION__);
567 /* Return the appropriate instructions to move one operand to another. */
569 const char *
570 iq2000_move_1word (rtx operands[], rtx_insn *insn, int unsignedp)
572 const char *ret = 0;
573 rtx op0 = operands[0];
574 rtx op1 = operands[1];
575 enum rtx_code code0 = GET_CODE (op0);
576 enum rtx_code code1 = GET_CODE (op1);
577 machine_mode mode = GET_MODE (op0);
578 int subreg_offset0 = 0;
579 int subreg_offset1 = 0;
580 enum delay_type delay = DELAY_NONE;
582 while (code0 == SUBREG)
584 subreg_offset0 += subreg_regno_offset (REGNO (SUBREG_REG (op0)),
585 GET_MODE (SUBREG_REG (op0)),
586 SUBREG_BYTE (op0),
587 GET_MODE (op0));
588 op0 = SUBREG_REG (op0);
589 code0 = GET_CODE (op0);
592 while (code1 == SUBREG)
594 subreg_offset1 += subreg_regno_offset (REGNO (SUBREG_REG (op1)),
595 GET_MODE (SUBREG_REG (op1)),
596 SUBREG_BYTE (op1),
597 GET_MODE (op1));
598 op1 = SUBREG_REG (op1);
599 code1 = GET_CODE (op1);
602 /* For our purposes, a condition code mode is the same as SImode. */
603 if (mode == CCmode)
604 mode = SImode;
606 if (code0 == REG)
608 int regno0 = REGNO (op0) + subreg_offset0;
610 if (code1 == REG)
612 int regno1 = REGNO (op1) + subreg_offset1;
614 /* Do not do anything for assigning a register to itself */
615 if (regno0 == regno1)
616 ret = "";
618 else if (GP_REG_P (regno0))
620 if (GP_REG_P (regno1))
621 ret = "or\t%0,%%0,%1";
626 else if (code1 == MEM)
628 delay = DELAY_LOAD;
630 if (TARGET_STATS)
631 iq2000_count_memory_refs (op1, 1);
633 if (GP_REG_P (regno0))
635 /* For loads, use the mode of the memory item, instead of the
636 target, so zero/sign extend can use this code as well. */
637 switch (GET_MODE (op1))
639 default:
640 break;
641 case SFmode:
642 ret = "lw\t%0,%1";
643 break;
644 case SImode:
645 case CCmode:
646 ret = "lw\t%0,%1";
647 break;
648 case HImode:
649 ret = (unsignedp) ? "lhu\t%0,%1" : "lh\t%0,%1";
650 break;
651 case QImode:
652 ret = (unsignedp) ? "lbu\t%0,%1" : "lb\t%0,%1";
653 break;
658 else if (code1 == CONST_INT
659 || (code1 == CONST_DOUBLE
660 && GET_MODE (op1) == VOIDmode))
662 if (code1 == CONST_DOUBLE)
664 /* This can happen when storing constants into long long
665 bitfields. Just store the least significant word of
666 the value. */
667 operands[1] = op1 = GEN_INT (CONST_DOUBLE_LOW (op1));
670 if (INTVAL (op1) == 0)
672 if (GP_REG_P (regno0))
673 ret = "or\t%0,%%0,%z1";
675 else if (GP_REG_P (regno0))
677 if (SMALL_INT_UNSIGNED (op1))
678 ret = "ori\t%0,%%0,%x1\t\t\t# %1";
679 else if (SMALL_INT (op1))
680 ret = "addiu\t%0,%%0,%1\t\t\t# %1";
681 else
682 ret = "lui\t%0,%X1\t\t\t# %1\n\tori\t%0,%0,%x1";
686 else if (code1 == CONST_DOUBLE && mode == SFmode)
688 if (op1 == CONST0_RTX (SFmode))
690 if (GP_REG_P (regno0))
691 ret = "or\t%0,%%0,%.";
694 else
696 delay = DELAY_LOAD;
697 ret = "li.s\t%0,%1";
701 else if (code1 == LABEL_REF)
703 if (TARGET_STATS)
704 iq2000_count_memory_refs (op1, 1);
706 ret = "la\t%0,%a1";
709 else if (code1 == SYMBOL_REF || code1 == CONST)
711 if (TARGET_STATS)
712 iq2000_count_memory_refs (op1, 1);
714 ret = "la\t%0,%a1";
717 else if (code1 == PLUS)
719 rtx add_op0 = XEXP (op1, 0);
720 rtx add_op1 = XEXP (op1, 1);
722 if (GET_CODE (XEXP (op1, 1)) == REG
723 && GET_CODE (XEXP (op1, 0)) == CONST_INT)
724 add_op0 = XEXP (op1, 1), add_op1 = XEXP (op1, 0);
726 operands[2] = add_op0;
727 operands[3] = add_op1;
728 ret = "add%:\t%0,%2,%3";
731 else if (code1 == HIGH)
733 operands[1] = XEXP (op1, 0);
734 ret = "lui\t%0,%%hi(%1)";
738 else if (code0 == MEM)
740 if (TARGET_STATS)
741 iq2000_count_memory_refs (op0, 1);
743 if (code1 == REG)
745 int regno1 = REGNO (op1) + subreg_offset1;
747 if (GP_REG_P (regno1))
749 switch (mode)
751 case SFmode: ret = "sw\t%1,%0"; break;
752 case SImode: ret = "sw\t%1,%0"; break;
753 case HImode: ret = "sh\t%1,%0"; break;
754 case QImode: ret = "sb\t%1,%0"; break;
755 default: break;
760 else if (code1 == CONST_INT && INTVAL (op1) == 0)
762 switch (mode)
764 case SFmode: ret = "sw\t%z1,%0"; break;
765 case SImode: ret = "sw\t%z1,%0"; break;
766 case HImode: ret = "sh\t%z1,%0"; break;
767 case QImode: ret = "sb\t%z1,%0"; break;
768 default: break;
772 else if (code1 == CONST_DOUBLE && op1 == CONST0_RTX (mode))
774 switch (mode)
776 case SFmode: ret = "sw\t%.,%0"; break;
777 case SImode: ret = "sw\t%.,%0"; break;
778 case HImode: ret = "sh\t%.,%0"; break;
779 case QImode: ret = "sb\t%.,%0"; break;
780 default: break;
785 if (ret == 0)
787 abort_with_insn (insn, "Bad move");
788 return 0;
791 if (delay != DELAY_NONE)
792 return iq2000_fill_delay_slot (ret, delay, operands, insn);
794 return ret;
797 /* Provide the costs of an addressing mode that contains ADDR. */
799 static int
800 iq2000_address_cost (rtx addr, machine_mode mode, addr_space_t as,
801 bool speed)
803 switch (GET_CODE (addr))
805 case LO_SUM:
806 return 1;
808 case LABEL_REF:
809 return 2;
811 case CONST:
813 rtx offset = const0_rtx;
815 addr = eliminate_constant_term (XEXP (addr, 0), & offset);
816 if (GET_CODE (addr) == LABEL_REF)
817 return 2;
819 if (GET_CODE (addr) != SYMBOL_REF)
820 return 4;
822 if (! SMALL_INT (offset))
823 return 2;
826 /* Fall through. */
828 case SYMBOL_REF:
829 return SYMBOL_REF_FLAG (addr) ? 1 : 2;
831 case PLUS:
833 rtx plus0 = XEXP (addr, 0);
834 rtx plus1 = XEXP (addr, 1);
836 if (GET_CODE (plus0) != REG && GET_CODE (plus1) == REG)
837 plus0 = XEXP (addr, 1), plus1 = XEXP (addr, 0);
839 if (GET_CODE (plus0) != REG)
840 break;
842 switch (GET_CODE (plus1))
844 case CONST_INT:
845 return SMALL_INT (plus1) ? 1 : 2;
847 case CONST:
848 case SYMBOL_REF:
849 case LABEL_REF:
850 case HIGH:
851 case LO_SUM:
852 return iq2000_address_cost (plus1, mode, as, speed) + 1;
854 default:
855 break;
859 default:
860 break;
863 return 4;
866 /* Make normal rtx_code into something we can index from an array. */
868 static enum internal_test
869 map_test_to_internal_test (enum rtx_code test_code)
871 enum internal_test test = ITEST_MAX;
873 switch (test_code)
875 case EQ: test = ITEST_EQ; break;
876 case NE: test = ITEST_NE; break;
877 case GT: test = ITEST_GT; break;
878 case GE: test = ITEST_GE; break;
879 case LT: test = ITEST_LT; break;
880 case LE: test = ITEST_LE; break;
881 case GTU: test = ITEST_GTU; break;
882 case GEU: test = ITEST_GEU; break;
883 case LTU: test = ITEST_LTU; break;
884 case LEU: test = ITEST_LEU; break;
885 default: break;
888 return test;
891 /* Generate the code to do a TEST_CODE comparison on two integer values CMP0
892 and CMP1. P_INVERT is NULL or ptr if branch needs to reverse its test.
893 The return value RESULT is:
894 (reg:SI xx) The pseudo register the comparison is in
895 0 No register, generate a simple branch. */
898 gen_int_relational (enum rtx_code test_code, rtx result, rtx cmp0, rtx cmp1,
899 int *p_invert)
901 struct cmp_info
903 enum rtx_code test_code; /* Code to use in instruction (LT vs. LTU). */
904 int const_low; /* Low bound of constant we can accept. */
905 int const_high; /* High bound of constant we can accept. */
906 int const_add; /* Constant to add (convert LE -> LT). */
907 int reverse_regs; /* Reverse registers in test. */
908 int invert_const; /* != 0 if invert value if cmp1 is constant. */
909 int invert_reg; /* != 0 if invert value if cmp1 is register. */
910 int unsignedp; /* != 0 for unsigned comparisons. */
913 static struct cmp_info info[ (int)ITEST_MAX ] =
915 { XOR, 0, 65535, 0, 0, 0, 0, 0 }, /* EQ */
916 { XOR, 0, 65535, 0, 0, 1, 1, 0 }, /* NE */
917 { LT, -32769, 32766, 1, 1, 1, 0, 0 }, /* GT */
918 { LT, -32768, 32767, 0, 0, 1, 1, 0 }, /* GE */
919 { LT, -32768, 32767, 0, 0, 0, 0, 0 }, /* LT */
920 { LT, -32769, 32766, 1, 1, 0, 1, 0 }, /* LE */
921 { LTU, -32769, 32766, 1, 1, 1, 0, 1 }, /* GTU */
922 { LTU, -32768, 32767, 0, 0, 1, 1, 1 }, /* GEU */
923 { LTU, -32768, 32767, 0, 0, 0, 0, 1 }, /* LTU */
924 { LTU, -32769, 32766, 1, 1, 0, 1, 1 }, /* LEU */
927 enum internal_test test;
928 machine_mode mode;
929 struct cmp_info *p_info;
930 int branch_p;
931 int eqne_p;
932 int invert;
933 rtx reg;
934 rtx reg2;
936 test = map_test_to_internal_test (test_code);
937 gcc_assert (test != ITEST_MAX);
939 p_info = &info[(int) test];
940 eqne_p = (p_info->test_code == XOR);
942 mode = GET_MODE (cmp0);
943 if (mode == VOIDmode)
944 mode = GET_MODE (cmp1);
946 /* Eliminate simple branches. */
947 branch_p = (result == 0);
948 if (branch_p)
950 if (GET_CODE (cmp0) == REG || GET_CODE (cmp0) == SUBREG)
952 /* Comparisons against zero are simple branches. */
953 if (GET_CODE (cmp1) == CONST_INT && INTVAL (cmp1) == 0)
954 return 0;
956 /* Test for beq/bne. */
957 if (eqne_p)
958 return 0;
961 /* Allocate a pseudo to calculate the value in. */
962 result = gen_reg_rtx (mode);
965 /* Make sure we can handle any constants given to us. */
966 if (GET_CODE (cmp0) == CONST_INT)
967 cmp0 = force_reg (mode, cmp0);
969 if (GET_CODE (cmp1) == CONST_INT)
971 HOST_WIDE_INT value = INTVAL (cmp1);
973 if (value < p_info->const_low
974 || value > p_info->const_high)
975 cmp1 = force_reg (mode, cmp1);
978 /* See if we need to invert the result. */
979 invert = (GET_CODE (cmp1) == CONST_INT
980 ? p_info->invert_const : p_info->invert_reg);
982 if (p_invert != (int *)0)
984 *p_invert = invert;
985 invert = 0;
988 /* Comparison to constants, may involve adding 1 to change a LT into LE.
989 Comparison between two registers, may involve switching operands. */
990 if (GET_CODE (cmp1) == CONST_INT)
992 if (p_info->const_add != 0)
994 HOST_WIDE_INT new_const = INTVAL (cmp1) + p_info->const_add;
996 /* If modification of cmp1 caused overflow,
997 we would get the wrong answer if we follow the usual path;
998 thus, x > 0xffffffffU would turn into x > 0U. */
999 if ((p_info->unsignedp
1000 ? (unsigned HOST_WIDE_INT) new_const >
1001 (unsigned HOST_WIDE_INT) INTVAL (cmp1)
1002 : new_const > INTVAL (cmp1))
1003 != (p_info->const_add > 0))
1005 /* This test is always true, but if INVERT is true then
1006 the result of the test needs to be inverted so 0 should
1007 be returned instead. */
1008 emit_move_insn (result, invert ? const0_rtx : const_true_rtx);
1009 return result;
1011 else
1012 cmp1 = GEN_INT (new_const);
1016 else if (p_info->reverse_regs)
1018 rtx temp = cmp0;
1019 cmp0 = cmp1;
1020 cmp1 = temp;
1023 if (test == ITEST_NE && GET_CODE (cmp1) == CONST_INT && INTVAL (cmp1) == 0)
1024 reg = cmp0;
1025 else
1027 reg = (invert || eqne_p) ? gen_reg_rtx (mode) : result;
1028 convert_move (reg, gen_rtx_fmt_ee (p_info->test_code, mode, cmp0, cmp1), 0);
1031 if (test == ITEST_NE)
1033 convert_move (result, gen_rtx_GTU (mode, reg, const0_rtx), 0);
1034 if (p_invert != NULL)
1035 *p_invert = 0;
1036 invert = 0;
1039 else if (test == ITEST_EQ)
1041 reg2 = invert ? gen_reg_rtx (mode) : result;
1042 convert_move (reg2, gen_rtx_LTU (mode, reg, const1_rtx), 0);
1043 reg = reg2;
1046 if (invert)
1048 rtx one;
1050 one = const1_rtx;
1051 convert_move (result, gen_rtx_XOR (mode, reg, one), 0);
1054 return result;
1057 /* Emit the common code for doing conditional branches.
1058 operand[0] is the label to jump to.
1059 The comparison operands are saved away by cmp{si,di,sf,df}. */
1061 void
1062 gen_conditional_branch (rtx operands[], machine_mode mode)
1064 enum rtx_code test_code = GET_CODE (operands[0]);
1065 rtx cmp0 = operands[1];
1066 rtx cmp1 = operands[2];
1067 rtx reg;
1068 int invert;
1069 rtx label1, label2;
1071 invert = 0;
1072 reg = gen_int_relational (test_code, NULL_RTX, cmp0, cmp1, &invert);
1074 if (reg)
1076 cmp0 = reg;
1077 cmp1 = const0_rtx;
1078 test_code = NE;
1080 else if (GET_CODE (cmp1) == CONST_INT && INTVAL (cmp1) != 0)
1081 /* We don't want to build a comparison against a nonzero
1082 constant. */
1083 cmp1 = force_reg (mode, cmp1);
1085 /* Generate the branch. */
1086 label1 = gen_rtx_LABEL_REF (VOIDmode, operands[3]);
1087 label2 = pc_rtx;
1089 if (invert)
1091 label2 = label1;
1092 label1 = pc_rtx;
1095 emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
1096 gen_rtx_IF_THEN_ELSE (VOIDmode,
1097 gen_rtx_fmt_ee (test_code,
1098 VOIDmode,
1099 cmp0, cmp1),
1100 label1, label2)));
1103 /* Initialize CUM for a function FNTYPE. */
1105 void
1106 init_cumulative_args (CUMULATIVE_ARGS *cum, tree fntype,
1107 rtx libname ATTRIBUTE_UNUSED)
1109 static CUMULATIVE_ARGS zero_cum;
1110 tree param;
1111 tree next_param;
1113 if (TARGET_DEBUG_D_MODE)
1115 fprintf (stderr,
1116 "\ninit_cumulative_args, fntype = 0x%.8lx", (long) fntype);
1118 if (!fntype)
1119 fputc ('\n', stderr);
1121 else
1123 tree ret_type = TREE_TYPE (fntype);
1125 fprintf (stderr, ", fntype code = %s, ret code = %s\n",
1126 get_tree_code_name (TREE_CODE (fntype)),
1127 get_tree_code_name (TREE_CODE (ret_type)));
1131 *cum = zero_cum;
1133 /* Determine if this function has variable arguments. This is
1134 indicated by the last argument being 'void_type_mode' if there
1135 are no variable arguments. The standard IQ2000 calling sequence
1136 passes all arguments in the general purpose registers in this case. */
1138 for (param = fntype ? TYPE_ARG_TYPES (fntype) : 0;
1139 param != 0; param = next_param)
1141 next_param = TREE_CHAIN (param);
1142 if (next_param == 0 && TREE_VALUE (param) != void_type_node)
1143 cum->gp_reg_found = 1;
1147 /* Advance the argument of type TYPE and mode MODE to the next argument
1148 position in CUM. */
1150 static void
1151 iq2000_function_arg_advance (cumulative_args_t cum_v, machine_mode mode,
1152 const_tree type, bool named)
1154 CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
1156 if (TARGET_DEBUG_D_MODE)
1158 fprintf (stderr,
1159 "function_adv({gp reg found = %d, arg # = %2d, words = %2d}, %4s, ",
1160 cum->gp_reg_found, cum->arg_number, cum->arg_words,
1161 GET_MODE_NAME (mode));
1162 fprintf (stderr, "%p", (const void *) type);
1163 fprintf (stderr, ", %d )\n\n", named);
1166 cum->arg_number++;
1167 switch (mode)
1169 case VOIDmode:
1170 break;
1172 default:
1173 gcc_assert (GET_MODE_CLASS (mode) == MODE_COMPLEX_INT
1174 || GET_MODE_CLASS (mode) == MODE_COMPLEX_FLOAT);
1176 cum->gp_reg_found = 1;
1177 cum->arg_words += ((GET_MODE_SIZE (mode) + UNITS_PER_WORD - 1)
1178 / UNITS_PER_WORD);
1179 break;
1181 case BLKmode:
1182 cum->gp_reg_found = 1;
1183 cum->arg_words += ((int_size_in_bytes (type) + UNITS_PER_WORD - 1)
1184 / UNITS_PER_WORD);
1185 break;
1187 case SFmode:
1188 cum->arg_words ++;
1189 if (! cum->gp_reg_found && cum->arg_number <= 2)
1190 cum->fp_code += 1 << ((cum->arg_number - 1) * 2);
1191 break;
1193 case DFmode:
1194 cum->arg_words += 2;
1195 if (! cum->gp_reg_found && cum->arg_number <= 2)
1196 cum->fp_code += 2 << ((cum->arg_number - 1) * 2);
1197 break;
1199 case DImode:
1200 cum->gp_reg_found = 1;
1201 cum->arg_words += 2;
1202 break;
1204 case TImode:
1205 cum->gp_reg_found = 1;
1206 cum->arg_words += 4;
1207 break;
1209 case QImode:
1210 case HImode:
1211 case SImode:
1212 cum->gp_reg_found = 1;
1213 cum->arg_words ++;
1214 break;
1218 /* Return an RTL expression containing the register for the given mode MODE
1219 and type TYPE in CUM, or 0 if the argument is to be passed on the stack. */
1221 static rtx
1222 iq2000_function_arg (cumulative_args_t cum_v, machine_mode mode,
1223 const_tree type, bool named)
1225 CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
1226 rtx ret;
1227 int regbase = -1;
1228 int bias = 0;
1229 unsigned int *arg_words = &cum->arg_words;
1230 int struct_p = (type != 0
1231 && (TREE_CODE (type) == RECORD_TYPE
1232 || TREE_CODE (type) == UNION_TYPE
1233 || TREE_CODE (type) == QUAL_UNION_TYPE));
1235 if (TARGET_DEBUG_D_MODE)
1237 fprintf (stderr,
1238 "function_arg( {gp reg found = %d, arg # = %2d, words = %2d}, %4s, ",
1239 cum->gp_reg_found, cum->arg_number, cum->arg_words,
1240 GET_MODE_NAME (mode));
1241 fprintf (stderr, "%p", (const void *) type);
1242 fprintf (stderr, ", %d ) = ", named);
1246 cum->last_arg_fp = 0;
1247 switch (mode)
1249 case SFmode:
1250 regbase = GP_ARG_FIRST;
1251 break;
1253 case DFmode:
1254 cum->arg_words += cum->arg_words & 1;
1256 regbase = GP_ARG_FIRST;
1257 break;
1259 default:
1260 gcc_assert (GET_MODE_CLASS (mode) == MODE_COMPLEX_INT
1261 || GET_MODE_CLASS (mode) == MODE_COMPLEX_FLOAT);
1263 /* Drops through. */
1264 case BLKmode:
1265 if (type != NULL_TREE && TYPE_ALIGN (type) > (unsigned) BITS_PER_WORD)
1266 cum->arg_words += (cum->arg_words & 1);
1267 regbase = GP_ARG_FIRST;
1268 break;
1270 case VOIDmode:
1271 case QImode:
1272 case HImode:
1273 case SImode:
1274 regbase = GP_ARG_FIRST;
1275 break;
1277 case DImode:
1278 cum->arg_words += (cum->arg_words & 1);
1279 regbase = GP_ARG_FIRST;
1280 break;
1282 case TImode:
1283 cum->arg_words += (cum->arg_words & 3);
1284 regbase = GP_ARG_FIRST;
1285 break;
1288 if (*arg_words >= (unsigned) MAX_ARGS_IN_REGISTERS)
1290 if (TARGET_DEBUG_D_MODE)
1291 fprintf (stderr, "<stack>%s\n", struct_p ? ", [struct]" : "");
1293 ret = 0;
1295 else
1297 gcc_assert (regbase != -1);
1299 if (! type || TREE_CODE (type) != RECORD_TYPE
1300 || ! named || ! TYPE_SIZE_UNIT (type)
1301 || ! tree_fits_uhwi_p (TYPE_SIZE_UNIT (type)))
1302 ret = gen_rtx_REG (mode, regbase + *arg_words + bias);
1303 else
1305 tree field;
1307 for (field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
1308 if (TREE_CODE (field) == FIELD_DECL
1309 && TREE_CODE (TREE_TYPE (field)) == REAL_TYPE
1310 && TYPE_PRECISION (TREE_TYPE (field)) == BITS_PER_WORD
1311 && tree_fits_shwi_p (bit_position (field))
1312 && int_bit_position (field) % BITS_PER_WORD == 0)
1313 break;
1315 /* If the whole struct fits a DFmode register,
1316 we don't need the PARALLEL. */
1317 if (! field || mode == DFmode)
1318 ret = gen_rtx_REG (mode, regbase + *arg_words + bias);
1319 else
1321 unsigned int chunks;
1322 HOST_WIDE_INT bitpos;
1323 unsigned int regno;
1324 unsigned int i;
1326 /* ??? If this is a packed structure, then the last hunk won't
1327 be 64 bits. */
1328 chunks
1329 = tree_to_uhwi (TYPE_SIZE_UNIT (type)) / UNITS_PER_WORD;
1330 if (chunks + *arg_words + bias > (unsigned) MAX_ARGS_IN_REGISTERS)
1331 chunks = MAX_ARGS_IN_REGISTERS - *arg_words - bias;
1333 /* Assign_parms checks the mode of ENTRY_PARM, so we must
1334 use the actual mode here. */
1335 ret = gen_rtx_PARALLEL (mode, rtvec_alloc (chunks));
1337 bitpos = 0;
1338 regno = regbase + *arg_words + bias;
1339 field = TYPE_FIELDS (type);
1340 for (i = 0; i < chunks; i++)
1342 rtx reg;
1344 for (; field; field = DECL_CHAIN (field))
1345 if (TREE_CODE (field) == FIELD_DECL
1346 && int_bit_position (field) >= bitpos)
1347 break;
1349 if (field
1350 && int_bit_position (field) == bitpos
1351 && TREE_CODE (TREE_TYPE (field)) == REAL_TYPE
1352 && TYPE_PRECISION (TREE_TYPE (field)) == BITS_PER_WORD)
1353 reg = gen_rtx_REG (DFmode, regno++);
1354 else
1355 reg = gen_rtx_REG (word_mode, regno);
1357 XVECEXP (ret, 0, i)
1358 = gen_rtx_EXPR_LIST (VOIDmode, reg,
1359 GEN_INT (bitpos / BITS_PER_UNIT));
1361 bitpos += 64;
1362 regno++;
1367 if (TARGET_DEBUG_D_MODE)
1368 fprintf (stderr, "%s%s\n", reg_names[regbase + *arg_words + bias],
1369 struct_p ? ", [struct]" : "");
1372 /* We will be called with a mode of VOIDmode after the last argument
1373 has been seen. Whatever we return will be passed to the call
1374 insn. If we need any shifts for small structures, return them in
1375 a PARALLEL. */
1376 if (mode == VOIDmode)
1378 if (cum->num_adjusts > 0)
1379 ret = gen_rtx_PARALLEL ((machine_mode) cum->fp_code,
1380 gen_rtvec_v (cum->num_adjusts, cum->adjust));
1383 return ret;
1386 static unsigned int
1387 iq2000_function_arg_boundary (machine_mode mode, const_tree type)
1389 return (type != NULL_TREE
1390 ? (TYPE_ALIGN (type) <= PARM_BOUNDARY
1391 ? PARM_BOUNDARY
1392 : TYPE_ALIGN (type))
1393 : (GET_MODE_ALIGNMENT (mode) <= PARM_BOUNDARY
1394 ? PARM_BOUNDARY
1395 : GET_MODE_ALIGNMENT (mode)));
1398 static int
1399 iq2000_arg_partial_bytes (cumulative_args_t cum_v, machine_mode mode,
1400 tree type ATTRIBUTE_UNUSED,
1401 bool named ATTRIBUTE_UNUSED)
1403 CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
1405 if (mode == DImode && cum->arg_words == MAX_ARGS_IN_REGISTERS - 1)
1407 if (TARGET_DEBUG_D_MODE)
1408 fprintf (stderr, "iq2000_arg_partial_bytes=%d\n", UNITS_PER_WORD);
1409 return UNITS_PER_WORD;
1412 return 0;
1415 /* Implement va_start. */
1417 static void
1418 iq2000_va_start (tree valist, rtx nextarg)
1420 int int_arg_words;
1421 /* Find out how many non-float named formals. */
1422 int gpr_save_area_size;
1423 /* Note UNITS_PER_WORD is 4 bytes. */
1424 int_arg_words = crtl->args.info.arg_words;
1426 if (int_arg_words < 8 )
1427 /* Adjust for the prologue's economy measure. */
1428 gpr_save_area_size = (8 - int_arg_words) * UNITS_PER_WORD;
1429 else
1430 gpr_save_area_size = 0;
1432 /* Everything is in the GPR save area, or in the overflow
1433 area which is contiguous with it. */
1434 nextarg = plus_constant (Pmode, nextarg, - gpr_save_area_size);
1435 std_expand_builtin_va_start (valist, nextarg);
1438 /* Allocate a chunk of memory for per-function machine-dependent data. */
1440 static struct machine_function *
1441 iq2000_init_machine_status (void)
1443 return ggc_cleared_alloc<machine_function> ();
1446 /* Detect any conflicts in the switches. */
1448 static void
1449 iq2000_option_override (void)
1451 target_flags &= ~MASK_GPOPT;
1453 iq2000_isa = IQ2000_ISA_DEFAULT;
1455 /* Identify the processor type. */
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;
1466 iq2000_print_operand_punct['['] = 1;
1467 iq2000_print_operand_punct[']'] = 1;
1468 iq2000_print_operand_punct['<'] = 1;
1469 iq2000_print_operand_punct['>'] = 1;
1470 iq2000_print_operand_punct['{'] = 1;
1471 iq2000_print_operand_punct['}'] = 1;
1472 iq2000_print_operand_punct['^'] = 1;
1473 iq2000_print_operand_punct['$'] = 1;
1474 iq2000_print_operand_punct['+'] = 1;
1475 iq2000_print_operand_punct['~'] = 1;
1477 /* Save GPR registers in word_mode sized hunks. word_mode hasn't been
1478 initialized yet, so we can't use that here. */
1479 gpr_mode = SImode;
1481 /* Function to allocate machine-dependent function status. */
1482 init_machine_status = iq2000_init_machine_status;
1485 /* The arg pointer (which is eliminated) points to the virtual frame pointer,
1486 while the frame pointer (which may be eliminated) points to the stack
1487 pointer after the initial adjustments. */
1489 HOST_WIDE_INT
1490 iq2000_debugger_offset (rtx addr, HOST_WIDE_INT offset)
1492 rtx offset2 = const0_rtx;
1493 rtx reg = eliminate_constant_term (addr, & offset2);
1495 if (offset == 0)
1496 offset = INTVAL (offset2);
1498 if (reg == stack_pointer_rtx || reg == frame_pointer_rtx
1499 || reg == hard_frame_pointer_rtx)
1501 HOST_WIDE_INT frame_size = (!cfun->machine->initialized)
1502 ? compute_frame_size (get_frame_size ())
1503 : cfun->machine->total_size;
1505 offset = offset - frame_size;
1508 return offset;
1511 /* If defined, a C statement to be executed just prior to the output of
1512 assembler code for INSN, to modify the extracted operands so they will be
1513 output differently.
1515 Here the argument OPVEC is the vector containing the operands extracted
1516 from INSN, and NOPERANDS is the number of elements of the vector which
1517 contain meaningful data for this insn. The contents of this vector are
1518 what will be used to convert the insn template into assembler code, so you
1519 can change the assembler output by changing the contents of the vector.
1521 We use it to check if the current insn needs a nop in front of it because
1522 of load delays, and also to update the delay slot statistics. */
1524 void
1525 final_prescan_insn (rtx_insn *insn, rtx opvec[] ATTRIBUTE_UNUSED,
1526 int noperands ATTRIBUTE_UNUSED)
1528 if (dslots_number_nops > 0)
1530 rtx pattern = PATTERN (insn);
1531 int length = get_attr_length (insn);
1533 /* Do we need to emit a NOP? */
1534 if (length == 0
1535 || (iq2000_load_reg != 0 && reg_mentioned_p (iq2000_load_reg, pattern))
1536 || (iq2000_load_reg2 != 0 && reg_mentioned_p (iq2000_load_reg2, pattern))
1537 || (iq2000_load_reg3 != 0 && reg_mentioned_p (iq2000_load_reg3, pattern))
1538 || (iq2000_load_reg4 != 0
1539 && reg_mentioned_p (iq2000_load_reg4, pattern)))
1540 fputs ("\tnop\n", asm_out_file);
1542 else
1543 dslots_load_filled ++;
1545 while (--dslots_number_nops > 0)
1546 fputs ("\tnop\n", asm_out_file);
1548 iq2000_load_reg = 0;
1549 iq2000_load_reg2 = 0;
1550 iq2000_load_reg3 = 0;
1551 iq2000_load_reg4 = 0;
1554 if ( (JUMP_P (insn)
1555 || CALL_P (insn)
1556 || (GET_CODE (PATTERN (insn)) == RETURN))
1557 && NEXT_INSN (PREV_INSN (insn)) == insn)
1559 rtx_insn *nop_insn = emit_insn_after (gen_nop (), insn);
1561 INSN_ADDRESSES_NEW (nop_insn, -1);
1564 if (TARGET_STATS
1565 && (JUMP_P (insn) || CALL_P (insn)))
1566 dslots_jump_total ++;
1569 /* Return the bytes needed to compute the frame pointer from the current
1570 stack pointer where SIZE is the # of var. bytes allocated.
1572 IQ2000 stack frames look like:
1574 Before call After call
1575 +-----------------------+ +-----------------------+
1576 high | | | |
1577 mem. | | | |
1578 | caller's temps. | | caller's temps. |
1579 | | | |
1580 +-----------------------+ +-----------------------+
1581 | | | |
1582 | arguments on stack. | | arguments on stack. |
1583 | | | |
1584 +-----------------------+ +-----------------------+
1585 | 4 words to save | | 4 words to save |
1586 | arguments passed | | arguments passed |
1587 | in registers, even | | in registers, even |
1588 SP->| if not passed. | VFP->| if not passed. |
1589 +-----------------------+ +-----------------------+
1591 | fp register save |
1593 +-----------------------+
1595 | gp register save |
1597 +-----------------------+
1599 | local variables |
1601 +-----------------------+
1603 | alloca allocations |
1605 +-----------------------+
1607 | GP save for V.4 abi |
1609 +-----------------------+
1611 | arguments on stack |
1613 +-----------------------+
1614 | 4 words to save |
1615 | arguments passed |
1616 | in registers, even |
1617 low SP->| if not passed. |
1618 memory +-----------------------+ */
1620 HOST_WIDE_INT
1621 compute_frame_size (HOST_WIDE_INT size)
1623 int regno;
1624 HOST_WIDE_INT total_size; /* # bytes that the entire frame takes up. */
1625 HOST_WIDE_INT var_size; /* # bytes that variables take up. */
1626 HOST_WIDE_INT args_size; /* # bytes that outgoing arguments take up. */
1627 HOST_WIDE_INT extra_size; /* # extra bytes. */
1628 HOST_WIDE_INT gp_reg_rounded; /* # bytes needed to store gp after rounding. */
1629 HOST_WIDE_INT gp_reg_size; /* # bytes needed to store gp regs. */
1630 HOST_WIDE_INT fp_reg_size; /* # bytes needed to store fp regs. */
1631 long mask; /* mask of saved gp registers. */
1633 gp_reg_size = 0;
1634 fp_reg_size = 0;
1635 mask = 0;
1636 extra_size = IQ2000_STACK_ALIGN ((0));
1637 var_size = IQ2000_STACK_ALIGN (size);
1638 args_size = IQ2000_STACK_ALIGN (crtl->outgoing_args_size);
1640 /* If a function dynamically allocates the stack and
1641 has 0 for STACK_DYNAMIC_OFFSET then allocate some stack space. */
1642 if (args_size == 0 && cfun->calls_alloca)
1643 args_size = 4 * UNITS_PER_WORD;
1645 total_size = var_size + args_size + extra_size;
1647 /* Calculate space needed for gp registers. */
1648 for (regno = GP_REG_FIRST; regno <= GP_REG_LAST; regno++)
1650 if (MUST_SAVE_REGISTER (regno))
1652 gp_reg_size += GET_MODE_SIZE (gpr_mode);
1653 mask |= 1L << (regno - GP_REG_FIRST);
1657 /* We need to restore these for the handler. */
1658 if (crtl->calls_eh_return)
1660 unsigned int i;
1662 for (i = 0; ; ++i)
1664 regno = EH_RETURN_DATA_REGNO (i);
1665 if (regno == (int) INVALID_REGNUM)
1666 break;
1667 gp_reg_size += GET_MODE_SIZE (gpr_mode);
1668 mask |= 1L << (regno - GP_REG_FIRST);
1672 gp_reg_rounded = IQ2000_STACK_ALIGN (gp_reg_size);
1673 total_size += gp_reg_rounded + IQ2000_STACK_ALIGN (fp_reg_size);
1675 /* The gp reg is caller saved, so there is no need for leaf routines
1676 (total_size == extra_size) to save the gp reg. */
1677 if (total_size == extra_size
1678 && ! profile_flag)
1679 total_size = extra_size = 0;
1681 total_size += IQ2000_STACK_ALIGN (crtl->args.pretend_args_size);
1683 /* Save other computed information. */
1684 cfun->machine->total_size = total_size;
1685 cfun->machine->var_size = var_size;
1686 cfun->machine->args_size = args_size;
1687 cfun->machine->extra_size = extra_size;
1688 cfun->machine->gp_reg_size = gp_reg_size;
1689 cfun->machine->fp_reg_size = fp_reg_size;
1690 cfun->machine->mask = mask;
1691 cfun->machine->initialized = reload_completed;
1692 cfun->machine->num_gp = gp_reg_size / UNITS_PER_WORD;
1694 if (mask)
1696 unsigned long offset;
1698 offset = (args_size + extra_size + var_size
1699 + gp_reg_size - GET_MODE_SIZE (gpr_mode));
1701 cfun->machine->gp_sp_offset = offset;
1702 cfun->machine->gp_save_offset = offset - total_size;
1704 else
1706 cfun->machine->gp_sp_offset = 0;
1707 cfun->machine->gp_save_offset = 0;
1710 cfun->machine->fp_sp_offset = 0;
1711 cfun->machine->fp_save_offset = 0;
1713 /* Ok, we're done. */
1714 return total_size;
1718 /* We can always eliminate to the frame pointer. We can eliminate to the
1719 stack pointer unless a frame pointer is needed. */
1721 bool
1722 iq2000_can_eliminate (const int from, const int to)
1724 return (from == RETURN_ADDRESS_POINTER_REGNUM
1725 && (! leaf_function_p ()
1726 || (to == GP_REG_FIRST + 31 && leaf_function_p ())))
1727 || (from != RETURN_ADDRESS_POINTER_REGNUM
1728 && (to == HARD_FRAME_POINTER_REGNUM
1729 || (to == STACK_POINTER_REGNUM
1730 && ! frame_pointer_needed)));
1733 /* Implement INITIAL_ELIMINATION_OFFSET. FROM is either the frame
1734 pointer, argument pointer, or return address pointer. TO is either
1735 the stack pointer or hard frame pointer. */
1738 iq2000_initial_elimination_offset (int from, int to ATTRIBUTE_UNUSED)
1740 int offset;
1742 compute_frame_size (get_frame_size ());
1743 if ((from) == FRAME_POINTER_REGNUM)
1744 (offset) = 0;
1745 else if ((from) == ARG_POINTER_REGNUM)
1746 (offset) = (cfun->machine->total_size);
1747 else if ((from) == RETURN_ADDRESS_POINTER_REGNUM)
1749 if (leaf_function_p ())
1750 (offset) = 0;
1751 else (offset) = cfun->machine->gp_sp_offset
1752 + ((UNITS_PER_WORD - (POINTER_SIZE / BITS_PER_UNIT))
1753 * (BYTES_BIG_ENDIAN != 0));
1755 else
1756 gcc_unreachable ();
1758 return offset;
1761 /* Common code to emit the insns (or to write the instructions to a file)
1762 to save/restore registers.
1763 Other parts of the code assume that IQ2000_TEMP1_REGNUM (aka large_reg)
1764 is not modified within save_restore_insns. */
1766 #define BITSET_P(VALUE,BIT) (((VALUE) & (1L << (BIT))) != 0)
1768 /* Emit instructions to load the value (SP + OFFSET) into IQ2000_TEMP2_REGNUM
1769 and return an rtl expression for the register. Write the assembly
1770 instructions directly to FILE if it is not null, otherwise emit them as
1771 rtl.
1773 This function is a subroutine of save_restore_insns. It is used when
1774 OFFSET is too large to add in a single instruction. */
1776 static rtx
1777 iq2000_add_large_offset_to_sp (HOST_WIDE_INT offset)
1779 rtx reg = gen_rtx_REG (Pmode, IQ2000_TEMP2_REGNUM);
1780 rtx offset_rtx = GEN_INT (offset);
1782 emit_move_insn (reg, offset_rtx);
1783 emit_insn (gen_addsi3 (reg, reg, stack_pointer_rtx));
1784 return reg;
1787 /* Make INSN frame related and note that it performs the frame-related
1788 operation DWARF_PATTERN. */
1790 static void
1791 iq2000_annotate_frame_insn (rtx_insn *insn, rtx dwarf_pattern)
1793 RTX_FRAME_RELATED_P (insn) = 1;
1794 REG_NOTES (insn) = alloc_EXPR_LIST (REG_FRAME_RELATED_EXPR,
1795 dwarf_pattern,
1796 REG_NOTES (insn));
1799 /* Emit a move instruction that stores REG in MEM. Make the instruction
1800 frame related and note that it stores REG at (SP + OFFSET). */
1802 static void
1803 iq2000_emit_frame_related_store (rtx mem, rtx reg, HOST_WIDE_INT offset)
1805 rtx dwarf_address = plus_constant (Pmode, stack_pointer_rtx, offset);
1806 rtx dwarf_mem = gen_rtx_MEM (GET_MODE (reg), dwarf_address);
1808 iq2000_annotate_frame_insn (emit_move_insn (mem, reg),
1809 gen_rtx_SET (GET_MODE (reg), dwarf_mem, reg));
1812 /* Emit instructions to save/restore registers, as determined by STORE_P. */
1814 static void
1815 save_restore_insns (int store_p)
1817 long mask = cfun->machine->mask;
1818 int regno;
1819 rtx base_reg_rtx;
1820 HOST_WIDE_INT base_offset;
1821 HOST_WIDE_INT gp_offset;
1822 HOST_WIDE_INT end_offset;
1824 gcc_assert (!frame_pointer_needed
1825 || BITSET_P (mask, HARD_FRAME_POINTER_REGNUM - GP_REG_FIRST));
1827 if (mask == 0)
1829 base_reg_rtx = 0, base_offset = 0;
1830 return;
1833 /* Save registers starting from high to low. The debuggers prefer at least
1834 the return register be stored at func+4, and also it allows us not to
1835 need a nop in the epilog if at least one register is reloaded in
1836 addition to return address. */
1838 /* Save GP registers if needed. */
1839 /* Pick which pointer to use as a base register. For small frames, just
1840 use the stack pointer. Otherwise, use a temporary register. Save 2
1841 cycles if the save area is near the end of a large frame, by reusing
1842 the constant created in the prologue/epilogue to adjust the stack
1843 frame. */
1845 gp_offset = cfun->machine->gp_sp_offset;
1846 end_offset
1847 = gp_offset - (cfun->machine->gp_reg_size
1848 - GET_MODE_SIZE (gpr_mode));
1850 if (gp_offset < 0 || end_offset < 0)
1851 internal_error
1852 ("gp_offset (%ld) or end_offset (%ld) is less than zero",
1853 (long) gp_offset, (long) end_offset);
1855 else if (gp_offset < 32768)
1856 base_reg_rtx = stack_pointer_rtx, base_offset = 0;
1857 else
1859 int regno;
1860 int reg_save_count = 0;
1862 for (regno = GP_REG_LAST; regno >= GP_REG_FIRST; regno--)
1863 if (BITSET_P (mask, regno - GP_REG_FIRST)) reg_save_count += 1;
1864 base_offset = gp_offset - ((reg_save_count - 1) * 4);
1865 base_reg_rtx = iq2000_add_large_offset_to_sp (base_offset);
1868 for (regno = GP_REG_LAST; regno >= GP_REG_FIRST; regno--)
1870 if (BITSET_P (mask, regno - GP_REG_FIRST))
1872 rtx reg_rtx;
1873 rtx mem_rtx
1874 = gen_rtx_MEM (gpr_mode,
1875 gen_rtx_PLUS (Pmode, base_reg_rtx,
1876 GEN_INT (gp_offset - base_offset)));
1878 reg_rtx = gen_rtx_REG (gpr_mode, regno);
1880 if (store_p)
1881 iq2000_emit_frame_related_store (mem_rtx, reg_rtx, gp_offset);
1882 else
1884 emit_move_insn (reg_rtx, mem_rtx);
1886 gp_offset -= GET_MODE_SIZE (gpr_mode);
1891 /* Expand the prologue into a bunch of separate insns. */
1893 void
1894 iq2000_expand_prologue (void)
1896 int regno;
1897 HOST_WIDE_INT tsize;
1898 int last_arg_is_vararg_marker = 0;
1899 tree fndecl = current_function_decl;
1900 tree fntype = TREE_TYPE (fndecl);
1901 tree fnargs = DECL_ARGUMENTS (fndecl);
1902 rtx next_arg_reg;
1903 int i;
1904 tree next_arg;
1905 tree cur_arg;
1906 CUMULATIVE_ARGS args_so_far_v;
1907 cumulative_args_t args_so_far;
1908 int store_args_on_stack = (iq2000_can_use_return_insn ());
1910 /* If struct value address is treated as the first argument. */
1911 if (aggregate_value_p (DECL_RESULT (fndecl), fndecl)
1912 && !cfun->returns_pcc_struct
1913 && targetm.calls.struct_value_rtx (TREE_TYPE (fndecl), 1) == 0)
1915 tree type = build_pointer_type (fntype);
1916 tree function_result_decl = build_decl (BUILTINS_LOCATION,
1917 PARM_DECL, NULL_TREE, type);
1919 DECL_ARG_TYPE (function_result_decl) = type;
1920 DECL_CHAIN (function_result_decl) = fnargs;
1921 fnargs = function_result_decl;
1924 /* For arguments passed in registers, find the register number
1925 of the first argument in the variable part of the argument list,
1926 otherwise GP_ARG_LAST+1. Note also if the last argument is
1927 the varargs special argument, and treat it as part of the
1928 variable arguments.
1930 This is only needed if store_args_on_stack is true. */
1931 INIT_CUMULATIVE_ARGS (args_so_far_v, fntype, NULL_RTX, 0, 0);
1932 args_so_far = pack_cumulative_args (&args_so_far_v);
1933 regno = GP_ARG_FIRST;
1935 for (cur_arg = fnargs; cur_arg != 0; cur_arg = next_arg)
1937 tree passed_type = DECL_ARG_TYPE (cur_arg);
1938 machine_mode passed_mode = TYPE_MODE (passed_type);
1939 rtx entry_parm;
1941 if (TREE_ADDRESSABLE (passed_type))
1943 passed_type = build_pointer_type (passed_type);
1944 passed_mode = Pmode;
1947 entry_parm = iq2000_function_arg (args_so_far, passed_mode,
1948 passed_type, true);
1950 iq2000_function_arg_advance (args_so_far, passed_mode,
1951 passed_type, true);
1952 next_arg = DECL_CHAIN (cur_arg);
1954 if (entry_parm && store_args_on_stack)
1956 if (next_arg == 0
1957 && DECL_NAME (cur_arg)
1958 && ((0 == strcmp (IDENTIFIER_POINTER (DECL_NAME (cur_arg)),
1959 "__builtin_va_alist"))
1960 || (0 == strcmp (IDENTIFIER_POINTER (DECL_NAME (cur_arg)),
1961 "va_alist"))))
1963 last_arg_is_vararg_marker = 1;
1964 break;
1966 else
1968 int words;
1970 gcc_assert (GET_CODE (entry_parm) == REG);
1972 /* Passed in a register, so will get homed automatically. */
1973 if (GET_MODE (entry_parm) == BLKmode)
1974 words = (int_size_in_bytes (passed_type) + 3) / 4;
1975 else
1976 words = (GET_MODE_SIZE (GET_MODE (entry_parm)) + 3) / 4;
1978 regno = REGNO (entry_parm) + words - 1;
1981 else
1983 regno = GP_ARG_LAST+1;
1984 break;
1988 /* In order to pass small structures by value in registers we need to
1989 shift the value into the high part of the register.
1990 iq2000_unction_arg has encoded a PARALLEL rtx, holding a vector of
1991 adjustments to be made as the next_arg_reg variable, so we split up
1992 the insns, and emit them separately. */
1993 next_arg_reg = iq2000_function_arg (args_so_far, VOIDmode,
1994 void_type_node, true);
1995 if (next_arg_reg != 0 && GET_CODE (next_arg_reg) == PARALLEL)
1997 rtvec adjust = XVEC (next_arg_reg, 0);
1998 int num = GET_NUM_ELEM (adjust);
2000 for (i = 0; i < num; i++)
2002 rtx pattern;
2004 pattern = RTVEC_ELT (adjust, i);
2005 if (GET_CODE (pattern) != SET
2006 || GET_CODE (SET_SRC (pattern)) != ASHIFT)
2007 abort_with_insn (pattern, "Insn is not a shift");
2008 PUT_CODE (SET_SRC (pattern), ASHIFTRT);
2010 emit_insn (pattern);
2014 tsize = compute_frame_size (get_frame_size ());
2016 /* If this function is a varargs function, store any registers that
2017 would normally hold arguments ($4 - $7) on the stack. */
2018 if (store_args_on_stack
2019 && (stdarg_p (fntype)
2020 || last_arg_is_vararg_marker))
2022 int offset = (regno - GP_ARG_FIRST) * UNITS_PER_WORD;
2023 rtx ptr = stack_pointer_rtx;
2025 for (; regno <= GP_ARG_LAST; regno++)
2027 if (offset != 0)
2028 ptr = gen_rtx_PLUS (Pmode, stack_pointer_rtx, GEN_INT (offset));
2029 emit_move_insn (gen_rtx_MEM (gpr_mode, ptr),
2030 gen_rtx_REG (gpr_mode, regno));
2032 offset += GET_MODE_SIZE (gpr_mode);
2036 if (tsize > 0)
2038 rtx tsize_rtx = GEN_INT (tsize);
2039 rtx adjustment_rtx, dwarf_pattern;
2040 rtx_insn *insn;
2042 if (tsize > 32767)
2044 adjustment_rtx = gen_rtx_REG (Pmode, IQ2000_TEMP1_REGNUM);
2045 emit_move_insn (adjustment_rtx, tsize_rtx);
2047 else
2048 adjustment_rtx = tsize_rtx;
2050 insn = emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
2051 adjustment_rtx));
2053 dwarf_pattern = gen_rtx_SET (Pmode, stack_pointer_rtx,
2054 plus_constant (Pmode, stack_pointer_rtx,
2055 -tsize));
2057 iq2000_annotate_frame_insn (insn, dwarf_pattern);
2059 save_restore_insns (1);
2061 if (frame_pointer_needed)
2063 rtx_insn *insn = 0;
2065 insn = emit_insn (gen_movsi (hard_frame_pointer_rtx,
2066 stack_pointer_rtx));
2068 if (insn)
2069 RTX_FRAME_RELATED_P (insn) = 1;
2073 emit_insn (gen_blockage ());
2076 /* Expand the epilogue into a bunch of separate insns. */
2078 void
2079 iq2000_expand_epilogue (void)
2081 HOST_WIDE_INT tsize = cfun->machine->total_size;
2082 rtx tsize_rtx = GEN_INT (tsize);
2083 rtx tmp_rtx = (rtx)0;
2085 if (iq2000_can_use_return_insn ())
2087 emit_jump_insn (gen_return ());
2088 return;
2091 if (tsize > 32767)
2093 tmp_rtx = gen_rtx_REG (Pmode, IQ2000_TEMP1_REGNUM);
2094 emit_move_insn (tmp_rtx, tsize_rtx);
2095 tsize_rtx = tmp_rtx;
2098 if (tsize > 0)
2100 if (frame_pointer_needed)
2102 emit_insn (gen_blockage ());
2104 emit_insn (gen_movsi (stack_pointer_rtx, hard_frame_pointer_rtx));
2107 save_restore_insns (0);
2109 if (crtl->calls_eh_return)
2111 rtx eh_ofs = EH_RETURN_STACKADJ_RTX;
2112 emit_insn (gen_addsi3 (eh_ofs, eh_ofs, tsize_rtx));
2113 tsize_rtx = eh_ofs;
2116 emit_insn (gen_blockage ());
2118 if (tsize != 0 || crtl->calls_eh_return)
2120 emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx,
2121 tsize_rtx));
2125 if (crtl->calls_eh_return)
2127 /* Perform the additional bump for __throw. */
2128 emit_move_insn (gen_rtx_REG (Pmode, HARD_FRAME_POINTER_REGNUM),
2129 stack_pointer_rtx);
2130 emit_use (gen_rtx_REG (Pmode, HARD_FRAME_POINTER_REGNUM));
2131 emit_jump_insn (gen_eh_return_internal ());
2133 else
2134 emit_jump_insn (gen_return_internal (gen_rtx_REG (Pmode,
2135 GP_REG_FIRST + 31)));
2138 void
2139 iq2000_expand_eh_return (rtx address)
2141 HOST_WIDE_INT gp_offset = cfun->machine->gp_sp_offset;
2142 rtx scratch;
2144 scratch = plus_constant (Pmode, stack_pointer_rtx, gp_offset);
2145 emit_move_insn (gen_rtx_MEM (GET_MODE (address), scratch), address);
2148 /* Return nonzero if this function is known to have a null epilogue.
2149 This allows the optimizer to omit jumps to jumps if no stack
2150 was created. */
2153 iq2000_can_use_return_insn (void)
2155 if (! reload_completed)
2156 return 0;
2158 if (df_regs_ever_live_p (31) || profile_flag)
2159 return 0;
2161 if (cfun->machine->initialized)
2162 return cfun->machine->total_size == 0;
2164 return compute_frame_size (get_frame_size ()) == 0;
2167 /* Choose the section to use for the constant rtx expression X that has
2168 mode MODE. */
2170 static section *
2171 iq2000_select_rtx_section (machine_mode mode, rtx x ATTRIBUTE_UNUSED,
2172 unsigned HOST_WIDE_INT align)
2174 /* For embedded applications, always put constants in read-only data,
2175 in order to reduce RAM usage. */
2176 return mergeable_constant_section (mode, align, 0);
2179 /* Choose the section to use for DECL. RELOC is true if its value contains
2180 any relocatable expression.
2182 Some of the logic used here needs to be replicated in
2183 ENCODE_SECTION_INFO in iq2000.h so that references to these symbols
2184 are done correctly. */
2186 static section *
2187 iq2000_select_section (tree decl, int reloc ATTRIBUTE_UNUSED,
2188 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED)
2190 if (TARGET_EMBEDDED_DATA)
2192 /* For embedded applications, always put an object in read-only data
2193 if possible, in order to reduce RAM usage. */
2194 if ((TREE_CODE (decl) == VAR_DECL
2195 && TREE_READONLY (decl) && !TREE_SIDE_EFFECTS (decl)
2196 && DECL_INITIAL (decl)
2197 && (DECL_INITIAL (decl) == error_mark_node
2198 || TREE_CONSTANT (DECL_INITIAL (decl))))
2199 /* Deal with calls from output_constant_def_contents. */
2200 || TREE_CODE (decl) != VAR_DECL)
2201 return readonly_data_section;
2202 else
2203 return data_section;
2205 else
2207 /* For hosted applications, always put an object in small data if
2208 possible, as this gives the best performance. */
2209 if ((TREE_CODE (decl) == VAR_DECL
2210 && TREE_READONLY (decl) && !TREE_SIDE_EFFECTS (decl)
2211 && DECL_INITIAL (decl)
2212 && (DECL_INITIAL (decl) == error_mark_node
2213 || TREE_CONSTANT (DECL_INITIAL (decl))))
2214 /* Deal with calls from output_constant_def_contents. */
2215 || TREE_CODE (decl) != VAR_DECL)
2216 return readonly_data_section;
2217 else
2218 return data_section;
2221 /* Return register to use for a function return value with VALTYPE for function
2222 FUNC. */
2224 static rtx
2225 iq2000_function_value (const_tree valtype,
2226 const_tree fn_decl_or_type,
2227 bool outgoing ATTRIBUTE_UNUSED)
2229 int reg = GP_RETURN;
2230 machine_mode mode = TYPE_MODE (valtype);
2231 int unsignedp = TYPE_UNSIGNED (valtype);
2232 const_tree func = fn_decl_or_type;
2234 if (fn_decl_or_type
2235 && !DECL_P (fn_decl_or_type))
2236 fn_decl_or_type = NULL;
2238 /* Since we promote return types, we must promote the mode here too. */
2239 mode = promote_function_mode (valtype, mode, &unsignedp, func, 1);
2241 return gen_rtx_REG (mode, reg);
2244 /* Worker function for TARGET_LIBCALL_VALUE. */
2246 static rtx
2247 iq2000_libcall_value (machine_mode mode, const_rtx fun ATTRIBUTE_UNUSED)
2249 return gen_rtx_REG (((GET_MODE_CLASS (mode) != MODE_INT
2250 || GET_MODE_SIZE (mode) >= 4)
2251 ? mode : SImode),
2252 GP_RETURN);
2255 /* Worker function for FUNCTION_VALUE_REGNO_P.
2257 On the IQ2000, R2 and R3 are the only register thus used. */
2259 bool
2260 iq2000_function_value_regno_p (const unsigned int regno)
2262 return (regno == GP_RETURN);
2266 /* Return true when an argument must be passed by reference. */
2268 static bool
2269 iq2000_pass_by_reference (cumulative_args_t cum_v, machine_mode mode,
2270 const_tree type, bool named ATTRIBUTE_UNUSED)
2272 CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
2273 int size;
2275 /* We must pass by reference if we would be both passing in registers
2276 and the stack. This is because any subsequent partial arg would be
2277 handled incorrectly in this case. */
2278 if (cum && targetm.calls.must_pass_in_stack (mode, type))
2280 /* Don't pass the actual CUM to FUNCTION_ARG, because we would
2281 get double copies of any offsets generated for small structs
2282 passed in registers. */
2283 CUMULATIVE_ARGS temp;
2285 temp = *cum;
2286 if (iq2000_function_arg (pack_cumulative_args (&temp), mode, type, named)
2287 != 0)
2288 return 1;
2291 if (type == NULL_TREE || mode == DImode || mode == DFmode)
2292 return 0;
2294 size = int_size_in_bytes (type);
2295 return size == -1 || size > UNITS_PER_WORD;
2298 /* Return the length of INSN. LENGTH is the initial length computed by
2299 attributes in the machine-description file. */
2302 iq2000_adjust_insn_length (rtx_insn *insn, int length)
2304 /* A unconditional jump has an unfilled delay slot if it is not part
2305 of a sequence. A conditional jump normally has a delay slot. */
2306 if (simplejump_p (insn)
2307 || ( (JUMP_P (insn)
2308 || CALL_P (insn))))
2309 length += 4;
2311 return length;
2314 /* Output assembly instructions to perform a conditional branch.
2316 INSN is the branch instruction. OPERANDS[0] is the condition.
2317 OPERANDS[1] is the target of the branch. OPERANDS[2] is the target
2318 of the first operand to the condition. If TWO_OPERANDS_P is
2319 nonzero the comparison takes two operands; OPERANDS[3] will be the
2320 second operand.
2322 If INVERTED_P is nonzero we are to branch if the condition does
2323 not hold. If FLOAT_P is nonzero this is a floating-point comparison.
2325 LENGTH is the length (in bytes) of the sequence we are to generate.
2326 That tells us whether to generate a simple conditional branch, or a
2327 reversed conditional branch around a `jr' instruction. */
2329 char *
2330 iq2000_output_conditional_branch (rtx_insn *insn, rtx * operands,
2331 int two_operands_p, int float_p,
2332 int inverted_p, int length)
2334 static char buffer[200];
2335 /* The kind of comparison we are doing. */
2336 enum rtx_code code = GET_CODE (operands[0]);
2337 /* Nonzero if the opcode for the comparison needs a `z' indicating
2338 that it is a comparison against zero. */
2339 int need_z_p;
2340 /* A string to use in the assembly output to represent the first
2341 operand. */
2342 const char *op1 = "%z2";
2343 /* A string to use in the assembly output to represent the second
2344 operand. Use the hard-wired zero register if there's no second
2345 operand. */
2346 const char *op2 = (two_operands_p ? ",%z3" : ",%.");
2347 /* The operand-printing string for the comparison. */
2348 const char *comp = (float_p ? "%F0" : "%C0");
2349 /* The operand-printing string for the inverted comparison. */
2350 const char *inverted_comp = (float_p ? "%W0" : "%N0");
2352 /* Likely variants of each branch instruction annul the instruction
2353 in the delay slot if the branch is not taken. */
2354 iq2000_branch_likely = (final_sequence && INSN_ANNULLED_BRANCH_P (insn));
2356 if (!two_operands_p)
2358 /* To compute whether than A > B, for example, we normally
2359 subtract B from A and then look at the sign bit. But, if we
2360 are doing an unsigned comparison, and B is zero, we don't
2361 have to do the subtraction. Instead, we can just check to
2362 see if A is nonzero. Thus, we change the CODE here to
2363 reflect the simpler comparison operation. */
2364 switch (code)
2366 case GTU:
2367 code = NE;
2368 break;
2370 case LEU:
2371 code = EQ;
2372 break;
2374 case GEU:
2375 /* A condition which will always be true. */
2376 code = EQ;
2377 op1 = "%.";
2378 break;
2380 case LTU:
2381 /* A condition which will always be false. */
2382 code = NE;
2383 op1 = "%.";
2384 break;
2386 default:
2387 /* Not a special case. */
2388 break;
2392 /* Relative comparisons are always done against zero. But
2393 equality comparisons are done between two operands, and therefore
2394 do not require a `z' in the assembly language output. */
2395 need_z_p = (!float_p && code != EQ && code != NE);
2396 /* For comparisons against zero, the zero is not provided
2397 explicitly. */
2398 if (need_z_p)
2399 op2 = "";
2401 /* Begin by terminating the buffer. That way we can always use
2402 strcat to add to it. */
2403 buffer[0] = '\0';
2405 switch (length)
2407 case 4:
2408 case 8:
2409 /* Just a simple conditional branch. */
2410 if (float_p)
2411 sprintf (buffer, "b%s%%?\t%%Z2%%1",
2412 inverted_p ? inverted_comp : comp);
2413 else
2414 sprintf (buffer, "b%s%s%%?\t%s%s,%%1",
2415 inverted_p ? inverted_comp : comp,
2416 need_z_p ? "z" : "",
2417 op1,
2418 op2);
2419 return buffer;
2421 case 12:
2422 case 16:
2424 /* Generate a reversed conditional branch around ` j'
2425 instruction:
2427 .set noreorder
2428 .set nomacro
2429 bc l
2431 j target
2432 .set macro
2433 .set reorder
2436 Because we have to jump four bytes *past* the following
2437 instruction if this branch was annulled, we can't just use
2438 a label, as in the picture above; there's no way to put the
2439 label after the next instruction, as the assembler does not
2440 accept `.L+4' as the target of a branch. (We can't just
2441 wait until the next instruction is output; it might be a
2442 macro and take up more than four bytes. Once again, we see
2443 why we want to eliminate macros.)
2445 If the branch is annulled, we jump four more bytes that we
2446 would otherwise; that way we skip the annulled instruction
2447 in the delay slot. */
2449 const char *target
2450 = ((iq2000_branch_likely || length == 16) ? ".+16" : ".+12");
2451 char *c;
2453 c = strchr (buffer, '\0');
2454 /* Generate the reversed comparison. This takes four
2455 bytes. */
2456 if (float_p)
2457 sprintf (c, "b%s\t%%Z2%s",
2458 inverted_p ? comp : inverted_comp,
2459 target);
2460 else
2461 sprintf (c, "b%s%s\t%s%s,%s",
2462 inverted_p ? comp : inverted_comp,
2463 need_z_p ? "z" : "",
2464 op1,
2465 op2,
2466 target);
2467 strcat (c, "\n\tnop\n\tj\t%1");
2468 if (length == 16)
2469 /* The delay slot was unfilled. Since we're inside
2470 .noreorder, the assembler will not fill in the NOP for
2471 us, so we must do it ourselves. */
2472 strcat (buffer, "\n\tnop");
2473 return buffer;
2476 default:
2477 gcc_unreachable ();
2480 /* NOTREACHED */
2481 return 0;
2484 #define def_builtin(NAME, TYPE, CODE) \
2485 add_builtin_function ((NAME), (TYPE), (CODE), BUILT_IN_MD, \
2486 NULL, NULL_TREE)
2488 static void
2489 iq2000_init_builtins (void)
2491 tree void_ftype, void_ftype_int, void_ftype_int_int;
2492 tree void_ftype_int_int_int;
2493 tree int_ftype_int, int_ftype_int_int, int_ftype_int_int_int;
2494 tree int_ftype_int_int_int_int;
2496 /* func () */
2497 void_ftype
2498 = build_function_type_list (void_type_node, NULL_TREE);
2500 /* func (int) */
2501 void_ftype_int
2502 = build_function_type_list (void_type_node, integer_type_node, NULL_TREE);
2504 /* void func (int, int) */
2505 void_ftype_int_int
2506 = build_function_type_list (void_type_node,
2507 integer_type_node,
2508 integer_type_node,
2509 NULL_TREE);
2511 /* int func (int) */
2512 int_ftype_int
2513 = build_function_type_list (integer_type_node,
2514 integer_type_node, NULL_TREE);
2516 /* int func (int, int) */
2517 int_ftype_int_int
2518 = build_function_type_list (integer_type_node,
2519 integer_type_node,
2520 integer_type_node,
2521 NULL_TREE);
2523 /* void func (int, int, int) */
2524 void_ftype_int_int_int
2525 = build_function_type_list (void_type_node,
2526 integer_type_node,
2527 integer_type_node,
2528 integer_type_node,
2529 NULL_TREE);
2531 /* int func (int, int, int) */
2532 int_ftype_int_int_int
2533 = build_function_type_list (integer_type_node,
2534 integer_type_node,
2535 integer_type_node,
2536 integer_type_node,
2537 NULL_TREE);
2539 /* int func (int, int, int, int) */
2540 int_ftype_int_int_int_int
2541 = build_function_type_list (integer_type_node,
2542 integer_type_node,
2543 integer_type_node,
2544 integer_type_node,
2545 integer_type_node,
2546 NULL_TREE);
2548 def_builtin ("__builtin_ado16", int_ftype_int_int, IQ2000_BUILTIN_ADO16);
2549 def_builtin ("__builtin_ram", int_ftype_int_int_int_int, IQ2000_BUILTIN_RAM);
2550 def_builtin ("__builtin_chkhdr", void_ftype_int_int, IQ2000_BUILTIN_CHKHDR);
2551 def_builtin ("__builtin_pkrl", void_ftype_int_int, IQ2000_BUILTIN_PKRL);
2552 def_builtin ("__builtin_cfc0", int_ftype_int, IQ2000_BUILTIN_CFC0);
2553 def_builtin ("__builtin_cfc1", int_ftype_int, IQ2000_BUILTIN_CFC1);
2554 def_builtin ("__builtin_cfc2", int_ftype_int, IQ2000_BUILTIN_CFC2);
2555 def_builtin ("__builtin_cfc3", int_ftype_int, IQ2000_BUILTIN_CFC3);
2556 def_builtin ("__builtin_ctc0", void_ftype_int_int, IQ2000_BUILTIN_CTC0);
2557 def_builtin ("__builtin_ctc1", void_ftype_int_int, IQ2000_BUILTIN_CTC1);
2558 def_builtin ("__builtin_ctc2", void_ftype_int_int, IQ2000_BUILTIN_CTC2);
2559 def_builtin ("__builtin_ctc3", void_ftype_int_int, IQ2000_BUILTIN_CTC3);
2560 def_builtin ("__builtin_mfc0", int_ftype_int, IQ2000_BUILTIN_MFC0);
2561 def_builtin ("__builtin_mfc1", int_ftype_int, IQ2000_BUILTIN_MFC1);
2562 def_builtin ("__builtin_mfc2", int_ftype_int, IQ2000_BUILTIN_MFC2);
2563 def_builtin ("__builtin_mfc3", int_ftype_int, IQ2000_BUILTIN_MFC3);
2564 def_builtin ("__builtin_mtc0", void_ftype_int_int, IQ2000_BUILTIN_MTC0);
2565 def_builtin ("__builtin_mtc1", void_ftype_int_int, IQ2000_BUILTIN_MTC1);
2566 def_builtin ("__builtin_mtc2", void_ftype_int_int, IQ2000_BUILTIN_MTC2);
2567 def_builtin ("__builtin_mtc3", void_ftype_int_int, IQ2000_BUILTIN_MTC3);
2568 def_builtin ("__builtin_lur", void_ftype_int_int, IQ2000_BUILTIN_LUR);
2569 def_builtin ("__builtin_rb", void_ftype_int_int, IQ2000_BUILTIN_RB);
2570 def_builtin ("__builtin_rx", void_ftype_int_int, IQ2000_BUILTIN_RX);
2571 def_builtin ("__builtin_srrd", void_ftype_int, IQ2000_BUILTIN_SRRD);
2572 def_builtin ("__builtin_srwr", void_ftype_int_int, IQ2000_BUILTIN_SRWR);
2573 def_builtin ("__builtin_wb", void_ftype_int_int, IQ2000_BUILTIN_WB);
2574 def_builtin ("__builtin_wx", void_ftype_int_int, IQ2000_BUILTIN_WX);
2575 def_builtin ("__builtin_luc32l", void_ftype_int_int, IQ2000_BUILTIN_LUC32L);
2576 def_builtin ("__builtin_luc64", void_ftype_int_int, IQ2000_BUILTIN_LUC64);
2577 def_builtin ("__builtin_luc64l", void_ftype_int_int, IQ2000_BUILTIN_LUC64L);
2578 def_builtin ("__builtin_luk", void_ftype_int_int, IQ2000_BUILTIN_LUK);
2579 def_builtin ("__builtin_lulck", void_ftype_int, IQ2000_BUILTIN_LULCK);
2580 def_builtin ("__builtin_lum32", void_ftype_int_int, IQ2000_BUILTIN_LUM32);
2581 def_builtin ("__builtin_lum32l", void_ftype_int_int, IQ2000_BUILTIN_LUM32L);
2582 def_builtin ("__builtin_lum64", void_ftype_int_int, IQ2000_BUILTIN_LUM64);
2583 def_builtin ("__builtin_lum64l", void_ftype_int_int, IQ2000_BUILTIN_LUM64L);
2584 def_builtin ("__builtin_lurl", void_ftype_int_int, IQ2000_BUILTIN_LURL);
2585 def_builtin ("__builtin_mrgb", int_ftype_int_int_int, IQ2000_BUILTIN_MRGB);
2586 def_builtin ("__builtin_srrdl", void_ftype_int, IQ2000_BUILTIN_SRRDL);
2587 def_builtin ("__builtin_srulck", void_ftype_int, IQ2000_BUILTIN_SRULCK);
2588 def_builtin ("__builtin_srwru", void_ftype_int_int, IQ2000_BUILTIN_SRWRU);
2589 def_builtin ("__builtin_trapqfl", void_ftype, IQ2000_BUILTIN_TRAPQFL);
2590 def_builtin ("__builtin_trapqne", void_ftype, IQ2000_BUILTIN_TRAPQNE);
2591 def_builtin ("__builtin_traprel", void_ftype_int, IQ2000_BUILTIN_TRAPREL);
2592 def_builtin ("__builtin_wbu", void_ftype_int_int_int, IQ2000_BUILTIN_WBU);
2593 def_builtin ("__builtin_syscall", void_ftype, IQ2000_BUILTIN_SYSCALL);
2596 /* Builtin for ICODE having ARGCOUNT args in EXP where each arg
2597 has an rtx CODE. */
2599 static rtx
2600 expand_one_builtin (enum insn_code icode, rtx target, tree exp,
2601 enum rtx_code *code, int argcount)
2603 rtx pat;
2604 tree arg [5];
2605 rtx op [5];
2606 machine_mode mode [5];
2607 int i;
2609 mode[0] = insn_data[icode].operand[0].mode;
2610 for (i = 0; i < argcount; i++)
2612 arg[i] = CALL_EXPR_ARG (exp, i);
2613 op[i] = expand_normal (arg[i]);
2614 mode[i] = insn_data[icode].operand[i].mode;
2615 if (code[i] == CONST_INT && GET_CODE (op[i]) != CONST_INT)
2616 error ("argument %qd is not a constant", i + 1);
2617 if (code[i] == REG
2618 && ! (*insn_data[icode].operand[i].predicate) (op[i], mode[i]))
2619 op[i] = copy_to_mode_reg (mode[i], op[i]);
2622 if (insn_data[icode].operand[0].constraint[0] == '=')
2624 if (target == 0
2625 || GET_MODE (target) != mode[0]
2626 || ! (*insn_data[icode].operand[0].predicate) (target, mode[0]))
2627 target = gen_reg_rtx (mode[0]);
2629 else
2630 target = 0;
2632 switch (argcount)
2634 case 0:
2635 pat = GEN_FCN (icode) (target);
2636 case 1:
2637 if (target)
2638 pat = GEN_FCN (icode) (target, op[0]);
2639 else
2640 pat = GEN_FCN (icode) (op[0]);
2641 break;
2642 case 2:
2643 if (target)
2644 pat = GEN_FCN (icode) (target, op[0], op[1]);
2645 else
2646 pat = GEN_FCN (icode) (op[0], op[1]);
2647 break;
2648 case 3:
2649 if (target)
2650 pat = GEN_FCN (icode) (target, op[0], op[1], op[2]);
2651 else
2652 pat = GEN_FCN (icode) (op[0], op[1], op[2]);
2653 break;
2654 case 4:
2655 if (target)
2656 pat = GEN_FCN (icode) (target, op[0], op[1], op[2], op[3]);
2657 else
2658 pat = GEN_FCN (icode) (op[0], op[1], op[2], op[3]);
2659 break;
2660 default:
2661 gcc_unreachable ();
2664 if (! pat)
2665 return 0;
2666 emit_insn (pat);
2667 return target;
2670 /* Expand an expression EXP that calls a built-in function,
2671 with result going to TARGET if that's convenient
2672 (and in mode MODE if that's convenient).
2673 SUBTARGET may be used as the target for computing one of EXP's operands.
2674 IGNORE is nonzero if the value is to be ignored. */
2676 static rtx
2677 iq2000_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED,
2678 machine_mode mode ATTRIBUTE_UNUSED,
2679 int ignore ATTRIBUTE_UNUSED)
2681 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
2682 int fcode = DECL_FUNCTION_CODE (fndecl);
2683 enum rtx_code code [5];
2685 code[0] = REG;
2686 code[1] = REG;
2687 code[2] = REG;
2688 code[3] = REG;
2689 code[4] = REG;
2690 switch (fcode)
2692 default:
2693 break;
2695 case IQ2000_BUILTIN_ADO16:
2696 return expand_one_builtin (CODE_FOR_ado16, target, exp, code, 2);
2698 case IQ2000_BUILTIN_RAM:
2699 code[1] = CONST_INT;
2700 code[2] = CONST_INT;
2701 code[3] = CONST_INT;
2702 return expand_one_builtin (CODE_FOR_ram, target, exp, code, 4);
2704 case IQ2000_BUILTIN_CHKHDR:
2705 return expand_one_builtin (CODE_FOR_chkhdr, target, exp, code, 2);
2707 case IQ2000_BUILTIN_PKRL:
2708 return expand_one_builtin (CODE_FOR_pkrl, target, exp, code, 2);
2710 case IQ2000_BUILTIN_CFC0:
2711 code[0] = CONST_INT;
2712 return expand_one_builtin (CODE_FOR_cfc0, target, exp, code, 1);
2714 case IQ2000_BUILTIN_CFC1:
2715 code[0] = CONST_INT;
2716 return expand_one_builtin (CODE_FOR_cfc1, target, exp, code, 1);
2718 case IQ2000_BUILTIN_CFC2:
2719 code[0] = CONST_INT;
2720 return expand_one_builtin (CODE_FOR_cfc2, target, exp, code, 1);
2722 case IQ2000_BUILTIN_CFC3:
2723 code[0] = CONST_INT;
2724 return expand_one_builtin (CODE_FOR_cfc3, target, exp, code, 1);
2726 case IQ2000_BUILTIN_CTC0:
2727 code[1] = CONST_INT;
2728 return expand_one_builtin (CODE_FOR_ctc0, target, exp, code, 2);
2730 case IQ2000_BUILTIN_CTC1:
2731 code[1] = CONST_INT;
2732 return expand_one_builtin (CODE_FOR_ctc1, target, exp, code, 2);
2734 case IQ2000_BUILTIN_CTC2:
2735 code[1] = CONST_INT;
2736 return expand_one_builtin (CODE_FOR_ctc2, target, exp, code, 2);
2738 case IQ2000_BUILTIN_CTC3:
2739 code[1] = CONST_INT;
2740 return expand_one_builtin (CODE_FOR_ctc3, target, exp, code, 2);
2742 case IQ2000_BUILTIN_MFC0:
2743 code[0] = CONST_INT;
2744 return expand_one_builtin (CODE_FOR_mfc0, target, exp, code, 1);
2746 case IQ2000_BUILTIN_MFC1:
2747 code[0] = CONST_INT;
2748 return expand_one_builtin (CODE_FOR_mfc1, target, exp, code, 1);
2750 case IQ2000_BUILTIN_MFC2:
2751 code[0] = CONST_INT;
2752 return expand_one_builtin (CODE_FOR_mfc2, target, exp, code, 1);
2754 case IQ2000_BUILTIN_MFC3:
2755 code[0] = CONST_INT;
2756 return expand_one_builtin (CODE_FOR_mfc3, target, exp, code, 1);
2758 case IQ2000_BUILTIN_MTC0:
2759 code[1] = CONST_INT;
2760 return expand_one_builtin (CODE_FOR_mtc0, target, exp, code, 2);
2762 case IQ2000_BUILTIN_MTC1:
2763 code[1] = CONST_INT;
2764 return expand_one_builtin (CODE_FOR_mtc1, target, exp, code, 2);
2766 case IQ2000_BUILTIN_MTC2:
2767 code[1] = CONST_INT;
2768 return expand_one_builtin (CODE_FOR_mtc2, target, exp, code, 2);
2770 case IQ2000_BUILTIN_MTC3:
2771 code[1] = CONST_INT;
2772 return expand_one_builtin (CODE_FOR_mtc3, target, exp, code, 2);
2774 case IQ2000_BUILTIN_LUR:
2775 return expand_one_builtin (CODE_FOR_lur, target, exp, code, 2);
2777 case IQ2000_BUILTIN_RB:
2778 return expand_one_builtin (CODE_FOR_rb, target, exp, code, 2);
2780 case IQ2000_BUILTIN_RX:
2781 return expand_one_builtin (CODE_FOR_rx, target, exp, code, 2);
2783 case IQ2000_BUILTIN_SRRD:
2784 return expand_one_builtin (CODE_FOR_srrd, target, exp, code, 1);
2786 case IQ2000_BUILTIN_SRWR:
2787 return expand_one_builtin (CODE_FOR_srwr, target, exp, code, 2);
2789 case IQ2000_BUILTIN_WB:
2790 return expand_one_builtin (CODE_FOR_wb, target, exp, code, 2);
2792 case IQ2000_BUILTIN_WX:
2793 return expand_one_builtin (CODE_FOR_wx, target, exp, code, 2);
2795 case IQ2000_BUILTIN_LUC32L:
2796 return expand_one_builtin (CODE_FOR_luc32l, target, exp, code, 2);
2798 case IQ2000_BUILTIN_LUC64:
2799 return expand_one_builtin (CODE_FOR_luc64, target, exp, code, 2);
2801 case IQ2000_BUILTIN_LUC64L:
2802 return expand_one_builtin (CODE_FOR_luc64l, target, exp, code, 2);
2804 case IQ2000_BUILTIN_LUK:
2805 return expand_one_builtin (CODE_FOR_luk, target, exp, code, 2);
2807 case IQ2000_BUILTIN_LULCK:
2808 return expand_one_builtin (CODE_FOR_lulck, target, exp, code, 1);
2810 case IQ2000_BUILTIN_LUM32:
2811 return expand_one_builtin (CODE_FOR_lum32, target, exp, code, 2);
2813 case IQ2000_BUILTIN_LUM32L:
2814 return expand_one_builtin (CODE_FOR_lum32l, target, exp, code, 2);
2816 case IQ2000_BUILTIN_LUM64:
2817 return expand_one_builtin (CODE_FOR_lum64, target, exp, code, 2);
2819 case IQ2000_BUILTIN_LUM64L:
2820 return expand_one_builtin (CODE_FOR_lum64l, target, exp, code, 2);
2822 case IQ2000_BUILTIN_LURL:
2823 return expand_one_builtin (CODE_FOR_lurl, target, exp, code, 2);
2825 case IQ2000_BUILTIN_MRGB:
2826 code[2] = CONST_INT;
2827 return expand_one_builtin (CODE_FOR_mrgb, target, exp, code, 3);
2829 case IQ2000_BUILTIN_SRRDL:
2830 return expand_one_builtin (CODE_FOR_srrdl, target, exp, code, 1);
2832 case IQ2000_BUILTIN_SRULCK:
2833 return expand_one_builtin (CODE_FOR_srulck, target, exp, code, 1);
2835 case IQ2000_BUILTIN_SRWRU:
2836 return expand_one_builtin (CODE_FOR_srwru, target, exp, code, 2);
2838 case IQ2000_BUILTIN_TRAPQFL:
2839 return expand_one_builtin (CODE_FOR_trapqfl, target, exp, code, 0);
2841 case IQ2000_BUILTIN_TRAPQNE:
2842 return expand_one_builtin (CODE_FOR_trapqne, target, exp, code, 0);
2844 case IQ2000_BUILTIN_TRAPREL:
2845 return expand_one_builtin (CODE_FOR_traprel, target, exp, code, 1);
2847 case IQ2000_BUILTIN_WBU:
2848 return expand_one_builtin (CODE_FOR_wbu, target, exp, code, 3);
2850 case IQ2000_BUILTIN_SYSCALL:
2851 return expand_one_builtin (CODE_FOR_syscall, target, exp, code, 0);
2854 return NULL_RTX;
2857 /* Worker function for TARGET_RETURN_IN_MEMORY. */
2859 static bool
2860 iq2000_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED)
2862 return ((int_size_in_bytes (type) > (2 * UNITS_PER_WORD))
2863 || (int_size_in_bytes (type) == -1));
2866 /* Worker function for TARGET_SETUP_INCOMING_VARARGS. */
2868 static void
2869 iq2000_setup_incoming_varargs (cumulative_args_t cum_v,
2870 machine_mode mode ATTRIBUTE_UNUSED,
2871 tree type ATTRIBUTE_UNUSED, int * pretend_size,
2872 int no_rtl)
2874 CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
2875 unsigned int iq2000_off = ! cum->last_arg_fp;
2876 unsigned int iq2000_fp_off = cum->last_arg_fp;
2878 if ((cum->arg_words < MAX_ARGS_IN_REGISTERS - iq2000_off))
2880 int iq2000_save_gp_regs
2881 = MAX_ARGS_IN_REGISTERS - cum->arg_words - iq2000_off;
2882 int iq2000_save_fp_regs
2883 = (MAX_ARGS_IN_REGISTERS - cum->fp_arg_words - iq2000_fp_off);
2885 if (iq2000_save_gp_regs < 0)
2886 iq2000_save_gp_regs = 0;
2887 if (iq2000_save_fp_regs < 0)
2888 iq2000_save_fp_regs = 0;
2890 *pretend_size = ((iq2000_save_gp_regs * UNITS_PER_WORD)
2891 + (iq2000_save_fp_regs * UNITS_PER_FPREG));
2893 if (! (no_rtl))
2895 if (cum->arg_words < MAX_ARGS_IN_REGISTERS - iq2000_off)
2897 rtx ptr, mem;
2898 ptr = plus_constant (Pmode, virtual_incoming_args_rtx,
2899 - (iq2000_save_gp_regs
2900 * UNITS_PER_WORD));
2901 mem = gen_rtx_MEM (BLKmode, ptr);
2902 move_block_from_reg
2903 (cum->arg_words + GP_ARG_FIRST + iq2000_off,
2904 mem,
2905 iq2000_save_gp_regs);
2911 /* A C compound statement to output to stdio stream STREAM the
2912 assembler syntax for an instruction operand that is a memory
2913 reference whose address is ADDR. ADDR is an RTL expression. */
2915 static void
2916 iq2000_print_operand_address (FILE * file, rtx addr)
2918 if (!addr)
2919 error ("PRINT_OPERAND_ADDRESS, null pointer");
2921 else
2922 switch (GET_CODE (addr))
2924 case REG:
2925 if (REGNO (addr) == ARG_POINTER_REGNUM)
2926 abort_with_insn (addr, "Arg pointer not eliminated.");
2928 fprintf (file, "0(%s)", reg_names [REGNO (addr)]);
2929 break;
2931 case LO_SUM:
2933 rtx arg0 = XEXP (addr, 0);
2934 rtx arg1 = XEXP (addr, 1);
2936 if (GET_CODE (arg0) != REG)
2937 abort_with_insn (addr,
2938 "PRINT_OPERAND_ADDRESS, LO_SUM with #1 not REG.");
2940 fprintf (file, "%%lo(");
2941 iq2000_print_operand_address (file, arg1);
2942 fprintf (file, ")(%s)", reg_names [REGNO (arg0)]);
2944 break;
2946 case PLUS:
2948 rtx reg = 0;
2949 rtx offset = 0;
2950 rtx arg0 = XEXP (addr, 0);
2951 rtx arg1 = XEXP (addr, 1);
2953 if (GET_CODE (arg0) == REG)
2955 reg = arg0;
2956 offset = arg1;
2957 if (GET_CODE (offset) == REG)
2958 abort_with_insn (addr, "PRINT_OPERAND_ADDRESS, 2 regs");
2961 else if (GET_CODE (arg1) == REG)
2962 reg = arg1, offset = arg0;
2963 else if (CONSTANT_P (arg0) && CONSTANT_P (arg1))
2965 output_addr_const (file, addr);
2966 break;
2968 else
2969 abort_with_insn (addr, "PRINT_OPERAND_ADDRESS, no regs");
2971 if (! CONSTANT_P (offset))
2972 abort_with_insn (addr, "PRINT_OPERAND_ADDRESS, invalid insn #2");
2974 if (REGNO (reg) == ARG_POINTER_REGNUM)
2975 abort_with_insn (addr, "Arg pointer not eliminated.");
2977 output_addr_const (file, offset);
2978 fprintf (file, "(%s)", reg_names [REGNO (reg)]);
2980 break;
2982 case LABEL_REF:
2983 case SYMBOL_REF:
2984 case CONST_INT:
2985 case CONST:
2986 output_addr_const (file, addr);
2987 if (GET_CODE (addr) == CONST_INT)
2988 fprintf (file, "(%s)", reg_names [0]);
2989 break;
2991 default:
2992 abort_with_insn (addr, "PRINT_OPERAND_ADDRESS, invalid insn #1");
2993 break;
2997 /* A C compound statement to output to stdio stream FILE the
2998 assembler syntax for an instruction operand OP.
3000 LETTER is a value that can be used to specify one of several ways
3001 of printing the operand. It is used when identical operands
3002 must be printed differently depending on the context. LETTER
3003 comes from the `%' specification that was used to request
3004 printing of the operand. If the specification was just `%DIGIT'
3005 then LETTER is 0; if the specification was `%LTR DIGIT' then LETTER
3006 is the ASCII code for LTR.
3008 If OP is a register, this macro should print the register's name.
3009 The names can be found in an array `reg_names' whose type is
3010 `char *[]'. `reg_names' is initialized from `REGISTER_NAMES'.
3012 When the machine description has a specification `%PUNCT' (a `%'
3013 followed by a punctuation character), this macro is called with
3014 a null pointer for X and the punctuation character for LETTER.
3016 The IQ2000 specific codes are:
3018 'X' X is CONST_INT, prints upper 16 bits in hexadecimal format = "0x%04x",
3019 'x' X is CONST_INT, prints lower 16 bits in hexadecimal format = "0x%04x",
3020 'd' output integer constant in decimal,
3021 'z' if the operand is 0, use $0 instead of normal operand.
3022 'D' print second part of double-word register or memory operand.
3023 'L' print low-order register of double-word register operand.
3024 'M' print high-order register of double-word register operand.
3025 'C' print part of opcode for a branch condition.
3026 'F' print part of opcode for a floating-point branch condition.
3027 'N' print part of opcode for a branch condition, inverted.
3028 'W' print part of opcode for a floating-point branch condition, inverted.
3029 'A' Print part of opcode for a bit test condition.
3030 'P' Print label for a bit test.
3031 'p' Print log for a bit test.
3032 'B' print 'z' for EQ, 'n' for NE
3033 'b' print 'n' for EQ, 'z' for NE
3034 'T' print 'f' for EQ, 't' for NE
3035 't' print 't' for EQ, 'f' for NE
3036 'Z' print register and a comma, but print nothing for $fcc0
3037 '?' Print 'l' if we are to use a branch likely instead of normal branch.
3038 '@' Print the name of the assembler temporary register (at or $1).
3039 '.' Print the name of the register with a hard-wired zero (zero or $0).
3040 '$' Print the name of the stack pointer register (sp or $29).
3041 '+' Print the name of the gp register (gp or $28). */
3043 static void
3044 iq2000_print_operand (FILE *file, rtx op, int letter)
3046 enum rtx_code code;
3048 if (iq2000_print_operand_punct_valid_p (letter))
3050 switch (letter)
3052 case '?':
3053 if (iq2000_branch_likely)
3054 putc ('l', file);
3055 break;
3057 case '@':
3058 fputs (reg_names [GP_REG_FIRST + 1], file);
3059 break;
3061 case '.':
3062 fputs (reg_names [GP_REG_FIRST + 0], file);
3063 break;
3065 case '$':
3066 fputs (reg_names[STACK_POINTER_REGNUM], file);
3067 break;
3069 case '+':
3070 fputs (reg_names[GP_REG_FIRST + 28], file);
3071 break;
3073 default:
3074 error ("PRINT_OPERAND: Unknown punctuation '%c'", letter);
3075 break;
3078 return;
3081 if (! op)
3083 error ("PRINT_OPERAND null pointer");
3084 return;
3087 code = GET_CODE (op);
3089 if (code == SIGN_EXTEND)
3090 op = XEXP (op, 0), code = GET_CODE (op);
3092 if (letter == 'C')
3093 switch (code)
3095 case EQ: fputs ("eq", file); break;
3096 case NE: fputs ("ne", file); break;
3097 case GT: fputs ("gt", file); break;
3098 case GE: fputs ("ge", file); break;
3099 case LT: fputs ("lt", file); break;
3100 case LE: fputs ("le", file); break;
3101 case GTU: fputs ("ne", file); break;
3102 case GEU: fputs ("geu", file); break;
3103 case LTU: fputs ("ltu", file); break;
3104 case LEU: fputs ("eq", file); break;
3105 default:
3106 abort_with_insn (op, "PRINT_OPERAND, invalid insn for %%C");
3109 else if (letter == 'N')
3110 switch (code)
3112 case EQ: fputs ("ne", file); break;
3113 case NE: fputs ("eq", file); break;
3114 case GT: fputs ("le", file); break;
3115 case GE: fputs ("lt", file); break;
3116 case LT: fputs ("ge", file); break;
3117 case LE: fputs ("gt", file); break;
3118 case GTU: fputs ("leu", file); break;
3119 case GEU: fputs ("ltu", file); break;
3120 case LTU: fputs ("geu", file); break;
3121 case LEU: fputs ("gtu", file); break;
3122 default:
3123 abort_with_insn (op, "PRINT_OPERAND, invalid insn for %%N");
3126 else if (letter == 'F')
3127 switch (code)
3129 case EQ: fputs ("c1f", file); break;
3130 case NE: fputs ("c1t", file); break;
3131 default:
3132 abort_with_insn (op, "PRINT_OPERAND, invalid insn for %%F");
3135 else if (letter == 'W')
3136 switch (code)
3138 case EQ: fputs ("c1t", file); break;
3139 case NE: fputs ("c1f", file); break;
3140 default:
3141 abort_with_insn (op, "PRINT_OPERAND, invalid insn for %%W");
3144 else if (letter == 'A')
3145 fputs (code == LABEL_REF ? "i" : "in", file);
3147 else if (letter == 'P')
3149 if (code == LABEL_REF)
3150 output_addr_const (file, op);
3151 else if (code != PC)
3152 output_operand_lossage ("invalid %%P operand");
3155 else if (letter == 'p')
3157 int value;
3158 if (code != CONST_INT
3159 || (value = exact_log2 (INTVAL (op))) < 0)
3160 output_operand_lossage ("invalid %%p value");
3161 else
3162 fprintf (file, "%d", value);
3165 else if (letter == 'Z')
3167 gcc_unreachable ();
3170 else if (code == REG || code == SUBREG)
3172 int regnum;
3174 if (code == REG)
3175 regnum = REGNO (op);
3176 else
3177 regnum = true_regnum (op);
3179 if ((letter == 'M' && ! WORDS_BIG_ENDIAN)
3180 || (letter == 'L' && WORDS_BIG_ENDIAN)
3181 || letter == 'D')
3182 regnum++;
3184 fprintf (file, "%s", reg_names[regnum]);
3187 else if (code == MEM)
3189 if (letter == 'D')
3190 output_address (plus_constant (Pmode, XEXP (op, 0), 4));
3191 else
3192 output_address (XEXP (op, 0));
3195 else if (code == CONST_DOUBLE
3196 && GET_MODE_CLASS (GET_MODE (op)) == MODE_FLOAT)
3198 char s[60];
3200 real_to_decimal (s, CONST_DOUBLE_REAL_VALUE (op), sizeof (s), 0, 1);
3201 fputs (s, file);
3204 else if (letter == 'x' && GET_CODE (op) == CONST_INT)
3205 fprintf (file, HOST_WIDE_INT_PRINT_HEX, 0xffff & INTVAL(op));
3207 else if (letter == 'X' && GET_CODE(op) == CONST_INT)
3208 fprintf (file, HOST_WIDE_INT_PRINT_HEX, 0xffff & (INTVAL (op) >> 16));
3210 else if (letter == 'd' && GET_CODE(op) == CONST_INT)
3211 fprintf (file, HOST_WIDE_INT_PRINT_DEC, (INTVAL(op)));
3213 else if (letter == 'z' && GET_CODE (op) == CONST_INT && INTVAL (op) == 0)
3214 fputs (reg_names[GP_REG_FIRST], file);
3216 else if (letter == 'd' || letter == 'x' || letter == 'X')
3217 output_operand_lossage ("invalid use of %%d, %%x, or %%X");
3219 else if (letter == 'B')
3220 fputs (code == EQ ? "z" : "n", file);
3221 else if (letter == 'b')
3222 fputs (code == EQ ? "n" : "z", file);
3223 else if (letter == 'T')
3224 fputs (code == EQ ? "f" : "t", file);
3225 else if (letter == 't')
3226 fputs (code == EQ ? "t" : "f", file);
3228 else if (code == CONST && GET_CODE (XEXP (op, 0)) == REG)
3230 iq2000_print_operand (file, XEXP (op, 0), letter);
3233 else
3234 output_addr_const (file, op);
3237 static bool
3238 iq2000_print_operand_punct_valid_p (unsigned char code)
3240 return iq2000_print_operand_punct[code];
3243 /* For the IQ2000, transform:
3245 memory(X + <large int>)
3246 into:
3247 Y = <large int> & ~0x7fff;
3248 Z = X + Y
3249 memory (Z + (<large int> & 0x7fff));
3253 iq2000_legitimize_address (rtx xinsn, rtx old_x ATTRIBUTE_UNUSED,
3254 machine_mode mode)
3256 if (TARGET_DEBUG_B_MODE)
3258 GO_PRINTF ("\n========== LEGITIMIZE_ADDRESS\n");
3259 GO_DEBUG_RTX (xinsn);
3262 if (iq2000_check_split (xinsn, mode))
3264 return gen_rtx_LO_SUM (Pmode,
3265 copy_to_mode_reg (Pmode,
3266 gen_rtx_HIGH (Pmode, xinsn)),
3267 xinsn);
3270 if (GET_CODE (xinsn) == PLUS)
3272 rtx xplus0 = XEXP (xinsn, 0);
3273 rtx xplus1 = XEXP (xinsn, 1);
3274 enum rtx_code code0 = GET_CODE (xplus0);
3275 enum rtx_code code1 = GET_CODE (xplus1);
3277 if (code0 != REG && code1 == REG)
3279 xplus0 = XEXP (xinsn, 1);
3280 xplus1 = XEXP (xinsn, 0);
3281 code0 = GET_CODE (xplus0);
3282 code1 = GET_CODE (xplus1);
3285 if (code0 == REG && REG_MODE_OK_FOR_BASE_P (xplus0, mode)
3286 && code1 == CONST_INT && !SMALL_INT (xplus1))
3288 rtx int_reg = gen_reg_rtx (Pmode);
3289 rtx ptr_reg = gen_reg_rtx (Pmode);
3291 emit_move_insn (int_reg,
3292 GEN_INT (INTVAL (xplus1) & ~ 0x7fff));
3294 emit_insn (gen_rtx_SET (VOIDmode,
3295 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, int code, int outer_code ATTRIBUTE_UNUSED,
3311 int opno ATTRIBUTE_UNUSED, int * total,
3312 bool speed ATTRIBUTE_UNUSED)
3314 machine_mode mode = GET_MODE (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);
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 #include "gt-iq2000.h"