OSDN Git Service

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