OSDN Git Service

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