xref: /openbsd-src/gnu/gcc/gcc/config/iq2000/iq2000.c (revision 404b540a9034ac75a6199ad1a32d1bbc7a0d4210)
1 /* Subroutines used for code generation on Vitesse IQ2000 processors
2    Copyright (C) 2003, 2004, 2005 Free Software Foundation, Inc.
3 
4 This file is part of GCC.
5 
6 GCC is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
10 
11 GCC is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 GNU General Public License for more details.
15 
16 You should have received a copy of the GNU General Public License
17 along with GCC; see the file COPYING.  If not, write to
18 the Free Software Foundation, 51 Franklin Street, Fifth Floor,
19 Boston, 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 
54 enum 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 
69 struct 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 
75 struct 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 
92 struct 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.  */
113 char iq2000_print_operand_punct[256];
114 
115 /* The target cpu for optimization and scheduling.  */
116 enum processor_type iq2000_tune;
117 
118 /* Which instruction set architecture to use.  */
119 int iq2000_isa;
120 
121 /* Cached operands, and operator to compare for use in set/branch/trap
122    on condition codes.  */
123 rtx branch_cmp[2];
124 
125 /* What type of branch to use.  */
126 enum cmp_type branch_type;
127 
128 /* Local variables.  */
129 
130 /* The next branch instruction is a branch likely, not branch normal.  */
131 static int iq2000_branch_likely;
132 
133 /* Count of delay slots and how many are filled.  */
134 static int dslots_load_total;
135 static int dslots_load_filled;
136 static int dslots_jump_total;
137 
138 /* # of nops needed by previous insn.  */
139 static int dslots_number_nops;
140 
141 /* Number of 1/2/3 word references to data items (i.e., not jal's).  */
142 static int num_refs[3];
143 
144 /* Registers to check for load delay.  */
145 static rtx iq2000_load_reg;
146 static rtx iq2000_load_reg2;
147 static rtx iq2000_load_reg3;
148 static rtx iq2000_load_reg4;
149 
150 /* Mode used for saving/restoring general purpose registers.  */
151 static enum machine_mode gpr_mode;
152 
153 
154 /* Initialize the GCC target structure.  */
155 static struct machine_function* iq2000_init_machine_status (void);
156 static bool iq2000_handle_option      (size_t, const char *, int);
157 static section *iq2000_select_rtx_section (enum machine_mode, rtx,
158 					   unsigned HOST_WIDE_INT);
159 static void iq2000_init_builtins      (void);
160 static rtx  iq2000_expand_builtin     (tree, rtx, rtx, enum machine_mode, int);
161 static bool iq2000_return_in_memory   (tree, tree);
162 static void iq2000_setup_incoming_varargs (CUMULATIVE_ARGS *,
163 					   enum machine_mode, tree, int *,
164 					   int);
165 static bool iq2000_rtx_costs          (rtx, int, int, int *);
166 static int  iq2000_address_cost       (rtx);
167 static section *iq2000_select_section (tree, int, unsigned HOST_WIDE_INT);
168 static bool iq2000_return_in_memory   (tree, tree);
169 static bool iq2000_pass_by_reference  (CUMULATIVE_ARGS *, enum machine_mode,
170 				       tree, bool);
171 static 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 
215 struct gcc_target targetm = TARGET_INITIALIZER;
216 
217 /* Return nonzero if we split the address into high and low parts.  */
218 
219 int
iq2000_check_split(rtx address,enum machine_mode mode)220 iq2000_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 
238 int
iq2000_reg_mode_ok_for_base_p(rtx reg,enum machine_mode mode ATTRIBUTE_UNUSED,int strict)239 iq2000_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 
252 int
iq2000_legitimate_address_p(enum machine_mode mode,rtx xinsn,int strict)253 iq2000_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 
329 const char *
iq2000_fill_delay_slot(const char * ret,enum delay_type type,rtx operands[],rtx cur_insn)330 iq2000_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 
392 static void
iq2000_count_memory_refs(rtx op,int num)393 iq2000_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 
504 static void
abort_with_insn(rtx insn,const char * reason)505 abort_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 
514 const char *
iq2000_move_1word(rtx operands[],rtx insn,int unsignedp)515 iq2000_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 
744 static int
iq2000_address_cost(rtx addr)745 iq2000_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 
812 static enum internal_test
map_test_to_internal_test(enum rtx_code test_code)813 map_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 
841 rtx
gen_int_relational(enum rtx_code test_code,rtx result,rtx cmp0,rtx cmp1,int * p_invert)842 gen_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 
1005 void
gen_conditional_branch(rtx operands[],enum rtx_code test_code)1006 gen_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 
1078 void
init_cumulative_args(CUMULATIVE_ARGS * cum,tree fntype,rtx libname ATTRIBUTE_UNUSED)1079 init_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 
1123 void
function_arg_advance(CUMULATIVE_ARGS * cum,enum machine_mode mode,tree type,int named)1124 function_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 
1187 struct rtx_def *
function_arg(CUMULATIVE_ARGS * cum,enum machine_mode mode,tree type,int named)1188 function_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 
1345 static int
iq2000_arg_partial_bytes(CUMULATIVE_ARGS * cum,enum machine_mode mode,tree type ATTRIBUTE_UNUSED,bool named ATTRIBUTE_UNUSED)1346 iq2000_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 
1362 void
iq2000_va_start(tree valist,rtx nextarg)1363 iq2000_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 
1385 static struct machine_function *
iq2000_init_machine_status(void)1386 iq2000_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 
1397 static bool
iq2000_handle_option(size_t code,const char * arg,int value ATTRIBUTE_UNUSED)1398 iq2000_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 
1424 void
override_options(void)1425 override_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 
1465 HOST_WIDE_INT
iq2000_debugger_offset(rtx addr,HOST_WIDE_INT offset)1466 iq2000_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 
1500 void
final_prescan_insn(rtx insn,rtx opvec[]ATTRIBUTE_UNUSED,int noperands ATTRIBUTE_UNUSED)1501 final_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 
1596 HOST_WIDE_INT
compute_frame_size(HOST_WIDE_INT size)1597 compute_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 
1701 int
iq2000_initial_elimination_offset(int from,int to ATTRIBUTE_UNUSED)1702 iq2000_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 
1738 static rtx
iq2000_add_large_offset_to_sp(HOST_WIDE_INT offset)1739 iq2000_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 
1752 static void
iq2000_annotate_frame_insn(rtx insn,rtx dwarf_pattern)1753 iq2000_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 
1764 static void
iq2000_emit_frame_related_store(rtx mem,rtx reg,HOST_WIDE_INT offset)1765 iq2000_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 
1776 static void
save_restore_insns(int store_p)1777 save_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 
1855 void
iq2000_expand_prologue(void)1856 iq2000_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 
2041 void
iq2000_expand_epilogue(void)2042 iq2000_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 
2102 void
iq2000_expand_eh_return(rtx address)2103 iq2000_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 
2116 int
iq2000_can_use_return_insn(void)2117 iq2000_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 
2133 static int
symbolic_expression_p(rtx x)2134 symbolic_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 
2155 static section *
iq2000_select_rtx_section(enum machine_mode mode,rtx x ATTRIBUTE_UNUSED,unsigned HOST_WIDE_INT align)2156 iq2000_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 
2171 static section *
iq2000_select_section(tree decl,int reloc ATTRIBUTE_UNUSED,unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED)2172 iq2000_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 
2209 rtx
iq2000_function_value(tree valtype,tree func ATTRIBUTE_UNUSED)2210 iq2000_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 
2225 static bool
iq2000_pass_by_reference(CUMULATIVE_ARGS * cum,enum machine_mode mode,tree type,bool named ATTRIBUTE_UNUSED)2226 iq2000_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 
2256 int
iq2000_adjust_insn_length(rtx insn,int length)2257 iq2000_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 
2284 char *
iq2000_output_conditional_branch(rtx insn,rtx * operands,int two_operands_p,int float_p,int inverted_p,int length)2285 iq2000_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 
2442 static void
iq2000_init_builtins(void)2443 iq2000_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) */
2481 void_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 
2575 static rtx
expand_one_builtin(enum insn_code icode,rtx target,tree arglist,enum rtx_code * code,int argcount)2576 expand_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 
2653 static rtx
iq2000_expand_builtin(tree exp,rtx target,rtx subtarget ATTRIBUTE_UNUSED,enum machine_mode mode ATTRIBUTE_UNUSED,int ignore ATTRIBUTE_UNUSED)2654 iq2000_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 
2837 static bool
iq2000_return_in_memory(tree type,tree fntype ATTRIBUTE_UNUSED)2838 iq2000_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 
2846 static void
iq2000_setup_incoming_varargs(CUMULATIVE_ARGS * cum,enum machine_mode mode ATTRIBUTE_UNUSED,tree type ATTRIBUTE_UNUSED,int * pretend_size,int no_rtl)2847 iq2000_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 
2892 void
print_operand_address(FILE * file,rtx addr)2893 print_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 
3020 void
print_operand(FILE * file,rtx op,int letter)3021 print_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 
3213 static bool
iq2000_rtx_costs(rtx x,int code,int outer_code ATTRIBUTE_UNUSED,int * total)3214 iq2000_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