Merged trunk at revision 161680 into branch.
[official-gcc.git] / gcc / config / iq2000 / iq2000.c
blob559d88433fa7d73884e0f835ed105d4bb7a7db5d
1 /* Subroutines used for code generation on Vitesse IQ2000 processors
2 Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009
3 Free Software Foundation, Inc.
5 This file is part of GCC.
7 GCC is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3, or (at your option)
10 any later version.
12 GCC is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING3. If not see
19 <http://www.gnu.org/licenses/>. */
21 #include "config.h"
22 #include "system.h"
23 #include "coretypes.h"
24 #include <signal.h>
25 #include "tm.h"
26 #include "tree.h"
27 #include "rtl.h"
28 #include "regs.h"
29 #include "hard-reg-set.h"
30 #include "insn-config.h"
31 #include "conditions.h"
32 #include "output.h"
33 #include "insn-attr.h"
34 #include "flags.h"
35 #include "function.h"
36 #include "expr.h"
37 #include "optabs.h"
38 #include "libfuncs.h"
39 #include "recog.h"
40 #include "toplev.h"
41 #include "reload.h"
42 #include "ggc.h"
43 #include "tm_p.h"
44 #include "debug.h"
45 #include "target.h"
46 #include "target-def.h"
47 #include "langhooks.h"
49 /* Enumeration for all of the relational tests, so that we can build
50 arrays indexed by the test type, and not worry about the order
51 of EQ, NE, etc. */
53 enum internal_test
55 ITEST_EQ,
56 ITEST_NE,
57 ITEST_GT,
58 ITEST_GE,
59 ITEST_LT,
60 ITEST_LE,
61 ITEST_GTU,
62 ITEST_GEU,
63 ITEST_LTU,
64 ITEST_LEU,
65 ITEST_MAX
68 struct constant;
71 /* Structure to be filled in by compute_frame_size with register
72 save masks, and offsets for the current function. */
74 struct iq2000_frame_info
76 long total_size; /* # bytes that the entire frame takes up. */
77 long var_size; /* # bytes that variables take up. */
78 long args_size; /* # bytes that outgoing arguments take up. */
79 long extra_size; /* # bytes of extra gunk. */
80 int gp_reg_size; /* # bytes needed to store gp regs. */
81 int fp_reg_size; /* # bytes needed to store fp regs. */
82 long mask; /* Mask of saved gp registers. */
83 long gp_save_offset; /* Offset from vfp to store gp registers. */
84 long fp_save_offset; /* Offset from vfp to store fp registers. */
85 long gp_sp_offset; /* Offset from new sp to store gp registers. */
86 long fp_sp_offset; /* Offset from new sp to store fp registers. */
87 int initialized; /* != 0 if frame size already calculated. */
88 int num_gp; /* Number of gp registers saved. */
89 } iq2000_frame_info;
91 struct GTY(()) machine_function
93 /* Current frame information, calculated by compute_frame_size. */
94 long total_size; /* # bytes that the entire frame takes up. */
95 long var_size; /* # bytes that variables take up. */
96 long args_size; /* # bytes that outgoing arguments take up. */
97 long extra_size; /* # bytes of extra gunk. */
98 int gp_reg_size; /* # bytes needed to store gp regs. */
99 int fp_reg_size; /* # bytes needed to store fp regs. */
100 long mask; /* Mask of saved gp registers. */
101 long gp_save_offset; /* Offset from vfp to store gp registers. */
102 long fp_save_offset; /* Offset from vfp to store fp registers. */
103 long gp_sp_offset; /* Offset from new sp to store gp registers. */
104 long fp_sp_offset; /* Offset from new sp to store fp registers. */
105 int initialized; /* != 0 if frame size already calculated. */
106 int num_gp; /* Number of gp registers saved. */
109 /* Global variables for machine-dependent things. */
111 /* List of all IQ2000 punctuation characters used by iq2000_print_operand. */
112 static char iq2000_print_operand_punct[256];
114 /* The target cpu for optimization and scheduling. */
115 enum processor_type iq2000_tune;
117 /* Which instruction set architecture to use. */
118 int iq2000_isa;
120 /* Local variables. */
122 /* The next branch instruction is a branch likely, not branch normal. */
123 static int iq2000_branch_likely;
125 /* Count of delay slots and how many are filled. */
126 static int dslots_load_total;
127 static int dslots_load_filled;
128 static int dslots_jump_total;
130 /* # of nops needed by previous insn. */
131 static int dslots_number_nops;
133 /* Number of 1/2/3 word references to data items (i.e., not jal's). */
134 static int num_refs[3];
136 /* Registers to check for load delay. */
137 static rtx iq2000_load_reg;
138 static rtx iq2000_load_reg2;
139 static rtx iq2000_load_reg3;
140 static rtx iq2000_load_reg4;
142 /* Mode used for saving/restoring general purpose registers. */
143 static enum machine_mode gpr_mode;
146 /* Initialize the GCC target structure. */
147 static struct machine_function* iq2000_init_machine_status (void);
148 static bool iq2000_handle_option (size_t, const char *, int);
149 static section *iq2000_select_rtx_section (enum machine_mode, rtx,
150 unsigned HOST_WIDE_INT);
151 static void iq2000_init_builtins (void);
152 static rtx iq2000_expand_builtin (tree, rtx, rtx, enum machine_mode, int);
153 static bool iq2000_return_in_memory (const_tree, const_tree);
154 static void iq2000_setup_incoming_varargs (CUMULATIVE_ARGS *,
155 enum machine_mode, tree, int *,
156 int);
157 static bool iq2000_rtx_costs (rtx, int, int, int *, bool);
158 static int iq2000_address_cost (rtx, bool);
159 static section *iq2000_select_section (tree, int, unsigned HOST_WIDE_INT);
160 static rtx iq2000_legitimize_address (rtx, rtx, enum machine_mode);
161 static bool iq2000_pass_by_reference (CUMULATIVE_ARGS *, enum machine_mode,
162 const_tree, bool);
163 static int iq2000_arg_partial_bytes (CUMULATIVE_ARGS *, enum machine_mode,
164 tree, bool);
165 static void iq2000_va_start (tree, rtx);
166 static bool iq2000_legitimate_address_p (enum machine_mode, rtx, bool);
167 static bool iq2000_can_eliminate (const int, const int);
168 static void iq2000_asm_trampoline_template (FILE *);
169 static void iq2000_trampoline_init (rtx, tree, rtx);
170 static rtx iq2000_function_value (const_tree, const_tree, bool);
171 static rtx iq2000_libcall_value (enum machine_mode, const_rtx);
172 static void iq2000_print_operand (FILE *, rtx, int);
173 static void iq2000_print_operand_address (FILE *, rtx);
174 static bool iq2000_print_operand_punct_valid_p (unsigned char code);
176 #undef TARGET_INIT_BUILTINS
177 #define TARGET_INIT_BUILTINS iq2000_init_builtins
178 #undef TARGET_EXPAND_BUILTIN
179 #define TARGET_EXPAND_BUILTIN iq2000_expand_builtin
180 #undef TARGET_ASM_SELECT_RTX_SECTION
181 #define TARGET_ASM_SELECT_RTX_SECTION iq2000_select_rtx_section
182 #undef TARGET_HANDLE_OPTION
183 #define TARGET_HANDLE_OPTION iq2000_handle_option
184 #undef TARGET_RTX_COSTS
185 #define TARGET_RTX_COSTS iq2000_rtx_costs
186 #undef TARGET_ADDRESS_COST
187 #define TARGET_ADDRESS_COST iq2000_address_cost
188 #undef TARGET_ASM_SELECT_SECTION
189 #define TARGET_ASM_SELECT_SECTION iq2000_select_section
191 #undef TARGET_LEGITIMIZE_ADDRESS
192 #define TARGET_LEGITIMIZE_ADDRESS iq2000_legitimize_address
194 /* The assembler supports switchable .bss sections, but
195 iq2000_select_section doesn't yet make use of them. */
196 #undef TARGET_HAVE_SWITCHABLE_BSS_SECTIONS
197 #define TARGET_HAVE_SWITCHABLE_BSS_SECTIONS false
199 #undef TARGET_PRINT_OPERAND
200 #define TARGET_PRINT_OPERAND iq2000_print_operand
201 #undef TARGET_PRINT_OPERAND_ADDRESS
202 #define TARGET_PRINT_OPERAND_ADDRESS iq2000_print_operand_address
203 #undef TARGET_PRINT_OPERAND_PUNCT_VALID_P
204 #define TARGET_PRINT_OPERAND_PUNCT_VALID_P iq2000_print_operand_punct_valid_p
206 #undef TARGET_PROMOTE_FUNCTION_MODE
207 #define TARGET_PROMOTE_FUNCTION_MODE default_promote_function_mode_always_promote
208 #undef TARGET_PROMOTE_PROTOTYPES
209 #define TARGET_PROMOTE_PROTOTYPES hook_bool_const_tree_true
211 #undef TARGET_FUNCTION_VALUE
212 #define TARGET_FUNCTION_VALUE iq2000_function_value
213 #undef TARGET_LIBCALL_VALUE
214 #define TARGET_LIBCALL_VALUE iq2000_libcall_value
215 #undef TARGET_RETURN_IN_MEMORY
216 #define TARGET_RETURN_IN_MEMORY iq2000_return_in_memory
217 #undef TARGET_PASS_BY_REFERENCE
218 #define TARGET_PASS_BY_REFERENCE iq2000_pass_by_reference
219 #undef TARGET_CALLEE_COPIES
220 #define TARGET_CALLEE_COPIES hook_callee_copies_named
221 #undef TARGET_ARG_PARTIAL_BYTES
222 #define TARGET_ARG_PARTIAL_BYTES iq2000_arg_partial_bytes
224 #undef TARGET_SETUP_INCOMING_VARARGS
225 #define TARGET_SETUP_INCOMING_VARARGS iq2000_setup_incoming_varargs
226 #undef TARGET_STRICT_ARGUMENT_NAMING
227 #define TARGET_STRICT_ARGUMENT_NAMING hook_bool_CUMULATIVE_ARGS_true
229 #undef TARGET_EXPAND_BUILTIN_VA_START
230 #define TARGET_EXPAND_BUILTIN_VA_START iq2000_va_start
232 #undef TARGET_LEGITIMATE_ADDRESS_P
233 #define TARGET_LEGITIMATE_ADDRESS_P iq2000_legitimate_address_p
235 #undef TARGET_CAN_ELIMINATE
236 #define TARGET_CAN_ELIMINATE iq2000_can_eliminate
238 #undef TARGET_ASM_TRAMPOLINE_TEMPLATE
239 #define TARGET_ASM_TRAMPOLINE_TEMPLATE iq2000_asm_trampoline_template
240 #undef TARGET_TRAMPOLINE_INIT
241 #define TARGET_TRAMPOLINE_INIT iq2000_trampoline_init
243 struct gcc_target targetm = TARGET_INITIALIZER;
245 /* Return nonzero if we split the address into high and low parts. */
248 iq2000_check_split (rtx address, enum machine_mode mode)
250 /* This is the same check used in simple_memory_operand.
251 We use it here because LO_SUM is not offsettable. */
252 if (GET_MODE_SIZE (mode) > (unsigned) UNITS_PER_WORD)
253 return 0;
255 if ((GET_CODE (address) == SYMBOL_REF)
256 || (GET_CODE (address) == CONST
257 && GET_CODE (XEXP (XEXP (address, 0), 0)) == SYMBOL_REF)
258 || GET_CODE (address) == LABEL_REF)
259 return 1;
261 return 0;
264 /* Return nonzero if REG is valid for MODE. */
267 iq2000_reg_mode_ok_for_base_p (rtx reg,
268 enum machine_mode mode ATTRIBUTE_UNUSED,
269 int strict)
271 return (strict
272 ? REGNO_MODE_OK_FOR_BASE_P (REGNO (reg), mode)
273 : GP_REG_OR_PSEUDO_NONSTRICT_P (REGNO (reg), mode));
276 /* Return a nonzero value if XINSN is a legitimate address for a
277 memory operand of the indicated MODE. STRICT is nonzero if this
278 function is called during reload. */
280 bool
281 iq2000_legitimate_address_p (enum machine_mode mode, rtx xinsn, bool strict)
283 if (TARGET_DEBUG_A_MODE)
285 GO_PRINTF2 ("\n========== legitimate_address_p, %sstrict\n",
286 strict ? "" : "not ");
287 GO_DEBUG_RTX (xinsn);
290 /* Check for constant before stripping off SUBREG, so that we don't
291 accept (subreg (const_int)) which will fail to reload. */
292 if (CONSTANT_ADDRESS_P (xinsn)
293 && ! (iq2000_check_split (xinsn, mode))
294 && ! (GET_CODE (xinsn) == CONST_INT && ! SMALL_INT (xinsn)))
295 return 1;
297 while (GET_CODE (xinsn) == SUBREG)
298 xinsn = SUBREG_REG (xinsn);
300 if (GET_CODE (xinsn) == REG
301 && iq2000_reg_mode_ok_for_base_p (xinsn, mode, strict))
302 return 1;
304 if (GET_CODE (xinsn) == LO_SUM)
306 rtx xlow0 = XEXP (xinsn, 0);
307 rtx xlow1 = XEXP (xinsn, 1);
309 while (GET_CODE (xlow0) == SUBREG)
310 xlow0 = SUBREG_REG (xlow0);
311 if (GET_CODE (xlow0) == REG
312 && iq2000_reg_mode_ok_for_base_p (xlow0, mode, strict)
313 && iq2000_check_split (xlow1, mode))
314 return 1;
317 if (GET_CODE (xinsn) == PLUS)
319 rtx xplus0 = XEXP (xinsn, 0);
320 rtx xplus1 = XEXP (xinsn, 1);
321 enum rtx_code code0;
322 enum rtx_code code1;
324 while (GET_CODE (xplus0) == SUBREG)
325 xplus0 = SUBREG_REG (xplus0);
326 code0 = GET_CODE (xplus0);
328 while (GET_CODE (xplus1) == SUBREG)
329 xplus1 = SUBREG_REG (xplus1);
330 code1 = GET_CODE (xplus1);
332 if (code0 == REG
333 && iq2000_reg_mode_ok_for_base_p (xplus0, mode, strict))
335 if (code1 == CONST_INT && SMALL_INT (xplus1)
336 && SMALL_INT_UNSIGNED (xplus1) /* No negative offsets */)
337 return 1;
341 if (TARGET_DEBUG_A_MODE)
342 GO_PRINTF ("Not a enum machine_mode mode, legitimate address\n");
344 /* The address was not legitimate. */
345 return 0;
348 /* Returns an operand string for the given instruction's delay slot,
349 after updating filled delay slot statistics.
351 We assume that operands[0] is the target register that is set.
353 In order to check the next insn, most of this functionality is moved
354 to FINAL_PRESCAN_INSN, and we just set the global variables that
355 it needs. */
357 const char *
358 iq2000_fill_delay_slot (const char *ret, enum delay_type type, rtx operands[],
359 rtx cur_insn)
361 rtx set_reg;
362 enum machine_mode mode;
363 rtx next_insn = cur_insn ? NEXT_INSN (cur_insn) : NULL_RTX;
364 int num_nops;
366 if (type == DELAY_LOAD || type == DELAY_FCMP)
367 num_nops = 1;
369 else
370 num_nops = 0;
372 /* Make sure that we don't put nop's after labels. */
373 next_insn = NEXT_INSN (cur_insn);
374 while (next_insn != 0
375 && (GET_CODE (next_insn) == NOTE
376 || GET_CODE (next_insn) == CODE_LABEL))
377 next_insn = NEXT_INSN (next_insn);
379 dslots_load_total += num_nops;
380 if (TARGET_DEBUG_C_MODE
381 || type == DELAY_NONE
382 || operands == 0
383 || cur_insn == 0
384 || next_insn == 0
385 || GET_CODE (next_insn) == CODE_LABEL
386 || (set_reg = operands[0]) == 0)
388 dslots_number_nops = 0;
389 iq2000_load_reg = 0;
390 iq2000_load_reg2 = 0;
391 iq2000_load_reg3 = 0;
392 iq2000_load_reg4 = 0;
394 return ret;
397 set_reg = operands[0];
398 if (set_reg == 0)
399 return ret;
401 while (GET_CODE (set_reg) == SUBREG)
402 set_reg = SUBREG_REG (set_reg);
404 mode = GET_MODE (set_reg);
405 dslots_number_nops = num_nops;
406 iq2000_load_reg = set_reg;
407 if (GET_MODE_SIZE (mode)
408 > (unsigned) (UNITS_PER_WORD))
409 iq2000_load_reg2 = gen_rtx_REG (SImode, REGNO (set_reg) + 1);
410 else
411 iq2000_load_reg2 = 0;
413 return ret;
416 /* Determine whether a memory reference takes one (based off of the GP
417 pointer), two (normal), or three (label + reg) instructions, and bump the
418 appropriate counter for -mstats. */
420 static void
421 iq2000_count_memory_refs (rtx op, int num)
423 int additional = 0;
424 int n_words = 0;
425 rtx addr, plus0, plus1;
426 enum rtx_code code0, code1;
427 int looping;
429 if (TARGET_DEBUG_B_MODE)
431 fprintf (stderr, "\n========== iq2000_count_memory_refs:\n");
432 debug_rtx (op);
435 /* Skip MEM if passed, otherwise handle movsi of address. */
436 addr = (GET_CODE (op) != MEM) ? op : XEXP (op, 0);
438 /* Loop, going through the address RTL. */
441 looping = FALSE;
442 switch (GET_CODE (addr))
444 case REG:
445 case CONST_INT:
446 case LO_SUM:
447 break;
449 case PLUS:
450 plus0 = XEXP (addr, 0);
451 plus1 = XEXP (addr, 1);
452 code0 = GET_CODE (plus0);
453 code1 = GET_CODE (plus1);
455 if (code0 == REG)
457 additional++;
458 addr = plus1;
459 looping = 1;
460 continue;
463 if (code0 == CONST_INT)
465 addr = plus1;
466 looping = 1;
467 continue;
470 if (code1 == REG)
472 additional++;
473 addr = plus0;
474 looping = 1;
475 continue;
478 if (code1 == CONST_INT)
480 addr = plus0;
481 looping = 1;
482 continue;
485 if (code0 == SYMBOL_REF || code0 == LABEL_REF || code0 == CONST)
487 addr = plus0;
488 looping = 1;
489 continue;
492 if (code1 == SYMBOL_REF || code1 == LABEL_REF || code1 == CONST)
494 addr = plus1;
495 looping = 1;
496 continue;
499 break;
501 case LABEL_REF:
502 n_words = 2; /* Always 2 words. */
503 break;
505 case CONST:
506 addr = XEXP (addr, 0);
507 looping = 1;
508 continue;
510 case SYMBOL_REF:
511 n_words = SYMBOL_REF_FLAG (addr) ? 1 : 2;
512 break;
514 default:
515 break;
518 while (looping);
520 if (n_words == 0)
521 return;
523 n_words += additional;
524 if (n_words > 3)
525 n_words = 3;
527 num_refs[n_words-1] += num;
530 /* Abort after printing out a specific insn. */
532 static void
533 abort_with_insn (rtx insn, const char * reason)
535 error (reason);
536 debug_rtx (insn);
537 fancy_abort (__FILE__, __LINE__, __FUNCTION__);
540 /* Return the appropriate instructions to move one operand to another. */
542 const char *
543 iq2000_move_1word (rtx operands[], rtx insn, int unsignedp)
545 const char *ret = 0;
546 rtx op0 = operands[0];
547 rtx op1 = operands[1];
548 enum rtx_code code0 = GET_CODE (op0);
549 enum rtx_code code1 = GET_CODE (op1);
550 enum machine_mode mode = GET_MODE (op0);
551 int subreg_offset0 = 0;
552 int subreg_offset1 = 0;
553 enum delay_type delay = DELAY_NONE;
555 while (code0 == SUBREG)
557 subreg_offset0 += subreg_regno_offset (REGNO (SUBREG_REG (op0)),
558 GET_MODE (SUBREG_REG (op0)),
559 SUBREG_BYTE (op0),
560 GET_MODE (op0));
561 op0 = SUBREG_REG (op0);
562 code0 = GET_CODE (op0);
565 while (code1 == SUBREG)
567 subreg_offset1 += subreg_regno_offset (REGNO (SUBREG_REG (op1)),
568 GET_MODE (SUBREG_REG (op1)),
569 SUBREG_BYTE (op1),
570 GET_MODE (op1));
571 op1 = SUBREG_REG (op1);
572 code1 = GET_CODE (op1);
575 /* For our purposes, a condition code mode is the same as SImode. */
576 if (mode == CCmode)
577 mode = SImode;
579 if (code0 == REG)
581 int regno0 = REGNO (op0) + subreg_offset0;
583 if (code1 == REG)
585 int regno1 = REGNO (op1) + subreg_offset1;
587 /* Do not do anything for assigning a register to itself */
588 if (regno0 == regno1)
589 ret = "";
591 else if (GP_REG_P (regno0))
593 if (GP_REG_P (regno1))
594 ret = "or\t%0,%%0,%1";
599 else if (code1 == MEM)
601 delay = DELAY_LOAD;
603 if (TARGET_STATS)
604 iq2000_count_memory_refs (op1, 1);
606 if (GP_REG_P (regno0))
608 /* For loads, use the mode of the memory item, instead of the
609 target, so zero/sign extend can use this code as well. */
610 switch (GET_MODE (op1))
612 default:
613 break;
614 case SFmode:
615 ret = "lw\t%0,%1";
616 break;
617 case SImode:
618 case CCmode:
619 ret = "lw\t%0,%1";
620 break;
621 case HImode:
622 ret = (unsignedp) ? "lhu\t%0,%1" : "lh\t%0,%1";
623 break;
624 case QImode:
625 ret = (unsignedp) ? "lbu\t%0,%1" : "lb\t%0,%1";
626 break;
631 else if (code1 == CONST_INT
632 || (code1 == CONST_DOUBLE
633 && GET_MODE (op1) == VOIDmode))
635 if (code1 == CONST_DOUBLE)
637 /* This can happen when storing constants into long long
638 bitfields. Just store the least significant word of
639 the value. */
640 operands[1] = op1 = GEN_INT (CONST_DOUBLE_LOW (op1));
643 if (INTVAL (op1) == 0)
645 if (GP_REG_P (regno0))
646 ret = "or\t%0,%%0,%z1";
648 else if (GP_REG_P (regno0))
650 if (SMALL_INT_UNSIGNED (op1))
651 ret = "ori\t%0,%%0,%x1\t\t\t# %1";
652 else if (SMALL_INT (op1))
653 ret = "addiu\t%0,%%0,%1\t\t\t# %1";
654 else
655 ret = "lui\t%0,%X1\t\t\t# %1\n\tori\t%0,%0,%x1";
659 else if (code1 == CONST_DOUBLE && mode == SFmode)
661 if (op1 == CONST0_RTX (SFmode))
663 if (GP_REG_P (regno0))
664 ret = "or\t%0,%%0,%.";
667 else
669 delay = DELAY_LOAD;
670 ret = "li.s\t%0,%1";
674 else if (code1 == LABEL_REF)
676 if (TARGET_STATS)
677 iq2000_count_memory_refs (op1, 1);
679 ret = "la\t%0,%a1";
682 else if (code1 == SYMBOL_REF || code1 == CONST)
684 if (TARGET_STATS)
685 iq2000_count_memory_refs (op1, 1);
687 ret = "la\t%0,%a1";
690 else if (code1 == PLUS)
692 rtx add_op0 = XEXP (op1, 0);
693 rtx add_op1 = XEXP (op1, 1);
695 if (GET_CODE (XEXP (op1, 1)) == REG
696 && GET_CODE (XEXP (op1, 0)) == CONST_INT)
697 add_op0 = XEXP (op1, 1), add_op1 = XEXP (op1, 0);
699 operands[2] = add_op0;
700 operands[3] = add_op1;
701 ret = "add%:\t%0,%2,%3";
704 else if (code1 == HIGH)
706 operands[1] = XEXP (op1, 0);
707 ret = "lui\t%0,%%hi(%1)";
711 else if (code0 == MEM)
713 if (TARGET_STATS)
714 iq2000_count_memory_refs (op0, 1);
716 if (code1 == REG)
718 int regno1 = REGNO (op1) + subreg_offset1;
720 if (GP_REG_P (regno1))
722 switch (mode)
724 case SFmode: ret = "sw\t%1,%0"; break;
725 case SImode: ret = "sw\t%1,%0"; break;
726 case HImode: ret = "sh\t%1,%0"; break;
727 case QImode: ret = "sb\t%1,%0"; break;
728 default: break;
733 else if (code1 == CONST_INT && INTVAL (op1) == 0)
735 switch (mode)
737 case SFmode: ret = "sw\t%z1,%0"; break;
738 case SImode: ret = "sw\t%z1,%0"; break;
739 case HImode: ret = "sh\t%z1,%0"; break;
740 case QImode: ret = "sb\t%z1,%0"; break;
741 default: break;
745 else if (code1 == CONST_DOUBLE && op1 == CONST0_RTX (mode))
747 switch (mode)
749 case SFmode: ret = "sw\t%.,%0"; break;
750 case SImode: ret = "sw\t%.,%0"; break;
751 case HImode: ret = "sh\t%.,%0"; break;
752 case QImode: ret = "sb\t%.,%0"; break;
753 default: break;
758 if (ret == 0)
760 abort_with_insn (insn, "Bad move");
761 return 0;
764 if (delay != DELAY_NONE)
765 return iq2000_fill_delay_slot (ret, delay, operands, insn);
767 return ret;
770 /* Provide the costs of an addressing mode that contains ADDR. */
772 static int
773 iq2000_address_cost (rtx addr, bool speed)
775 switch (GET_CODE (addr))
777 case LO_SUM:
778 return 1;
780 case LABEL_REF:
781 return 2;
783 case CONST:
785 rtx offset = const0_rtx;
787 addr = eliminate_constant_term (XEXP (addr, 0), & offset);
788 if (GET_CODE (addr) == LABEL_REF)
789 return 2;
791 if (GET_CODE (addr) != SYMBOL_REF)
792 return 4;
794 if (! SMALL_INT (offset))
795 return 2;
798 /* Fall through. */
800 case SYMBOL_REF:
801 return SYMBOL_REF_FLAG (addr) ? 1 : 2;
803 case PLUS:
805 rtx plus0 = XEXP (addr, 0);
806 rtx plus1 = XEXP (addr, 1);
808 if (GET_CODE (plus0) != REG && GET_CODE (plus1) == REG)
809 plus0 = XEXP (addr, 1), plus1 = XEXP (addr, 0);
811 if (GET_CODE (plus0) != REG)
812 break;
814 switch (GET_CODE (plus1))
816 case CONST_INT:
817 return SMALL_INT (plus1) ? 1 : 2;
819 case CONST:
820 case SYMBOL_REF:
821 case LABEL_REF:
822 case HIGH:
823 case LO_SUM:
824 return iq2000_address_cost (plus1, speed) + 1;
826 default:
827 break;
831 default:
832 break;
835 return 4;
838 /* Make normal rtx_code into something we can index from an array. */
840 static enum internal_test
841 map_test_to_internal_test (enum rtx_code test_code)
843 enum internal_test test = ITEST_MAX;
845 switch (test_code)
847 case EQ: test = ITEST_EQ; break;
848 case NE: test = ITEST_NE; break;
849 case GT: test = ITEST_GT; break;
850 case GE: test = ITEST_GE; break;
851 case LT: test = ITEST_LT; break;
852 case LE: test = ITEST_LE; break;
853 case GTU: test = ITEST_GTU; break;
854 case GEU: test = ITEST_GEU; break;
855 case LTU: test = ITEST_LTU; break;
856 case LEU: test = ITEST_LEU; break;
857 default: break;
860 return test;
863 /* Generate the code to do a TEST_CODE comparison on two integer values CMP0
864 and CMP1. P_INVERT is NULL or ptr if branch needs to reverse its test.
865 The return value RESULT is:
866 (reg:SI xx) The pseudo register the comparison is in
867 0 No register, generate a simple branch. */
870 gen_int_relational (enum rtx_code test_code, rtx result, rtx cmp0, rtx cmp1,
871 int *p_invert)
873 struct cmp_info
875 enum rtx_code test_code; /* Code to use in instruction (LT vs. LTU). */
876 int const_low; /* Low bound of constant we can accept. */
877 int const_high; /* High bound of constant we can accept. */
878 int const_add; /* Constant to add (convert LE -> LT). */
879 int reverse_regs; /* Reverse registers in test. */
880 int invert_const; /* != 0 if invert value if cmp1 is constant. */
881 int invert_reg; /* != 0 if invert value if cmp1 is register. */
882 int unsignedp; /* != 0 for unsigned comparisons. */
885 static struct cmp_info info[ (int)ITEST_MAX ] =
887 { XOR, 0, 65535, 0, 0, 0, 0, 0 }, /* EQ */
888 { XOR, 0, 65535, 0, 0, 1, 1, 0 }, /* NE */
889 { LT, -32769, 32766, 1, 1, 1, 0, 0 }, /* GT */
890 { LT, -32768, 32767, 0, 0, 1, 1, 0 }, /* GE */
891 { LT, -32768, 32767, 0, 0, 0, 0, 0 }, /* LT */
892 { LT, -32769, 32766, 1, 1, 0, 1, 0 }, /* LE */
893 { LTU, -32769, 32766, 1, 1, 1, 0, 1 }, /* GTU */
894 { LTU, -32768, 32767, 0, 0, 1, 1, 1 }, /* GEU */
895 { LTU, -32768, 32767, 0, 0, 0, 0, 1 }, /* LTU */
896 { LTU, -32769, 32766, 1, 1, 0, 1, 1 }, /* LEU */
899 enum internal_test test;
900 enum machine_mode mode;
901 struct cmp_info *p_info;
902 int branch_p;
903 int eqne_p;
904 int invert;
905 rtx reg;
906 rtx reg2;
908 test = map_test_to_internal_test (test_code);
909 gcc_assert (test != ITEST_MAX);
911 p_info = &info[(int) test];
912 eqne_p = (p_info->test_code == XOR);
914 mode = GET_MODE (cmp0);
915 if (mode == VOIDmode)
916 mode = GET_MODE (cmp1);
918 /* Eliminate simple branches. */
919 branch_p = (result == 0);
920 if (branch_p)
922 if (GET_CODE (cmp0) == REG || GET_CODE (cmp0) == SUBREG)
924 /* Comparisons against zero are simple branches. */
925 if (GET_CODE (cmp1) == CONST_INT && INTVAL (cmp1) == 0)
926 return 0;
928 /* Test for beq/bne. */
929 if (eqne_p)
930 return 0;
933 /* Allocate a pseudo to calculate the value in. */
934 result = gen_reg_rtx (mode);
937 /* Make sure we can handle any constants given to us. */
938 if (GET_CODE (cmp0) == CONST_INT)
939 cmp0 = force_reg (mode, cmp0);
941 if (GET_CODE (cmp1) == CONST_INT)
943 HOST_WIDE_INT value = INTVAL (cmp1);
945 if (value < p_info->const_low
946 || value > p_info->const_high)
947 cmp1 = force_reg (mode, cmp1);
950 /* See if we need to invert the result. */
951 invert = (GET_CODE (cmp1) == CONST_INT
952 ? p_info->invert_const : p_info->invert_reg);
954 if (p_invert != (int *)0)
956 *p_invert = invert;
957 invert = 0;
960 /* Comparison to constants, may involve adding 1 to change a LT into LE.
961 Comparison between two registers, may involve switching operands. */
962 if (GET_CODE (cmp1) == CONST_INT)
964 if (p_info->const_add != 0)
966 HOST_WIDE_INT new_const = INTVAL (cmp1) + p_info->const_add;
968 /* If modification of cmp1 caused overflow,
969 we would get the wrong answer if we follow the usual path;
970 thus, x > 0xffffffffU would turn into x > 0U. */
971 if ((p_info->unsignedp
972 ? (unsigned HOST_WIDE_INT) new_const >
973 (unsigned HOST_WIDE_INT) INTVAL (cmp1)
974 : new_const > INTVAL (cmp1))
975 != (p_info->const_add > 0))
977 /* This test is always true, but if INVERT is true then
978 the result of the test needs to be inverted so 0 should
979 be returned instead. */
980 emit_move_insn (result, invert ? const0_rtx : const_true_rtx);
981 return result;
983 else
984 cmp1 = GEN_INT (new_const);
988 else if (p_info->reverse_regs)
990 rtx temp = cmp0;
991 cmp0 = cmp1;
992 cmp1 = temp;
995 if (test == ITEST_NE && GET_CODE (cmp1) == CONST_INT && INTVAL (cmp1) == 0)
996 reg = cmp0;
997 else
999 reg = (invert || eqne_p) ? gen_reg_rtx (mode) : result;
1000 convert_move (reg, gen_rtx_fmt_ee (p_info->test_code, mode, cmp0, cmp1), 0);
1003 if (test == ITEST_NE)
1005 convert_move (result, gen_rtx_GTU (mode, reg, const0_rtx), 0);
1006 if (p_invert != NULL)
1007 *p_invert = 0;
1008 invert = 0;
1011 else if (test == ITEST_EQ)
1013 reg2 = invert ? gen_reg_rtx (mode) : result;
1014 convert_move (reg2, gen_rtx_LTU (mode, reg, const1_rtx), 0);
1015 reg = reg2;
1018 if (invert)
1020 rtx one;
1022 one = const1_rtx;
1023 convert_move (result, gen_rtx_XOR (mode, reg, one), 0);
1026 return result;
1029 /* Emit the common code for doing conditional branches.
1030 operand[0] is the label to jump to.
1031 The comparison operands are saved away by cmp{si,di,sf,df}. */
1033 void
1034 gen_conditional_branch (rtx operands[], enum machine_mode mode)
1036 enum rtx_code test_code = GET_CODE (operands[0]);
1037 rtx cmp0 = operands[1];
1038 rtx cmp1 = operands[2];
1039 rtx reg;
1040 int invert;
1041 rtx label1, label2;
1043 invert = 0;
1044 reg = gen_int_relational (test_code, NULL_RTX, cmp0, cmp1, &invert);
1046 if (reg)
1048 cmp0 = reg;
1049 cmp1 = const0_rtx;
1050 test_code = NE;
1052 else if (GET_CODE (cmp1) == CONST_INT && INTVAL (cmp1) != 0)
1053 /* We don't want to build a comparison against a nonzero
1054 constant. */
1055 cmp1 = force_reg (mode, cmp1);
1057 /* Generate the branch. */
1058 label1 = gen_rtx_LABEL_REF (VOIDmode, operands[3]);
1059 label2 = pc_rtx;
1061 if (invert)
1063 label2 = label1;
1064 label1 = pc_rtx;
1067 emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
1068 gen_rtx_IF_THEN_ELSE (VOIDmode,
1069 gen_rtx_fmt_ee (test_code,
1070 mode,
1071 cmp0, cmp1),
1072 label1, label2)));
1075 /* Initialize CUM for a function FNTYPE. */
1077 void
1078 init_cumulative_args (CUMULATIVE_ARGS *cum, tree fntype,
1079 rtx libname ATTRIBUTE_UNUSED)
1081 static CUMULATIVE_ARGS zero_cum;
1082 tree param;
1083 tree next_param;
1085 if (TARGET_DEBUG_D_MODE)
1087 fprintf (stderr,
1088 "\ninit_cumulative_args, fntype = 0x%.8lx", (long) fntype);
1090 if (!fntype)
1091 fputc ('\n', stderr);
1093 else
1095 tree ret_type = TREE_TYPE (fntype);
1097 fprintf (stderr, ", fntype code = %s, ret code = %s\n",
1098 tree_code_name[(int)TREE_CODE (fntype)],
1099 tree_code_name[(int)TREE_CODE (ret_type)]);
1103 *cum = zero_cum;
1105 /* Determine if this function has variable arguments. This is
1106 indicated by the last argument being 'void_type_mode' if there
1107 are no variable arguments. The standard IQ2000 calling sequence
1108 passes all arguments in the general purpose registers in this case. */
1110 for (param = fntype ? TYPE_ARG_TYPES (fntype) : 0;
1111 param != 0; param = next_param)
1113 next_param = TREE_CHAIN (param);
1114 if (next_param == 0 && TREE_VALUE (param) != void_type_node)
1115 cum->gp_reg_found = 1;
1119 /* Advance the argument of type TYPE and mode MODE to the next argument
1120 position in CUM. */
1122 void
1123 function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode, tree type,
1124 int named)
1126 if (TARGET_DEBUG_D_MODE)
1128 fprintf (stderr,
1129 "function_adv({gp reg found = %d, arg # = %2d, words = %2d}, %4s, ",
1130 cum->gp_reg_found, cum->arg_number, cum->arg_words,
1131 GET_MODE_NAME (mode));
1132 fprintf (stderr, "%p", (void *) type);
1133 fprintf (stderr, ", %d )\n\n", named);
1136 cum->arg_number++;
1137 switch (mode)
1139 case VOIDmode:
1140 break;
1142 default:
1143 gcc_assert (GET_MODE_CLASS (mode) == MODE_COMPLEX_INT
1144 || GET_MODE_CLASS (mode) == MODE_COMPLEX_FLOAT);
1146 cum->gp_reg_found = 1;
1147 cum->arg_words += ((GET_MODE_SIZE (mode) + UNITS_PER_WORD - 1)
1148 / UNITS_PER_WORD);
1149 break;
1151 case BLKmode:
1152 cum->gp_reg_found = 1;
1153 cum->arg_words += ((int_size_in_bytes (type) + UNITS_PER_WORD - 1)
1154 / UNITS_PER_WORD);
1155 break;
1157 case SFmode:
1158 cum->arg_words ++;
1159 if (! cum->gp_reg_found && cum->arg_number <= 2)
1160 cum->fp_code += 1 << ((cum->arg_number - 1) * 2);
1161 break;
1163 case DFmode:
1164 cum->arg_words += 2;
1165 if (! cum->gp_reg_found && cum->arg_number <= 2)
1166 cum->fp_code += 2 << ((cum->arg_number - 1) * 2);
1167 break;
1169 case DImode:
1170 cum->gp_reg_found = 1;
1171 cum->arg_words += 2;
1172 break;
1174 case TImode:
1175 cum->gp_reg_found = 1;
1176 cum->arg_words += 4;
1177 break;
1179 case QImode:
1180 case HImode:
1181 case SImode:
1182 cum->gp_reg_found = 1;
1183 cum->arg_words ++;
1184 break;
1188 /* Return an RTL expression containing the register for the given mode MODE
1189 and type TYPE in CUM, or 0 if the argument is to be passed on the stack. */
1191 struct rtx_def *
1192 function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode, const_tree type,
1193 int named)
1195 rtx ret;
1196 int regbase = -1;
1197 int bias = 0;
1198 unsigned int *arg_words = &cum->arg_words;
1199 int struct_p = (type != 0
1200 && (TREE_CODE (type) == RECORD_TYPE
1201 || TREE_CODE (type) == UNION_TYPE
1202 || TREE_CODE (type) == QUAL_UNION_TYPE));
1204 if (TARGET_DEBUG_D_MODE)
1206 fprintf (stderr,
1207 "function_arg( {gp reg found = %d, arg # = %2d, words = %2d}, %4s, ",
1208 cum->gp_reg_found, cum->arg_number, cum->arg_words,
1209 GET_MODE_NAME (mode));
1210 fprintf (stderr, "%p", (const void *) type);
1211 fprintf (stderr, ", %d ) = ", named);
1215 cum->last_arg_fp = 0;
1216 switch (mode)
1218 case SFmode:
1219 regbase = GP_ARG_FIRST;
1220 break;
1222 case DFmode:
1223 cum->arg_words += cum->arg_words & 1;
1225 regbase = GP_ARG_FIRST;
1226 break;
1228 default:
1229 gcc_assert (GET_MODE_CLASS (mode) == MODE_COMPLEX_INT
1230 || GET_MODE_CLASS (mode) == MODE_COMPLEX_FLOAT);
1232 /* Drops through. */
1233 case BLKmode:
1234 if (type != NULL_TREE && TYPE_ALIGN (type) > (unsigned) BITS_PER_WORD)
1235 cum->arg_words += (cum->arg_words & 1);
1236 regbase = GP_ARG_FIRST;
1237 break;
1239 case VOIDmode:
1240 case QImode:
1241 case HImode:
1242 case SImode:
1243 regbase = GP_ARG_FIRST;
1244 break;
1246 case DImode:
1247 cum->arg_words += (cum->arg_words & 1);
1248 regbase = GP_ARG_FIRST;
1249 break;
1251 case TImode:
1252 cum->arg_words += (cum->arg_words & 3);
1253 regbase = GP_ARG_FIRST;
1254 break;
1257 if (*arg_words >= (unsigned) MAX_ARGS_IN_REGISTERS)
1259 if (TARGET_DEBUG_D_MODE)
1260 fprintf (stderr, "<stack>%s\n", struct_p ? ", [struct]" : "");
1262 ret = 0;
1264 else
1266 gcc_assert (regbase != -1);
1268 if (! type || TREE_CODE (type) != RECORD_TYPE
1269 || ! named || ! TYPE_SIZE_UNIT (type)
1270 || ! host_integerp (TYPE_SIZE_UNIT (type), 1))
1271 ret = gen_rtx_REG (mode, regbase + *arg_words + bias);
1272 else
1274 tree field;
1276 for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field))
1277 if (TREE_CODE (field) == FIELD_DECL
1278 && TREE_CODE (TREE_TYPE (field)) == REAL_TYPE
1279 && TYPE_PRECISION (TREE_TYPE (field)) == BITS_PER_WORD
1280 && host_integerp (bit_position (field), 0)
1281 && int_bit_position (field) % BITS_PER_WORD == 0)
1282 break;
1284 /* If the whole struct fits a DFmode register,
1285 we don't need the PARALLEL. */
1286 if (! field || mode == DFmode)
1287 ret = gen_rtx_REG (mode, regbase + *arg_words + bias);
1288 else
1290 unsigned int chunks;
1291 HOST_WIDE_INT bitpos;
1292 unsigned int regno;
1293 unsigned int i;
1295 /* ??? If this is a packed structure, then the last hunk won't
1296 be 64 bits. */
1297 chunks
1298 = tree_low_cst (TYPE_SIZE_UNIT (type), 1) / UNITS_PER_WORD;
1299 if (chunks + *arg_words + bias > (unsigned) MAX_ARGS_IN_REGISTERS)
1300 chunks = MAX_ARGS_IN_REGISTERS - *arg_words - bias;
1302 /* Assign_parms checks the mode of ENTRY_PARM, so we must
1303 use the actual mode here. */
1304 ret = gen_rtx_PARALLEL (mode, rtvec_alloc (chunks));
1306 bitpos = 0;
1307 regno = regbase + *arg_words + bias;
1308 field = TYPE_FIELDS (type);
1309 for (i = 0; i < chunks; i++)
1311 rtx reg;
1313 for (; field; field = TREE_CHAIN (field))
1314 if (TREE_CODE (field) == FIELD_DECL
1315 && int_bit_position (field) >= bitpos)
1316 break;
1318 if (field
1319 && int_bit_position (field) == bitpos
1320 && TREE_CODE (TREE_TYPE (field)) == REAL_TYPE
1321 && TYPE_PRECISION (TREE_TYPE (field)) == BITS_PER_WORD)
1322 reg = gen_rtx_REG (DFmode, regno++);
1323 else
1324 reg = gen_rtx_REG (word_mode, regno);
1326 XVECEXP (ret, 0, i)
1327 = gen_rtx_EXPR_LIST (VOIDmode, reg,
1328 GEN_INT (bitpos / BITS_PER_UNIT));
1330 bitpos += 64;
1331 regno++;
1336 if (TARGET_DEBUG_D_MODE)
1337 fprintf (stderr, "%s%s\n", reg_names[regbase + *arg_words + bias],
1338 struct_p ? ", [struct]" : "");
1341 /* We will be called with a mode of VOIDmode after the last argument
1342 has been seen. Whatever we return will be passed to the call
1343 insn. If we need any shifts for small structures, return them in
1344 a PARALLEL. */
1345 if (mode == VOIDmode)
1347 if (cum->num_adjusts > 0)
1348 ret = gen_rtx_PARALLEL ((enum machine_mode) cum->fp_code,
1349 gen_rtvec_v (cum->num_adjusts, cum->adjust));
1352 return ret;
1355 static int
1356 iq2000_arg_partial_bytes (CUMULATIVE_ARGS *cum, enum machine_mode mode,
1357 tree type ATTRIBUTE_UNUSED,
1358 bool named ATTRIBUTE_UNUSED)
1360 if (mode == DImode && cum->arg_words == MAX_ARGS_IN_REGISTERS - 1)
1362 if (TARGET_DEBUG_D_MODE)
1363 fprintf (stderr, "iq2000_arg_partial_bytes=%d\n", UNITS_PER_WORD);
1364 return UNITS_PER_WORD;
1367 return 0;
1370 /* Implement va_start. */
1372 static void
1373 iq2000_va_start (tree valist, rtx nextarg)
1375 int int_arg_words;
1376 /* Find out how many non-float named formals. */
1377 int gpr_save_area_size;
1378 /* Note UNITS_PER_WORD is 4 bytes. */
1379 int_arg_words = crtl->args.info.arg_words;
1381 if (int_arg_words < 8 )
1382 /* Adjust for the prologue's economy measure. */
1383 gpr_save_area_size = (8 - int_arg_words) * UNITS_PER_WORD;
1384 else
1385 gpr_save_area_size = 0;
1387 /* Everything is in the GPR save area, or in the overflow
1388 area which is contiguous with it. */
1389 nextarg = plus_constant (nextarg, - gpr_save_area_size);
1390 std_expand_builtin_va_start (valist, nextarg);
1393 /* Allocate a chunk of memory for per-function machine-dependent data. */
1395 static struct machine_function *
1396 iq2000_init_machine_status (void)
1398 return ggc_alloc_cleared_machine_function ();
1401 /* Implement TARGET_HANDLE_OPTION. */
1403 static bool
1404 iq2000_handle_option (size_t code, const char *arg, int value ATTRIBUTE_UNUSED)
1406 switch (code)
1408 case OPT_mcpu_:
1409 if (strcmp (arg, "iq10") == 0)
1410 iq2000_tune = PROCESSOR_IQ10;
1411 else if (strcmp (arg, "iq2000") == 0)
1412 iq2000_tune = PROCESSOR_IQ2000;
1413 else
1414 return false;
1415 return true;
1417 case OPT_march_:
1418 /* This option has no effect at the moment. */
1419 return (strcmp (arg, "default") == 0
1420 || strcmp (arg, "DEFAULT") == 0
1421 || strcmp (arg, "iq2000") == 0);
1423 default:
1424 return true;
1428 /* Detect any conflicts in the switches. */
1430 void
1431 override_options (void)
1433 target_flags &= ~MASK_GPOPT;
1435 iq2000_isa = IQ2000_ISA_DEFAULT;
1437 /* Identify the processor type. */
1439 iq2000_print_operand_punct['?'] = 1;
1440 iq2000_print_operand_punct['#'] = 1;
1441 iq2000_print_operand_punct['&'] = 1;
1442 iq2000_print_operand_punct['!'] = 1;
1443 iq2000_print_operand_punct['*'] = 1;
1444 iq2000_print_operand_punct['@'] = 1;
1445 iq2000_print_operand_punct['.'] = 1;
1446 iq2000_print_operand_punct['('] = 1;
1447 iq2000_print_operand_punct[')'] = 1;
1448 iq2000_print_operand_punct['['] = 1;
1449 iq2000_print_operand_punct[']'] = 1;
1450 iq2000_print_operand_punct['<'] = 1;
1451 iq2000_print_operand_punct['>'] = 1;
1452 iq2000_print_operand_punct['{'] = 1;
1453 iq2000_print_operand_punct['}'] = 1;
1454 iq2000_print_operand_punct['^'] = 1;
1455 iq2000_print_operand_punct['$'] = 1;
1456 iq2000_print_operand_punct['+'] = 1;
1457 iq2000_print_operand_punct['~'] = 1;
1459 /* Save GPR registers in word_mode sized hunks. word_mode hasn't been
1460 initialized yet, so we can't use that here. */
1461 gpr_mode = SImode;
1463 /* Function to allocate machine-dependent function status. */
1464 init_machine_status = iq2000_init_machine_status;
1467 /* The arg pointer (which is eliminated) points to the virtual frame pointer,
1468 while the frame pointer (which may be eliminated) points to the stack
1469 pointer after the initial adjustments. */
1471 HOST_WIDE_INT
1472 iq2000_debugger_offset (rtx addr, HOST_WIDE_INT offset)
1474 rtx offset2 = const0_rtx;
1475 rtx reg = eliminate_constant_term (addr, & offset2);
1477 if (offset == 0)
1478 offset = INTVAL (offset2);
1480 if (reg == stack_pointer_rtx || reg == frame_pointer_rtx
1481 || reg == hard_frame_pointer_rtx)
1483 HOST_WIDE_INT frame_size = (!cfun->machine->initialized)
1484 ? compute_frame_size (get_frame_size ())
1485 : cfun->machine->total_size;
1487 offset = offset - frame_size;
1490 return offset;
1493 /* If defined, a C statement to be executed just prior to the output of
1494 assembler code for INSN, to modify the extracted operands so they will be
1495 output differently.
1497 Here the argument OPVEC is the vector containing the operands extracted
1498 from INSN, and NOPERANDS is the number of elements of the vector which
1499 contain meaningful data for this insn. The contents of this vector are
1500 what will be used to convert the insn template into assembler code, so you
1501 can change the assembler output by changing the contents of the vector.
1503 We use it to check if the current insn needs a nop in front of it because
1504 of load delays, and also to update the delay slot statistics. */
1506 void
1507 final_prescan_insn (rtx insn, rtx opvec[] ATTRIBUTE_UNUSED,
1508 int noperands ATTRIBUTE_UNUSED)
1510 if (dslots_number_nops > 0)
1512 rtx pattern = PATTERN (insn);
1513 int length = get_attr_length (insn);
1515 /* Do we need to emit a NOP? */
1516 if (length == 0
1517 || (iq2000_load_reg != 0 && reg_mentioned_p (iq2000_load_reg, pattern))
1518 || (iq2000_load_reg2 != 0 && reg_mentioned_p (iq2000_load_reg2, pattern))
1519 || (iq2000_load_reg3 != 0 && reg_mentioned_p (iq2000_load_reg3, pattern))
1520 || (iq2000_load_reg4 != 0
1521 && reg_mentioned_p (iq2000_load_reg4, pattern)))
1522 fputs ("\tnop\n", asm_out_file);
1524 else
1525 dslots_load_filled ++;
1527 while (--dslots_number_nops > 0)
1528 fputs ("\tnop\n", asm_out_file);
1530 iq2000_load_reg = 0;
1531 iq2000_load_reg2 = 0;
1532 iq2000_load_reg3 = 0;
1533 iq2000_load_reg4 = 0;
1536 if ( (GET_CODE (insn) == JUMP_INSN
1537 || GET_CODE (insn) == CALL_INSN
1538 || (GET_CODE (PATTERN (insn)) == RETURN))
1539 && NEXT_INSN (PREV_INSN (insn)) == insn)
1541 rtx nop_insn = emit_insn_after (gen_nop (), insn);
1543 INSN_ADDRESSES_NEW (nop_insn, -1);
1546 if (TARGET_STATS
1547 && (GET_CODE (insn) == JUMP_INSN || GET_CODE (insn) == CALL_INSN))
1548 dslots_jump_total ++;
1551 /* Return the bytes needed to compute the frame pointer from the current
1552 stack pointer where SIZE is the # of var. bytes allocated.
1554 IQ2000 stack frames look like:
1556 Before call After call
1557 +-----------------------+ +-----------------------+
1558 high | | | |
1559 mem. | | | |
1560 | caller's temps. | | caller's temps. |
1561 | | | |
1562 +-----------------------+ +-----------------------+
1563 | | | |
1564 | arguments on stack. | | arguments on stack. |
1565 | | | |
1566 +-----------------------+ +-----------------------+
1567 | 4 words to save | | 4 words to save |
1568 | arguments passed | | arguments passed |
1569 | in registers, even | | in registers, even |
1570 SP->| if not passed. | VFP->| if not passed. |
1571 +-----------------------+ +-----------------------+
1573 | fp register save |
1575 +-----------------------+
1577 | gp register save |
1579 +-----------------------+
1581 | local variables |
1583 +-----------------------+
1585 | alloca allocations |
1587 +-----------------------+
1589 | GP save for V.4 abi |
1591 +-----------------------+
1593 | arguments on stack |
1595 +-----------------------+
1596 | 4 words to save |
1597 | arguments passed |
1598 | in registers, even |
1599 low SP->| if not passed. |
1600 memory +-----------------------+ */
1602 HOST_WIDE_INT
1603 compute_frame_size (HOST_WIDE_INT size)
1605 int regno;
1606 HOST_WIDE_INT total_size; /* # bytes that the entire frame takes up. */
1607 HOST_WIDE_INT var_size; /* # bytes that variables take up. */
1608 HOST_WIDE_INT args_size; /* # bytes that outgoing arguments take up. */
1609 HOST_WIDE_INT extra_size; /* # extra bytes. */
1610 HOST_WIDE_INT gp_reg_rounded; /* # bytes needed to store gp after rounding. */
1611 HOST_WIDE_INT gp_reg_size; /* # bytes needed to store gp regs. */
1612 HOST_WIDE_INT fp_reg_size; /* # bytes needed to store fp regs. */
1613 long mask; /* mask of saved gp registers. */
1614 int fp_inc; /* 1 or 2 depending on the size of fp regs. */
1615 long fp_bits; /* bitmask to use for each fp register. */
1617 gp_reg_size = 0;
1618 fp_reg_size = 0;
1619 mask = 0;
1620 extra_size = IQ2000_STACK_ALIGN ((0));
1621 var_size = IQ2000_STACK_ALIGN (size);
1622 args_size = IQ2000_STACK_ALIGN (crtl->outgoing_args_size);
1624 /* If a function dynamically allocates the stack and
1625 has 0 for STACK_DYNAMIC_OFFSET then allocate some stack space. */
1626 if (args_size == 0 && cfun->calls_alloca)
1627 args_size = 4 * UNITS_PER_WORD;
1629 total_size = var_size + args_size + extra_size;
1631 /* Calculate space needed for gp registers. */
1632 for (regno = GP_REG_FIRST; regno <= GP_REG_LAST; regno++)
1634 if (MUST_SAVE_REGISTER (regno))
1636 gp_reg_size += GET_MODE_SIZE (gpr_mode);
1637 mask |= 1L << (regno - GP_REG_FIRST);
1641 /* We need to restore these for the handler. */
1642 if (crtl->calls_eh_return)
1644 unsigned int i;
1646 for (i = 0; ; ++i)
1648 regno = EH_RETURN_DATA_REGNO (i);
1649 if (regno == (int) INVALID_REGNUM)
1650 break;
1651 gp_reg_size += GET_MODE_SIZE (gpr_mode);
1652 mask |= 1L << (regno - GP_REG_FIRST);
1656 fp_inc = 2;
1657 fp_bits = 3;
1658 gp_reg_rounded = IQ2000_STACK_ALIGN (gp_reg_size);
1659 total_size += gp_reg_rounded + IQ2000_STACK_ALIGN (fp_reg_size);
1661 /* The gp reg is caller saved, so there is no need for leaf routines
1662 (total_size == extra_size) to save the gp reg. */
1663 if (total_size == extra_size
1664 && ! profile_flag)
1665 total_size = extra_size = 0;
1667 total_size += IQ2000_STACK_ALIGN (crtl->args.pretend_args_size);
1669 /* Save other computed information. */
1670 cfun->machine->total_size = total_size;
1671 cfun->machine->var_size = var_size;
1672 cfun->machine->args_size = args_size;
1673 cfun->machine->extra_size = extra_size;
1674 cfun->machine->gp_reg_size = gp_reg_size;
1675 cfun->machine->fp_reg_size = fp_reg_size;
1676 cfun->machine->mask = mask;
1677 cfun->machine->initialized = reload_completed;
1678 cfun->machine->num_gp = gp_reg_size / UNITS_PER_WORD;
1680 if (mask)
1682 unsigned long offset;
1684 offset = (args_size + extra_size + var_size
1685 + gp_reg_size - GET_MODE_SIZE (gpr_mode));
1687 cfun->machine->gp_sp_offset = offset;
1688 cfun->machine->gp_save_offset = offset - total_size;
1690 else
1692 cfun->machine->gp_sp_offset = 0;
1693 cfun->machine->gp_save_offset = 0;
1696 cfun->machine->fp_sp_offset = 0;
1697 cfun->machine->fp_save_offset = 0;
1699 /* Ok, we're done. */
1700 return total_size;
1704 /* We can always eliminate to the frame pointer. We can eliminate to the
1705 stack pointer unless a frame pointer is needed. */
1707 bool
1708 iq2000_can_eliminate (const int from, const int to)
1710 return (from == RETURN_ADDRESS_POINTER_REGNUM
1711 && (! leaf_function_p ()
1712 || (to == GP_REG_FIRST + 31 && leaf_function_p)))
1713 || (from != RETURN_ADDRESS_POINTER_REGNUM
1714 && (to == HARD_FRAME_POINTER_REGNUM
1715 || (to == STACK_POINTER_REGNUM
1716 && ! frame_pointer_needed)));
1719 /* Implement INITIAL_ELIMINATION_OFFSET. FROM is either the frame
1720 pointer, argument pointer, or return address pointer. TO is either
1721 the stack pointer or hard frame pointer. */
1724 iq2000_initial_elimination_offset (int from, int to ATTRIBUTE_UNUSED)
1726 int offset;
1728 compute_frame_size (get_frame_size ());
1729 if ((from) == FRAME_POINTER_REGNUM)
1730 (offset) = 0;
1731 else if ((from) == ARG_POINTER_REGNUM)
1732 (offset) = (cfun->machine->total_size);
1733 else if ((from) == RETURN_ADDRESS_POINTER_REGNUM)
1735 if (leaf_function_p ())
1736 (offset) = 0;
1737 else (offset) = cfun->machine->gp_sp_offset
1738 + ((UNITS_PER_WORD - (POINTER_SIZE / BITS_PER_UNIT))
1739 * (BYTES_BIG_ENDIAN != 0));
1742 return offset;
1745 /* Common code to emit the insns (or to write the instructions to a file)
1746 to save/restore registers.
1747 Other parts of the code assume that IQ2000_TEMP1_REGNUM (aka large_reg)
1748 is not modified within save_restore_insns. */
1750 #define BITSET_P(VALUE,BIT) (((VALUE) & (1L << (BIT))) != 0)
1752 /* Emit instructions to load the value (SP + OFFSET) into IQ2000_TEMP2_REGNUM
1753 and return an rtl expression for the register. Write the assembly
1754 instructions directly to FILE if it is not null, otherwise emit them as
1755 rtl.
1757 This function is a subroutine of save_restore_insns. It is used when
1758 OFFSET is too large to add in a single instruction. */
1760 static rtx
1761 iq2000_add_large_offset_to_sp (HOST_WIDE_INT offset)
1763 rtx reg = gen_rtx_REG (Pmode, IQ2000_TEMP2_REGNUM);
1764 rtx offset_rtx = GEN_INT (offset);
1766 emit_move_insn (reg, offset_rtx);
1767 emit_insn (gen_addsi3 (reg, reg, stack_pointer_rtx));
1768 return reg;
1771 /* Make INSN frame related and note that it performs the frame-related
1772 operation DWARF_PATTERN. */
1774 static void
1775 iq2000_annotate_frame_insn (rtx insn, rtx dwarf_pattern)
1777 RTX_FRAME_RELATED_P (insn) = 1;
1778 REG_NOTES (insn) = alloc_EXPR_LIST (REG_FRAME_RELATED_EXPR,
1779 dwarf_pattern,
1780 REG_NOTES (insn));
1783 /* Emit a move instruction that stores REG in MEM. Make the instruction
1784 frame related and note that it stores REG at (SP + OFFSET). */
1786 static void
1787 iq2000_emit_frame_related_store (rtx mem, rtx reg, HOST_WIDE_INT offset)
1789 rtx dwarf_address = plus_constant (stack_pointer_rtx, offset);
1790 rtx dwarf_mem = gen_rtx_MEM (GET_MODE (reg), dwarf_address);
1792 iq2000_annotate_frame_insn (emit_move_insn (mem, reg),
1793 gen_rtx_SET (GET_MODE (reg), dwarf_mem, reg));
1796 /* Emit instructions to save/restore registers, as determined by STORE_P. */
1798 static void
1799 save_restore_insns (int store_p)
1801 long mask = cfun->machine->mask;
1802 int regno;
1803 rtx base_reg_rtx;
1804 HOST_WIDE_INT base_offset;
1805 HOST_WIDE_INT gp_offset;
1806 HOST_WIDE_INT end_offset;
1808 gcc_assert (!frame_pointer_needed
1809 || BITSET_P (mask, HARD_FRAME_POINTER_REGNUM - GP_REG_FIRST));
1811 if (mask == 0)
1813 base_reg_rtx = 0, base_offset = 0;
1814 return;
1817 /* Save registers starting from high to low. The debuggers prefer at least
1818 the return register be stored at func+4, and also it allows us not to
1819 need a nop in the epilog if at least one register is reloaded in
1820 addition to return address. */
1822 /* Save GP registers if needed. */
1823 /* Pick which pointer to use as a base register. For small frames, just
1824 use the stack pointer. Otherwise, use a temporary register. Save 2
1825 cycles if the save area is near the end of a large frame, by reusing
1826 the constant created in the prologue/epilogue to adjust the stack
1827 frame. */
1829 gp_offset = cfun->machine->gp_sp_offset;
1830 end_offset
1831 = gp_offset - (cfun->machine->gp_reg_size
1832 - GET_MODE_SIZE (gpr_mode));
1834 if (gp_offset < 0 || end_offset < 0)
1835 internal_error
1836 ("gp_offset (%ld) or end_offset (%ld) is less than zero",
1837 (long) gp_offset, (long) end_offset);
1839 else if (gp_offset < 32768)
1840 base_reg_rtx = stack_pointer_rtx, base_offset = 0;
1841 else
1843 int regno;
1844 int reg_save_count = 0;
1846 for (regno = GP_REG_LAST; regno >= GP_REG_FIRST; regno--)
1847 if (BITSET_P (mask, regno - GP_REG_FIRST)) reg_save_count += 1;
1848 base_offset = gp_offset - ((reg_save_count - 1) * 4);
1849 base_reg_rtx = iq2000_add_large_offset_to_sp (base_offset);
1852 for (regno = GP_REG_LAST; regno >= GP_REG_FIRST; regno--)
1854 if (BITSET_P (mask, regno - GP_REG_FIRST))
1856 rtx reg_rtx;
1857 rtx mem_rtx
1858 = gen_rtx_MEM (gpr_mode,
1859 gen_rtx_PLUS (Pmode, base_reg_rtx,
1860 GEN_INT (gp_offset - base_offset)));
1862 reg_rtx = gen_rtx_REG (gpr_mode, regno);
1864 if (store_p)
1865 iq2000_emit_frame_related_store (mem_rtx, reg_rtx, gp_offset);
1866 else
1868 emit_move_insn (reg_rtx, mem_rtx);
1870 gp_offset -= GET_MODE_SIZE (gpr_mode);
1875 /* Expand the prologue into a bunch of separate insns. */
1877 void
1878 iq2000_expand_prologue (void)
1880 int regno;
1881 HOST_WIDE_INT tsize;
1882 int last_arg_is_vararg_marker = 0;
1883 tree fndecl = current_function_decl;
1884 tree fntype = TREE_TYPE (fndecl);
1885 tree fnargs = DECL_ARGUMENTS (fndecl);
1886 rtx next_arg_reg;
1887 int i;
1888 tree next_arg;
1889 tree cur_arg;
1890 CUMULATIVE_ARGS args_so_far;
1891 int store_args_on_stack = (iq2000_can_use_return_insn ());
1893 /* If struct value address is treated as the first argument. */
1894 if (aggregate_value_p (DECL_RESULT (fndecl), fndecl)
1895 && !cfun->returns_pcc_struct
1896 && targetm.calls.struct_value_rtx (TREE_TYPE (fndecl), 1) == 0)
1898 tree type = build_pointer_type (fntype);
1899 tree function_result_decl = build_decl (BUILTINS_LOCATION,
1900 PARM_DECL, NULL_TREE, type);
1902 DECL_ARG_TYPE (function_result_decl) = type;
1903 TREE_CHAIN (function_result_decl) = fnargs;
1904 fnargs = function_result_decl;
1907 /* For arguments passed in registers, find the register number
1908 of the first argument in the variable part of the argument list,
1909 otherwise GP_ARG_LAST+1. Note also if the last argument is
1910 the varargs special argument, and treat it as part of the
1911 variable arguments.
1913 This is only needed if store_args_on_stack is true. */
1914 INIT_CUMULATIVE_ARGS (args_so_far, fntype, NULL_RTX, 0, 0);
1915 regno = GP_ARG_FIRST;
1917 for (cur_arg = fnargs; cur_arg != 0; cur_arg = next_arg)
1919 tree passed_type = DECL_ARG_TYPE (cur_arg);
1920 enum machine_mode passed_mode = TYPE_MODE (passed_type);
1921 rtx entry_parm;
1923 if (TREE_ADDRESSABLE (passed_type))
1925 passed_type = build_pointer_type (passed_type);
1926 passed_mode = Pmode;
1929 entry_parm = FUNCTION_ARG (args_so_far, passed_mode, passed_type, 1);
1931 FUNCTION_ARG_ADVANCE (args_so_far, passed_mode, passed_type, 1);
1932 next_arg = TREE_CHAIN (cur_arg);
1934 if (entry_parm && store_args_on_stack)
1936 if (next_arg == 0
1937 && DECL_NAME (cur_arg)
1938 && ((0 == strcmp (IDENTIFIER_POINTER (DECL_NAME (cur_arg)),
1939 "__builtin_va_alist"))
1940 || (0 == strcmp (IDENTIFIER_POINTER (DECL_NAME (cur_arg)),
1941 "va_alist"))))
1943 last_arg_is_vararg_marker = 1;
1944 break;
1946 else
1948 int words;
1950 gcc_assert (GET_CODE (entry_parm) == REG);
1952 /* Passed in a register, so will get homed automatically. */
1953 if (GET_MODE (entry_parm) == BLKmode)
1954 words = (int_size_in_bytes (passed_type) + 3) / 4;
1955 else
1956 words = (GET_MODE_SIZE (GET_MODE (entry_parm)) + 3) / 4;
1958 regno = REGNO (entry_parm) + words - 1;
1961 else
1963 regno = GP_ARG_LAST+1;
1964 break;
1968 /* In order to pass small structures by value in registers we need to
1969 shift the value into the high part of the register.
1970 Function_arg has encoded a PARALLEL rtx, holding a vector of
1971 adjustments to be made as the next_arg_reg variable, so we split up the
1972 insns, and emit them separately. */
1973 next_arg_reg = FUNCTION_ARG (args_so_far, VOIDmode, void_type_node, 1);
1974 if (next_arg_reg != 0 && GET_CODE (next_arg_reg) == PARALLEL)
1976 rtvec adjust = XVEC (next_arg_reg, 0);
1977 int num = GET_NUM_ELEM (adjust);
1979 for (i = 0; i < num; i++)
1981 rtx insn, pattern;
1983 pattern = RTVEC_ELT (adjust, i);
1984 if (GET_CODE (pattern) != SET
1985 || GET_CODE (SET_SRC (pattern)) != ASHIFT)
1986 abort_with_insn (pattern, "Insn is not a shift");
1987 PUT_CODE (SET_SRC (pattern), ASHIFTRT);
1989 insn = emit_insn (pattern);
1993 tsize = compute_frame_size (get_frame_size ());
1995 /* If this function is a varargs function, store any registers that
1996 would normally hold arguments ($4 - $7) on the stack. */
1997 if (store_args_on_stack
1998 && ((TYPE_ARG_TYPES (fntype) != 0
1999 && (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
2000 != void_type_node))
2001 || last_arg_is_vararg_marker))
2003 int offset = (regno - GP_ARG_FIRST) * UNITS_PER_WORD;
2004 rtx ptr = stack_pointer_rtx;
2006 for (; regno <= GP_ARG_LAST; regno++)
2008 if (offset != 0)
2009 ptr = gen_rtx_PLUS (Pmode, stack_pointer_rtx, GEN_INT (offset));
2010 emit_move_insn (gen_rtx_MEM (gpr_mode, ptr),
2011 gen_rtx_REG (gpr_mode, regno));
2013 offset += GET_MODE_SIZE (gpr_mode);
2017 if (tsize > 0)
2019 rtx tsize_rtx = GEN_INT (tsize);
2020 rtx adjustment_rtx, insn, dwarf_pattern;
2022 if (tsize > 32767)
2024 adjustment_rtx = gen_rtx_REG (Pmode, IQ2000_TEMP1_REGNUM);
2025 emit_move_insn (adjustment_rtx, tsize_rtx);
2027 else
2028 adjustment_rtx = tsize_rtx;
2030 insn = emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
2031 adjustment_rtx));
2033 dwarf_pattern = gen_rtx_SET (Pmode, stack_pointer_rtx,
2034 plus_constant (stack_pointer_rtx, -tsize));
2036 iq2000_annotate_frame_insn (insn, dwarf_pattern);
2038 save_restore_insns (1);
2040 if (frame_pointer_needed)
2042 rtx insn = 0;
2044 insn = emit_insn (gen_movsi (hard_frame_pointer_rtx,
2045 stack_pointer_rtx));
2047 if (insn)
2048 RTX_FRAME_RELATED_P (insn) = 1;
2052 emit_insn (gen_blockage ());
2055 /* Expand the epilogue into a bunch of separate insns. */
2057 void
2058 iq2000_expand_epilogue (void)
2060 HOST_WIDE_INT tsize = cfun->machine->total_size;
2061 rtx tsize_rtx = GEN_INT (tsize);
2062 rtx tmp_rtx = (rtx)0;
2064 if (iq2000_can_use_return_insn ())
2066 emit_jump_insn (gen_return ());
2067 return;
2070 if (tsize > 32767)
2072 tmp_rtx = gen_rtx_REG (Pmode, IQ2000_TEMP1_REGNUM);
2073 emit_move_insn (tmp_rtx, tsize_rtx);
2074 tsize_rtx = tmp_rtx;
2077 if (tsize > 0)
2079 if (frame_pointer_needed)
2081 emit_insn (gen_blockage ());
2083 emit_insn (gen_movsi (stack_pointer_rtx, hard_frame_pointer_rtx));
2086 save_restore_insns (0);
2088 if (crtl->calls_eh_return)
2090 rtx eh_ofs = EH_RETURN_STACKADJ_RTX;
2091 emit_insn (gen_addsi3 (eh_ofs, eh_ofs, tsize_rtx));
2092 tsize_rtx = eh_ofs;
2095 emit_insn (gen_blockage ());
2097 if (tsize != 0 || crtl->calls_eh_return)
2099 emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx,
2100 tsize_rtx));
2104 if (crtl->calls_eh_return)
2106 /* Perform the additional bump for __throw. */
2107 emit_move_insn (gen_rtx_REG (Pmode, HARD_FRAME_POINTER_REGNUM),
2108 stack_pointer_rtx);
2109 emit_use (gen_rtx_REG (Pmode, HARD_FRAME_POINTER_REGNUM));
2110 emit_jump_insn (gen_eh_return_internal ());
2112 else
2113 emit_jump_insn (gen_return_internal (gen_rtx_REG (Pmode,
2114 GP_REG_FIRST + 31)));
2117 void
2118 iq2000_expand_eh_return (rtx address)
2120 HOST_WIDE_INT gp_offset = cfun->machine->gp_sp_offset;
2121 rtx scratch;
2123 scratch = plus_constant (stack_pointer_rtx, gp_offset);
2124 emit_move_insn (gen_rtx_MEM (GET_MODE (address), scratch), address);
2127 /* Return nonzero if this function is known to have a null epilogue.
2128 This allows the optimizer to omit jumps to jumps if no stack
2129 was created. */
2132 iq2000_can_use_return_insn (void)
2134 if (! reload_completed)
2135 return 0;
2137 if (df_regs_ever_live_p (31) || profile_flag)
2138 return 0;
2140 if (cfun->machine->initialized)
2141 return cfun->machine->total_size == 0;
2143 return compute_frame_size (get_frame_size ()) == 0;
2146 /* Returns nonzero if X contains a SYMBOL_REF. */
2148 static int
2149 symbolic_expression_p (rtx x)
2151 if (GET_CODE (x) == SYMBOL_REF)
2152 return 1;
2154 if (GET_CODE (x) == CONST)
2155 return symbolic_expression_p (XEXP (x, 0));
2157 if (UNARY_P (x))
2158 return symbolic_expression_p (XEXP (x, 0));
2160 if (ARITHMETIC_P (x))
2161 return (symbolic_expression_p (XEXP (x, 0))
2162 || symbolic_expression_p (XEXP (x, 1)));
2164 return 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 (enum 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 enum machine_mode mode = TYPE_MODE (valtype);
2231 int unsignedp = TYPE_UNSIGNED (valtype);
2232 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 (enum 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 *cum, enum machine_mode mode,
2270 const_tree type, bool named ATTRIBUTE_UNUSED)
2272 int size;
2274 /* We must pass by reference if we would be both passing in registers
2275 and the stack. This is because any subsequent partial arg would be
2276 handled incorrectly in this case. */
2277 if (cum && targetm.calls.must_pass_in_stack (mode, type))
2279 /* Don't pass the actual CUM to FUNCTION_ARG, because we would
2280 get double copies of any offsets generated for small structs
2281 passed in registers. */
2282 CUMULATIVE_ARGS temp;
2284 temp = *cum;
2285 if (FUNCTION_ARG (temp, mode, type, named) != 0)
2286 return 1;
2289 if (type == NULL_TREE || mode == DImode || mode == DFmode)
2290 return 0;
2292 size = int_size_in_bytes (type);
2293 return size == -1 || size > UNITS_PER_WORD;
2296 /* Return the length of INSN. LENGTH is the initial length computed by
2297 attributes in the machine-description file. */
2300 iq2000_adjust_insn_length (rtx insn, int length)
2302 /* A unconditional jump has an unfilled delay slot if it is not part
2303 of a sequence. A conditional jump normally has a delay slot. */
2304 if (simplejump_p (insn)
2305 || ( (GET_CODE (insn) == JUMP_INSN
2306 || GET_CODE (insn) == CALL_INSN)))
2307 length += 4;
2309 return length;
2312 /* Output assembly instructions to perform a conditional branch.
2314 INSN is the branch instruction. OPERANDS[0] is the condition.
2315 OPERANDS[1] is the target of the branch. OPERANDS[2] is the target
2316 of the first operand to the condition. If TWO_OPERANDS_P is
2317 nonzero the comparison takes two operands; OPERANDS[3] will be the
2318 second operand.
2320 If INVERTED_P is nonzero we are to branch if the condition does
2321 not hold. If FLOAT_P is nonzero this is a floating-point comparison.
2323 LENGTH is the length (in bytes) of the sequence we are to generate.
2324 That tells us whether to generate a simple conditional branch, or a
2325 reversed conditional branch around a `jr' instruction. */
2327 char *
2328 iq2000_output_conditional_branch (rtx insn, rtx * operands, int two_operands_p,
2329 int float_p, int inverted_p, int length)
2331 static char buffer[200];
2332 /* The kind of comparison we are doing. */
2333 enum rtx_code code = GET_CODE (operands[0]);
2334 /* Nonzero if the opcode for the comparison needs a `z' indicating
2335 that it is a comparison against zero. */
2336 int need_z_p;
2337 /* A string to use in the assembly output to represent the first
2338 operand. */
2339 const char *op1 = "%z2";
2340 /* A string to use in the assembly output to represent the second
2341 operand. Use the hard-wired zero register if there's no second
2342 operand. */
2343 const char *op2 = (two_operands_p ? ",%z3" : ",%.");
2344 /* The operand-printing string for the comparison. */
2345 const char *comp = (float_p ? "%F0" : "%C0");
2346 /* The operand-printing string for the inverted comparison. */
2347 const char *inverted_comp = (float_p ? "%W0" : "%N0");
2349 /* Likely variants of each branch instruction annul the instruction
2350 in the delay slot if the branch is not taken. */
2351 iq2000_branch_likely = (final_sequence && INSN_ANNULLED_BRANCH_P (insn));
2353 if (!two_operands_p)
2355 /* To compute whether than A > B, for example, we normally
2356 subtract B from A and then look at the sign bit. But, if we
2357 are doing an unsigned comparison, and B is zero, we don't
2358 have to do the subtraction. Instead, we can just check to
2359 see if A is nonzero. Thus, we change the CODE here to
2360 reflect the simpler comparison operation. */
2361 switch (code)
2363 case GTU:
2364 code = NE;
2365 break;
2367 case LEU:
2368 code = EQ;
2369 break;
2371 case GEU:
2372 /* A condition which will always be true. */
2373 code = EQ;
2374 op1 = "%.";
2375 break;
2377 case LTU:
2378 /* A condition which will always be false. */
2379 code = NE;
2380 op1 = "%.";
2381 break;
2383 default:
2384 /* Not a special case. */
2385 break;
2389 /* Relative comparisons are always done against zero. But
2390 equality comparisons are done between two operands, and therefore
2391 do not require a `z' in the assembly language output. */
2392 need_z_p = (!float_p && code != EQ && code != NE);
2393 /* For comparisons against zero, the zero is not provided
2394 explicitly. */
2395 if (need_z_p)
2396 op2 = "";
2398 /* Begin by terminating the buffer. That way we can always use
2399 strcat to add to it. */
2400 buffer[0] = '\0';
2402 switch (length)
2404 case 4:
2405 case 8:
2406 /* Just a simple conditional branch. */
2407 if (float_p)
2408 sprintf (buffer, "b%s%%?\t%%Z2%%1",
2409 inverted_p ? inverted_comp : comp);
2410 else
2411 sprintf (buffer, "b%s%s%%?\t%s%s,%%1",
2412 inverted_p ? inverted_comp : comp,
2413 need_z_p ? "z" : "",
2414 op1,
2415 op2);
2416 return buffer;
2418 case 12:
2419 case 16:
2421 /* Generate a reversed conditional branch around ` j'
2422 instruction:
2424 .set noreorder
2425 .set nomacro
2426 bc l
2428 j target
2429 .set macro
2430 .set reorder
2433 Because we have to jump four bytes *past* the following
2434 instruction if this branch was annulled, we can't just use
2435 a label, as in the picture above; there's no way to put the
2436 label after the next instruction, as the assembler does not
2437 accept `.L+4' as the target of a branch. (We can't just
2438 wait until the next instruction is output; it might be a
2439 macro and take up more than four bytes. Once again, we see
2440 why we want to eliminate macros.)
2442 If the branch is annulled, we jump four more bytes that we
2443 would otherwise; that way we skip the annulled instruction
2444 in the delay slot. */
2446 const char *target
2447 = ((iq2000_branch_likely || length == 16) ? ".+16" : ".+12");
2448 char *c;
2450 c = strchr (buffer, '\0');
2451 /* Generate the reversed comparison. This takes four
2452 bytes. */
2453 if (float_p)
2454 sprintf (c, "b%s\t%%Z2%s",
2455 inverted_p ? comp : inverted_comp,
2456 target);
2457 else
2458 sprintf (c, "b%s%s\t%s%s,%s",
2459 inverted_p ? comp : inverted_comp,
2460 need_z_p ? "z" : "",
2461 op1,
2462 op2,
2463 target);
2464 strcat (c, "\n\tnop\n\tj\t%1");
2465 if (length == 16)
2466 /* The delay slot was unfilled. Since we're inside
2467 .noreorder, the assembler will not fill in the NOP for
2468 us, so we must do it ourselves. */
2469 strcat (buffer, "\n\tnop");
2470 return buffer;
2473 default:
2474 gcc_unreachable ();
2477 /* NOTREACHED */
2478 return 0;
2481 #define def_builtin(NAME, TYPE, CODE) \
2482 add_builtin_function ((NAME), (TYPE), (CODE), BUILT_IN_MD, \
2483 NULL, NULL_TREE)
2485 static void
2486 iq2000_init_builtins (void)
2488 tree endlink = void_list_node;
2489 tree void_ftype, void_ftype_int, void_ftype_int_int;
2490 tree void_ftype_int_int_int;
2491 tree int_ftype_int, int_ftype_int_int, int_ftype_int_int_int;
2492 tree int_ftype_int_int_int_int;
2494 /* func () */
2495 void_ftype
2496 = build_function_type (void_type_node,
2497 tree_cons (NULL_TREE, void_type_node, endlink));
2499 /* func (int) */
2500 void_ftype_int
2501 = build_function_type (void_type_node,
2502 tree_cons (NULL_TREE, integer_type_node, endlink));
2504 /* void func (int, int) */
2505 void_ftype_int_int
2506 = build_function_type (void_type_node,
2507 tree_cons (NULL_TREE, integer_type_node,
2508 tree_cons (NULL_TREE, integer_type_node,
2509 endlink)));
2511 /* int func (int) */
2512 int_ftype_int
2513 = build_function_type (integer_type_node,
2514 tree_cons (NULL_TREE, integer_type_node, endlink));
2516 /* int func (int, int) */
2517 int_ftype_int_int
2518 = build_function_type (integer_type_node,
2519 tree_cons (NULL_TREE, integer_type_node,
2520 tree_cons (NULL_TREE, integer_type_node,
2521 endlink)));
2523 /* void func (int, int, int) */
2524 void_ftype_int_int_int
2525 = build_function_type
2526 (void_type_node,
2527 tree_cons (NULL_TREE, integer_type_node,
2528 tree_cons (NULL_TREE, integer_type_node,
2529 tree_cons (NULL_TREE,
2530 integer_type_node,
2531 endlink))));
2533 /* int func (int, int, int, int) */
2534 int_ftype_int_int_int_int
2535 = build_function_type
2536 (integer_type_node,
2537 tree_cons (NULL_TREE, integer_type_node,
2538 tree_cons (NULL_TREE, integer_type_node,
2539 tree_cons (NULL_TREE,
2540 integer_type_node,
2541 tree_cons (NULL_TREE,
2542 integer_type_node,
2543 endlink)))));
2545 /* int func (int, int, int) */
2546 int_ftype_int_int_int
2547 = build_function_type
2548 (integer_type_node,
2549 tree_cons (NULL_TREE, integer_type_node,
2550 tree_cons (NULL_TREE, integer_type_node,
2551 tree_cons (NULL_TREE,
2552 integer_type_node,
2553 endlink))));
2555 /* int func (int, int, int, int) */
2556 int_ftype_int_int_int_int
2557 = build_function_type
2558 (integer_type_node,
2559 tree_cons (NULL_TREE, integer_type_node,
2560 tree_cons (NULL_TREE, integer_type_node,
2561 tree_cons (NULL_TREE,
2562 integer_type_node,
2563 tree_cons (NULL_TREE,
2564 integer_type_node,
2565 endlink)))));
2567 def_builtin ("__builtin_ado16", int_ftype_int_int, IQ2000_BUILTIN_ADO16);
2568 def_builtin ("__builtin_ram", int_ftype_int_int_int_int, IQ2000_BUILTIN_RAM);
2569 def_builtin ("__builtin_chkhdr", void_ftype_int_int, IQ2000_BUILTIN_CHKHDR);
2570 def_builtin ("__builtin_pkrl", void_ftype_int_int, IQ2000_BUILTIN_PKRL);
2571 def_builtin ("__builtin_cfc0", int_ftype_int, IQ2000_BUILTIN_CFC0);
2572 def_builtin ("__builtin_cfc1", int_ftype_int, IQ2000_BUILTIN_CFC1);
2573 def_builtin ("__builtin_cfc2", int_ftype_int, IQ2000_BUILTIN_CFC2);
2574 def_builtin ("__builtin_cfc3", int_ftype_int, IQ2000_BUILTIN_CFC3);
2575 def_builtin ("__builtin_ctc0", void_ftype_int_int, IQ2000_BUILTIN_CTC0);
2576 def_builtin ("__builtin_ctc1", void_ftype_int_int, IQ2000_BUILTIN_CTC1);
2577 def_builtin ("__builtin_ctc2", void_ftype_int_int, IQ2000_BUILTIN_CTC2);
2578 def_builtin ("__builtin_ctc3", void_ftype_int_int, IQ2000_BUILTIN_CTC3);
2579 def_builtin ("__builtin_mfc0", int_ftype_int, IQ2000_BUILTIN_MFC0);
2580 def_builtin ("__builtin_mfc1", int_ftype_int, IQ2000_BUILTIN_MFC1);
2581 def_builtin ("__builtin_mfc2", int_ftype_int, IQ2000_BUILTIN_MFC2);
2582 def_builtin ("__builtin_mfc3", int_ftype_int, IQ2000_BUILTIN_MFC3);
2583 def_builtin ("__builtin_mtc0", void_ftype_int_int, IQ2000_BUILTIN_MTC0);
2584 def_builtin ("__builtin_mtc1", void_ftype_int_int, IQ2000_BUILTIN_MTC1);
2585 def_builtin ("__builtin_mtc2", void_ftype_int_int, IQ2000_BUILTIN_MTC2);
2586 def_builtin ("__builtin_mtc3", void_ftype_int_int, IQ2000_BUILTIN_MTC3);
2587 def_builtin ("__builtin_lur", void_ftype_int_int, IQ2000_BUILTIN_LUR);
2588 def_builtin ("__builtin_rb", void_ftype_int_int, IQ2000_BUILTIN_RB);
2589 def_builtin ("__builtin_rx", void_ftype_int_int, IQ2000_BUILTIN_RX);
2590 def_builtin ("__builtin_srrd", void_ftype_int, IQ2000_BUILTIN_SRRD);
2591 def_builtin ("__builtin_srwr", void_ftype_int_int, IQ2000_BUILTIN_SRWR);
2592 def_builtin ("__builtin_wb", void_ftype_int_int, IQ2000_BUILTIN_WB);
2593 def_builtin ("__builtin_wx", void_ftype_int_int, IQ2000_BUILTIN_WX);
2594 def_builtin ("__builtin_luc32l", void_ftype_int_int, IQ2000_BUILTIN_LUC32L);
2595 def_builtin ("__builtin_luc64", void_ftype_int_int, IQ2000_BUILTIN_LUC64);
2596 def_builtin ("__builtin_luc64l", void_ftype_int_int, IQ2000_BUILTIN_LUC64L);
2597 def_builtin ("__builtin_luk", void_ftype_int_int, IQ2000_BUILTIN_LUK);
2598 def_builtin ("__builtin_lulck", void_ftype_int, IQ2000_BUILTIN_LULCK);
2599 def_builtin ("__builtin_lum32", void_ftype_int_int, IQ2000_BUILTIN_LUM32);
2600 def_builtin ("__builtin_lum32l", void_ftype_int_int, IQ2000_BUILTIN_LUM32L);
2601 def_builtin ("__builtin_lum64", void_ftype_int_int, IQ2000_BUILTIN_LUM64);
2602 def_builtin ("__builtin_lum64l", void_ftype_int_int, IQ2000_BUILTIN_LUM64L);
2603 def_builtin ("__builtin_lurl", void_ftype_int_int, IQ2000_BUILTIN_LURL);
2604 def_builtin ("__builtin_mrgb", int_ftype_int_int_int, IQ2000_BUILTIN_MRGB);
2605 def_builtin ("__builtin_srrdl", void_ftype_int, IQ2000_BUILTIN_SRRDL);
2606 def_builtin ("__builtin_srulck", void_ftype_int, IQ2000_BUILTIN_SRULCK);
2607 def_builtin ("__builtin_srwru", void_ftype_int_int, IQ2000_BUILTIN_SRWRU);
2608 def_builtin ("__builtin_trapqfl", void_ftype, IQ2000_BUILTIN_TRAPQFL);
2609 def_builtin ("__builtin_trapqne", void_ftype, IQ2000_BUILTIN_TRAPQNE);
2610 def_builtin ("__builtin_traprel", void_ftype_int, IQ2000_BUILTIN_TRAPREL);
2611 def_builtin ("__builtin_wbu", void_ftype_int_int_int, IQ2000_BUILTIN_WBU);
2612 def_builtin ("__builtin_syscall", void_ftype, IQ2000_BUILTIN_SYSCALL);
2615 /* Builtin for ICODE having ARGCOUNT args in EXP where each arg
2616 has an rtx CODE. */
2618 static rtx
2619 expand_one_builtin (enum insn_code icode, rtx target, tree exp,
2620 enum rtx_code *code, int argcount)
2622 rtx pat;
2623 tree arg [5];
2624 rtx op [5];
2625 enum machine_mode mode [5];
2626 int i;
2628 mode[0] = insn_data[icode].operand[0].mode;
2629 for (i = 0; i < argcount; i++)
2631 arg[i] = CALL_EXPR_ARG (exp, i);
2632 op[i] = expand_expr (arg[i], NULL_RTX, VOIDmode, 0);
2633 mode[i] = insn_data[icode].operand[i].mode;
2634 if (code[i] == CONST_INT && GET_CODE (op[i]) != CONST_INT)
2635 error ("argument %qd is not a constant", i + 1);
2636 if (code[i] == REG
2637 && ! (*insn_data[icode].operand[i].predicate) (op[i], mode[i]))
2638 op[i] = copy_to_mode_reg (mode[i], op[i]);
2641 if (insn_data[icode].operand[0].constraint[0] == '=')
2643 if (target == 0
2644 || GET_MODE (target) != mode[0]
2645 || ! (*insn_data[icode].operand[0].predicate) (target, mode[0]))
2646 target = gen_reg_rtx (mode[0]);
2648 else
2649 target = 0;
2651 switch (argcount)
2653 case 0:
2654 pat = GEN_FCN (icode) (target);
2655 case 1:
2656 if (target)
2657 pat = GEN_FCN (icode) (target, op[0]);
2658 else
2659 pat = GEN_FCN (icode) (op[0]);
2660 break;
2661 case 2:
2662 if (target)
2663 pat = GEN_FCN (icode) (target, op[0], op[1]);
2664 else
2665 pat = GEN_FCN (icode) (op[0], op[1]);
2666 break;
2667 case 3:
2668 if (target)
2669 pat = GEN_FCN (icode) (target, op[0], op[1], op[2]);
2670 else
2671 pat = GEN_FCN (icode) (op[0], op[1], op[2]);
2672 break;
2673 case 4:
2674 if (target)
2675 pat = GEN_FCN (icode) (target, op[0], op[1], op[2], op[3]);
2676 else
2677 pat = GEN_FCN (icode) (op[0], op[1], op[2], op[3]);
2678 break;
2679 default:
2680 gcc_unreachable ();
2683 if (! pat)
2684 return 0;
2685 emit_insn (pat);
2686 return target;
2689 /* Expand an expression EXP that calls a built-in function,
2690 with result going to TARGET if that's convenient
2691 (and in mode MODE if that's convenient).
2692 SUBTARGET may be used as the target for computing one of EXP's operands.
2693 IGNORE is nonzero if the value is to be ignored. */
2695 static rtx
2696 iq2000_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED,
2697 enum machine_mode mode ATTRIBUTE_UNUSED,
2698 int ignore ATTRIBUTE_UNUSED)
2700 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
2701 int fcode = DECL_FUNCTION_CODE (fndecl);
2702 enum rtx_code code [5];
2704 code[0] = REG;
2705 code[1] = REG;
2706 code[2] = REG;
2707 code[3] = REG;
2708 code[4] = REG;
2709 switch (fcode)
2711 default:
2712 break;
2714 case IQ2000_BUILTIN_ADO16:
2715 return expand_one_builtin (CODE_FOR_ado16, target, exp, code, 2);
2717 case IQ2000_BUILTIN_RAM:
2718 code[1] = CONST_INT;
2719 code[2] = CONST_INT;
2720 code[3] = CONST_INT;
2721 return expand_one_builtin (CODE_FOR_ram, target, exp, code, 4);
2723 case IQ2000_BUILTIN_CHKHDR:
2724 return expand_one_builtin (CODE_FOR_chkhdr, target, exp, code, 2);
2726 case IQ2000_BUILTIN_PKRL:
2727 return expand_one_builtin (CODE_FOR_pkrl, target, exp, code, 2);
2729 case IQ2000_BUILTIN_CFC0:
2730 code[0] = CONST_INT;
2731 return expand_one_builtin (CODE_FOR_cfc0, target, exp, code, 1);
2733 case IQ2000_BUILTIN_CFC1:
2734 code[0] = CONST_INT;
2735 return expand_one_builtin (CODE_FOR_cfc1, target, exp, code, 1);
2737 case IQ2000_BUILTIN_CFC2:
2738 code[0] = CONST_INT;
2739 return expand_one_builtin (CODE_FOR_cfc2, target, exp, code, 1);
2741 case IQ2000_BUILTIN_CFC3:
2742 code[0] = CONST_INT;
2743 return expand_one_builtin (CODE_FOR_cfc3, target, exp, code, 1);
2745 case IQ2000_BUILTIN_CTC0:
2746 code[1] = CONST_INT;
2747 return expand_one_builtin (CODE_FOR_ctc0, target, exp, code, 2);
2749 case IQ2000_BUILTIN_CTC1:
2750 code[1] = CONST_INT;
2751 return expand_one_builtin (CODE_FOR_ctc1, target, exp, code, 2);
2753 case IQ2000_BUILTIN_CTC2:
2754 code[1] = CONST_INT;
2755 return expand_one_builtin (CODE_FOR_ctc2, target, exp, code, 2);
2757 case IQ2000_BUILTIN_CTC3:
2758 code[1] = CONST_INT;
2759 return expand_one_builtin (CODE_FOR_ctc3, target, exp, code, 2);
2761 case IQ2000_BUILTIN_MFC0:
2762 code[0] = CONST_INT;
2763 return expand_one_builtin (CODE_FOR_mfc0, target, exp, code, 1);
2765 case IQ2000_BUILTIN_MFC1:
2766 code[0] = CONST_INT;
2767 return expand_one_builtin (CODE_FOR_mfc1, target, exp, code, 1);
2769 case IQ2000_BUILTIN_MFC2:
2770 code[0] = CONST_INT;
2771 return expand_one_builtin (CODE_FOR_mfc2, target, exp, code, 1);
2773 case IQ2000_BUILTIN_MFC3:
2774 code[0] = CONST_INT;
2775 return expand_one_builtin (CODE_FOR_mfc3, target, exp, code, 1);
2777 case IQ2000_BUILTIN_MTC0:
2778 code[1] = CONST_INT;
2779 return expand_one_builtin (CODE_FOR_mtc0, target, exp, code, 2);
2781 case IQ2000_BUILTIN_MTC1:
2782 code[1] = CONST_INT;
2783 return expand_one_builtin (CODE_FOR_mtc1, target, exp, code, 2);
2785 case IQ2000_BUILTIN_MTC2:
2786 code[1] = CONST_INT;
2787 return expand_one_builtin (CODE_FOR_mtc2, target, exp, code, 2);
2789 case IQ2000_BUILTIN_MTC3:
2790 code[1] = CONST_INT;
2791 return expand_one_builtin (CODE_FOR_mtc3, target, exp, code, 2);
2793 case IQ2000_BUILTIN_LUR:
2794 return expand_one_builtin (CODE_FOR_lur, target, exp, code, 2);
2796 case IQ2000_BUILTIN_RB:
2797 return expand_one_builtin (CODE_FOR_rb, target, exp, code, 2);
2799 case IQ2000_BUILTIN_RX:
2800 return expand_one_builtin (CODE_FOR_rx, target, exp, code, 2);
2802 case IQ2000_BUILTIN_SRRD:
2803 return expand_one_builtin (CODE_FOR_srrd, target, exp, code, 1);
2805 case IQ2000_BUILTIN_SRWR:
2806 return expand_one_builtin (CODE_FOR_srwr, target, exp, code, 2);
2808 case IQ2000_BUILTIN_WB:
2809 return expand_one_builtin (CODE_FOR_wb, target, exp, code, 2);
2811 case IQ2000_BUILTIN_WX:
2812 return expand_one_builtin (CODE_FOR_wx, target, exp, code, 2);
2814 case IQ2000_BUILTIN_LUC32L:
2815 return expand_one_builtin (CODE_FOR_luc32l, target, exp, code, 2);
2817 case IQ2000_BUILTIN_LUC64:
2818 return expand_one_builtin (CODE_FOR_luc64, target, exp, code, 2);
2820 case IQ2000_BUILTIN_LUC64L:
2821 return expand_one_builtin (CODE_FOR_luc64l, target, exp, code, 2);
2823 case IQ2000_BUILTIN_LUK:
2824 return expand_one_builtin (CODE_FOR_luk, target, exp, code, 2);
2826 case IQ2000_BUILTIN_LULCK:
2827 return expand_one_builtin (CODE_FOR_lulck, target, exp, code, 1);
2829 case IQ2000_BUILTIN_LUM32:
2830 return expand_one_builtin (CODE_FOR_lum32, target, exp, code, 2);
2832 case IQ2000_BUILTIN_LUM32L:
2833 return expand_one_builtin (CODE_FOR_lum32l, target, exp, code, 2);
2835 case IQ2000_BUILTIN_LUM64:
2836 return expand_one_builtin (CODE_FOR_lum64, target, exp, code, 2);
2838 case IQ2000_BUILTIN_LUM64L:
2839 return expand_one_builtin (CODE_FOR_lum64l, target, exp, code, 2);
2841 case IQ2000_BUILTIN_LURL:
2842 return expand_one_builtin (CODE_FOR_lurl, target, exp, code, 2);
2844 case IQ2000_BUILTIN_MRGB:
2845 code[2] = CONST_INT;
2846 return expand_one_builtin (CODE_FOR_mrgb, target, exp, code, 3);
2848 case IQ2000_BUILTIN_SRRDL:
2849 return expand_one_builtin (CODE_FOR_srrdl, target, exp, code, 1);
2851 case IQ2000_BUILTIN_SRULCK:
2852 return expand_one_builtin (CODE_FOR_srulck, target, exp, code, 1);
2854 case IQ2000_BUILTIN_SRWRU:
2855 return expand_one_builtin (CODE_FOR_srwru, target, exp, code, 2);
2857 case IQ2000_BUILTIN_TRAPQFL:
2858 return expand_one_builtin (CODE_FOR_trapqfl, target, exp, code, 0);
2860 case IQ2000_BUILTIN_TRAPQNE:
2861 return expand_one_builtin (CODE_FOR_trapqne, target, exp, code, 0);
2863 case IQ2000_BUILTIN_TRAPREL:
2864 return expand_one_builtin (CODE_FOR_traprel, target, exp, code, 1);
2866 case IQ2000_BUILTIN_WBU:
2867 return expand_one_builtin (CODE_FOR_wbu, target, exp, code, 3);
2869 case IQ2000_BUILTIN_SYSCALL:
2870 return expand_one_builtin (CODE_FOR_syscall, target, exp, code, 0);
2873 return NULL_RTX;
2876 /* Worker function for TARGET_RETURN_IN_MEMORY. */
2878 static bool
2879 iq2000_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED)
2881 return ((int_size_in_bytes (type) > (2 * UNITS_PER_WORD))
2882 || (int_size_in_bytes (type) == -1));
2885 /* Worker function for TARGET_SETUP_INCOMING_VARARGS. */
2887 static void
2888 iq2000_setup_incoming_varargs (CUMULATIVE_ARGS *cum,
2889 enum machine_mode mode ATTRIBUTE_UNUSED,
2890 tree type ATTRIBUTE_UNUSED, int * pretend_size,
2891 int no_rtl)
2893 unsigned int iq2000_off = ! cum->last_arg_fp;
2894 unsigned int iq2000_fp_off = cum->last_arg_fp;
2896 if ((cum->arg_words < MAX_ARGS_IN_REGISTERS - iq2000_off))
2898 int iq2000_save_gp_regs
2899 = MAX_ARGS_IN_REGISTERS - cum->arg_words - iq2000_off;
2900 int iq2000_save_fp_regs
2901 = (MAX_ARGS_IN_REGISTERS - cum->fp_arg_words - iq2000_fp_off);
2903 if (iq2000_save_gp_regs < 0)
2904 iq2000_save_gp_regs = 0;
2905 if (iq2000_save_fp_regs < 0)
2906 iq2000_save_fp_regs = 0;
2908 *pretend_size = ((iq2000_save_gp_regs * UNITS_PER_WORD)
2909 + (iq2000_save_fp_regs * UNITS_PER_FPREG));
2911 if (! (no_rtl))
2913 if (cum->arg_words < MAX_ARGS_IN_REGISTERS - iq2000_off)
2915 rtx ptr, mem;
2916 ptr = plus_constant (virtual_incoming_args_rtx,
2917 - (iq2000_save_gp_regs
2918 * UNITS_PER_WORD));
2919 mem = gen_rtx_MEM (BLKmode, ptr);
2920 move_block_from_reg
2921 (cum->arg_words + GP_ARG_FIRST + iq2000_off,
2922 mem,
2923 iq2000_save_gp_regs);
2929 /* A C compound statement to output to stdio stream STREAM the
2930 assembler syntax for an instruction operand that is a memory
2931 reference whose address is ADDR. ADDR is an RTL expression. */
2933 static void
2934 iq2000_print_operand_address (FILE * file, rtx addr)
2936 if (!addr)
2937 error ("PRINT_OPERAND_ADDRESS, null pointer");
2939 else
2940 switch (GET_CODE (addr))
2942 case REG:
2943 if (REGNO (addr) == ARG_POINTER_REGNUM)
2944 abort_with_insn (addr, "Arg pointer not eliminated.");
2946 fprintf (file, "0(%s)", reg_names [REGNO (addr)]);
2947 break;
2949 case LO_SUM:
2951 rtx arg0 = XEXP (addr, 0);
2952 rtx arg1 = XEXP (addr, 1);
2954 if (GET_CODE (arg0) != REG)
2955 abort_with_insn (addr,
2956 "PRINT_OPERAND_ADDRESS, LO_SUM with #1 not REG.");
2958 fprintf (file, "%%lo(");
2959 iq2000_print_operand_address (file, arg1);
2960 fprintf (file, ")(%s)", reg_names [REGNO (arg0)]);
2962 break;
2964 case PLUS:
2966 rtx reg = 0;
2967 rtx offset = 0;
2968 rtx arg0 = XEXP (addr, 0);
2969 rtx arg1 = XEXP (addr, 1);
2971 if (GET_CODE (arg0) == REG)
2973 reg = arg0;
2974 offset = arg1;
2975 if (GET_CODE (offset) == REG)
2976 abort_with_insn (addr, "PRINT_OPERAND_ADDRESS, 2 regs");
2979 else if (GET_CODE (arg1) == REG)
2980 reg = arg1, offset = arg0;
2981 else if (CONSTANT_P (arg0) && CONSTANT_P (arg1))
2983 output_addr_const (file, addr);
2984 break;
2986 else
2987 abort_with_insn (addr, "PRINT_OPERAND_ADDRESS, no regs");
2989 if (! CONSTANT_P (offset))
2990 abort_with_insn (addr, "PRINT_OPERAND_ADDRESS, invalid insn #2");
2992 if (REGNO (reg) == ARG_POINTER_REGNUM)
2993 abort_with_insn (addr, "Arg pointer not eliminated.");
2995 output_addr_const (file, offset);
2996 fprintf (file, "(%s)", reg_names [REGNO (reg)]);
2998 break;
3000 case LABEL_REF:
3001 case SYMBOL_REF:
3002 case CONST_INT:
3003 case CONST:
3004 output_addr_const (file, addr);
3005 if (GET_CODE (addr) == CONST_INT)
3006 fprintf (file, "(%s)", reg_names [0]);
3007 break;
3009 default:
3010 abort_with_insn (addr, "PRINT_OPERAND_ADDRESS, invalid insn #1");
3011 break;
3015 /* A C compound statement to output to stdio stream FILE the
3016 assembler syntax for an instruction operand OP.
3018 LETTER is a value that can be used to specify one of several ways
3019 of printing the operand. It is used when identical operands
3020 must be printed differently depending on the context. LETTER
3021 comes from the `%' specification that was used to request
3022 printing of the operand. If the specification was just `%DIGIT'
3023 then LETTER is 0; if the specification was `%LTR DIGIT' then LETTER
3024 is the ASCII code for LTR.
3026 If OP is a register, this macro should print the register's name.
3027 The names can be found in an array `reg_names' whose type is
3028 `char *[]'. `reg_names' is initialized from `REGISTER_NAMES'.
3030 When the machine description has a specification `%PUNCT' (a `%'
3031 followed by a punctuation character), this macro is called with
3032 a null pointer for X and the punctuation character for LETTER.
3034 The IQ2000 specific codes are:
3036 'X' X is CONST_INT, prints upper 16 bits in hexadecimal format = "0x%04x",
3037 'x' X is CONST_INT, prints lower 16 bits in hexadecimal format = "0x%04x",
3038 'd' output integer constant in decimal,
3039 'z' if the operand is 0, use $0 instead of normal operand.
3040 'D' print second part of double-word register or memory operand.
3041 'L' print low-order register of double-word register operand.
3042 'M' print high-order register of double-word register operand.
3043 'C' print part of opcode for a branch condition.
3044 'F' print part of opcode for a floating-point branch condition.
3045 'N' print part of opcode for a branch condition, inverted.
3046 'W' print part of opcode for a floating-point branch condition, inverted.
3047 'A' Print part of opcode for a bit test condition.
3048 'P' Print label for a bit test.
3049 'p' Print log for a bit test.
3050 'B' print 'z' for EQ, 'n' for NE
3051 'b' print 'n' for EQ, 'z' for NE
3052 'T' print 'f' for EQ, 't' for NE
3053 't' print 't' for EQ, 'f' for NE
3054 'Z' print register and a comma, but print nothing for $fcc0
3055 '?' Print 'l' if we are to use a branch likely instead of normal branch.
3056 '@' Print the name of the assembler temporary register (at or $1).
3057 '.' Print the name of the register with a hard-wired zero (zero or $0).
3058 '$' Print the name of the stack pointer register (sp or $29).
3059 '+' Print the name of the gp register (gp or $28). */
3061 static void
3062 iq2000_print_operand (FILE *file, rtx op, int letter)
3064 enum rtx_code code;
3066 if (iq2000_print_operand_punct_valid_p (letter))
3068 switch (letter)
3070 case '?':
3071 if (iq2000_branch_likely)
3072 putc ('l', file);
3073 break;
3075 case '@':
3076 fputs (reg_names [GP_REG_FIRST + 1], file);
3077 break;
3079 case '.':
3080 fputs (reg_names [GP_REG_FIRST + 0], file);
3081 break;
3083 case '$':
3084 fputs (reg_names[STACK_POINTER_REGNUM], file);
3085 break;
3087 case '+':
3088 fputs (reg_names[GP_REG_FIRST + 28], file);
3089 break;
3091 default:
3092 error ("PRINT_OPERAND: Unknown punctuation '%c'", letter);
3093 break;
3096 return;
3099 if (! op)
3101 error ("PRINT_OPERAND null pointer");
3102 return;
3105 code = GET_CODE (op);
3107 if (code == SIGN_EXTEND)
3108 op = XEXP (op, 0), code = GET_CODE (op);
3110 if (letter == 'C')
3111 switch (code)
3113 case EQ: fputs ("eq", file); break;
3114 case NE: fputs ("ne", file); break;
3115 case GT: fputs ("gt", file); break;
3116 case GE: fputs ("ge", file); break;
3117 case LT: fputs ("lt", file); break;
3118 case LE: fputs ("le", file); break;
3119 case GTU: fputs ("ne", file); break;
3120 case GEU: fputs ("geu", file); break;
3121 case LTU: fputs ("ltu", file); break;
3122 case LEU: fputs ("eq", file); break;
3123 default:
3124 abort_with_insn (op, "PRINT_OPERAND, invalid insn for %%C");
3127 else if (letter == 'N')
3128 switch (code)
3130 case EQ: fputs ("ne", file); break;
3131 case NE: fputs ("eq", file); break;
3132 case GT: fputs ("le", file); break;
3133 case GE: fputs ("lt", file); break;
3134 case LT: fputs ("ge", file); break;
3135 case LE: fputs ("gt", file); break;
3136 case GTU: fputs ("leu", file); break;
3137 case GEU: fputs ("ltu", file); break;
3138 case LTU: fputs ("geu", file); break;
3139 case LEU: fputs ("gtu", file); break;
3140 default:
3141 abort_with_insn (op, "PRINT_OPERAND, invalid insn for %%N");
3144 else if (letter == 'F')
3145 switch (code)
3147 case EQ: fputs ("c1f", file); break;
3148 case NE: fputs ("c1t", file); break;
3149 default:
3150 abort_with_insn (op, "PRINT_OPERAND, invalid insn for %%F");
3153 else if (letter == 'W')
3154 switch (code)
3156 case EQ: fputs ("c1t", file); break;
3157 case NE: fputs ("c1f", file); break;
3158 default:
3159 abort_with_insn (op, "PRINT_OPERAND, invalid insn for %%W");
3162 else if (letter == 'A')
3163 fputs (code == LABEL_REF ? "i" : "in", file);
3165 else if (letter == 'P')
3167 if (code == LABEL_REF)
3168 output_addr_const (file, op);
3169 else if (code != PC)
3170 output_operand_lossage ("invalid %%P operand");
3173 else if (letter == 'p')
3175 int value;
3176 if (code != CONST_INT
3177 || (value = exact_log2 (INTVAL (op))) < 0)
3178 output_operand_lossage ("invalid %%p value");
3179 fprintf (file, "%d", value);
3182 else if (letter == 'Z')
3184 gcc_unreachable ();
3187 else if (code == REG || code == SUBREG)
3189 int regnum;
3191 if (code == REG)
3192 regnum = REGNO (op);
3193 else
3194 regnum = true_regnum (op);
3196 if ((letter == 'M' && ! WORDS_BIG_ENDIAN)
3197 || (letter == 'L' && WORDS_BIG_ENDIAN)
3198 || letter == 'D')
3199 regnum++;
3201 fprintf (file, "%s", reg_names[regnum]);
3204 else if (code == MEM)
3206 if (letter == 'D')
3207 output_address (plus_constant (XEXP (op, 0), 4));
3208 else
3209 output_address (XEXP (op, 0));
3212 else if (code == CONST_DOUBLE
3213 && GET_MODE_CLASS (GET_MODE (op)) == MODE_FLOAT)
3215 char s[60];
3217 real_to_decimal (s, CONST_DOUBLE_REAL_VALUE (op), sizeof (s), 0, 1);
3218 fputs (s, file);
3221 else if (letter == 'x' && GET_CODE (op) == CONST_INT)
3222 fprintf (file, HOST_WIDE_INT_PRINT_HEX, 0xffff & INTVAL(op));
3224 else if (letter == 'X' && GET_CODE(op) == CONST_INT)
3225 fprintf (file, HOST_WIDE_INT_PRINT_HEX, 0xffff & (INTVAL (op) >> 16));
3227 else if (letter == 'd' && GET_CODE(op) == CONST_INT)
3228 fprintf (file, HOST_WIDE_INT_PRINT_DEC, (INTVAL(op)));
3230 else if (letter == 'z' && GET_CODE (op) == CONST_INT && INTVAL (op) == 0)
3231 fputs (reg_names[GP_REG_FIRST], file);
3233 else if (letter == 'd' || letter == 'x' || letter == 'X')
3234 output_operand_lossage ("invalid use of %%d, %%x, or %%X");
3236 else if (letter == 'B')
3237 fputs (code == EQ ? "z" : "n", file);
3238 else if (letter == 'b')
3239 fputs (code == EQ ? "n" : "z", file);
3240 else if (letter == 'T')
3241 fputs (code == EQ ? "f" : "t", file);
3242 else if (letter == 't')
3243 fputs (code == EQ ? "t" : "f", file);
3245 else if (code == CONST && GET_CODE (XEXP (op, 0)) == REG)
3247 iq2000_print_operand (file, XEXP (op, 0), letter);
3250 else
3251 output_addr_const (file, op);
3254 static bool
3255 iq2000_print_operand_punct_valid_p (unsigned char code)
3257 return iq2000_print_operand_punct[code];
3260 /* For the IQ2000, transform:
3262 memory(X + <large int>)
3263 into:
3264 Y = <large int> & ~0x7fff;
3265 Z = X + Y
3266 memory (Z + (<large int> & 0x7fff));
3270 iq2000_legitimize_address (rtx xinsn, rtx old_x ATTRIBUTE_UNUSED,
3271 enum machine_mode mode)
3273 if (TARGET_DEBUG_B_MODE)
3275 GO_PRINTF ("\n========== LEGITIMIZE_ADDRESS\n");
3276 GO_DEBUG_RTX (xinsn);
3279 if (iq2000_check_split (xinsn, mode))
3281 return gen_rtx_LO_SUM (Pmode,
3282 copy_to_mode_reg (Pmode,
3283 gen_rtx_HIGH (Pmode, xinsn)),
3284 xinsn);
3287 if (GET_CODE (xinsn) == PLUS)
3289 rtx xplus0 = XEXP (xinsn, 0);
3290 rtx xplus1 = XEXP (xinsn, 1);
3291 enum rtx_code code0 = GET_CODE (xplus0);
3292 enum rtx_code code1 = GET_CODE (xplus1);
3294 if (code0 != REG && code1 == REG)
3296 xplus0 = XEXP (xinsn, 1);
3297 xplus1 = XEXP (xinsn, 0);
3298 code0 = GET_CODE (xplus0);
3299 code1 = GET_CODE (xplus1);
3302 if (code0 == REG && REG_MODE_OK_FOR_BASE_P (xplus0, mode)
3303 && code1 == CONST_INT && !SMALL_INT (xplus1))
3305 rtx int_reg = gen_reg_rtx (Pmode);
3306 rtx ptr_reg = gen_reg_rtx (Pmode);
3308 emit_move_insn (int_reg,
3309 GEN_INT (INTVAL (xplus1) & ~ 0x7fff));
3311 emit_insn (gen_rtx_SET (VOIDmode,
3312 ptr_reg,
3313 gen_rtx_PLUS (Pmode, xplus0, int_reg)));
3315 return plus_constant (ptr_reg, INTVAL (xplus1) & 0x7fff);
3319 if (TARGET_DEBUG_B_MODE)
3320 GO_PRINTF ("LEGITIMIZE_ADDRESS could not fix.\n");
3322 return xinsn;
3326 static bool
3327 iq2000_rtx_costs (rtx x, int code, int outer_code ATTRIBUTE_UNUSED, int * total,
3328 bool speed ATTRIBUTE_UNUSED)
3330 enum machine_mode mode = GET_MODE (x);
3332 switch (code)
3334 case MEM:
3336 int num_words = (GET_MODE_SIZE (mode) > UNITS_PER_WORD) ? 2 : 1;
3338 if (simple_memory_operand (x, mode))
3339 return COSTS_N_INSNS (num_words);
3341 * total = COSTS_N_INSNS (2 * num_words);
3342 break;
3345 case FFS:
3346 * total = COSTS_N_INSNS (6);
3347 break;
3349 case AND:
3350 case IOR:
3351 case XOR:
3352 case NOT:
3353 * total = COSTS_N_INSNS (mode == DImode ? 2 : 1);
3354 break;
3356 case ASHIFT:
3357 case ASHIFTRT:
3358 case LSHIFTRT:
3359 if (mode == DImode)
3360 * total = COSTS_N_INSNS ((GET_CODE (XEXP (x, 1)) == CONST_INT) ? 4 : 12);
3361 else
3362 * total = COSTS_N_INSNS (1);
3363 break;
3365 case ABS:
3366 if (mode == SFmode || mode == DFmode)
3367 * total = COSTS_N_INSNS (1);
3368 else
3369 * total = COSTS_N_INSNS (4);
3370 break;
3372 case PLUS:
3373 case MINUS:
3374 if (mode == SFmode || mode == DFmode)
3375 * total = COSTS_N_INSNS (6);
3376 else if (mode == DImode)
3377 * total = COSTS_N_INSNS (4);
3378 else
3379 * total = COSTS_N_INSNS (1);
3380 break;
3382 case NEG:
3383 * total = (mode == DImode) ? 4 : 1;
3384 break;
3386 case MULT:
3387 if (mode == SFmode)
3388 * total = COSTS_N_INSNS (7);
3389 else if (mode == DFmode)
3390 * total = COSTS_N_INSNS (8);
3391 else
3392 * total = COSTS_N_INSNS (10);
3393 break;
3395 case DIV:
3396 case MOD:
3397 if (mode == SFmode)
3398 * total = COSTS_N_INSNS (23);
3399 else if (mode == DFmode)
3400 * total = COSTS_N_INSNS (36);
3401 else
3402 * total = COSTS_N_INSNS (69);
3403 break;
3405 case UDIV:
3406 case UMOD:
3407 * total = COSTS_N_INSNS (69);
3408 break;
3410 case SIGN_EXTEND:
3411 * total = COSTS_N_INSNS (2);
3412 break;
3414 case ZERO_EXTEND:
3415 * total = COSTS_N_INSNS (1);
3416 break;
3418 case CONST_INT:
3419 * total = 0;
3420 break;
3422 case LABEL_REF:
3423 * total = COSTS_N_INSNS (2);
3424 break;
3426 case CONST:
3428 rtx offset = const0_rtx;
3429 rtx symref = eliminate_constant_term (XEXP (x, 0), & offset);
3431 if (GET_CODE (symref) == LABEL_REF)
3432 * total = COSTS_N_INSNS (2);
3433 else if (GET_CODE (symref) != SYMBOL_REF)
3434 * total = COSTS_N_INSNS (4);
3435 /* Let's be paranoid.... */
3436 else if (INTVAL (offset) < -32768 || INTVAL (offset) > 32767)
3437 * total = COSTS_N_INSNS (2);
3438 else
3439 * total = COSTS_N_INSNS (SYMBOL_REF_FLAG (symref) ? 1 : 2);
3440 break;
3443 case SYMBOL_REF:
3444 * total = COSTS_N_INSNS (SYMBOL_REF_FLAG (x) ? 1 : 2);
3445 break;
3447 case CONST_DOUBLE:
3449 rtx high, low;
3451 split_double (x, & high, & low);
3453 * total = COSTS_N_INSNS ( (high == CONST0_RTX (GET_MODE (high))
3454 || low == CONST0_RTX (GET_MODE (low)))
3455 ? 2 : 4);
3456 break;
3459 default:
3460 return false;
3462 return true;
3465 /* Worker for TARGET_ASM_TRAMPOLINE_TEMPLATE. */
3467 static void
3468 iq2000_asm_trampoline_template (FILE *f)
3470 fprintf (f, "\t.word\t0x03e00821\t\t# move $1,$31\n");
3471 fprintf (f, "\t.word\t0x04110001\t\t# bgezal $0,.+8\n");
3472 fprintf (f, "\t.word\t0x00000000\t\t# nop\n");
3473 if (Pmode == DImode)
3475 fprintf (f, "\t.word\t0xdfe30014\t\t# ld $3,20($31)\n");
3476 fprintf (f, "\t.word\t0xdfe2001c\t\t# ld $2,28($31)\n");
3478 else
3480 fprintf (f, "\t.word\t0x8fe30014\t\t# lw $3,20($31)\n");
3481 fprintf (f, "\t.word\t0x8fe20018\t\t# lw $2,24($31)\n");
3483 fprintf (f, "\t.word\t0x0060c821\t\t# move $25,$3 (abicalls)\n");
3484 fprintf (f, "\t.word\t0x00600008\t\t# jr $3\n");
3485 fprintf (f, "\t.word\t0x0020f821\t\t# move $31,$1\n");
3486 fprintf (f, "\t.word\t0x00000000\t\t# <function address>\n");
3487 fprintf (f, "\t.word\t0x00000000\t\t# <static chain value>\n");
3490 /* Worker for TARGET_TRAMPOLINE_INIT. */
3492 static void
3493 iq2000_trampoline_init (rtx m_tramp, tree fndecl, rtx chain_value)
3495 rtx fnaddr = XEXP (DECL_RTL (fndecl), 0);
3496 rtx mem;
3498 emit_block_move (m_tramp, assemble_trampoline_template (),
3499 GEN_INT (TRAMPOLINE_CODE_SIZE), BLOCK_OP_NORMAL);
3501 mem = adjust_address (m_tramp, Pmode, TRAMPOLINE_CODE_SIZE);
3502 emit_move_insn (mem, fnaddr);
3503 mem = adjust_address (m_tramp, Pmode,
3504 TRAMPOLINE_CODE_SIZE + GET_MODE_SIZE (Pmode));
3505 emit_move_insn (mem, chain_value);
3508 #include "gt-iq2000.h"