OSDN Git Service

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