OSDN Git Service

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