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