OSDN Git Service

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