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