]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/config/iq2000/iq2000.c
hooks.c (hook_int_rtx_mode_as_bool_0): New function.
[thirdparty/gcc.git] / gcc / config / iq2000 / iq2000.c
1 /* Subroutines used for code generation on Vitesse IQ2000 processors
2 Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011
3 Free Software Foundation, Inc.
4
5 This file is part of GCC.
6
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.
11
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.
16
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/>. */
20
21 #include "config.h"
22 #include "system.h"
23 #include "coretypes.h"
24 #include "tm.h"
25 #include "tree.h"
26 #include "rtl.h"
27 #include "regs.h"
28 #include "hard-reg-set.h"
29 #include "insn-config.h"
30 #include "conditions.h"
31 #include "output.h"
32 #include "insn-attr.h"
33 #include "flags.h"
34 #include "function.h"
35 #include "expr.h"
36 #include "optabs.h"
37 #include "libfuncs.h"
38 #include "recog.h"
39 #include "diagnostic-core.h"
40 #include "reload.h"
41 #include "ggc.h"
42 #include "tm_p.h"
43 #include "debug.h"
44 #include "target.h"
45 #include "target-def.h"
46 #include "langhooks.h"
47 #include "df.h"
48
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. */
52
53 enum internal_test
54 {
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
66 };
67
68 struct constant;
69
70 \f
71 /* Structure to be filled in by compute_frame_size with register
72 save masks, and offsets for the current function. */
73
74 struct iq2000_frame_info
75 {
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;
90
91 struct GTY(()) machine_function
92 {
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. */
107 };
108
109 /* Global variables for machine-dependent things. */
110
111 /* List of all IQ2000 punctuation characters used by iq2000_print_operand. */
112 static char iq2000_print_operand_punct[256];
113
114 /* Which instruction set architecture to use. */
115 int iq2000_isa;
116
117 /* Local variables. */
118
119 /* The next branch instruction is a branch likely, not branch normal. */
120 static int iq2000_branch_likely;
121
122 /* Count of delay slots and how many are filled. */
123 static int dslots_load_total;
124 static int dslots_load_filled;
125 static int dslots_jump_total;
126
127 /* # of nops needed by previous insn. */
128 static int dslots_number_nops;
129
130 /* Number of 1/2/3 word references to data items (i.e., not jal's). */
131 static int num_refs[3];
132
133 /* Registers to check for load delay. */
134 static rtx iq2000_load_reg;
135 static rtx iq2000_load_reg2;
136 static rtx iq2000_load_reg3;
137 static rtx iq2000_load_reg4;
138
139 /* Mode used for saving/restoring general purpose registers. */
140 static enum machine_mode gpr_mode;
141
142 \f
143 /* Initialize the GCC target structure. */
144 static struct machine_function* iq2000_init_machine_status (void);
145 static void iq2000_option_override (void);
146 static section *iq2000_select_rtx_section (enum machine_mode, rtx,
147 unsigned HOST_WIDE_INT);
148 static void iq2000_init_builtins (void);
149 static rtx iq2000_expand_builtin (tree, rtx, rtx, enum machine_mode, int);
150 static bool iq2000_return_in_memory (const_tree, const_tree);
151 static void iq2000_setup_incoming_varargs (cumulative_args_t,
152 enum machine_mode, tree, int *,
153 int);
154 static bool iq2000_rtx_costs (rtx, int, int, int, int *, bool);
155 static int iq2000_address_cost (rtx, enum machine_mode, addr_space_t,
156 bool);
157 static section *iq2000_select_section (tree, int, unsigned HOST_WIDE_INT);
158 static rtx iq2000_legitimize_address (rtx, rtx, enum machine_mode);
159 static bool iq2000_pass_by_reference (cumulative_args_t, enum machine_mode,
160 const_tree, bool);
161 static int iq2000_arg_partial_bytes (cumulative_args_t, enum machine_mode,
162 tree, bool);
163 static rtx iq2000_function_arg (cumulative_args_t,
164 enum machine_mode, const_tree, bool);
165 static void iq2000_function_arg_advance (cumulative_args_t,
166 enum machine_mode, const_tree, bool);
167 static unsigned int iq2000_function_arg_boundary (enum machine_mode,
168 const_tree);
169 static void iq2000_va_start (tree, rtx);
170 static bool iq2000_legitimate_address_p (enum machine_mode, rtx, bool);
171 static bool iq2000_can_eliminate (const int, const int);
172 static void iq2000_asm_trampoline_template (FILE *);
173 static void iq2000_trampoline_init (rtx, tree, rtx);
174 static rtx iq2000_function_value (const_tree, const_tree, bool);
175 static rtx iq2000_libcall_value (enum machine_mode, const_rtx);
176 static void iq2000_print_operand (FILE *, rtx, int);
177 static void iq2000_print_operand_address (FILE *, rtx);
178 static bool iq2000_print_operand_punct_valid_p (unsigned char code);
179
180 #undef TARGET_INIT_BUILTINS
181 #define TARGET_INIT_BUILTINS iq2000_init_builtins
182 #undef TARGET_EXPAND_BUILTIN
183 #define TARGET_EXPAND_BUILTIN iq2000_expand_builtin
184 #undef TARGET_ASM_SELECT_RTX_SECTION
185 #define TARGET_ASM_SELECT_RTX_SECTION iq2000_select_rtx_section
186 #undef TARGET_OPTION_OVERRIDE
187 #define TARGET_OPTION_OVERRIDE iq2000_option_override
188 #undef TARGET_RTX_COSTS
189 #define TARGET_RTX_COSTS iq2000_rtx_costs
190 #undef TARGET_ADDRESS_COST
191 #define TARGET_ADDRESS_COST iq2000_address_cost
192 #undef TARGET_ASM_SELECT_SECTION
193 #define TARGET_ASM_SELECT_SECTION iq2000_select_section
194
195 #undef TARGET_LEGITIMIZE_ADDRESS
196 #define TARGET_LEGITIMIZE_ADDRESS iq2000_legitimize_address
197
198 /* The assembler supports switchable .bss sections, but
199 iq2000_select_section doesn't yet make use of them. */
200 #undef TARGET_HAVE_SWITCHABLE_BSS_SECTIONS
201 #define TARGET_HAVE_SWITCHABLE_BSS_SECTIONS false
202
203 #undef TARGET_PRINT_OPERAND
204 #define TARGET_PRINT_OPERAND iq2000_print_operand
205 #undef TARGET_PRINT_OPERAND_ADDRESS
206 #define TARGET_PRINT_OPERAND_ADDRESS iq2000_print_operand_address
207 #undef TARGET_PRINT_OPERAND_PUNCT_VALID_P
208 #define TARGET_PRINT_OPERAND_PUNCT_VALID_P iq2000_print_operand_punct_valid_p
209
210 #undef TARGET_PROMOTE_FUNCTION_MODE
211 #define TARGET_PROMOTE_FUNCTION_MODE default_promote_function_mode_always_promote
212 #undef TARGET_PROMOTE_PROTOTYPES
213 #define TARGET_PROMOTE_PROTOTYPES hook_bool_const_tree_true
214
215 #undef TARGET_FUNCTION_VALUE
216 #define TARGET_FUNCTION_VALUE iq2000_function_value
217 #undef TARGET_LIBCALL_VALUE
218 #define TARGET_LIBCALL_VALUE iq2000_libcall_value
219 #undef TARGET_RETURN_IN_MEMORY
220 #define TARGET_RETURN_IN_MEMORY iq2000_return_in_memory
221 #undef TARGET_PASS_BY_REFERENCE
222 #define TARGET_PASS_BY_REFERENCE iq2000_pass_by_reference
223 #undef TARGET_CALLEE_COPIES
224 #define TARGET_CALLEE_COPIES hook_callee_copies_named
225 #undef TARGET_ARG_PARTIAL_BYTES
226 #define TARGET_ARG_PARTIAL_BYTES iq2000_arg_partial_bytes
227 #undef TARGET_FUNCTION_ARG
228 #define TARGET_FUNCTION_ARG iq2000_function_arg
229 #undef TARGET_FUNCTION_ARG_ADVANCE
230 #define TARGET_FUNCTION_ARG_ADVANCE iq2000_function_arg_advance
231 #undef TARGET_FUNCTION_ARG_BOUNDARY
232 #define TARGET_FUNCTION_ARG_BOUNDARY iq2000_function_arg_boundary
233
234 #undef TARGET_SETUP_INCOMING_VARARGS
235 #define TARGET_SETUP_INCOMING_VARARGS iq2000_setup_incoming_varargs
236 #undef TARGET_STRICT_ARGUMENT_NAMING
237 #define TARGET_STRICT_ARGUMENT_NAMING hook_bool_CUMULATIVE_ARGS_true
238
239 #undef TARGET_EXPAND_BUILTIN_VA_START
240 #define TARGET_EXPAND_BUILTIN_VA_START iq2000_va_start
241
242 #undef TARGET_LEGITIMATE_ADDRESS_P
243 #define TARGET_LEGITIMATE_ADDRESS_P iq2000_legitimate_address_p
244
245 #undef TARGET_CAN_ELIMINATE
246 #define TARGET_CAN_ELIMINATE iq2000_can_eliminate
247
248 #undef TARGET_ASM_TRAMPOLINE_TEMPLATE
249 #define TARGET_ASM_TRAMPOLINE_TEMPLATE iq2000_asm_trampoline_template
250 #undef TARGET_TRAMPOLINE_INIT
251 #define TARGET_TRAMPOLINE_INIT iq2000_trampoline_init
252
253 struct gcc_target targetm = TARGET_INITIALIZER;
254 \f
255 /* Return nonzero if we split the address into high and low parts. */
256
257 int
258 iq2000_check_split (rtx address, enum machine_mode mode)
259 {
260 /* This is the same check used in simple_memory_operand.
261 We use it here because LO_SUM is not offsettable. */
262 if (GET_MODE_SIZE (mode) > (unsigned) UNITS_PER_WORD)
263 return 0;
264
265 if ((GET_CODE (address) == SYMBOL_REF)
266 || (GET_CODE (address) == CONST
267 && GET_CODE (XEXP (XEXP (address, 0), 0)) == SYMBOL_REF)
268 || GET_CODE (address) == LABEL_REF)
269 return 1;
270
271 return 0;
272 }
273
274 /* Return nonzero if REG is valid for MODE. */
275
276 int
277 iq2000_reg_mode_ok_for_base_p (rtx reg,
278 enum machine_mode mode ATTRIBUTE_UNUSED,
279 int strict)
280 {
281 return (strict
282 ? REGNO_MODE_OK_FOR_BASE_P (REGNO (reg), mode)
283 : GP_REG_OR_PSEUDO_NONSTRICT_P (REGNO (reg), mode));
284 }
285
286 /* Return a nonzero value if XINSN is a legitimate address for a
287 memory operand of the indicated MODE. STRICT is nonzero if this
288 function is called during reload. */
289
290 bool
291 iq2000_legitimate_address_p (enum machine_mode mode, rtx xinsn, bool strict)
292 {
293 if (TARGET_DEBUG_A_MODE)
294 {
295 GO_PRINTF2 ("\n========== legitimate_address_p, %sstrict\n",
296 strict ? "" : "not ");
297 GO_DEBUG_RTX (xinsn);
298 }
299
300 /* Check for constant before stripping off SUBREG, so that we don't
301 accept (subreg (const_int)) which will fail to reload. */
302 if (CONSTANT_ADDRESS_P (xinsn)
303 && ! (iq2000_check_split (xinsn, mode))
304 && ! (GET_CODE (xinsn) == CONST_INT && ! SMALL_INT (xinsn)))
305 return 1;
306
307 while (GET_CODE (xinsn) == SUBREG)
308 xinsn = SUBREG_REG (xinsn);
309
310 if (GET_CODE (xinsn) == REG
311 && iq2000_reg_mode_ok_for_base_p (xinsn, mode, strict))
312 return 1;
313
314 if (GET_CODE (xinsn) == LO_SUM)
315 {
316 rtx xlow0 = XEXP (xinsn, 0);
317 rtx xlow1 = XEXP (xinsn, 1);
318
319 while (GET_CODE (xlow0) == SUBREG)
320 xlow0 = SUBREG_REG (xlow0);
321 if (GET_CODE (xlow0) == REG
322 && iq2000_reg_mode_ok_for_base_p (xlow0, mode, strict)
323 && iq2000_check_split (xlow1, mode))
324 return 1;
325 }
326
327 if (GET_CODE (xinsn) == PLUS)
328 {
329 rtx xplus0 = XEXP (xinsn, 0);
330 rtx xplus1 = XEXP (xinsn, 1);
331 enum rtx_code code0;
332 enum rtx_code code1;
333
334 while (GET_CODE (xplus0) == SUBREG)
335 xplus0 = SUBREG_REG (xplus0);
336 code0 = GET_CODE (xplus0);
337
338 while (GET_CODE (xplus1) == SUBREG)
339 xplus1 = SUBREG_REG (xplus1);
340 code1 = GET_CODE (xplus1);
341
342 if (code0 == REG
343 && iq2000_reg_mode_ok_for_base_p (xplus0, mode, strict))
344 {
345 if (code1 == CONST_INT && SMALL_INT (xplus1)
346 && SMALL_INT_UNSIGNED (xplus1) /* No negative offsets */)
347 return 1;
348 }
349 }
350
351 if (TARGET_DEBUG_A_MODE)
352 GO_PRINTF ("Not a enum machine_mode mode, legitimate address\n");
353
354 /* The address was not legitimate. */
355 return 0;
356 }
357 \f
358 /* Returns an operand string for the given instruction's delay slot,
359 after updating filled delay slot statistics.
360
361 We assume that operands[0] is the target register that is set.
362
363 In order to check the next insn, most of this functionality is moved
364 to FINAL_PRESCAN_INSN, and we just set the global variables that
365 it needs. */
366
367 const char *
368 iq2000_fill_delay_slot (const char *ret, enum delay_type type, rtx operands[],
369 rtx cur_insn)
370 {
371 rtx set_reg;
372 enum machine_mode mode;
373 rtx next_insn = cur_insn ? NEXT_INSN (cur_insn) : NULL_RTX;
374 int num_nops;
375
376 if (type == DELAY_LOAD || type == DELAY_FCMP)
377 num_nops = 1;
378
379 else
380 num_nops = 0;
381
382 /* Make sure that we don't put nop's after labels. */
383 next_insn = NEXT_INSN (cur_insn);
384 while (next_insn != 0
385 && (GET_CODE (next_insn) == NOTE
386 || GET_CODE (next_insn) == CODE_LABEL))
387 next_insn = NEXT_INSN (next_insn);
388
389 dslots_load_total += num_nops;
390 if (TARGET_DEBUG_C_MODE
391 || type == DELAY_NONE
392 || operands == 0
393 || cur_insn == 0
394 || next_insn == 0
395 || GET_CODE (next_insn) == CODE_LABEL
396 || (set_reg = operands[0]) == 0)
397 {
398 dslots_number_nops = 0;
399 iq2000_load_reg = 0;
400 iq2000_load_reg2 = 0;
401 iq2000_load_reg3 = 0;
402 iq2000_load_reg4 = 0;
403
404 return ret;
405 }
406
407 set_reg = operands[0];
408 if (set_reg == 0)
409 return ret;
410
411 while (GET_CODE (set_reg) == SUBREG)
412 set_reg = SUBREG_REG (set_reg);
413
414 mode = GET_MODE (set_reg);
415 dslots_number_nops = num_nops;
416 iq2000_load_reg = set_reg;
417 if (GET_MODE_SIZE (mode)
418 > (unsigned) (UNITS_PER_WORD))
419 iq2000_load_reg2 = gen_rtx_REG (SImode, REGNO (set_reg) + 1);
420 else
421 iq2000_load_reg2 = 0;
422
423 return ret;
424 }
425 \f
426 /* Determine whether a memory reference takes one (based off of the GP
427 pointer), two (normal), or three (label + reg) instructions, and bump the
428 appropriate counter for -mstats. */
429
430 static void
431 iq2000_count_memory_refs (rtx op, int num)
432 {
433 int additional = 0;
434 int n_words = 0;
435 rtx addr, plus0, plus1;
436 enum rtx_code code0, code1;
437 int looping;
438
439 if (TARGET_DEBUG_B_MODE)
440 {
441 fprintf (stderr, "\n========== iq2000_count_memory_refs:\n");
442 debug_rtx (op);
443 }
444
445 /* Skip MEM if passed, otherwise handle movsi of address. */
446 addr = (GET_CODE (op) != MEM) ? op : XEXP (op, 0);
447
448 /* Loop, going through the address RTL. */
449 do
450 {
451 looping = FALSE;
452 switch (GET_CODE (addr))
453 {
454 case REG:
455 case CONST_INT:
456 case LO_SUM:
457 break;
458
459 case PLUS:
460 plus0 = XEXP (addr, 0);
461 plus1 = XEXP (addr, 1);
462 code0 = GET_CODE (plus0);
463 code1 = GET_CODE (plus1);
464
465 if (code0 == REG)
466 {
467 additional++;
468 addr = plus1;
469 looping = 1;
470 continue;
471 }
472
473 if (code0 == CONST_INT)
474 {
475 addr = plus1;
476 looping = 1;
477 continue;
478 }
479
480 if (code1 == REG)
481 {
482 additional++;
483 addr = plus0;
484 looping = 1;
485 continue;
486 }
487
488 if (code1 == CONST_INT)
489 {
490 addr = plus0;
491 looping = 1;
492 continue;
493 }
494
495 if (code0 == SYMBOL_REF || code0 == LABEL_REF || code0 == CONST)
496 {
497 addr = plus0;
498 looping = 1;
499 continue;
500 }
501
502 if (code1 == SYMBOL_REF || code1 == LABEL_REF || code1 == CONST)
503 {
504 addr = plus1;
505 looping = 1;
506 continue;
507 }
508
509 break;
510
511 case LABEL_REF:
512 n_words = 2; /* Always 2 words. */
513 break;
514
515 case CONST:
516 addr = XEXP (addr, 0);
517 looping = 1;
518 continue;
519
520 case SYMBOL_REF:
521 n_words = SYMBOL_REF_FLAG (addr) ? 1 : 2;
522 break;
523
524 default:
525 break;
526 }
527 }
528 while (looping);
529
530 if (n_words == 0)
531 return;
532
533 n_words += additional;
534 if (n_words > 3)
535 n_words = 3;
536
537 num_refs[n_words-1] += num;
538 }
539 \f
540 /* Abort after printing out a specific insn. */
541
542 static void
543 abort_with_insn (rtx insn, const char * reason)
544 {
545 error (reason);
546 debug_rtx (insn);
547 fancy_abort (__FILE__, __LINE__, __FUNCTION__);
548 }
549 \f
550 /* Return the appropriate instructions to move one operand to another. */
551
552 const char *
553 iq2000_move_1word (rtx operands[], rtx insn, int unsignedp)
554 {
555 const char *ret = 0;
556 rtx op0 = operands[0];
557 rtx op1 = operands[1];
558 enum rtx_code code0 = GET_CODE (op0);
559 enum rtx_code code1 = GET_CODE (op1);
560 enum machine_mode mode = GET_MODE (op0);
561 int subreg_offset0 = 0;
562 int subreg_offset1 = 0;
563 enum delay_type delay = DELAY_NONE;
564
565 while (code0 == SUBREG)
566 {
567 subreg_offset0 += subreg_regno_offset (REGNO (SUBREG_REG (op0)),
568 GET_MODE (SUBREG_REG (op0)),
569 SUBREG_BYTE (op0),
570 GET_MODE (op0));
571 op0 = SUBREG_REG (op0);
572 code0 = GET_CODE (op0);
573 }
574
575 while (code1 == SUBREG)
576 {
577 subreg_offset1 += subreg_regno_offset (REGNO (SUBREG_REG (op1)),
578 GET_MODE (SUBREG_REG (op1)),
579 SUBREG_BYTE (op1),
580 GET_MODE (op1));
581 op1 = SUBREG_REG (op1);
582 code1 = GET_CODE (op1);
583 }
584
585 /* For our purposes, a condition code mode is the same as SImode. */
586 if (mode == CCmode)
587 mode = SImode;
588
589 if (code0 == REG)
590 {
591 int regno0 = REGNO (op0) + subreg_offset0;
592
593 if (code1 == REG)
594 {
595 int regno1 = REGNO (op1) + subreg_offset1;
596
597 /* Do not do anything for assigning a register to itself */
598 if (regno0 == regno1)
599 ret = "";
600
601 else if (GP_REG_P (regno0))
602 {
603 if (GP_REG_P (regno1))
604 ret = "or\t%0,%%0,%1";
605 }
606
607 }
608
609 else if (code1 == MEM)
610 {
611 delay = DELAY_LOAD;
612
613 if (TARGET_STATS)
614 iq2000_count_memory_refs (op1, 1);
615
616 if (GP_REG_P (regno0))
617 {
618 /* For loads, use the mode of the memory item, instead of the
619 target, so zero/sign extend can use this code as well. */
620 switch (GET_MODE (op1))
621 {
622 default:
623 break;
624 case SFmode:
625 ret = "lw\t%0,%1";
626 break;
627 case SImode:
628 case CCmode:
629 ret = "lw\t%0,%1";
630 break;
631 case HImode:
632 ret = (unsignedp) ? "lhu\t%0,%1" : "lh\t%0,%1";
633 break;
634 case QImode:
635 ret = (unsignedp) ? "lbu\t%0,%1" : "lb\t%0,%1";
636 break;
637 }
638 }
639 }
640
641 else if (code1 == CONST_INT
642 || (code1 == CONST_DOUBLE
643 && GET_MODE (op1) == VOIDmode))
644 {
645 if (code1 == CONST_DOUBLE)
646 {
647 /* This can happen when storing constants into long long
648 bitfields. Just store the least significant word of
649 the value. */
650 operands[1] = op1 = GEN_INT (CONST_DOUBLE_LOW (op1));
651 }
652
653 if (INTVAL (op1) == 0)
654 {
655 if (GP_REG_P (regno0))
656 ret = "or\t%0,%%0,%z1";
657 }
658 else if (GP_REG_P (regno0))
659 {
660 if (SMALL_INT_UNSIGNED (op1))
661 ret = "ori\t%0,%%0,%x1\t\t\t# %1";
662 else if (SMALL_INT (op1))
663 ret = "addiu\t%0,%%0,%1\t\t\t# %1";
664 else
665 ret = "lui\t%0,%X1\t\t\t# %1\n\tori\t%0,%0,%x1";
666 }
667 }
668
669 else if (code1 == CONST_DOUBLE && mode == SFmode)
670 {
671 if (op1 == CONST0_RTX (SFmode))
672 {
673 if (GP_REG_P (regno0))
674 ret = "or\t%0,%%0,%.";
675 }
676
677 else
678 {
679 delay = DELAY_LOAD;
680 ret = "li.s\t%0,%1";
681 }
682 }
683
684 else if (code1 == LABEL_REF)
685 {
686 if (TARGET_STATS)
687 iq2000_count_memory_refs (op1, 1);
688
689 ret = "la\t%0,%a1";
690 }
691
692 else if (code1 == SYMBOL_REF || code1 == CONST)
693 {
694 if (TARGET_STATS)
695 iq2000_count_memory_refs (op1, 1);
696
697 ret = "la\t%0,%a1";
698 }
699
700 else if (code1 == PLUS)
701 {
702 rtx add_op0 = XEXP (op1, 0);
703 rtx add_op1 = XEXP (op1, 1);
704
705 if (GET_CODE (XEXP (op1, 1)) == REG
706 && GET_CODE (XEXP (op1, 0)) == CONST_INT)
707 add_op0 = XEXP (op1, 1), add_op1 = XEXP (op1, 0);
708
709 operands[2] = add_op0;
710 operands[3] = add_op1;
711 ret = "add%:\t%0,%2,%3";
712 }
713
714 else if (code1 == HIGH)
715 {
716 operands[1] = XEXP (op1, 0);
717 ret = "lui\t%0,%%hi(%1)";
718 }
719 }
720
721 else if (code0 == MEM)
722 {
723 if (TARGET_STATS)
724 iq2000_count_memory_refs (op0, 1);
725
726 if (code1 == REG)
727 {
728 int regno1 = REGNO (op1) + subreg_offset1;
729
730 if (GP_REG_P (regno1))
731 {
732 switch (mode)
733 {
734 case SFmode: ret = "sw\t%1,%0"; break;
735 case SImode: ret = "sw\t%1,%0"; break;
736 case HImode: ret = "sh\t%1,%0"; break;
737 case QImode: ret = "sb\t%1,%0"; break;
738 default: break;
739 }
740 }
741 }
742
743 else if (code1 == CONST_INT && INTVAL (op1) == 0)
744 {
745 switch (mode)
746 {
747 case SFmode: ret = "sw\t%z1,%0"; break;
748 case SImode: ret = "sw\t%z1,%0"; break;
749 case HImode: ret = "sh\t%z1,%0"; break;
750 case QImode: ret = "sb\t%z1,%0"; break;
751 default: break;
752 }
753 }
754
755 else if (code1 == CONST_DOUBLE && op1 == CONST0_RTX (mode))
756 {
757 switch (mode)
758 {
759 case SFmode: ret = "sw\t%.,%0"; break;
760 case SImode: ret = "sw\t%.,%0"; break;
761 case HImode: ret = "sh\t%.,%0"; break;
762 case QImode: ret = "sb\t%.,%0"; break;
763 default: break;
764 }
765 }
766 }
767
768 if (ret == 0)
769 {
770 abort_with_insn (insn, "Bad move");
771 return 0;
772 }
773
774 if (delay != DELAY_NONE)
775 return iq2000_fill_delay_slot (ret, delay, operands, insn);
776
777 return ret;
778 }
779 \f
780 /* Provide the costs of an addressing mode that contains ADDR. */
781
782 static int
783 iq2000_address_cost (rtx addr, enum machine_mode mode, addr_space_t as,
784 bool speed)
785 {
786 switch (GET_CODE (addr))
787 {
788 case LO_SUM:
789 return 1;
790
791 case LABEL_REF:
792 return 2;
793
794 case CONST:
795 {
796 rtx offset = const0_rtx;
797
798 addr = eliminate_constant_term (XEXP (addr, 0), & offset);
799 if (GET_CODE (addr) == LABEL_REF)
800 return 2;
801
802 if (GET_CODE (addr) != SYMBOL_REF)
803 return 4;
804
805 if (! SMALL_INT (offset))
806 return 2;
807 }
808
809 /* Fall through. */
810
811 case SYMBOL_REF:
812 return SYMBOL_REF_FLAG (addr) ? 1 : 2;
813
814 case PLUS:
815 {
816 rtx plus0 = XEXP (addr, 0);
817 rtx plus1 = XEXP (addr, 1);
818
819 if (GET_CODE (plus0) != REG && GET_CODE (plus1) == REG)
820 plus0 = XEXP (addr, 1), plus1 = XEXP (addr, 0);
821
822 if (GET_CODE (plus0) != REG)
823 break;
824
825 switch (GET_CODE (plus1))
826 {
827 case CONST_INT:
828 return SMALL_INT (plus1) ? 1 : 2;
829
830 case CONST:
831 case SYMBOL_REF:
832 case LABEL_REF:
833 case HIGH:
834 case LO_SUM:
835 return iq2000_address_cost (plus1, mode, as, speed) + 1;
836
837 default:
838 break;
839 }
840 }
841
842 default:
843 break;
844 }
845
846 return 4;
847 }
848 \f
849 /* Make normal rtx_code into something we can index from an array. */
850
851 static enum internal_test
852 map_test_to_internal_test (enum rtx_code test_code)
853 {
854 enum internal_test test = ITEST_MAX;
855
856 switch (test_code)
857 {
858 case EQ: test = ITEST_EQ; break;
859 case NE: test = ITEST_NE; break;
860 case GT: test = ITEST_GT; break;
861 case GE: test = ITEST_GE; break;
862 case LT: test = ITEST_LT; break;
863 case LE: test = ITEST_LE; break;
864 case GTU: test = ITEST_GTU; break;
865 case GEU: test = ITEST_GEU; break;
866 case LTU: test = ITEST_LTU; break;
867 case LEU: test = ITEST_LEU; break;
868 default: break;
869 }
870
871 return test;
872 }
873 \f
874 /* Generate the code to do a TEST_CODE comparison on two integer values CMP0
875 and CMP1. P_INVERT is NULL or ptr if branch needs to reverse its test.
876 The return value RESULT is:
877 (reg:SI xx) The pseudo register the comparison is in
878 0 No register, generate a simple branch. */
879
880 rtx
881 gen_int_relational (enum rtx_code test_code, rtx result, rtx cmp0, rtx cmp1,
882 int *p_invert)
883 {
884 struct cmp_info
885 {
886 enum rtx_code test_code; /* Code to use in instruction (LT vs. LTU). */
887 int const_low; /* Low bound of constant we can accept. */
888 int const_high; /* High bound of constant we can accept. */
889 int const_add; /* Constant to add (convert LE -> LT). */
890 int reverse_regs; /* Reverse registers in test. */
891 int invert_const; /* != 0 if invert value if cmp1 is constant. */
892 int invert_reg; /* != 0 if invert value if cmp1 is register. */
893 int unsignedp; /* != 0 for unsigned comparisons. */
894 };
895
896 static struct cmp_info info[ (int)ITEST_MAX ] =
897 {
898 { XOR, 0, 65535, 0, 0, 0, 0, 0 }, /* EQ */
899 { XOR, 0, 65535, 0, 0, 1, 1, 0 }, /* NE */
900 { LT, -32769, 32766, 1, 1, 1, 0, 0 }, /* GT */
901 { LT, -32768, 32767, 0, 0, 1, 1, 0 }, /* GE */
902 { LT, -32768, 32767, 0, 0, 0, 0, 0 }, /* LT */
903 { LT, -32769, 32766, 1, 1, 0, 1, 0 }, /* LE */
904 { LTU, -32769, 32766, 1, 1, 1, 0, 1 }, /* GTU */
905 { LTU, -32768, 32767, 0, 0, 1, 1, 1 }, /* GEU */
906 { LTU, -32768, 32767, 0, 0, 0, 0, 1 }, /* LTU */
907 { LTU, -32769, 32766, 1, 1, 0, 1, 1 }, /* LEU */
908 };
909
910 enum internal_test test;
911 enum machine_mode mode;
912 struct cmp_info *p_info;
913 int branch_p;
914 int eqne_p;
915 int invert;
916 rtx reg;
917 rtx reg2;
918
919 test = map_test_to_internal_test (test_code);
920 gcc_assert (test != ITEST_MAX);
921
922 p_info = &info[(int) test];
923 eqne_p = (p_info->test_code == XOR);
924
925 mode = GET_MODE (cmp0);
926 if (mode == VOIDmode)
927 mode = GET_MODE (cmp1);
928
929 /* Eliminate simple branches. */
930 branch_p = (result == 0);
931 if (branch_p)
932 {
933 if (GET_CODE (cmp0) == REG || GET_CODE (cmp0) == SUBREG)
934 {
935 /* Comparisons against zero are simple branches. */
936 if (GET_CODE (cmp1) == CONST_INT && INTVAL (cmp1) == 0)
937 return 0;
938
939 /* Test for beq/bne. */
940 if (eqne_p)
941 return 0;
942 }
943
944 /* Allocate a pseudo to calculate the value in. */
945 result = gen_reg_rtx (mode);
946 }
947
948 /* Make sure we can handle any constants given to us. */
949 if (GET_CODE (cmp0) == CONST_INT)
950 cmp0 = force_reg (mode, cmp0);
951
952 if (GET_CODE (cmp1) == CONST_INT)
953 {
954 HOST_WIDE_INT value = INTVAL (cmp1);
955
956 if (value < p_info->const_low
957 || value > p_info->const_high)
958 cmp1 = force_reg (mode, cmp1);
959 }
960
961 /* See if we need to invert the result. */
962 invert = (GET_CODE (cmp1) == CONST_INT
963 ? p_info->invert_const : p_info->invert_reg);
964
965 if (p_invert != (int *)0)
966 {
967 *p_invert = invert;
968 invert = 0;
969 }
970
971 /* Comparison to constants, may involve adding 1 to change a LT into LE.
972 Comparison between two registers, may involve switching operands. */
973 if (GET_CODE (cmp1) == CONST_INT)
974 {
975 if (p_info->const_add != 0)
976 {
977 HOST_WIDE_INT new_const = INTVAL (cmp1) + p_info->const_add;
978
979 /* If modification of cmp1 caused overflow,
980 we would get the wrong answer if we follow the usual path;
981 thus, x > 0xffffffffU would turn into x > 0U. */
982 if ((p_info->unsignedp
983 ? (unsigned HOST_WIDE_INT) new_const >
984 (unsigned HOST_WIDE_INT) INTVAL (cmp1)
985 : new_const > INTVAL (cmp1))
986 != (p_info->const_add > 0))
987 {
988 /* This test is always true, but if INVERT is true then
989 the result of the test needs to be inverted so 0 should
990 be returned instead. */
991 emit_move_insn (result, invert ? const0_rtx : const_true_rtx);
992 return result;
993 }
994 else
995 cmp1 = GEN_INT (new_const);
996 }
997 }
998
999 else if (p_info->reverse_regs)
1000 {
1001 rtx temp = cmp0;
1002 cmp0 = cmp1;
1003 cmp1 = temp;
1004 }
1005
1006 if (test == ITEST_NE && GET_CODE (cmp1) == CONST_INT && INTVAL (cmp1) == 0)
1007 reg = cmp0;
1008 else
1009 {
1010 reg = (invert || eqne_p) ? gen_reg_rtx (mode) : result;
1011 convert_move (reg, gen_rtx_fmt_ee (p_info->test_code, mode, cmp0, cmp1), 0);
1012 }
1013
1014 if (test == ITEST_NE)
1015 {
1016 convert_move (result, gen_rtx_GTU (mode, reg, const0_rtx), 0);
1017 if (p_invert != NULL)
1018 *p_invert = 0;
1019 invert = 0;
1020 }
1021
1022 else if (test == ITEST_EQ)
1023 {
1024 reg2 = invert ? gen_reg_rtx (mode) : result;
1025 convert_move (reg2, gen_rtx_LTU (mode, reg, const1_rtx), 0);
1026 reg = reg2;
1027 }
1028
1029 if (invert)
1030 {
1031 rtx one;
1032
1033 one = const1_rtx;
1034 convert_move (result, gen_rtx_XOR (mode, reg, one), 0);
1035 }
1036
1037 return result;
1038 }
1039 \f
1040 /* Emit the common code for doing conditional branches.
1041 operand[0] is the label to jump to.
1042 The comparison operands are saved away by cmp{si,di,sf,df}. */
1043
1044 void
1045 gen_conditional_branch (rtx operands[], enum machine_mode mode)
1046 {
1047 enum rtx_code test_code = GET_CODE (operands[0]);
1048 rtx cmp0 = operands[1];
1049 rtx cmp1 = operands[2];
1050 rtx reg;
1051 int invert;
1052 rtx label1, label2;
1053
1054 invert = 0;
1055 reg = gen_int_relational (test_code, NULL_RTX, cmp0, cmp1, &invert);
1056
1057 if (reg)
1058 {
1059 cmp0 = reg;
1060 cmp1 = const0_rtx;
1061 test_code = NE;
1062 }
1063 else if (GET_CODE (cmp1) == CONST_INT && INTVAL (cmp1) != 0)
1064 /* We don't want to build a comparison against a nonzero
1065 constant. */
1066 cmp1 = force_reg (mode, cmp1);
1067
1068 /* Generate the branch. */
1069 label1 = gen_rtx_LABEL_REF (VOIDmode, operands[3]);
1070 label2 = pc_rtx;
1071
1072 if (invert)
1073 {
1074 label2 = label1;
1075 label1 = pc_rtx;
1076 }
1077
1078 emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
1079 gen_rtx_IF_THEN_ELSE (VOIDmode,
1080 gen_rtx_fmt_ee (test_code,
1081 VOIDmode,
1082 cmp0, cmp1),
1083 label1, label2)));
1084 }
1085 \f
1086 /* Initialize CUM for a function FNTYPE. */
1087
1088 void
1089 init_cumulative_args (CUMULATIVE_ARGS *cum, tree fntype,
1090 rtx libname ATTRIBUTE_UNUSED)
1091 {
1092 static CUMULATIVE_ARGS zero_cum;
1093 tree param;
1094 tree next_param;
1095
1096 if (TARGET_DEBUG_D_MODE)
1097 {
1098 fprintf (stderr,
1099 "\ninit_cumulative_args, fntype = 0x%.8lx", (long) fntype);
1100
1101 if (!fntype)
1102 fputc ('\n', stderr);
1103
1104 else
1105 {
1106 tree ret_type = TREE_TYPE (fntype);
1107
1108 fprintf (stderr, ", fntype code = %s, ret code = %s\n",
1109 tree_code_name[(int)TREE_CODE (fntype)],
1110 tree_code_name[(int)TREE_CODE (ret_type)]);
1111 }
1112 }
1113
1114 *cum = zero_cum;
1115
1116 /* Determine if this function has variable arguments. This is
1117 indicated by the last argument being 'void_type_mode' if there
1118 are no variable arguments. The standard IQ2000 calling sequence
1119 passes all arguments in the general purpose registers in this case. */
1120
1121 for (param = fntype ? TYPE_ARG_TYPES (fntype) : 0;
1122 param != 0; param = next_param)
1123 {
1124 next_param = TREE_CHAIN (param);
1125 if (next_param == 0 && TREE_VALUE (param) != void_type_node)
1126 cum->gp_reg_found = 1;
1127 }
1128 }
1129
1130 /* Advance the argument of type TYPE and mode MODE to the next argument
1131 position in CUM. */
1132
1133 static void
1134 iq2000_function_arg_advance (cumulative_args_t cum_v, enum machine_mode mode,
1135 const_tree type, bool named)
1136 {
1137 CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
1138
1139 if (TARGET_DEBUG_D_MODE)
1140 {
1141 fprintf (stderr,
1142 "function_adv({gp reg found = %d, arg # = %2d, words = %2d}, %4s, ",
1143 cum->gp_reg_found, cum->arg_number, cum->arg_words,
1144 GET_MODE_NAME (mode));
1145 fprintf (stderr, "%p", type);
1146 fprintf (stderr, ", %d )\n\n", named);
1147 }
1148
1149 cum->arg_number++;
1150 switch (mode)
1151 {
1152 case VOIDmode:
1153 break;
1154
1155 default:
1156 gcc_assert (GET_MODE_CLASS (mode) == MODE_COMPLEX_INT
1157 || GET_MODE_CLASS (mode) == MODE_COMPLEX_FLOAT);
1158
1159 cum->gp_reg_found = 1;
1160 cum->arg_words += ((GET_MODE_SIZE (mode) + UNITS_PER_WORD - 1)
1161 / UNITS_PER_WORD);
1162 break;
1163
1164 case BLKmode:
1165 cum->gp_reg_found = 1;
1166 cum->arg_words += ((int_size_in_bytes (type) + UNITS_PER_WORD - 1)
1167 / UNITS_PER_WORD);
1168 break;
1169
1170 case SFmode:
1171 cum->arg_words ++;
1172 if (! cum->gp_reg_found && cum->arg_number <= 2)
1173 cum->fp_code += 1 << ((cum->arg_number - 1) * 2);
1174 break;
1175
1176 case DFmode:
1177 cum->arg_words += 2;
1178 if (! cum->gp_reg_found && cum->arg_number <= 2)
1179 cum->fp_code += 2 << ((cum->arg_number - 1) * 2);
1180 break;
1181
1182 case DImode:
1183 cum->gp_reg_found = 1;
1184 cum->arg_words += 2;
1185 break;
1186
1187 case TImode:
1188 cum->gp_reg_found = 1;
1189 cum->arg_words += 4;
1190 break;
1191
1192 case QImode:
1193 case HImode:
1194 case SImode:
1195 cum->gp_reg_found = 1;
1196 cum->arg_words ++;
1197 break;
1198 }
1199 }
1200
1201 /* Return an RTL expression containing the register for the given mode MODE
1202 and type TYPE in CUM, or 0 if the argument is to be passed on the stack. */
1203
1204 static rtx
1205 iq2000_function_arg (cumulative_args_t cum_v, enum machine_mode mode,
1206 const_tree type, bool named)
1207 {
1208 CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
1209 rtx ret;
1210 int regbase = -1;
1211 int bias = 0;
1212 unsigned int *arg_words = &cum->arg_words;
1213 int struct_p = (type != 0
1214 && (TREE_CODE (type) == RECORD_TYPE
1215 || TREE_CODE (type) == UNION_TYPE
1216 || TREE_CODE (type) == QUAL_UNION_TYPE));
1217
1218 if (TARGET_DEBUG_D_MODE)
1219 {
1220 fprintf (stderr,
1221 "function_arg( {gp reg found = %d, arg # = %2d, words = %2d}, %4s, ",
1222 cum->gp_reg_found, cum->arg_number, cum->arg_words,
1223 GET_MODE_NAME (mode));
1224 fprintf (stderr, "%p", (const void *) type);
1225 fprintf (stderr, ", %d ) = ", named);
1226 }
1227
1228
1229 cum->last_arg_fp = 0;
1230 switch (mode)
1231 {
1232 case SFmode:
1233 regbase = GP_ARG_FIRST;
1234 break;
1235
1236 case DFmode:
1237 cum->arg_words += cum->arg_words & 1;
1238
1239 regbase = GP_ARG_FIRST;
1240 break;
1241
1242 default:
1243 gcc_assert (GET_MODE_CLASS (mode) == MODE_COMPLEX_INT
1244 || GET_MODE_CLASS (mode) == MODE_COMPLEX_FLOAT);
1245
1246 /* Drops through. */
1247 case BLKmode:
1248 if (type != NULL_TREE && TYPE_ALIGN (type) > (unsigned) BITS_PER_WORD)
1249 cum->arg_words += (cum->arg_words & 1);
1250 regbase = GP_ARG_FIRST;
1251 break;
1252
1253 case VOIDmode:
1254 case QImode:
1255 case HImode:
1256 case SImode:
1257 regbase = GP_ARG_FIRST;
1258 break;
1259
1260 case DImode:
1261 cum->arg_words += (cum->arg_words & 1);
1262 regbase = GP_ARG_FIRST;
1263 break;
1264
1265 case TImode:
1266 cum->arg_words += (cum->arg_words & 3);
1267 regbase = GP_ARG_FIRST;
1268 break;
1269 }
1270
1271 if (*arg_words >= (unsigned) MAX_ARGS_IN_REGISTERS)
1272 {
1273 if (TARGET_DEBUG_D_MODE)
1274 fprintf (stderr, "<stack>%s\n", struct_p ? ", [struct]" : "");
1275
1276 ret = 0;
1277 }
1278 else
1279 {
1280 gcc_assert (regbase != -1);
1281
1282 if (! type || TREE_CODE (type) != RECORD_TYPE
1283 || ! named || ! TYPE_SIZE_UNIT (type)
1284 || ! host_integerp (TYPE_SIZE_UNIT (type), 1))
1285 ret = gen_rtx_REG (mode, regbase + *arg_words + bias);
1286 else
1287 {
1288 tree field;
1289
1290 for (field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
1291 if (TREE_CODE (field) == FIELD_DECL
1292 && TREE_CODE (TREE_TYPE (field)) == REAL_TYPE
1293 && TYPE_PRECISION (TREE_TYPE (field)) == BITS_PER_WORD
1294 && host_integerp (bit_position (field), 0)
1295 && int_bit_position (field) % BITS_PER_WORD == 0)
1296 break;
1297
1298 /* If the whole struct fits a DFmode register,
1299 we don't need the PARALLEL. */
1300 if (! field || mode == DFmode)
1301 ret = gen_rtx_REG (mode, regbase + *arg_words + bias);
1302 else
1303 {
1304 unsigned int chunks;
1305 HOST_WIDE_INT bitpos;
1306 unsigned int regno;
1307 unsigned int i;
1308
1309 /* ??? If this is a packed structure, then the last hunk won't
1310 be 64 bits. */
1311 chunks
1312 = tree_low_cst (TYPE_SIZE_UNIT (type), 1) / UNITS_PER_WORD;
1313 if (chunks + *arg_words + bias > (unsigned) MAX_ARGS_IN_REGISTERS)
1314 chunks = MAX_ARGS_IN_REGISTERS - *arg_words - bias;
1315
1316 /* Assign_parms checks the mode of ENTRY_PARM, so we must
1317 use the actual mode here. */
1318 ret = gen_rtx_PARALLEL (mode, rtvec_alloc (chunks));
1319
1320 bitpos = 0;
1321 regno = regbase + *arg_words + bias;
1322 field = TYPE_FIELDS (type);
1323 for (i = 0; i < chunks; i++)
1324 {
1325 rtx reg;
1326
1327 for (; field; field = DECL_CHAIN (field))
1328 if (TREE_CODE (field) == FIELD_DECL
1329 && int_bit_position (field) >= bitpos)
1330 break;
1331
1332 if (field
1333 && int_bit_position (field) == bitpos
1334 && TREE_CODE (TREE_TYPE (field)) == REAL_TYPE
1335 && TYPE_PRECISION (TREE_TYPE (field)) == BITS_PER_WORD)
1336 reg = gen_rtx_REG (DFmode, regno++);
1337 else
1338 reg = gen_rtx_REG (word_mode, regno);
1339
1340 XVECEXP (ret, 0, i)
1341 = gen_rtx_EXPR_LIST (VOIDmode, reg,
1342 GEN_INT (bitpos / BITS_PER_UNIT));
1343
1344 bitpos += 64;
1345 regno++;
1346 }
1347 }
1348 }
1349
1350 if (TARGET_DEBUG_D_MODE)
1351 fprintf (stderr, "%s%s\n", reg_names[regbase + *arg_words + bias],
1352 struct_p ? ", [struct]" : "");
1353 }
1354
1355 /* We will be called with a mode of VOIDmode after the last argument
1356 has been seen. Whatever we return will be passed to the call
1357 insn. If we need any shifts for small structures, return them in
1358 a PARALLEL. */
1359 if (mode == VOIDmode)
1360 {
1361 if (cum->num_adjusts > 0)
1362 ret = gen_rtx_PARALLEL ((enum machine_mode) cum->fp_code,
1363 gen_rtvec_v (cum->num_adjusts, cum->adjust));
1364 }
1365
1366 return ret;
1367 }
1368
1369 static unsigned int
1370 iq2000_function_arg_boundary (enum machine_mode mode, const_tree type)
1371 {
1372 return (type != NULL_TREE
1373 ? (TYPE_ALIGN (type) <= PARM_BOUNDARY
1374 ? PARM_BOUNDARY
1375 : TYPE_ALIGN (type))
1376 : (GET_MODE_ALIGNMENT (mode) <= PARM_BOUNDARY
1377 ? PARM_BOUNDARY
1378 : GET_MODE_ALIGNMENT (mode)));
1379 }
1380
1381 static int
1382 iq2000_arg_partial_bytes (cumulative_args_t cum_v, enum machine_mode mode,
1383 tree type ATTRIBUTE_UNUSED,
1384 bool named ATTRIBUTE_UNUSED)
1385 {
1386 CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
1387
1388 if (mode == DImode && cum->arg_words == MAX_ARGS_IN_REGISTERS - 1)
1389 {
1390 if (TARGET_DEBUG_D_MODE)
1391 fprintf (stderr, "iq2000_arg_partial_bytes=%d\n", UNITS_PER_WORD);
1392 return UNITS_PER_WORD;
1393 }
1394
1395 return 0;
1396 }
1397 \f
1398 /* Implement va_start. */
1399
1400 static void
1401 iq2000_va_start (tree valist, rtx nextarg)
1402 {
1403 int int_arg_words;
1404 /* Find out how many non-float named formals. */
1405 int gpr_save_area_size;
1406 /* Note UNITS_PER_WORD is 4 bytes. */
1407 int_arg_words = crtl->args.info.arg_words;
1408
1409 if (int_arg_words < 8 )
1410 /* Adjust for the prologue's economy measure. */
1411 gpr_save_area_size = (8 - int_arg_words) * UNITS_PER_WORD;
1412 else
1413 gpr_save_area_size = 0;
1414
1415 /* Everything is in the GPR save area, or in the overflow
1416 area which is contiguous with it. */
1417 nextarg = plus_constant (Pmode, nextarg, - gpr_save_area_size);
1418 std_expand_builtin_va_start (valist, nextarg);
1419 }
1420 \f
1421 /* Allocate a chunk of memory for per-function machine-dependent data. */
1422
1423 static struct machine_function *
1424 iq2000_init_machine_status (void)
1425 {
1426 return ggc_alloc_cleared_machine_function ();
1427 }
1428
1429 /* Detect any conflicts in the switches. */
1430
1431 static void
1432 iq2000_option_override (void)
1433 {
1434 target_flags &= ~MASK_GPOPT;
1435
1436 iq2000_isa = IQ2000_ISA_DEFAULT;
1437
1438 /* Identify the processor type. */
1439
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;
1458 iq2000_print_operand_punct['~'] = 1;
1459
1460 /* Save GPR registers in word_mode sized hunks. word_mode hasn't been
1461 initialized yet, so we can't use that here. */
1462 gpr_mode = SImode;
1463
1464 /* Function to allocate machine-dependent function status. */
1465 init_machine_status = iq2000_init_machine_status;
1466 }
1467 \f
1468 /* The arg pointer (which is eliminated) points to the virtual frame pointer,
1469 while the frame pointer (which may be eliminated) points to the stack
1470 pointer after the initial adjustments. */
1471
1472 HOST_WIDE_INT
1473 iq2000_debugger_offset (rtx addr, HOST_WIDE_INT offset)
1474 {
1475 rtx offset2 = const0_rtx;
1476 rtx reg = eliminate_constant_term (addr, & offset2);
1477
1478 if (offset == 0)
1479 offset = INTVAL (offset2);
1480
1481 if (reg == stack_pointer_rtx || reg == frame_pointer_rtx
1482 || reg == hard_frame_pointer_rtx)
1483 {
1484 HOST_WIDE_INT frame_size = (!cfun->machine->initialized)
1485 ? compute_frame_size (get_frame_size ())
1486 : cfun->machine->total_size;
1487
1488 offset = offset - frame_size;
1489 }
1490
1491 return offset;
1492 }
1493 \f
1494 /* If defined, a C statement to be executed just prior to the output of
1495 assembler code for INSN, to modify the extracted operands so they will be
1496 output differently.
1497
1498 Here the argument OPVEC is the vector containing the operands extracted
1499 from INSN, and NOPERANDS is the number of elements of the vector which
1500 contain meaningful data for this insn. The contents of this vector are
1501 what will be used to convert the insn template into assembler code, so you
1502 can change the assembler output by changing the contents of the vector.
1503
1504 We use it to check if the current insn needs a nop in front of it because
1505 of load delays, and also to update the delay slot statistics. */
1506
1507 void
1508 final_prescan_insn (rtx insn, rtx opvec[] ATTRIBUTE_UNUSED,
1509 int noperands ATTRIBUTE_UNUSED)
1510 {
1511 if (dslots_number_nops > 0)
1512 {
1513 rtx pattern = PATTERN (insn);
1514 int length = get_attr_length (insn);
1515
1516 /* Do we need to emit a NOP? */
1517 if (length == 0
1518 || (iq2000_load_reg != 0 && reg_mentioned_p (iq2000_load_reg, pattern))
1519 || (iq2000_load_reg2 != 0 && reg_mentioned_p (iq2000_load_reg2, pattern))
1520 || (iq2000_load_reg3 != 0 && reg_mentioned_p (iq2000_load_reg3, pattern))
1521 || (iq2000_load_reg4 != 0
1522 && reg_mentioned_p (iq2000_load_reg4, pattern)))
1523 fputs ("\tnop\n", asm_out_file);
1524
1525 else
1526 dslots_load_filled ++;
1527
1528 while (--dslots_number_nops > 0)
1529 fputs ("\tnop\n", asm_out_file);
1530
1531 iq2000_load_reg = 0;
1532 iq2000_load_reg2 = 0;
1533 iq2000_load_reg3 = 0;
1534 iq2000_load_reg4 = 0;
1535 }
1536
1537 if ( (GET_CODE (insn) == JUMP_INSN
1538 || GET_CODE (insn) == CALL_INSN
1539 || (GET_CODE (PATTERN (insn)) == RETURN))
1540 && NEXT_INSN (PREV_INSN (insn)) == insn)
1541 {
1542 rtx nop_insn = emit_insn_after (gen_nop (), insn);
1543
1544 INSN_ADDRESSES_NEW (nop_insn, -1);
1545 }
1546
1547 if (TARGET_STATS
1548 && (GET_CODE (insn) == JUMP_INSN || GET_CODE (insn) == CALL_INSN))
1549 dslots_jump_total ++;
1550 }
1551 \f
1552 /* Return the bytes needed to compute the frame pointer from the current
1553 stack pointer where SIZE is the # of var. bytes allocated.
1554
1555 IQ2000 stack frames look like:
1556
1557 Before call After call
1558 +-----------------------+ +-----------------------+
1559 high | | | |
1560 mem. | | | |
1561 | caller's temps. | | caller's temps. |
1562 | | | |
1563 +-----------------------+ +-----------------------+
1564 | | | |
1565 | arguments on stack. | | arguments on stack. |
1566 | | | |
1567 +-----------------------+ +-----------------------+
1568 | 4 words to save | | 4 words to save |
1569 | arguments passed | | arguments passed |
1570 | in registers, even | | in registers, even |
1571 SP->| if not passed. | VFP->| if not passed. |
1572 +-----------------------+ +-----------------------+
1573 | |
1574 | fp register save |
1575 | |
1576 +-----------------------+
1577 | |
1578 | gp register save |
1579 | |
1580 +-----------------------+
1581 | |
1582 | local variables |
1583 | |
1584 +-----------------------+
1585 | |
1586 | alloca allocations |
1587 | |
1588 +-----------------------+
1589 | |
1590 | GP save for V.4 abi |
1591 | |
1592 +-----------------------+
1593 | |
1594 | arguments on stack |
1595 | |
1596 +-----------------------+
1597 | 4 words to save |
1598 | arguments passed |
1599 | in registers, even |
1600 low SP->| if not passed. |
1601 memory +-----------------------+ */
1602
1603 HOST_WIDE_INT
1604 compute_frame_size (HOST_WIDE_INT size)
1605 {
1606 int regno;
1607 HOST_WIDE_INT total_size; /* # bytes that the entire frame takes up. */
1608 HOST_WIDE_INT var_size; /* # bytes that variables take up. */
1609 HOST_WIDE_INT args_size; /* # bytes that outgoing arguments take up. */
1610 HOST_WIDE_INT extra_size; /* # extra bytes. */
1611 HOST_WIDE_INT gp_reg_rounded; /* # bytes needed to store gp after rounding. */
1612 HOST_WIDE_INT gp_reg_size; /* # bytes needed to store gp regs. */
1613 HOST_WIDE_INT fp_reg_size; /* # bytes needed to store fp regs. */
1614 long mask; /* mask of saved gp registers. */
1615
1616 gp_reg_size = 0;
1617 fp_reg_size = 0;
1618 mask = 0;
1619 extra_size = IQ2000_STACK_ALIGN ((0));
1620 var_size = IQ2000_STACK_ALIGN (size);
1621 args_size = IQ2000_STACK_ALIGN (crtl->outgoing_args_size);
1622
1623 /* If a function dynamically allocates the stack and
1624 has 0 for STACK_DYNAMIC_OFFSET then allocate some stack space. */
1625 if (args_size == 0 && cfun->calls_alloca)
1626 args_size = 4 * UNITS_PER_WORD;
1627
1628 total_size = var_size + args_size + extra_size;
1629
1630 /* Calculate space needed for gp registers. */
1631 for (regno = GP_REG_FIRST; regno <= GP_REG_LAST; regno++)
1632 {
1633 if (MUST_SAVE_REGISTER (regno))
1634 {
1635 gp_reg_size += GET_MODE_SIZE (gpr_mode);
1636 mask |= 1L << (regno - GP_REG_FIRST);
1637 }
1638 }
1639
1640 /* We need to restore these for the handler. */
1641 if (crtl->calls_eh_return)
1642 {
1643 unsigned int i;
1644
1645 for (i = 0; ; ++i)
1646 {
1647 regno = EH_RETURN_DATA_REGNO (i);
1648 if (regno == (int) INVALID_REGNUM)
1649 break;
1650 gp_reg_size += GET_MODE_SIZE (gpr_mode);
1651 mask |= 1L << (regno - GP_REG_FIRST);
1652 }
1653 }
1654
1655 gp_reg_rounded = IQ2000_STACK_ALIGN (gp_reg_size);
1656 total_size += gp_reg_rounded + IQ2000_STACK_ALIGN (fp_reg_size);
1657
1658 /* The gp reg is caller saved, so there is no need for leaf routines
1659 (total_size == extra_size) to save the gp reg. */
1660 if (total_size == extra_size
1661 && ! profile_flag)
1662 total_size = extra_size = 0;
1663
1664 total_size += IQ2000_STACK_ALIGN (crtl->args.pretend_args_size);
1665
1666 /* Save other computed information. */
1667 cfun->machine->total_size = total_size;
1668 cfun->machine->var_size = var_size;
1669 cfun->machine->args_size = args_size;
1670 cfun->machine->extra_size = extra_size;
1671 cfun->machine->gp_reg_size = gp_reg_size;
1672 cfun->machine->fp_reg_size = fp_reg_size;
1673 cfun->machine->mask = mask;
1674 cfun->machine->initialized = reload_completed;
1675 cfun->machine->num_gp = gp_reg_size / UNITS_PER_WORD;
1676
1677 if (mask)
1678 {
1679 unsigned long offset;
1680
1681 offset = (args_size + extra_size + var_size
1682 + gp_reg_size - GET_MODE_SIZE (gpr_mode));
1683
1684 cfun->machine->gp_sp_offset = offset;
1685 cfun->machine->gp_save_offset = offset - total_size;
1686 }
1687 else
1688 {
1689 cfun->machine->gp_sp_offset = 0;
1690 cfun->machine->gp_save_offset = 0;
1691 }
1692
1693 cfun->machine->fp_sp_offset = 0;
1694 cfun->machine->fp_save_offset = 0;
1695
1696 /* Ok, we're done. */
1697 return total_size;
1698 }
1699 \f
1700
1701 /* We can always eliminate to the frame pointer. We can eliminate to the
1702 stack pointer unless a frame pointer is needed. */
1703
1704 bool
1705 iq2000_can_eliminate (const int from, const int to)
1706 {
1707 return (from == RETURN_ADDRESS_POINTER_REGNUM
1708 && (! leaf_function_p ()
1709 || (to == GP_REG_FIRST + 31 && leaf_function_p ())))
1710 || (from != RETURN_ADDRESS_POINTER_REGNUM
1711 && (to == HARD_FRAME_POINTER_REGNUM
1712 || (to == STACK_POINTER_REGNUM
1713 && ! frame_pointer_needed)));
1714 }
1715
1716 /* Implement INITIAL_ELIMINATION_OFFSET. FROM is either the frame
1717 pointer, argument pointer, or return address pointer. TO is either
1718 the stack pointer or hard frame pointer. */
1719
1720 int
1721 iq2000_initial_elimination_offset (int from, int to ATTRIBUTE_UNUSED)
1722 {
1723 int offset;
1724
1725 compute_frame_size (get_frame_size ());
1726 if ((from) == FRAME_POINTER_REGNUM)
1727 (offset) = 0;
1728 else if ((from) == ARG_POINTER_REGNUM)
1729 (offset) = (cfun->machine->total_size);
1730 else if ((from) == RETURN_ADDRESS_POINTER_REGNUM)
1731 {
1732 if (leaf_function_p ())
1733 (offset) = 0;
1734 else (offset) = cfun->machine->gp_sp_offset
1735 + ((UNITS_PER_WORD - (POINTER_SIZE / BITS_PER_UNIT))
1736 * (BYTES_BIG_ENDIAN != 0));
1737 }
1738 else
1739 gcc_unreachable ();
1740
1741 return offset;
1742 }
1743 \f
1744 /* Common code to emit the insns (or to write the instructions to a file)
1745 to save/restore registers.
1746 Other parts of the code assume that IQ2000_TEMP1_REGNUM (aka large_reg)
1747 is not modified within save_restore_insns. */
1748
1749 #define BITSET_P(VALUE,BIT) (((VALUE) & (1L << (BIT))) != 0)
1750
1751 /* Emit instructions to load the value (SP + OFFSET) into IQ2000_TEMP2_REGNUM
1752 and return an rtl expression for the register. Write the assembly
1753 instructions directly to FILE if it is not null, otherwise emit them as
1754 rtl.
1755
1756 This function is a subroutine of save_restore_insns. It is used when
1757 OFFSET is too large to add in a single instruction. */
1758
1759 static rtx
1760 iq2000_add_large_offset_to_sp (HOST_WIDE_INT offset)
1761 {
1762 rtx reg = gen_rtx_REG (Pmode, IQ2000_TEMP2_REGNUM);
1763 rtx offset_rtx = GEN_INT (offset);
1764
1765 emit_move_insn (reg, offset_rtx);
1766 emit_insn (gen_addsi3 (reg, reg, stack_pointer_rtx));
1767 return reg;
1768 }
1769
1770 /* Make INSN frame related and note that it performs the frame-related
1771 operation DWARF_PATTERN. */
1772
1773 static void
1774 iq2000_annotate_frame_insn (rtx insn, rtx dwarf_pattern)
1775 {
1776 RTX_FRAME_RELATED_P (insn) = 1;
1777 REG_NOTES (insn) = alloc_EXPR_LIST (REG_FRAME_RELATED_EXPR,
1778 dwarf_pattern,
1779 REG_NOTES (insn));
1780 }
1781
1782 /* Emit a move instruction that stores REG in MEM. Make the instruction
1783 frame related and note that it stores REG at (SP + OFFSET). */
1784
1785 static void
1786 iq2000_emit_frame_related_store (rtx mem, rtx reg, HOST_WIDE_INT offset)
1787 {
1788 rtx dwarf_address = plus_constant (Pmode, stack_pointer_rtx, offset);
1789 rtx dwarf_mem = gen_rtx_MEM (GET_MODE (reg), dwarf_address);
1790
1791 iq2000_annotate_frame_insn (emit_move_insn (mem, reg),
1792 gen_rtx_SET (GET_MODE (reg), dwarf_mem, reg));
1793 }
1794
1795 /* Emit instructions to save/restore registers, as determined by STORE_P. */
1796
1797 static void
1798 save_restore_insns (int store_p)
1799 {
1800 long mask = cfun->machine->mask;
1801 int regno;
1802 rtx base_reg_rtx;
1803 HOST_WIDE_INT base_offset;
1804 HOST_WIDE_INT gp_offset;
1805 HOST_WIDE_INT end_offset;
1806
1807 gcc_assert (!frame_pointer_needed
1808 || BITSET_P (mask, HARD_FRAME_POINTER_REGNUM - GP_REG_FIRST));
1809
1810 if (mask == 0)
1811 {
1812 base_reg_rtx = 0, base_offset = 0;
1813 return;
1814 }
1815
1816 /* Save registers starting from high to low. The debuggers prefer at least
1817 the return register be stored at func+4, and also it allows us not to
1818 need a nop in the epilog if at least one register is reloaded in
1819 addition to return address. */
1820
1821 /* Save GP registers if needed. */
1822 /* Pick which pointer to use as a base register. For small frames, just
1823 use the stack pointer. Otherwise, use a temporary register. Save 2
1824 cycles if the save area is near the end of a large frame, by reusing
1825 the constant created in the prologue/epilogue to adjust the stack
1826 frame. */
1827
1828 gp_offset = cfun->machine->gp_sp_offset;
1829 end_offset
1830 = gp_offset - (cfun->machine->gp_reg_size
1831 - GET_MODE_SIZE (gpr_mode));
1832
1833 if (gp_offset < 0 || end_offset < 0)
1834 internal_error
1835 ("gp_offset (%ld) or end_offset (%ld) is less than zero",
1836 (long) gp_offset, (long) end_offset);
1837
1838 else if (gp_offset < 32768)
1839 base_reg_rtx = stack_pointer_rtx, base_offset = 0;
1840 else
1841 {
1842 int regno;
1843 int reg_save_count = 0;
1844
1845 for (regno = GP_REG_LAST; regno >= GP_REG_FIRST; regno--)
1846 if (BITSET_P (mask, regno - GP_REG_FIRST)) reg_save_count += 1;
1847 base_offset = gp_offset - ((reg_save_count - 1) * 4);
1848 base_reg_rtx = iq2000_add_large_offset_to_sp (base_offset);
1849 }
1850
1851 for (regno = GP_REG_LAST; regno >= GP_REG_FIRST; regno--)
1852 {
1853 if (BITSET_P (mask, regno - GP_REG_FIRST))
1854 {
1855 rtx reg_rtx;
1856 rtx mem_rtx
1857 = gen_rtx_MEM (gpr_mode,
1858 gen_rtx_PLUS (Pmode, base_reg_rtx,
1859 GEN_INT (gp_offset - base_offset)));
1860
1861 reg_rtx = gen_rtx_REG (gpr_mode, regno);
1862
1863 if (store_p)
1864 iq2000_emit_frame_related_store (mem_rtx, reg_rtx, gp_offset);
1865 else
1866 {
1867 emit_move_insn (reg_rtx, mem_rtx);
1868 }
1869 gp_offset -= GET_MODE_SIZE (gpr_mode);
1870 }
1871 }
1872 }
1873 \f
1874 /* Expand the prologue into a bunch of separate insns. */
1875
1876 void
1877 iq2000_expand_prologue (void)
1878 {
1879 int regno;
1880 HOST_WIDE_INT tsize;
1881 int last_arg_is_vararg_marker = 0;
1882 tree fndecl = current_function_decl;
1883 tree fntype = TREE_TYPE (fndecl);
1884 tree fnargs = DECL_ARGUMENTS (fndecl);
1885 rtx next_arg_reg;
1886 int i;
1887 tree next_arg;
1888 tree cur_arg;
1889 CUMULATIVE_ARGS args_so_far_v;
1890 cumulative_args_t args_so_far;
1891 int store_args_on_stack = (iq2000_can_use_return_insn ());
1892
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)
1897 {
1898 tree type = build_pointer_type (fntype);
1899 tree function_result_decl = build_decl (BUILTINS_LOCATION,
1900 PARM_DECL, NULL_TREE, type);
1901
1902 DECL_ARG_TYPE (function_result_decl) = type;
1903 DECL_CHAIN (function_result_decl) = fnargs;
1904 fnargs = function_result_decl;
1905 }
1906
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.
1912
1913 This is only needed if store_args_on_stack is true. */
1914 INIT_CUMULATIVE_ARGS (args_so_far_v, fntype, NULL_RTX, 0, 0);
1915 args_so_far = pack_cumulative_args (&args_so_far_v);
1916 regno = GP_ARG_FIRST;
1917
1918 for (cur_arg = fnargs; cur_arg != 0; cur_arg = next_arg)
1919 {
1920 tree passed_type = DECL_ARG_TYPE (cur_arg);
1921 enum machine_mode passed_mode = TYPE_MODE (passed_type);
1922 rtx entry_parm;
1923
1924 if (TREE_ADDRESSABLE (passed_type))
1925 {
1926 passed_type = build_pointer_type (passed_type);
1927 passed_mode = Pmode;
1928 }
1929
1930 entry_parm = iq2000_function_arg (args_so_far, passed_mode,
1931 passed_type, true);
1932
1933 iq2000_function_arg_advance (args_so_far, passed_mode,
1934 passed_type, true);
1935 next_arg = DECL_CHAIN (cur_arg);
1936
1937 if (entry_parm && store_args_on_stack)
1938 {
1939 if (next_arg == 0
1940 && DECL_NAME (cur_arg)
1941 && ((0 == strcmp (IDENTIFIER_POINTER (DECL_NAME (cur_arg)),
1942 "__builtin_va_alist"))
1943 || (0 == strcmp (IDENTIFIER_POINTER (DECL_NAME (cur_arg)),
1944 "va_alist"))))
1945 {
1946 last_arg_is_vararg_marker = 1;
1947 break;
1948 }
1949 else
1950 {
1951 int words;
1952
1953 gcc_assert (GET_CODE (entry_parm) == REG);
1954
1955 /* Passed in a register, so will get homed automatically. */
1956 if (GET_MODE (entry_parm) == BLKmode)
1957 words = (int_size_in_bytes (passed_type) + 3) / 4;
1958 else
1959 words = (GET_MODE_SIZE (GET_MODE (entry_parm)) + 3) / 4;
1960
1961 regno = REGNO (entry_parm) + words - 1;
1962 }
1963 }
1964 else
1965 {
1966 regno = GP_ARG_LAST+1;
1967 break;
1968 }
1969 }
1970
1971 /* In order to pass small structures by value in registers we need to
1972 shift the value into the high part of the register.
1973 iq2000_unction_arg has encoded a PARALLEL rtx, holding a vector of
1974 adjustments to be made as the next_arg_reg variable, so we split up
1975 the insns, and emit them separately. */
1976 next_arg_reg = iq2000_function_arg (args_so_far, VOIDmode,
1977 void_type_node, true);
1978 if (next_arg_reg != 0 && GET_CODE (next_arg_reg) == PARALLEL)
1979 {
1980 rtvec adjust = XVEC (next_arg_reg, 0);
1981 int num = GET_NUM_ELEM (adjust);
1982
1983 for (i = 0; i < num; i++)
1984 {
1985 rtx pattern;
1986
1987 pattern = RTVEC_ELT (adjust, i);
1988 if (GET_CODE (pattern) != SET
1989 || GET_CODE (SET_SRC (pattern)) != ASHIFT)
1990 abort_with_insn (pattern, "Insn is not a shift");
1991 PUT_CODE (SET_SRC (pattern), ASHIFTRT);
1992
1993 emit_insn (pattern);
1994 }
1995 }
1996
1997 tsize = compute_frame_size (get_frame_size ());
1998
1999 /* If this function is a varargs function, store any registers that
2000 would normally hold arguments ($4 - $7) on the stack. */
2001 if (store_args_on_stack
2002 && (stdarg_p (fntype)
2003 || last_arg_is_vararg_marker))
2004 {
2005 int offset = (regno - GP_ARG_FIRST) * UNITS_PER_WORD;
2006 rtx ptr = stack_pointer_rtx;
2007
2008 for (; regno <= GP_ARG_LAST; regno++)
2009 {
2010 if (offset != 0)
2011 ptr = gen_rtx_PLUS (Pmode, stack_pointer_rtx, GEN_INT (offset));
2012 emit_move_insn (gen_rtx_MEM (gpr_mode, ptr),
2013 gen_rtx_REG (gpr_mode, regno));
2014
2015 offset += GET_MODE_SIZE (gpr_mode);
2016 }
2017 }
2018
2019 if (tsize > 0)
2020 {
2021 rtx tsize_rtx = GEN_INT (tsize);
2022 rtx adjustment_rtx, insn, dwarf_pattern;
2023
2024 if (tsize > 32767)
2025 {
2026 adjustment_rtx = gen_rtx_REG (Pmode, IQ2000_TEMP1_REGNUM);
2027 emit_move_insn (adjustment_rtx, tsize_rtx);
2028 }
2029 else
2030 adjustment_rtx = tsize_rtx;
2031
2032 insn = emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
2033 adjustment_rtx));
2034
2035 dwarf_pattern = gen_rtx_SET (Pmode, stack_pointer_rtx,
2036 plus_constant (Pmode, stack_pointer_rtx,
2037 -tsize));
2038
2039 iq2000_annotate_frame_insn (insn, dwarf_pattern);
2040
2041 save_restore_insns (1);
2042
2043 if (frame_pointer_needed)
2044 {
2045 rtx insn = 0;
2046
2047 insn = emit_insn (gen_movsi (hard_frame_pointer_rtx,
2048 stack_pointer_rtx));
2049
2050 if (insn)
2051 RTX_FRAME_RELATED_P (insn) = 1;
2052 }
2053 }
2054
2055 emit_insn (gen_blockage ());
2056 }
2057 \f
2058 /* Expand the epilogue into a bunch of separate insns. */
2059
2060 void
2061 iq2000_expand_epilogue (void)
2062 {
2063 HOST_WIDE_INT tsize = cfun->machine->total_size;
2064 rtx tsize_rtx = GEN_INT (tsize);
2065 rtx tmp_rtx = (rtx)0;
2066
2067 if (iq2000_can_use_return_insn ())
2068 {
2069 emit_jump_insn (gen_return ());
2070 return;
2071 }
2072
2073 if (tsize > 32767)
2074 {
2075 tmp_rtx = gen_rtx_REG (Pmode, IQ2000_TEMP1_REGNUM);
2076 emit_move_insn (tmp_rtx, tsize_rtx);
2077 tsize_rtx = tmp_rtx;
2078 }
2079
2080 if (tsize > 0)
2081 {
2082 if (frame_pointer_needed)
2083 {
2084 emit_insn (gen_blockage ());
2085
2086 emit_insn (gen_movsi (stack_pointer_rtx, hard_frame_pointer_rtx));
2087 }
2088
2089 save_restore_insns (0);
2090
2091 if (crtl->calls_eh_return)
2092 {
2093 rtx eh_ofs = EH_RETURN_STACKADJ_RTX;
2094 emit_insn (gen_addsi3 (eh_ofs, eh_ofs, tsize_rtx));
2095 tsize_rtx = eh_ofs;
2096 }
2097
2098 emit_insn (gen_blockage ());
2099
2100 if (tsize != 0 || crtl->calls_eh_return)
2101 {
2102 emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx,
2103 tsize_rtx));
2104 }
2105 }
2106
2107 if (crtl->calls_eh_return)
2108 {
2109 /* Perform the additional bump for __throw. */
2110 emit_move_insn (gen_rtx_REG (Pmode, HARD_FRAME_POINTER_REGNUM),
2111 stack_pointer_rtx);
2112 emit_use (gen_rtx_REG (Pmode, HARD_FRAME_POINTER_REGNUM));
2113 emit_jump_insn (gen_eh_return_internal ());
2114 }
2115 else
2116 emit_jump_insn (gen_return_internal (gen_rtx_REG (Pmode,
2117 GP_REG_FIRST + 31)));
2118 }
2119
2120 void
2121 iq2000_expand_eh_return (rtx address)
2122 {
2123 HOST_WIDE_INT gp_offset = cfun->machine->gp_sp_offset;
2124 rtx scratch;
2125
2126 scratch = plus_constant (Pmode, stack_pointer_rtx, gp_offset);
2127 emit_move_insn (gen_rtx_MEM (GET_MODE (address), scratch), address);
2128 }
2129 \f
2130 /* Return nonzero if this function is known to have a null epilogue.
2131 This allows the optimizer to omit jumps to jumps if no stack
2132 was created. */
2133
2134 int
2135 iq2000_can_use_return_insn (void)
2136 {
2137 if (! reload_completed)
2138 return 0;
2139
2140 if (df_regs_ever_live_p (31) || profile_flag)
2141 return 0;
2142
2143 if (cfun->machine->initialized)
2144 return cfun->machine->total_size == 0;
2145
2146 return compute_frame_size (get_frame_size ()) == 0;
2147 }
2148 \f
2149 /* Choose the section to use for the constant rtx expression X that has
2150 mode MODE. */
2151
2152 static section *
2153 iq2000_select_rtx_section (enum machine_mode mode, rtx x ATTRIBUTE_UNUSED,
2154 unsigned HOST_WIDE_INT align)
2155 {
2156 /* For embedded applications, always put constants in read-only data,
2157 in order to reduce RAM usage. */
2158 return mergeable_constant_section (mode, align, 0);
2159 }
2160
2161 /* Choose the section to use for DECL. RELOC is true if its value contains
2162 any relocatable expression.
2163
2164 Some of the logic used here needs to be replicated in
2165 ENCODE_SECTION_INFO in iq2000.h so that references to these symbols
2166 are done correctly. */
2167
2168 static section *
2169 iq2000_select_section (tree decl, int reloc ATTRIBUTE_UNUSED,
2170 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED)
2171 {
2172 if (TARGET_EMBEDDED_DATA)
2173 {
2174 /* For embedded applications, always put an object in read-only data
2175 if possible, in order to reduce RAM usage. */
2176 if ((TREE_CODE (decl) == VAR_DECL
2177 && TREE_READONLY (decl) && !TREE_SIDE_EFFECTS (decl)
2178 && DECL_INITIAL (decl)
2179 && (DECL_INITIAL (decl) == error_mark_node
2180 || TREE_CONSTANT (DECL_INITIAL (decl))))
2181 /* Deal with calls from output_constant_def_contents. */
2182 || TREE_CODE (decl) != VAR_DECL)
2183 return readonly_data_section;
2184 else
2185 return data_section;
2186 }
2187 else
2188 {
2189 /* For hosted applications, always put an object in small data if
2190 possible, as this gives the best performance. */
2191 if ((TREE_CODE (decl) == VAR_DECL
2192 && TREE_READONLY (decl) && !TREE_SIDE_EFFECTS (decl)
2193 && DECL_INITIAL (decl)
2194 && (DECL_INITIAL (decl) == error_mark_node
2195 || TREE_CONSTANT (DECL_INITIAL (decl))))
2196 /* Deal with calls from output_constant_def_contents. */
2197 || TREE_CODE (decl) != VAR_DECL)
2198 return readonly_data_section;
2199 else
2200 return data_section;
2201 }
2202 }
2203 /* Return register to use for a function return value with VALTYPE for function
2204 FUNC. */
2205
2206 static rtx
2207 iq2000_function_value (const_tree valtype,
2208 const_tree fn_decl_or_type,
2209 bool outgoing ATTRIBUTE_UNUSED)
2210 {
2211 int reg = GP_RETURN;
2212 enum machine_mode mode = TYPE_MODE (valtype);
2213 int unsignedp = TYPE_UNSIGNED (valtype);
2214 const_tree func = fn_decl_or_type;
2215
2216 if (fn_decl_or_type
2217 && !DECL_P (fn_decl_or_type))
2218 fn_decl_or_type = NULL;
2219
2220 /* Since we promote return types, we must promote the mode here too. */
2221 mode = promote_function_mode (valtype, mode, &unsignedp, func, 1);
2222
2223 return gen_rtx_REG (mode, reg);
2224 }
2225
2226 /* Worker function for TARGET_LIBCALL_VALUE. */
2227
2228 static rtx
2229 iq2000_libcall_value (enum machine_mode mode, const_rtx fun ATTRIBUTE_UNUSED)
2230 {
2231 return gen_rtx_REG (((GET_MODE_CLASS (mode) != MODE_INT
2232 || GET_MODE_SIZE (mode) >= 4)
2233 ? mode : SImode),
2234 GP_RETURN);
2235 }
2236
2237 /* Worker function for FUNCTION_VALUE_REGNO_P.
2238
2239 On the IQ2000, R2 and R3 are the only register thus used. */
2240
2241 bool
2242 iq2000_function_value_regno_p (const unsigned int regno)
2243 {
2244 return (regno == GP_RETURN);
2245 }
2246
2247 \f
2248 /* Return true when an argument must be passed by reference. */
2249
2250 static bool
2251 iq2000_pass_by_reference (cumulative_args_t cum_v, enum machine_mode mode,
2252 const_tree type, bool named ATTRIBUTE_UNUSED)
2253 {
2254 CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
2255 int size;
2256
2257 /* We must pass by reference if we would be both passing in registers
2258 and the stack. This is because any subsequent partial arg would be
2259 handled incorrectly in this case. */
2260 if (cum && targetm.calls.must_pass_in_stack (mode, type))
2261 {
2262 /* Don't pass the actual CUM to FUNCTION_ARG, because we would
2263 get double copies of any offsets generated for small structs
2264 passed in registers. */
2265 CUMULATIVE_ARGS temp;
2266
2267 temp = *cum;
2268 if (iq2000_function_arg (pack_cumulative_args (&temp), mode, type, named)
2269 != 0)
2270 return 1;
2271 }
2272
2273 if (type == NULL_TREE || mode == DImode || mode == DFmode)
2274 return 0;
2275
2276 size = int_size_in_bytes (type);
2277 return size == -1 || size > UNITS_PER_WORD;
2278 }
2279
2280 /* Return the length of INSN. LENGTH is the initial length computed by
2281 attributes in the machine-description file. */
2282
2283 int
2284 iq2000_adjust_insn_length (rtx insn, int length)
2285 {
2286 /* A unconditional jump has an unfilled delay slot if it is not part
2287 of a sequence. A conditional jump normally has a delay slot. */
2288 if (simplejump_p (insn)
2289 || ( (GET_CODE (insn) == JUMP_INSN
2290 || GET_CODE (insn) == CALL_INSN)))
2291 length += 4;
2292
2293 return length;
2294 }
2295
2296 /* Output assembly instructions to perform a conditional branch.
2297
2298 INSN is the branch instruction. OPERANDS[0] is the condition.
2299 OPERANDS[1] is the target of the branch. OPERANDS[2] is the target
2300 of the first operand to the condition. If TWO_OPERANDS_P is
2301 nonzero the comparison takes two operands; OPERANDS[3] will be the
2302 second operand.
2303
2304 If INVERTED_P is nonzero we are to branch if the condition does
2305 not hold. If FLOAT_P is nonzero this is a floating-point comparison.
2306
2307 LENGTH is the length (in bytes) of the sequence we are to generate.
2308 That tells us whether to generate a simple conditional branch, or a
2309 reversed conditional branch around a `jr' instruction. */
2310
2311 char *
2312 iq2000_output_conditional_branch (rtx insn, rtx * operands, int two_operands_p,
2313 int float_p, int inverted_p, int length)
2314 {
2315 static char buffer[200];
2316 /* The kind of comparison we are doing. */
2317 enum rtx_code code = GET_CODE (operands[0]);
2318 /* Nonzero if the opcode for the comparison needs a `z' indicating
2319 that it is a comparison against zero. */
2320 int need_z_p;
2321 /* A string to use in the assembly output to represent the first
2322 operand. */
2323 const char *op1 = "%z2";
2324 /* A string to use in the assembly output to represent the second
2325 operand. Use the hard-wired zero register if there's no second
2326 operand. */
2327 const char *op2 = (two_operands_p ? ",%z3" : ",%.");
2328 /* The operand-printing string for the comparison. */
2329 const char *comp = (float_p ? "%F0" : "%C0");
2330 /* The operand-printing string for the inverted comparison. */
2331 const char *inverted_comp = (float_p ? "%W0" : "%N0");
2332
2333 /* Likely variants of each branch instruction annul the instruction
2334 in the delay slot if the branch is not taken. */
2335 iq2000_branch_likely = (final_sequence && INSN_ANNULLED_BRANCH_P (insn));
2336
2337 if (!two_operands_p)
2338 {
2339 /* To compute whether than A > B, for example, we normally
2340 subtract B from A and then look at the sign bit. But, if we
2341 are doing an unsigned comparison, and B is zero, we don't
2342 have to do the subtraction. Instead, we can just check to
2343 see if A is nonzero. Thus, we change the CODE here to
2344 reflect the simpler comparison operation. */
2345 switch (code)
2346 {
2347 case GTU:
2348 code = NE;
2349 break;
2350
2351 case LEU:
2352 code = EQ;
2353 break;
2354
2355 case GEU:
2356 /* A condition which will always be true. */
2357 code = EQ;
2358 op1 = "%.";
2359 break;
2360
2361 case LTU:
2362 /* A condition which will always be false. */
2363 code = NE;
2364 op1 = "%.";
2365 break;
2366
2367 default:
2368 /* Not a special case. */
2369 break;
2370 }
2371 }
2372
2373 /* Relative comparisons are always done against zero. But
2374 equality comparisons are done between two operands, and therefore
2375 do not require a `z' in the assembly language output. */
2376 need_z_p = (!float_p && code != EQ && code != NE);
2377 /* For comparisons against zero, the zero is not provided
2378 explicitly. */
2379 if (need_z_p)
2380 op2 = "";
2381
2382 /* Begin by terminating the buffer. That way we can always use
2383 strcat to add to it. */
2384 buffer[0] = '\0';
2385
2386 switch (length)
2387 {
2388 case 4:
2389 case 8:
2390 /* Just a simple conditional branch. */
2391 if (float_p)
2392 sprintf (buffer, "b%s%%?\t%%Z2%%1",
2393 inverted_p ? inverted_comp : comp);
2394 else
2395 sprintf (buffer, "b%s%s%%?\t%s%s,%%1",
2396 inverted_p ? inverted_comp : comp,
2397 need_z_p ? "z" : "",
2398 op1,
2399 op2);
2400 return buffer;
2401
2402 case 12:
2403 case 16:
2404 {
2405 /* Generate a reversed conditional branch around ` j'
2406 instruction:
2407
2408 .set noreorder
2409 .set nomacro
2410 bc l
2411 nop
2412 j target
2413 .set macro
2414 .set reorder
2415 l:
2416
2417 Because we have to jump four bytes *past* the following
2418 instruction if this branch was annulled, we can't just use
2419 a label, as in the picture above; there's no way to put the
2420 label after the next instruction, as the assembler does not
2421 accept `.L+4' as the target of a branch. (We can't just
2422 wait until the next instruction is output; it might be a
2423 macro and take up more than four bytes. Once again, we see
2424 why we want to eliminate macros.)
2425
2426 If the branch is annulled, we jump four more bytes that we
2427 would otherwise; that way we skip the annulled instruction
2428 in the delay slot. */
2429
2430 const char *target
2431 = ((iq2000_branch_likely || length == 16) ? ".+16" : ".+12");
2432 char *c;
2433
2434 c = strchr (buffer, '\0');
2435 /* Generate the reversed comparison. This takes four
2436 bytes. */
2437 if (float_p)
2438 sprintf (c, "b%s\t%%Z2%s",
2439 inverted_p ? comp : inverted_comp,
2440 target);
2441 else
2442 sprintf (c, "b%s%s\t%s%s,%s",
2443 inverted_p ? comp : inverted_comp,
2444 need_z_p ? "z" : "",
2445 op1,
2446 op2,
2447 target);
2448 strcat (c, "\n\tnop\n\tj\t%1");
2449 if (length == 16)
2450 /* The delay slot was unfilled. Since we're inside
2451 .noreorder, the assembler will not fill in the NOP for
2452 us, so we must do it ourselves. */
2453 strcat (buffer, "\n\tnop");
2454 return buffer;
2455 }
2456
2457 default:
2458 gcc_unreachable ();
2459 }
2460
2461 /* NOTREACHED */
2462 return 0;
2463 }
2464
2465 #define def_builtin(NAME, TYPE, CODE) \
2466 add_builtin_function ((NAME), (TYPE), (CODE), BUILT_IN_MD, \
2467 NULL, NULL_TREE)
2468
2469 static void
2470 iq2000_init_builtins (void)
2471 {
2472 tree void_ftype, void_ftype_int, void_ftype_int_int;
2473 tree void_ftype_int_int_int;
2474 tree int_ftype_int, int_ftype_int_int, int_ftype_int_int_int;
2475 tree int_ftype_int_int_int_int;
2476
2477 /* func () */
2478 void_ftype
2479 = build_function_type_list (void_type_node, NULL_TREE);
2480
2481 /* func (int) */
2482 void_ftype_int
2483 = build_function_type_list (void_type_node, integer_type_node, NULL_TREE);
2484
2485 /* void func (int, int) */
2486 void_ftype_int_int
2487 = build_function_type_list (void_type_node,
2488 integer_type_node,
2489 integer_type_node,
2490 NULL_TREE);
2491
2492 /* int func (int) */
2493 int_ftype_int
2494 = build_function_type_list (integer_type_node,
2495 integer_type_node, NULL_TREE);
2496
2497 /* int func (int, int) */
2498 int_ftype_int_int
2499 = build_function_type_list (integer_type_node,
2500 integer_type_node,
2501 integer_type_node,
2502 NULL_TREE);
2503
2504 /* void func (int, int, int) */
2505 void_ftype_int_int_int
2506 = build_function_type_list (void_type_node,
2507 integer_type_node,
2508 integer_type_node,
2509 integer_type_node,
2510 NULL_TREE);
2511
2512 /* int func (int, int, int) */
2513 int_ftype_int_int_int
2514 = build_function_type_list (integer_type_node,
2515 integer_type_node,
2516 integer_type_node,
2517 integer_type_node,
2518 NULL_TREE);
2519
2520 /* int func (int, int, int, int) */
2521 int_ftype_int_int_int_int
2522 = build_function_type_list (integer_type_node,
2523 integer_type_node,
2524 integer_type_node,
2525 integer_type_node,
2526 integer_type_node,
2527 NULL_TREE);
2528
2529 def_builtin ("__builtin_ado16", int_ftype_int_int, IQ2000_BUILTIN_ADO16);
2530 def_builtin ("__builtin_ram", int_ftype_int_int_int_int, IQ2000_BUILTIN_RAM);
2531 def_builtin ("__builtin_chkhdr", void_ftype_int_int, IQ2000_BUILTIN_CHKHDR);
2532 def_builtin ("__builtin_pkrl", void_ftype_int_int, IQ2000_BUILTIN_PKRL);
2533 def_builtin ("__builtin_cfc0", int_ftype_int, IQ2000_BUILTIN_CFC0);
2534 def_builtin ("__builtin_cfc1", int_ftype_int, IQ2000_BUILTIN_CFC1);
2535 def_builtin ("__builtin_cfc2", int_ftype_int, IQ2000_BUILTIN_CFC2);
2536 def_builtin ("__builtin_cfc3", int_ftype_int, IQ2000_BUILTIN_CFC3);
2537 def_builtin ("__builtin_ctc0", void_ftype_int_int, IQ2000_BUILTIN_CTC0);
2538 def_builtin ("__builtin_ctc1", void_ftype_int_int, IQ2000_BUILTIN_CTC1);
2539 def_builtin ("__builtin_ctc2", void_ftype_int_int, IQ2000_BUILTIN_CTC2);
2540 def_builtin ("__builtin_ctc3", void_ftype_int_int, IQ2000_BUILTIN_CTC3);
2541 def_builtin ("__builtin_mfc0", int_ftype_int, IQ2000_BUILTIN_MFC0);
2542 def_builtin ("__builtin_mfc1", int_ftype_int, IQ2000_BUILTIN_MFC1);
2543 def_builtin ("__builtin_mfc2", int_ftype_int, IQ2000_BUILTIN_MFC2);
2544 def_builtin ("__builtin_mfc3", int_ftype_int, IQ2000_BUILTIN_MFC3);
2545 def_builtin ("__builtin_mtc0", void_ftype_int_int, IQ2000_BUILTIN_MTC0);
2546 def_builtin ("__builtin_mtc1", void_ftype_int_int, IQ2000_BUILTIN_MTC1);
2547 def_builtin ("__builtin_mtc2", void_ftype_int_int, IQ2000_BUILTIN_MTC2);
2548 def_builtin ("__builtin_mtc3", void_ftype_int_int, IQ2000_BUILTIN_MTC3);
2549 def_builtin ("__builtin_lur", void_ftype_int_int, IQ2000_BUILTIN_LUR);
2550 def_builtin ("__builtin_rb", void_ftype_int_int, IQ2000_BUILTIN_RB);
2551 def_builtin ("__builtin_rx", void_ftype_int_int, IQ2000_BUILTIN_RX);
2552 def_builtin ("__builtin_srrd", void_ftype_int, IQ2000_BUILTIN_SRRD);
2553 def_builtin ("__builtin_srwr", void_ftype_int_int, IQ2000_BUILTIN_SRWR);
2554 def_builtin ("__builtin_wb", void_ftype_int_int, IQ2000_BUILTIN_WB);
2555 def_builtin ("__builtin_wx", void_ftype_int_int, IQ2000_BUILTIN_WX);
2556 def_builtin ("__builtin_luc32l", void_ftype_int_int, IQ2000_BUILTIN_LUC32L);
2557 def_builtin ("__builtin_luc64", void_ftype_int_int, IQ2000_BUILTIN_LUC64);
2558 def_builtin ("__builtin_luc64l", void_ftype_int_int, IQ2000_BUILTIN_LUC64L);
2559 def_builtin ("__builtin_luk", void_ftype_int_int, IQ2000_BUILTIN_LUK);
2560 def_builtin ("__builtin_lulck", void_ftype_int, IQ2000_BUILTIN_LULCK);
2561 def_builtin ("__builtin_lum32", void_ftype_int_int, IQ2000_BUILTIN_LUM32);
2562 def_builtin ("__builtin_lum32l", void_ftype_int_int, IQ2000_BUILTIN_LUM32L);
2563 def_builtin ("__builtin_lum64", void_ftype_int_int, IQ2000_BUILTIN_LUM64);
2564 def_builtin ("__builtin_lum64l", void_ftype_int_int, IQ2000_BUILTIN_LUM64L);
2565 def_builtin ("__builtin_lurl", void_ftype_int_int, IQ2000_BUILTIN_LURL);
2566 def_builtin ("__builtin_mrgb", int_ftype_int_int_int, IQ2000_BUILTIN_MRGB);
2567 def_builtin ("__builtin_srrdl", void_ftype_int, IQ2000_BUILTIN_SRRDL);
2568 def_builtin ("__builtin_srulck", void_ftype_int, IQ2000_BUILTIN_SRULCK);
2569 def_builtin ("__builtin_srwru", void_ftype_int_int, IQ2000_BUILTIN_SRWRU);
2570 def_builtin ("__builtin_trapqfl", void_ftype, IQ2000_BUILTIN_TRAPQFL);
2571 def_builtin ("__builtin_trapqne", void_ftype, IQ2000_BUILTIN_TRAPQNE);
2572 def_builtin ("__builtin_traprel", void_ftype_int, IQ2000_BUILTIN_TRAPREL);
2573 def_builtin ("__builtin_wbu", void_ftype_int_int_int, IQ2000_BUILTIN_WBU);
2574 def_builtin ("__builtin_syscall", void_ftype, IQ2000_BUILTIN_SYSCALL);
2575 }
2576
2577 /* Builtin for ICODE having ARGCOUNT args in EXP where each arg
2578 has an rtx CODE. */
2579
2580 static rtx
2581 expand_one_builtin (enum insn_code icode, rtx target, tree exp,
2582 enum rtx_code *code, int argcount)
2583 {
2584 rtx pat;
2585 tree arg [5];
2586 rtx op [5];
2587 enum machine_mode mode [5];
2588 int i;
2589
2590 mode[0] = insn_data[icode].operand[0].mode;
2591 for (i = 0; i < argcount; i++)
2592 {
2593 arg[i] = CALL_EXPR_ARG (exp, i);
2594 op[i] = expand_normal (arg[i]);
2595 mode[i] = insn_data[icode].operand[i].mode;
2596 if (code[i] == CONST_INT && GET_CODE (op[i]) != CONST_INT)
2597 error ("argument %qd is not a constant", i + 1);
2598 if (code[i] == REG
2599 && ! (*insn_data[icode].operand[i].predicate) (op[i], mode[i]))
2600 op[i] = copy_to_mode_reg (mode[i], op[i]);
2601 }
2602
2603 if (insn_data[icode].operand[0].constraint[0] == '=')
2604 {
2605 if (target == 0
2606 || GET_MODE (target) != mode[0]
2607 || ! (*insn_data[icode].operand[0].predicate) (target, mode[0]))
2608 target = gen_reg_rtx (mode[0]);
2609 }
2610 else
2611 target = 0;
2612
2613 switch (argcount)
2614 {
2615 case 0:
2616 pat = GEN_FCN (icode) (target);
2617 case 1:
2618 if (target)
2619 pat = GEN_FCN (icode) (target, op[0]);
2620 else
2621 pat = GEN_FCN (icode) (op[0]);
2622 break;
2623 case 2:
2624 if (target)
2625 pat = GEN_FCN (icode) (target, op[0], op[1]);
2626 else
2627 pat = GEN_FCN (icode) (op[0], op[1]);
2628 break;
2629 case 3:
2630 if (target)
2631 pat = GEN_FCN (icode) (target, op[0], op[1], op[2]);
2632 else
2633 pat = GEN_FCN (icode) (op[0], op[1], op[2]);
2634 break;
2635 case 4:
2636 if (target)
2637 pat = GEN_FCN (icode) (target, op[0], op[1], op[2], op[3]);
2638 else
2639 pat = GEN_FCN (icode) (op[0], op[1], op[2], op[3]);
2640 break;
2641 default:
2642 gcc_unreachable ();
2643 }
2644
2645 if (! pat)
2646 return 0;
2647 emit_insn (pat);
2648 return target;
2649 }
2650
2651 /* Expand an expression EXP that calls a built-in function,
2652 with result going to TARGET if that's convenient
2653 (and in mode MODE if that's convenient).
2654 SUBTARGET may be used as the target for computing one of EXP's operands.
2655 IGNORE is nonzero if the value is to be ignored. */
2656
2657 static rtx
2658 iq2000_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED,
2659 enum machine_mode mode ATTRIBUTE_UNUSED,
2660 int ignore ATTRIBUTE_UNUSED)
2661 {
2662 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
2663 int fcode = DECL_FUNCTION_CODE (fndecl);
2664 enum rtx_code code [5];
2665
2666 code[0] = REG;
2667 code[1] = REG;
2668 code[2] = REG;
2669 code[3] = REG;
2670 code[4] = REG;
2671 switch (fcode)
2672 {
2673 default:
2674 break;
2675
2676 case IQ2000_BUILTIN_ADO16:
2677 return expand_one_builtin (CODE_FOR_ado16, target, exp, code, 2);
2678
2679 case IQ2000_BUILTIN_RAM:
2680 code[1] = CONST_INT;
2681 code[2] = CONST_INT;
2682 code[3] = CONST_INT;
2683 return expand_one_builtin (CODE_FOR_ram, target, exp, code, 4);
2684
2685 case IQ2000_BUILTIN_CHKHDR:
2686 return expand_one_builtin (CODE_FOR_chkhdr, target, exp, code, 2);
2687
2688 case IQ2000_BUILTIN_PKRL:
2689 return expand_one_builtin (CODE_FOR_pkrl, target, exp, code, 2);
2690
2691 case IQ2000_BUILTIN_CFC0:
2692 code[0] = CONST_INT;
2693 return expand_one_builtin (CODE_FOR_cfc0, target, exp, code, 1);
2694
2695 case IQ2000_BUILTIN_CFC1:
2696 code[0] = CONST_INT;
2697 return expand_one_builtin (CODE_FOR_cfc1, target, exp, code, 1);
2698
2699 case IQ2000_BUILTIN_CFC2:
2700 code[0] = CONST_INT;
2701 return expand_one_builtin (CODE_FOR_cfc2, target, exp, code, 1);
2702
2703 case IQ2000_BUILTIN_CFC3:
2704 code[0] = CONST_INT;
2705 return expand_one_builtin (CODE_FOR_cfc3, target, exp, code, 1);
2706
2707 case IQ2000_BUILTIN_CTC0:
2708 code[1] = CONST_INT;
2709 return expand_one_builtin (CODE_FOR_ctc0, target, exp, code, 2);
2710
2711 case IQ2000_BUILTIN_CTC1:
2712 code[1] = CONST_INT;
2713 return expand_one_builtin (CODE_FOR_ctc1, target, exp, code, 2);
2714
2715 case IQ2000_BUILTIN_CTC2:
2716 code[1] = CONST_INT;
2717 return expand_one_builtin (CODE_FOR_ctc2, target, exp, code, 2);
2718
2719 case IQ2000_BUILTIN_CTC3:
2720 code[1] = CONST_INT;
2721 return expand_one_builtin (CODE_FOR_ctc3, target, exp, code, 2);
2722
2723 case IQ2000_BUILTIN_MFC0:
2724 code[0] = CONST_INT;
2725 return expand_one_builtin (CODE_FOR_mfc0, target, exp, code, 1);
2726
2727 case IQ2000_BUILTIN_MFC1:
2728 code[0] = CONST_INT;
2729 return expand_one_builtin (CODE_FOR_mfc1, target, exp, code, 1);
2730
2731 case IQ2000_BUILTIN_MFC2:
2732 code[0] = CONST_INT;
2733 return expand_one_builtin (CODE_FOR_mfc2, target, exp, code, 1);
2734
2735 case IQ2000_BUILTIN_MFC3:
2736 code[0] = CONST_INT;
2737 return expand_one_builtin (CODE_FOR_mfc3, target, exp, code, 1);
2738
2739 case IQ2000_BUILTIN_MTC0:
2740 code[1] = CONST_INT;
2741 return expand_one_builtin (CODE_FOR_mtc0, target, exp, code, 2);
2742
2743 case IQ2000_BUILTIN_MTC1:
2744 code[1] = CONST_INT;
2745 return expand_one_builtin (CODE_FOR_mtc1, target, exp, code, 2);
2746
2747 case IQ2000_BUILTIN_MTC2:
2748 code[1] = CONST_INT;
2749 return expand_one_builtin (CODE_FOR_mtc2, target, exp, code, 2);
2750
2751 case IQ2000_BUILTIN_MTC3:
2752 code[1] = CONST_INT;
2753 return expand_one_builtin (CODE_FOR_mtc3, target, exp, code, 2);
2754
2755 case IQ2000_BUILTIN_LUR:
2756 return expand_one_builtin (CODE_FOR_lur, target, exp, code, 2);
2757
2758 case IQ2000_BUILTIN_RB:
2759 return expand_one_builtin (CODE_FOR_rb, target, exp, code, 2);
2760
2761 case IQ2000_BUILTIN_RX:
2762 return expand_one_builtin (CODE_FOR_rx, target, exp, code, 2);
2763
2764 case IQ2000_BUILTIN_SRRD:
2765 return expand_one_builtin (CODE_FOR_srrd, target, exp, code, 1);
2766
2767 case IQ2000_BUILTIN_SRWR:
2768 return expand_one_builtin (CODE_FOR_srwr, target, exp, code, 2);
2769
2770 case IQ2000_BUILTIN_WB:
2771 return expand_one_builtin (CODE_FOR_wb, target, exp, code, 2);
2772
2773 case IQ2000_BUILTIN_WX:
2774 return expand_one_builtin (CODE_FOR_wx, target, exp, code, 2);
2775
2776 case IQ2000_BUILTIN_LUC32L:
2777 return expand_one_builtin (CODE_FOR_luc32l, target, exp, code, 2);
2778
2779 case IQ2000_BUILTIN_LUC64:
2780 return expand_one_builtin (CODE_FOR_luc64, target, exp, code, 2);
2781
2782 case IQ2000_BUILTIN_LUC64L:
2783 return expand_one_builtin (CODE_FOR_luc64l, target, exp, code, 2);
2784
2785 case IQ2000_BUILTIN_LUK:
2786 return expand_one_builtin (CODE_FOR_luk, target, exp, code, 2);
2787
2788 case IQ2000_BUILTIN_LULCK:
2789 return expand_one_builtin (CODE_FOR_lulck, target, exp, code, 1);
2790
2791 case IQ2000_BUILTIN_LUM32:
2792 return expand_one_builtin (CODE_FOR_lum32, target, exp, code, 2);
2793
2794 case IQ2000_BUILTIN_LUM32L:
2795 return expand_one_builtin (CODE_FOR_lum32l, target, exp, code, 2);
2796
2797 case IQ2000_BUILTIN_LUM64:
2798 return expand_one_builtin (CODE_FOR_lum64, target, exp, code, 2);
2799
2800 case IQ2000_BUILTIN_LUM64L:
2801 return expand_one_builtin (CODE_FOR_lum64l, target, exp, code, 2);
2802
2803 case IQ2000_BUILTIN_LURL:
2804 return expand_one_builtin (CODE_FOR_lurl, target, exp, code, 2);
2805
2806 case IQ2000_BUILTIN_MRGB:
2807 code[2] = CONST_INT;
2808 return expand_one_builtin (CODE_FOR_mrgb, target, exp, code, 3);
2809
2810 case IQ2000_BUILTIN_SRRDL:
2811 return expand_one_builtin (CODE_FOR_srrdl, target, exp, code, 1);
2812
2813 case IQ2000_BUILTIN_SRULCK:
2814 return expand_one_builtin (CODE_FOR_srulck, target, exp, code, 1);
2815
2816 case IQ2000_BUILTIN_SRWRU:
2817 return expand_one_builtin (CODE_FOR_srwru, target, exp, code, 2);
2818
2819 case IQ2000_BUILTIN_TRAPQFL:
2820 return expand_one_builtin (CODE_FOR_trapqfl, target, exp, code, 0);
2821
2822 case IQ2000_BUILTIN_TRAPQNE:
2823 return expand_one_builtin (CODE_FOR_trapqne, target, exp, code, 0);
2824
2825 case IQ2000_BUILTIN_TRAPREL:
2826 return expand_one_builtin (CODE_FOR_traprel, target, exp, code, 1);
2827
2828 case IQ2000_BUILTIN_WBU:
2829 return expand_one_builtin (CODE_FOR_wbu, target, exp, code, 3);
2830
2831 case IQ2000_BUILTIN_SYSCALL:
2832 return expand_one_builtin (CODE_FOR_syscall, target, exp, code, 0);
2833 }
2834
2835 return NULL_RTX;
2836 }
2837 \f
2838 /* Worker function for TARGET_RETURN_IN_MEMORY. */
2839
2840 static bool
2841 iq2000_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED)
2842 {
2843 return ((int_size_in_bytes (type) > (2 * UNITS_PER_WORD))
2844 || (int_size_in_bytes (type) == -1));
2845 }
2846
2847 /* Worker function for TARGET_SETUP_INCOMING_VARARGS. */
2848
2849 static void
2850 iq2000_setup_incoming_varargs (cumulative_args_t cum_v,
2851 enum machine_mode mode ATTRIBUTE_UNUSED,
2852 tree type ATTRIBUTE_UNUSED, int * pretend_size,
2853 int no_rtl)
2854 {
2855 CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
2856 unsigned int iq2000_off = ! cum->last_arg_fp;
2857 unsigned int iq2000_fp_off = cum->last_arg_fp;
2858
2859 if ((cum->arg_words < MAX_ARGS_IN_REGISTERS - iq2000_off))
2860 {
2861 int iq2000_save_gp_regs
2862 = MAX_ARGS_IN_REGISTERS - cum->arg_words - iq2000_off;
2863 int iq2000_save_fp_regs
2864 = (MAX_ARGS_IN_REGISTERS - cum->fp_arg_words - iq2000_fp_off);
2865
2866 if (iq2000_save_gp_regs < 0)
2867 iq2000_save_gp_regs = 0;
2868 if (iq2000_save_fp_regs < 0)
2869 iq2000_save_fp_regs = 0;
2870
2871 *pretend_size = ((iq2000_save_gp_regs * UNITS_PER_WORD)
2872 + (iq2000_save_fp_regs * UNITS_PER_FPREG));
2873
2874 if (! (no_rtl))
2875 {
2876 if (cum->arg_words < MAX_ARGS_IN_REGISTERS - iq2000_off)
2877 {
2878 rtx ptr, mem;
2879 ptr = plus_constant (Pmode, virtual_incoming_args_rtx,
2880 - (iq2000_save_gp_regs
2881 * UNITS_PER_WORD));
2882 mem = gen_rtx_MEM (BLKmode, ptr);
2883 move_block_from_reg
2884 (cum->arg_words + GP_ARG_FIRST + iq2000_off,
2885 mem,
2886 iq2000_save_gp_regs);
2887 }
2888 }
2889 }
2890 }
2891 \f
2892 /* A C compound statement to output to stdio stream STREAM the
2893 assembler syntax for an instruction operand that is a memory
2894 reference whose address is ADDR. ADDR is an RTL expression. */
2895
2896 static void
2897 iq2000_print_operand_address (FILE * file, rtx addr)
2898 {
2899 if (!addr)
2900 error ("PRINT_OPERAND_ADDRESS, null pointer");
2901
2902 else
2903 switch (GET_CODE (addr))
2904 {
2905 case REG:
2906 if (REGNO (addr) == ARG_POINTER_REGNUM)
2907 abort_with_insn (addr, "Arg pointer not eliminated.");
2908
2909 fprintf (file, "0(%s)", reg_names [REGNO (addr)]);
2910 break;
2911
2912 case LO_SUM:
2913 {
2914 rtx arg0 = XEXP (addr, 0);
2915 rtx arg1 = XEXP (addr, 1);
2916
2917 if (GET_CODE (arg0) != REG)
2918 abort_with_insn (addr,
2919 "PRINT_OPERAND_ADDRESS, LO_SUM with #1 not REG.");
2920
2921 fprintf (file, "%%lo(");
2922 iq2000_print_operand_address (file, arg1);
2923 fprintf (file, ")(%s)", reg_names [REGNO (arg0)]);
2924 }
2925 break;
2926
2927 case PLUS:
2928 {
2929 rtx reg = 0;
2930 rtx offset = 0;
2931 rtx arg0 = XEXP (addr, 0);
2932 rtx arg1 = XEXP (addr, 1);
2933
2934 if (GET_CODE (arg0) == REG)
2935 {
2936 reg = arg0;
2937 offset = arg1;
2938 if (GET_CODE (offset) == REG)
2939 abort_with_insn (addr, "PRINT_OPERAND_ADDRESS, 2 regs");
2940 }
2941
2942 else if (GET_CODE (arg1) == REG)
2943 reg = arg1, offset = arg0;
2944 else if (CONSTANT_P (arg0) && CONSTANT_P (arg1))
2945 {
2946 output_addr_const (file, addr);
2947 break;
2948 }
2949 else
2950 abort_with_insn (addr, "PRINT_OPERAND_ADDRESS, no regs");
2951
2952 if (! CONSTANT_P (offset))
2953 abort_with_insn (addr, "PRINT_OPERAND_ADDRESS, invalid insn #2");
2954
2955 if (REGNO (reg) == ARG_POINTER_REGNUM)
2956 abort_with_insn (addr, "Arg pointer not eliminated.");
2957
2958 output_addr_const (file, offset);
2959 fprintf (file, "(%s)", reg_names [REGNO (reg)]);
2960 }
2961 break;
2962
2963 case LABEL_REF:
2964 case SYMBOL_REF:
2965 case CONST_INT:
2966 case CONST:
2967 output_addr_const (file, addr);
2968 if (GET_CODE (addr) == CONST_INT)
2969 fprintf (file, "(%s)", reg_names [0]);
2970 break;
2971
2972 default:
2973 abort_with_insn (addr, "PRINT_OPERAND_ADDRESS, invalid insn #1");
2974 break;
2975 }
2976 }
2977 \f
2978 /* A C compound statement to output to stdio stream FILE the
2979 assembler syntax for an instruction operand OP.
2980
2981 LETTER is a value that can be used to specify one of several ways
2982 of printing the operand. It is used when identical operands
2983 must be printed differently depending on the context. LETTER
2984 comes from the `%' specification that was used to request
2985 printing of the operand. If the specification was just `%DIGIT'
2986 then LETTER is 0; if the specification was `%LTR DIGIT' then LETTER
2987 is the ASCII code for LTR.
2988
2989 If OP is a register, this macro should print the register's name.
2990 The names can be found in an array `reg_names' whose type is
2991 `char *[]'. `reg_names' is initialized from `REGISTER_NAMES'.
2992
2993 When the machine description has a specification `%PUNCT' (a `%'
2994 followed by a punctuation character), this macro is called with
2995 a null pointer for X and the punctuation character for LETTER.
2996
2997 The IQ2000 specific codes are:
2998
2999 'X' X is CONST_INT, prints upper 16 bits in hexadecimal format = "0x%04x",
3000 'x' X is CONST_INT, prints lower 16 bits in hexadecimal format = "0x%04x",
3001 'd' output integer constant in decimal,
3002 'z' if the operand is 0, use $0 instead of normal operand.
3003 'D' print second part of double-word register or memory operand.
3004 'L' print low-order register of double-word register operand.
3005 'M' print high-order register of double-word register operand.
3006 'C' print part of opcode for a branch condition.
3007 'F' print part of opcode for a floating-point branch condition.
3008 'N' print part of opcode for a branch condition, inverted.
3009 'W' print part of opcode for a floating-point branch condition, inverted.
3010 'A' Print part of opcode for a bit test condition.
3011 'P' Print label for a bit test.
3012 'p' Print log for a bit test.
3013 'B' print 'z' for EQ, 'n' for NE
3014 'b' print 'n' for EQ, 'z' for NE
3015 'T' print 'f' for EQ, 't' for NE
3016 't' print 't' for EQ, 'f' for NE
3017 'Z' print register and a comma, but print nothing for $fcc0
3018 '?' Print 'l' if we are to use a branch likely instead of normal branch.
3019 '@' Print the name of the assembler temporary register (at or $1).
3020 '.' Print the name of the register with a hard-wired zero (zero or $0).
3021 '$' Print the name of the stack pointer register (sp or $29).
3022 '+' Print the name of the gp register (gp or $28). */
3023
3024 static void
3025 iq2000_print_operand (FILE *file, rtx op, int letter)
3026 {
3027 enum rtx_code code;
3028
3029 if (iq2000_print_operand_punct_valid_p (letter))
3030 {
3031 switch (letter)
3032 {
3033 case '?':
3034 if (iq2000_branch_likely)
3035 putc ('l', file);
3036 break;
3037
3038 case '@':
3039 fputs (reg_names [GP_REG_FIRST + 1], file);
3040 break;
3041
3042 case '.':
3043 fputs (reg_names [GP_REG_FIRST + 0], file);
3044 break;
3045
3046 case '$':
3047 fputs (reg_names[STACK_POINTER_REGNUM], file);
3048 break;
3049
3050 case '+':
3051 fputs (reg_names[GP_REG_FIRST + 28], file);
3052 break;
3053
3054 default:
3055 error ("PRINT_OPERAND: Unknown punctuation '%c'", letter);
3056 break;
3057 }
3058
3059 return;
3060 }
3061
3062 if (! op)
3063 {
3064 error ("PRINT_OPERAND null pointer");
3065 return;
3066 }
3067
3068 code = GET_CODE (op);
3069
3070 if (code == SIGN_EXTEND)
3071 op = XEXP (op, 0), code = GET_CODE (op);
3072
3073 if (letter == 'C')
3074 switch (code)
3075 {
3076 case EQ: fputs ("eq", file); break;
3077 case NE: fputs ("ne", file); break;
3078 case GT: fputs ("gt", file); break;
3079 case GE: fputs ("ge", file); break;
3080 case LT: fputs ("lt", file); break;
3081 case LE: fputs ("le", file); break;
3082 case GTU: fputs ("ne", file); break;
3083 case GEU: fputs ("geu", file); break;
3084 case LTU: fputs ("ltu", file); break;
3085 case LEU: fputs ("eq", file); break;
3086 default:
3087 abort_with_insn (op, "PRINT_OPERAND, invalid insn for %%C");
3088 }
3089
3090 else if (letter == 'N')
3091 switch (code)
3092 {
3093 case EQ: fputs ("ne", file); break;
3094 case NE: fputs ("eq", file); break;
3095 case GT: fputs ("le", file); break;
3096 case GE: fputs ("lt", file); break;
3097 case LT: fputs ("ge", file); break;
3098 case LE: fputs ("gt", file); break;
3099 case GTU: fputs ("leu", file); break;
3100 case GEU: fputs ("ltu", file); break;
3101 case LTU: fputs ("geu", file); break;
3102 case LEU: fputs ("gtu", file); break;
3103 default:
3104 abort_with_insn (op, "PRINT_OPERAND, invalid insn for %%N");
3105 }
3106
3107 else if (letter == 'F')
3108 switch (code)
3109 {
3110 case EQ: fputs ("c1f", file); break;
3111 case NE: fputs ("c1t", file); break;
3112 default:
3113 abort_with_insn (op, "PRINT_OPERAND, invalid insn for %%F");
3114 }
3115
3116 else if (letter == 'W')
3117 switch (code)
3118 {
3119 case EQ: fputs ("c1t", file); break;
3120 case NE: fputs ("c1f", file); break;
3121 default:
3122 abort_with_insn (op, "PRINT_OPERAND, invalid insn for %%W");
3123 }
3124
3125 else if (letter == 'A')
3126 fputs (code == LABEL_REF ? "i" : "in", file);
3127
3128 else if (letter == 'P')
3129 {
3130 if (code == LABEL_REF)
3131 output_addr_const (file, op);
3132 else if (code != PC)
3133 output_operand_lossage ("invalid %%P operand");
3134 }
3135
3136 else if (letter == 'p')
3137 {
3138 int value;
3139 if (code != CONST_INT
3140 || (value = exact_log2 (INTVAL (op))) < 0)
3141 output_operand_lossage ("invalid %%p value");
3142 else
3143 fprintf (file, "%d", value);
3144 }
3145
3146 else if (letter == 'Z')
3147 {
3148 gcc_unreachable ();
3149 }
3150
3151 else if (code == REG || code == SUBREG)
3152 {
3153 int regnum;
3154
3155 if (code == REG)
3156 regnum = REGNO (op);
3157 else
3158 regnum = true_regnum (op);
3159
3160 if ((letter == 'M' && ! WORDS_BIG_ENDIAN)
3161 || (letter == 'L' && WORDS_BIG_ENDIAN)
3162 || letter == 'D')
3163 regnum++;
3164
3165 fprintf (file, "%s", reg_names[regnum]);
3166 }
3167
3168 else if (code == MEM)
3169 {
3170 if (letter == 'D')
3171 output_address (plus_constant (Pmode, XEXP (op, 0), 4));
3172 else
3173 output_address (XEXP (op, 0));
3174 }
3175
3176 else if (code == CONST_DOUBLE
3177 && GET_MODE_CLASS (GET_MODE (op)) == MODE_FLOAT)
3178 {
3179 char s[60];
3180
3181 real_to_decimal (s, CONST_DOUBLE_REAL_VALUE (op), sizeof (s), 0, 1);
3182 fputs (s, file);
3183 }
3184
3185 else if (letter == 'x' && GET_CODE (op) == CONST_INT)
3186 fprintf (file, HOST_WIDE_INT_PRINT_HEX, 0xffff & INTVAL(op));
3187
3188 else if (letter == 'X' && GET_CODE(op) == CONST_INT)
3189 fprintf (file, HOST_WIDE_INT_PRINT_HEX, 0xffff & (INTVAL (op) >> 16));
3190
3191 else if (letter == 'd' && GET_CODE(op) == CONST_INT)
3192 fprintf (file, HOST_WIDE_INT_PRINT_DEC, (INTVAL(op)));
3193
3194 else if (letter == 'z' && GET_CODE (op) == CONST_INT && INTVAL (op) == 0)
3195 fputs (reg_names[GP_REG_FIRST], file);
3196
3197 else if (letter == 'd' || letter == 'x' || letter == 'X')
3198 output_operand_lossage ("invalid use of %%d, %%x, or %%X");
3199
3200 else if (letter == 'B')
3201 fputs (code == EQ ? "z" : "n", file);
3202 else if (letter == 'b')
3203 fputs (code == EQ ? "n" : "z", file);
3204 else if (letter == 'T')
3205 fputs (code == EQ ? "f" : "t", file);
3206 else if (letter == 't')
3207 fputs (code == EQ ? "t" : "f", file);
3208
3209 else if (code == CONST && GET_CODE (XEXP (op, 0)) == REG)
3210 {
3211 iq2000_print_operand (file, XEXP (op, 0), letter);
3212 }
3213
3214 else
3215 output_addr_const (file, op);
3216 }
3217
3218 static bool
3219 iq2000_print_operand_punct_valid_p (unsigned char code)
3220 {
3221 return iq2000_print_operand_punct[code];
3222 }
3223
3224 /* For the IQ2000, transform:
3225
3226 memory(X + <large int>)
3227 into:
3228 Y = <large int> & ~0x7fff;
3229 Z = X + Y
3230 memory (Z + (<large int> & 0x7fff));
3231 */
3232
3233 rtx
3234 iq2000_legitimize_address (rtx xinsn, rtx old_x ATTRIBUTE_UNUSED,
3235 enum machine_mode mode)
3236 {
3237 if (TARGET_DEBUG_B_MODE)
3238 {
3239 GO_PRINTF ("\n========== LEGITIMIZE_ADDRESS\n");
3240 GO_DEBUG_RTX (xinsn);
3241 }
3242
3243 if (iq2000_check_split (xinsn, mode))
3244 {
3245 return gen_rtx_LO_SUM (Pmode,
3246 copy_to_mode_reg (Pmode,
3247 gen_rtx_HIGH (Pmode, xinsn)),
3248 xinsn);
3249 }
3250
3251 if (GET_CODE (xinsn) == PLUS)
3252 {
3253 rtx xplus0 = XEXP (xinsn, 0);
3254 rtx xplus1 = XEXP (xinsn, 1);
3255 enum rtx_code code0 = GET_CODE (xplus0);
3256 enum rtx_code code1 = GET_CODE (xplus1);
3257
3258 if (code0 != REG && code1 == REG)
3259 {
3260 xplus0 = XEXP (xinsn, 1);
3261 xplus1 = XEXP (xinsn, 0);
3262 code0 = GET_CODE (xplus0);
3263 code1 = GET_CODE (xplus1);
3264 }
3265
3266 if (code0 == REG && REG_MODE_OK_FOR_BASE_P (xplus0, mode)
3267 && code1 == CONST_INT && !SMALL_INT (xplus1))
3268 {
3269 rtx int_reg = gen_reg_rtx (Pmode);
3270 rtx ptr_reg = gen_reg_rtx (Pmode);
3271
3272 emit_move_insn (int_reg,
3273 GEN_INT (INTVAL (xplus1) & ~ 0x7fff));
3274
3275 emit_insn (gen_rtx_SET (VOIDmode,
3276 ptr_reg,
3277 gen_rtx_PLUS (Pmode, xplus0, int_reg)));
3278
3279 return plus_constant (Pmode, ptr_reg, INTVAL (xplus1) & 0x7fff);
3280 }
3281 }
3282
3283 if (TARGET_DEBUG_B_MODE)
3284 GO_PRINTF ("LEGITIMIZE_ADDRESS could not fix.\n");
3285
3286 return xinsn;
3287 }
3288
3289
3290 static bool
3291 iq2000_rtx_costs (rtx x, int code, int outer_code ATTRIBUTE_UNUSED,
3292 int opno ATTRIBUTE_UNUSED, int * total,
3293 bool speed ATTRIBUTE_UNUSED)
3294 {
3295 enum machine_mode mode = GET_MODE (x);
3296
3297 switch (code)
3298 {
3299 case MEM:
3300 {
3301 int num_words = (GET_MODE_SIZE (mode) > UNITS_PER_WORD) ? 2 : 1;
3302
3303 if (simple_memory_operand (x, mode))
3304 return COSTS_N_INSNS (num_words);
3305
3306 * total = COSTS_N_INSNS (2 * num_words);
3307 break;
3308 }
3309
3310 case FFS:
3311 * total = COSTS_N_INSNS (6);
3312 break;
3313
3314 case AND:
3315 case IOR:
3316 case XOR:
3317 case NOT:
3318 * total = COSTS_N_INSNS (mode == DImode ? 2 : 1);
3319 break;
3320
3321 case ASHIFT:
3322 case ASHIFTRT:
3323 case LSHIFTRT:
3324 if (mode == DImode)
3325 * total = COSTS_N_INSNS ((GET_CODE (XEXP (x, 1)) == CONST_INT) ? 4 : 12);
3326 else
3327 * total = COSTS_N_INSNS (1);
3328 break;
3329
3330 case ABS:
3331 if (mode == SFmode || mode == DFmode)
3332 * total = COSTS_N_INSNS (1);
3333 else
3334 * total = COSTS_N_INSNS (4);
3335 break;
3336
3337 case PLUS:
3338 case MINUS:
3339 if (mode == SFmode || mode == DFmode)
3340 * total = COSTS_N_INSNS (6);
3341 else if (mode == DImode)
3342 * total = COSTS_N_INSNS (4);
3343 else
3344 * total = COSTS_N_INSNS (1);
3345 break;
3346
3347 case NEG:
3348 * total = (mode == DImode) ? 4 : 1;
3349 break;
3350
3351 case MULT:
3352 if (mode == SFmode)
3353 * total = COSTS_N_INSNS (7);
3354 else if (mode == DFmode)
3355 * total = COSTS_N_INSNS (8);
3356 else
3357 * total = COSTS_N_INSNS (10);
3358 break;
3359
3360 case DIV:
3361 case MOD:
3362 if (mode == SFmode)
3363 * total = COSTS_N_INSNS (23);
3364 else if (mode == DFmode)
3365 * total = COSTS_N_INSNS (36);
3366 else
3367 * total = COSTS_N_INSNS (69);
3368 break;
3369
3370 case UDIV:
3371 case UMOD:
3372 * total = COSTS_N_INSNS (69);
3373 break;
3374
3375 case SIGN_EXTEND:
3376 * total = COSTS_N_INSNS (2);
3377 break;
3378
3379 case ZERO_EXTEND:
3380 * total = COSTS_N_INSNS (1);
3381 break;
3382
3383 case CONST_INT:
3384 * total = 0;
3385 break;
3386
3387 case LABEL_REF:
3388 * total = COSTS_N_INSNS (2);
3389 break;
3390
3391 case CONST:
3392 {
3393 rtx offset = const0_rtx;
3394 rtx symref = eliminate_constant_term (XEXP (x, 0), & offset);
3395
3396 if (GET_CODE (symref) == LABEL_REF)
3397 * total = COSTS_N_INSNS (2);
3398 else if (GET_CODE (symref) != SYMBOL_REF)
3399 * total = COSTS_N_INSNS (4);
3400 /* Let's be paranoid.... */
3401 else if (INTVAL (offset) < -32768 || INTVAL (offset) > 32767)
3402 * total = COSTS_N_INSNS (2);
3403 else
3404 * total = COSTS_N_INSNS (SYMBOL_REF_FLAG (symref) ? 1 : 2);
3405 break;
3406 }
3407
3408 case SYMBOL_REF:
3409 * total = COSTS_N_INSNS (SYMBOL_REF_FLAG (x) ? 1 : 2);
3410 break;
3411
3412 case CONST_DOUBLE:
3413 {
3414 rtx high, low;
3415
3416 split_double (x, & high, & low);
3417
3418 * total = COSTS_N_INSNS ( (high == CONST0_RTX (GET_MODE (high))
3419 || low == CONST0_RTX (GET_MODE (low)))
3420 ? 2 : 4);
3421 break;
3422 }
3423
3424 default:
3425 return false;
3426 }
3427 return true;
3428 }
3429
3430 /* Worker for TARGET_ASM_TRAMPOLINE_TEMPLATE. */
3431
3432 static void
3433 iq2000_asm_trampoline_template (FILE *f)
3434 {
3435 fprintf (f, "\t.word\t0x03e00821\t\t# move $1,$31\n");
3436 fprintf (f, "\t.word\t0x04110001\t\t# bgezal $0,.+8\n");
3437 fprintf (f, "\t.word\t0x00000000\t\t# nop\n");
3438 if (Pmode == DImode)
3439 {
3440 fprintf (f, "\t.word\t0xdfe30014\t\t# ld $3,20($31)\n");
3441 fprintf (f, "\t.word\t0xdfe2001c\t\t# ld $2,28($31)\n");
3442 }
3443 else
3444 {
3445 fprintf (f, "\t.word\t0x8fe30014\t\t# lw $3,20($31)\n");
3446 fprintf (f, "\t.word\t0x8fe20018\t\t# lw $2,24($31)\n");
3447 }
3448 fprintf (f, "\t.word\t0x0060c821\t\t# move $25,$3 (abicalls)\n");
3449 fprintf (f, "\t.word\t0x00600008\t\t# jr $3\n");
3450 fprintf (f, "\t.word\t0x0020f821\t\t# move $31,$1\n");
3451 fprintf (f, "\t.word\t0x00000000\t\t# <function address>\n");
3452 fprintf (f, "\t.word\t0x00000000\t\t# <static chain value>\n");
3453 }
3454
3455 /* Worker for TARGET_TRAMPOLINE_INIT. */
3456
3457 static void
3458 iq2000_trampoline_init (rtx m_tramp, tree fndecl, rtx chain_value)
3459 {
3460 rtx fnaddr = XEXP (DECL_RTL (fndecl), 0);
3461 rtx mem;
3462
3463 emit_block_move (m_tramp, assemble_trampoline_template (),
3464 GEN_INT (TRAMPOLINE_CODE_SIZE), BLOCK_OP_NORMAL);
3465
3466 mem = adjust_address (m_tramp, Pmode, TRAMPOLINE_CODE_SIZE);
3467 emit_move_insn (mem, fnaddr);
3468 mem = adjust_address (m_tramp, Pmode,
3469 TRAMPOLINE_CODE_SIZE + GET_MODE_SIZE (Pmode));
3470 emit_move_insn (mem, chain_value);
3471 }
3472
3473 #include "gt-iq2000.h"