OSDN Git Service

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