OSDN Git Service

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