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