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