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