OSDN Git Service

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