1/* Subroutines for insn-output.c for Tensilica's Xtensa architecture.
2   Copyright 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
3   Free Software Foundation, Inc.
4   Contributed by Bob Wilson (bwilson@tensilica.com) at Tensilica.
5
6This file is part of GCC.
7
8GCC is free software; you can redistribute it and/or modify it under
9the terms of the GNU General Public License as published by the Free
10Software Foundation; either version 3, or (at your option) any later
11version.
12
13GCC is distributed in the hope that it will be useful, but WITHOUT ANY
14WARRANTY; without even the implied warranty of MERCHANTABILITY or
15FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
16for more details.
17
18You should have received a copy of the GNU General Public License
19along with GCC; see the file COPYING3.  If not see
20<http://www.gnu.org/licenses/>.  */
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 "gimple.h"
52#include "df.h"
53
54
55/* Enumeration for all of the relational tests, so that we can build
56   arrays indexed by the test type, and not worry about the order
57   of EQ, NE, etc.  */
58
59enum internal_test
60{
61  ITEST_EQ,
62  ITEST_NE,
63  ITEST_GT,
64  ITEST_GE,
65  ITEST_LT,
66  ITEST_LE,
67  ITEST_GTU,
68  ITEST_GEU,
69  ITEST_LTU,
70  ITEST_LEU,
71  ITEST_MAX
72};
73
74/* Array giving truth value on whether or not a given hard register
75   can support a given mode.  */
76char xtensa_hard_regno_mode_ok[(int) MAX_MACHINE_MODE][FIRST_PSEUDO_REGISTER];
77
78/* Current frame size calculated by compute_frame_size.  */
79unsigned xtensa_current_frame_size;
80
81/* Largest block move to handle in-line.  */
82#define LARGEST_MOVE_RATIO 15
83
84/* Define the structure for the machine field in struct function.  */
85struct GTY(()) machine_function
86{
87  int accesses_prev_frame;
88  bool need_a7_copy;
89  bool vararg_a7;
90  rtx vararg_a7_copy;
91  rtx set_frame_ptr_insn;
92};
93
94/* Vector, indexed by hard register number, which contains 1 for a
95   register that is allowable in a candidate for leaf function
96   treatment.  */
97
98const char xtensa_leaf_regs[FIRST_PSEUDO_REGISTER] =
99{
100  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
101  1, 1, 1,
102  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
103  1
104};
105
106/* Map hard register number to register class */
107const enum reg_class xtensa_regno_to_class[FIRST_PSEUDO_REGISTER] =
108{
109  RL_REGS,	SP_REG,		RL_REGS,	RL_REGS,
110  RL_REGS,	RL_REGS,	RL_REGS,	GR_REGS,
111  RL_REGS,	RL_REGS,	RL_REGS,	RL_REGS,
112  RL_REGS,	RL_REGS,	RL_REGS,	RL_REGS,
113  AR_REGS,	AR_REGS,	BR_REGS,
114  FP_REGS,	FP_REGS,	FP_REGS,	FP_REGS,
115  FP_REGS,	FP_REGS,	FP_REGS,	FP_REGS,
116  FP_REGS,	FP_REGS,	FP_REGS,	FP_REGS,
117  FP_REGS,	FP_REGS,	FP_REGS,	FP_REGS,
118  ACC_REG,
119};
120
121static enum internal_test map_test_to_internal_test (enum rtx_code);
122static rtx gen_int_relational (enum rtx_code, rtx, rtx, int *);
123static rtx gen_float_relational (enum rtx_code, rtx, rtx);
124static rtx gen_conditional_move (enum rtx_code, enum machine_mode, rtx, rtx);
125static rtx fixup_subreg_mem (rtx);
126static struct machine_function * xtensa_init_machine_status (void);
127static rtx xtensa_legitimize_tls_address (rtx);
128static rtx xtensa_legitimize_address (rtx, rtx, enum machine_mode);
129static bool xtensa_return_in_msb (const_tree);
130static void printx (FILE *, signed int);
131static void xtensa_function_epilogue (FILE *, HOST_WIDE_INT);
132static rtx xtensa_builtin_saveregs (void);
133static bool xtensa_legitimate_address_p (enum machine_mode, rtx, bool);
134static unsigned int xtensa_multibss_section_type_flags (tree, const char *,
135							int) ATTRIBUTE_UNUSED;
136static section *xtensa_select_rtx_section (enum machine_mode, rtx,
137					   unsigned HOST_WIDE_INT);
138static bool xtensa_rtx_costs (rtx, int, int, int *, bool);
139static tree xtensa_build_builtin_va_list (void);
140static bool xtensa_return_in_memory (const_tree, const_tree);
141static tree xtensa_gimplify_va_arg_expr (tree, tree, gimple_seq *,
142					 gimple_seq *);
143static rtx xtensa_function_value (const_tree, const_tree, bool);
144static void xtensa_init_builtins (void);
145static tree xtensa_fold_builtin (tree, tree, bool);
146static rtx xtensa_expand_builtin (tree, rtx, rtx, enum machine_mode, int);
147static void xtensa_va_start (tree, rtx);
148static bool xtensa_frame_pointer_required (void);
149static rtx xtensa_static_chain (const_tree, bool);
150static void xtensa_asm_trampoline_template (FILE *);
151static void xtensa_trampoline_init (rtx, tree, rtx);
152
153static const int reg_nonleaf_alloc_order[FIRST_PSEUDO_REGISTER] =
154  REG_ALLOC_ORDER;
155
156
157/* This macro generates the assembly code for function exit,
158   on machines that need it.  If FUNCTION_EPILOGUE is not defined
159   then individual return instructions are generated for each
160   return statement.  Args are same as for FUNCTION_PROLOGUE.  */
161
162#undef TARGET_ASM_FUNCTION_EPILOGUE
163#define TARGET_ASM_FUNCTION_EPILOGUE xtensa_function_epilogue
164
165/* These hooks specify assembly directives for creating certain kinds
166   of integer object.  */
167
168#undef TARGET_ASM_ALIGNED_SI_OP
169#define TARGET_ASM_ALIGNED_SI_OP "\t.word\t"
170
171#undef TARGET_ASM_SELECT_RTX_SECTION
172#define TARGET_ASM_SELECT_RTX_SECTION  xtensa_select_rtx_section
173
174#undef TARGET_DEFAULT_TARGET_FLAGS
175#define TARGET_DEFAULT_TARGET_FLAGS (TARGET_DEFAULT | MASK_FUSED_MADD)
176
177#undef TARGET_LEGITIMIZE_ADDRESS
178#define TARGET_LEGITIMIZE_ADDRESS xtensa_legitimize_address
179
180#undef TARGET_RTX_COSTS
181#define TARGET_RTX_COSTS xtensa_rtx_costs
182#undef TARGET_ADDRESS_COST
183#define TARGET_ADDRESS_COST hook_int_rtx_bool_0
184
185#undef TARGET_BUILD_BUILTIN_VA_LIST
186#define TARGET_BUILD_BUILTIN_VA_LIST xtensa_build_builtin_va_list
187
188#undef TARGET_EXPAND_BUILTIN_VA_START
189#define TARGET_EXPAND_BUILTIN_VA_START xtensa_va_start
190
191#undef TARGET_PROMOTE_FUNCTION_MODE
192#define TARGET_PROMOTE_FUNCTION_MODE default_promote_function_mode_always_promote
193#undef TARGET_PROMOTE_PROTOTYPES
194#define TARGET_PROMOTE_PROTOTYPES hook_bool_const_tree_true
195
196#undef TARGET_RETURN_IN_MEMORY
197#define TARGET_RETURN_IN_MEMORY xtensa_return_in_memory
198#undef TARGET_FUNCTION_VALUE
199#define TARGET_FUNCTION_VALUE xtensa_function_value
200#undef TARGET_SPLIT_COMPLEX_ARG
201#define TARGET_SPLIT_COMPLEX_ARG hook_bool_const_tree_true
202#undef TARGET_MUST_PASS_IN_STACK
203#define TARGET_MUST_PASS_IN_STACK must_pass_in_stack_var_size
204
205#undef TARGET_EXPAND_BUILTIN_SAVEREGS
206#define TARGET_EXPAND_BUILTIN_SAVEREGS xtensa_builtin_saveregs
207#undef TARGET_GIMPLIFY_VA_ARG_EXPR
208#define TARGET_GIMPLIFY_VA_ARG_EXPR xtensa_gimplify_va_arg_expr
209
210#undef TARGET_RETURN_IN_MSB
211#define TARGET_RETURN_IN_MSB xtensa_return_in_msb
212
213#undef  TARGET_INIT_BUILTINS
214#define TARGET_INIT_BUILTINS xtensa_init_builtins
215#undef  TARGET_FOLD_BUILTIN
216#define TARGET_FOLD_BUILTIN xtensa_fold_builtin
217#undef  TARGET_EXPAND_BUILTIN
218#define TARGET_EXPAND_BUILTIN xtensa_expand_builtin
219
220#undef TARGET_SECONDARY_RELOAD
221#define TARGET_SECONDARY_RELOAD xtensa_secondary_reload
222
223#undef TARGET_HAVE_TLS
224#define TARGET_HAVE_TLS (TARGET_THREADPTR && HAVE_AS_TLS)
225
226#undef TARGET_CANNOT_FORCE_CONST_MEM
227#define TARGET_CANNOT_FORCE_CONST_MEM xtensa_tls_referenced_p
228
229#undef TARGET_LEGITIMATE_ADDRESS_P
230#define TARGET_LEGITIMATE_ADDRESS_P	xtensa_legitimate_address_p
231
232#undef TARGET_FRAME_POINTER_REQUIRED
233#define TARGET_FRAME_POINTER_REQUIRED xtensa_frame_pointer_required
234
235#undef TARGET_STATIC_CHAIN
236#define TARGET_STATIC_CHAIN xtensa_static_chain
237#undef TARGET_ASM_TRAMPOLINE_TEMPLATE
238#define TARGET_ASM_TRAMPOLINE_TEMPLATE xtensa_asm_trampoline_template
239#undef TARGET_TRAMPOLINE_INIT
240#define TARGET_TRAMPOLINE_INIT xtensa_trampoline_init
241
242struct gcc_target targetm = TARGET_INITIALIZER;
243
244
245/* Functions to test Xtensa immediate operand validity.  */
246
247bool
248xtensa_simm8 (HOST_WIDE_INT v)
249{
250  return v >= -128 && v <= 127;
251}
252
253
254bool
255xtensa_simm8x256 (HOST_WIDE_INT v)
256{
257  return (v & 255) == 0 && (v >= -32768 && v <= 32512);
258}
259
260
261bool
262xtensa_simm12b (HOST_WIDE_INT v)
263{
264  return v >= -2048 && v <= 2047;
265}
266
267
268static bool
269xtensa_uimm8 (HOST_WIDE_INT v)
270{
271  return v >= 0 && v <= 255;
272}
273
274
275static bool
276xtensa_uimm8x2 (HOST_WIDE_INT v)
277{
278  return (v & 1) == 0 && (v >= 0 && v <= 510);
279}
280
281
282static bool
283xtensa_uimm8x4 (HOST_WIDE_INT v)
284{
285  return (v & 3) == 0 && (v >= 0 && v <= 1020);
286}
287
288
289static bool
290xtensa_b4const (HOST_WIDE_INT v)
291{
292  switch (v)
293    {
294    case -1:
295    case 1:
296    case 2:
297    case 3:
298    case 4:
299    case 5:
300    case 6:
301    case 7:
302    case 8:
303    case 10:
304    case 12:
305    case 16:
306    case 32:
307    case 64:
308    case 128:
309    case 256:
310      return true;
311    }
312  return false;
313}
314
315
316bool
317xtensa_b4const_or_zero (HOST_WIDE_INT v)
318{
319  if (v == 0)
320    return true;
321  return xtensa_b4const (v);
322}
323
324
325bool
326xtensa_b4constu (HOST_WIDE_INT v)
327{
328  switch (v)
329    {
330    case 32768:
331    case 65536:
332    case 2:
333    case 3:
334    case 4:
335    case 5:
336    case 6:
337    case 7:
338    case 8:
339    case 10:
340    case 12:
341    case 16:
342    case 32:
343    case 64:
344    case 128:
345    case 256:
346      return true;
347    }
348  return false;
349}
350
351
352bool
353xtensa_mask_immediate (HOST_WIDE_INT v)
354{
355#define MAX_MASK_SIZE 16
356  int mask_size;
357
358  for (mask_size = 1; mask_size <= MAX_MASK_SIZE; mask_size++)
359    {
360      if ((v & 1) == 0)
361	return false;
362      v = v >> 1;
363      if (v == 0)
364	return true;
365    }
366
367  return false;
368}
369
370
371/* This is just like the standard true_regnum() function except that it
372   works even when reg_renumber is not initialized.  */
373
374int
375xt_true_regnum (rtx x)
376{
377  if (GET_CODE (x) == REG)
378    {
379      if (reg_renumber
380	  && REGNO (x) >= FIRST_PSEUDO_REGISTER
381	  && reg_renumber[REGNO (x)] >= 0)
382	return reg_renumber[REGNO (x)];
383      return REGNO (x);
384    }
385  if (GET_CODE (x) == SUBREG)
386    {
387      int base = xt_true_regnum (SUBREG_REG (x));
388      if (base >= 0 && base < FIRST_PSEUDO_REGISTER)
389        return base + subreg_regno_offset (REGNO (SUBREG_REG (x)),
390                                           GET_MODE (SUBREG_REG (x)),
391                                           SUBREG_BYTE (x), GET_MODE (x));
392    }
393  return -1;
394}
395
396
397int
398xtensa_valid_move (enum machine_mode mode, rtx *operands)
399{
400  /* Either the destination or source must be a register, and the
401     MAC16 accumulator doesn't count.  */
402
403  if (register_operand (operands[0], mode))
404    {
405      int dst_regnum = xt_true_regnum (operands[0]);
406
407      /* The stack pointer can only be assigned with a MOVSP opcode.  */
408      if (dst_regnum == STACK_POINTER_REGNUM)
409	return (mode == SImode
410		&& register_operand (operands[1], mode)
411		&& !ACC_REG_P (xt_true_regnum (operands[1])));
412
413      if (!ACC_REG_P (dst_regnum))
414	return true;
415    }
416  if (register_operand (operands[1], mode))
417    {
418      int src_regnum = xt_true_regnum (operands[1]);
419      if (!ACC_REG_P (src_regnum))
420	return true;
421    }
422  return FALSE;
423}
424
425
426int
427smalloffset_mem_p (rtx op)
428{
429  if (GET_CODE (op) == MEM)
430    {
431      rtx addr = XEXP (op, 0);
432      if (GET_CODE (addr) == REG)
433	return BASE_REG_P (addr, 0);
434      if (GET_CODE (addr) == PLUS)
435	{
436	  rtx offset = XEXP (addr, 0);
437	  HOST_WIDE_INT val;
438	  if (GET_CODE (offset) != CONST_INT)
439	    offset = XEXP (addr, 1);
440	  if (GET_CODE (offset) != CONST_INT)
441	    return FALSE;
442
443	  val = INTVAL (offset);
444	  return (val & 3) == 0 && (val >= 0 && val <= 60);
445	}
446    }
447  return FALSE;
448}
449
450
451int
452constantpool_address_p (rtx addr)
453{
454  rtx sym = addr;
455
456  if (GET_CODE (addr) == CONST)
457    {
458      rtx offset;
459
460      /* Only handle (PLUS (SYM, OFFSET)) form.  */
461      addr = XEXP (addr, 0);
462      if (GET_CODE (addr) != PLUS)
463	return FALSE;
464
465      /* Make sure the address is word aligned.  */
466      offset = XEXP (addr, 1);
467      if ((GET_CODE (offset) != CONST_INT)
468	  || ((INTVAL (offset) & 3) != 0))
469	return FALSE;
470
471      sym = XEXP (addr, 0);
472    }
473
474  if ((GET_CODE (sym) == SYMBOL_REF)
475      && CONSTANT_POOL_ADDRESS_P (sym))
476    return TRUE;
477  return FALSE;
478}
479
480
481int
482constantpool_mem_p (rtx op)
483{
484  if (GET_CODE (op) == SUBREG)
485    op = SUBREG_REG (op);
486  if (GET_CODE (op) == MEM)
487    return constantpool_address_p (XEXP (op, 0));
488  return FALSE;
489}
490
491
492/* Return TRUE if X is a thread-local symbol.  */
493
494static bool
495xtensa_tls_symbol_p (rtx x)
496{
497  if (! TARGET_HAVE_TLS)
498    return false;
499
500  return GET_CODE (x) == SYMBOL_REF && SYMBOL_REF_TLS_MODEL (x) != 0;
501}
502
503
504void
505xtensa_extend_reg (rtx dst, rtx src)
506{
507  rtx temp = gen_reg_rtx (SImode);
508  rtx shift = GEN_INT (BITS_PER_WORD - GET_MODE_BITSIZE (GET_MODE (src)));
509
510  /* Generate paradoxical subregs as needed so that the modes match.  */
511  src = simplify_gen_subreg (SImode, src, GET_MODE (src), 0);
512  dst = simplify_gen_subreg (SImode, dst, GET_MODE (dst), 0);
513
514  emit_insn (gen_ashlsi3 (temp, src, shift));
515  emit_insn (gen_ashrsi3 (dst, temp, shift));
516}
517
518
519bool
520xtensa_mem_offset (unsigned v, enum machine_mode mode)
521{
522  switch (mode)
523    {
524    case BLKmode:
525      /* Handle the worst case for block moves.  See xtensa_expand_block_move
526	 where we emit an optimized block move operation if the block can be
527	 moved in < "move_ratio" pieces.  The worst case is when the block is
528	 aligned but has a size of (3 mod 4) (does this happen?) so that the
529	 last piece requires a byte load/store.  */
530      return (xtensa_uimm8 (v)
531	      && xtensa_uimm8 (v + MOVE_MAX * LARGEST_MOVE_RATIO));
532
533    case QImode:
534      return xtensa_uimm8 (v);
535
536    case HImode:
537      return xtensa_uimm8x2 (v);
538
539    case DFmode:
540      return (xtensa_uimm8x4 (v) && xtensa_uimm8x4 (v + 4));
541
542    default:
543      break;
544    }
545
546  return xtensa_uimm8x4 (v);
547}
548
549
550/* Make normal rtx_code into something we can index from an array.  */
551
552static enum internal_test
553map_test_to_internal_test (enum rtx_code test_code)
554{
555  enum internal_test test = ITEST_MAX;
556
557  switch (test_code)
558    {
559    default:			break;
560    case EQ:  test = ITEST_EQ;  break;
561    case NE:  test = ITEST_NE;  break;
562    case GT:  test = ITEST_GT;  break;
563    case GE:  test = ITEST_GE;  break;
564    case LT:  test = ITEST_LT;  break;
565    case LE:  test = ITEST_LE;  break;
566    case GTU: test = ITEST_GTU; break;
567    case GEU: test = ITEST_GEU; break;
568    case LTU: test = ITEST_LTU; break;
569    case LEU: test = ITEST_LEU; break;
570    }
571
572  return test;
573}
574
575
576/* Generate the code to compare two integer values.  The return value is
577   the comparison expression.  */
578
579static rtx
580gen_int_relational (enum rtx_code test_code, /* relational test (EQ, etc) */
581		    rtx cmp0, /* first operand to compare */
582		    rtx cmp1, /* second operand to compare */
583		    int *p_invert /* whether branch needs to reverse test */)
584{
585  struct cmp_info
586  {
587    enum rtx_code test_code;	/* test code to use in insn */
588    bool (*const_range_p) (HOST_WIDE_INT); /* range check function */
589    int const_add;		/* constant to add (convert LE -> LT) */
590    int reverse_regs;		/* reverse registers in test */
591    int invert_const;		/* != 0 if invert value if cmp1 is constant */
592    int invert_reg;		/* != 0 if invert value if cmp1 is register */
593    int unsignedp;		/* != 0 for unsigned comparisons.  */
594  };
595
596  static struct cmp_info info[ (int)ITEST_MAX ] = {
597
598    { EQ,	xtensa_b4const_or_zero,	0, 0, 0, 0, 0 },	/* EQ  */
599    { NE,	xtensa_b4const_or_zero,	0, 0, 0, 0, 0 },	/* NE  */
600
601    { LT,	xtensa_b4const_or_zero,	1, 1, 1, 0, 0 },	/* GT  */
602    { GE,	xtensa_b4const_or_zero,	0, 0, 0, 0, 0 },	/* GE  */
603    { LT,	xtensa_b4const_or_zero,	0, 0, 0, 0, 0 },	/* LT  */
604    { GE,	xtensa_b4const_or_zero,	1, 1, 1, 0, 0 },	/* LE  */
605
606    { LTU,	xtensa_b4constu,	1, 1, 1, 0, 1 },	/* GTU */
607    { GEU,	xtensa_b4constu,	0, 0, 0, 0, 1 },	/* GEU */
608    { LTU,	xtensa_b4constu,	0, 0, 0, 0, 1 },	/* LTU */
609    { GEU,	xtensa_b4constu,	1, 1, 1, 0, 1 },	/* LEU */
610  };
611
612  enum internal_test test;
613  enum machine_mode mode;
614  struct cmp_info *p_info;
615
616  test = map_test_to_internal_test (test_code);
617  gcc_assert (test != ITEST_MAX);
618
619  p_info = &info[ (int)test ];
620
621  mode = GET_MODE (cmp0);
622  if (mode == VOIDmode)
623    mode = GET_MODE (cmp1);
624
625  /* Make sure we can handle any constants given to us.  */
626  if (GET_CODE (cmp1) == CONST_INT)
627    {
628      HOST_WIDE_INT value = INTVAL (cmp1);
629      unsigned HOST_WIDE_INT uvalue = (unsigned HOST_WIDE_INT)value;
630
631      /* if the immediate overflows or does not fit in the immediate field,
632	 spill it to a register */
633
634      if ((p_info->unsignedp ?
635	   (uvalue + p_info->const_add > uvalue) :
636	   (value + p_info->const_add > value)) != (p_info->const_add > 0))
637	{
638	  cmp1 = force_reg (mode, cmp1);
639	}
640      else if (!(p_info->const_range_p) (value + p_info->const_add))
641	{
642	  cmp1 = force_reg (mode, cmp1);
643	}
644    }
645  else if ((GET_CODE (cmp1) != REG) && (GET_CODE (cmp1) != SUBREG))
646    {
647      cmp1 = force_reg (mode, cmp1);
648    }
649
650  /* See if we need to invert the result.  */
651  *p_invert = ((GET_CODE (cmp1) == CONST_INT)
652	       ? p_info->invert_const
653	       : p_info->invert_reg);
654
655  /* Comparison to constants, may involve adding 1 to change a LT into LE.
656     Comparison between two registers, may involve switching operands.  */
657  if (GET_CODE (cmp1) == CONST_INT)
658    {
659      if (p_info->const_add != 0)
660	cmp1 = GEN_INT (INTVAL (cmp1) + p_info->const_add);
661
662    }
663  else if (p_info->reverse_regs)
664    {
665      rtx temp = cmp0;
666      cmp0 = cmp1;
667      cmp1 = temp;
668    }
669
670  return gen_rtx_fmt_ee (p_info->test_code, VOIDmode, cmp0, cmp1);
671}
672
673
674/* Generate the code to compare two float values.  The return value is
675   the comparison expression.  */
676
677static rtx
678gen_float_relational (enum rtx_code test_code, /* relational test (EQ, etc) */
679		      rtx cmp0, /* first operand to compare */
680		      rtx cmp1 /* second operand to compare */)
681{
682  rtx (*gen_fn) (rtx, rtx, rtx);
683  rtx brtmp;
684  int reverse_regs, invert;
685
686  switch (test_code)
687    {
688    case EQ: reverse_regs = 0; invert = 0; gen_fn = gen_seq_sf; break;
689    case NE: reverse_regs = 0; invert = 1; gen_fn = gen_seq_sf; break;
690    case LE: reverse_regs = 0; invert = 0; gen_fn = gen_sle_sf; break;
691    case GT: reverse_regs = 1; invert = 0; gen_fn = gen_slt_sf; break;
692    case LT: reverse_regs = 0; invert = 0; gen_fn = gen_slt_sf; break;
693    case GE: reverse_regs = 1; invert = 0; gen_fn = gen_sle_sf; break;
694    case UNEQ: reverse_regs = 0; invert = 0; gen_fn = gen_suneq_sf; break;
695    case LTGT: reverse_regs = 0; invert = 1; gen_fn = gen_suneq_sf; break;
696    case UNLE: reverse_regs = 0; invert = 0; gen_fn = gen_sunle_sf; break;
697    case UNGT: reverse_regs = 1; invert = 0; gen_fn = gen_sunlt_sf; break;
698    case UNLT: reverse_regs = 0; invert = 0; gen_fn = gen_sunlt_sf; break;
699    case UNGE: reverse_regs = 1; invert = 0; gen_fn = gen_sunle_sf; break;
700    case UNORDERED:
701      reverse_regs = 0; invert = 0; gen_fn = gen_sunordered_sf; break;
702    case ORDERED:
703      reverse_regs = 0; invert = 1; gen_fn = gen_sunordered_sf; break;
704    default:
705      fatal_insn ("bad test", gen_rtx_fmt_ee (test_code, VOIDmode, cmp0, cmp1));
706      reverse_regs = 0; invert = 0; gen_fn = 0; /* avoid compiler warnings */
707    }
708
709  if (reverse_regs)
710    {
711      rtx temp = cmp0;
712      cmp0 = cmp1;
713      cmp1 = temp;
714    }
715
716  brtmp = gen_rtx_REG (CCmode, FPCC_REGNUM);
717  emit_insn (gen_fn (brtmp, cmp0, cmp1));
718
719  return gen_rtx_fmt_ee (invert ? EQ : NE, VOIDmode, brtmp, const0_rtx);
720}
721
722
723void
724xtensa_expand_conditional_branch (rtx *operands, enum machine_mode mode)
725{
726  enum rtx_code test_code = GET_CODE (operands[0]);
727  rtx cmp0 = operands[1];
728  rtx cmp1 = operands[2];
729  rtx cmp;
730  int invert;
731  rtx label1, label2;
732
733  switch (mode)
734    {
735    case DFmode:
736    default:
737      fatal_insn ("bad test", gen_rtx_fmt_ee (test_code, VOIDmode, cmp0, cmp1));
738
739    case SImode:
740      invert = FALSE;
741      cmp = gen_int_relational (test_code, cmp0, cmp1, &invert);
742      break;
743
744    case SFmode:
745      if (!TARGET_HARD_FLOAT)
746	fatal_insn ("bad test", gen_rtx_fmt_ee (test_code, VOIDmode,
747						cmp0, cmp1));
748      invert = FALSE;
749      cmp = gen_float_relational (test_code, cmp0, cmp1);
750      break;
751    }
752
753  /* Generate the branch.  */
754
755  label1 = gen_rtx_LABEL_REF (VOIDmode, operands[3]);
756  label2 = pc_rtx;
757
758  if (invert)
759    {
760      label2 = label1;
761      label1 = pc_rtx;
762    }
763
764  emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
765			       gen_rtx_IF_THEN_ELSE (VOIDmode, cmp,
766						     label1,
767						     label2)));
768}
769
770
771static rtx
772gen_conditional_move (enum rtx_code code, enum machine_mode mode,
773		      rtx op0, rtx op1)
774{
775  if (mode == SImode)
776    {
777      rtx cmp;
778
779      /* Jump optimization calls get_condition() which canonicalizes
780	 comparisons like (GE x <const>) to (GT x <const-1>).
781	 Transform those comparisons back to GE, since that is the
782	 comparison supported in Xtensa.  We shouldn't have to
783	 transform <LE x const> comparisons, because neither
784	 xtensa_expand_conditional_branch() nor get_condition() will
785	 produce them.  */
786
787      if ((code == GT) && (op1 == constm1_rtx))
788	{
789	  code = GE;
790	  op1 = const0_rtx;
791	}
792      cmp = gen_rtx_fmt_ee (code, VOIDmode, cc0_rtx, const0_rtx);
793
794      if (boolean_operator (cmp, VOIDmode))
795	{
796	  /* Swap the operands to make const0 second.  */
797	  if (op0 == const0_rtx)
798	    {
799	      op0 = op1;
800	      op1 = const0_rtx;
801	    }
802
803	  /* If not comparing against zero, emit a comparison (subtract).  */
804	  if (op1 != const0_rtx)
805	    {
806	      op0 = expand_binop (SImode, sub_optab, op0, op1,
807				  0, 0, OPTAB_LIB_WIDEN);
808	      op1 = const0_rtx;
809	    }
810	}
811      else if (branch_operator (cmp, VOIDmode))
812	{
813	  /* Swap the operands to make const0 second.  */
814	  if (op0 == const0_rtx)
815	    {
816	      op0 = op1;
817	      op1 = const0_rtx;
818
819	      switch (code)
820		{
821		case LT: code = GE; break;
822		case GE: code = LT; break;
823		default: gcc_unreachable ();
824		}
825	    }
826
827	  if (op1 != const0_rtx)
828	    return 0;
829	}
830      else
831	return 0;
832
833      return gen_rtx_fmt_ee (code, VOIDmode, op0, op1);
834    }
835
836  if (TARGET_HARD_FLOAT && mode == SFmode)
837    return gen_float_relational (code, op0, op1);
838
839  return 0;
840}
841
842
843int
844xtensa_expand_conditional_move (rtx *operands, int isflt)
845{
846  rtx dest = operands[0];
847  rtx cmp = operands[1];
848  enum machine_mode cmp_mode = GET_MODE (XEXP (cmp, 0));
849  rtx (*gen_fn) (rtx, rtx, rtx, rtx, rtx);
850
851  if (!(cmp = gen_conditional_move (GET_CODE (cmp), cmp_mode,
852				    XEXP (cmp, 0), XEXP (cmp, 1))))
853    return 0;
854
855  if (isflt)
856    gen_fn = (cmp_mode == SImode
857	      ? gen_movsfcc_internal0
858	      : gen_movsfcc_internal1);
859  else
860    gen_fn = (cmp_mode == SImode
861	      ? gen_movsicc_internal0
862	      : gen_movsicc_internal1);
863
864  emit_insn (gen_fn (dest, XEXP (cmp, 0), operands[2], operands[3], cmp));
865  return 1;
866}
867
868
869int
870xtensa_expand_scc (rtx operands[4], enum machine_mode cmp_mode)
871{
872  rtx dest = operands[0];
873  rtx cmp;
874  rtx one_tmp, zero_tmp;
875  rtx (*gen_fn) (rtx, rtx, rtx, rtx, rtx);
876
877  if (!(cmp = gen_conditional_move (GET_CODE (operands[1]), cmp_mode,
878				    operands[2], operands[3])))
879    return 0;
880
881  one_tmp = gen_reg_rtx (SImode);
882  zero_tmp = gen_reg_rtx (SImode);
883  emit_insn (gen_movsi (one_tmp, const_true_rtx));
884  emit_insn (gen_movsi (zero_tmp, const0_rtx));
885
886  gen_fn = (cmp_mode == SImode
887	    ? gen_movsicc_internal0
888	    : gen_movsicc_internal1);
889  emit_insn (gen_fn (dest, XEXP (cmp, 0), one_tmp, zero_tmp, cmp));
890  return 1;
891}
892
893
894/* Split OP[1] into OP[2,3] and likewise for OP[0] into OP[0,1].  MODE is
895   for the output, i.e., the input operands are twice as big as MODE.  */
896
897void
898xtensa_split_operand_pair (rtx operands[4], enum machine_mode mode)
899{
900  switch (GET_CODE (operands[1]))
901    {
902    case REG:
903      operands[3] = gen_rtx_REG (mode, REGNO (operands[1]) + 1);
904      operands[2] = gen_rtx_REG (mode, REGNO (operands[1]));
905      break;
906
907    case MEM:
908      operands[3] = adjust_address (operands[1], mode, GET_MODE_SIZE (mode));
909      operands[2] = adjust_address (operands[1], mode, 0);
910      break;
911
912    case CONST_INT:
913    case CONST_DOUBLE:
914      split_double (operands[1], &operands[2], &operands[3]);
915      break;
916
917    default:
918      gcc_unreachable ();
919    }
920
921  switch (GET_CODE (operands[0]))
922    {
923    case REG:
924      operands[1] = gen_rtx_REG (mode, REGNO (operands[0]) + 1);
925      operands[0] = gen_rtx_REG (mode, REGNO (operands[0]));
926      break;
927
928    case MEM:
929      operands[1] = adjust_address (operands[0], mode, GET_MODE_SIZE (mode));
930      operands[0] = adjust_address (operands[0], mode, 0);
931      break;
932
933    default:
934      gcc_unreachable ();
935    }
936}
937
938
939/* Emit insns to move operands[1] into operands[0].
940   Return 1 if we have written out everything that needs to be done to
941   do the move.  Otherwise, return 0 and the caller will emit the move
942   normally.  */
943
944int
945xtensa_emit_move_sequence (rtx *operands, enum machine_mode mode)
946{
947  rtx src = operands[1];
948
949  if (CONSTANT_P (src)
950      && (GET_CODE (src) != CONST_INT || ! xtensa_simm12b (INTVAL (src))))
951    {
952      rtx dst = operands[0];
953
954      if (xtensa_tls_referenced_p (src))
955	{
956	  rtx addend = NULL;
957
958	  if (GET_CODE (src) == CONST && GET_CODE (XEXP (src, 0)) == PLUS)
959	    {
960	      addend = XEXP (XEXP (src, 0), 1);
961	      src = XEXP (XEXP (src, 0), 0);
962	    }
963
964	  src = xtensa_legitimize_tls_address (src);
965	  if (addend)
966	    {
967	      src = gen_rtx_PLUS (mode, src, addend);
968	      src = force_operand (src, dst);
969	    }
970	  emit_move_insn (dst, src);
971	  return 1;
972	}
973
974      if (! TARGET_CONST16)
975	{
976	  src = force_const_mem (SImode, src);
977	  operands[1] = src;
978	}
979
980      /* PC-relative loads are always SImode, and CONST16 is only
981	 supported in the movsi pattern, so add a SUBREG for any other
982	 (smaller) mode.  */
983
984      if (mode != SImode)
985	{
986	  if (register_operand (dst, mode))
987	    {
988	      emit_move_insn (simplify_gen_subreg (SImode, dst, mode, 0), src);
989	      return 1;
990	    }
991	  else
992	    {
993	      src = force_reg (SImode, src);
994	      src = gen_lowpart_SUBREG (mode, src);
995	      operands[1] = src;
996	    }
997	}
998    }
999
1000  if (!(reload_in_progress | reload_completed)
1001      && !xtensa_valid_move (mode, operands))
1002    operands[1] = force_reg (mode, operands[1]);
1003
1004  operands[1] = xtensa_copy_incoming_a7 (operands[1]);
1005
1006  /* During reload we don't want to emit (subreg:X (mem:Y)) since that
1007     instruction won't be recognized after reload, so we remove the
1008     subreg and adjust mem accordingly.  */
1009  if (reload_in_progress)
1010    {
1011      operands[0] = fixup_subreg_mem (operands[0]);
1012      operands[1] = fixup_subreg_mem (operands[1]);
1013    }
1014  return 0;
1015}
1016
1017
1018static rtx
1019fixup_subreg_mem (rtx x)
1020{
1021  if (GET_CODE (x) == SUBREG
1022      && GET_CODE (SUBREG_REG (x)) == REG
1023      && REGNO (SUBREG_REG (x)) >= FIRST_PSEUDO_REGISTER)
1024    {
1025      rtx temp =
1026	gen_rtx_SUBREG (GET_MODE (x),
1027			reg_equiv_mem [REGNO (SUBREG_REG (x))],
1028			SUBREG_BYTE (x));
1029      x = alter_subreg (&temp);
1030    }
1031  return x;
1032}
1033
1034
1035/* Check if an incoming argument in a7 is expected to be used soon and
1036   if OPND is a register or register pair that includes a7.  If so,
1037   create a new pseudo and copy a7 into that pseudo at the very
1038   beginning of the function, followed by the special "set_frame_ptr"
1039   unspec_volatile insn.  The return value is either the original
1040   operand, if it is not a7, or the new pseudo containing a copy of
1041   the incoming argument.  This is necessary because the register
1042   allocator will ignore conflicts with a7 and may either assign some
1043   other pseudo to a7 or use a7 as the hard_frame_pointer, clobbering
1044   the incoming argument in a7.  By copying the argument out of a7 as
1045   the very first thing, and then immediately following that with an
1046   unspec_volatile to keep the scheduler away, we should avoid any
1047   problems.  Putting the set_frame_ptr insn at the beginning, with
1048   only the a7 copy before it, also makes it easier for the prologue
1049   expander to initialize the frame pointer after the a7 copy and to
1050   fix up the a7 copy to use the stack pointer instead of the frame
1051   pointer.  */
1052
1053rtx
1054xtensa_copy_incoming_a7 (rtx opnd)
1055{
1056  rtx entry_insns = 0;
1057  rtx reg, tmp;
1058  enum machine_mode mode;
1059
1060  if (!cfun->machine->need_a7_copy)
1061    return opnd;
1062
1063  /* This function should never be called again once a7 has been copied.  */
1064  gcc_assert (!cfun->machine->set_frame_ptr_insn);
1065
1066  mode = GET_MODE (opnd);
1067
1068  /* The operand using a7 may come in a later instruction, so just return
1069     the original operand if it doesn't use a7.  */
1070  reg = opnd;
1071  if (GET_CODE (reg) == SUBREG)
1072    {
1073      gcc_assert (SUBREG_BYTE (reg) == 0);
1074      reg = SUBREG_REG (reg);
1075    }
1076  if (GET_CODE (reg) != REG
1077      || REGNO (reg) > A7_REG
1078      || REGNO (reg) + HARD_REGNO_NREGS (A7_REG, mode) <= A7_REG)
1079    return opnd;
1080
1081  /* 1-word args will always be in a7; 2-word args in a6/a7.  */
1082  gcc_assert (REGNO (reg) + HARD_REGNO_NREGS (A7_REG, mode) - 1 == A7_REG);
1083
1084  cfun->machine->need_a7_copy = false;
1085
1086  /* Copy a7 to a new pseudo at the function entry.  Use gen_raw_REG to
1087     create the REG for a7 so that hard_frame_pointer_rtx is not used.  */
1088
1089  start_sequence ();
1090  tmp = gen_reg_rtx (mode);
1091
1092  switch (mode)
1093    {
1094    case DFmode:
1095    case DImode:
1096      /* Copy the value out of A7 here but keep the first word in A6 until
1097	 after the set_frame_ptr insn.  Otherwise, the register allocator
1098	 may decide to put "subreg (tmp, 0)" in A7 and clobber the incoming
1099	 value.  */
1100      emit_insn (gen_movsi_internal (gen_rtx_SUBREG (SImode, tmp, 4),
1101				     gen_raw_REG (SImode, A7_REG)));
1102      break;
1103    case SFmode:
1104      emit_insn (gen_movsf_internal (tmp, gen_raw_REG (mode, A7_REG)));
1105      break;
1106    case SImode:
1107      emit_insn (gen_movsi_internal (tmp, gen_raw_REG (mode, A7_REG)));
1108      break;
1109    case HImode:
1110      emit_insn (gen_movhi_internal (tmp, gen_raw_REG (mode, A7_REG)));
1111      break;
1112    case QImode:
1113      emit_insn (gen_movqi_internal (tmp, gen_raw_REG (mode, A7_REG)));
1114      break;
1115    default:
1116      gcc_unreachable ();
1117    }
1118
1119  cfun->machine->set_frame_ptr_insn = emit_insn (gen_set_frame_ptr ());
1120
1121  /* For DF and DI mode arguments, copy the incoming value in A6 now.  */
1122  if (mode == DFmode || mode == DImode)
1123    emit_insn (gen_movsi_internal (gen_rtx_SUBREG (SImode, tmp, 0),
1124				   gen_rtx_REG (SImode, A7_REG - 1)));
1125  entry_insns = get_insns ();
1126  end_sequence ();
1127
1128  if (cfun->machine->vararg_a7)
1129    {
1130      /* This is called from within builtin_saveregs, which will insert the
1131	 saveregs code at the function entry, ahead of anything placed at
1132	 the function entry now.  Instead, save the sequence to be inserted
1133	 at the beginning of the saveregs code.  */
1134      cfun->machine->vararg_a7_copy = entry_insns;
1135    }
1136  else
1137    {
1138      /* Put entry_insns after the NOTE that starts the function.  If
1139	 this is inside a start_sequence, make the outer-level insn
1140	 chain current, so the code is placed at the start of the
1141	 function.  */
1142      push_topmost_sequence ();
1143      /* Do not use entry_of_function() here.  This is called from within
1144	 expand_function_start, when the CFG still holds GIMPLE.  */
1145      emit_insn_after (entry_insns, get_insns ());
1146      pop_topmost_sequence ();
1147    }
1148
1149  return tmp;
1150}
1151
1152
1153/* Try to expand a block move operation to a sequence of RTL move
1154   instructions.  If not optimizing, or if the block size is not a
1155   constant, or if the block is too large, the expansion fails and GCC
1156   falls back to calling memcpy().
1157
1158   operands[0] is the destination
1159   operands[1] is the source
1160   operands[2] is the length
1161   operands[3] is the alignment */
1162
1163int
1164xtensa_expand_block_move (rtx *operands)
1165{
1166  static const enum machine_mode mode_from_align[] =
1167  {
1168    VOIDmode, QImode, HImode, VOIDmode, SImode,
1169  };
1170
1171  rtx dst_mem = operands[0];
1172  rtx src_mem = operands[1];
1173  HOST_WIDE_INT bytes, align;
1174  int num_pieces, move_ratio;
1175  rtx temp[2];
1176  enum machine_mode mode[2];
1177  int amount[2];
1178  bool active[2];
1179  int phase = 0;
1180  int next;
1181  int offset_ld = 0;
1182  int offset_st = 0;
1183  rtx x;
1184
1185  /* If this is not a fixed size move, just call memcpy.  */
1186  if (!optimize || (GET_CODE (operands[2]) != CONST_INT))
1187    return 0;
1188
1189  bytes = INTVAL (operands[2]);
1190  align = INTVAL (operands[3]);
1191
1192  /* Anything to move?  */
1193  if (bytes <= 0)
1194    return 0;
1195
1196  if (align > MOVE_MAX)
1197    align = MOVE_MAX;
1198
1199  /* Decide whether to expand inline based on the optimization level.  */
1200  move_ratio = 4;
1201  if (optimize > 2)
1202    move_ratio = LARGEST_MOVE_RATIO;
1203  num_pieces = (bytes / align) + (bytes % align); /* Close enough anyway.  */
1204  if (num_pieces > move_ratio)
1205    return 0;
1206
1207  x = XEXP (dst_mem, 0);
1208  if (!REG_P (x))
1209    {
1210      x = force_reg (Pmode, x);
1211      dst_mem = replace_equiv_address (dst_mem, x);
1212    }
1213
1214  x = XEXP (src_mem, 0);
1215  if (!REG_P (x))
1216    {
1217      x = force_reg (Pmode, x);
1218      src_mem = replace_equiv_address (src_mem, x);
1219    }
1220
1221  active[0] = active[1] = false;
1222
1223  do
1224    {
1225      next = phase;
1226      phase ^= 1;
1227
1228      if (bytes > 0)
1229	{
1230	  int next_amount;
1231
1232	  next_amount = (bytes >= 4 ? 4 : (bytes >= 2 ? 2 : 1));
1233	  next_amount = MIN (next_amount, align);
1234
1235	  amount[next] = next_amount;
1236	  mode[next] = mode_from_align[next_amount];
1237	  temp[next] = gen_reg_rtx (mode[next]);
1238
1239	  x = adjust_address (src_mem, mode[next], offset_ld);
1240	  emit_insn (gen_rtx_SET (VOIDmode, temp[next], x));
1241
1242	  offset_ld += next_amount;
1243	  bytes -= next_amount;
1244	  active[next] = true;
1245	}
1246
1247      if (active[phase])
1248	{
1249	  active[phase] = false;
1250
1251	  x = adjust_address (dst_mem, mode[phase], offset_st);
1252	  emit_insn (gen_rtx_SET (VOIDmode, x, temp[phase]));
1253
1254	  offset_st += amount[phase];
1255	}
1256    }
1257  while (active[next]);
1258
1259  return 1;
1260}
1261
1262
1263void
1264xtensa_expand_nonlocal_goto (rtx *operands)
1265{
1266  rtx goto_handler = operands[1];
1267  rtx containing_fp = operands[3];
1268
1269  /* Generate a call to "__xtensa_nonlocal_goto" (in libgcc); the code
1270     is too big to generate in-line.  */
1271
1272  if (GET_CODE (containing_fp) != REG)
1273    containing_fp = force_reg (Pmode, containing_fp);
1274
1275  emit_library_call (gen_rtx_SYMBOL_REF (Pmode, "__xtensa_nonlocal_goto"),
1276		     0, VOIDmode, 2,
1277		     containing_fp, Pmode,
1278		     goto_handler, Pmode);
1279}
1280
1281
1282static struct machine_function *
1283xtensa_init_machine_status (void)
1284{
1285  return GGC_CNEW (struct machine_function);
1286}
1287
1288
1289/* Shift VAL of mode MODE left by COUNT bits.  */
1290
1291static inline rtx
1292xtensa_expand_mask_and_shift (rtx val, enum machine_mode mode, rtx count)
1293{
1294  val = expand_simple_binop (SImode, AND, val, GEN_INT (GET_MODE_MASK (mode)),
1295			     NULL_RTX, 1, OPTAB_DIRECT);
1296  return expand_simple_binop (SImode, ASHIFT, val, count,
1297			      NULL_RTX, 1, OPTAB_DIRECT);
1298}
1299
1300
1301/* Structure to hold the initial parameters for a compare_and_swap operation
1302   in HImode and QImode.  */
1303
1304struct alignment_context
1305{
1306  rtx memsi;	  /* SI aligned memory location.  */
1307  rtx shift;	  /* Bit offset with regard to lsb.  */
1308  rtx modemask;	  /* Mask of the HQImode shifted by SHIFT bits.  */
1309  rtx modemaski;  /* ~modemask */
1310};
1311
1312
1313/* Initialize structure AC for word access to HI and QI mode memory.  */
1314
1315static void
1316init_alignment_context (struct alignment_context *ac, rtx mem)
1317{
1318  enum machine_mode mode = GET_MODE (mem);
1319  rtx byteoffset = NULL_RTX;
1320  bool aligned = (MEM_ALIGN (mem) >= GET_MODE_BITSIZE (SImode));
1321
1322  if (aligned)
1323    ac->memsi = adjust_address (mem, SImode, 0); /* Memory is aligned.  */
1324  else
1325    {
1326      /* Alignment is unknown.  */
1327      rtx addr, align;
1328
1329      /* Force the address into a register.  */
1330      addr = force_reg (Pmode, XEXP (mem, 0));
1331
1332      /* Align it to SImode.  */
1333      align = expand_simple_binop (Pmode, AND, addr,
1334				   GEN_INT (-GET_MODE_SIZE (SImode)),
1335				   NULL_RTX, 1, OPTAB_DIRECT);
1336      /* Generate MEM.  */
1337      ac->memsi = gen_rtx_MEM (SImode, align);
1338      MEM_VOLATILE_P (ac->memsi) = MEM_VOLATILE_P (mem);
1339      set_mem_alias_set (ac->memsi, ALIAS_SET_MEMORY_BARRIER);
1340      set_mem_align (ac->memsi, GET_MODE_BITSIZE (SImode));
1341
1342      byteoffset = expand_simple_binop (Pmode, AND, addr,
1343					GEN_INT (GET_MODE_SIZE (SImode) - 1),
1344					NULL_RTX, 1, OPTAB_DIRECT);
1345    }
1346
1347  /* Calculate shiftcount.  */
1348  if (TARGET_BIG_ENDIAN)
1349    {
1350      ac->shift = GEN_INT (GET_MODE_SIZE (SImode) - GET_MODE_SIZE (mode));
1351      if (!aligned)
1352	ac->shift = expand_simple_binop (SImode, MINUS, ac->shift, byteoffset,
1353					 NULL_RTX, 1, OPTAB_DIRECT);
1354    }
1355  else
1356    {
1357      if (aligned)
1358	ac->shift = NULL_RTX;
1359      else
1360	ac->shift = byteoffset;
1361    }
1362
1363  if (ac->shift != NULL_RTX)
1364    {
1365      /* Shift is the byte count, but we need the bitcount.  */
1366      ac->shift = expand_simple_binop (SImode, MULT, ac->shift,
1367				       GEN_INT (BITS_PER_UNIT),
1368				       NULL_RTX, 1, OPTAB_DIRECT);
1369      ac->modemask = expand_simple_binop (SImode, ASHIFT,
1370					  GEN_INT (GET_MODE_MASK (mode)),
1371					  ac->shift,
1372					  NULL_RTX, 1, OPTAB_DIRECT);
1373    }
1374  else
1375    ac->modemask = GEN_INT (GET_MODE_MASK (mode));
1376
1377  ac->modemaski = expand_simple_unop (SImode, NOT, ac->modemask, NULL_RTX, 1);
1378}
1379
1380
1381/* Expand an atomic compare and swap operation for HImode and QImode.
1382   MEM is the memory location, CMP the old value to compare MEM with
1383   and NEW_RTX the value to set if CMP == MEM.  */
1384
1385void
1386xtensa_expand_compare_and_swap (rtx target, rtx mem, rtx cmp, rtx new_rtx)
1387{
1388  enum machine_mode mode = GET_MODE (mem);
1389  struct alignment_context ac;
1390  rtx tmp, cmpv, newv, val;
1391  rtx oldval = gen_reg_rtx (SImode);
1392  rtx res = gen_reg_rtx (SImode);
1393  rtx csloop = gen_label_rtx ();
1394  rtx csend = gen_label_rtx ();
1395
1396  init_alignment_context (&ac, mem);
1397
1398  if (ac.shift != NULL_RTX)
1399    {
1400      cmp = xtensa_expand_mask_and_shift (cmp, mode, ac.shift);
1401      new_rtx = xtensa_expand_mask_and_shift (new_rtx, mode, ac.shift);
1402    }
1403
1404  /* Load the surrounding word into VAL with the MEM value masked out.  */
1405  val = force_reg (SImode, expand_simple_binop (SImode, AND, ac.memsi,
1406						ac.modemaski, NULL_RTX, 1,
1407						OPTAB_DIRECT));
1408  emit_label (csloop);
1409
1410  /* Patch CMP and NEW_RTX into VAL at correct position.  */
1411  cmpv = force_reg (SImode, expand_simple_binop (SImode, IOR, cmp, val,
1412						 NULL_RTX, 1, OPTAB_DIRECT));
1413  newv = force_reg (SImode, expand_simple_binop (SImode, IOR, new_rtx, val,
1414						 NULL_RTX, 1, OPTAB_DIRECT));
1415
1416  /* Jump to end if we're done.  */
1417  emit_insn (gen_sync_compare_and_swapsi (res, ac.memsi, cmpv, newv));
1418  emit_cmp_and_jump_insns (res, cmpv, EQ, const0_rtx, SImode, true, csend);
1419
1420  /* Check for changes outside mode.  */
1421  emit_move_insn (oldval, val);
1422  tmp = expand_simple_binop (SImode, AND, res, ac.modemaski,
1423			     val, 1, OPTAB_DIRECT);
1424  if (tmp != val)
1425    emit_move_insn (val, tmp);
1426
1427  /* Loop internal if so.  */
1428  emit_cmp_and_jump_insns (oldval, val, NE, const0_rtx, SImode, true, csloop);
1429
1430  emit_label (csend);
1431
1432  /* Return the correct part of the bitfield.  */
1433  convert_move (target,
1434		(ac.shift == NULL_RTX ? res
1435		 : expand_simple_binop (SImode, LSHIFTRT, res, ac.shift,
1436					NULL_RTX, 1, OPTAB_DIRECT)),
1437		1);
1438}
1439
1440
1441/* Expand an atomic operation CODE of mode MODE (either HImode or QImode --
1442   the default expansion works fine for SImode).  MEM is the memory location
1443   and VAL the value to play with.  If AFTER is true then store the value
1444   MEM holds after the operation, if AFTER is false then store the value MEM
1445   holds before the operation.  If TARGET is zero then discard that value, else
1446   store it to TARGET.  */
1447
1448void
1449xtensa_expand_atomic (enum rtx_code code, rtx target, rtx mem, rtx val,
1450		      bool after)
1451{
1452  enum machine_mode mode = GET_MODE (mem);
1453  struct alignment_context ac;
1454  rtx csloop = gen_label_rtx ();
1455  rtx cmp, tmp;
1456  rtx old = gen_reg_rtx (SImode);
1457  rtx new_rtx = gen_reg_rtx (SImode);
1458  rtx orig = NULL_RTX;
1459
1460  init_alignment_context (&ac, mem);
1461
1462  /* Prepare values before the compare-and-swap loop.  */
1463  if (ac.shift != NULL_RTX)
1464    val = xtensa_expand_mask_and_shift (val, mode, ac.shift);
1465  switch (code)
1466    {
1467    case PLUS:
1468    case MINUS:
1469      orig = gen_reg_rtx (SImode);
1470      convert_move (orig, val, 1);
1471      break;
1472
1473    case SET:
1474    case IOR:
1475    case XOR:
1476      break;
1477
1478    case MULT: /* NAND */
1479    case AND:
1480      /* val = "11..1<val>11..1" */
1481      val = expand_simple_binop (SImode, XOR, val, ac.modemaski,
1482				 NULL_RTX, 1, OPTAB_DIRECT);
1483      break;
1484
1485    default:
1486      gcc_unreachable ();
1487    }
1488
1489  /* Load full word.  Subsequent loads are performed by S32C1I.  */
1490  cmp = force_reg (SImode, ac.memsi);
1491
1492  emit_label (csloop);
1493  emit_move_insn (old, cmp);
1494
1495  switch (code)
1496    {
1497    case PLUS:
1498    case MINUS:
1499      val = expand_simple_binop (SImode, code, old, orig,
1500				 NULL_RTX, 1, OPTAB_DIRECT);
1501      val = expand_simple_binop (SImode, AND, val, ac.modemask,
1502				 NULL_RTX, 1, OPTAB_DIRECT);
1503      /* FALLTHRU */
1504    case SET:
1505      tmp = expand_simple_binop (SImode, AND, old, ac.modemaski,
1506				 NULL_RTX, 1, OPTAB_DIRECT);
1507      tmp = expand_simple_binop (SImode, IOR, tmp, val,
1508				 new_rtx, 1, OPTAB_DIRECT);
1509      break;
1510
1511    case AND:
1512    case IOR:
1513    case XOR:
1514      tmp = expand_simple_binop (SImode, code, old, val,
1515				 new_rtx, 1, OPTAB_DIRECT);
1516      break;
1517
1518    case MULT: /* NAND */
1519      tmp = expand_simple_binop (SImode, XOR, old, ac.modemask,
1520				 NULL_RTX, 1, OPTAB_DIRECT);
1521      tmp = expand_simple_binop (SImode, AND, tmp, val,
1522				 new_rtx, 1, OPTAB_DIRECT);
1523      break;
1524
1525    default:
1526      gcc_unreachable ();
1527    }
1528
1529  if (tmp != new_rtx)
1530    emit_move_insn (new_rtx, tmp);
1531  emit_insn (gen_sync_compare_and_swapsi (cmp, ac.memsi, old, new_rtx));
1532  emit_cmp_and_jump_insns (cmp, old, NE, const0_rtx, SImode, true, csloop);
1533
1534  if (target)
1535    {
1536      tmp = (after ? new_rtx : cmp);
1537      convert_move (target,
1538		    (ac.shift == NULL_RTX ? tmp
1539		     : expand_simple_binop (SImode, LSHIFTRT, tmp, ac.shift,
1540					    NULL_RTX, 1, OPTAB_DIRECT)),
1541		    1);
1542    }
1543}
1544
1545
1546void
1547xtensa_setup_frame_addresses (void)
1548{
1549  /* Set flag to cause TARGET_FRAME_POINTER_REQUIRED to return true.  */
1550  cfun->machine->accesses_prev_frame = 1;
1551
1552  emit_library_call
1553    (gen_rtx_SYMBOL_REF (Pmode, "__xtensa_libgcc_window_spill"),
1554     0, VOIDmode, 0);
1555}
1556
1557
1558/* Emit the assembly for the end of a zero-cost loop.  Normally we just emit
1559   a comment showing where the end of the loop is.  However, if there is a
1560   label or a branch at the end of the loop then we need to place a nop
1561   there.  If the loop ends with a label we need the nop so that branches
1562   targeting that label will target the nop (and thus remain in the loop),
1563   instead of targeting the instruction after the loop (and thus exiting
1564   the loop).  If the loop ends with a branch, we need the nop in case the
1565   branch is targeting a location inside the loop.  When the branch
1566   executes it will cause the loop count to be decremented even if it is
1567   taken (because it is the last instruction in the loop), so we need to
1568   nop after the branch to prevent the loop count from being decremented
1569   when the branch is taken.  */
1570
1571void
1572xtensa_emit_loop_end (rtx insn, rtx *operands)
1573{
1574  char done = 0;
1575
1576  for (insn = PREV_INSN (insn); insn && !done; insn = PREV_INSN (insn))
1577    {
1578      switch (GET_CODE (insn))
1579	{
1580	case NOTE:
1581	case BARRIER:
1582	  break;
1583
1584	case CODE_LABEL:
1585	  output_asm_insn (TARGET_DENSITY ? "nop.n" : "nop", operands);
1586	  done = 1;
1587	  break;
1588
1589	default:
1590	  {
1591	    rtx body = PATTERN (insn);
1592
1593	    if (GET_CODE (body) == JUMP_INSN)
1594	      {
1595		output_asm_insn (TARGET_DENSITY ? "nop.n" : "nop", operands);
1596		done = 1;
1597	      }
1598	    else if ((GET_CODE (body) != USE)
1599		     && (GET_CODE (body) != CLOBBER))
1600	      done = 1;
1601	  }
1602	  break;
1603        }
1604    }
1605
1606  output_asm_insn ("# loop end for %0", operands);
1607}
1608
1609
1610char *
1611xtensa_emit_branch (bool inverted, bool immed, rtx *operands)
1612{
1613  static char result[64];
1614  enum rtx_code code;
1615  const char *op;
1616
1617  code = GET_CODE (operands[3]);
1618  switch (code)
1619    {
1620    case EQ:	op = inverted ? "ne" : "eq"; break;
1621    case NE:	op = inverted ? "eq" : "ne"; break;
1622    case LT:	op = inverted ? "ge" : "lt"; break;
1623    case GE:	op = inverted ? "lt" : "ge"; break;
1624    case LTU:	op = inverted ? "geu" : "ltu"; break;
1625    case GEU:	op = inverted ? "ltu" : "geu"; break;
1626    default:	gcc_unreachable ();
1627    }
1628
1629  if (immed)
1630    {
1631      if (INTVAL (operands[1]) == 0)
1632	sprintf (result, "b%sz%s\t%%0, %%2", op,
1633		 (TARGET_DENSITY && (code == EQ || code == NE)) ? ".n" : "");
1634      else
1635	sprintf (result, "b%si\t%%0, %%d1, %%2", op);
1636    }
1637  else
1638    sprintf (result, "b%s\t%%0, %%1, %%2", op);
1639
1640  return result;
1641}
1642
1643
1644char *
1645xtensa_emit_bit_branch (bool inverted, bool immed, rtx *operands)
1646{
1647  static char result[64];
1648  const char *op;
1649
1650  switch (GET_CODE (operands[3]))
1651    {
1652    case EQ:	op = inverted ? "bs" : "bc"; break;
1653    case NE:	op = inverted ? "bc" : "bs"; break;
1654    default:	gcc_unreachable ();
1655    }
1656
1657  if (immed)
1658    {
1659      unsigned bitnum = INTVAL (operands[1]) & 0x1f;
1660      operands[1] = GEN_INT (bitnum);
1661      sprintf (result, "b%si\t%%0, %%d1, %%2", op);
1662    }
1663  else
1664    sprintf (result, "b%s\t%%0, %%1, %%2", op);
1665
1666  return result;
1667}
1668
1669
1670char *
1671xtensa_emit_movcc (bool inverted, bool isfp, bool isbool, rtx *operands)
1672{
1673  static char result[64];
1674  enum rtx_code code;
1675  const char *op;
1676
1677  code = GET_CODE (operands[4]);
1678  if (isbool)
1679    {
1680      switch (code)
1681	{
1682	case EQ:	op = inverted ? "t" : "f"; break;
1683	case NE:	op = inverted ? "f" : "t"; break;
1684	default:	gcc_unreachable ();
1685	}
1686    }
1687  else
1688    {
1689      switch (code)
1690	{
1691	case EQ:	op = inverted ? "nez" : "eqz"; break;
1692	case NE:	op = inverted ? "eqz" : "nez"; break;
1693	case LT:	op = inverted ? "gez" : "ltz"; break;
1694	case GE:	op = inverted ? "ltz" : "gez"; break;
1695	default:	gcc_unreachable ();
1696	}
1697    }
1698
1699  sprintf (result, "mov%s%s\t%%0, %%%d, %%1",
1700	   op, isfp ? ".s" : "", inverted ? 3 : 2);
1701  return result;
1702}
1703
1704
1705char *
1706xtensa_emit_call (int callop, rtx *operands)
1707{
1708  static char result[64];
1709  rtx tgt = operands[callop];
1710
1711  if (GET_CODE (tgt) == CONST_INT)
1712    sprintf (result, "call8\t0x%lx", INTVAL (tgt));
1713  else if (register_operand (tgt, VOIDmode))
1714    sprintf (result, "callx8\t%%%d", callop);
1715  else
1716    sprintf (result, "call8\t%%%d", callop);
1717
1718  return result;
1719}
1720
1721
1722bool
1723xtensa_legitimate_address_p (enum machine_mode mode, rtx addr, bool strict)
1724{
1725  /* Allow constant pool addresses.  */
1726  if (mode != BLKmode && GET_MODE_SIZE (mode) >= UNITS_PER_WORD
1727      && ! TARGET_CONST16 && constantpool_address_p (addr)
1728      && ! xtensa_tls_referenced_p (addr))
1729    return true;
1730
1731  while (GET_CODE (addr) == SUBREG)
1732    addr = SUBREG_REG (addr);
1733
1734  /* Allow base registers.  */
1735  if (GET_CODE (addr) == REG && BASE_REG_P (addr, strict))
1736    return true;
1737
1738  /* Check for "register + offset" addressing.  */
1739  if (GET_CODE (addr) == PLUS)
1740    {
1741      rtx xplus0 = XEXP (addr, 0);
1742      rtx xplus1 = XEXP (addr, 1);
1743      enum rtx_code code0;
1744      enum rtx_code code1;
1745
1746      while (GET_CODE (xplus0) == SUBREG)
1747	xplus0 = SUBREG_REG (xplus0);
1748      code0 = GET_CODE (xplus0);
1749
1750      while (GET_CODE (xplus1) == SUBREG)
1751	xplus1 = SUBREG_REG (xplus1);
1752      code1 = GET_CODE (xplus1);
1753
1754      /* Swap operands if necessary so the register is first.  */
1755      if (code0 != REG && code1 == REG)
1756	{
1757	  xplus0 = XEXP (addr, 1);
1758	  xplus1 = XEXP (addr, 0);
1759	  code0 = GET_CODE (xplus0);
1760	  code1 = GET_CODE (xplus1);
1761	}
1762
1763      if (code0 == REG && BASE_REG_P (xplus0, strict)
1764	  && code1 == CONST_INT
1765	  && xtensa_mem_offset (INTVAL (xplus1), mode))
1766	return true;
1767    }
1768
1769  return false;
1770}
1771
1772
1773/* Construct the SYMBOL_REF for the _TLS_MODULE_BASE_ symbol.  */
1774
1775static GTY(()) rtx xtensa_tls_module_base_symbol;
1776
1777static rtx
1778xtensa_tls_module_base (void)
1779{
1780  if (! xtensa_tls_module_base_symbol)
1781    {
1782      xtensa_tls_module_base_symbol =
1783	gen_rtx_SYMBOL_REF (Pmode, "_TLS_MODULE_BASE_");
1784      SYMBOL_REF_FLAGS (xtensa_tls_module_base_symbol)
1785        |= TLS_MODEL_GLOBAL_DYNAMIC << SYMBOL_FLAG_TLS_SHIFT;
1786    }
1787
1788  return xtensa_tls_module_base_symbol;
1789}
1790
1791
1792static rtx
1793xtensa_call_tls_desc (rtx sym, rtx *retp)
1794{
1795  rtx fn, arg, a10, call_insn, insns;
1796
1797  start_sequence ();
1798  fn = gen_reg_rtx (Pmode);
1799  arg = gen_reg_rtx (Pmode);
1800  a10 = gen_rtx_REG (Pmode, 10);
1801
1802  emit_insn (gen_tls_func (fn, sym));
1803  emit_insn (gen_tls_arg (arg, sym));
1804  emit_move_insn (a10, arg);
1805  call_insn = emit_call_insn (gen_tls_call (a10, fn, sym, const1_rtx));
1806  CALL_INSN_FUNCTION_USAGE (call_insn)
1807    = gen_rtx_EXPR_LIST (VOIDmode, gen_rtx_USE (VOIDmode, a10),
1808			 CALL_INSN_FUNCTION_USAGE (call_insn));
1809  insns = get_insns ();
1810  end_sequence ();
1811
1812  *retp = a10;
1813  return insns;
1814}
1815
1816
1817static rtx
1818xtensa_legitimize_tls_address (rtx x)
1819{
1820  unsigned int model = SYMBOL_REF_TLS_MODEL (x);
1821  rtx dest, tp, ret, modbase, base, addend, insns;
1822
1823  dest = gen_reg_rtx (Pmode);
1824  switch (model)
1825    {
1826    case TLS_MODEL_GLOBAL_DYNAMIC:
1827      insns = xtensa_call_tls_desc (x, &ret);
1828      emit_libcall_block (insns, dest, ret, x);
1829      break;
1830
1831    case TLS_MODEL_LOCAL_DYNAMIC:
1832      base = gen_reg_rtx (Pmode);
1833      modbase = xtensa_tls_module_base ();
1834      insns = xtensa_call_tls_desc (modbase, &ret);
1835      emit_libcall_block (insns, base, ret, modbase);
1836      addend = force_reg (SImode, gen_sym_DTPOFF (x));
1837      emit_insn (gen_addsi3 (dest, base, addend));
1838      break;
1839
1840    case TLS_MODEL_INITIAL_EXEC:
1841    case TLS_MODEL_LOCAL_EXEC:
1842      tp = gen_reg_rtx (SImode);
1843      emit_insn (gen_load_tp (tp));
1844      addend = force_reg (SImode, gen_sym_TPOFF (x));
1845      emit_insn (gen_addsi3 (dest, tp, addend));
1846      break;
1847
1848    default:
1849      gcc_unreachable ();
1850    }
1851
1852  return dest;
1853}
1854
1855
1856rtx
1857xtensa_legitimize_address (rtx x,
1858			   rtx oldx ATTRIBUTE_UNUSED,
1859			   enum machine_mode mode)
1860{
1861  if (xtensa_tls_symbol_p (x))
1862    return xtensa_legitimize_tls_address (x);
1863
1864  if (GET_CODE (x) == PLUS)
1865    {
1866      rtx plus0 = XEXP (x, 0);
1867      rtx plus1 = XEXP (x, 1);
1868
1869      if (GET_CODE (plus0) != REG && GET_CODE (plus1) == REG)
1870	{
1871	  plus0 = XEXP (x, 1);
1872	  plus1 = XEXP (x, 0);
1873	}
1874
1875      /* Try to split up the offset to use an ADDMI instruction.  */
1876      if (GET_CODE (plus0) == REG
1877	  && GET_CODE (plus1) == CONST_INT
1878	  && !xtensa_mem_offset (INTVAL (plus1), mode)
1879	  && !xtensa_simm8 (INTVAL (plus1))
1880	  && xtensa_mem_offset (INTVAL (plus1) & 0xff, mode)
1881	  && xtensa_simm8x256 (INTVAL (plus1) & ~0xff))
1882	{
1883	  rtx temp = gen_reg_rtx (Pmode);
1884	  rtx addmi_offset = GEN_INT (INTVAL (plus1) & ~0xff);
1885	  emit_insn (gen_rtx_SET (Pmode, temp,
1886				  gen_rtx_PLUS (Pmode, plus0, addmi_offset)));
1887	  return gen_rtx_PLUS (Pmode, temp, GEN_INT (INTVAL (plus1) & 0xff));
1888	}
1889    }
1890
1891  return x;
1892}
1893
1894
1895/* Helper for xtensa_tls_referenced_p.  */
1896
1897static int
1898xtensa_tls_referenced_p_1 (rtx *x, void *data ATTRIBUTE_UNUSED)
1899{
1900  if (GET_CODE (*x) == SYMBOL_REF)
1901    return SYMBOL_REF_TLS_MODEL (*x) != 0;
1902
1903  /* Ignore TLS references that have already been legitimized.  */
1904  if (GET_CODE (*x) == UNSPEC)
1905    {
1906      switch (XINT (*x, 1))
1907	{
1908	case UNSPEC_TPOFF:
1909	case UNSPEC_DTPOFF:
1910	case UNSPEC_TLS_FUNC:
1911	case UNSPEC_TLS_ARG:
1912	case UNSPEC_TLS_CALL:
1913	  return -1;
1914	default:
1915	  break;
1916	}
1917    }
1918
1919  return 0;
1920}
1921
1922
1923/* Return TRUE if X contains any TLS symbol references.  */
1924
1925bool
1926xtensa_tls_referenced_p (rtx x)
1927{
1928  if (! TARGET_HAVE_TLS)
1929    return false;
1930
1931  return for_each_rtx (&x, xtensa_tls_referenced_p_1, NULL);
1932}
1933
1934
1935/* Return the debugger register number to use for 'regno'.  */
1936
1937int
1938xtensa_dbx_register_number (int regno)
1939{
1940  int first = -1;
1941
1942  if (GP_REG_P (regno))
1943    {
1944      regno -= GP_REG_FIRST;
1945      first = 0;
1946    }
1947  else if (BR_REG_P (regno))
1948    {
1949      regno -= BR_REG_FIRST;
1950      first = 16;
1951    }
1952  else if (FP_REG_P (regno))
1953    {
1954      regno -= FP_REG_FIRST;
1955      first = 48;
1956    }
1957  else if (ACC_REG_P (regno))
1958    {
1959      first = 0x200;	/* Start of Xtensa special registers.  */
1960      regno = 16;	/* ACCLO is special register 16.  */
1961    }
1962
1963  /* When optimizing, we sometimes get asked about pseudo-registers
1964     that don't represent hard registers.  Return 0 for these.  */
1965  if (first == -1)
1966    return 0;
1967
1968  return first + regno;
1969}
1970
1971
1972/* Argument support functions.  */
1973
1974/* Initialize CUMULATIVE_ARGS for a function.  */
1975
1976void
1977init_cumulative_args (CUMULATIVE_ARGS *cum, int incoming)
1978{
1979  cum->arg_words = 0;
1980  cum->incoming = incoming;
1981}
1982
1983
1984/* Advance the argument to the next argument position.  */
1985
1986void
1987function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode, tree type)
1988{
1989  int words, max;
1990  int *arg_words;
1991
1992  arg_words = &cum->arg_words;
1993  max = MAX_ARGS_IN_REGISTERS;
1994
1995  words = (((mode != BLKmode)
1996	    ? (int) GET_MODE_SIZE (mode)
1997	    : int_size_in_bytes (type)) + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
1998
1999  if (*arg_words < max
2000      && (targetm.calls.must_pass_in_stack (mode, type)
2001	  || *arg_words + words > max))
2002    *arg_words = max;
2003
2004  *arg_words += words;
2005}
2006
2007
2008/* Return an RTL expression containing the register for the given mode,
2009   or 0 if the argument is to be passed on the stack.  INCOMING_P is nonzero
2010   if this is an incoming argument to the current function.  */
2011
2012rtx
2013function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode, tree type,
2014	      int incoming_p)
2015{
2016  int regbase, words, max;
2017  int *arg_words;
2018  int regno;
2019
2020  arg_words = &cum->arg_words;
2021  regbase = (incoming_p ? GP_ARG_FIRST : GP_OUTGOING_ARG_FIRST);
2022  max = MAX_ARGS_IN_REGISTERS;
2023
2024  words = (((mode != BLKmode)
2025	    ? (int) GET_MODE_SIZE (mode)
2026	    : int_size_in_bytes (type)) + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
2027
2028  if (type && (TYPE_ALIGN (type) > BITS_PER_WORD))
2029    {
2030      int align = MIN (TYPE_ALIGN (type), STACK_BOUNDARY) / BITS_PER_WORD;
2031      *arg_words = (*arg_words + align - 1) & -align;
2032    }
2033
2034  if (*arg_words + words > max)
2035    return (rtx)0;
2036
2037  regno = regbase + *arg_words;
2038
2039  if (cum->incoming && regno <= A7_REG && regno + words > A7_REG)
2040    cfun->machine->need_a7_copy = true;
2041
2042  return gen_rtx_REG (mode, regno);
2043}
2044
2045
2046int
2047function_arg_boundary (enum machine_mode mode, tree type)
2048{
2049  unsigned int alignment;
2050
2051  alignment = type ? TYPE_ALIGN (type) : GET_MODE_ALIGNMENT (mode);
2052  if (alignment < PARM_BOUNDARY)
2053    alignment = PARM_BOUNDARY;
2054  if (alignment > STACK_BOUNDARY)
2055    alignment = STACK_BOUNDARY;
2056  return alignment;
2057}
2058
2059
2060static bool
2061xtensa_return_in_msb (const_tree valtype)
2062{
2063  return (TARGET_BIG_ENDIAN
2064	  && AGGREGATE_TYPE_P (valtype)
2065	  && int_size_in_bytes (valtype) >= UNITS_PER_WORD);
2066}
2067
2068
2069void
2070override_options (void)
2071{
2072  int regno;
2073  enum machine_mode mode;
2074
2075  if (!TARGET_BOOLEANS && TARGET_HARD_FLOAT)
2076    error ("boolean registers required for the floating-point option");
2077
2078  /* Set up array giving whether a given register can hold a given mode.  */
2079  for (mode = VOIDmode;
2080       mode != MAX_MACHINE_MODE;
2081       mode = (enum machine_mode) ((int) mode + 1))
2082    {
2083      int size = GET_MODE_SIZE (mode);
2084      enum mode_class mclass = GET_MODE_CLASS (mode);
2085
2086      for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
2087	{
2088	  int temp;
2089
2090	  if (ACC_REG_P (regno))
2091	    temp = (TARGET_MAC16
2092		    && (mclass == MODE_INT) && (size <= UNITS_PER_WORD));
2093	  else if (GP_REG_P (regno))
2094	    temp = ((regno & 1) == 0 || (size <= UNITS_PER_WORD));
2095	  else if (FP_REG_P (regno))
2096	    temp = (TARGET_HARD_FLOAT && (mode == SFmode));
2097	  else if (BR_REG_P (regno))
2098	    temp = (TARGET_BOOLEANS && (mode == CCmode));
2099	  else
2100	    temp = FALSE;
2101
2102	  xtensa_hard_regno_mode_ok[(int) mode][regno] = temp;
2103	}
2104    }
2105
2106  init_machine_status = xtensa_init_machine_status;
2107
2108  /* Check PIC settings.  PIC is only supported when using L32R
2109     instructions, and some targets need to always use PIC.  */
2110  if (flag_pic && TARGET_CONST16)
2111    error ("-f%s is not supported with CONST16 instructions",
2112	   (flag_pic > 1 ? "PIC" : "pic"));
2113  else if (XTENSA_ALWAYS_PIC)
2114    {
2115      if (TARGET_CONST16)
2116	error ("PIC is required but not supported with CONST16 instructions");
2117      flag_pic = 1;
2118    }
2119  /* There's no need for -fPIC (as opposed to -fpic) on Xtensa.  */
2120  if (flag_pic > 1)
2121    flag_pic = 1;
2122  if (flag_pic && !flag_pie)
2123    flag_shlib = 1;
2124
2125  /* Hot/cold partitioning does not work on this architecture, because of
2126     constant pools (the load instruction cannot necessarily reach that far).
2127     Therefore disable it on this architecture.  */
2128  if (flag_reorder_blocks_and_partition)
2129    {
2130      flag_reorder_blocks_and_partition = 0;
2131      flag_reorder_blocks = 1;
2132    }
2133}
2134
2135
2136/* A C compound statement to output to stdio stream STREAM the
2137   assembler syntax for an instruction operand X.  X is an RTL
2138   expression.
2139
2140   CODE is a value that can be used to specify one of several ways
2141   of printing the operand.  It is used when identical operands
2142   must be printed differently depending on the context.  CODE
2143   comes from the '%' specification that was used to request
2144   printing of the operand.  If the specification was just '%DIGIT'
2145   then CODE is 0; if the specification was '%LTR DIGIT' then CODE
2146   is the ASCII code for LTR.
2147
2148   If X is a register, this macro should print the register's name.
2149   The names can be found in an array 'reg_names' whose type is
2150   'char *[]'.  'reg_names' is initialized from 'REGISTER_NAMES'.
2151
2152   When the machine description has a specification '%PUNCT' (a '%'
2153   followed by a punctuation character), this macro is called with
2154   a null pointer for X and the punctuation character for CODE.
2155
2156   'a', 'c', 'l', and 'n' are reserved.
2157
2158   The Xtensa specific codes are:
2159
2160   'd'  CONST_INT, print as signed decimal
2161   'x'  CONST_INT, print as signed hexadecimal
2162   'K'  CONST_INT, print number of bits in mask for EXTUI
2163   'R'  CONST_INT, print (X & 0x1f)
2164   'L'  CONST_INT, print ((32 - X) & 0x1f)
2165   'D'  REG, print second register of double-word register operand
2166   'N'  MEM, print address of next word following a memory operand
2167   'v'  MEM, if memory reference is volatile, output a MEMW before it
2168   't'  any constant, add "@h" suffix for top 16 bits
2169   'b'  any constant, add "@l" suffix for bottom 16 bits
2170*/
2171
2172static void
2173printx (FILE *file, signed int val)
2174{
2175  /* Print a hexadecimal value in a nice way.  */
2176  if ((val > -0xa) && (val < 0xa))
2177    fprintf (file, "%d", val);
2178  else if (val < 0)
2179    fprintf (file, "-0x%x", -val);
2180  else
2181    fprintf (file, "0x%x", val);
2182}
2183
2184
2185void
2186print_operand (FILE *file, rtx x, int letter)
2187{
2188  if (!x)
2189    error ("PRINT_OPERAND null pointer");
2190
2191  switch (letter)
2192    {
2193    case 'D':
2194      if (GET_CODE (x) == REG || GET_CODE (x) == SUBREG)
2195	fprintf (file, "%s", reg_names[xt_true_regnum (x) + 1]);
2196      else
2197	output_operand_lossage ("invalid %%D value");
2198      break;
2199
2200    case 'v':
2201      if (GET_CODE (x) == MEM)
2202	{
2203	  /* For a volatile memory reference, emit a MEMW before the
2204	     load or store.  */
2205	  if (MEM_VOLATILE_P (x) && TARGET_SERIALIZE_VOLATILE)
2206	    fprintf (file, "memw\n\t");
2207	}
2208      else
2209	output_operand_lossage ("invalid %%v value");
2210      break;
2211
2212    case 'N':
2213      if (GET_CODE (x) == MEM
2214	  && (GET_MODE (x) == DFmode || GET_MODE (x) == DImode))
2215	{
2216	  x = adjust_address (x, GET_MODE (x) == DFmode ? SFmode : SImode, 4);
2217	  output_address (XEXP (x, 0));
2218	}
2219      else
2220	output_operand_lossage ("invalid %%N value");
2221      break;
2222
2223    case 'K':
2224      if (GET_CODE (x) == CONST_INT)
2225	{
2226	  int num_bits = 0;
2227	  unsigned val = INTVAL (x);
2228	  while (val & 1)
2229	    {
2230	      num_bits += 1;
2231	      val = val >> 1;
2232	    }
2233	  if ((val != 0) || (num_bits == 0) || (num_bits > 16))
2234	    fatal_insn ("invalid mask", x);
2235
2236	  fprintf (file, "%d", num_bits);
2237	}
2238      else
2239	output_operand_lossage ("invalid %%K value");
2240      break;
2241
2242    case 'L':
2243      if (GET_CODE (x) == CONST_INT)
2244	fprintf (file, "%ld", (32 - INTVAL (x)) & 0x1f);
2245      else
2246	output_operand_lossage ("invalid %%L value");
2247      break;
2248
2249    case 'R':
2250      if (GET_CODE (x) == CONST_INT)
2251	fprintf (file, "%ld", INTVAL (x) & 0x1f);
2252      else
2253	output_operand_lossage ("invalid %%R value");
2254      break;
2255
2256    case 'x':
2257      if (GET_CODE (x) == CONST_INT)
2258	printx (file, INTVAL (x));
2259      else
2260	output_operand_lossage ("invalid %%x value");
2261      break;
2262
2263    case 'd':
2264      if (GET_CODE (x) == CONST_INT)
2265	fprintf (file, "%ld", INTVAL (x));
2266      else
2267	output_operand_lossage ("invalid %%d value");
2268      break;
2269
2270    case 't':
2271    case 'b':
2272      if (GET_CODE (x) == CONST_INT)
2273	{
2274	  printx (file, INTVAL (x));
2275	  fputs (letter == 't' ? "@h" : "@l", file);
2276	}
2277      else if (GET_CODE (x) == CONST_DOUBLE)
2278	{
2279	  REAL_VALUE_TYPE r;
2280	  REAL_VALUE_FROM_CONST_DOUBLE (r, x);
2281	  if (GET_MODE (x) == SFmode)
2282	    {
2283	      long l;
2284	      REAL_VALUE_TO_TARGET_SINGLE (r, l);
2285	      fprintf (file, "0x%08lx@%c", l, letter == 't' ? 'h' : 'l');
2286	    }
2287	  else
2288	    output_operand_lossage ("invalid %%t/%%b value");
2289	}
2290      else if (GET_CODE (x) == CONST)
2291	{
2292	  /* X must be a symbolic constant on ELF.  Write an expression
2293	     suitable for 'const16' that sets the high or low 16 bits.  */
2294	  if (GET_CODE (XEXP (x, 0)) != PLUS
2295	      || (GET_CODE (XEXP (XEXP (x, 0), 0)) != SYMBOL_REF
2296		  && GET_CODE (XEXP (XEXP (x, 0), 0)) != LABEL_REF)
2297	      || GET_CODE (XEXP (XEXP (x, 0), 1)) != CONST_INT)
2298	    output_operand_lossage ("invalid %%t/%%b value");
2299	  print_operand (file, XEXP (XEXP (x, 0), 0), 0);
2300	  fputs (letter == 't' ? "@h" : "@l", file);
2301	  /* There must be a non-alphanumeric character between 'h' or 'l'
2302	     and the number.  The '-' is added by print_operand() already.  */
2303	  if (INTVAL (XEXP (XEXP (x, 0), 1)) >= 0)
2304	    fputs ("+", file);
2305	  print_operand (file, XEXP (XEXP (x, 0), 1), 0);
2306	}
2307      else
2308	{
2309	  output_addr_const (file, x);
2310	  fputs (letter == 't' ? "@h" : "@l", file);
2311	}
2312      break;
2313
2314    default:
2315      if (GET_CODE (x) == REG || GET_CODE (x) == SUBREG)
2316	fprintf (file, "%s", reg_names[xt_true_regnum (x)]);
2317      else if (GET_CODE (x) == MEM)
2318	output_address (XEXP (x, 0));
2319      else if (GET_CODE (x) == CONST_INT)
2320	fprintf (file, "%ld", INTVAL (x));
2321      else
2322	output_addr_const (file, x);
2323    }
2324}
2325
2326
2327/* A C compound statement to output to stdio stream STREAM the
2328   assembler syntax for an instruction operand that is a memory
2329   reference whose address is ADDR.  ADDR is an RTL expression.  */
2330
2331void
2332print_operand_address (FILE *file, rtx addr)
2333{
2334  if (!addr)
2335    error ("PRINT_OPERAND_ADDRESS, null pointer");
2336
2337  switch (GET_CODE (addr))
2338    {
2339    default:
2340      fatal_insn ("invalid address", addr);
2341      break;
2342
2343    case REG:
2344      fprintf (file, "%s, 0", reg_names [REGNO (addr)]);
2345      break;
2346
2347    case PLUS:
2348      {
2349	rtx reg = (rtx)0;
2350	rtx offset = (rtx)0;
2351	rtx arg0 = XEXP (addr, 0);
2352	rtx arg1 = XEXP (addr, 1);
2353
2354	if (GET_CODE (arg0) == REG)
2355	  {
2356	    reg = arg0;
2357	    offset = arg1;
2358	  }
2359	else if (GET_CODE (arg1) == REG)
2360	  {
2361	    reg = arg1;
2362	    offset = arg0;
2363	  }
2364	else
2365	  fatal_insn ("no register in address", addr);
2366
2367	if (CONSTANT_P (offset))
2368	  {
2369	    fprintf (file, "%s, ", reg_names [REGNO (reg)]);
2370	    output_addr_const (file, offset);
2371	  }
2372	else
2373	  fatal_insn ("address offset not a constant", addr);
2374      }
2375      break;
2376
2377    case LABEL_REF:
2378    case SYMBOL_REF:
2379    case CONST_INT:
2380    case CONST:
2381      output_addr_const (file, addr);
2382      break;
2383    }
2384}
2385
2386
2387bool
2388xtensa_output_addr_const_extra (FILE *fp, rtx x)
2389{
2390  if (GET_CODE (x) == UNSPEC && XVECLEN (x, 0) == 1)
2391    {
2392      switch (XINT (x, 1))
2393	{
2394	case UNSPEC_TPOFF:
2395	  output_addr_const (fp, XVECEXP (x, 0, 0));
2396	  fputs ("@TPOFF", fp);
2397	  return true;
2398	case UNSPEC_DTPOFF:
2399	  output_addr_const (fp, XVECEXP (x, 0, 0));
2400	  fputs ("@DTPOFF", fp);
2401	  return true;
2402	case UNSPEC_PLT:
2403	  if (flag_pic)
2404	    {
2405	      output_addr_const (fp, XVECEXP (x, 0, 0));
2406	      fputs ("@PLT", fp);
2407	      return true;
2408	    }
2409	  break;
2410	default:
2411	  break;
2412	}
2413    }
2414  return false;
2415}
2416
2417
2418void
2419xtensa_output_literal (FILE *file, rtx x, enum machine_mode mode, int labelno)
2420{
2421  long value_long[2];
2422  REAL_VALUE_TYPE r;
2423  int size;
2424  rtx first, second;
2425
2426  fprintf (file, "\t.literal .LC%u, ", (unsigned) labelno);
2427
2428  switch (GET_MODE_CLASS (mode))
2429    {
2430    case MODE_FLOAT:
2431      gcc_assert (GET_CODE (x) == CONST_DOUBLE);
2432
2433      REAL_VALUE_FROM_CONST_DOUBLE (r, x);
2434      switch (mode)
2435	{
2436	case SFmode:
2437	  REAL_VALUE_TO_TARGET_SINGLE (r, value_long[0]);
2438	  if (HOST_BITS_PER_LONG > 32)
2439	    value_long[0] &= 0xffffffff;
2440	  fprintf (file, "0x%08lx\n", value_long[0]);
2441	  break;
2442
2443	case DFmode:
2444	  REAL_VALUE_TO_TARGET_DOUBLE (r, value_long);
2445	  if (HOST_BITS_PER_LONG > 32)
2446	    {
2447	      value_long[0] &= 0xffffffff;
2448	      value_long[1] &= 0xffffffff;
2449	    }
2450	  fprintf (file, "0x%08lx, 0x%08lx\n",
2451		   value_long[0], value_long[1]);
2452	  break;
2453
2454	default:
2455	  gcc_unreachable ();
2456	}
2457
2458      break;
2459
2460    case MODE_INT:
2461    case MODE_PARTIAL_INT:
2462      size = GET_MODE_SIZE (mode);
2463      switch (size)
2464	{
2465	case 4:
2466	  output_addr_const (file, x);
2467	  fputs ("\n", file);
2468	  break;
2469
2470	case 8:
2471	  split_double (x, &first, &second);
2472	  output_addr_const (file, first);
2473	  fputs (", ", file);
2474	  output_addr_const (file, second);
2475	  fputs ("\n", file);
2476	  break;
2477
2478	default:
2479	  gcc_unreachable ();
2480	}
2481      break;
2482
2483    default:
2484      gcc_unreachable ();
2485    }
2486}
2487
2488
2489/* Return the bytes needed to compute the frame pointer from the current
2490   stack pointer.  */
2491
2492#define STACK_BYTES (STACK_BOUNDARY / BITS_PER_UNIT)
2493#define XTENSA_STACK_ALIGN(LOC) (((LOC) + STACK_BYTES-1) & ~(STACK_BYTES-1))
2494
2495long
2496compute_frame_size (int size)
2497{
2498  /* Add space for the incoming static chain value.  */
2499  if (cfun->static_chain_decl != NULL)
2500    size += (1 * UNITS_PER_WORD);
2501
2502  xtensa_current_frame_size =
2503    XTENSA_STACK_ALIGN (size
2504			+ crtl->outgoing_args_size
2505			+ (WINDOW_SIZE * UNITS_PER_WORD));
2506  return xtensa_current_frame_size;
2507}
2508
2509
2510bool
2511xtensa_frame_pointer_required (void)
2512{
2513  /* The code to expand builtin_frame_addr and builtin_return_addr
2514     currently uses the hard_frame_pointer instead of frame_pointer.
2515     This seems wrong but maybe it's necessary for other architectures.
2516     This function is derived from the i386 code.  */
2517
2518  if (cfun->machine->accesses_prev_frame)
2519    return true;
2520
2521  return false;
2522}
2523
2524
2525/* minimum frame = reg save area (4 words) plus static chain (1 word)
2526   and the total number of words must be a multiple of 128 bits.  */
2527#define MIN_FRAME_SIZE (8 * UNITS_PER_WORD)
2528
2529void
2530xtensa_expand_prologue (void)
2531{
2532  HOST_WIDE_INT total_size;
2533  rtx size_rtx;
2534  rtx insn, note_rtx;
2535
2536  total_size = compute_frame_size (get_frame_size ());
2537  size_rtx = GEN_INT (total_size);
2538
2539  if (total_size < (1 << (12+3)))
2540    insn = emit_insn (gen_entry (size_rtx));
2541  else
2542    {
2543      /* Use a8 as a temporary since a0-a7 may be live.  */
2544      rtx tmp_reg = gen_rtx_REG (Pmode, A8_REG);
2545      emit_insn (gen_entry (GEN_INT (MIN_FRAME_SIZE)));
2546      emit_move_insn (tmp_reg, GEN_INT (total_size - MIN_FRAME_SIZE));
2547      emit_insn (gen_subsi3 (tmp_reg, stack_pointer_rtx, tmp_reg));
2548      insn = emit_insn (gen_movsi (stack_pointer_rtx, tmp_reg));
2549    }
2550
2551  if (frame_pointer_needed)
2552    {
2553      if (cfun->machine->set_frame_ptr_insn)
2554	{
2555	  rtx first;
2556
2557	  push_topmost_sequence ();
2558	  first = get_insns ();
2559	  pop_topmost_sequence ();
2560
2561	  /* For all instructions prior to set_frame_ptr_insn, replace
2562	     hard_frame_pointer references with stack_pointer.  */
2563	  for (insn = first;
2564	       insn != cfun->machine->set_frame_ptr_insn;
2565	       insn = NEXT_INSN (insn))
2566	    {
2567	      if (INSN_P (insn))
2568		{
2569		  PATTERN (insn) = replace_rtx (copy_rtx (PATTERN (insn)),
2570						hard_frame_pointer_rtx,
2571						stack_pointer_rtx);
2572		  df_insn_rescan (insn);
2573		}
2574	    }
2575	}
2576      else
2577	insn = emit_insn (gen_movsi (hard_frame_pointer_rtx,
2578				     stack_pointer_rtx));
2579    }
2580
2581  /* Create a note to describe the CFA.  Because this is only used to set
2582     DW_AT_frame_base for debug info, don't bother tracking changes through
2583     each instruction in the prologue.  It just takes up space.  */
2584  note_rtx = gen_rtx_SET (VOIDmode, (frame_pointer_needed
2585				     ? hard_frame_pointer_rtx
2586				     : stack_pointer_rtx),
2587			  plus_constant (stack_pointer_rtx, -total_size));
2588  RTX_FRAME_RELATED_P (insn) = 1;
2589  REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR,
2590					note_rtx, REG_NOTES (insn));
2591}
2592
2593
2594/* Clear variables at function end.  */
2595
2596void
2597xtensa_function_epilogue (FILE *file ATTRIBUTE_UNUSED,
2598			  HOST_WIDE_INT size ATTRIBUTE_UNUSED)
2599{
2600  xtensa_current_frame_size = 0;
2601}
2602
2603
2604rtx
2605xtensa_return_addr (int count, rtx frame)
2606{
2607  rtx result, retaddr, curaddr, label;
2608
2609  if (count == -1)
2610    retaddr = gen_rtx_REG (Pmode, A0_REG);
2611  else
2612    {
2613      rtx addr = plus_constant (frame, -4 * UNITS_PER_WORD);
2614      addr = memory_address (Pmode, addr);
2615      retaddr = gen_reg_rtx (Pmode);
2616      emit_move_insn (retaddr, gen_rtx_MEM (Pmode, addr));
2617    }
2618
2619  /* The 2 most-significant bits of the return address on Xtensa hold
2620     the register window size.  To get the real return address, these
2621     bits must be replaced with the high bits from some address in the
2622     code.  */
2623
2624  /* Get the 2 high bits of a local label in the code.  */
2625  curaddr = gen_reg_rtx (Pmode);
2626  label = gen_label_rtx ();
2627  emit_label (label);
2628  LABEL_PRESERVE_P (label) = 1;
2629  emit_move_insn (curaddr, gen_rtx_LABEL_REF (Pmode, label));
2630  emit_insn (gen_lshrsi3 (curaddr, curaddr, GEN_INT (30)));
2631  emit_insn (gen_ashlsi3 (curaddr, curaddr, GEN_INT (30)));
2632
2633  /* Clear the 2 high bits of the return address.  */
2634  result = gen_reg_rtx (Pmode);
2635  emit_insn (gen_ashlsi3 (result, retaddr, GEN_INT (2)));
2636  emit_insn (gen_lshrsi3 (result, result, GEN_INT (2)));
2637
2638  /* Combine them to get the result.  */
2639  emit_insn (gen_iorsi3 (result, result, curaddr));
2640  return result;
2641}
2642
2643
2644/* Create the va_list data type.
2645
2646   This structure is set up by __builtin_saveregs.  The __va_reg field
2647   points to a stack-allocated region holding the contents of the
2648   incoming argument registers.  The __va_ndx field is an index
2649   initialized to the position of the first unnamed (variable)
2650   argument.  This same index is also used to address the arguments
2651   passed in memory.  Thus, the __va_stk field is initialized to point
2652   to the position of the first argument in memory offset to account
2653   for the arguments passed in registers and to account for the size
2654   of the argument registers not being 16-byte aligned.  E.G., there
2655   are 6 argument registers of 4 bytes each, but we want the __va_ndx
2656   for the first stack argument to have the maximal alignment of 16
2657   bytes, so we offset the __va_stk address by 32 bytes so that
2658   __va_stk[32] references the first argument on the stack.  */
2659
2660static tree
2661xtensa_build_builtin_va_list (void)
2662{
2663  tree f_stk, f_reg, f_ndx, record, type_decl;
2664
2665  record = (*lang_hooks.types.make_type) (RECORD_TYPE);
2666  type_decl = build_decl (BUILTINS_LOCATION,
2667			  TYPE_DECL, get_identifier ("__va_list_tag"), record);
2668
2669  f_stk = build_decl (BUILTINS_LOCATION,
2670		      FIELD_DECL, get_identifier ("__va_stk"),
2671		      ptr_type_node);
2672  f_reg = build_decl (BUILTINS_LOCATION,
2673		      FIELD_DECL, get_identifier ("__va_reg"),
2674		      ptr_type_node);
2675  f_ndx = build_decl (BUILTINS_LOCATION,
2676		      FIELD_DECL, get_identifier ("__va_ndx"),
2677		      integer_type_node);
2678
2679  DECL_FIELD_CONTEXT (f_stk) = record;
2680  DECL_FIELD_CONTEXT (f_reg) = record;
2681  DECL_FIELD_CONTEXT (f_ndx) = record;
2682
2683  TREE_CHAIN (record) = type_decl;
2684  TYPE_NAME (record) = type_decl;
2685  TYPE_FIELDS (record) = f_stk;
2686  TREE_CHAIN (f_stk) = f_reg;
2687  TREE_CHAIN (f_reg) = f_ndx;
2688
2689  layout_type (record);
2690  return record;
2691}
2692
2693
2694/* Save the incoming argument registers on the stack.  Returns the
2695   address of the saved registers.  */
2696
2697static rtx
2698xtensa_builtin_saveregs (void)
2699{
2700  rtx gp_regs;
2701  int arg_words = crtl->args.info.arg_words;
2702  int gp_left = MAX_ARGS_IN_REGISTERS - arg_words;
2703
2704  if (gp_left <= 0)
2705    return const0_rtx;
2706
2707  /* Allocate the general-purpose register space.  */
2708  gp_regs = assign_stack_local
2709    (BLKmode, MAX_ARGS_IN_REGISTERS * UNITS_PER_WORD, -1);
2710  set_mem_alias_set (gp_regs, get_varargs_alias_set ());
2711
2712  /* Now store the incoming registers.  */
2713  cfun->machine->need_a7_copy = true;
2714  cfun->machine->vararg_a7 = true;
2715  move_block_from_reg (GP_ARG_FIRST + arg_words,
2716		       adjust_address (gp_regs, BLKmode,
2717				       arg_words * UNITS_PER_WORD),
2718		       gp_left);
2719  gcc_assert (cfun->machine->vararg_a7_copy != 0);
2720  emit_insn_before (cfun->machine->vararg_a7_copy, get_insns ());
2721
2722  return XEXP (gp_regs, 0);
2723}
2724
2725
2726/* Implement `va_start' for varargs and stdarg.  We look at the
2727   current function to fill in an initial va_list.  */
2728
2729static void
2730xtensa_va_start (tree valist, rtx nextarg ATTRIBUTE_UNUSED)
2731{
2732  tree f_stk, stk;
2733  tree f_reg, reg;
2734  tree f_ndx, ndx;
2735  tree t, u;
2736  int arg_words;
2737
2738  arg_words = crtl->args.info.arg_words;
2739
2740  f_stk = TYPE_FIELDS (va_list_type_node);
2741  f_reg = TREE_CHAIN (f_stk);
2742  f_ndx = TREE_CHAIN (f_reg);
2743
2744  stk = build3 (COMPONENT_REF, TREE_TYPE (f_stk), valist, f_stk, NULL_TREE);
2745  reg = build3 (COMPONENT_REF, TREE_TYPE (f_reg), unshare_expr (valist),
2746		f_reg, NULL_TREE);
2747  ndx = build3 (COMPONENT_REF, TREE_TYPE (f_ndx), unshare_expr (valist),
2748		f_ndx, NULL_TREE);
2749
2750  /* Call __builtin_saveregs; save the result in __va_reg */
2751  u = make_tree (sizetype, expand_builtin_saveregs ());
2752  u = fold_convert (ptr_type_node, u);
2753  t = build2 (MODIFY_EXPR, ptr_type_node, reg, u);
2754  TREE_SIDE_EFFECTS (t) = 1;
2755  expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
2756
2757  /* Set the __va_stk member to ($arg_ptr - 32).  */
2758  u = make_tree (ptr_type_node, virtual_incoming_args_rtx);
2759  u = fold_build2 (POINTER_PLUS_EXPR, ptr_type_node, u, size_int (-32));
2760  t = build2 (MODIFY_EXPR, ptr_type_node, stk, u);
2761  TREE_SIDE_EFFECTS (t) = 1;
2762  expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
2763
2764  /* Set the __va_ndx member.  If the first variable argument is on
2765     the stack, adjust __va_ndx by 2 words to account for the extra
2766     alignment offset for __va_stk.  */
2767  if (arg_words >= MAX_ARGS_IN_REGISTERS)
2768    arg_words += 2;
2769  t = build2 (MODIFY_EXPR, integer_type_node, ndx,
2770	      build_int_cst (integer_type_node, arg_words * UNITS_PER_WORD));
2771  TREE_SIDE_EFFECTS (t) = 1;
2772  expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
2773}
2774
2775
2776/* Implement `va_arg'.  */
2777
2778static tree
2779xtensa_gimplify_va_arg_expr (tree valist, tree type, gimple_seq *pre_p,
2780			     gimple_seq *post_p ATTRIBUTE_UNUSED)
2781{
2782  tree f_stk, stk;
2783  tree f_reg, reg;
2784  tree f_ndx, ndx;
2785  tree type_size, array, orig_ndx, addr, size, va_size, t;
2786  tree lab_false, lab_over, lab_false2;
2787  bool indirect;
2788
2789  indirect = pass_by_reference (NULL, TYPE_MODE (type), type, false);
2790  if (indirect)
2791    type = build_pointer_type (type);
2792
2793  /* Handle complex values as separate real and imaginary parts.  */
2794  if (TREE_CODE (type) == COMPLEX_TYPE)
2795    {
2796      tree real_part, imag_part;
2797
2798      real_part = xtensa_gimplify_va_arg_expr (valist, TREE_TYPE (type),
2799					       pre_p, NULL);
2800      real_part = get_initialized_tmp_var (real_part, pre_p, NULL);
2801
2802      imag_part = xtensa_gimplify_va_arg_expr (unshare_expr (valist),
2803					       TREE_TYPE (type),
2804					       pre_p, NULL);
2805      imag_part = get_initialized_tmp_var (imag_part, pre_p, NULL);
2806
2807      return build2 (COMPLEX_EXPR, type, real_part, imag_part);
2808    }
2809
2810  f_stk = TYPE_FIELDS (va_list_type_node);
2811  f_reg = TREE_CHAIN (f_stk);
2812  f_ndx = TREE_CHAIN (f_reg);
2813
2814  stk = build3 (COMPONENT_REF, TREE_TYPE (f_stk), valist,
2815		f_stk, NULL_TREE);
2816  reg = build3 (COMPONENT_REF, TREE_TYPE (f_reg), unshare_expr (valist),
2817		f_reg, NULL_TREE);
2818  ndx = build3 (COMPONENT_REF, TREE_TYPE (f_ndx), unshare_expr (valist),
2819		f_ndx, NULL_TREE);
2820
2821  type_size = size_in_bytes (type);
2822  va_size = round_up (type_size, UNITS_PER_WORD);
2823  gimplify_expr (&va_size, pre_p, NULL, is_gimple_val, fb_rvalue);
2824
2825
2826  /* First align __va_ndx if necessary for this arg:
2827
2828     orig_ndx = (AP).__va_ndx;
2829     if (__alignof__ (TYPE) > 4 )
2830       orig_ndx = ((orig_ndx + __alignof__ (TYPE) - 1)
2831			& -__alignof__ (TYPE)); */
2832
2833  orig_ndx = get_initialized_tmp_var (ndx, pre_p, NULL);
2834
2835  if (TYPE_ALIGN (type) > BITS_PER_WORD)
2836    {
2837      int align = MIN (TYPE_ALIGN (type), STACK_BOUNDARY) / BITS_PER_UNIT;
2838
2839      t = build2 (PLUS_EXPR, integer_type_node, unshare_expr (orig_ndx),
2840		  build_int_cst (integer_type_node, align - 1));
2841      t = build2 (BIT_AND_EXPR, integer_type_node, t,
2842		  build_int_cst (integer_type_node, -align));
2843      gimplify_assign (unshare_expr (orig_ndx), t, pre_p);
2844    }
2845
2846
2847  /* Increment __va_ndx to point past the argument:
2848
2849     (AP).__va_ndx = orig_ndx + __va_size (TYPE); */
2850
2851  t = fold_convert (integer_type_node, va_size);
2852  t = build2 (PLUS_EXPR, integer_type_node, orig_ndx, t);
2853  gimplify_assign (unshare_expr (ndx), t, pre_p);
2854
2855
2856  /* Check if the argument is in registers:
2857
2858     if ((AP).__va_ndx <= __MAX_ARGS_IN_REGISTERS * 4
2859         && !must_pass_in_stack (type))
2860        __array = (AP).__va_reg; */
2861
2862  array = create_tmp_var (ptr_type_node, NULL);
2863
2864  lab_over = NULL;
2865  if (!targetm.calls.must_pass_in_stack (TYPE_MODE (type), type))
2866    {
2867      lab_false = create_artificial_label (UNKNOWN_LOCATION);
2868      lab_over = create_artificial_label (UNKNOWN_LOCATION);
2869
2870      t = build2 (GT_EXPR, boolean_type_node, unshare_expr (ndx),
2871		  build_int_cst (integer_type_node,
2872				 MAX_ARGS_IN_REGISTERS * UNITS_PER_WORD));
2873      t = build3 (COND_EXPR, void_type_node, t,
2874		  build1 (GOTO_EXPR, void_type_node, lab_false),
2875		  NULL_TREE);
2876      gimplify_and_add (t, pre_p);
2877
2878      gimplify_assign (unshare_expr (array), reg, pre_p);
2879
2880      t = build1 (GOTO_EXPR, void_type_node, lab_over);
2881      gimplify_and_add (t, pre_p);
2882
2883      t = build1 (LABEL_EXPR, void_type_node, lab_false);
2884      gimplify_and_add (t, pre_p);
2885    }
2886
2887
2888  /* ...otherwise, the argument is on the stack (never split between
2889     registers and the stack -- change __va_ndx if necessary):
2890
2891     else
2892       {
2893	 if (orig_ndx <= __MAX_ARGS_IN_REGISTERS * 4)
2894	     (AP).__va_ndx = 32 + __va_size (TYPE);
2895	 __array = (AP).__va_stk;
2896       } */
2897
2898  lab_false2 = create_artificial_label (UNKNOWN_LOCATION);
2899
2900  t = build2 (GT_EXPR, boolean_type_node, unshare_expr (orig_ndx),
2901	      build_int_cst (integer_type_node,
2902			     MAX_ARGS_IN_REGISTERS * UNITS_PER_WORD));
2903  t = build3 (COND_EXPR, void_type_node, t,
2904	      build1 (GOTO_EXPR, void_type_node, lab_false2),
2905	      NULL_TREE);
2906  gimplify_and_add (t, pre_p);
2907
2908  t = size_binop (PLUS_EXPR, unshare_expr (va_size), size_int (32));
2909  t = fold_convert (integer_type_node, t);
2910  gimplify_assign (unshare_expr (ndx), t, pre_p);
2911
2912  t = build1 (LABEL_EXPR, void_type_node, lab_false2);
2913  gimplify_and_add (t, pre_p);
2914
2915  gimplify_assign (array, stk, pre_p);
2916
2917  if (lab_over)
2918    {
2919      t = build1 (LABEL_EXPR, void_type_node, lab_over);
2920      gimplify_and_add (t, pre_p);
2921    }
2922
2923
2924  /* Given the base array pointer (__array) and index to the subsequent
2925     argument (__va_ndx), find the address:
2926
2927     __array + (AP).__va_ndx - (BYTES_BIG_ENDIAN && sizeof (TYPE) < 4
2928				? sizeof (TYPE)
2929				: __va_size (TYPE))
2930
2931     The results are endian-dependent because values smaller than one word
2932     are aligned differently.  */
2933
2934
2935  if (BYTES_BIG_ENDIAN && TREE_CODE (type_size) == INTEGER_CST)
2936    {
2937      t = fold_build2 (GE_EXPR, boolean_type_node, unshare_expr (type_size),
2938		       size_int (PARM_BOUNDARY / BITS_PER_UNIT));
2939      t = fold_build3 (COND_EXPR, sizetype, t, unshare_expr (va_size),
2940		       unshare_expr (type_size));
2941      size = t;
2942    }
2943  else
2944    size = unshare_expr (va_size);
2945
2946  t = fold_convert (sizetype, unshare_expr (ndx));
2947  t = build2 (MINUS_EXPR, sizetype, t, size);
2948  addr = build2 (POINTER_PLUS_EXPR, ptr_type_node, unshare_expr (array), t);
2949
2950  addr = fold_convert (build_pointer_type (type), addr);
2951  if (indirect)
2952    addr = build_va_arg_indirect_ref (addr);
2953  return build_va_arg_indirect_ref (addr);
2954}
2955
2956
2957/* Builtins.  */
2958
2959enum xtensa_builtin
2960{
2961  XTENSA_BUILTIN_UMULSIDI3,
2962  XTENSA_BUILTIN_THREAD_POINTER,
2963  XTENSA_BUILTIN_SET_THREAD_POINTER,
2964  XTENSA_BUILTIN_max
2965};
2966
2967
2968static void
2969xtensa_init_builtins (void)
2970{
2971  tree ftype, decl;
2972
2973  ftype = build_function_type_list (unsigned_intDI_type_node,
2974				    unsigned_intSI_type_node,
2975				    unsigned_intSI_type_node, NULL_TREE);
2976
2977  decl = add_builtin_function ("__builtin_umulsidi3", ftype,
2978			       XTENSA_BUILTIN_UMULSIDI3, BUILT_IN_MD,
2979			       "__umulsidi3", NULL_TREE);
2980  TREE_NOTHROW (decl) = 1;
2981  TREE_READONLY (decl) = 1;
2982
2983  if (TARGET_THREADPTR)
2984    {
2985      ftype = build_function_type (ptr_type_node, void_list_node);
2986      decl = add_builtin_function ("__builtin_thread_pointer", ftype,
2987				   XTENSA_BUILTIN_THREAD_POINTER, BUILT_IN_MD,
2988				   NULL, NULL_TREE);
2989      TREE_READONLY (decl) = 1;
2990      TREE_NOTHROW (decl) = 1;
2991
2992      ftype = build_function_type_list (void_type_node, ptr_type_node,
2993					NULL_TREE);
2994      decl = add_builtin_function ("__builtin_set_thread_pointer", ftype,
2995				   XTENSA_BUILTIN_SET_THREAD_POINTER,
2996				   BUILT_IN_MD, NULL, NULL_TREE);
2997      TREE_NOTHROW (decl) = 1;
2998    }
2999}
3000
3001
3002static tree
3003xtensa_fold_builtin (tree fndecl, tree arglist, bool ignore ATTRIBUTE_UNUSED)
3004{
3005  unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
3006  tree arg0, arg1;
3007
3008  switch (fcode)
3009    {
3010    case XTENSA_BUILTIN_UMULSIDI3:
3011      arg0 = TREE_VALUE (arglist);
3012      arg1 = TREE_VALUE (TREE_CHAIN (arglist));
3013      if ((TREE_CODE (arg0) == INTEGER_CST && TREE_CODE (arg1) == INTEGER_CST)
3014	  || TARGET_MUL32_HIGH)
3015	return fold_build2 (MULT_EXPR, unsigned_intDI_type_node,
3016			    fold_convert (unsigned_intDI_type_node, arg0),
3017			    fold_convert (unsigned_intDI_type_node, arg1));
3018      break;
3019
3020    case XTENSA_BUILTIN_THREAD_POINTER:
3021    case XTENSA_BUILTIN_SET_THREAD_POINTER:
3022      break;
3023
3024    default:
3025      internal_error ("bad builtin code");
3026      break;
3027    }
3028
3029  return NULL;
3030}
3031
3032
3033static rtx
3034xtensa_expand_builtin (tree exp, rtx target,
3035		       rtx subtarget ATTRIBUTE_UNUSED,
3036		       enum machine_mode mode ATTRIBUTE_UNUSED,
3037		       int ignore)
3038{
3039  tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
3040  unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
3041  rtx arg;
3042
3043  switch (fcode)
3044    {
3045    case XTENSA_BUILTIN_UMULSIDI3:
3046      /* The umulsidi3 builtin is just a mechanism to avoid calling the real
3047	 __umulsidi3 function when the Xtensa configuration can directly
3048	 implement it.  If not, just call the function.  */
3049      return expand_call (exp, target, ignore);
3050
3051    case XTENSA_BUILTIN_THREAD_POINTER:
3052      if (!target || !register_operand (target, Pmode))
3053	target = gen_reg_rtx (Pmode);
3054      emit_insn (gen_load_tp (target));
3055      return target;
3056
3057    case XTENSA_BUILTIN_SET_THREAD_POINTER:
3058      arg = expand_normal (CALL_EXPR_ARG (exp, 0));
3059      if (!register_operand (arg, Pmode))
3060	arg = copy_to_mode_reg (Pmode, arg);
3061      emit_insn (gen_set_tp (arg));
3062      return const0_rtx;
3063
3064    default:
3065      internal_error ("bad builtin code");
3066    }
3067  return NULL_RTX;
3068}
3069
3070
3071enum reg_class
3072xtensa_preferred_reload_class (rtx x, enum reg_class rclass, int isoutput)
3073{
3074  if (!isoutput && CONSTANT_P (x) && GET_CODE (x) == CONST_DOUBLE)
3075    return NO_REGS;
3076
3077  /* Don't use the stack pointer or hard frame pointer for reloads!
3078     The hard frame pointer would normally be OK except that it may
3079     briefly hold an incoming argument in the prologue, and reload
3080     won't know that it is live because the hard frame pointer is
3081     treated specially.  */
3082
3083  if (rclass == AR_REGS || rclass == GR_REGS)
3084    return RL_REGS;
3085
3086  return rclass;
3087}
3088
3089
3090enum reg_class
3091xtensa_secondary_reload (bool in_p, rtx x, enum reg_class rclass,
3092			 enum machine_mode mode, secondary_reload_info *sri)
3093{
3094  int regno;
3095
3096  if (in_p && constantpool_mem_p (x))
3097    {
3098      if (rclass == FP_REGS)
3099	return RL_REGS;
3100
3101      if (mode == QImode)
3102	sri->icode = CODE_FOR_reloadqi_literal;
3103      else if (mode == HImode)
3104	sri->icode = CODE_FOR_reloadhi_literal;
3105    }
3106
3107  regno = xt_true_regnum (x);
3108  if (ACC_REG_P (regno))
3109    return ((rclass == GR_REGS || rclass == RL_REGS) ? NO_REGS : RL_REGS);
3110  if (rclass == ACC_REG)
3111    return (GP_REG_P (regno) ? NO_REGS : RL_REGS);
3112
3113  return NO_REGS;
3114}
3115
3116
3117void
3118order_regs_for_local_alloc (void)
3119{
3120  if (!leaf_function_p ())
3121    {
3122      memcpy (reg_alloc_order, reg_nonleaf_alloc_order,
3123	      FIRST_PSEUDO_REGISTER * sizeof (int));
3124    }
3125  else
3126    {
3127      int i, num_arg_regs;
3128      int nxt = 0;
3129
3130      /* Use the AR registers in increasing order (skipping a0 and a1)
3131	 but save the incoming argument registers for a last resort.  */
3132      num_arg_regs = crtl->args.info.arg_words;
3133      if (num_arg_regs > MAX_ARGS_IN_REGISTERS)
3134	num_arg_regs = MAX_ARGS_IN_REGISTERS;
3135      for (i = GP_ARG_FIRST; i < 16 - num_arg_regs; i++)
3136	reg_alloc_order[nxt++] = i + num_arg_regs;
3137      for (i = 0; i < num_arg_regs; i++)
3138	reg_alloc_order[nxt++] = GP_ARG_FIRST + i;
3139
3140      /* List the coprocessor registers in order.  */
3141      for (i = 0; i < BR_REG_NUM; i++)
3142	reg_alloc_order[nxt++] = BR_REG_FIRST + i;
3143
3144      /* List the FP registers in order for now.  */
3145      for (i = 0; i < 16; i++)
3146	reg_alloc_order[nxt++] = FP_REG_FIRST + i;
3147
3148      /* GCC requires that we list *all* the registers....  */
3149      reg_alloc_order[nxt++] = 0;	/* a0 = return address */
3150      reg_alloc_order[nxt++] = 1;	/* a1 = stack pointer */
3151      reg_alloc_order[nxt++] = 16;	/* pseudo frame pointer */
3152      reg_alloc_order[nxt++] = 17;	/* pseudo arg pointer */
3153
3154      reg_alloc_order[nxt++] = ACC_REG_FIRST;	/* MAC16 accumulator */
3155    }
3156}
3157
3158
3159/* Some Xtensa targets support multiple bss sections.  If the section
3160   name ends with ".bss", add SECTION_BSS to the flags.  */
3161
3162static unsigned int
3163xtensa_multibss_section_type_flags (tree decl, const char *name, int reloc)
3164{
3165  unsigned int flags = default_section_type_flags (decl, name, reloc);
3166  const char *suffix;
3167
3168  suffix = strrchr (name, '.');
3169  if (suffix && strcmp (suffix, ".bss") == 0)
3170    {
3171      if (!decl || (TREE_CODE (decl) == VAR_DECL
3172		    && DECL_INITIAL (decl) == NULL_TREE))
3173	flags |= SECTION_BSS;  /* @nobits */
3174      else
3175	warning (0, "only uninitialized variables can be placed in a "
3176		 ".bss section");
3177    }
3178
3179  return flags;
3180}
3181
3182
3183/* The literal pool stays with the function.  */
3184
3185static section *
3186xtensa_select_rtx_section (enum machine_mode mode ATTRIBUTE_UNUSED,
3187			   rtx x ATTRIBUTE_UNUSED,
3188			   unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED)
3189{
3190  return function_section (current_function_decl);
3191}
3192
3193
3194/* Compute a (partial) cost for rtx X.  Return true if the complete
3195   cost has been computed, and false if subexpressions should be
3196   scanned.  In either case, *TOTAL contains the cost result.  */
3197
3198static bool
3199xtensa_rtx_costs (rtx x, int code, int outer_code, int *total,
3200		  bool speed ATTRIBUTE_UNUSED)
3201{
3202  switch (code)
3203    {
3204    case CONST_INT:
3205      switch (outer_code)
3206	{
3207	case SET:
3208	  if (xtensa_simm12b (INTVAL (x)))
3209	    {
3210	      *total = 4;
3211	      return true;
3212	    }
3213	  break;
3214	case PLUS:
3215	  if (xtensa_simm8 (INTVAL (x))
3216	      || xtensa_simm8x256 (INTVAL (x)))
3217	    {
3218	      *total = 0;
3219	      return true;
3220	    }
3221	  break;
3222	case AND:
3223	  if (xtensa_mask_immediate (INTVAL (x)))
3224	    {
3225	      *total = 0;
3226	      return true;
3227	    }
3228	  break;
3229	case COMPARE:
3230	  if ((INTVAL (x) == 0) || xtensa_b4const (INTVAL (x)))
3231	    {
3232	      *total = 0;
3233	      return true;
3234	    }
3235	  break;
3236	case ASHIFT:
3237	case ASHIFTRT:
3238	case LSHIFTRT:
3239	case ROTATE:
3240	case ROTATERT:
3241	  /* No way to tell if X is the 2nd operand so be conservative.  */
3242	default: break;
3243	}
3244      if (xtensa_simm12b (INTVAL (x)))
3245	*total = 5;
3246      else if (TARGET_CONST16)
3247	*total = COSTS_N_INSNS (2);
3248      else
3249	*total = 6;
3250      return true;
3251
3252    case CONST:
3253    case LABEL_REF:
3254    case SYMBOL_REF:
3255      if (TARGET_CONST16)
3256	*total = COSTS_N_INSNS (2);
3257      else
3258	*total = 5;
3259      return true;
3260
3261    case CONST_DOUBLE:
3262      if (TARGET_CONST16)
3263	*total = COSTS_N_INSNS (4);
3264      else
3265	*total = 7;
3266      return true;
3267
3268    case MEM:
3269      {
3270	int num_words =
3271	  (GET_MODE_SIZE (GET_MODE (x)) > UNITS_PER_WORD) ?  2 : 1;
3272
3273	if (memory_address_p (GET_MODE (x), XEXP ((x), 0)))
3274	  *total = COSTS_N_INSNS (num_words);
3275	else
3276	  *total = COSTS_N_INSNS (2*num_words);
3277	return true;
3278      }
3279
3280    case FFS:
3281    case CTZ:
3282      *total = COSTS_N_INSNS (TARGET_NSA ? 5 : 50);
3283      return true;
3284
3285    case CLZ:
3286      *total = COSTS_N_INSNS (TARGET_NSA ? 1 : 50);
3287      return true;
3288
3289    case NOT:
3290      *total = COSTS_N_INSNS ((GET_MODE (x) == DImode) ? 3 : 2);
3291      return true;
3292
3293    case AND:
3294    case IOR:
3295    case XOR:
3296      if (GET_MODE (x) == DImode)
3297	*total = COSTS_N_INSNS (2);
3298      else
3299	*total = COSTS_N_INSNS (1);
3300      return true;
3301
3302    case ASHIFT:
3303    case ASHIFTRT:
3304    case LSHIFTRT:
3305      if (GET_MODE (x) == DImode)
3306	*total = COSTS_N_INSNS (50);
3307      else
3308	*total = COSTS_N_INSNS (1);
3309      return true;
3310
3311    case ABS:
3312      {
3313	enum machine_mode xmode = GET_MODE (x);
3314	if (xmode == SFmode)
3315	  *total = COSTS_N_INSNS (TARGET_HARD_FLOAT ? 1 : 50);
3316	else if (xmode == DFmode)
3317	  *total = COSTS_N_INSNS (50);
3318	else
3319	  *total = COSTS_N_INSNS (4);
3320	return true;
3321      }
3322
3323    case PLUS:
3324    case MINUS:
3325      {
3326	enum machine_mode xmode = GET_MODE (x);
3327	if (xmode == SFmode)
3328	  *total = COSTS_N_INSNS (TARGET_HARD_FLOAT ? 1 : 50);
3329	else if (xmode == DFmode || xmode == DImode)
3330	  *total = COSTS_N_INSNS (50);
3331	else
3332	  *total = COSTS_N_INSNS (1);
3333	return true;
3334      }
3335
3336    case NEG:
3337      *total = COSTS_N_INSNS ((GET_MODE (x) == DImode) ? 4 : 2);
3338      return true;
3339
3340    case MULT:
3341      {
3342	enum machine_mode xmode = GET_MODE (x);
3343	if (xmode == SFmode)
3344	  *total = COSTS_N_INSNS (TARGET_HARD_FLOAT ? 4 : 50);
3345	else if (xmode == DFmode)
3346	  *total = COSTS_N_INSNS (50);
3347	else if (xmode == DImode)
3348	  *total = COSTS_N_INSNS (TARGET_MUL32_HIGH ? 10 : 50);
3349	else if (TARGET_MUL32)
3350	  *total = COSTS_N_INSNS (4);
3351	else if (TARGET_MAC16)
3352	  *total = COSTS_N_INSNS (16);
3353	else if (TARGET_MUL16)
3354	  *total = COSTS_N_INSNS (12);
3355	else
3356	  *total = COSTS_N_INSNS (50);
3357	return true;
3358      }
3359
3360    case DIV:
3361    case MOD:
3362      {
3363	enum machine_mode xmode = GET_MODE (x);
3364	if (xmode == SFmode)
3365	  {
3366	    *total = COSTS_N_INSNS (TARGET_HARD_FLOAT_DIV ? 8 : 50);
3367	    return true;
3368	  }
3369	else if (xmode == DFmode)
3370	  {
3371	    *total = COSTS_N_INSNS (50);
3372	    return true;
3373	  }
3374      }
3375      /* Fall through.  */
3376
3377    case UDIV:
3378    case UMOD:
3379      {
3380	enum machine_mode xmode = GET_MODE (x);
3381	if (xmode == DImode)
3382	  *total = COSTS_N_INSNS (50);
3383	else if (TARGET_DIV32)
3384	  *total = COSTS_N_INSNS (32);
3385	else
3386	  *total = COSTS_N_INSNS (50);
3387	return true;
3388      }
3389
3390    case SQRT:
3391      if (GET_MODE (x) == SFmode)
3392	*total = COSTS_N_INSNS (TARGET_HARD_FLOAT_SQRT ? 8 : 50);
3393      else
3394	*total = COSTS_N_INSNS (50);
3395      return true;
3396
3397    case SMIN:
3398    case UMIN:
3399    case SMAX:
3400    case UMAX:
3401      *total = COSTS_N_INSNS (TARGET_MINMAX ? 1 : 50);
3402      return true;
3403
3404    case SIGN_EXTRACT:
3405    case SIGN_EXTEND:
3406      *total = COSTS_N_INSNS (TARGET_SEXT ? 1 : 2);
3407      return true;
3408
3409    case ZERO_EXTRACT:
3410    case ZERO_EXTEND:
3411      *total = COSTS_N_INSNS (1);
3412      return true;
3413
3414    default:
3415      return false;
3416    }
3417}
3418
3419/* Worker function for TARGET_RETURN_IN_MEMORY.  */
3420
3421static bool
3422xtensa_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED)
3423{
3424  return ((unsigned HOST_WIDE_INT) int_size_in_bytes (type)
3425	  > 4 * UNITS_PER_WORD);
3426}
3427
3428/* Worker function for TARGET_FUNCTION_VALUE.  */
3429
3430rtx
3431xtensa_function_value (const_tree valtype, const_tree func ATTRIBUTE_UNUSED,
3432                      bool outgoing)
3433{
3434  return gen_rtx_REG ((INTEGRAL_TYPE_P (valtype)
3435                      && TYPE_PRECISION (valtype) < BITS_PER_WORD)
3436                     ? SImode : TYPE_MODE (valtype),
3437                     outgoing ? GP_OUTGOING_RETURN : GP_RETURN);
3438}
3439
3440/* The static chain is passed in memory.  Provide rtx giving 'mem'
3441   expressions that denote where they are stored.  */
3442
3443static rtx
3444xtensa_static_chain (const_tree ARG_UNUSED (fndecl), bool incoming_p)
3445{
3446  rtx base = incoming_p ? arg_pointer_rtx : stack_pointer_rtx;
3447  return gen_frame_mem (Pmode, plus_constant (base, -5 * UNITS_PER_WORD));
3448}
3449
3450
3451/* TRAMPOLINE_TEMPLATE: For Xtensa, the trampoline must perform an ENTRY
3452   instruction with a minimal stack frame in order to get some free
3453   registers.  Once the actual call target is known, the proper stack frame
3454   size is extracted from the ENTRY instruction at the target and the
3455   current frame is adjusted to match.  The trampoline then transfers
3456   control to the instruction following the ENTRY at the target.  Note:
3457   this assumes that the target begins with an ENTRY instruction.  */
3458
3459static void
3460xtensa_asm_trampoline_template (FILE *stream)
3461{
3462  bool use_call0 = (TARGET_CONST16 || TARGET_ABSOLUTE_LITERALS);
3463
3464  fprintf (stream, "\t.begin no-transform\n");
3465  fprintf (stream, "\tentry\tsp, %d\n", MIN_FRAME_SIZE);
3466
3467  if (use_call0)
3468    {
3469      /* Save the return address.  */
3470      fprintf (stream, "\tmov\ta10, a0\n");
3471
3472      /* Use a CALL0 instruction to skip past the constants and in the
3473	 process get the PC into A0.  This allows PC-relative access to
3474	 the constants without relying on L32R.  */
3475      fprintf (stream, "\tcall0\t.Lskipconsts\n");
3476    }
3477  else
3478    fprintf (stream, "\tj\t.Lskipconsts\n");
3479
3480  fprintf (stream, "\t.align\t4\n");
3481  fprintf (stream, ".Lchainval:%s0\n", integer_asm_op (4, TRUE));
3482  fprintf (stream, ".Lfnaddr:%s0\n", integer_asm_op (4, TRUE));
3483  fprintf (stream, ".Lskipconsts:\n");
3484
3485  /* Load the static chain and function address from the trampoline.  */
3486  if (use_call0)
3487    {
3488      fprintf (stream, "\taddi\ta0, a0, 3\n");
3489      fprintf (stream, "\tl32i\ta9, a0, 0\n");
3490      fprintf (stream, "\tl32i\ta8, a0, 4\n");
3491    }
3492  else
3493    {
3494      fprintf (stream, "\tl32r\ta9, .Lchainval\n");
3495      fprintf (stream, "\tl32r\ta8, .Lfnaddr\n");
3496    }
3497
3498  /* Store the static chain.  */
3499  fprintf (stream, "\ts32i\ta9, sp, %d\n", MIN_FRAME_SIZE - 20);
3500
3501  /* Set the proper stack pointer value.  */
3502  fprintf (stream, "\tl32i\ta9, a8, 0\n");
3503  fprintf (stream, "\textui\ta9, a9, %d, 12\n",
3504	   TARGET_BIG_ENDIAN ? 8 : 12);
3505  fprintf (stream, "\tslli\ta9, a9, 3\n");
3506  fprintf (stream, "\taddi\ta9, a9, %d\n", -MIN_FRAME_SIZE);
3507  fprintf (stream, "\tsub\ta9, sp, a9\n");
3508  fprintf (stream, "\tmovsp\tsp, a9\n");
3509
3510  if (use_call0)
3511    /* Restore the return address.  */
3512    fprintf (stream, "\tmov\ta0, a10\n");
3513
3514  /* Jump to the instruction following the ENTRY.  */
3515  fprintf (stream, "\taddi\ta8, a8, 3\n");
3516  fprintf (stream, "\tjx\ta8\n");
3517
3518  /* Pad size to a multiple of TRAMPOLINE_ALIGNMENT.  */
3519  if (use_call0)
3520    fprintf (stream, "\t.byte\t0\n");
3521  else
3522    fprintf (stream, "\tnop\n");
3523
3524  fprintf (stream, "\t.end no-transform\n");
3525}
3526
3527static void
3528xtensa_trampoline_init (rtx m_tramp, tree fndecl, rtx chain)
3529{
3530  rtx func = XEXP (DECL_RTL (fndecl), 0);
3531  bool use_call0 = (TARGET_CONST16 || TARGET_ABSOLUTE_LITERALS);
3532  int chain_off = use_call0 ? 12 : 8;
3533  int func_off = use_call0 ? 16 : 12;
3534
3535  emit_block_move (m_tramp, assemble_trampoline_template (),
3536		   GEN_INT (TRAMPOLINE_SIZE), BLOCK_OP_NORMAL);
3537
3538  emit_move_insn (adjust_address (m_tramp, SImode, chain_off), chain);
3539  emit_move_insn (adjust_address (m_tramp, SImode, func_off), func);
3540  emit_library_call (gen_rtx_SYMBOL_REF (Pmode, "__xtensa_sync_caches"),
3541		     0, VOIDmode, 1, XEXP (m_tramp, 0), Pmode);
3542}
3543
3544
3545#include "gt-xtensa.h"
3546