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