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