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