OSDN Git Service

(iq2000_expand_epilogue): Use emit_jump_insn() to generate the return
[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 #include "langhooks.h"
49
50 /* Enumeration for all of the relational tests, so that we can build
51    arrays indexed by the test type, and not worry about the order
52    of EQ, NE, etc.  */
53
54 enum internal_test
55   {
56     ITEST_EQ,
57     ITEST_NE,
58     ITEST_GT,
59     ITEST_GE,
60     ITEST_LT,
61     ITEST_LE,
62     ITEST_GTU,
63     ITEST_GEU,
64     ITEST_LTU,
65     ITEST_LEU,
66     ITEST_MAX
67   };
68
69 struct constant;
70
71 \f
72 /* Structure to be filled in by compute_frame_size with register
73    save masks, and offsets for the current function.  */
74
75 struct iq2000_frame_info
76 {
77   long total_size;              /* # bytes that the entire frame takes up.  */
78   long var_size;                /* # bytes that variables take up.  */
79   long args_size;               /* # bytes that outgoing arguments take up.  */
80   long extra_size;              /* # bytes of extra gunk.  */
81   int  gp_reg_size;             /* # bytes needed to store gp regs.  */
82   int  fp_reg_size;             /* # bytes needed to store fp regs.  */
83   long mask;                    /* Mask of saved gp registers.  */
84   long gp_save_offset;          /* Offset from vfp to store gp registers.  */
85   long fp_save_offset;          /* Offset from vfp to store fp registers.  */
86   long gp_sp_offset;            /* Offset from new sp to store gp registers.  */
87   long fp_sp_offset;            /* Offset from new sp to store fp registers.  */
88   int  initialized;             /* != 0 if frame size already calculated.  */
89   int  num_gp;                  /* Number of gp registers saved.  */
90 } iq2000_frame_info;
91
92 struct machine_function GTY(())
93 {
94   /* Current frame information, calculated by compute_frame_size.  */
95   long total_size;              /* # bytes that the entire frame takes up.  */
96   long var_size;                /* # bytes that variables take up.  */
97   long args_size;               /* # bytes that outgoing arguments take up.  */
98   long extra_size;              /* # bytes of extra gunk.  */
99   int  gp_reg_size;             /* # bytes needed to store gp regs.  */
100   int  fp_reg_size;             /* # bytes needed to store fp regs.  */
101   long mask;                    /* Mask of saved gp registers.  */
102   long gp_save_offset;          /* Offset from vfp to store gp registers.  */
103   long fp_save_offset;          /* Offset from vfp to store fp registers.  */
104   long gp_sp_offset;            /* Offset from new sp to store gp registers.  */
105   long fp_sp_offset;            /* Offset from new sp to store fp registers.  */
106   int  initialized;             /* != 0 if frame size already calculated.  */
107   int  num_gp;                  /* Number of gp registers saved.  */
108 };
109
110 /* Global variables for machine-dependent things.  */
111
112 /* List of all IQ2000 punctuation characters used by print_operand.  */
113 char iq2000_print_operand_punct[256];
114
115 /* The target cpu for optimization and scheduling.  */
116 enum processor_type iq2000_tune;
117
118 /* Which instruction set architecture to use.  */
119 int iq2000_isa;
120
121 /* Cached operands, and operator to compare for use in set/branch/trap
122    on condition codes.  */
123 rtx branch_cmp[2];
124
125 /* What type of branch to use.  */
126 enum cmp_type branch_type;
127
128 /* Strings to hold which cpu and instruction set architecture to use.  */
129 const char * iq2000_cpu_string;   /* For -mcpu=<xxx>.  */
130 const char * iq2000_arch_string;  /* For -march=<xxx>.  */
131
132
133 /* Local variables.  */
134
135 /* The next branch instruction is a branch likely, not branch normal.  */
136 static int iq2000_branch_likely;
137
138 /* Count of delay slots and how many are filled.  */
139 static int dslots_load_total;
140 static int dslots_load_filled;
141 static int dslots_jump_total;
142
143 /* # of nops needed by previous insn.  */
144 static int dslots_number_nops;
145
146 /* Number of 1/2/3 word references to data items (i.e., not jal's).  */
147 static int num_refs[3];
148
149 /* Registers to check for load delay.  */
150 static rtx iq2000_load_reg;
151 static rtx iq2000_load_reg2;
152 static rtx iq2000_load_reg3;
153 static rtx iq2000_load_reg4;
154
155 /* The target cpu for code generation.  */
156 static enum processor_type iq2000_arch;
157
158 /* Mode used for saving/restoring general purpose registers.  */
159 static enum machine_mode gpr_mode;
160
161 \f
162 /* Initialize the GCC target structure.  */
163 static struct machine_function* iq2000_init_machine_status (void);
164 static void iq2000_select_rtx_section (enum machine_mode, rtx, unsigned HOST_WIDE_INT);
165 static void iq2000_init_builtins      (void);
166 static rtx  iq2000_expand_builtin     (tree, rtx, rtx, enum machine_mode, int);
167 static bool iq2000_return_in_memory   (tree, tree);
168 static void iq2000_setup_incoming_varargs (CUMULATIVE_ARGS *,
169                                            enum machine_mode, tree, int *,
170                                            int);
171 static bool iq2000_rtx_costs          (rtx, int, int, int *);
172 static int  iq2000_address_cost       (rtx);
173 static void iq2000_select_section     (tree, int, unsigned HOST_WIDE_INT);
174 static bool iq2000_return_in_memory   (tree, tree);
175 static bool iq2000_pass_by_reference  (CUMULATIVE_ARGS *, enum machine_mode,
176                                        tree, bool);
177
178 #undef  TARGET_INIT_BUILTINS
179 #define TARGET_INIT_BUILTINS            iq2000_init_builtins
180 #undef  TARGET_EXPAND_BUILTIN
181 #define TARGET_EXPAND_BUILTIN           iq2000_expand_builtin
182 #undef  TARGET_ASM_SELECT_RTX_SECTION
183 #define TARGET_ASM_SELECT_RTX_SECTION   iq2000_select_rtx_section
184 #undef  TARGET_RTX_COSTS
185 #define TARGET_RTX_COSTS                iq2000_rtx_costs
186 #undef  TARGET_ADDRESS_COST
187 #define TARGET_ADDRESS_COST             iq2000_address_cost
188 #undef  TARGET_ASM_SELECT_SECTION
189 #define TARGET_ASM_SELECT_SECTION       iq2000_select_section
190
191 #undef  TARGET_PROMOTE_FUNCTION_ARGS
192 #define TARGET_PROMOTE_FUNCTION_ARGS    hook_bool_tree_true
193 #undef  TARGET_PROMOTE_FUNCTION_RETURN
194 #define TARGET_PROMOTE_FUNCTION_RETURN  hook_bool_tree_true
195 #undef  TARGET_PROMOTE_PROTOTYPES
196 #define TARGET_PROMOTE_PROTOTYPES       hook_bool_tree_true
197
198 #undef  TARGET_RETURN_IN_MEMORY
199 #define TARGET_RETURN_IN_MEMORY         iq2000_return_in_memory
200 #undef  TARGET_PASS_BY_REFERENCE
201 #define TARGET_PASS_BY_REFERENCE        iq2000_pass_by_reference
202 #undef  TARGET_CALLEE_COPIES
203 #define TARGET_CALLEE_COPIES            hook_callee_copies_named
204
205 #undef  TARGET_SETUP_INCOMING_VARARGS
206 #define TARGET_SETUP_INCOMING_VARARGS   iq2000_setup_incoming_varargs
207 #undef  TARGET_STRICT_ARGUMENT_NAMING
208 #define TARGET_STRICT_ARGUMENT_NAMING   hook_bool_CUMULATIVE_ARGS_true
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    (i.e., 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           reg_rtx = gen_rtx_REG (gpr_mode, regno);
2090
2091           if (store_p)
2092             iq2000_emit_frame_related_store (mem_rtx, reg_rtx, gp_offset);
2093           else 
2094             {
2095               emit_move_insn (reg_rtx, mem_rtx);
2096             }
2097           gp_offset -= GET_MODE_SIZE (gpr_mode);
2098         }
2099     }
2100 }
2101 \f
2102 /* Expand the prologue into a bunch of separate insns.  */
2103
2104 void
2105 iq2000_expand_prologue (void)
2106 {
2107   int regno;
2108   HOST_WIDE_INT tsize;
2109   int last_arg_is_vararg_marker = 0;
2110   tree fndecl = current_function_decl;
2111   tree fntype = TREE_TYPE (fndecl);
2112   tree fnargs = DECL_ARGUMENTS (fndecl);
2113   rtx next_arg_reg;
2114   int i;
2115   tree next_arg;
2116   tree cur_arg;
2117   CUMULATIVE_ARGS args_so_far;
2118   int store_args_on_stack = (iq2000_can_use_return_insn ());
2119
2120   /* If struct value address is treated as the first argument.  */
2121   if (aggregate_value_p (DECL_RESULT (fndecl), fndecl)
2122       && ! current_function_returns_pcc_struct
2123       && targetm.calls.struct_value_rtx (TREE_TYPE (fndecl), 1) == 0)
2124     {
2125       tree type = build_pointer_type (fntype);
2126       tree function_result_decl = build_decl (PARM_DECL, NULL_TREE, type);
2127
2128       DECL_ARG_TYPE (function_result_decl) = type;
2129       TREE_CHAIN (function_result_decl) = fnargs;
2130       fnargs = function_result_decl;
2131     }
2132
2133   /* For arguments passed in registers, find the register number
2134      of the first argument in the variable part of the argument list,
2135      otherwise GP_ARG_LAST+1.  Note also if the last argument is
2136      the varargs special argument, and treat it as part of the
2137      variable arguments.
2138
2139      This is only needed if store_args_on_stack is true.  */
2140   INIT_CUMULATIVE_ARGS (args_so_far, fntype, NULL_RTX, 0, 0);
2141   regno = GP_ARG_FIRST;
2142
2143   for (cur_arg = fnargs; cur_arg != 0; cur_arg = next_arg)
2144     {
2145       tree passed_type = DECL_ARG_TYPE (cur_arg);
2146       enum machine_mode passed_mode = TYPE_MODE (passed_type);
2147       rtx entry_parm;
2148
2149       if (TREE_ADDRESSABLE (passed_type))
2150         {
2151           passed_type = build_pointer_type (passed_type);
2152           passed_mode = Pmode;
2153         }
2154
2155       entry_parm = FUNCTION_ARG (args_so_far, passed_mode, passed_type, 1);
2156
2157       FUNCTION_ARG_ADVANCE (args_so_far, passed_mode, passed_type, 1);
2158       next_arg = TREE_CHAIN (cur_arg);
2159
2160       if (entry_parm && store_args_on_stack)
2161         {
2162           if (next_arg == 0
2163               && DECL_NAME (cur_arg)
2164               && ((0 == strcmp (IDENTIFIER_POINTER (DECL_NAME (cur_arg)),
2165                                 "__builtin_va_alist"))
2166                   || (0 == strcmp (IDENTIFIER_POINTER (DECL_NAME (cur_arg)),
2167                                    "va_alist"))))
2168             {
2169               last_arg_is_vararg_marker = 1;
2170               break;
2171             }
2172           else
2173             {
2174               int words;
2175
2176               if (GET_CODE (entry_parm) != REG)
2177                 abort ();
2178
2179               /* Passed in a register, so will get homed automatically.  */
2180               if (GET_MODE (entry_parm) == BLKmode)
2181                 words = (int_size_in_bytes (passed_type) + 3) / 4;
2182               else
2183                 words = (GET_MODE_SIZE (GET_MODE (entry_parm)) + 3) / 4;
2184
2185               regno = REGNO (entry_parm) + words - 1;
2186             }
2187         }
2188       else
2189         {
2190           regno = GP_ARG_LAST+1;
2191           break;
2192         }
2193     }
2194
2195   /* In order to pass small structures by value in registers we need to
2196      shift the value into the high part of the register.
2197      Function_arg has encoded a PARALLEL rtx, holding a vector of
2198      adjustments to be made as the next_arg_reg variable, so we split up the
2199      insns, and emit them separately.  */
2200   next_arg_reg = FUNCTION_ARG (args_so_far, VOIDmode, void_type_node, 1);
2201   if (next_arg_reg != 0 && GET_CODE (next_arg_reg) == PARALLEL)
2202     {
2203       rtvec adjust = XVEC (next_arg_reg, 0);
2204       int num = GET_NUM_ELEM (adjust);
2205
2206       for (i = 0; i < num; i++)
2207         {
2208           rtx insn, pattern;
2209
2210           pattern = RTVEC_ELT (adjust, i);
2211           if (GET_CODE (pattern) != SET
2212               || GET_CODE (SET_SRC (pattern)) != ASHIFT)
2213             abort_with_insn (pattern, "Insn is not a shift");
2214           PUT_CODE (SET_SRC (pattern), ASHIFTRT);
2215
2216           insn = emit_insn (pattern);
2217
2218           /* Global life information isn't valid at this point, so we
2219              can't check whether these shifts are actually used.  Mark
2220              them MAYBE_DEAD so that flow2 will remove them, and not
2221              complain about dead code in the prologue.  */
2222           REG_NOTES(insn) = gen_rtx_EXPR_LIST (REG_MAYBE_DEAD, NULL_RTX,
2223                                                REG_NOTES (insn));
2224         }
2225     }
2226
2227   tsize = compute_frame_size (get_frame_size ());
2228
2229   /* If this function is a varargs function, store any registers that
2230      would normally hold arguments ($4 - $7) on the stack.  */
2231   if (store_args_on_stack
2232       && ((TYPE_ARG_TYPES (fntype) != 0
2233            && (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
2234                != void_type_node))
2235           || last_arg_is_vararg_marker))
2236     {
2237       int offset = (regno - GP_ARG_FIRST) * UNITS_PER_WORD;
2238       rtx ptr = stack_pointer_rtx;
2239
2240       for (; regno <= GP_ARG_LAST; regno++)
2241         {
2242           if (offset != 0)
2243             ptr = gen_rtx_PLUS (Pmode, stack_pointer_rtx, GEN_INT (offset));
2244           emit_move_insn (gen_rtx_MEM (gpr_mode, ptr),
2245                           gen_rtx_REG (gpr_mode, regno));
2246
2247           offset += GET_MODE_SIZE (gpr_mode);
2248         }
2249     }
2250
2251   if (tsize > 0)
2252     {
2253       rtx tsize_rtx = GEN_INT (tsize);
2254       rtx adjustment_rtx, insn, dwarf_pattern;
2255
2256       if (tsize > 32767)
2257         {
2258           adjustment_rtx = gen_rtx_REG (Pmode, IQ2000_TEMP1_REGNUM);
2259           emit_move_insn (adjustment_rtx, tsize_rtx);
2260         }
2261       else
2262         adjustment_rtx = tsize_rtx;
2263
2264       insn = emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
2265                                     adjustment_rtx));
2266
2267       dwarf_pattern = gen_rtx_SET (Pmode, stack_pointer_rtx,
2268                                    plus_constant (stack_pointer_rtx, -tsize));
2269
2270       iq2000_annotate_frame_insn (insn, dwarf_pattern);
2271
2272       save_restore_insns (1);
2273
2274       if (frame_pointer_needed)
2275         {
2276           rtx insn = 0;
2277
2278           insn = emit_insn (gen_movsi (hard_frame_pointer_rtx,
2279                                        stack_pointer_rtx));
2280
2281           if (insn)
2282             RTX_FRAME_RELATED_P (insn) = 1;
2283         }
2284     }
2285
2286   emit_insn (gen_blockage ());
2287 }
2288 \f
2289 /* Expand the epilogue into a bunch of separate insns.  */
2290
2291 void
2292 iq2000_expand_epilogue (void)
2293 {
2294   HOST_WIDE_INT tsize = cfun->machine->total_size;
2295   rtx tsize_rtx = GEN_INT (tsize);
2296   rtx tmp_rtx = (rtx)0;
2297
2298   if (iq2000_can_use_return_insn ())
2299     {
2300       emit_jump_insn (gen_return ());
2301       return;
2302     }
2303
2304   if (tsize > 32767)
2305     {
2306       tmp_rtx = gen_rtx_REG (Pmode, IQ2000_TEMP1_REGNUM);
2307       emit_move_insn (tmp_rtx, tsize_rtx);
2308       tsize_rtx = tmp_rtx;
2309     }
2310
2311   if (tsize > 0)
2312     {
2313       if (frame_pointer_needed)
2314         {
2315           emit_insn (gen_blockage ());
2316
2317           emit_insn (gen_movsi (stack_pointer_rtx, hard_frame_pointer_rtx));
2318         }
2319
2320       save_restore_insns (0);
2321
2322       if (current_function_calls_eh_return)
2323         {
2324           rtx eh_ofs = EH_RETURN_STACKADJ_RTX;
2325           emit_insn (gen_addsi3 (eh_ofs, eh_ofs, tsize_rtx));
2326           tsize_rtx = eh_ofs;
2327         }
2328
2329       emit_insn (gen_blockage ());
2330
2331       if (tsize != 0 || current_function_calls_eh_return)
2332         {
2333           emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx,
2334                                  tsize_rtx));
2335         }
2336     }
2337
2338   if (current_function_calls_eh_return)
2339     {
2340       /* Perform the additional bump for __throw.  */
2341       emit_move_insn (gen_rtx_REG (Pmode, HARD_FRAME_POINTER_REGNUM),
2342                       stack_pointer_rtx);
2343       emit_insn (gen_rtx_USE (VOIDmode, gen_rtx_REG (Pmode,
2344                                                   HARD_FRAME_POINTER_REGNUM)));
2345       emit_jump_insn (gen_eh_return_internal ());
2346     }
2347   else
2348       emit_jump_insn (gen_return_internal (gen_rtx_REG (Pmode,
2349                                                   GP_REG_FIRST + 31)));
2350 }
2351
2352 void
2353 iq2000_expand_eh_return (rtx address)
2354 {
2355   HOST_WIDE_INT gp_offset = cfun->machine->gp_sp_offset;
2356   rtx scratch;
2357
2358   scratch = plus_constant (stack_pointer_rtx, gp_offset);
2359   emit_move_insn (gen_rtx_MEM (GET_MODE (address), scratch), address);
2360 }
2361 \f
2362 /* Return nonzero if this function is known to have a null epilogue.
2363    This allows the optimizer to omit jumps to jumps if no stack
2364    was created.  */
2365
2366 int
2367 iq2000_can_use_return_insn (void)
2368 {
2369   if (! reload_completed)
2370     return 0;
2371
2372   if (regs_ever_live[31] || profile_flag)
2373     return 0;
2374
2375   if (cfun->machine->initialized)
2376     return cfun->machine->total_size == 0;
2377
2378   return compute_frame_size (get_frame_size ()) == 0;
2379 }
2380 \f
2381 /* Returns nonzero if X contains a SYMBOL_REF.  */
2382
2383 static int
2384 symbolic_expression_p (rtx x)
2385 {
2386   if (GET_CODE (x) == SYMBOL_REF)
2387     return 1;
2388
2389   if (GET_CODE (x) == CONST)
2390     return symbolic_expression_p (XEXP (x, 0));
2391
2392   if (UNARY_P (x))
2393     return symbolic_expression_p (XEXP (x, 0));
2394
2395   if (ARITHMETIC_P (x))
2396     return (symbolic_expression_p (XEXP (x, 0))
2397             || symbolic_expression_p (XEXP (x, 1)));
2398
2399   return 0;
2400 }
2401
2402 /* Choose the section to use for the constant rtx expression X that has
2403    mode MODE.  */
2404
2405 static void
2406 iq2000_select_rtx_section (enum machine_mode mode, rtx x ATTRIBUTE_UNUSED,
2407                            unsigned HOST_WIDE_INT align)
2408 {
2409   /* For embedded applications, always put constants in read-only data,
2410      in order to reduce RAM usage.  */
2411       /* For embedded applications, always put constants in read-only data,
2412          in order to reduce RAM usage.  */
2413   mergeable_constant_section (mode, align, 0);
2414 }
2415
2416 /* Choose the section to use for DECL.  RELOC is true if its value contains
2417    any relocatable expression.
2418
2419    Some of the logic used here needs to be replicated in
2420    ENCODE_SECTION_INFO in iq2000.h so that references to these symbols
2421    are done correctly.  */
2422
2423 static void
2424 iq2000_select_section (tree decl, int reloc ATTRIBUTE_UNUSED,
2425                        unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED)
2426 {
2427   if (TARGET_EMBEDDED_DATA)
2428     {
2429       /* For embedded applications, always put an object in read-only data
2430          if possible, in order to reduce RAM usage.  */
2431       if ((TREE_CODE (decl) == VAR_DECL
2432            && TREE_READONLY (decl) && !TREE_SIDE_EFFECTS (decl)
2433            && DECL_INITIAL (decl)
2434            && (DECL_INITIAL (decl) == error_mark_node
2435                || TREE_CONSTANT (DECL_INITIAL (decl))))
2436           /* Deal with calls from output_constant_def_contents.  */
2437           || TREE_CODE (decl) != VAR_DECL)
2438         readonly_data_section ();
2439       else
2440         data_section ();
2441     }
2442   else
2443     {
2444       /* For hosted applications, always put an object in small data if
2445          possible, as this gives the best performance.  */
2446       if ((TREE_CODE (decl) == VAR_DECL
2447            && TREE_READONLY (decl) && !TREE_SIDE_EFFECTS (decl)
2448            && DECL_INITIAL (decl)
2449            && (DECL_INITIAL (decl) == error_mark_node
2450                || TREE_CONSTANT (DECL_INITIAL (decl))))
2451           /* Deal with calls from output_constant_def_contents.  */
2452           || TREE_CODE (decl) != VAR_DECL)
2453         readonly_data_section ();
2454       else
2455         data_section ();
2456     }
2457 }
2458 /* Return register to use for a function return value with VALTYPE for function
2459    FUNC.  */
2460
2461 rtx
2462 iq2000_function_value (tree valtype, tree func ATTRIBUTE_UNUSED)
2463 {
2464   int reg = GP_RETURN;
2465   enum machine_mode mode = TYPE_MODE (valtype);
2466   int unsignedp = TYPE_UNSIGNED (valtype);
2467
2468   /* Since we define TARGET_PROMOTE_FUNCTION_RETURN that returns true,
2469      we must promote the mode just as PROMOTE_MODE does.  */
2470   mode = promote_mode (valtype, mode, &unsignedp, 1);
2471
2472   return gen_rtx_REG (mode, reg);
2473 }
2474 \f
2475 /* Return true when an argument must be passed by reference.  */
2476
2477 static bool
2478 iq2000_pass_by_reference (CUMULATIVE_ARGS *cum, enum machine_mode mode,
2479                           tree type, bool named ATTRIBUTE_UNUSED)
2480 {
2481   int size;
2482
2483   /* We must pass by reference if we would be both passing in registers
2484      and the stack.  This is because any subsequent partial arg would be
2485      handled incorrectly in this case.  */
2486   if (cum && targetm.calls.must_pass_in_stack (mode, type))
2487      {
2488        /* Don't pass the actual CUM to FUNCTION_ARG, because we would
2489           get double copies of any offsets generated for small structs
2490           passed in registers.  */
2491        CUMULATIVE_ARGS temp;
2492
2493        temp = *cum;
2494        if (FUNCTION_ARG (temp, mode, type, named) != 0)
2495          return 1;
2496      }
2497
2498   if (type == NULL_TREE || mode == DImode || mode == DFmode)
2499     return 0;
2500
2501   size = int_size_in_bytes (type);
2502   return size == -1 || size > UNITS_PER_WORD;
2503 }
2504
2505 /* Return the length of INSN.  LENGTH is the initial length computed by
2506    attributes in the machine-description file.  */
2507
2508 int
2509 iq2000_adjust_insn_length (rtx insn, int length)
2510 {
2511   /* A unconditional jump has an unfilled delay slot if it is not part
2512      of a sequence.  A conditional jump normally has a delay slot.  */
2513   if (simplejump_p (insn)
2514       || (   (GET_CODE (insn) == JUMP_INSN
2515            || GET_CODE (insn) == CALL_INSN)))
2516     length += 4;
2517
2518   return length;
2519 }
2520
2521 /* Output assembly instructions to perform a conditional branch.
2522
2523    INSN is the branch instruction.  OPERANDS[0] is the condition.
2524    OPERANDS[1] is the target of the branch.  OPERANDS[2] is the target
2525    of the first operand to the condition.  If TWO_OPERANDS_P is
2526    nonzero the comparison takes two operands; OPERANDS[3] will be the
2527    second operand.
2528
2529    If INVERTED_P is nonzero we are to branch if the condition does
2530    not hold.  If FLOAT_P is nonzero this is a floating-point comparison.
2531
2532    LENGTH is the length (in bytes) of the sequence we are to generate.
2533    That tells us whether to generate a simple conditional branch, or a
2534    reversed conditional branch around a `jr' instruction.  */
2535
2536 char *
2537 iq2000_output_conditional_branch (rtx insn, rtx * operands, int two_operands_p,
2538                                   int float_p, int inverted_p, int length)
2539 {
2540   static char buffer[200];
2541   /* The kind of comparison we are doing.  */
2542   enum rtx_code code = GET_CODE (operands[0]);
2543   /* Nonzero if the opcode for the comparison needs a `z' indicating
2544      that it is a comparison against zero.  */
2545   int need_z_p;
2546   /* A string to use in the assembly output to represent the first
2547      operand.  */
2548   const char *op1 = "%z2";
2549   /* A string to use in the assembly output to represent the second
2550      operand.  Use the hard-wired zero register if there's no second
2551      operand.  */
2552   const char *op2 = (two_operands_p ? ",%z3" : ",%.");
2553   /* The operand-printing string for the comparison.  */
2554   const char *comp = (float_p ? "%F0" : "%C0");
2555   /* The operand-printing string for the inverted comparison.  */
2556   const char *inverted_comp = (float_p ? "%W0" : "%N0");
2557
2558   /* Likely variants of each branch instruction annul the instruction
2559      in the delay slot if the branch is not taken.  */
2560   iq2000_branch_likely = (final_sequence && INSN_ANNULLED_BRANCH_P (insn));
2561
2562   if (!two_operands_p)
2563     {
2564       /* To compute whether than A > B, for example, we normally
2565          subtract B from A and then look at the sign bit.  But, if we
2566          are doing an unsigned comparison, and B is zero, we don't
2567          have to do the subtraction.  Instead, we can just check to
2568          see if A is nonzero.  Thus, we change the CODE here to
2569          reflect the simpler comparison operation.  */
2570       switch (code)
2571         {
2572         case GTU:
2573           code = NE;
2574           break;
2575
2576         case LEU:
2577           code = EQ;
2578           break;
2579
2580         case GEU:
2581           /* A condition which will always be true.  */
2582           code = EQ;
2583           op1 = "%.";
2584           break;
2585
2586         case LTU:
2587           /* A condition which will always be false.  */
2588           code = NE;
2589           op1 = "%.";
2590           break;
2591
2592         default:
2593           /* Not a special case.  */
2594           break;
2595         }
2596     }
2597
2598   /* Relative comparisons are always done against zero.  But
2599      equality comparisons are done between two operands, and therefore
2600      do not require a `z' in the assembly language output.  */
2601   need_z_p = (!float_p && code != EQ && code != NE);
2602   /* For comparisons against zero, the zero is not provided
2603      explicitly.  */
2604   if (need_z_p)
2605     op2 = "";
2606
2607   /* Begin by terminating the buffer.  That way we can always use
2608      strcat to add to it.  */
2609   buffer[0] = '\0';
2610
2611   switch (length)
2612     {
2613     case 4:
2614     case 8:
2615       /* Just a simple conditional branch.  */
2616       if (float_p)
2617         sprintf (buffer, "b%s%%?\t%%Z2%%1",
2618                  inverted_p ? inverted_comp : comp);
2619       else
2620         sprintf (buffer, "b%s%s%%?\t%s%s,%%1",
2621                  inverted_p ? inverted_comp : comp,
2622                  need_z_p ? "z" : "",
2623                  op1,
2624                  op2);
2625       return buffer;
2626
2627     case 12:
2628     case 16:
2629       {
2630         /* Generate a reversed conditional branch around ` j'
2631            instruction:
2632
2633                 .set noreorder
2634                 .set nomacro
2635                 bc    l
2636                 nop
2637                 j     target
2638                 .set macro
2639                 .set reorder
2640              l:
2641
2642            Because we have to jump four bytes *past* the following
2643            instruction if this branch was annulled, we can't just use
2644            a label, as in the picture above; there's no way to put the
2645            label after the next instruction, as the assembler does not
2646            accept `.L+4' as the target of a branch.  (We can't just
2647            wait until the next instruction is output; it might be a
2648            macro and take up more than four bytes.  Once again, we see
2649            why we want to eliminate macros.)
2650
2651            If the branch is annulled, we jump four more bytes that we
2652            would otherwise; that way we skip the annulled instruction
2653            in the delay slot.  */
2654
2655         const char *target
2656           = ((iq2000_branch_likely || length == 16) ? ".+16" : ".+12");
2657         char *c;
2658
2659         c = strchr (buffer, '\0');
2660         /* Generate the reversed comparison.  This takes four
2661            bytes.  */
2662         if (float_p)
2663           sprintf (c, "b%s\t%%Z2%s",
2664                    inverted_p ? comp : inverted_comp,
2665                    target);
2666         else
2667           sprintf (c, "b%s%s\t%s%s,%s",
2668                    inverted_p ? comp : inverted_comp,
2669                    need_z_p ? "z" : "",
2670                    op1,
2671                    op2,
2672                    target);
2673         strcat (c, "\n\tnop\n\tj\t%1");
2674         if (length == 16)
2675           /* The delay slot was unfilled.  Since we're inside
2676              .noreorder, the assembler will not fill in the NOP for
2677              us, so we must do it ourselves.  */
2678           strcat (buffer, "\n\tnop");
2679         return buffer;
2680       }
2681
2682     default:
2683       abort ();
2684     }
2685
2686   /* NOTREACHED */
2687   return 0;
2688 }
2689
2690 #define def_builtin(NAME, TYPE, CODE)                                   \
2691   lang_hooks.builtin_function ((NAME), (TYPE), (CODE), BUILT_IN_MD,     \
2692                                NULL, NULL_TREE)
2693
2694 static void
2695 iq2000_init_builtins (void)
2696 {
2697   tree endlink = void_list_node;
2698   tree void_ftype, void_ftype_int, void_ftype_int_int;
2699   tree void_ftype_int_int_int;
2700   tree int_ftype_int, int_ftype_int_int, int_ftype_int_int_int;
2701   tree int_ftype_int_int_int_int;
2702
2703   /* func () */
2704   void_ftype
2705     = build_function_type (void_type_node,
2706                            tree_cons (NULL_TREE, void_type_node, endlink));
2707
2708   /* func (int) */
2709   void_ftype_int
2710     = build_function_type (void_type_node,
2711                            tree_cons (NULL_TREE, integer_type_node, endlink));
2712
2713   /* void func (int, int) */
2714   void_ftype_int_int
2715     = build_function_type (void_type_node,
2716                            tree_cons (NULL_TREE, integer_type_node,
2717                                       tree_cons (NULL_TREE, integer_type_node,
2718                                                  endlink)));
2719
2720   /* int func (int) */
2721   int_ftype_int
2722     = build_function_type (integer_type_node,
2723                            tree_cons (NULL_TREE, integer_type_node, endlink));
2724
2725   /* int func (int, int) */
2726   int_ftype_int_int
2727     = build_function_type (integer_type_node,
2728                            tree_cons (NULL_TREE, integer_type_node,
2729                                       tree_cons (NULL_TREE, integer_type_node,
2730                                                  endlink)));
2731
2732   /* void func (int, int, int) */
2733 void_ftype_int_int_int
2734     = build_function_type
2735     (void_type_node,
2736      tree_cons (NULL_TREE, integer_type_node,
2737                 tree_cons (NULL_TREE, integer_type_node,
2738                            tree_cons (NULL_TREE,
2739                                       integer_type_node,
2740                                       endlink))));
2741
2742   /* int func (int, int, int, int) */
2743   int_ftype_int_int_int_int
2744     = build_function_type
2745     (integer_type_node,
2746      tree_cons (NULL_TREE, integer_type_node,
2747                 tree_cons (NULL_TREE, integer_type_node,
2748                            tree_cons (NULL_TREE,
2749                                       integer_type_node,
2750                                       tree_cons (NULL_TREE,
2751                                                  integer_type_node,
2752                                                  endlink)))));
2753
2754   /* int func (int, int, int) */
2755   int_ftype_int_int_int
2756     = build_function_type
2757     (integer_type_node,
2758      tree_cons (NULL_TREE, integer_type_node,
2759                 tree_cons (NULL_TREE, integer_type_node,
2760                            tree_cons (NULL_TREE,
2761                                       integer_type_node,
2762                                       endlink))));
2763
2764   /* int func (int, int, int, int) */
2765   int_ftype_int_int_int_int
2766     = build_function_type
2767     (integer_type_node,
2768      tree_cons (NULL_TREE, integer_type_node,
2769                 tree_cons (NULL_TREE, integer_type_node,
2770                            tree_cons (NULL_TREE,
2771                                       integer_type_node,
2772                                       tree_cons (NULL_TREE,
2773                                                  integer_type_node,
2774                                                  endlink)))));
2775
2776   def_builtin ("__builtin_ado16", int_ftype_int_int, IQ2000_BUILTIN_ADO16);
2777   def_builtin ("__builtin_ram", int_ftype_int_int_int_int, IQ2000_BUILTIN_RAM);
2778   def_builtin ("__builtin_chkhdr", void_ftype_int_int, IQ2000_BUILTIN_CHKHDR);
2779   def_builtin ("__builtin_pkrl", void_ftype_int_int, IQ2000_BUILTIN_PKRL);
2780   def_builtin ("__builtin_cfc0", int_ftype_int, IQ2000_BUILTIN_CFC0);
2781   def_builtin ("__builtin_cfc1", int_ftype_int, IQ2000_BUILTIN_CFC1);
2782   def_builtin ("__builtin_cfc2", int_ftype_int, IQ2000_BUILTIN_CFC2);
2783   def_builtin ("__builtin_cfc3", int_ftype_int, IQ2000_BUILTIN_CFC3);
2784   def_builtin ("__builtin_ctc0", void_ftype_int_int, IQ2000_BUILTIN_CTC0);
2785   def_builtin ("__builtin_ctc1", void_ftype_int_int, IQ2000_BUILTIN_CTC1);
2786   def_builtin ("__builtin_ctc2", void_ftype_int_int, IQ2000_BUILTIN_CTC2);
2787   def_builtin ("__builtin_ctc3", void_ftype_int_int, IQ2000_BUILTIN_CTC3);
2788   def_builtin ("__builtin_mfc0", int_ftype_int, IQ2000_BUILTIN_MFC0);
2789   def_builtin ("__builtin_mfc1", int_ftype_int, IQ2000_BUILTIN_MFC1);
2790   def_builtin ("__builtin_mfc2", int_ftype_int, IQ2000_BUILTIN_MFC2);
2791   def_builtin ("__builtin_mfc3", int_ftype_int, IQ2000_BUILTIN_MFC3);
2792   def_builtin ("__builtin_mtc0", void_ftype_int_int, IQ2000_BUILTIN_MTC0);
2793   def_builtin ("__builtin_mtc1", void_ftype_int_int, IQ2000_BUILTIN_MTC1);
2794   def_builtin ("__builtin_mtc2", void_ftype_int_int, IQ2000_BUILTIN_MTC2);
2795   def_builtin ("__builtin_mtc3", void_ftype_int_int, IQ2000_BUILTIN_MTC3);
2796   def_builtin ("__builtin_lur", void_ftype_int_int, IQ2000_BUILTIN_LUR);
2797   def_builtin ("__builtin_rb", void_ftype_int_int, IQ2000_BUILTIN_RB);
2798   def_builtin ("__builtin_rx", void_ftype_int_int, IQ2000_BUILTIN_RX);
2799   def_builtin ("__builtin_srrd", void_ftype_int, IQ2000_BUILTIN_SRRD);
2800   def_builtin ("__builtin_srwr", void_ftype_int_int, IQ2000_BUILTIN_SRWR);
2801   def_builtin ("__builtin_wb", void_ftype_int_int, IQ2000_BUILTIN_WB);
2802   def_builtin ("__builtin_wx", void_ftype_int_int, IQ2000_BUILTIN_WX);
2803   def_builtin ("__builtin_luc32l", void_ftype_int_int, IQ2000_BUILTIN_LUC32L);
2804   def_builtin ("__builtin_luc64", void_ftype_int_int, IQ2000_BUILTIN_LUC64);
2805   def_builtin ("__builtin_luc64l", void_ftype_int_int, IQ2000_BUILTIN_LUC64L);
2806   def_builtin ("__builtin_luk", void_ftype_int_int, IQ2000_BUILTIN_LUK);
2807   def_builtin ("__builtin_lulck", void_ftype_int, IQ2000_BUILTIN_LULCK);
2808   def_builtin ("__builtin_lum32", void_ftype_int_int, IQ2000_BUILTIN_LUM32);
2809   def_builtin ("__builtin_lum32l", void_ftype_int_int, IQ2000_BUILTIN_LUM32L);
2810   def_builtin ("__builtin_lum64", void_ftype_int_int, IQ2000_BUILTIN_LUM64);
2811   def_builtin ("__builtin_lum64l", void_ftype_int_int, IQ2000_BUILTIN_LUM64L);
2812   def_builtin ("__builtin_lurl", void_ftype_int_int, IQ2000_BUILTIN_LURL);
2813   def_builtin ("__builtin_mrgb", int_ftype_int_int_int, IQ2000_BUILTIN_MRGB);
2814   def_builtin ("__builtin_srrdl", void_ftype_int, IQ2000_BUILTIN_SRRDL);
2815   def_builtin ("__builtin_srulck", void_ftype_int, IQ2000_BUILTIN_SRULCK);
2816   def_builtin ("__builtin_srwru", void_ftype_int_int, IQ2000_BUILTIN_SRWRU);
2817   def_builtin ("__builtin_trapqfl", void_ftype, IQ2000_BUILTIN_TRAPQFL);
2818   def_builtin ("__builtin_trapqne", void_ftype, IQ2000_BUILTIN_TRAPQNE);
2819   def_builtin ("__builtin_traprel", void_ftype_int, IQ2000_BUILTIN_TRAPREL);
2820   def_builtin ("__builtin_wbu", void_ftype_int_int_int, IQ2000_BUILTIN_WBU);
2821   def_builtin ("__builtin_syscall", void_ftype, IQ2000_BUILTIN_SYSCALL);
2822 }
2823
2824 /* Builtin for ICODE having ARGCOUNT args in ARGLIST where each arg
2825    has an rtx CODE.  */
2826
2827 static rtx
2828 expand_one_builtin (enum insn_code icode, rtx target, tree arglist,
2829                     enum rtx_code *code, int argcount)
2830 {
2831   rtx pat;
2832   tree arg [5];
2833   rtx op [5];
2834   enum machine_mode mode [5];
2835   int i;
2836
2837   mode[0] = insn_data[icode].operand[0].mode;
2838   for (i = 0; i < argcount; i++)
2839     {
2840       arg[i] = TREE_VALUE (arglist);
2841       arglist = TREE_CHAIN (arglist);
2842       op[i] = expand_expr (arg[i], NULL_RTX, VOIDmode, 0);
2843       mode[i] = insn_data[icode].operand[i].mode;
2844       if (code[i] == CONST_INT && GET_CODE (op[i]) != CONST_INT)
2845         error ("argument `%d' is not a constant", i + 1);
2846       if (code[i] == REG
2847           && ! (*insn_data[icode].operand[i].predicate) (op[i], mode[i]))
2848         op[i] = copy_to_mode_reg (mode[i], op[i]);
2849     }
2850
2851   if (insn_data[icode].operand[0].constraint[0] == '=')
2852     {
2853       if (target == 0
2854           || GET_MODE (target) != mode[0]
2855           || ! (*insn_data[icode].operand[0].predicate) (target, mode[0]))
2856         target = gen_reg_rtx (mode[0]);
2857     }
2858   else
2859     target = 0;
2860
2861   switch (argcount)
2862     {
2863     case 0:
2864         pat = GEN_FCN (icode) (target);
2865     case 1:
2866       if (target)
2867         pat = GEN_FCN (icode) (target, op[0]);
2868       else
2869         pat = GEN_FCN (icode) (op[0]);
2870       break;
2871     case 2:
2872       if (target)
2873         pat = GEN_FCN (icode) (target, op[0], op[1]);
2874       else
2875         pat = GEN_FCN (icode) (op[0], op[1]);
2876       break;
2877     case 3:
2878       if (target)
2879         pat = GEN_FCN (icode) (target, op[0], op[1], op[2]);
2880       else
2881         pat = GEN_FCN (icode) (op[0], op[1], op[2]);
2882       break;
2883     case 4:
2884       if (target)
2885         pat = GEN_FCN (icode) (target, op[0], op[1], op[2], op[3]);
2886       else
2887         pat = GEN_FCN (icode) (op[0], op[1], op[2], op[3]);
2888       break;
2889     default:
2890       abort ();
2891     }
2892   
2893   if (! pat)
2894     return 0;
2895   emit_insn (pat);
2896   return target;
2897 }
2898
2899 /* Expand an expression EXP that calls a built-in function,
2900    with result going to TARGET if that's convenient
2901    (and in mode MODE if that's convenient).
2902    SUBTARGET may be used as the target for computing one of EXP's operands.
2903    IGNORE is nonzero if the value is to be ignored.  */
2904
2905 static rtx
2906 iq2000_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED,
2907                        enum machine_mode mode ATTRIBUTE_UNUSED,
2908                        int ignore ATTRIBUTE_UNUSED)
2909 {
2910   tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
2911   tree arglist = TREE_OPERAND (exp, 1);
2912   int fcode = DECL_FUNCTION_CODE (fndecl);
2913   enum rtx_code code [5];
2914
2915   code[0] = REG;
2916   code[1] = REG;
2917   code[2] = REG;
2918   code[3] = REG;
2919   code[4] = REG;
2920   switch (fcode)
2921     {
2922     default:
2923       break;
2924       
2925     case IQ2000_BUILTIN_ADO16:
2926       return expand_one_builtin (CODE_FOR_ado16, target, arglist, code, 2);
2927
2928     case IQ2000_BUILTIN_RAM:
2929       code[1] = CONST_INT;
2930       code[2] = CONST_INT;
2931       code[3] = CONST_INT;
2932       return expand_one_builtin (CODE_FOR_ram, target, arglist, code, 4);
2933       
2934     case IQ2000_BUILTIN_CHKHDR:
2935       return expand_one_builtin (CODE_FOR_chkhdr, target, arglist, code, 2);
2936       
2937     case IQ2000_BUILTIN_PKRL:
2938       return expand_one_builtin (CODE_FOR_pkrl, target, arglist, code, 2);
2939
2940     case IQ2000_BUILTIN_CFC0:
2941       code[0] = CONST_INT;
2942       return expand_one_builtin (CODE_FOR_cfc0, target, arglist, code, 1);
2943
2944     case IQ2000_BUILTIN_CFC1:
2945       code[0] = CONST_INT;
2946       return expand_one_builtin (CODE_FOR_cfc1, target, arglist, code, 1);
2947
2948     case IQ2000_BUILTIN_CFC2:
2949       code[0] = CONST_INT;
2950       return expand_one_builtin (CODE_FOR_cfc2, target, arglist, code, 1);
2951
2952     case IQ2000_BUILTIN_CFC3:
2953       code[0] = CONST_INT;
2954       return expand_one_builtin (CODE_FOR_cfc3, target, arglist, code, 1);
2955
2956     case IQ2000_BUILTIN_CTC0:
2957       code[1] = CONST_INT;
2958       return expand_one_builtin (CODE_FOR_ctc0, target, arglist, code, 2);
2959
2960     case IQ2000_BUILTIN_CTC1:
2961       code[1] = CONST_INT;
2962       return expand_one_builtin (CODE_FOR_ctc1, target, arglist, code, 2);
2963
2964     case IQ2000_BUILTIN_CTC2:
2965       code[1] = CONST_INT;
2966       return expand_one_builtin (CODE_FOR_ctc2, target, arglist, code, 2);
2967
2968     case IQ2000_BUILTIN_CTC3:
2969       code[1] = CONST_INT;
2970       return expand_one_builtin (CODE_FOR_ctc3, target, arglist, code, 2);
2971
2972     case IQ2000_BUILTIN_MFC0:
2973       code[0] = CONST_INT;
2974       return expand_one_builtin (CODE_FOR_mfc0, target, arglist, code, 1);
2975
2976     case IQ2000_BUILTIN_MFC1:
2977       code[0] = CONST_INT;
2978       return expand_one_builtin (CODE_FOR_mfc1, target, arglist, code, 1);
2979
2980     case IQ2000_BUILTIN_MFC2:
2981       code[0] = CONST_INT;
2982       return expand_one_builtin (CODE_FOR_mfc2, target, arglist, code, 1);
2983
2984     case IQ2000_BUILTIN_MFC3:
2985       code[0] = CONST_INT;
2986       return expand_one_builtin (CODE_FOR_mfc3, target, arglist, code, 1);
2987
2988     case IQ2000_BUILTIN_MTC0:
2989       code[1] = CONST_INT;
2990       return expand_one_builtin (CODE_FOR_mtc0, target, arglist, code, 2);
2991
2992     case IQ2000_BUILTIN_MTC1:
2993       code[1] = CONST_INT;
2994       return expand_one_builtin (CODE_FOR_mtc1, target, arglist, code, 2);
2995
2996     case IQ2000_BUILTIN_MTC2:
2997       code[1] = CONST_INT;
2998       return expand_one_builtin (CODE_FOR_mtc2, target, arglist, code, 2);
2999
3000     case IQ2000_BUILTIN_MTC3:
3001       code[1] = CONST_INT;
3002       return expand_one_builtin (CODE_FOR_mtc3, target, arglist, code, 2);
3003
3004     case IQ2000_BUILTIN_LUR:
3005       return expand_one_builtin (CODE_FOR_lur, target, arglist, code, 2);
3006
3007     case IQ2000_BUILTIN_RB:
3008       return expand_one_builtin (CODE_FOR_rb, target, arglist, code, 2);
3009
3010     case IQ2000_BUILTIN_RX:
3011       return expand_one_builtin (CODE_FOR_rx, target, arglist, code, 2);
3012
3013     case IQ2000_BUILTIN_SRRD:
3014       return expand_one_builtin (CODE_FOR_srrd, target, arglist, code, 1);
3015
3016     case IQ2000_BUILTIN_SRWR:
3017       return expand_one_builtin (CODE_FOR_srwr, target, arglist, code, 2);
3018
3019     case IQ2000_BUILTIN_WB:
3020       return expand_one_builtin (CODE_FOR_wb, target, arglist, code, 2);
3021
3022     case IQ2000_BUILTIN_WX:
3023       return expand_one_builtin (CODE_FOR_wx, target, arglist, code, 2);
3024
3025     case IQ2000_BUILTIN_LUC32L:
3026       return expand_one_builtin (CODE_FOR_luc32l, target, arglist, code, 2);
3027
3028     case IQ2000_BUILTIN_LUC64:
3029       return expand_one_builtin (CODE_FOR_luc64, target, arglist, code, 2);
3030
3031     case IQ2000_BUILTIN_LUC64L:
3032       return expand_one_builtin (CODE_FOR_luc64l, target, arglist, code, 2);
3033
3034     case IQ2000_BUILTIN_LUK:
3035       return expand_one_builtin (CODE_FOR_luk, target, arglist, code, 2);
3036
3037     case IQ2000_BUILTIN_LULCK:
3038       return expand_one_builtin (CODE_FOR_lulck, target, arglist, code, 1);
3039
3040     case IQ2000_BUILTIN_LUM32:
3041       return expand_one_builtin (CODE_FOR_lum32, target, arglist, code, 2);
3042
3043     case IQ2000_BUILTIN_LUM32L:
3044       return expand_one_builtin (CODE_FOR_lum32l, target, arglist, code, 2);
3045
3046     case IQ2000_BUILTIN_LUM64:
3047       return expand_one_builtin (CODE_FOR_lum64, target, arglist, code, 2);
3048
3049     case IQ2000_BUILTIN_LUM64L:
3050       return expand_one_builtin (CODE_FOR_lum64l, target, arglist, code, 2);
3051
3052     case IQ2000_BUILTIN_LURL:
3053       return expand_one_builtin (CODE_FOR_lurl, target, arglist, code, 2);
3054
3055     case IQ2000_BUILTIN_MRGB:
3056       code[2] = CONST_INT;
3057       return expand_one_builtin (CODE_FOR_mrgb, target, arglist, code, 3);
3058
3059     case IQ2000_BUILTIN_SRRDL:
3060       return expand_one_builtin (CODE_FOR_srrdl, target, arglist, code, 1);
3061
3062     case IQ2000_BUILTIN_SRULCK:
3063       return expand_one_builtin (CODE_FOR_srulck, target, arglist, code, 1);
3064
3065     case IQ2000_BUILTIN_SRWRU:
3066       return expand_one_builtin (CODE_FOR_srwru, target, arglist, code, 2);
3067
3068     case IQ2000_BUILTIN_TRAPQFL:
3069       return expand_one_builtin (CODE_FOR_trapqfl, target, arglist, code, 0);
3070
3071     case IQ2000_BUILTIN_TRAPQNE:
3072       return expand_one_builtin (CODE_FOR_trapqne, target, arglist, code, 0);
3073
3074     case IQ2000_BUILTIN_TRAPREL:
3075       return expand_one_builtin (CODE_FOR_traprel, target, arglist, code, 1);
3076
3077     case IQ2000_BUILTIN_WBU:
3078       return expand_one_builtin (CODE_FOR_wbu, target, arglist, code, 3);
3079
3080     case IQ2000_BUILTIN_SYSCALL:
3081       return expand_one_builtin (CODE_FOR_syscall, target, arglist, code, 0);
3082     }
3083   
3084   return NULL_RTX;
3085 }
3086 \f
3087 /* Worker function for TARGET_RETURN_IN_MEMORY.  */
3088
3089 static bool
3090 iq2000_return_in_memory (tree type, tree fntype ATTRIBUTE_UNUSED)
3091 {
3092   return ((int_size_in_bytes (type) > (2 * UNITS_PER_WORD))
3093           || (int_size_in_bytes (type) == -1));
3094 }
3095
3096 /* Worker function for TARGET_SETUP_INCOMING_VARARGS.  */
3097
3098 static void
3099 iq2000_setup_incoming_varargs (CUMULATIVE_ARGS *cum,
3100                                enum machine_mode mode ATTRIBUTE_UNUSED,
3101                                tree type ATTRIBUTE_UNUSED, int * pretend_size,
3102                                int no_rtl)
3103 {
3104   unsigned int iq2000_off = ! cum->last_arg_fp; 
3105   unsigned int iq2000_fp_off = cum->last_arg_fp; 
3106
3107   if ((cum->arg_words < MAX_ARGS_IN_REGISTERS - iq2000_off))
3108     {
3109       int iq2000_save_gp_regs 
3110         = MAX_ARGS_IN_REGISTERS - cum->arg_words - iq2000_off; 
3111       int iq2000_save_fp_regs 
3112         = (MAX_ARGS_IN_REGISTERS - cum->fp_arg_words - iq2000_fp_off); 
3113
3114       if (iq2000_save_gp_regs < 0) 
3115         iq2000_save_gp_regs = 0; 
3116       if (iq2000_save_fp_regs < 0) 
3117         iq2000_save_fp_regs = 0; 
3118
3119       *pretend_size = ((iq2000_save_gp_regs * UNITS_PER_WORD) 
3120                       + (iq2000_save_fp_regs * UNITS_PER_FPREG)); 
3121
3122       if (! (no_rtl)) 
3123         {
3124           if (cum->arg_words < MAX_ARGS_IN_REGISTERS - iq2000_off) 
3125             {
3126               rtx ptr, mem; 
3127               ptr = plus_constant (virtual_incoming_args_rtx, 
3128                                    - (iq2000_save_gp_regs 
3129                                       * UNITS_PER_WORD)); 
3130               mem = gen_rtx_MEM (BLKmode, ptr); 
3131               move_block_from_reg 
3132                 (cum->arg_words + GP_ARG_FIRST + iq2000_off, 
3133                  mem, 
3134                  iq2000_save_gp_regs);
3135             } 
3136         } 
3137     }
3138 }
3139 \f
3140 /* A C compound statement to output to stdio stream STREAM the
3141    assembler syntax for an instruction operand that is a memory
3142    reference whose address is ADDR.  ADDR is an RTL expression.  */
3143
3144 void
3145 print_operand_address (FILE * file, rtx addr)
3146 {
3147   if (!addr)
3148     error ("PRINT_OPERAND_ADDRESS, null pointer");
3149
3150   else
3151     switch (GET_CODE (addr))
3152       {
3153       case REG:
3154         if (REGNO (addr) == ARG_POINTER_REGNUM)
3155           abort_with_insn (addr, "Arg pointer not eliminated.");
3156
3157         fprintf (file, "0(%s)", reg_names [REGNO (addr)]);
3158         break;
3159
3160       case LO_SUM:
3161         {
3162           rtx arg0 = XEXP (addr, 0);
3163           rtx arg1 = XEXP (addr, 1);
3164
3165           if (GET_CODE (arg0) != REG)
3166             abort_with_insn (addr,
3167                              "PRINT_OPERAND_ADDRESS, LO_SUM with #1 not REG.");
3168
3169           fprintf (file, "%%lo(");
3170           print_operand_address (file, arg1);
3171           fprintf (file, ")(%s)", reg_names [REGNO (arg0)]);
3172         }
3173         break;
3174
3175       case PLUS:
3176         {
3177           rtx reg = 0;
3178           rtx offset = 0;
3179           rtx arg0 = XEXP (addr, 0);
3180           rtx arg1 = XEXP (addr, 1);
3181
3182           if (GET_CODE (arg0) == REG)
3183             {
3184               reg = arg0;
3185               offset = arg1;
3186               if (GET_CODE (offset) == REG)
3187                 abort_with_insn (addr, "PRINT_OPERAND_ADDRESS, 2 regs");
3188             }
3189
3190           else if (GET_CODE (arg1) == REG)
3191               reg = arg1, offset = arg0;
3192           else if (CONSTANT_P (arg0) && CONSTANT_P (arg1))
3193             {
3194               output_addr_const (file, addr);
3195               break;
3196             }
3197           else
3198             abort_with_insn (addr, "PRINT_OPERAND_ADDRESS, no regs");
3199
3200           if (! CONSTANT_P (offset))
3201             abort_with_insn (addr, "PRINT_OPERAND_ADDRESS, invalid insn #2");
3202
3203           if (REGNO (reg) == ARG_POINTER_REGNUM)
3204             abort_with_insn (addr, "Arg pointer not eliminated.");
3205
3206           output_addr_const (file, offset);
3207           fprintf (file, "(%s)", reg_names [REGNO (reg)]);
3208         }
3209         break;
3210
3211       case LABEL_REF:
3212       case SYMBOL_REF:
3213       case CONST_INT:
3214       case CONST:
3215         output_addr_const (file, addr);
3216         if (GET_CODE (addr) == CONST_INT)
3217           fprintf (file, "(%s)", reg_names [0]);
3218         break;
3219
3220       default:
3221         abort_with_insn (addr, "PRINT_OPERAND_ADDRESS, invalid insn #1");
3222         break;
3223     }
3224 }
3225 \f
3226 /* A C compound statement to output to stdio stream FILE the
3227    assembler syntax for an instruction operand OP.
3228
3229    LETTER is a value that can be used to specify one of several ways
3230    of printing the operand.  It is used when identical operands
3231    must be printed differently depending on the context.  LETTER
3232    comes from the `%' specification that was used to request
3233    printing of the operand.  If the specification was just `%DIGIT'
3234    then LETTER is 0; if the specification was `%LTR DIGIT' then LETTER
3235    is the ASCII code for LTR.
3236
3237    If OP is a register, this macro should print the register's name.
3238    The names can be found in an array `reg_names' whose type is
3239    `char *[]'.  `reg_names' is initialized from `REGISTER_NAMES'.
3240
3241    When the machine description has a specification `%PUNCT' (a `%'
3242    followed by a punctuation character), this macro is called with
3243    a null pointer for X and the punctuation character for LETTER.
3244
3245    The IQ2000 specific codes are:
3246
3247    'X'  X is CONST_INT, prints upper 16 bits in hexadecimal format = "0x%04x",
3248    'x'  X is CONST_INT, prints lower 16 bits in hexadecimal format = "0x%04x",
3249    'd'  output integer constant in decimal,
3250    'z'  if the operand is 0, use $0 instead of normal operand.
3251    'D'  print second part of double-word register or memory operand.
3252    'L'  print low-order register of double-word register operand.
3253    'M'  print high-order register of double-word register operand.
3254    'C'  print part of opcode for a branch condition.
3255    'F'  print part of opcode for a floating-point branch condition.
3256    'N'  print part of opcode for a branch condition, inverted.
3257    'W'  print part of opcode for a floating-point branch condition, inverted.
3258    'A'  Print part of opcode for a bit test condition.
3259    'P'  Print label for a bit test.
3260    'p'  Print log for a bit test.
3261    'B'  print 'z' for EQ, 'n' for NE
3262    'b'  print 'n' for EQ, 'z' for NE
3263    'T'  print 'f' for EQ, 't' for NE
3264    't'  print 't' for EQ, 'f' for NE
3265    'Z'  print register and a comma, but print nothing for $fcc0
3266    '?'  Print 'l' if we are to use a branch likely instead of normal branch.
3267    '@'  Print the name of the assembler temporary register (at or $1).
3268    '.'  Print the name of the register with a hard-wired zero (zero or $0).
3269    '$'  Print the name of the stack pointer register (sp or $29).
3270    '+'  Print the name of the gp register (gp or $28).  */
3271
3272 void
3273 print_operand (FILE *file, rtx op, int letter)
3274 {
3275   enum rtx_code code;
3276
3277   if (PRINT_OPERAND_PUNCT_VALID_P (letter))
3278     {
3279       switch (letter)
3280         {
3281         case '?':
3282           if (iq2000_branch_likely)
3283             putc ('l', file);
3284           break;
3285
3286         case '@':
3287           fputs (reg_names [GP_REG_FIRST + 1], file);
3288           break;
3289
3290         case '.':
3291           fputs (reg_names [GP_REG_FIRST + 0], file);
3292           break;
3293
3294         case '$':
3295           fputs (reg_names[STACK_POINTER_REGNUM], file);
3296           break;
3297
3298         case '+':
3299           fputs (reg_names[GP_REG_FIRST + 28], file);
3300           break;
3301
3302         default:
3303           error ("PRINT_OPERAND: Unknown punctuation '%c'", letter);
3304           break;
3305         }
3306
3307       return;
3308     }
3309
3310   if (! op)
3311     {
3312       error ("PRINT_OPERAND null pointer");
3313       return;
3314     }
3315
3316   code = GET_CODE (op);
3317
3318   if (code == SIGN_EXTEND)
3319     op = XEXP (op, 0), code = GET_CODE (op);
3320
3321   if (letter == 'C')
3322     switch (code)
3323       {
3324       case EQ:  fputs ("eq",  file); break;
3325       case NE:  fputs ("ne",  file); break;
3326       case GT:  fputs ("gt",  file); break;
3327       case GE:  fputs ("ge",  file); break;
3328       case LT:  fputs ("lt",  file); break;
3329       case LE:  fputs ("le",  file); break;
3330       case GTU: fputs ("ne", file); break;
3331       case GEU: fputs ("geu", file); break;
3332       case LTU: fputs ("ltu", file); break;
3333       case LEU: fputs ("eq", file); break;
3334       default:
3335         abort_with_insn (op, "PRINT_OPERAND, invalid insn for %%C");
3336       }
3337
3338   else if (letter == 'N')
3339     switch (code)
3340       {
3341       case EQ:  fputs ("ne",  file); break;
3342       case NE:  fputs ("eq",  file); break;
3343       case GT:  fputs ("le",  file); break;
3344       case GE:  fputs ("lt",  file); break;
3345       case LT:  fputs ("ge",  file); break;
3346       case LE:  fputs ("gt",  file); break;
3347       case GTU: fputs ("leu", file); break;
3348       case GEU: fputs ("ltu", file); break;
3349       case LTU: fputs ("geu", file); break;
3350       case LEU: fputs ("gtu", file); break;
3351       default:
3352         abort_with_insn (op, "PRINT_OPERAND, invalid insn for %%N");
3353       }
3354
3355   else if (letter == 'F')
3356     switch (code)
3357       {
3358       case EQ: fputs ("c1f", file); break;
3359       case NE: fputs ("c1t", file); break;
3360       default:
3361         abort_with_insn (op, "PRINT_OPERAND, invalid insn for %%F");
3362       }
3363
3364   else if (letter == 'W')
3365     switch (code)
3366       {
3367       case EQ: fputs ("c1t", file); break;
3368       case NE: fputs ("c1f", file); break;
3369       default:
3370         abort_with_insn (op, "PRINT_OPERAND, invalid insn for %%W");
3371       }
3372
3373   else if (letter == 'A')
3374     fputs (code == LABEL_REF ? "i" : "in", file);
3375
3376   else if (letter == 'P')
3377     {
3378       if (code == LABEL_REF)
3379         output_addr_const (file, op);
3380       else if (code != PC)
3381         output_operand_lossage ("invalid %%P operand");
3382     }
3383
3384   else if (letter == 'p')
3385     {
3386       int value;
3387       if (code != CONST_INT
3388           || (value = exact_log2 (INTVAL (op))) < 0)
3389         output_operand_lossage ("invalid %%p value");
3390       fprintf (file, "%d", value);
3391     }
3392
3393   else if (letter == 'Z')
3394     {
3395       int regnum;
3396
3397       if (code != REG)
3398         abort ();
3399
3400       regnum = REGNO (op);
3401       abort ();
3402
3403       fprintf (file, "%s,", reg_names[regnum]);
3404     }
3405
3406   else if (code == REG || code == SUBREG)
3407     {
3408       int regnum;
3409
3410       if (code == REG)
3411         regnum = REGNO (op);
3412       else
3413         regnum = true_regnum (op);
3414
3415       if ((letter == 'M' && ! WORDS_BIG_ENDIAN)
3416           || (letter == 'L' && WORDS_BIG_ENDIAN)
3417           || letter == 'D')
3418         regnum++;
3419
3420       fprintf (file, "%s", reg_names[regnum]);
3421     }
3422
3423   else if (code == MEM)
3424     {
3425       if (letter == 'D')
3426         output_address (plus_constant (XEXP (op, 0), 4));
3427       else
3428         output_address (XEXP (op, 0));
3429     }
3430
3431   else if (code == CONST_DOUBLE
3432            && GET_MODE_CLASS (GET_MODE (op)) == MODE_FLOAT)
3433     {
3434       char s[60];
3435
3436       real_to_decimal (s, CONST_DOUBLE_REAL_VALUE (op), sizeof (s), 0, 1);
3437       fputs (s, file);
3438     }
3439
3440   else if (letter == 'x' && GET_CODE (op) == CONST_INT)
3441     fprintf (file, HOST_WIDE_INT_PRINT_HEX, 0xffff & INTVAL(op));
3442
3443   else if (letter == 'X' && GET_CODE(op) == CONST_INT)
3444     fprintf (file, HOST_WIDE_INT_PRINT_HEX, 0xffff & (INTVAL (op) >> 16));
3445
3446   else if (letter == 'd' && GET_CODE(op) == CONST_INT)
3447     fprintf (file, HOST_WIDE_INT_PRINT_DEC, (INTVAL(op)));
3448
3449   else if (letter == 'z' && GET_CODE (op) == CONST_INT && INTVAL (op) == 0)
3450     fputs (reg_names[GP_REG_FIRST], file);
3451
3452   else if (letter == 'd' || letter == 'x' || letter == 'X')
3453     output_operand_lossage ("invalid use of %%d, %%x, or %%X");
3454
3455   else if (letter == 'B')
3456     fputs (code == EQ ? "z" : "n", file);
3457   else if (letter == 'b')
3458     fputs (code == EQ ? "n" : "z", file);
3459   else if (letter == 'T')
3460     fputs (code == EQ ? "f" : "t", file);
3461   else if (letter == 't')
3462     fputs (code == EQ ? "t" : "f", file);
3463
3464   else if (code == CONST && GET_CODE (XEXP (op, 0)) == REG)
3465     {
3466       print_operand (file, XEXP (op, 0), letter);
3467     }
3468
3469   else
3470     output_addr_const (file, op);
3471 }
3472
3473 static bool
3474 iq2000_rtx_costs (rtx x, int code, int outer_code ATTRIBUTE_UNUSED, int * total)
3475 {
3476   enum machine_mode mode = GET_MODE (x);
3477
3478   switch (code)
3479     {
3480     case MEM:
3481       {
3482         int num_words = (GET_MODE_SIZE (mode) > UNITS_PER_WORD) ? 2 : 1;
3483
3484         if (simple_memory_operand (x, mode))
3485           return COSTS_N_INSNS (num_words);
3486
3487         * total = COSTS_N_INSNS (2 * num_words);
3488         break;
3489       }
3490       
3491     case FFS:
3492       * total = COSTS_N_INSNS (6);
3493       break;
3494
3495     case AND:
3496     case IOR:
3497     case XOR:
3498     case NOT:
3499       * total = COSTS_N_INSNS (mode == DImode ? 2 : 1);
3500       break;
3501
3502     case ASHIFT:
3503     case ASHIFTRT:
3504     case LSHIFTRT:
3505       if (mode == DImode)
3506         * total = COSTS_N_INSNS ((GET_CODE (XEXP (x, 1)) == CONST_INT) ? 4 : 12);
3507       else
3508         * total = COSTS_N_INSNS (1);
3509     break;                                                              
3510
3511     case ABS:
3512       if (mode == SFmode || mode == DFmode)
3513         * total = COSTS_N_INSNS (1);
3514       else
3515         * total = COSTS_N_INSNS (4);
3516       break;
3517     
3518     case PLUS:
3519     case MINUS:
3520       if (mode == SFmode || mode == DFmode)
3521         * total = COSTS_N_INSNS (6);
3522       else if (mode == DImode)
3523         * total = COSTS_N_INSNS (4);
3524       else
3525         * total = COSTS_N_INSNS (1);
3526       break;
3527     
3528     case NEG:
3529       * total = (mode == DImode) ? 4 : 1;
3530       break;
3531
3532     case MULT:
3533       if (mode == SFmode)
3534         * total = COSTS_N_INSNS (7);
3535       else if (mode == DFmode)
3536         * total = COSTS_N_INSNS (8);
3537       else
3538         * total = COSTS_N_INSNS (10);
3539       break;
3540
3541     case DIV:
3542     case MOD:
3543       if (mode == SFmode)
3544         * total = COSTS_N_INSNS (23);
3545       else if (mode == DFmode)
3546         * total = COSTS_N_INSNS (36);
3547       else
3548         * total = COSTS_N_INSNS (69);
3549       break;
3550       
3551     case UDIV:
3552     case UMOD:
3553       * total = COSTS_N_INSNS (69);
3554       break;
3555       
3556     case SIGN_EXTEND:
3557       * total = COSTS_N_INSNS (2);
3558       break;
3559     
3560     case ZERO_EXTEND:
3561       * total = COSTS_N_INSNS (1);
3562       break;
3563
3564     case CONST_INT:
3565       * total = 0;
3566       break;
3567     
3568     case LABEL_REF:
3569       * total = COSTS_N_INSNS (2);
3570       break;
3571
3572     case CONST:
3573       {
3574         rtx offset = const0_rtx;
3575         rtx symref = eliminate_constant_term (XEXP (x, 0), & offset);
3576
3577         if (GET_CODE (symref) == LABEL_REF)
3578           * total = COSTS_N_INSNS (2);
3579         else if (GET_CODE (symref) != SYMBOL_REF)
3580           * total = COSTS_N_INSNS (4);
3581         /* Let's be paranoid....  */
3582         else if (INTVAL (offset) < -32768 || INTVAL (offset) > 32767)
3583           * total = COSTS_N_INSNS (2);
3584         else
3585           * total = COSTS_N_INSNS (SYMBOL_REF_FLAG (symref) ? 1 : 2);
3586         break;
3587       }
3588
3589     case SYMBOL_REF:
3590       * total = COSTS_N_INSNS (SYMBOL_REF_FLAG (x) ? 1 : 2);
3591       break;
3592     
3593     case CONST_DOUBLE:
3594       {
3595         rtx high, low;
3596       
3597         split_double (x, & high, & low);
3598       
3599         * total = COSTS_N_INSNS (  (high == CONST0_RTX (GET_MODE (high))
3600                                   || low == CONST0_RTX (GET_MODE (low)))
3601                                    ? 2 : 4);
3602         break;
3603       }
3604     
3605     default:
3606       return false;
3607     }
3608   return true;
3609 }
3610
3611 #include "gt-iq2000.h"