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