OSDN Git Service

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