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