1/* Subroutines for insn-output.c for Tensilica's Xtensa architecture.
2   Copyright 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
3   Contributed by Bob Wilson (bwilson@tensilica.com) at Tensilica.
4
5This file is part of GCC.
6
7GCC is free software; you can redistribute it and/or modify it under
8the terms of the GNU General Public License as published by the Free
9Software Foundation; either version 2, or (at your option) any later
10version.
11
12GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13WARRANTY; without even the implied warranty of MERCHANTABILITY or
14FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
15for more details.
16
17You should have received a copy of the GNU General Public License
18along with GCC; see the file COPYING.  If not, write to the Free
19Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
2002110-1301, USA.  */
21
22#include "config.h"
23#include "system.h"
24#include "coretypes.h"
25#include "tm.h"
26#include "rtl.h"
27#include "regs.h"
28#include "hard-reg-set.h"
29#include "basic-block.h"
30#include "real.h"
31#include "insn-config.h"
32#include "conditions.h"
33#include "insn-flags.h"
34#include "insn-attr.h"
35#include "insn-codes.h"
36#include "recog.h"
37#include "output.h"
38#include "tree.h"
39#include "expr.h"
40#include "flags.h"
41#include "reload.h"
42#include "tm_p.h"
43#include "function.h"
44#include "toplev.h"
45#include "optabs.h"
46#include "libfuncs.h"
47#include "ggc.h"
48#include "target.h"
49#include "target-def.h"
50#include "langhooks.h"
51#include "tree-gimple.h"
52
53
54/* Enumeration for all of the relational tests, so that we can build
55   arrays indexed by the test type, and not worry about the order
56   of EQ, NE, etc.  */
57
58enum internal_test
59{
60  ITEST_EQ,
61  ITEST_NE,
62  ITEST_GT,
63  ITEST_GE,
64  ITEST_LT,
65  ITEST_LE,
66  ITEST_GTU,
67  ITEST_GEU,
68  ITEST_LTU,
69  ITEST_LEU,
70  ITEST_MAX
71};
72
73/* Cached operands, and operator to compare for use in set/branch on
74   condition codes.  */
75rtx branch_cmp[2];
76
77/* what type of branch to use */
78enum cmp_type branch_type;
79
80/* Array giving truth value on whether or not a given hard register
81   can support a given mode.  */
82char xtensa_hard_regno_mode_ok[(int) MAX_MACHINE_MODE][FIRST_PSEUDO_REGISTER];
83
84/* Current frame size calculated by compute_frame_size.  */
85unsigned xtensa_current_frame_size;
86
87/* Largest block move to handle in-line.  */
88#define LARGEST_MOVE_RATIO 15
89
90/* Define the structure for the machine field in struct function.  */
91struct machine_function GTY(())
92{
93  int accesses_prev_frame;
94  bool need_a7_copy;
95  bool vararg_a7;
96  rtx set_frame_ptr_insn;
97};
98
99/* Vector, indexed by hard register number, which contains 1 for a
100   register that is allowable in a candidate for leaf function
101   treatment.  */
102
103const char xtensa_leaf_regs[FIRST_PSEUDO_REGISTER] =
104{
105  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
106  1, 1, 1,
107  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
108  1
109};
110
111/* Map hard register number to register class */
112const enum reg_class xtensa_regno_to_class[FIRST_PSEUDO_REGISTER] =
113{
114  RL_REGS,	SP_REG,		RL_REGS,	RL_REGS,
115  RL_REGS,	RL_REGS,	RL_REGS,	GR_REGS,
116  RL_REGS,	RL_REGS,	RL_REGS,	RL_REGS,
117  RL_REGS,	RL_REGS,	RL_REGS,	RL_REGS,
118  AR_REGS,	AR_REGS,	BR_REGS,
119  FP_REGS,	FP_REGS,	FP_REGS,	FP_REGS,
120  FP_REGS,	FP_REGS,	FP_REGS,	FP_REGS,
121  FP_REGS,	FP_REGS,	FP_REGS,	FP_REGS,
122  FP_REGS,	FP_REGS,	FP_REGS,	FP_REGS,
123  ACC_REG,
124};
125
126/* Map register constraint character to register class.  */
127enum reg_class xtensa_char_to_class[256] =
128{
129  NO_REGS,	NO_REGS,	NO_REGS,	NO_REGS,
130  NO_REGS,	NO_REGS,	NO_REGS,	NO_REGS,
131  NO_REGS,	NO_REGS,	NO_REGS,	NO_REGS,
132  NO_REGS,	NO_REGS,	NO_REGS,	NO_REGS,
133  NO_REGS,	NO_REGS,	NO_REGS,	NO_REGS,
134  NO_REGS,	NO_REGS,	NO_REGS,	NO_REGS,
135  NO_REGS,	NO_REGS,	NO_REGS,	NO_REGS,
136  NO_REGS,	NO_REGS,	NO_REGS,	NO_REGS,
137  NO_REGS,	NO_REGS,	NO_REGS,	NO_REGS,
138  NO_REGS,	NO_REGS,	NO_REGS,	NO_REGS,
139  NO_REGS,	NO_REGS,	NO_REGS,	NO_REGS,
140  NO_REGS,	NO_REGS,	NO_REGS,	NO_REGS,
141  NO_REGS,	NO_REGS,	NO_REGS,	NO_REGS,
142  NO_REGS,	NO_REGS,	NO_REGS,	NO_REGS,
143  NO_REGS,	NO_REGS,	NO_REGS,	NO_REGS,
144  NO_REGS,	NO_REGS,	NO_REGS,	NO_REGS,
145  NO_REGS,	NO_REGS,	NO_REGS,	NO_REGS,
146  NO_REGS,	NO_REGS,	NO_REGS,	NO_REGS,
147  NO_REGS,	NO_REGS,	NO_REGS,	NO_REGS,
148  NO_REGS,	NO_REGS,	NO_REGS,	NO_REGS,
149  NO_REGS,	NO_REGS,	NO_REGS,	NO_REGS,
150  NO_REGS,	NO_REGS,	NO_REGS,	NO_REGS,
151  NO_REGS,	NO_REGS,	NO_REGS,	NO_REGS,
152  NO_REGS,	NO_REGS,	NO_REGS,	NO_REGS,
153  NO_REGS,	NO_REGS,	NO_REGS,	NO_REGS,
154  NO_REGS,	NO_REGS,	NO_REGS,	NO_REGS,
155  NO_REGS,	NO_REGS,	NO_REGS,	NO_REGS,
156  NO_REGS,	NO_REGS,	NO_REGS,	NO_REGS,
157  NO_REGS,	NO_REGS,	NO_REGS,	NO_REGS,
158  NO_REGS,	NO_REGS,	NO_REGS,	NO_REGS,
159  NO_REGS,	NO_REGS,	NO_REGS,	NO_REGS,
160  NO_REGS,	NO_REGS,	NO_REGS,	NO_REGS,
161  NO_REGS,	NO_REGS,	NO_REGS,	NO_REGS,
162  NO_REGS,	NO_REGS,	NO_REGS,	NO_REGS,
163  NO_REGS,	NO_REGS,	NO_REGS,	NO_REGS,
164  NO_REGS,	NO_REGS,	NO_REGS,	NO_REGS,
165  NO_REGS,	NO_REGS,	NO_REGS,	NO_REGS,
166  NO_REGS,	NO_REGS,	NO_REGS,	NO_REGS,
167  NO_REGS,	NO_REGS,	NO_REGS,	NO_REGS,
168  NO_REGS,	NO_REGS,	NO_REGS,	NO_REGS,
169  NO_REGS,	NO_REGS,	NO_REGS,	NO_REGS,
170  NO_REGS,	NO_REGS,	NO_REGS,	NO_REGS,
171  NO_REGS,	NO_REGS,	NO_REGS,	NO_REGS,
172  NO_REGS,	NO_REGS,	NO_REGS,	NO_REGS,
173  NO_REGS,	NO_REGS,	NO_REGS,	NO_REGS,
174  NO_REGS,	NO_REGS,	NO_REGS,	NO_REGS,
175  NO_REGS,	NO_REGS,	NO_REGS,	NO_REGS,
176  NO_REGS,	NO_REGS,	NO_REGS,	NO_REGS,
177  NO_REGS,	NO_REGS,	NO_REGS,	NO_REGS,
178  NO_REGS,	NO_REGS,	NO_REGS,	NO_REGS,
179  NO_REGS,	NO_REGS,	NO_REGS,	NO_REGS,
180  NO_REGS,	NO_REGS,	NO_REGS,	NO_REGS,
181  NO_REGS,	NO_REGS,	NO_REGS,	NO_REGS,
182  NO_REGS,	NO_REGS,	NO_REGS,	NO_REGS,
183  NO_REGS,	NO_REGS,	NO_REGS,	NO_REGS,
184  NO_REGS,	NO_REGS,	NO_REGS,	NO_REGS,
185  NO_REGS,	NO_REGS,	NO_REGS,	NO_REGS,
186  NO_REGS,	NO_REGS,	NO_REGS,	NO_REGS,
187  NO_REGS,	NO_REGS,	NO_REGS,	NO_REGS,
188  NO_REGS,	NO_REGS,	NO_REGS,	NO_REGS,
189  NO_REGS,	NO_REGS,	NO_REGS,	NO_REGS,
190  NO_REGS,	NO_REGS,	NO_REGS,	NO_REGS,
191  NO_REGS,	NO_REGS,	NO_REGS,	NO_REGS,
192  NO_REGS,	NO_REGS,	NO_REGS,	NO_REGS,
193};
194
195static enum internal_test map_test_to_internal_test (enum rtx_code);
196static rtx gen_int_relational (enum rtx_code, rtx, rtx, int *);
197static rtx gen_float_relational (enum rtx_code, rtx, rtx);
198static rtx gen_conditional_move (rtx);
199static rtx fixup_subreg_mem (rtx);
200static struct machine_function * xtensa_init_machine_status (void);
201static bool xtensa_return_in_msb (tree);
202static void printx (FILE *, signed int);
203static void xtensa_function_epilogue (FILE *, HOST_WIDE_INT);
204static rtx xtensa_builtin_saveregs (void);
205static unsigned int xtensa_multibss_section_type_flags (tree, const char *,
206							int) ATTRIBUTE_UNUSED;
207static void xtensa_select_rtx_section (enum machine_mode, rtx,
208				       unsigned HOST_WIDE_INT);
209static bool xtensa_rtx_costs (rtx, int, int, int *);
210static tree xtensa_build_builtin_va_list (void);
211static bool xtensa_return_in_memory (tree, tree);
212static tree xtensa_gimplify_va_arg_expr (tree, tree, tree *, tree *);
213
214static const int reg_nonleaf_alloc_order[FIRST_PSEUDO_REGISTER] =
215  REG_ALLOC_ORDER;
216
217
218/* This macro generates the assembly code for function exit,
219   on machines that need it.  If FUNCTION_EPILOGUE is not defined
220   then individual return instructions are generated for each
221   return statement.  Args are same as for FUNCTION_PROLOGUE.  */
222
223#undef TARGET_ASM_FUNCTION_EPILOGUE
224#define TARGET_ASM_FUNCTION_EPILOGUE xtensa_function_epilogue
225
226/* These hooks specify assembly directives for creating certain kinds
227   of integer object.  */
228
229#undef TARGET_ASM_ALIGNED_SI_OP
230#define TARGET_ASM_ALIGNED_SI_OP "\t.word\t"
231
232#undef TARGET_ASM_SELECT_RTX_SECTION
233#define TARGET_ASM_SELECT_RTX_SECTION  xtensa_select_rtx_section
234
235#undef TARGET_DEFAULT_TARGET_FLAGS
236#define TARGET_DEFAULT_TARGET_FLAGS (TARGET_DEFAULT | MASK_FUSED_MADD)
237
238#undef TARGET_RTX_COSTS
239#define TARGET_RTX_COSTS xtensa_rtx_costs
240#undef TARGET_ADDRESS_COST
241#define TARGET_ADDRESS_COST hook_int_rtx_0
242
243#undef TARGET_BUILD_BUILTIN_VA_LIST
244#define TARGET_BUILD_BUILTIN_VA_LIST xtensa_build_builtin_va_list
245
246#undef TARGET_PROMOTE_FUNCTION_ARGS
247#define TARGET_PROMOTE_FUNCTION_ARGS hook_bool_tree_true
248#undef TARGET_PROMOTE_FUNCTION_RETURN
249#define TARGET_PROMOTE_FUNCTION_RETURN hook_bool_tree_true
250#undef TARGET_PROMOTE_PROTOTYPES
251#define TARGET_PROMOTE_PROTOTYPES hook_bool_tree_true
252
253#undef TARGET_RETURN_IN_MEMORY
254#define TARGET_RETURN_IN_MEMORY xtensa_return_in_memory
255#undef TARGET_SPLIT_COMPLEX_ARG
256#define TARGET_SPLIT_COMPLEX_ARG hook_bool_tree_true
257#undef TARGET_MUST_PASS_IN_STACK
258#define TARGET_MUST_PASS_IN_STACK must_pass_in_stack_var_size
259
260#undef TARGET_EXPAND_BUILTIN_SAVEREGS
261#define TARGET_EXPAND_BUILTIN_SAVEREGS xtensa_builtin_saveregs
262#undef TARGET_GIMPLIFY_VA_ARG_EXPR
263#define TARGET_GIMPLIFY_VA_ARG_EXPR xtensa_gimplify_va_arg_expr
264
265#undef TARGET_RETURN_IN_MSB
266#define TARGET_RETURN_IN_MSB xtensa_return_in_msb
267
268struct gcc_target targetm = TARGET_INITIALIZER;
269
270
271/*
272 * Functions to test Xtensa immediate operand validity.
273 */
274
275bool
276xtensa_simm8 (HOST_WIDE_INT v)
277{
278  return v >= -128 && v <= 127;
279}
280
281
282bool
283xtensa_simm8x256 (HOST_WIDE_INT v)
284{
285  return (v & 255) == 0 && (v >= -32768 && v <= 32512);
286}
287
288
289bool
290xtensa_simm12b (HOST_WIDE_INT v)
291{
292  return v >= -2048 && v <= 2047;
293}
294
295
296static bool
297xtensa_uimm8 (HOST_WIDE_INT v)
298{
299  return v >= 0 && v <= 255;
300}
301
302
303static bool
304xtensa_uimm8x2 (HOST_WIDE_INT v)
305{
306  return (v & 1) == 0 && (v >= 0 && v <= 510);
307}
308
309
310static bool
311xtensa_uimm8x4 (HOST_WIDE_INT v)
312{
313  return (v & 3) == 0 && (v >= 0 && v <= 1020);
314}
315
316
317static bool
318xtensa_b4const (HOST_WIDE_INT v)
319{
320  switch (v)
321    {
322    case -1:
323    case 1:
324    case 2:
325    case 3:
326    case 4:
327    case 5:
328    case 6:
329    case 7:
330    case 8:
331    case 10:
332    case 12:
333    case 16:
334    case 32:
335    case 64:
336    case 128:
337    case 256:
338      return true;
339    }
340  return false;
341}
342
343
344bool
345xtensa_b4const_or_zero (HOST_WIDE_INT v)
346{
347  if (v == 0)
348    return true;
349  return xtensa_b4const (v);
350}
351
352
353bool
354xtensa_b4constu (HOST_WIDE_INT v)
355{
356  switch (v)
357    {
358    case 32768:
359    case 65536:
360    case 2:
361    case 3:
362    case 4:
363    case 5:
364    case 6:
365    case 7:
366    case 8:
367    case 10:
368    case 12:
369    case 16:
370    case 32:
371    case 64:
372    case 128:
373    case 256:
374      return true;
375    }
376  return false;
377}
378
379
380bool
381xtensa_mask_immediate (HOST_WIDE_INT v)
382{
383#define MAX_MASK_SIZE 16
384  int mask_size;
385
386  for (mask_size = 1; mask_size <= MAX_MASK_SIZE; mask_size++)
387    {
388      if ((v & 1) == 0)
389	return false;
390      v = v >> 1;
391      if (v == 0)
392	return true;
393    }
394
395  return false;
396}
397
398
399bool
400xtensa_const_ok_for_letter_p (HOST_WIDE_INT v, int c)
401{
402  switch (c)
403    {
404    case 'I': return xtensa_simm12b (v);
405    case 'J': return xtensa_simm8 (v);
406    case 'K': return (v == 0 || xtensa_b4const (v));
407    case 'L': return xtensa_b4constu (v);
408    case 'M': return (v >= -32 && v <= 95);
409    case 'N': return xtensa_simm8x256 (v);
410    case 'O': return (v == -1 || (v >= 1 && v <= 15));
411    case 'P': return xtensa_mask_immediate (v);
412    default: break;
413    }
414  return false;
415}
416
417
418/* This is just like the standard true_regnum() function except that it
419   works even when reg_renumber is not initialized.  */
420
421int
422xt_true_regnum (rtx x)
423{
424  if (GET_CODE (x) == REG)
425    {
426      if (reg_renumber
427	  && REGNO (x) >= FIRST_PSEUDO_REGISTER
428	  && reg_renumber[REGNO (x)] >= 0)
429	return reg_renumber[REGNO (x)];
430      return REGNO (x);
431    }
432  if (GET_CODE (x) == SUBREG)
433    {
434      int base = xt_true_regnum (SUBREG_REG (x));
435      if (base >= 0 && base < FIRST_PSEUDO_REGISTER)
436        return base + subreg_regno_offset (REGNO (SUBREG_REG (x)),
437                                           GET_MODE (SUBREG_REG (x)),
438                                           SUBREG_BYTE (x), GET_MODE (x));
439    }
440  return -1;
441}
442
443
444int
445xtensa_valid_move (enum machine_mode mode, rtx *operands)
446{
447  /* Either the destination or source must be a register, and the
448     MAC16 accumulator doesn't count.  */
449
450  if (register_operand (operands[0], mode))
451    {
452      int dst_regnum = xt_true_regnum (operands[0]);
453
454      /* The stack pointer can only be assigned with a MOVSP opcode.  */
455      if (dst_regnum == STACK_POINTER_REGNUM)
456	return (mode == SImode
457		&& register_operand (operands[1], mode)
458		&& !ACC_REG_P (xt_true_regnum (operands[1])));
459
460      if (!ACC_REG_P (dst_regnum))
461	return true;
462    }
463  if (register_operand (operands[1], mode))
464    {
465      int src_regnum = xt_true_regnum (operands[1]);
466      if (!ACC_REG_P (src_regnum))
467	return true;
468    }
469  return FALSE;
470}
471
472
473int
474smalloffset_mem_p (rtx op)
475{
476  if (GET_CODE (op) == MEM)
477    {
478      rtx addr = XEXP (op, 0);
479      if (GET_CODE (addr) == REG)
480	return REG_OK_FOR_BASE_P (addr);
481      if (GET_CODE (addr) == PLUS)
482	{
483	  rtx offset = XEXP (addr, 0);
484	  HOST_WIDE_INT val;
485	  if (GET_CODE (offset) != CONST_INT)
486	    offset = XEXP (addr, 1);
487	  if (GET_CODE (offset) != CONST_INT)
488	    return FALSE;
489
490	  val = INTVAL (offset);
491	  return (val & 3) == 0 && (val >= 0 && val <= 60);
492	}
493    }
494  return FALSE;
495}
496
497
498int
499constantpool_address_p (rtx addr)
500{
501  rtx sym = addr;
502
503  if (GET_CODE (addr) == CONST)
504    {
505      rtx offset;
506
507      /* Only handle (PLUS (SYM, OFFSET)) form.  */
508      addr = XEXP (addr, 0);
509      if (GET_CODE (addr) != PLUS)
510	return FALSE;
511
512      /* Make sure the address is word aligned.  */
513      offset = XEXP (addr, 1);
514      if ((GET_CODE (offset) != CONST_INT)
515	  || ((INTVAL (offset) & 3) != 0))
516	return FALSE;
517
518      sym = XEXP (addr, 0);
519    }
520
521  if ((GET_CODE (sym) == SYMBOL_REF)
522      && CONSTANT_POOL_ADDRESS_P (sym))
523    return TRUE;
524  return FALSE;
525}
526
527
528int
529constantpool_mem_p (rtx op)
530{
531  if (GET_CODE (op) == SUBREG)
532    op = SUBREG_REG (op);
533  if (GET_CODE (op) == MEM)
534    return constantpool_address_p (XEXP (op, 0));
535  return FALSE;
536}
537
538
539void
540xtensa_extend_reg (rtx dst, rtx src)
541{
542  rtx temp = gen_reg_rtx (SImode);
543  rtx shift = GEN_INT (BITS_PER_WORD - GET_MODE_BITSIZE (GET_MODE (src)));
544
545  /* Generate paradoxical subregs as needed so that the modes match.  */
546  src = simplify_gen_subreg (SImode, src, GET_MODE (src), 0);
547  dst = simplify_gen_subreg (SImode, dst, GET_MODE (dst), 0);
548
549  emit_insn (gen_ashlsi3 (temp, src, shift));
550  emit_insn (gen_ashrsi3 (dst, temp, shift));
551}
552
553
554bool
555xtensa_mem_offset (unsigned v, enum machine_mode mode)
556{
557  switch (mode)
558    {
559    case BLKmode:
560      /* Handle the worst case for block moves.  See xtensa_expand_block_move
561	 where we emit an optimized block move operation if the block can be
562	 moved in < "move_ratio" pieces.  The worst case is when the block is
563	 aligned but has a size of (3 mod 4) (does this happen?) so that the
564	 last piece requires a byte load/store.  */
565      return (xtensa_uimm8 (v)
566	      && xtensa_uimm8 (v + MOVE_MAX * LARGEST_MOVE_RATIO));
567
568    case QImode:
569      return xtensa_uimm8 (v);
570
571    case HImode:
572      return xtensa_uimm8x2 (v);
573
574    case DFmode:
575      return (xtensa_uimm8x4 (v) && xtensa_uimm8x4 (v + 4));
576
577    default:
578      break;
579    }
580
581  return xtensa_uimm8x4 (v);
582}
583
584
585bool
586xtensa_extra_constraint (rtx op, int c)
587{
588  /* Allow pseudo registers during reload.  */
589  if (GET_CODE (op) != MEM)
590    return (c >= 'R' && c <= 'U'
591	    && reload_in_progress && GET_CODE (op) == REG
592	    && REGNO (op) >= FIRST_PSEUDO_REGISTER);
593
594  switch (c)
595    {
596    case 'R': return smalloffset_mem_p (op);
597    case 'T': return !TARGET_CONST16 && constantpool_mem_p (op);
598    case 'U': return !constantpool_mem_p (op);
599    default: break;
600    }
601  return false;
602}
603
604
605/* Make normal rtx_code into something we can index from an array.  */
606
607static enum internal_test
608map_test_to_internal_test (enum rtx_code test_code)
609{
610  enum internal_test test = ITEST_MAX;
611
612  switch (test_code)
613    {
614    default:			break;
615    case EQ:  test = ITEST_EQ;  break;
616    case NE:  test = ITEST_NE;  break;
617    case GT:  test = ITEST_GT;  break;
618    case GE:  test = ITEST_GE;  break;
619    case LT:  test = ITEST_LT;  break;
620    case LE:  test = ITEST_LE;  break;
621    case GTU: test = ITEST_GTU; break;
622    case GEU: test = ITEST_GEU; break;
623    case LTU: test = ITEST_LTU; break;
624    case LEU: test = ITEST_LEU; break;
625    }
626
627  return test;
628}
629
630
631/* Generate the code to compare two integer values.  The return value is
632   the comparison expression.  */
633
634static rtx
635gen_int_relational (enum rtx_code test_code, /* relational test (EQ, etc) */
636		    rtx cmp0, /* first operand to compare */
637		    rtx cmp1, /* second operand to compare */
638		    int *p_invert /* whether branch needs to reverse test */)
639{
640  struct cmp_info
641  {
642    enum rtx_code test_code;	/* test code to use in insn */
643    bool (*const_range_p) (HOST_WIDE_INT); /* range check function */
644    int const_add;		/* constant to add (convert LE -> LT) */
645    int reverse_regs;		/* reverse registers in test */
646    int invert_const;		/* != 0 if invert value if cmp1 is constant */
647    int invert_reg;		/* != 0 if invert value if cmp1 is register */
648    int unsignedp;		/* != 0 for unsigned comparisons.  */
649  };
650
651  static struct cmp_info info[ (int)ITEST_MAX ] = {
652
653    { EQ,	xtensa_b4const_or_zero,	0, 0, 0, 0, 0 },	/* EQ  */
654    { NE,	xtensa_b4const_or_zero,	0, 0, 0, 0, 0 },	/* NE  */
655
656    { LT,	xtensa_b4const_or_zero,	1, 1, 1, 0, 0 },	/* GT  */
657    { GE,	xtensa_b4const_or_zero,	0, 0, 0, 0, 0 },	/* GE  */
658    { LT,	xtensa_b4const_or_zero,	0, 0, 0, 0, 0 },	/* LT  */
659    { GE,	xtensa_b4const_or_zero,	1, 1, 1, 0, 0 },	/* LE  */
660
661    { LTU,	xtensa_b4constu,	1, 1, 1, 0, 1 },	/* GTU */
662    { GEU,	xtensa_b4constu,	0, 0, 0, 0, 1 },	/* GEU */
663    { LTU,	xtensa_b4constu,	0, 0, 0, 0, 1 },	/* LTU */
664    { GEU,	xtensa_b4constu,	1, 1, 1, 0, 1 },	/* LEU */
665  };
666
667  enum internal_test test;
668  enum machine_mode mode;
669  struct cmp_info *p_info;
670
671  test = map_test_to_internal_test (test_code);
672  gcc_assert (test != ITEST_MAX);
673
674  p_info = &info[ (int)test ];
675
676  mode = GET_MODE (cmp0);
677  if (mode == VOIDmode)
678    mode = GET_MODE (cmp1);
679
680  /* Make sure we can handle any constants given to us.  */
681  if (GET_CODE (cmp1) == CONST_INT)
682    {
683      HOST_WIDE_INT value = INTVAL (cmp1);
684      unsigned HOST_WIDE_INT uvalue = (unsigned HOST_WIDE_INT)value;
685
686      /* if the immediate overflows or does not fit in the immediate field,
687	 spill it to a register */
688
689      if ((p_info->unsignedp ?
690	   (uvalue + p_info->const_add > uvalue) :
691	   (value + p_info->const_add > value)) != (p_info->const_add > 0))
692	{
693	  cmp1 = force_reg (mode, cmp1);
694	}
695      else if (!(p_info->const_range_p) (value + p_info->const_add))
696	{
697	  cmp1 = force_reg (mode, cmp1);
698	}
699    }
700  else if ((GET_CODE (cmp1) != REG) && (GET_CODE (cmp1) != SUBREG))
701    {
702      cmp1 = force_reg (mode, cmp1);
703    }
704
705  /* See if we need to invert the result.  */
706  *p_invert = ((GET_CODE (cmp1) == CONST_INT)
707	       ? p_info->invert_const
708	       : p_info->invert_reg);
709
710  /* Comparison to constants, may involve adding 1 to change a LT into LE.
711     Comparison between two registers, may involve switching operands.  */
712  if (GET_CODE (cmp1) == CONST_INT)
713    {
714      if (p_info->const_add != 0)
715	cmp1 = GEN_INT (INTVAL (cmp1) + p_info->const_add);
716
717    }
718  else if (p_info->reverse_regs)
719    {
720      rtx temp = cmp0;
721      cmp0 = cmp1;
722      cmp1 = temp;
723    }
724
725  return gen_rtx_fmt_ee (p_info->test_code, VOIDmode, cmp0, cmp1);
726}
727
728
729/* Generate the code to compare two float values.  The return value is
730   the comparison expression.  */
731
732static rtx
733gen_float_relational (enum rtx_code test_code, /* relational test (EQ, etc) */
734		      rtx cmp0, /* first operand to compare */
735		      rtx cmp1 /* second operand to compare */)
736{
737  rtx (*gen_fn) (rtx, rtx, rtx);
738  rtx brtmp;
739  int reverse_regs, invert;
740
741  switch (test_code)
742    {
743    case EQ: reverse_regs = 0; invert = 0; gen_fn = gen_seq_sf; break;
744    case NE: reverse_regs = 0; invert = 1; gen_fn = gen_seq_sf; break;
745    case LE: reverse_regs = 0; invert = 0; gen_fn = gen_sle_sf; break;
746    case GT: reverse_regs = 1; invert = 0; gen_fn = gen_slt_sf; break;
747    case LT: reverse_regs = 0; invert = 0; gen_fn = gen_slt_sf; break;
748    case GE: reverse_regs = 1; invert = 0; gen_fn = gen_sle_sf; break;
749    default:
750      fatal_insn ("bad test", gen_rtx_fmt_ee (test_code, VOIDmode, cmp0, cmp1));
751      reverse_regs = 0; invert = 0; gen_fn = 0; /* avoid compiler warnings */
752    }
753
754  if (reverse_regs)
755    {
756      rtx temp = cmp0;
757      cmp0 = cmp1;
758      cmp1 = temp;
759    }
760
761  brtmp = gen_rtx_REG (CCmode, FPCC_REGNUM);
762  emit_insn (gen_fn (brtmp, cmp0, cmp1));
763
764  return gen_rtx_fmt_ee (invert ? EQ : NE, VOIDmode, brtmp, const0_rtx);
765}
766
767
768void
769xtensa_expand_conditional_branch (rtx *operands, enum rtx_code test_code)
770{
771  enum cmp_type type = branch_type;
772  rtx cmp0 = branch_cmp[0];
773  rtx cmp1 = branch_cmp[1];
774  rtx cmp;
775  int invert;
776  rtx label1, label2;
777
778  switch (type)
779    {
780    case CMP_DF:
781    default:
782      fatal_insn ("bad test", gen_rtx_fmt_ee (test_code, VOIDmode, cmp0, cmp1));
783
784    case CMP_SI:
785      invert = FALSE;
786      cmp = gen_int_relational (test_code, cmp0, cmp1, &invert);
787      break;
788
789    case CMP_SF:
790      if (!TARGET_HARD_FLOAT)
791	fatal_insn ("bad test", gen_rtx_fmt_ee (test_code, VOIDmode, cmp0, cmp1));
792      invert = FALSE;
793      cmp = gen_float_relational (test_code, cmp0, cmp1);
794      break;
795    }
796
797  /* Generate the branch.  */
798
799  label1 = gen_rtx_LABEL_REF (VOIDmode, operands[0]);
800  label2 = pc_rtx;
801
802  if (invert)
803    {
804      label2 = label1;
805      label1 = pc_rtx;
806    }
807
808  emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
809			       gen_rtx_IF_THEN_ELSE (VOIDmode, cmp,
810						     label1,
811						     label2)));
812}
813
814
815static rtx
816gen_conditional_move (rtx cmp)
817{
818  enum rtx_code code = GET_CODE (cmp);
819  rtx op0 = branch_cmp[0];
820  rtx op1 = branch_cmp[1];
821
822  if (branch_type == CMP_SI)
823    {
824      /* Jump optimization calls get_condition() which canonicalizes
825	 comparisons like (GE x <const>) to (GT x <const-1>).
826	 Transform those comparisons back to GE, since that is the
827	 comparison supported in Xtensa.  We shouldn't have to
828	 transform <LE x const> comparisons, because neither
829	 xtensa_expand_conditional_branch() nor get_condition() will
830	 produce them.  */
831
832      if ((code == GT) && (op1 == constm1_rtx))
833	{
834	  code = GE;
835	  op1 = const0_rtx;
836	}
837      cmp = gen_rtx_fmt_ee (code, VOIDmode, cc0_rtx, const0_rtx);
838
839      if (boolean_operator (cmp, VOIDmode))
840	{
841	  /* Swap the operands to make const0 second.  */
842	  if (op0 == const0_rtx)
843	    {
844	      op0 = op1;
845	      op1 = const0_rtx;
846	    }
847
848	  /* If not comparing against zero, emit a comparison (subtract).  */
849	  if (op1 != const0_rtx)
850	    {
851	      op0 = expand_binop (SImode, sub_optab, op0, op1,
852				  0, 0, OPTAB_LIB_WIDEN);
853	      op1 = const0_rtx;
854	    }
855	}
856      else if (branch_operator (cmp, VOIDmode))
857	{
858	  /* Swap the operands to make const0 second.  */
859	  if (op0 == const0_rtx)
860	    {
861	      op0 = op1;
862	      op1 = const0_rtx;
863
864	      switch (code)
865		{
866		case LT: code = GE; break;
867		case GE: code = LT; break;
868		default: gcc_unreachable ();
869		}
870	    }
871
872	  if (op1 != const0_rtx)
873	    return 0;
874	}
875      else
876	return 0;
877
878      return gen_rtx_fmt_ee (code, VOIDmode, op0, op1);
879    }
880
881  if (TARGET_HARD_FLOAT && (branch_type == CMP_SF))
882    return gen_float_relational (code, op0, op1);
883
884  return 0;
885}
886
887
888int
889xtensa_expand_conditional_move (rtx *operands, int isflt)
890{
891  rtx cmp;
892  rtx (*gen_fn) (rtx, rtx, rtx, rtx, rtx);
893
894  if (!(cmp = gen_conditional_move (operands[1])))
895    return 0;
896
897  if (isflt)
898    gen_fn = (branch_type == CMP_SI
899	      ? gen_movsfcc_internal0
900	      : gen_movsfcc_internal1);
901  else
902    gen_fn = (branch_type == CMP_SI
903	      ? gen_movsicc_internal0
904	      : gen_movsicc_internal1);
905
906  emit_insn (gen_fn (operands[0], XEXP (cmp, 0),
907		     operands[2], operands[3], cmp));
908  return 1;
909}
910
911
912int
913xtensa_expand_scc (rtx *operands)
914{
915  rtx dest = operands[0];
916  rtx cmp = operands[1];
917  rtx one_tmp, zero_tmp;
918  rtx (*gen_fn) (rtx, rtx, rtx, rtx, rtx);
919
920  if (!(cmp = gen_conditional_move (cmp)))
921    return 0;
922
923  one_tmp = gen_reg_rtx (SImode);
924  zero_tmp = gen_reg_rtx (SImode);
925  emit_insn (gen_movsi (one_tmp, const_true_rtx));
926  emit_insn (gen_movsi (zero_tmp, const0_rtx));
927
928  gen_fn = (branch_type == CMP_SI
929	    ? gen_movsicc_internal0
930	    : gen_movsicc_internal1);
931  emit_insn (gen_fn (dest, XEXP (cmp, 0), one_tmp, zero_tmp, cmp));
932  return 1;
933}
934
935
936/* Split OP[1] into OP[2,3] and likewise for OP[0] into OP[0,1].  MODE is
937   for the output, i.e., the input operands are twice as big as MODE.  */
938
939void
940xtensa_split_operand_pair (rtx operands[4], enum machine_mode mode)
941{
942  switch (GET_CODE (operands[1]))
943    {
944    case REG:
945      operands[3] = gen_rtx_REG (mode, REGNO (operands[1]) + 1);
946      operands[2] = gen_rtx_REG (mode, REGNO (operands[1]));
947      break;
948
949    case MEM:
950      operands[3] = adjust_address (operands[1], mode, GET_MODE_SIZE (mode));
951      operands[2] = adjust_address (operands[1], mode, 0);
952      break;
953
954    case CONST_INT:
955    case CONST_DOUBLE:
956      split_double (operands[1], &operands[2], &operands[3]);
957      break;
958
959    default:
960      gcc_unreachable ();
961    }
962
963  switch (GET_CODE (operands[0]))
964    {
965    case REG:
966      operands[1] = gen_rtx_REG (mode, REGNO (operands[0]) + 1);
967      operands[0] = gen_rtx_REG (mode, REGNO (operands[0]));
968      break;
969
970    case MEM:
971      operands[1] = adjust_address (operands[0], mode, GET_MODE_SIZE (mode));
972      operands[0] = adjust_address (operands[0], mode, 0);
973      break;
974
975    default:
976      gcc_unreachable ();
977    }
978}
979
980
981/* Emit insns to move operands[1] into operands[0].
982   Return 1 if we have written out everything that needs to be done to
983   do the move.  Otherwise, return 0 and the caller will emit the move
984   normally.  */
985
986int
987xtensa_emit_move_sequence (rtx *operands, enum machine_mode mode)
988{
989  if (CONSTANT_P (operands[1])
990      && (GET_CODE (operands[1]) != CONST_INT
991	  || !xtensa_simm12b (INTVAL (operands[1]))))
992    {
993      if (!TARGET_CONST16)
994	operands[1] = force_const_mem (SImode, operands[1]);
995
996      /* PC-relative loads are always SImode, and CONST16 is only
997	 supported in the movsi pattern, so add a SUBREG for any other
998	 (smaller) mode.  */
999
1000      if (mode != SImode)
1001	{
1002	  if (register_operand (operands[0], mode))
1003	    {
1004	      operands[0] = simplify_gen_subreg (SImode, operands[0], mode, 0);
1005	      emit_move_insn (operands[0], operands[1]);
1006	      return 1;
1007	    }
1008	  else
1009	    {
1010	      operands[1] = force_reg (SImode, operands[1]);
1011	      operands[1] = gen_lowpart_SUBREG (mode, operands[1]);
1012	    }
1013	}
1014    }
1015
1016  if (!(reload_in_progress | reload_completed)
1017      && !xtensa_valid_move (mode, operands))
1018    operands[1] = force_reg (mode, operands[1]);
1019
1020  operands[1] = xtensa_copy_incoming_a7 (operands[1]);
1021
1022  /* During reload we don't want to emit (subreg:X (mem:Y)) since that
1023     instruction won't be recognized after reload, so we remove the
1024     subreg and adjust mem accordingly.  */
1025  if (reload_in_progress)
1026    {
1027      operands[0] = fixup_subreg_mem (operands[0]);
1028      operands[1] = fixup_subreg_mem (operands[1]);
1029    }
1030  return 0;
1031}
1032
1033
1034static rtx
1035fixup_subreg_mem (rtx x)
1036{
1037  if (GET_CODE (x) == SUBREG
1038      && GET_CODE (SUBREG_REG (x)) == REG
1039      && REGNO (SUBREG_REG (x)) >= FIRST_PSEUDO_REGISTER)
1040    {
1041      rtx temp =
1042	gen_rtx_SUBREG (GET_MODE (x),
1043			reg_equiv_mem [REGNO (SUBREG_REG (x))],
1044			SUBREG_BYTE (x));
1045      x = alter_subreg (&temp);
1046    }
1047  return x;
1048}
1049
1050
1051/* Check if an incoming argument in a7 is expected to be used soon and
1052   if OPND is a register or register pair that includes a7.  If so,
1053   create a new pseudo and copy a7 into that pseudo at the very
1054   beginning of the function, followed by the special "set_frame_ptr"
1055   unspec_volatile insn.  The return value is either the original
1056   operand, if it is not a7, or the new pseudo containing a copy of
1057   the incoming argument.  This is necessary because the register
1058   allocator will ignore conflicts with a7 and may either assign some
1059   other pseudo to a7 or use a7 as the hard_frame_pointer, clobbering
1060   the incoming argument in a7.  By copying the argument out of a7 as
1061   the very first thing, and then immediately following that with an
1062   unspec_volatile to keep the scheduler away, we should avoid any
1063   problems.  Putting the set_frame_ptr insn at the beginning, with
1064   only the a7 copy before it, also makes it easier for the prologue
1065   expander to initialize the frame pointer after the a7 copy and to
1066   fix up the a7 copy to use the stack pointer instead of the frame
1067   pointer.  */
1068
1069rtx
1070xtensa_copy_incoming_a7 (rtx opnd)
1071{
1072  rtx entry_insns = 0;
1073  rtx reg, tmp;
1074  enum machine_mode mode;
1075
1076  if (!cfun->machine->need_a7_copy)
1077    return opnd;
1078
1079  /* This function should never be called again once a7 has been copied.  */
1080  gcc_assert (!cfun->machine->set_frame_ptr_insn);
1081
1082  mode = GET_MODE (opnd);
1083
1084  /* The operand using a7 may come in a later instruction, so just return
1085     the original operand if it doesn't use a7.  */
1086  reg = opnd;
1087  if (GET_CODE (reg) == SUBREG)
1088    {
1089      gcc_assert (SUBREG_BYTE (reg) == 0);
1090      reg = SUBREG_REG (reg);
1091    }
1092  if (GET_CODE (reg) != REG
1093      || REGNO (reg) > A7_REG
1094      || REGNO (reg) + HARD_REGNO_NREGS (A7_REG, mode) <= A7_REG)
1095    return opnd;
1096
1097  /* 1-word args will always be in a7; 2-word args in a6/a7.  */
1098  gcc_assert (REGNO (reg) + HARD_REGNO_NREGS (A7_REG, mode) - 1 == A7_REG);
1099
1100  cfun->machine->need_a7_copy = false;
1101
1102  /* Copy a7 to a new pseudo at the function entry.  Use gen_raw_REG to
1103     create the REG for a7 so that hard_frame_pointer_rtx is not used.  */
1104
1105  push_to_sequence (entry_insns);
1106  tmp = gen_reg_rtx (mode);
1107
1108  switch (mode)
1109    {
1110    case DFmode:
1111    case DImode:
1112      emit_insn (gen_movsi_internal (gen_rtx_SUBREG (SImode, tmp, 0),
1113				     gen_rtx_REG (SImode, A7_REG - 1)));
1114      emit_insn (gen_movsi_internal (gen_rtx_SUBREG (SImode, tmp, 4),
1115				     gen_raw_REG (SImode, A7_REG)));
1116      break;
1117    case SFmode:
1118      emit_insn (gen_movsf_internal (tmp, gen_raw_REG (mode, A7_REG)));
1119      break;
1120    case SImode:
1121      emit_insn (gen_movsi_internal (tmp, gen_raw_REG (mode, A7_REG)));
1122      break;
1123    case HImode:
1124      emit_insn (gen_movhi_internal (tmp, gen_raw_REG (mode, A7_REG)));
1125      break;
1126    case QImode:
1127      emit_insn (gen_movqi_internal (tmp, gen_raw_REG (mode, A7_REG)));
1128      break;
1129    default:
1130      gcc_unreachable ();
1131    }
1132
1133  cfun->machine->set_frame_ptr_insn = emit_insn (gen_set_frame_ptr ());
1134  entry_insns = get_insns ();
1135  end_sequence ();
1136
1137  if (cfun->machine->vararg_a7)
1138    {
1139      /* This is called from within builtin_savereg, so we're already
1140	 inside a start_sequence that will be placed at the start of
1141	 the function.  */
1142      emit_insn (entry_insns);
1143    }
1144  else
1145    {
1146      /* Put entry_insns after the NOTE that starts the function.  If
1147	 this is inside a start_sequence, make the outer-level insn
1148	 chain current, so the code is placed at the start of the
1149	 function.  */
1150      push_topmost_sequence ();
1151      emit_insn_after (entry_insns, get_insns ());
1152      pop_topmost_sequence ();
1153    }
1154
1155  return tmp;
1156}
1157
1158
1159/* Try to expand a block move operation to a sequence of RTL move
1160   instructions.  If not optimizing, or if the block size is not a
1161   constant, or if the block is too large, the expansion fails and GCC
1162   falls back to calling memcpy().
1163
1164   operands[0] is the destination
1165   operands[1] is the source
1166   operands[2] is the length
1167   operands[3] is the alignment */
1168
1169int
1170xtensa_expand_block_move (rtx *operands)
1171{
1172  static const enum machine_mode mode_from_align[] =
1173  {
1174    VOIDmode, QImode, HImode, VOIDmode, SImode,
1175  };
1176
1177  rtx dst_mem = operands[0];
1178  rtx src_mem = operands[1];
1179  HOST_WIDE_INT bytes, align;
1180  int num_pieces, move_ratio;
1181  rtx temp[2];
1182  enum machine_mode mode[2];
1183  int amount[2];
1184  bool active[2];
1185  int phase = 0;
1186  int next;
1187  int offset_ld = 0;
1188  int offset_st = 0;
1189  rtx x;
1190
1191  /* If this is not a fixed size move, just call memcpy.  */
1192  if (!optimize || (GET_CODE (operands[2]) != CONST_INT))
1193    return 0;
1194
1195  bytes = INTVAL (operands[2]);
1196  align = INTVAL (operands[3]);
1197
1198  /* Anything to move?  */
1199  if (bytes <= 0)
1200    return 0;
1201
1202  if (align > MOVE_MAX)
1203    align = MOVE_MAX;
1204
1205  /* Decide whether to expand inline based on the optimization level.  */
1206  move_ratio = 4;
1207  if (optimize > 2)
1208    move_ratio = LARGEST_MOVE_RATIO;
1209  num_pieces = (bytes / align) + (bytes % align); /* Close enough anyway.  */
1210  if (num_pieces > move_ratio)
1211    return 0;
1212
1213  x = XEXP (dst_mem, 0);
1214  if (!REG_P (x))
1215    {
1216      x = force_reg (Pmode, x);
1217      dst_mem = replace_equiv_address (dst_mem, x);
1218    }
1219
1220  x = XEXP (src_mem, 0);
1221  if (!REG_P (x))
1222    {
1223      x = force_reg (Pmode, x);
1224      src_mem = replace_equiv_address (src_mem, x);
1225    }
1226
1227  active[0] = active[1] = false;
1228
1229  do
1230    {
1231      next = phase;
1232      phase ^= 1;
1233
1234      if (bytes > 0)
1235	{
1236	  int next_amount;
1237
1238	  next_amount = (bytes >= 4 ? 4 : (bytes >= 2 ? 2 : 1));
1239	  next_amount = MIN (next_amount, align);
1240
1241	  amount[next] = next_amount;
1242	  mode[next] = mode_from_align[next_amount];
1243	  temp[next] = gen_reg_rtx (mode[next]);
1244
1245	  x = adjust_address (src_mem, mode[next], offset_ld);
1246	  emit_insn (gen_rtx_SET (VOIDmode, temp[next], x));
1247
1248	  offset_ld += next_amount;
1249	  bytes -= next_amount;
1250	  active[next] = true;
1251	}
1252
1253      if (active[phase])
1254	{
1255	  active[phase] = false;
1256
1257	  x = adjust_address (dst_mem, mode[phase], offset_st);
1258	  emit_insn (gen_rtx_SET (VOIDmode, x, temp[phase]));
1259
1260	  offset_st += amount[phase];
1261	}
1262    }
1263  while (active[next]);
1264
1265  return 1;
1266}
1267
1268
1269void
1270xtensa_expand_nonlocal_goto (rtx *operands)
1271{
1272  rtx goto_handler = operands[1];
1273  rtx containing_fp = operands[3];
1274
1275  /* Generate a call to "__xtensa_nonlocal_goto" (in libgcc); the code
1276     is too big to generate in-line.  */
1277
1278  if (GET_CODE (containing_fp) != REG)
1279    containing_fp = force_reg (Pmode, containing_fp);
1280
1281  goto_handler = replace_rtx (copy_rtx (goto_handler),
1282			      virtual_stack_vars_rtx,
1283			      containing_fp);
1284
1285  emit_library_call (gen_rtx_SYMBOL_REF (Pmode, "__xtensa_nonlocal_goto"),
1286		     0, VOIDmode, 2,
1287		     containing_fp, Pmode,
1288		     goto_handler, Pmode);
1289}
1290
1291
1292static struct machine_function *
1293xtensa_init_machine_status (void)
1294{
1295  return ggc_alloc_cleared (sizeof (struct machine_function));
1296}
1297
1298
1299void
1300xtensa_setup_frame_addresses (void)
1301{
1302  /* Set flag to cause FRAME_POINTER_REQUIRED to be set.  */
1303  cfun->machine->accesses_prev_frame = 1;
1304
1305  emit_library_call
1306    (gen_rtx_SYMBOL_REF (Pmode, "__xtensa_libgcc_window_spill"),
1307     0, VOIDmode, 0);
1308}
1309
1310
1311/* Emit the assembly for the end of a zero-cost loop.  Normally we just emit
1312   a comment showing where the end of the loop is.  However, if there is a
1313   label or a branch at the end of the loop then we need to place a nop
1314   there.  If the loop ends with a label we need the nop so that branches
1315   targeting that label will target the nop (and thus remain in the loop),
1316   instead of targeting the instruction after the loop (and thus exiting
1317   the loop).  If the loop ends with a branch, we need the nop in case the
1318   branch is targeting a location inside the loop.  When the branch
1319   executes it will cause the loop count to be decremented even if it is
1320   taken (because it is the last instruction in the loop), so we need to
1321   nop after the branch to prevent the loop count from being decremented
1322   when the branch is taken.  */
1323
1324void
1325xtensa_emit_loop_end (rtx insn, rtx *operands)
1326{
1327  char done = 0;
1328
1329  for (insn = PREV_INSN (insn); insn && !done; insn = PREV_INSN (insn))
1330    {
1331      switch (GET_CODE (insn))
1332	{
1333	case NOTE:
1334	case BARRIER:
1335	  break;
1336
1337	case CODE_LABEL:
1338	  output_asm_insn (TARGET_DENSITY ? "nop.n" : "nop", operands);
1339	  done = 1;
1340	  break;
1341
1342	default:
1343	  {
1344	    rtx body = PATTERN (insn);
1345
1346	    if (GET_CODE (body) == JUMP_INSN)
1347	      {
1348		output_asm_insn (TARGET_DENSITY ? "nop.n" : "nop", operands);
1349		done = 1;
1350	      }
1351	    else if ((GET_CODE (body) != USE)
1352		     && (GET_CODE (body) != CLOBBER))
1353	      done = 1;
1354	  }
1355	  break;
1356        }
1357    }
1358
1359  output_asm_insn ("# loop end for %0", operands);
1360}
1361
1362
1363char *
1364xtensa_emit_call (int callop, rtx *operands)
1365{
1366  static char result[64];
1367  rtx tgt = operands[callop];
1368
1369  if (GET_CODE (tgt) == CONST_INT)
1370    sprintf (result, "call8\t0x%lx", INTVAL (tgt));
1371  else if (register_operand (tgt, VOIDmode))
1372    sprintf (result, "callx8\t%%%d", callop);
1373  else
1374    sprintf (result, "call8\t%%%d", callop);
1375
1376  return result;
1377}
1378
1379
1380/* Return the debugger register number to use for 'regno'.  */
1381
1382int
1383xtensa_dbx_register_number (int regno)
1384{
1385  int first = -1;
1386
1387  if (GP_REG_P (regno))
1388    {
1389      regno -= GP_REG_FIRST;
1390      first = 0;
1391    }
1392  else if (BR_REG_P (regno))
1393    {
1394      regno -= BR_REG_FIRST;
1395      first = 16;
1396    }
1397  else if (FP_REG_P (regno))
1398    {
1399      regno -= FP_REG_FIRST;
1400      first = 48;
1401    }
1402  else if (ACC_REG_P (regno))
1403    {
1404      first = 0x200;	/* Start of Xtensa special registers.  */
1405      regno = 16;	/* ACCLO is special register 16.  */
1406    }
1407
1408  /* When optimizing, we sometimes get asked about pseudo-registers
1409     that don't represent hard registers.  Return 0 for these.  */
1410  if (first == -1)
1411    return 0;
1412
1413  return first + regno;
1414}
1415
1416
1417/* Argument support functions.  */
1418
1419/* Initialize CUMULATIVE_ARGS for a function.  */
1420
1421void
1422init_cumulative_args (CUMULATIVE_ARGS *cum, int incoming)
1423{
1424  cum->arg_words = 0;
1425  cum->incoming = incoming;
1426}
1427
1428
1429/* Advance the argument to the next argument position.  */
1430
1431void
1432function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode, tree type)
1433{
1434  int words, max;
1435  int *arg_words;
1436
1437  arg_words = &cum->arg_words;
1438  max = MAX_ARGS_IN_REGISTERS;
1439
1440  words = (((mode != BLKmode)
1441	    ? (int) GET_MODE_SIZE (mode)
1442	    : int_size_in_bytes (type)) + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
1443
1444  if (*arg_words < max
1445      && (targetm.calls.must_pass_in_stack (mode, type)
1446	  || *arg_words + words > max))
1447    *arg_words = max;
1448
1449  *arg_words += words;
1450}
1451
1452
1453/* Return an RTL expression containing the register for the given mode,
1454   or 0 if the argument is to be passed on the stack.  INCOMING_P is nonzero
1455   if this is an incoming argument to the current function.  */
1456
1457rtx
1458function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode, tree type,
1459	      int incoming_p)
1460{
1461  int regbase, words, max;
1462  int *arg_words;
1463  int regno;
1464
1465  arg_words = &cum->arg_words;
1466  regbase = (incoming_p ? GP_ARG_FIRST : GP_OUTGOING_ARG_FIRST);
1467  max = MAX_ARGS_IN_REGISTERS;
1468
1469  words = (((mode != BLKmode)
1470	    ? (int) GET_MODE_SIZE (mode)
1471	    : int_size_in_bytes (type)) + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
1472
1473  if (type && (TYPE_ALIGN (type) > BITS_PER_WORD))
1474    {
1475      int align = TYPE_ALIGN (type) / BITS_PER_WORD;
1476      *arg_words = (*arg_words + align - 1) & -align;
1477    }
1478
1479  if (*arg_words + words > max)
1480    return (rtx)0;
1481
1482  regno = regbase + *arg_words;
1483
1484  if (cum->incoming && regno <= A7_REG && regno + words > A7_REG)
1485    cfun->machine->need_a7_copy = true;
1486
1487  return gen_rtx_REG (mode, regno);
1488}
1489
1490
1491static bool
1492xtensa_return_in_msb (tree valtype)
1493{
1494  return (TARGET_BIG_ENDIAN
1495	  && AGGREGATE_TYPE_P (valtype)
1496	  && int_size_in_bytes (valtype) >= UNITS_PER_WORD);
1497}
1498
1499
1500void
1501override_options (void)
1502{
1503  int regno;
1504  enum machine_mode mode;
1505
1506  if (!TARGET_BOOLEANS && TARGET_HARD_FLOAT)
1507    error ("boolean registers required for the floating-point option");
1508
1509  xtensa_char_to_class['q'] = SP_REG;
1510  xtensa_char_to_class['a'] = GR_REGS;
1511  xtensa_char_to_class['b'] = ((TARGET_BOOLEANS) ? BR_REGS : NO_REGS);
1512  xtensa_char_to_class['f'] = ((TARGET_HARD_FLOAT) ? FP_REGS : NO_REGS);
1513  xtensa_char_to_class['A'] = ((TARGET_MAC16) ? ACC_REG : NO_REGS);
1514  xtensa_char_to_class['B'] = ((TARGET_SEXT) ? GR_REGS : NO_REGS);
1515  xtensa_char_to_class['C'] = ((TARGET_MUL16) ? GR_REGS: NO_REGS);
1516  xtensa_char_to_class['D'] = ((TARGET_DENSITY) ? GR_REGS: NO_REGS);
1517  xtensa_char_to_class['d'] = ((TARGET_DENSITY) ? AR_REGS: NO_REGS);
1518  xtensa_char_to_class['W'] = ((TARGET_CONST16) ? GR_REGS: NO_REGS);
1519
1520  /* Set up array giving whether a given register can hold a given mode.  */
1521  for (mode = VOIDmode;
1522       mode != MAX_MACHINE_MODE;
1523       mode = (enum machine_mode) ((int) mode + 1))
1524    {
1525      int size = GET_MODE_SIZE (mode);
1526      enum mode_class class = GET_MODE_CLASS (mode);
1527
1528      for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1529	{
1530	  int temp;
1531
1532	  if (ACC_REG_P (regno))
1533	    temp = (TARGET_MAC16
1534		    && (class == MODE_INT) && (size <= UNITS_PER_WORD));
1535	  else if (GP_REG_P (regno))
1536	    temp = ((regno & 1) == 0 || (size <= UNITS_PER_WORD));
1537	  else if (FP_REG_P (regno))
1538	    temp = (TARGET_HARD_FLOAT && (mode == SFmode));
1539	  else if (BR_REG_P (regno))
1540	    temp = (TARGET_BOOLEANS && (mode == CCmode));
1541	  else
1542	    temp = FALSE;
1543
1544	  xtensa_hard_regno_mode_ok[(int) mode][regno] = temp;
1545	}
1546    }
1547
1548  init_machine_status = xtensa_init_machine_status;
1549
1550  /* Check PIC settings.  PIC is only supported when using L32R
1551     instructions, and some targets need to always use PIC.  */
1552  if (flag_pic && TARGET_CONST16)
1553    error ("-f%s is not supported with CONST16 instructions",
1554	   (flag_pic > 1 ? "PIC" : "pic"));
1555  else if (XTENSA_ALWAYS_PIC)
1556    {
1557      if (TARGET_CONST16)
1558	error ("PIC is required but not supported with CONST16 instructions");
1559      flag_pic = 1;
1560    }
1561  /* There's no need for -fPIC (as opposed to -fpic) on Xtensa.  */
1562  if (flag_pic > 1)
1563    flag_pic = 1;
1564
1565  /* Hot/cold partitioning does not work on this architecture, because of
1566     constant pools (the load instruction cannot necessarily reach that far).
1567     Therefore disable it on this architecture.  */
1568  if (flag_reorder_blocks_and_partition)
1569    {
1570      flag_reorder_blocks_and_partition = 0;
1571      flag_reorder_blocks = 1;
1572    }
1573}
1574
1575
1576/* A C compound statement to output to stdio stream STREAM the
1577   assembler syntax for an instruction operand X.  X is an RTL
1578   expression.
1579
1580   CODE is a value that can be used to specify one of several ways
1581   of printing the operand.  It is used when identical operands
1582   must be printed differently depending on the context.  CODE
1583   comes from the '%' specification that was used to request
1584   printing of the operand.  If the specification was just '%DIGIT'
1585   then CODE is 0; if the specification was '%LTR DIGIT' then CODE
1586   is the ASCII code for LTR.
1587
1588   If X is a register, this macro should print the register's name.
1589   The names can be found in an array 'reg_names' whose type is
1590   'char *[]'.  'reg_names' is initialized from 'REGISTER_NAMES'.
1591
1592   When the machine description has a specification '%PUNCT' (a '%'
1593   followed by a punctuation character), this macro is called with
1594   a null pointer for X and the punctuation character for CODE.
1595
1596   'a', 'c', 'l', and 'n' are reserved.
1597
1598   The Xtensa specific codes are:
1599
1600   'd'  CONST_INT, print as signed decimal
1601   'x'  CONST_INT, print as signed hexadecimal
1602   'K'  CONST_INT, print number of bits in mask for EXTUI
1603   'R'  CONST_INT, print (X & 0x1f)
1604   'L'  CONST_INT, print ((32 - X) & 0x1f)
1605   'D'  REG, print second register of double-word register operand
1606   'N'  MEM, print address of next word following a memory operand
1607   'v'  MEM, if memory reference is volatile, output a MEMW before it
1608   't'  any constant, add "@h" suffix for top 16 bits
1609   'b'  any constant, add "@l" suffix for bottom 16 bits
1610*/
1611
1612static void
1613printx (FILE *file, signed int val)
1614{
1615  /* Print a hexadecimal value in a nice way.  */
1616  if ((val > -0xa) && (val < 0xa))
1617    fprintf (file, "%d", val);
1618  else if (val < 0)
1619    fprintf (file, "-0x%x", -val);
1620  else
1621    fprintf (file, "0x%x", val);
1622}
1623
1624
1625void
1626print_operand (FILE *file, rtx x, int letter)
1627{
1628  if (!x)
1629    error ("PRINT_OPERAND null pointer");
1630
1631  switch (letter)
1632    {
1633    case 'D':
1634      if (GET_CODE (x) == REG || GET_CODE (x) == SUBREG)
1635	fprintf (file, "%s", reg_names[xt_true_regnum (x) + 1]);
1636      else
1637	output_operand_lossage ("invalid %%D value");
1638      break;
1639
1640    case 'v':
1641      if (GET_CODE (x) == MEM)
1642	{
1643	  /* For a volatile memory reference, emit a MEMW before the
1644	     load or store.  */
1645	  if (MEM_VOLATILE_P (x))
1646	    fprintf (file, "memw\n\t");
1647	}
1648      else
1649	output_operand_lossage ("invalid %%v value");
1650      break;
1651
1652    case 'N':
1653      if (GET_CODE (x) == MEM
1654	  && (GET_MODE (x) == DFmode || GET_MODE (x) == DImode))
1655	{
1656	  x = adjust_address (x, GET_MODE (x) == DFmode ? SFmode : SImode, 4);
1657	  output_address (XEXP (x, 0));
1658	}
1659      else
1660	output_operand_lossage ("invalid %%N value");
1661      break;
1662
1663    case 'K':
1664      if (GET_CODE (x) == CONST_INT)
1665	{
1666	  int num_bits = 0;
1667	  unsigned val = INTVAL (x);
1668	  while (val & 1)
1669	    {
1670	      num_bits += 1;
1671	      val = val >> 1;
1672	    }
1673	  if ((val != 0) || (num_bits == 0) || (num_bits > 16))
1674	    fatal_insn ("invalid mask", x);
1675
1676	  fprintf (file, "%d", num_bits);
1677	}
1678      else
1679	output_operand_lossage ("invalid %%K value");
1680      break;
1681
1682    case 'L':
1683      if (GET_CODE (x) == CONST_INT)
1684	fprintf (file, "%ld", (32 - INTVAL (x)) & 0x1f);
1685      else
1686	output_operand_lossage ("invalid %%L value");
1687      break;
1688
1689    case 'R':
1690      if (GET_CODE (x) == CONST_INT)
1691	fprintf (file, "%ld", INTVAL (x) & 0x1f);
1692      else
1693	output_operand_lossage ("invalid %%R value");
1694      break;
1695
1696    case 'x':
1697      if (GET_CODE (x) == CONST_INT)
1698	printx (file, INTVAL (x));
1699      else
1700	output_operand_lossage ("invalid %%x value");
1701      break;
1702
1703    case 'd':
1704      if (GET_CODE (x) == CONST_INT)
1705	fprintf (file, "%ld", INTVAL (x));
1706      else
1707	output_operand_lossage ("invalid %%d value");
1708      break;
1709
1710    case 't':
1711    case 'b':
1712      if (GET_CODE (x) == CONST_INT)
1713	{
1714	  printx (file, INTVAL (x));
1715	  fputs (letter == 't' ? "@h" : "@l", file);
1716	}
1717      else if (GET_CODE (x) == CONST_DOUBLE)
1718	{
1719	  REAL_VALUE_TYPE r;
1720	  REAL_VALUE_FROM_CONST_DOUBLE (r, x);
1721	  if (GET_MODE (x) == SFmode)
1722	    {
1723	      long l;
1724	      REAL_VALUE_TO_TARGET_SINGLE (r, l);
1725	      fprintf (file, "0x%08lx@%c", l, letter == 't' ? 'h' : 'l');
1726	    }
1727	  else
1728	    output_operand_lossage ("invalid %%t/%%b value");
1729	}
1730      else if (GET_CODE (x) == CONST)
1731	{
1732	  /* X must be a symbolic constant on ELF.  Write an expression
1733	     suitable for 'const16' that sets the high or low 16 bits.  */
1734	  if (GET_CODE (XEXP (x, 0)) != PLUS
1735	      || (GET_CODE (XEXP (XEXP (x, 0), 0)) != SYMBOL_REF
1736		  && GET_CODE (XEXP (XEXP (x, 0), 0)) != LABEL_REF)
1737	      || GET_CODE (XEXP (XEXP (x, 0), 1)) != CONST_INT)
1738	    output_operand_lossage ("invalid %%t/%%b value");
1739	  print_operand (file, XEXP (XEXP (x, 0), 0), 0);
1740	  fputs (letter == 't' ? "@h" : "@l", file);
1741	  /* There must be a non-alphanumeric character between 'h' or 'l'
1742	     and the number.  The '-' is added by print_operand() already.  */
1743	  if (INTVAL (XEXP (XEXP (x, 0), 1)) >= 0)
1744	    fputs ("+", file);
1745	  print_operand (file, XEXP (XEXP (x, 0), 1), 0);
1746	}
1747      else
1748	{
1749	  output_addr_const (file, x);
1750	  fputs (letter == 't' ? "@h" : "@l", file);
1751	}
1752      break;
1753
1754    default:
1755      if (GET_CODE (x) == REG || GET_CODE (x) == SUBREG)
1756	fprintf (file, "%s", reg_names[xt_true_regnum (x)]);
1757      else if (GET_CODE (x) == MEM)
1758	output_address (XEXP (x, 0));
1759      else if (GET_CODE (x) == CONST_INT)
1760	fprintf (file, "%ld", INTVAL (x));
1761      else
1762	output_addr_const (file, x);
1763    }
1764}
1765
1766
1767/* A C compound statement to output to stdio stream STREAM the
1768   assembler syntax for an instruction operand that is a memory
1769   reference whose address is ADDR.  ADDR is an RTL expression.  */
1770
1771void
1772print_operand_address (FILE *file, rtx addr)
1773{
1774  if (!addr)
1775    error ("PRINT_OPERAND_ADDRESS, null pointer");
1776
1777  switch (GET_CODE (addr))
1778    {
1779    default:
1780      fatal_insn ("invalid address", addr);
1781      break;
1782
1783    case REG:
1784      fprintf (file, "%s, 0", reg_names [REGNO (addr)]);
1785      break;
1786
1787    case PLUS:
1788      {
1789	rtx reg = (rtx)0;
1790	rtx offset = (rtx)0;
1791	rtx arg0 = XEXP (addr, 0);
1792	rtx arg1 = XEXP (addr, 1);
1793
1794	if (GET_CODE (arg0) == REG)
1795	  {
1796	    reg = arg0;
1797	    offset = arg1;
1798	  }
1799	else if (GET_CODE (arg1) == REG)
1800	  {
1801	    reg = arg1;
1802	    offset = arg0;
1803	  }
1804	else
1805	  fatal_insn ("no register in address", addr);
1806
1807	if (CONSTANT_P (offset))
1808	  {
1809	    fprintf (file, "%s, ", reg_names [REGNO (reg)]);
1810	    output_addr_const (file, offset);
1811	  }
1812	else
1813	  fatal_insn ("address offset not a constant", addr);
1814      }
1815      break;
1816
1817    case LABEL_REF:
1818    case SYMBOL_REF:
1819    case CONST_INT:
1820    case CONST:
1821      output_addr_const (file, addr);
1822      break;
1823    }
1824}
1825
1826
1827void
1828xtensa_output_literal (FILE *file, rtx x, enum machine_mode mode, int labelno)
1829{
1830  long value_long[2];
1831  REAL_VALUE_TYPE r;
1832  int size;
1833
1834  fprintf (file, "\t.literal .LC%u, ", (unsigned) labelno);
1835
1836  switch (GET_MODE_CLASS (mode))
1837    {
1838    case MODE_FLOAT:
1839      gcc_assert (GET_CODE (x) == CONST_DOUBLE);
1840
1841      REAL_VALUE_FROM_CONST_DOUBLE (r, x);
1842      switch (mode)
1843	{
1844	case SFmode:
1845	  REAL_VALUE_TO_TARGET_SINGLE (r, value_long[0]);
1846	  fprintf (file, "0x%08lx\n", value_long[0]);
1847	  break;
1848
1849	case DFmode:
1850	  REAL_VALUE_TO_TARGET_DOUBLE (r, value_long);
1851	  fprintf (file, "0x%08lx, 0x%08lx\n",
1852		   value_long[0], value_long[1]);
1853	  break;
1854
1855	default:
1856	  gcc_unreachable ();
1857	}
1858
1859      break;
1860
1861    case MODE_INT:
1862    case MODE_PARTIAL_INT:
1863      size = GET_MODE_SIZE (mode);
1864      switch (size)
1865	{
1866	case 4:
1867	  output_addr_const (file, x);
1868	  fputs ("\n", file);
1869	  break;
1870
1871	case 8:
1872	  output_addr_const (file, operand_subword (x, 0, 0, DImode));
1873	  fputs (", ", file);
1874	  output_addr_const (file, operand_subword (x, 1, 0, DImode));
1875	  fputs ("\n", file);
1876	  break;
1877
1878	default:
1879	  gcc_unreachable ();
1880	}
1881      break;
1882
1883    default:
1884      gcc_unreachable ();
1885    }
1886}
1887
1888
1889/* Return the bytes needed to compute the frame pointer from the current
1890   stack pointer.  */
1891
1892#define STACK_BYTES (STACK_BOUNDARY / BITS_PER_UNIT)
1893#define XTENSA_STACK_ALIGN(LOC) (((LOC) + STACK_BYTES-1) & ~(STACK_BYTES-1))
1894
1895long
1896compute_frame_size (int size)
1897{
1898  /* Add space for the incoming static chain value.  */
1899  if (cfun->static_chain_decl != NULL)
1900    size += (1 * UNITS_PER_WORD);
1901
1902  xtensa_current_frame_size =
1903    XTENSA_STACK_ALIGN (size
1904			+ current_function_outgoing_args_size
1905			+ (WINDOW_SIZE * UNITS_PER_WORD));
1906  return xtensa_current_frame_size;
1907}
1908
1909
1910int
1911xtensa_frame_pointer_required (void)
1912{
1913  /* The code to expand builtin_frame_addr and builtin_return_addr
1914     currently uses the hard_frame_pointer instead of frame_pointer.
1915     This seems wrong but maybe it's necessary for other architectures.
1916     This function is derived from the i386 code.  */
1917
1918  if (cfun->machine->accesses_prev_frame)
1919    return 1;
1920
1921  return 0;
1922}
1923
1924
1925void
1926xtensa_expand_prologue (void)
1927{
1928  HOST_WIDE_INT total_size;
1929  rtx size_rtx;
1930
1931  total_size = compute_frame_size (get_frame_size ());
1932  size_rtx = GEN_INT (total_size);
1933
1934  if (total_size < (1 << (12+3)))
1935    emit_insn (gen_entry (size_rtx, size_rtx));
1936  else
1937    {
1938      /* Use a8 as a temporary since a0-a7 may be live.  */
1939      rtx tmp_reg = gen_rtx_REG (Pmode, A8_REG);
1940      emit_insn (gen_entry (size_rtx, GEN_INT (MIN_FRAME_SIZE)));
1941      emit_move_insn (tmp_reg, GEN_INT (total_size - MIN_FRAME_SIZE));
1942      emit_insn (gen_subsi3 (tmp_reg, stack_pointer_rtx, tmp_reg));
1943      emit_move_insn (stack_pointer_rtx, tmp_reg);
1944    }
1945
1946  if (frame_pointer_needed)
1947    {
1948      if (cfun->machine->set_frame_ptr_insn)
1949	{
1950	  rtx first, insn;
1951
1952	  push_topmost_sequence ();
1953	  first = get_insns ();
1954	  pop_topmost_sequence ();
1955
1956	  /* For all instructions prior to set_frame_ptr_insn, replace
1957	     hard_frame_pointer references with stack_pointer.  */
1958	  for (insn = first;
1959	       insn != cfun->machine->set_frame_ptr_insn;
1960	       insn = NEXT_INSN (insn))
1961	    {
1962	      if (INSN_P (insn))
1963		PATTERN (insn) = replace_rtx (copy_rtx (PATTERN (insn)),
1964					      hard_frame_pointer_rtx,
1965					      stack_pointer_rtx);
1966	    }
1967	}
1968      else
1969	emit_move_insn (hard_frame_pointer_rtx, stack_pointer_rtx);
1970    }
1971}
1972
1973
1974/* Clear variables at function end.  */
1975
1976void
1977xtensa_function_epilogue (FILE *file ATTRIBUTE_UNUSED,
1978			  HOST_WIDE_INT size ATTRIBUTE_UNUSED)
1979{
1980  xtensa_current_frame_size = 0;
1981}
1982
1983
1984rtx
1985xtensa_return_addr (int count, rtx frame)
1986{
1987  rtx result, retaddr;
1988
1989  if (count == -1)
1990    retaddr = gen_rtx_REG (Pmode, A0_REG);
1991  else
1992    {
1993      rtx addr = plus_constant (frame, -4 * UNITS_PER_WORD);
1994      addr = memory_address (Pmode, addr);
1995      retaddr = gen_reg_rtx (Pmode);
1996      emit_move_insn (retaddr, gen_rtx_MEM (Pmode, addr));
1997    }
1998
1999  /* The 2 most-significant bits of the return address on Xtensa hold
2000     the register window size.  To get the real return address, these
2001     bits must be replaced with the high bits from the current PC.  */
2002
2003  result = gen_reg_rtx (Pmode);
2004  emit_insn (gen_fix_return_addr (result, retaddr));
2005  return result;
2006}
2007
2008
2009/* Create the va_list data type.
2010
2011   This structure is set up by __builtin_saveregs.  The __va_reg field
2012   points to a stack-allocated region holding the contents of the
2013   incoming argument registers.  The __va_ndx field is an index
2014   initialized to the position of the first unnamed (variable)
2015   argument.  This same index is also used to address the arguments
2016   passed in memory.  Thus, the __va_stk field is initialized to point
2017   to the position of the first argument in memory offset to account
2018   for the arguments passed in registers and to account for the size
2019   of the argument registers not being 16-byte aligned.  E.G., there
2020   are 6 argument registers of 4 bytes each, but we want the __va_ndx
2021   for the first stack argument to have the maximal alignment of 16
2022   bytes, so we offset the __va_stk address by 32 bytes so that
2023   __va_stk[32] references the first argument on the stack.  */
2024
2025static tree
2026xtensa_build_builtin_va_list (void)
2027{
2028  tree f_stk, f_reg, f_ndx, record, type_decl;
2029
2030  record = (*lang_hooks.types.make_type) (RECORD_TYPE);
2031  type_decl = build_decl (TYPE_DECL, get_identifier ("__va_list_tag"), record);
2032
2033  f_stk = build_decl (FIELD_DECL, get_identifier ("__va_stk"),
2034		      ptr_type_node);
2035  f_reg = build_decl (FIELD_DECL, get_identifier ("__va_reg"),
2036		      ptr_type_node);
2037  f_ndx = build_decl (FIELD_DECL, get_identifier ("__va_ndx"),
2038		      integer_type_node);
2039
2040  DECL_FIELD_CONTEXT (f_stk) = record;
2041  DECL_FIELD_CONTEXT (f_reg) = record;
2042  DECL_FIELD_CONTEXT (f_ndx) = record;
2043
2044  TREE_CHAIN (record) = type_decl;
2045  TYPE_NAME (record) = type_decl;
2046  TYPE_FIELDS (record) = f_stk;
2047  TREE_CHAIN (f_stk) = f_reg;
2048  TREE_CHAIN (f_reg) = f_ndx;
2049
2050  layout_type (record);
2051  return record;
2052}
2053
2054
2055/* Save the incoming argument registers on the stack.  Returns the
2056   address of the saved registers.  */
2057
2058static rtx
2059xtensa_builtin_saveregs (void)
2060{
2061  rtx gp_regs, dest;
2062  int arg_words = current_function_args_info.arg_words;
2063  int gp_left = MAX_ARGS_IN_REGISTERS - arg_words;
2064
2065  if (gp_left <= 0)
2066    return const0_rtx;
2067
2068  /* Allocate the general-purpose register space.  */
2069  gp_regs = assign_stack_local
2070    (BLKmode, MAX_ARGS_IN_REGISTERS * UNITS_PER_WORD, -1);
2071  set_mem_alias_set (gp_regs, get_varargs_alias_set ());
2072
2073  /* Now store the incoming registers.  */
2074  dest = change_address (gp_regs, SImode,
2075			 plus_constant (XEXP (gp_regs, 0),
2076					arg_words * UNITS_PER_WORD));
2077  cfun->machine->need_a7_copy = true;
2078  cfun->machine->vararg_a7 = true;
2079  move_block_from_reg (GP_ARG_FIRST + arg_words, dest, gp_left);
2080
2081  return XEXP (gp_regs, 0);
2082}
2083
2084
2085/* Implement `va_start' for varargs and stdarg.  We look at the
2086   current function to fill in an initial va_list.  */
2087
2088void
2089xtensa_va_start (tree valist, rtx nextarg ATTRIBUTE_UNUSED)
2090{
2091  tree f_stk, stk;
2092  tree f_reg, reg;
2093  tree f_ndx, ndx;
2094  tree t, u;
2095  int arg_words;
2096
2097  arg_words = current_function_args_info.arg_words;
2098
2099  f_stk = TYPE_FIELDS (va_list_type_node);
2100  f_reg = TREE_CHAIN (f_stk);
2101  f_ndx = TREE_CHAIN (f_reg);
2102
2103  stk = build (COMPONENT_REF, TREE_TYPE (f_stk), valist, f_stk, NULL_TREE);
2104  reg = build (COMPONENT_REF, TREE_TYPE (f_reg), valist, f_reg, NULL_TREE);
2105  ndx = build (COMPONENT_REF, TREE_TYPE (f_ndx), valist, f_ndx, NULL_TREE);
2106
2107  /* Call __builtin_saveregs; save the result in __va_reg */
2108  u = make_tree (ptr_type_node, expand_builtin_saveregs ());
2109  t = build (MODIFY_EXPR, ptr_type_node, reg, u);
2110  TREE_SIDE_EFFECTS (t) = 1;
2111  expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
2112
2113  /* Set the __va_stk member to ($arg_ptr - 32).  */
2114  u = make_tree (ptr_type_node, virtual_incoming_args_rtx);
2115  u = fold (build (PLUS_EXPR, ptr_type_node, u,
2116		   build_int_cst (NULL_TREE, -32)));
2117  t = build (MODIFY_EXPR, ptr_type_node, stk, u);
2118  TREE_SIDE_EFFECTS (t) = 1;
2119  expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
2120
2121  /* Set the __va_ndx member.  If the first variable argument is on
2122     the stack, adjust __va_ndx by 2 words to account for the extra
2123     alignment offset for __va_stk.  */
2124  if (arg_words >= MAX_ARGS_IN_REGISTERS)
2125    arg_words += 2;
2126  u = build_int_cst (NULL_TREE, arg_words * UNITS_PER_WORD);
2127  t = build (MODIFY_EXPR, integer_type_node, ndx, u);
2128  TREE_SIDE_EFFECTS (t) = 1;
2129  expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
2130}
2131
2132
2133/* Implement `va_arg'.  */
2134
2135static tree
2136xtensa_gimplify_va_arg_expr (tree valist, tree type, tree *pre_p,
2137			     tree *post_p ATTRIBUTE_UNUSED)
2138{
2139  tree f_stk, stk;
2140  tree f_reg, reg;
2141  tree f_ndx, ndx;
2142  tree type_size, array, orig_ndx, addr, size, va_size, t;
2143  tree lab_false, lab_over, lab_false2;
2144  bool indirect;
2145
2146  indirect = pass_by_reference (NULL, TYPE_MODE (type), type, false);
2147  if (indirect)
2148    type = build_pointer_type (type);
2149
2150  /* Handle complex values as separate real and imaginary parts.  */
2151  if (TREE_CODE (type) == COMPLEX_TYPE)
2152    {
2153      tree real_part, imag_part;
2154
2155      real_part = xtensa_gimplify_va_arg_expr (valist, TREE_TYPE (type),
2156					       pre_p, NULL);
2157      real_part = get_initialized_tmp_var (real_part, pre_p, NULL);
2158
2159      imag_part = xtensa_gimplify_va_arg_expr (valist, TREE_TYPE (type),
2160					       pre_p, NULL);
2161      imag_part = get_initialized_tmp_var (imag_part, pre_p, NULL);
2162
2163      return build (COMPLEX_EXPR, type, real_part, imag_part);
2164    }
2165
2166  f_stk = TYPE_FIELDS (va_list_type_node);
2167  f_reg = TREE_CHAIN (f_stk);
2168  f_ndx = TREE_CHAIN (f_reg);
2169
2170  stk = build (COMPONENT_REF, TREE_TYPE (f_stk), valist, f_stk, NULL_TREE);
2171  reg = build (COMPONENT_REF, TREE_TYPE (f_reg), valist, f_reg, NULL_TREE);
2172  ndx = build (COMPONENT_REF, TREE_TYPE (f_ndx), valist, f_ndx, NULL_TREE);
2173
2174  type_size = size_in_bytes (type);
2175  va_size = round_up (type_size, UNITS_PER_WORD);
2176  gimplify_expr (&va_size, pre_p, NULL, is_gimple_val, fb_rvalue);
2177
2178
2179  /* First align __va_ndx if necessary for this arg:
2180
2181     orig_ndx = (AP).__va_ndx;
2182     if (__alignof__ (TYPE) > 4 )
2183       orig_ndx = ((orig_ndx + __alignof__ (TYPE) - 1)
2184			& -__alignof__ (TYPE)); */
2185
2186  orig_ndx = get_initialized_tmp_var (ndx, pre_p, NULL);
2187
2188  if (TYPE_ALIGN (type) > BITS_PER_WORD)
2189    {
2190      int align = TYPE_ALIGN (type) / BITS_PER_UNIT;
2191
2192      t = build (PLUS_EXPR, integer_type_node, orig_ndx,
2193		 build_int_cst (NULL_TREE, align - 1));
2194      t = build (BIT_AND_EXPR, integer_type_node, t,
2195		 build_int_cst (NULL_TREE, -align));
2196      t = build (MODIFY_EXPR, integer_type_node, orig_ndx, t);
2197      gimplify_and_add (t, pre_p);
2198    }
2199
2200
2201  /* Increment __va_ndx to point past the argument:
2202
2203     (AP).__va_ndx = orig_ndx + __va_size (TYPE); */
2204
2205  t = fold_convert (integer_type_node, va_size);
2206  t = build (PLUS_EXPR, integer_type_node, orig_ndx, t);
2207  t = build (MODIFY_EXPR, integer_type_node, ndx, t);
2208  gimplify_and_add (t, pre_p);
2209
2210
2211  /* Check if the argument is in registers:
2212
2213     if ((AP).__va_ndx <= __MAX_ARGS_IN_REGISTERS * 4
2214         && !must_pass_in_stack (type))
2215        __array = (AP).__va_reg; */
2216
2217  array = create_tmp_var (ptr_type_node, NULL);
2218
2219  lab_over = NULL;
2220  if (!targetm.calls.must_pass_in_stack (TYPE_MODE (type), type))
2221    {
2222      lab_false = create_artificial_label ();
2223      lab_over = create_artificial_label ();
2224
2225      t = build_int_cst (NULL_TREE, MAX_ARGS_IN_REGISTERS * UNITS_PER_WORD);
2226      t = build (GT_EXPR, boolean_type_node, ndx, t);
2227      t = build (COND_EXPR, void_type_node, t,
2228		 build (GOTO_EXPR, void_type_node, lab_false),
2229		 NULL);
2230      gimplify_and_add (t, pre_p);
2231
2232      t = build (MODIFY_EXPR, void_type_node, array, reg);
2233      gimplify_and_add (t, pre_p);
2234
2235      t = build (GOTO_EXPR, void_type_node, lab_over);
2236      gimplify_and_add (t, pre_p);
2237
2238      t = build (LABEL_EXPR, void_type_node, lab_false);
2239      gimplify_and_add (t, pre_p);
2240    }
2241
2242
2243  /* ...otherwise, the argument is on the stack (never split between
2244     registers and the stack -- change __va_ndx if necessary):
2245
2246     else
2247       {
2248	 if (orig_ndx <= __MAX_ARGS_IN_REGISTERS * 4)
2249	     (AP).__va_ndx = 32 + __va_size (TYPE);
2250	 __array = (AP).__va_stk;
2251       } */
2252
2253  lab_false2 = create_artificial_label ();
2254
2255  t = build_int_cst (NULL_TREE, MAX_ARGS_IN_REGISTERS * UNITS_PER_WORD);
2256  t = build (GT_EXPR, boolean_type_node, orig_ndx, t);
2257  t = build (COND_EXPR, void_type_node, t,
2258	     build (GOTO_EXPR, void_type_node, lab_false2),
2259	     NULL);
2260  gimplify_and_add (t, pre_p);
2261
2262  t = size_binop (PLUS_EXPR, va_size, size_int (32));
2263  t = fold_convert (integer_type_node, t);
2264  t = build (MODIFY_EXPR, integer_type_node, ndx, t);
2265  gimplify_and_add (t, pre_p);
2266
2267  t = build (LABEL_EXPR, void_type_node, lab_false2);
2268  gimplify_and_add (t, pre_p);
2269
2270  t = build (MODIFY_EXPR, void_type_node, array, stk);
2271  gimplify_and_add (t, pre_p);
2272
2273  if (lab_over)
2274    {
2275      t = build (LABEL_EXPR, void_type_node, lab_over);
2276      gimplify_and_add (t, pre_p);
2277    }
2278
2279
2280  /* Given the base array pointer (__array) and index to the subsequent
2281     argument (__va_ndx), find the address:
2282
2283     __array + (AP).__va_ndx - (BYTES_BIG_ENDIAN && sizeof (TYPE) < 4
2284				? sizeof (TYPE)
2285				: __va_size (TYPE))
2286
2287     The results are endian-dependent because values smaller than one word
2288     are aligned differently.  */
2289
2290
2291  if (BYTES_BIG_ENDIAN && TREE_CODE (type_size) == INTEGER_CST)
2292    {
2293      t = size_int (PARM_BOUNDARY / BITS_PER_UNIT);
2294      t = fold (build (GE_EXPR, boolean_type_node, type_size, t));
2295      t = fold (build (COND_EXPR, sizetype, t, va_size, type_size));
2296      size = t;
2297    }
2298  else
2299    size = va_size;
2300
2301  t = fold_convert (ptr_type_node, ndx);
2302  addr = build (PLUS_EXPR, ptr_type_node, array, t);
2303  t = fold_convert (ptr_type_node, size);
2304  addr = build (MINUS_EXPR, ptr_type_node, addr, t);
2305
2306  addr = fold_convert (build_pointer_type (type), addr);
2307  if (indirect)
2308    addr = build_va_arg_indirect_ref (addr);
2309  return build_va_arg_indirect_ref (addr);
2310}
2311
2312
2313enum reg_class
2314xtensa_preferred_reload_class (rtx x, enum reg_class class, int isoutput)
2315{
2316  if (!isoutput && CONSTANT_P (x) && GET_CODE (x) == CONST_DOUBLE)
2317    return NO_REGS;
2318
2319  /* Don't use the stack pointer or hard frame pointer for reloads!
2320     The hard frame pointer would normally be OK except that it may
2321     briefly hold an incoming argument in the prologue, and reload
2322     won't know that it is live because the hard frame pointer is
2323     treated specially.  */
2324
2325  if (class == AR_REGS || class == GR_REGS)
2326    return RL_REGS;
2327
2328  return class;
2329}
2330
2331
2332enum reg_class
2333xtensa_secondary_reload_class (enum reg_class class,
2334			       enum machine_mode mode ATTRIBUTE_UNUSED,
2335			       rtx x, int isoutput)
2336{
2337  int regno;
2338
2339  if (GET_CODE (x) == SIGN_EXTEND)
2340    x = XEXP (x, 0);
2341  regno = xt_true_regnum (x);
2342
2343  if (!isoutput)
2344    {
2345      if (class == FP_REGS && constantpool_mem_p (x))
2346	return RL_REGS;
2347    }
2348
2349  if (ACC_REG_P (regno))
2350    return ((class == GR_REGS || class == RL_REGS) ? NO_REGS : RL_REGS);
2351  if (class == ACC_REG)
2352    return (GP_REG_P (regno) ? NO_REGS : RL_REGS);
2353
2354  return NO_REGS;
2355}
2356
2357
2358void
2359order_regs_for_local_alloc (void)
2360{
2361  if (!leaf_function_p ())
2362    {
2363      memcpy (reg_alloc_order, reg_nonleaf_alloc_order,
2364	      FIRST_PSEUDO_REGISTER * sizeof (int));
2365    }
2366  else
2367    {
2368      int i, num_arg_regs;
2369      int nxt = 0;
2370
2371      /* Use the AR registers in increasing order (skipping a0 and a1)
2372	 but save the incoming argument registers for a last resort.  */
2373      num_arg_regs = current_function_args_info.arg_words;
2374      if (num_arg_regs > MAX_ARGS_IN_REGISTERS)
2375	num_arg_regs = MAX_ARGS_IN_REGISTERS;
2376      for (i = GP_ARG_FIRST; i < 16 - num_arg_regs; i++)
2377	reg_alloc_order[nxt++] = i + num_arg_regs;
2378      for (i = 0; i < num_arg_regs; i++)
2379	reg_alloc_order[nxt++] = GP_ARG_FIRST + i;
2380
2381      /* List the coprocessor registers in order.  */
2382      for (i = 0; i < BR_REG_NUM; i++)
2383	reg_alloc_order[nxt++] = BR_REG_FIRST + i;
2384
2385      /* List the FP registers in order for now.  */
2386      for (i = 0; i < 16; i++)
2387	reg_alloc_order[nxt++] = FP_REG_FIRST + i;
2388
2389      /* GCC requires that we list *all* the registers....  */
2390      reg_alloc_order[nxt++] = 0;	/* a0 = return address */
2391      reg_alloc_order[nxt++] = 1;	/* a1 = stack pointer */
2392      reg_alloc_order[nxt++] = 16;	/* pseudo frame pointer */
2393      reg_alloc_order[nxt++] = 17;	/* pseudo arg pointer */
2394
2395      reg_alloc_order[nxt++] = ACC_REG_FIRST;	/* MAC16 accumulator */
2396    }
2397}
2398
2399
2400/* Some Xtensa targets support multiple bss sections.  If the section
2401   name ends with ".bss", add SECTION_BSS to the flags.  */
2402
2403static unsigned int
2404xtensa_multibss_section_type_flags (tree decl, const char *name, int reloc)
2405{
2406  unsigned int flags = default_section_type_flags (decl, name, reloc);
2407  const char *suffix;
2408
2409  suffix = strrchr (name, '.');
2410  if (suffix && strcmp (suffix, ".bss") == 0)
2411    {
2412      if (!decl || (TREE_CODE (decl) == VAR_DECL
2413		    && DECL_INITIAL (decl) == NULL_TREE))
2414	flags |= SECTION_BSS;  /* @nobits */
2415      else
2416	warning (0, "only uninitialized variables can be placed in a "
2417		 ".bss section");
2418    }
2419
2420  return flags;
2421}
2422
2423
2424/* The literal pool stays with the function.  */
2425
2426static void
2427xtensa_select_rtx_section (enum machine_mode mode ATTRIBUTE_UNUSED,
2428			   rtx x ATTRIBUTE_UNUSED,
2429			   unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED)
2430{
2431  function_section (current_function_decl);
2432}
2433
2434
2435/* Compute a (partial) cost for rtx X.  Return true if the complete
2436   cost has been computed, and false if subexpressions should be
2437   scanned.  In either case, *TOTAL contains the cost result.  */
2438
2439static bool
2440xtensa_rtx_costs (rtx x, int code, int outer_code, int *total)
2441{
2442  switch (code)
2443    {
2444    case CONST_INT:
2445      switch (outer_code)
2446	{
2447	case SET:
2448	  if (xtensa_simm12b (INTVAL (x)))
2449	    {
2450	      *total = 4;
2451	      return true;
2452	    }
2453	  break;
2454	case PLUS:
2455	  if (xtensa_simm8 (INTVAL (x))
2456	      || xtensa_simm8x256 (INTVAL (x)))
2457	    {
2458	      *total = 0;
2459	      return true;
2460	    }
2461	  break;
2462	case AND:
2463	  if (xtensa_mask_immediate (INTVAL (x)))
2464	    {
2465	      *total = 0;
2466	      return true;
2467	    }
2468	  break;
2469	case COMPARE:
2470	  if ((INTVAL (x) == 0) || xtensa_b4const (INTVAL (x)))
2471	    {
2472	      *total = 0;
2473	      return true;
2474	    }
2475	  break;
2476	case ASHIFT:
2477	case ASHIFTRT:
2478	case LSHIFTRT:
2479	case ROTATE:
2480	case ROTATERT:
2481	  /* No way to tell if X is the 2nd operand so be conservative.  */
2482	default: break;
2483	}
2484      if (xtensa_simm12b (INTVAL (x)))
2485	*total = 5;
2486      else if (TARGET_CONST16)
2487	*total = COSTS_N_INSNS (2);
2488      else
2489	*total = 6;
2490      return true;
2491
2492    case CONST:
2493    case LABEL_REF:
2494    case SYMBOL_REF:
2495      if (TARGET_CONST16)
2496	*total = COSTS_N_INSNS (2);
2497      else
2498	*total = 5;
2499      return true;
2500
2501    case CONST_DOUBLE:
2502      if (TARGET_CONST16)
2503	*total = COSTS_N_INSNS (4);
2504      else
2505	*total = 7;
2506      return true;
2507
2508    case MEM:
2509      {
2510	int num_words =
2511	  (GET_MODE_SIZE (GET_MODE (x)) > UNITS_PER_WORD) ?  2 : 1;
2512
2513	if (memory_address_p (GET_MODE (x), XEXP ((x), 0)))
2514	  *total = COSTS_N_INSNS (num_words);
2515	else
2516	  *total = COSTS_N_INSNS (2*num_words);
2517	return true;
2518      }
2519
2520    case FFS:
2521      *total = COSTS_N_INSNS (TARGET_NSA ? 5 : 50);
2522      return true;
2523
2524    case NOT:
2525      *total = COSTS_N_INSNS ((GET_MODE (x) == DImode) ? 3 : 2);
2526      return true;
2527
2528    case AND:
2529    case IOR:
2530    case XOR:
2531      if (GET_MODE (x) == DImode)
2532	*total = COSTS_N_INSNS (2);
2533      else
2534	*total = COSTS_N_INSNS (1);
2535      return true;
2536
2537    case ASHIFT:
2538    case ASHIFTRT:
2539    case LSHIFTRT:
2540      if (GET_MODE (x) == DImode)
2541	*total = COSTS_N_INSNS (50);
2542      else
2543	*total = COSTS_N_INSNS (1);
2544      return true;
2545
2546    case ABS:
2547      {
2548	enum machine_mode xmode = GET_MODE (x);
2549	if (xmode == SFmode)
2550	  *total = COSTS_N_INSNS (TARGET_HARD_FLOAT ? 1 : 50);
2551	else if (xmode == DFmode)
2552	  *total = COSTS_N_INSNS (50);
2553	else
2554	  *total = COSTS_N_INSNS (4);
2555	return true;
2556      }
2557
2558    case PLUS:
2559    case MINUS:
2560      {
2561	enum machine_mode xmode = GET_MODE (x);
2562	if (xmode == SFmode)
2563	  *total = COSTS_N_INSNS (TARGET_HARD_FLOAT ? 1 : 50);
2564	else if (xmode == DFmode || xmode == DImode)
2565	  *total = COSTS_N_INSNS (50);
2566	else
2567	  *total = COSTS_N_INSNS (1);
2568	return true;
2569      }
2570
2571    case NEG:
2572      *total = COSTS_N_INSNS ((GET_MODE (x) == DImode) ? 4 : 2);
2573      return true;
2574
2575    case MULT:
2576      {
2577	enum machine_mode xmode = GET_MODE (x);
2578	if (xmode == SFmode)
2579	  *total = COSTS_N_INSNS (TARGET_HARD_FLOAT ? 4 : 50);
2580	else if (xmode == DFmode || xmode == DImode)
2581	  *total = COSTS_N_INSNS (50);
2582	else if (TARGET_MUL32)
2583	  *total = COSTS_N_INSNS (4);
2584	else if (TARGET_MAC16)
2585	  *total = COSTS_N_INSNS (16);
2586	else if (TARGET_MUL16)
2587	  *total = COSTS_N_INSNS (12);
2588	else
2589	  *total = COSTS_N_INSNS (50);
2590	return true;
2591      }
2592
2593    case DIV:
2594    case MOD:
2595      {
2596	enum machine_mode xmode = GET_MODE (x);
2597	if (xmode == SFmode)
2598	  {
2599	    *total = COSTS_N_INSNS (TARGET_HARD_FLOAT_DIV ? 8 : 50);
2600	    return true;
2601	  }
2602	else if (xmode == DFmode)
2603	  {
2604	    *total = COSTS_N_INSNS (50);
2605	    return true;
2606	  }
2607      }
2608      /* Fall through.  */
2609
2610    case UDIV:
2611    case UMOD:
2612      {
2613	enum machine_mode xmode = GET_MODE (x);
2614	if (xmode == DImode)
2615	  *total = COSTS_N_INSNS (50);
2616	else if (TARGET_DIV32)
2617	  *total = COSTS_N_INSNS (32);
2618	else
2619	  *total = COSTS_N_INSNS (50);
2620	return true;
2621      }
2622
2623    case SQRT:
2624      if (GET_MODE (x) == SFmode)
2625	*total = COSTS_N_INSNS (TARGET_HARD_FLOAT_SQRT ? 8 : 50);
2626      else
2627	*total = COSTS_N_INSNS (50);
2628      return true;
2629
2630    case SMIN:
2631    case UMIN:
2632    case SMAX:
2633    case UMAX:
2634      *total = COSTS_N_INSNS (TARGET_MINMAX ? 1 : 50);
2635      return true;
2636
2637    case SIGN_EXTRACT:
2638    case SIGN_EXTEND:
2639      *total = COSTS_N_INSNS (TARGET_SEXT ? 1 : 2);
2640      return true;
2641
2642    case ZERO_EXTRACT:
2643    case ZERO_EXTEND:
2644      *total = COSTS_N_INSNS (1);
2645      return true;
2646
2647    default:
2648      return false;
2649    }
2650}
2651
2652/* Worker function for TARGET_RETURN_IN_MEMORY.  */
2653
2654static bool
2655xtensa_return_in_memory (tree type, tree fntype ATTRIBUTE_UNUSED)
2656{
2657  return ((unsigned HOST_WIDE_INT) int_size_in_bytes (type)
2658	  > 4 * UNITS_PER_WORD);
2659}
2660
2661#include "gt-xtensa.h"
2662