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