OSDN Git Service

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