OSDN Git Service

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