OSDN Git Service

* config/iq2000/iq2000.c: Follow spelling conventions.
[pf3gnuchains/gcc-fork.git] / gcc / config / iq2000 / iq2000.c
1 /* Subroutines used for code generation on Vitesse IQ2000 processors
2    Copyright (C) 2003 Free Software Foundation, Inc.
3
4 This file is part of GCC.
5
6 GCC is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
10
11 GCC is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with GCC; see the file COPYING.  If not, write to
18 the Free Software Foundation, 59 Temple Place - Suite 330,
19 Boston, 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
53 enum 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
67 struct constant;
68
69 static void iq2000_count_memory_refs (rtx, int);
70 static enum internal_test map_test_to_internal_test (enum rtx_code);
71 static rtx iq2000_add_large_offset_to_sp (HOST_WIDE_INT);
72 static void iq2000_annotate_frame_insn (rtx, rtx);
73 static void iq2000_emit_frame_related_store (rtx, rtx,
74                                              HOST_WIDE_INT);
75 static struct machine_function * iq2000_init_machine_status (void);
76 static void save_restore_insns (int);
77 static void abort_with_insn (rtx, const char *)
78      ATTRIBUTE_NORETURN;
79 static int symbolic_expression_p (rtx);
80 static enum processor_type iq2000_parse_cpu (const char *);
81 static void iq2000_select_rtx_section (enum machine_mode, rtx,
82                                        unsigned HOST_WIDE_INT);
83 static void iq2000_select_section (tree, int, unsigned HOST_WIDE_INT);
84 static rtx expand_one_builtin (enum insn_code, rtx, tree, enum rtx_code*,
85                                int);
86 \f
87 /* Structure to be filled in by compute_frame_size with register
88    save masks, and offsets for the current function.  */
89
90 struct 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
107 struct 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.  */
116 int 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.  */
121 FILE *asm_out_data_file;
122 FILE *asm_out_text_file;
123
124 /* The next branch instruction is a branch likely, not branch normal.  */
125 int iq2000_branch_likely;
126
127 /* Count of delay slots and how many are filled.  */
128 int dslots_load_total;
129 int dslots_load_filled;
130 int dslots_jump_total;
131 int dslots_jump_filled;
132
133 /* # of nops needed by previous insn */
134 int dslots_number_nops;
135
136 /* Number of 1/2/3 word references to data items (ie, not jal's).  */
137 int num_refs[3];
138
139 /* registers to check for load delay */
140 rtx 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.  */
144 rtx branch_cmp[2];
145
146 /* what type of branch to use */
147 enum cmp_type branch_type;
148
149 /* The target cpu for code generation.  */
150 enum processor_type iq2000_arch;
151
152 /* The target cpu for optimization and scheduling.  */
153 enum processor_type iq2000_tune;
154
155 /* which instruction set architecture to use.  */
156 int iq2000_isa;
157
158 /* Strings to hold which cpu and instruction set architecture to use.  */
159 const char *iq2000_cpu_string;  /* for -mcpu=<xxx> */
160 const char *iq2000_arch_string;   /* for -march=<xxx> */
161
162 /* Mode used for saving/restoring general purpose registers.  */
163 static enum machine_mode gpr_mode;
164
165 /* List of all IQ2000 punctuation characters used by print_operand.  */
166 char 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
178 struct 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
183 int
184 uns_arith_operand (rtx op, enum machine_mode mode)
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
194 int
195 arith_operand (rtx op, enum machine_mode mode)
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
205 int
206 small_int (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
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
214 int
215 large_int (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
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
241 int
242 reg_or_0_operand (rtx op, enum machine_mode mode)
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
266 int
267 simple_memory_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
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
318 int
319 equality_op (rtx op, enum machine_mode mode)
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
329 int
330 cmp_op (rtx op, enum machine_mode mode)
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
340 int
341 pc_or_label_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
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
354 int
355 call_insn_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
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
365 int
366 move_operand (rtx op, enum machine_mode mode)
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
378 int
379 power_of_2_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
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
393 int
394 iq2000_check_split (rtx address, enum machine_mode mode)
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
412 int
413 iq2000_reg_mode_ok_for_base_p (rtx reg,
414                                enum machine_mode mode ATTRIBUTE_UNUSED,
415                                int strict)
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
423    memory operand of the indicated MODE.  STRICT is nonzero if this
424    function is called during reload.  */
425
426 int
427 iq2000_legitimate_address_p (enum machine_mode mode, rtx xinsn, int strict)
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
503 const char *
504 iq2000_fill_delay_slot (const char *ret, enum delay_type type, rtx operands[],
505                         rtx cur_insn)
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
565 static void
566 iq2000_count_memory_refs (rtx op, int num)
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
677 const char *
678 iq2000_move_1word (rtx operands[], rtx insn, int unsignedp)
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
907 int
908 iq2000_address_cost (rtx addr)
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
974 static enum internal_test
975 map_test_to_internal_test (enum rtx_code test_code)
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.
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.  */
1006
1007 rtx
1008 gen_int_relational (enum rtx_code test_code, rtx result, rtx cmp0, rtx cmp1,
1009                     int *p_invert)
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
1172 void
1173 gen_conditional_branch (rtx operands[], enum rtx_code test_code)
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)
1198         /* We don't want to build a comparison against a nonzero
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
1244 void
1245 init_cumulative_args (CUMULATIVE_ARGS *cum, tree fntype,
1246                       rtx libname ATTRIBUTE_UNUSED)
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
1286 void
1287 function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode, tree type,
1288                       int named)
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
1351 struct rtx_def *
1352 function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode, tree type,
1353               int named)
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
1512 int
1513 function_arg_partial_nregs (CUMULATIVE_ARGS *cum, enum machine_mode mode,
1514                             tree type ATTRIBUTE_UNUSED,
1515                             int named ATTRIBUTE_UNUSED)
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
1531 void
1532 iq2000_va_start (tree valist, rtx nextarg)
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
1555 rtx
1556 iq2000_va_arg (tree valist, tree type)
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
1756 static void
1757 abort_with_insn (rtx insn, const char *reason)
1758 {
1759   error (reason);
1760   debug_rtx (insn);
1761   abort ();
1762 }
1763 \f
1764 /* Detect any conflicts in the switches.  */
1765
1766 void
1767 override_options (void)
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
1846 static struct machine_function *
1847 iq2000_init_machine_status (void)
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
1857 HOST_WIDE_INT
1858 iq2000_debugger_offset (rtx addr, HOST_WIDE_INT offset)
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
1892 void
1893 final_prescan_insn (rtx insn, rtx opvec[] ATTRIBUTE_UNUSED,
1894                     int noperands ATTRIBUTE_UNUSED)
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
1989 HOST_WIDE_INT
1990 compute_frame_size (HOST_WIDE_INT size)
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
2094 int
2095 iq2000_initial_elimination_offset (int from, int to ATTRIBUTE_UNUSED)
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
2131 static rtx
2132 iq2000_add_large_offset_to_sp (HOST_WIDE_INT offset)
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
2145 static void
2146 iq2000_annotate_frame_insn (rtx insn, rtx dwarf_pattern)
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
2157 static void
2158 iq2000_emit_frame_related_store (rtx mem, rtx reg, HOST_WIDE_INT offset)
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
2167 static void
2168 save_restore_insns (int store_p)
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
2249 void
2250 iq2000_expand_prologue (void)
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
2438 void
2439 iq2000_expand_epilogue (void)
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
2499 void
2500 iq2000_expand_eh_return (rtx address)
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
2513 int
2514 iq2000_can_use_return_insn (void)
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
2528 /* Returns nonzero if X contains a SYMBOL_REF.  */
2529
2530 static int
2531 symbolic_expression_p (rtx x)
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
2553 static void
2554 iq2000_select_rtx_section (enum machine_mode mode, rtx x ATTRIBUTE_UNUSED,
2555                            unsigned HOST_WIDE_INT align)
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
2571 static void
2572 iq2000_select_section (tree decl, int reloc ATTRIBUTE_UNUSED,
2573                        unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED)
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
2615 rtx
2616 iq2000_function_value (tree valtype, tree func ATTRIBUTE_UNUSED)
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
2632 int
2633 function_arg_pass_by_reference (CUMULATIVE_ARGS *cum ATTRIBUTE_UNUSED,
2634                                 enum machine_mode mode, tree type,
2635                                 int named ATTRIBUTE_UNUSED)
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
2664 int
2665 iq2000_adjust_insn_length (rtx insn, int length)
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
2682    nonzero the comparison takes two operands; OPERANDS[3] will be the
2683    second operand.
2684
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.
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
2692 char *
2693 iq2000_output_conditional_branch (rtx insn, rtx *operands, int two_operands_p,
2694                                   int float_p, int inverted_p, int length)
2695 {
2696   static char buffer[200];
2697   /* The kind of comparison we are doing.  */
2698   enum rtx_code code = GET_CODE (operands[0]);
2699   /* Nonzero if the opcode for the comparison needs a `z' indicating
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
2724          see if A is nonzero.  Thus, we change the CODE here to
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
2846 static enum processor_type
2847 iq2000_parse_cpu (const char *cpu_string)
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
2871 void
2872 iq2000_init_builtins (void)
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) */
2910 void_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
3004 static rtx
3005 expand_one_builtin (enum insn_code icode, rtx target, tree arglist,
3006                     enum rtx_code *code, int argcount)
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
3082 rtx
3083 iq2000_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED,
3084                        enum machine_mode mode ATTRIBUTE_UNUSED,
3085                        int ignore ATTRIBUTE_UNUSED)
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
3264 void
3265 iq2000_setup_incoming_varargs (CUMULATIVE_ARGS cum, int mode ATTRIBUTE_UNUSED,
3266                                tree type ATTRIBUTE_UNUSED, int *pretend_size,
3267                                int no_rtl) 
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
3309 void
3310 print_operand_address (FILE *file, rtx addr)
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
3438 void
3439 print_operand (FILE *file, rtx op, int letter)
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 }