OSDN Git Service

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