OSDN Git Service

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