OSDN Git Service

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