1 /* Subroutines for insn-output.c for Tensilica's Xtensa architecture.
2 Copyright 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
3 Free Software Foundation, Inc.
4 Contributed by Bob Wilson (bwilson@tensilica.com) at Tensilica.
6 This file is part of GCC.
8 GCC is free software; you can redistribute it and/or modify it under
9 the terms of the GNU General Public License as published by the Free
10 Software Foundation; either version 3, or (at your option) any later
13 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
14 WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
18 You should have received a copy of the GNU General Public License
19 along with GCC; see the file COPYING3. If not see
20 <http://www.gnu.org/licenses/>. */
24 #include "coretypes.h"
28 #include "hard-reg-set.h"
29 #include "basic-block.h"
30 #include "insn-config.h"
31 #include "conditions.h"
32 #include "insn-flags.h"
33 #include "insn-attr.h"
34 #include "insn-codes.h"
43 #include "diagnostic-core.h"
49 #include "target-def.h"
50 #include "langhooks.h"
55 /* Enumeration for all of the relational tests, so that we can build
56 arrays indexed by the test type, and not worry about the order
74 /* Array giving truth value on whether or not a given hard register
75 can support a given mode. */
76 char xtensa_hard_regno_mode_ok[(int) MAX_MACHINE_MODE][FIRST_PSEUDO_REGISTER];
78 /* Current frame size calculated by compute_frame_size. */
79 unsigned xtensa_current_frame_size;
81 /* Largest block move to handle in-line. */
82 #define LARGEST_MOVE_RATIO 15
84 /* Define the structure for the machine field in struct function. */
85 struct GTY(()) machine_function
87 int accesses_prev_frame;
91 rtx set_frame_ptr_insn;
94 /* Vector, indexed by hard register number, which contains 1 for a
95 register that is allowable in a candidate for leaf function
98 const char xtensa_leaf_regs[FIRST_PSEUDO_REGISTER] =
100 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
102 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
106 /* Map hard register number to register class */
107 const enum reg_class xtensa_regno_to_class[FIRST_PSEUDO_REGISTER] =
109 RL_REGS, SP_REG, RL_REGS, RL_REGS,
110 RL_REGS, RL_REGS, RL_REGS, GR_REGS,
111 RL_REGS, RL_REGS, RL_REGS, RL_REGS,
112 RL_REGS, RL_REGS, RL_REGS, RL_REGS,
113 AR_REGS, AR_REGS, BR_REGS,
114 FP_REGS, FP_REGS, FP_REGS, FP_REGS,
115 FP_REGS, FP_REGS, FP_REGS, FP_REGS,
116 FP_REGS, FP_REGS, FP_REGS, FP_REGS,
117 FP_REGS, FP_REGS, FP_REGS, FP_REGS,
121 static void xtensa_option_override (void);
122 static enum internal_test map_test_to_internal_test (enum rtx_code);
123 static rtx gen_int_relational (enum rtx_code, rtx, rtx, int *);
124 static rtx gen_float_relational (enum rtx_code, rtx, rtx);
125 static rtx gen_conditional_move (enum rtx_code, enum machine_mode, rtx, rtx);
126 static rtx fixup_subreg_mem (rtx);
127 static struct machine_function * xtensa_init_machine_status (void);
128 static rtx xtensa_legitimize_tls_address (rtx);
129 static rtx xtensa_legitimize_address (rtx, rtx, enum machine_mode);
130 static bool xtensa_return_in_msb (const_tree);
131 static void printx (FILE *, signed int);
132 static void xtensa_function_epilogue (FILE *, HOST_WIDE_INT);
133 static rtx xtensa_builtin_saveregs (void);
134 static bool xtensa_legitimate_address_p (enum machine_mode, rtx, bool);
135 static unsigned int xtensa_multibss_section_type_flags (tree, const char *,
136 int) ATTRIBUTE_UNUSED;
137 static section *xtensa_select_rtx_section (enum machine_mode, rtx,
138 unsigned HOST_WIDE_INT);
139 static bool xtensa_rtx_costs (rtx, int, int, int *, bool);
140 static tree xtensa_build_builtin_va_list (void);
141 static bool xtensa_return_in_memory (const_tree, const_tree);
142 static tree xtensa_gimplify_va_arg_expr (tree, tree, gimple_seq *,
144 static void xtensa_function_arg_advance (CUMULATIVE_ARGS *, enum machine_mode,
146 static rtx xtensa_function_arg (CUMULATIVE_ARGS *, enum machine_mode,
148 static rtx xtensa_function_incoming_arg (CUMULATIVE_ARGS *,
149 enum machine_mode, const_tree, bool);
150 static rtx xtensa_function_value (const_tree, const_tree, bool);
151 static void xtensa_init_builtins (void);
152 static tree xtensa_fold_builtin (tree, int, tree *, bool);
153 static rtx xtensa_expand_builtin (tree, rtx, rtx, enum machine_mode, int);
154 static void xtensa_va_start (tree, rtx);
155 static bool xtensa_frame_pointer_required (void);
156 static rtx xtensa_static_chain (const_tree, bool);
157 static void xtensa_asm_trampoline_template (FILE *);
158 static void xtensa_trampoline_init (rtx, tree, rtx);
160 static const int reg_nonleaf_alloc_order[FIRST_PSEUDO_REGISTER] =
164 /* This macro generates the assembly code for function exit,
165 on machines that need it. If FUNCTION_EPILOGUE is not defined
166 then individual return instructions are generated for each
167 return statement. Args are same as for FUNCTION_PROLOGUE. */
169 #undef TARGET_ASM_FUNCTION_EPILOGUE
170 #define TARGET_ASM_FUNCTION_EPILOGUE xtensa_function_epilogue
172 /* These hooks specify assembly directives for creating certain kinds
173 of integer object. */
175 #undef TARGET_ASM_ALIGNED_SI_OP
176 #define TARGET_ASM_ALIGNED_SI_OP "\t.word\t"
178 #undef TARGET_ASM_SELECT_RTX_SECTION
179 #define TARGET_ASM_SELECT_RTX_SECTION xtensa_select_rtx_section
181 #undef TARGET_DEFAULT_TARGET_FLAGS
182 #define TARGET_DEFAULT_TARGET_FLAGS (TARGET_DEFAULT | MASK_FUSED_MADD)
184 #undef TARGET_LEGITIMIZE_ADDRESS
185 #define TARGET_LEGITIMIZE_ADDRESS xtensa_legitimize_address
187 #undef TARGET_RTX_COSTS
188 #define TARGET_RTX_COSTS xtensa_rtx_costs
189 #undef TARGET_ADDRESS_COST
190 #define TARGET_ADDRESS_COST hook_int_rtx_bool_0
192 #undef TARGET_BUILD_BUILTIN_VA_LIST
193 #define TARGET_BUILD_BUILTIN_VA_LIST xtensa_build_builtin_va_list
195 #undef TARGET_EXPAND_BUILTIN_VA_START
196 #define TARGET_EXPAND_BUILTIN_VA_START xtensa_va_start
198 #undef TARGET_PROMOTE_FUNCTION_MODE
199 #define TARGET_PROMOTE_FUNCTION_MODE default_promote_function_mode_always_promote
200 #undef TARGET_PROMOTE_PROTOTYPES
201 #define TARGET_PROMOTE_PROTOTYPES hook_bool_const_tree_true
203 #undef TARGET_RETURN_IN_MEMORY
204 #define TARGET_RETURN_IN_MEMORY xtensa_return_in_memory
205 #undef TARGET_FUNCTION_VALUE
206 #define TARGET_FUNCTION_VALUE xtensa_function_value
207 #undef TARGET_SPLIT_COMPLEX_ARG
208 #define TARGET_SPLIT_COMPLEX_ARG hook_bool_const_tree_true
209 #undef TARGET_MUST_PASS_IN_STACK
210 #define TARGET_MUST_PASS_IN_STACK must_pass_in_stack_var_size
211 #undef TARGET_FUNCTION_ARG_ADVANCE
212 #define TARGET_FUNCTION_ARG_ADVANCE xtensa_function_arg_advance
213 #undef TARGET_FUNCTION_ARG
214 #define TARGET_FUNCTION_ARG xtensa_function_arg
215 #undef TARGET_FUNCTION_INCOMING_ARG
216 #define TARGET_FUNCTION_INCOMING_ARG xtensa_function_incoming_arg
218 #undef TARGET_EXPAND_BUILTIN_SAVEREGS
219 #define TARGET_EXPAND_BUILTIN_SAVEREGS xtensa_builtin_saveregs
220 #undef TARGET_GIMPLIFY_VA_ARG_EXPR
221 #define TARGET_GIMPLIFY_VA_ARG_EXPR xtensa_gimplify_va_arg_expr
223 #undef TARGET_RETURN_IN_MSB
224 #define TARGET_RETURN_IN_MSB xtensa_return_in_msb
226 #undef TARGET_INIT_BUILTINS
227 #define TARGET_INIT_BUILTINS xtensa_init_builtins
228 #undef TARGET_FOLD_BUILTIN
229 #define TARGET_FOLD_BUILTIN xtensa_fold_builtin
230 #undef TARGET_EXPAND_BUILTIN
231 #define TARGET_EXPAND_BUILTIN xtensa_expand_builtin
233 #undef TARGET_SECONDARY_RELOAD
234 #define TARGET_SECONDARY_RELOAD xtensa_secondary_reload
236 #undef TARGET_HAVE_TLS
237 #define TARGET_HAVE_TLS (TARGET_THREADPTR && HAVE_AS_TLS)
239 #undef TARGET_CANNOT_FORCE_CONST_MEM
240 #define TARGET_CANNOT_FORCE_CONST_MEM xtensa_tls_referenced_p
242 #undef TARGET_LEGITIMATE_ADDRESS_P
243 #define TARGET_LEGITIMATE_ADDRESS_P xtensa_legitimate_address_p
245 #undef TARGET_FRAME_POINTER_REQUIRED
246 #define TARGET_FRAME_POINTER_REQUIRED xtensa_frame_pointer_required
248 #undef TARGET_STATIC_CHAIN
249 #define TARGET_STATIC_CHAIN xtensa_static_chain
250 #undef TARGET_ASM_TRAMPOLINE_TEMPLATE
251 #define TARGET_ASM_TRAMPOLINE_TEMPLATE xtensa_asm_trampoline_template
252 #undef TARGET_TRAMPOLINE_INIT
253 #define TARGET_TRAMPOLINE_INIT xtensa_trampoline_init
255 #undef TARGET_OPTION_OVERRIDE
256 #define TARGET_OPTION_OVERRIDE xtensa_option_override
258 struct gcc_target targetm = TARGET_INITIALIZER;
261 /* Functions to test Xtensa immediate operand validity. */
264 xtensa_simm8 (HOST_WIDE_INT v)
266 return v >= -128 && v <= 127;
271 xtensa_simm8x256 (HOST_WIDE_INT v)
273 return (v & 255) == 0 && (v >= -32768 && v <= 32512);
278 xtensa_simm12b (HOST_WIDE_INT v)
280 return v >= -2048 && v <= 2047;
285 xtensa_uimm8 (HOST_WIDE_INT v)
287 return v >= 0 && v <= 255;
292 xtensa_uimm8x2 (HOST_WIDE_INT v)
294 return (v & 1) == 0 && (v >= 0 && v <= 510);
299 xtensa_uimm8x4 (HOST_WIDE_INT v)
301 return (v & 3) == 0 && (v >= 0 && v <= 1020);
306 xtensa_b4const (HOST_WIDE_INT v)
333 xtensa_b4const_or_zero (HOST_WIDE_INT v)
337 return xtensa_b4const (v);
342 xtensa_b4constu (HOST_WIDE_INT v)
369 xtensa_mask_immediate (HOST_WIDE_INT v)
371 #define MAX_MASK_SIZE 16
374 for (mask_size = 1; mask_size <= MAX_MASK_SIZE; mask_size++)
387 /* This is just like the standard true_regnum() function except that it
388 works even when reg_renumber is not initialized. */
391 xt_true_regnum (rtx x)
393 if (GET_CODE (x) == REG)
396 && REGNO (x) >= FIRST_PSEUDO_REGISTER
397 && reg_renumber[REGNO (x)] >= 0)
398 return reg_renumber[REGNO (x)];
401 if (GET_CODE (x) == SUBREG)
403 int base = xt_true_regnum (SUBREG_REG (x));
404 if (base >= 0 && base < FIRST_PSEUDO_REGISTER)
405 return base + subreg_regno_offset (REGNO (SUBREG_REG (x)),
406 GET_MODE (SUBREG_REG (x)),
407 SUBREG_BYTE (x), GET_MODE (x));
414 xtensa_valid_move (enum machine_mode mode, rtx *operands)
416 /* Either the destination or source must be a register, and the
417 MAC16 accumulator doesn't count. */
419 if (register_operand (operands[0], mode))
421 int dst_regnum = xt_true_regnum (operands[0]);
423 /* The stack pointer can only be assigned with a MOVSP opcode. */
424 if (dst_regnum == STACK_POINTER_REGNUM)
425 return (mode == SImode
426 && register_operand (operands[1], mode)
427 && !ACC_REG_P (xt_true_regnum (operands[1])));
429 if (!ACC_REG_P (dst_regnum))
432 if (register_operand (operands[1], mode))
434 int src_regnum = xt_true_regnum (operands[1]);
435 if (!ACC_REG_P (src_regnum))
443 smalloffset_mem_p (rtx op)
445 if (GET_CODE (op) == MEM)
447 rtx addr = XEXP (op, 0);
448 if (GET_CODE (addr) == REG)
449 return BASE_REG_P (addr, 0);
450 if (GET_CODE (addr) == PLUS)
452 rtx offset = XEXP (addr, 0);
454 if (GET_CODE (offset) != CONST_INT)
455 offset = XEXP (addr, 1);
456 if (GET_CODE (offset) != CONST_INT)
459 val = INTVAL (offset);
460 return (val & 3) == 0 && (val >= 0 && val <= 60);
468 constantpool_address_p (rtx addr)
472 if (GET_CODE (addr) == CONST)
476 /* Only handle (PLUS (SYM, OFFSET)) form. */
477 addr = XEXP (addr, 0);
478 if (GET_CODE (addr) != PLUS)
481 /* Make sure the address is word aligned. */
482 offset = XEXP (addr, 1);
483 if ((GET_CODE (offset) != CONST_INT)
484 || ((INTVAL (offset) & 3) != 0))
487 sym = XEXP (addr, 0);
490 if ((GET_CODE (sym) == SYMBOL_REF)
491 && CONSTANT_POOL_ADDRESS_P (sym))
498 constantpool_mem_p (rtx op)
500 if (GET_CODE (op) == SUBREG)
501 op = SUBREG_REG (op);
502 if (GET_CODE (op) == MEM)
503 return constantpool_address_p (XEXP (op, 0));
508 /* Return TRUE if X is a thread-local symbol. */
511 xtensa_tls_symbol_p (rtx x)
513 if (! TARGET_HAVE_TLS)
516 return GET_CODE (x) == SYMBOL_REF && SYMBOL_REF_TLS_MODEL (x) != 0;
521 xtensa_extend_reg (rtx dst, rtx src)
523 rtx temp = gen_reg_rtx (SImode);
524 rtx shift = GEN_INT (BITS_PER_WORD - GET_MODE_BITSIZE (GET_MODE (src)));
526 /* Generate paradoxical subregs as needed so that the modes match. */
527 src = simplify_gen_subreg (SImode, src, GET_MODE (src), 0);
528 dst = simplify_gen_subreg (SImode, dst, GET_MODE (dst), 0);
530 emit_insn (gen_ashlsi3 (temp, src, shift));
531 emit_insn (gen_ashrsi3 (dst, temp, shift));
536 xtensa_mem_offset (unsigned v, enum machine_mode mode)
541 /* Handle the worst case for block moves. See xtensa_expand_block_move
542 where we emit an optimized block move operation if the block can be
543 moved in < "move_ratio" pieces. The worst case is when the block is
544 aligned but has a size of (3 mod 4) (does this happen?) so that the
545 last piece requires a byte load/store. */
546 return (xtensa_uimm8 (v)
547 && xtensa_uimm8 (v + MOVE_MAX * LARGEST_MOVE_RATIO));
550 return xtensa_uimm8 (v);
553 return xtensa_uimm8x2 (v);
556 return (xtensa_uimm8x4 (v) && xtensa_uimm8x4 (v + 4));
562 return xtensa_uimm8x4 (v);
566 /* Make normal rtx_code into something we can index from an array. */
568 static enum internal_test
569 map_test_to_internal_test (enum rtx_code test_code)
571 enum internal_test test = ITEST_MAX;
576 case EQ: test = ITEST_EQ; break;
577 case NE: test = ITEST_NE; break;
578 case GT: test = ITEST_GT; break;
579 case GE: test = ITEST_GE; break;
580 case LT: test = ITEST_LT; break;
581 case LE: test = ITEST_LE; break;
582 case GTU: test = ITEST_GTU; break;
583 case GEU: test = ITEST_GEU; break;
584 case LTU: test = ITEST_LTU; break;
585 case LEU: test = ITEST_LEU; break;
592 /* Generate the code to compare two integer values. The return value is
593 the comparison expression. */
596 gen_int_relational (enum rtx_code test_code, /* relational test (EQ, etc) */
597 rtx cmp0, /* first operand to compare */
598 rtx cmp1, /* second operand to compare */
599 int *p_invert /* whether branch needs to reverse test */)
603 enum rtx_code test_code; /* test code to use in insn */
604 bool (*const_range_p) (HOST_WIDE_INT); /* range check function */
605 int const_add; /* constant to add (convert LE -> LT) */
606 int reverse_regs; /* reverse registers in test */
607 int invert_const; /* != 0 if invert value if cmp1 is constant */
608 int invert_reg; /* != 0 if invert value if cmp1 is register */
609 int unsignedp; /* != 0 for unsigned comparisons. */
612 static struct cmp_info info[ (int)ITEST_MAX ] = {
614 { EQ, xtensa_b4const_or_zero, 0, 0, 0, 0, 0 }, /* EQ */
615 { NE, xtensa_b4const_or_zero, 0, 0, 0, 0, 0 }, /* NE */
617 { LT, xtensa_b4const_or_zero, 1, 1, 1, 0, 0 }, /* GT */
618 { GE, xtensa_b4const_or_zero, 0, 0, 0, 0, 0 }, /* GE */
619 { LT, xtensa_b4const_or_zero, 0, 0, 0, 0, 0 }, /* LT */
620 { GE, xtensa_b4const_or_zero, 1, 1, 1, 0, 0 }, /* LE */
622 { LTU, xtensa_b4constu, 1, 1, 1, 0, 1 }, /* GTU */
623 { GEU, xtensa_b4constu, 0, 0, 0, 0, 1 }, /* GEU */
624 { LTU, xtensa_b4constu, 0, 0, 0, 0, 1 }, /* LTU */
625 { GEU, xtensa_b4constu, 1, 1, 1, 0, 1 }, /* LEU */
628 enum internal_test test;
629 enum machine_mode mode;
630 struct cmp_info *p_info;
632 test = map_test_to_internal_test (test_code);
633 gcc_assert (test != ITEST_MAX);
635 p_info = &info[ (int)test ];
637 mode = GET_MODE (cmp0);
638 if (mode == VOIDmode)
639 mode = GET_MODE (cmp1);
641 /* Make sure we can handle any constants given to us. */
642 if (GET_CODE (cmp1) == CONST_INT)
644 HOST_WIDE_INT value = INTVAL (cmp1);
645 unsigned HOST_WIDE_INT uvalue = (unsigned HOST_WIDE_INT)value;
647 /* if the immediate overflows or does not fit in the immediate field,
648 spill it to a register */
650 if ((p_info->unsignedp ?
651 (uvalue + p_info->const_add > uvalue) :
652 (value + p_info->const_add > value)) != (p_info->const_add > 0))
654 cmp1 = force_reg (mode, cmp1);
656 else if (!(p_info->const_range_p) (value + p_info->const_add))
658 cmp1 = force_reg (mode, cmp1);
661 else if ((GET_CODE (cmp1) != REG) && (GET_CODE (cmp1) != SUBREG))
663 cmp1 = force_reg (mode, cmp1);
666 /* See if we need to invert the result. */
667 *p_invert = ((GET_CODE (cmp1) == CONST_INT)
668 ? p_info->invert_const
669 : p_info->invert_reg);
671 /* Comparison to constants, may involve adding 1 to change a LT into LE.
672 Comparison between two registers, may involve switching operands. */
673 if (GET_CODE (cmp1) == CONST_INT)
675 if (p_info->const_add != 0)
676 cmp1 = GEN_INT (INTVAL (cmp1) + p_info->const_add);
679 else if (p_info->reverse_regs)
686 return gen_rtx_fmt_ee (p_info->test_code, VOIDmode, cmp0, cmp1);
690 /* Generate the code to compare two float values. The return value is
691 the comparison expression. */
694 gen_float_relational (enum rtx_code test_code, /* relational test (EQ, etc) */
695 rtx cmp0, /* first operand to compare */
696 rtx cmp1 /* second operand to compare */)
698 rtx (*gen_fn) (rtx, rtx, rtx);
700 int reverse_regs, invert;
704 case EQ: reverse_regs = 0; invert = 0; gen_fn = gen_seq_sf; break;
705 case NE: reverse_regs = 0; invert = 1; gen_fn = gen_seq_sf; break;
706 case LE: reverse_regs = 0; invert = 0; gen_fn = gen_sle_sf; break;
707 case GT: reverse_regs = 1; invert = 0; gen_fn = gen_slt_sf; break;
708 case LT: reverse_regs = 0; invert = 0; gen_fn = gen_slt_sf; break;
709 case GE: reverse_regs = 1; invert = 0; gen_fn = gen_sle_sf; break;
710 case UNEQ: reverse_regs = 0; invert = 0; gen_fn = gen_suneq_sf; break;
711 case LTGT: reverse_regs = 0; invert = 1; gen_fn = gen_suneq_sf; break;
712 case UNLE: reverse_regs = 0; invert = 0; gen_fn = gen_sunle_sf; break;
713 case UNGT: reverse_regs = 1; invert = 0; gen_fn = gen_sunlt_sf; break;
714 case UNLT: reverse_regs = 0; invert = 0; gen_fn = gen_sunlt_sf; break;
715 case UNGE: reverse_regs = 1; invert = 0; gen_fn = gen_sunle_sf; break;
717 reverse_regs = 0; invert = 0; gen_fn = gen_sunordered_sf; break;
719 reverse_regs = 0; invert = 1; gen_fn = gen_sunordered_sf; break;
721 fatal_insn ("bad test", gen_rtx_fmt_ee (test_code, VOIDmode, cmp0, cmp1));
722 reverse_regs = 0; invert = 0; gen_fn = 0; /* avoid compiler warnings */
732 brtmp = gen_rtx_REG (CCmode, FPCC_REGNUM);
733 emit_insn (gen_fn (brtmp, cmp0, cmp1));
735 return gen_rtx_fmt_ee (invert ? EQ : NE, VOIDmode, brtmp, const0_rtx);
740 xtensa_expand_conditional_branch (rtx *operands, enum machine_mode mode)
742 enum rtx_code test_code = GET_CODE (operands[0]);
743 rtx cmp0 = operands[1];
744 rtx cmp1 = operands[2];
753 fatal_insn ("bad test", gen_rtx_fmt_ee (test_code, VOIDmode, cmp0, cmp1));
757 cmp = gen_int_relational (test_code, cmp0, cmp1, &invert);
761 if (!TARGET_HARD_FLOAT)
762 fatal_insn ("bad test", gen_rtx_fmt_ee (test_code, VOIDmode,
765 cmp = gen_float_relational (test_code, cmp0, cmp1);
769 /* Generate the branch. */
771 label1 = gen_rtx_LABEL_REF (VOIDmode, operands[3]);
780 emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
781 gen_rtx_IF_THEN_ELSE (VOIDmode, cmp,
788 gen_conditional_move (enum rtx_code code, enum machine_mode mode,
795 /* Jump optimization calls get_condition() which canonicalizes
796 comparisons like (GE x <const>) to (GT x <const-1>).
797 Transform those comparisons back to GE, since that is the
798 comparison supported in Xtensa. We shouldn't have to
799 transform <LE x const> comparisons, because neither
800 xtensa_expand_conditional_branch() nor get_condition() will
803 if ((code == GT) && (op1 == constm1_rtx))
808 cmp = gen_rtx_fmt_ee (code, VOIDmode, cc0_rtx, const0_rtx);
810 if (boolean_operator (cmp, VOIDmode))
812 /* Swap the operands to make const0 second. */
813 if (op0 == const0_rtx)
819 /* If not comparing against zero, emit a comparison (subtract). */
820 if (op1 != const0_rtx)
822 op0 = expand_binop (SImode, sub_optab, op0, op1,
823 0, 0, OPTAB_LIB_WIDEN);
827 else if (branch_operator (cmp, VOIDmode))
829 /* Swap the operands to make const0 second. */
830 if (op0 == const0_rtx)
837 case LT: code = GE; break;
838 case GE: code = LT; break;
839 default: gcc_unreachable ();
843 if (op1 != const0_rtx)
849 return gen_rtx_fmt_ee (code, VOIDmode, op0, op1);
852 if (TARGET_HARD_FLOAT && mode == SFmode)
853 return gen_float_relational (code, op0, op1);
860 xtensa_expand_conditional_move (rtx *operands, int isflt)
862 rtx dest = operands[0];
863 rtx cmp = operands[1];
864 enum machine_mode cmp_mode = GET_MODE (XEXP (cmp, 0));
865 rtx (*gen_fn) (rtx, rtx, rtx, rtx, rtx);
867 if (!(cmp = gen_conditional_move (GET_CODE (cmp), cmp_mode,
868 XEXP (cmp, 0), XEXP (cmp, 1))))
872 gen_fn = (cmp_mode == SImode
873 ? gen_movsfcc_internal0
874 : gen_movsfcc_internal1);
876 gen_fn = (cmp_mode == SImode
877 ? gen_movsicc_internal0
878 : gen_movsicc_internal1);
880 emit_insn (gen_fn (dest, XEXP (cmp, 0), operands[2], operands[3], cmp));
886 xtensa_expand_scc (rtx operands[4], enum machine_mode cmp_mode)
888 rtx dest = operands[0];
890 rtx one_tmp, zero_tmp;
891 rtx (*gen_fn) (rtx, rtx, rtx, rtx, rtx);
893 if (!(cmp = gen_conditional_move (GET_CODE (operands[1]), cmp_mode,
894 operands[2], operands[3])))
897 one_tmp = gen_reg_rtx (SImode);
898 zero_tmp = gen_reg_rtx (SImode);
899 emit_insn (gen_movsi (one_tmp, const_true_rtx));
900 emit_insn (gen_movsi (zero_tmp, const0_rtx));
902 gen_fn = (cmp_mode == SImode
903 ? gen_movsicc_internal0
904 : gen_movsicc_internal1);
905 emit_insn (gen_fn (dest, XEXP (cmp, 0), one_tmp, zero_tmp, cmp));
910 /* Split OP[1] into OP[2,3] and likewise for OP[0] into OP[0,1]. MODE is
911 for the output, i.e., the input operands are twice as big as MODE. */
914 xtensa_split_operand_pair (rtx operands[4], enum machine_mode mode)
916 switch (GET_CODE (operands[1]))
919 operands[3] = gen_rtx_REG (mode, REGNO (operands[1]) + 1);
920 operands[2] = gen_rtx_REG (mode, REGNO (operands[1]));
924 operands[3] = adjust_address (operands[1], mode, GET_MODE_SIZE (mode));
925 operands[2] = adjust_address (operands[1], mode, 0);
930 split_double (operands[1], &operands[2], &operands[3]);
937 switch (GET_CODE (operands[0]))
940 operands[1] = gen_rtx_REG (mode, REGNO (operands[0]) + 1);
941 operands[0] = gen_rtx_REG (mode, REGNO (operands[0]));
945 operands[1] = adjust_address (operands[0], mode, GET_MODE_SIZE (mode));
946 operands[0] = adjust_address (operands[0], mode, 0);
955 /* Emit insns to move operands[1] into operands[0].
956 Return 1 if we have written out everything that needs to be done to
957 do the move. Otherwise, return 0 and the caller will emit the move
961 xtensa_emit_move_sequence (rtx *operands, enum machine_mode mode)
963 rtx src = operands[1];
966 && (GET_CODE (src) != CONST_INT || ! xtensa_simm12b (INTVAL (src))))
968 rtx dst = operands[0];
970 if (xtensa_tls_referenced_p (src))
974 if (GET_CODE (src) == CONST && GET_CODE (XEXP (src, 0)) == PLUS)
976 addend = XEXP (XEXP (src, 0), 1);
977 src = XEXP (XEXP (src, 0), 0);
980 src = xtensa_legitimize_tls_address (src);
983 src = gen_rtx_PLUS (mode, src, addend);
984 src = force_operand (src, dst);
986 emit_move_insn (dst, src);
990 if (! TARGET_CONST16)
992 src = force_const_mem (SImode, src);
996 /* PC-relative loads are always SImode, and CONST16 is only
997 supported in the movsi pattern, so add a SUBREG for any other
1002 if (register_operand (dst, mode))
1004 emit_move_insn (simplify_gen_subreg (SImode, dst, mode, 0), src);
1009 src = force_reg (SImode, src);
1010 src = gen_lowpart_SUBREG (mode, src);
1016 if (!(reload_in_progress | reload_completed)
1017 && !xtensa_valid_move (mode, operands))
1018 operands[1] = force_reg (mode, operands[1]);
1020 operands[1] = xtensa_copy_incoming_a7 (operands[1]);
1022 /* During reload we don't want to emit (subreg:X (mem:Y)) since that
1023 instruction won't be recognized after reload, so we remove the
1024 subreg and adjust mem accordingly. */
1025 if (reload_in_progress)
1027 operands[0] = fixup_subreg_mem (operands[0]);
1028 operands[1] = fixup_subreg_mem (operands[1]);
1035 fixup_subreg_mem (rtx x)
1037 if (GET_CODE (x) == SUBREG
1038 && GET_CODE (SUBREG_REG (x)) == REG
1039 && REGNO (SUBREG_REG (x)) >= FIRST_PSEUDO_REGISTER)
1042 gen_rtx_SUBREG (GET_MODE (x),
1043 reg_equiv_mem [REGNO (SUBREG_REG (x))],
1045 x = alter_subreg (&temp);
1051 /* Check if an incoming argument in a7 is expected to be used soon and
1052 if OPND is a register or register pair that includes a7. If so,
1053 create a new pseudo and copy a7 into that pseudo at the very
1054 beginning of the function, followed by the special "set_frame_ptr"
1055 unspec_volatile insn. The return value is either the original
1056 operand, if it is not a7, or the new pseudo containing a copy of
1057 the incoming argument. This is necessary because the register
1058 allocator will ignore conflicts with a7 and may either assign some
1059 other pseudo to a7 or use a7 as the hard_frame_pointer, clobbering
1060 the incoming argument in a7. By copying the argument out of a7 as
1061 the very first thing, and then immediately following that with an
1062 unspec_volatile to keep the scheduler away, we should avoid any
1063 problems. Putting the set_frame_ptr insn at the beginning, with
1064 only the a7 copy before it, also makes it easier for the prologue
1065 expander to initialize the frame pointer after the a7 copy and to
1066 fix up the a7 copy to use the stack pointer instead of the frame
1070 xtensa_copy_incoming_a7 (rtx opnd)
1072 rtx entry_insns = 0;
1074 enum machine_mode mode;
1076 if (!cfun->machine->need_a7_copy)
1079 /* This function should never be called again once a7 has been copied. */
1080 gcc_assert (!cfun->machine->set_frame_ptr_insn);
1082 mode = GET_MODE (opnd);
1084 /* The operand using a7 may come in a later instruction, so just return
1085 the original operand if it doesn't use a7. */
1087 if (GET_CODE (reg) == SUBREG)
1089 gcc_assert (SUBREG_BYTE (reg) == 0);
1090 reg = SUBREG_REG (reg);
1092 if (GET_CODE (reg) != REG
1093 || REGNO (reg) > A7_REG
1094 || REGNO (reg) + HARD_REGNO_NREGS (A7_REG, mode) <= A7_REG)
1097 /* 1-word args will always be in a7; 2-word args in a6/a7. */
1098 gcc_assert (REGNO (reg) + HARD_REGNO_NREGS (A7_REG, mode) - 1 == A7_REG);
1100 cfun->machine->need_a7_copy = false;
1102 /* Copy a7 to a new pseudo at the function entry. Use gen_raw_REG to
1103 create the REG for a7 so that hard_frame_pointer_rtx is not used. */
1106 tmp = gen_reg_rtx (mode);
1112 /* Copy the value out of A7 here but keep the first word in A6 until
1113 after the set_frame_ptr insn. Otherwise, the register allocator
1114 may decide to put "subreg (tmp, 0)" in A7 and clobber the incoming
1116 emit_insn (gen_movsi_internal (gen_rtx_SUBREG (SImode, tmp, 4),
1117 gen_raw_REG (SImode, A7_REG)));
1120 emit_insn (gen_movsf_internal (tmp, gen_raw_REG (mode, A7_REG)));
1123 emit_insn (gen_movsi_internal (tmp, gen_raw_REG (mode, A7_REG)));
1126 emit_insn (gen_movhi_internal (tmp, gen_raw_REG (mode, A7_REG)));
1129 emit_insn (gen_movqi_internal (tmp, gen_raw_REG (mode, A7_REG)));
1135 cfun->machine->set_frame_ptr_insn = emit_insn (gen_set_frame_ptr ());
1137 /* For DF and DI mode arguments, copy the incoming value in A6 now. */
1138 if (mode == DFmode || mode == DImode)
1139 emit_insn (gen_movsi_internal (gen_rtx_SUBREG (SImode, tmp, 0),
1140 gen_rtx_REG (SImode, A7_REG - 1)));
1141 entry_insns = get_insns ();
1144 if (cfun->machine->vararg_a7)
1146 /* This is called from within builtin_saveregs, which will insert the
1147 saveregs code at the function entry, ahead of anything placed at
1148 the function entry now. Instead, save the sequence to be inserted
1149 at the beginning of the saveregs code. */
1150 cfun->machine->vararg_a7_copy = entry_insns;
1154 /* Put entry_insns after the NOTE that starts the function. If
1155 this is inside a start_sequence, make the outer-level insn
1156 chain current, so the code is placed at the start of the
1158 push_topmost_sequence ();
1159 /* Do not use entry_of_function() here. This is called from within
1160 expand_function_start, when the CFG still holds GIMPLE. */
1161 emit_insn_after (entry_insns, get_insns ());
1162 pop_topmost_sequence ();
1169 /* Try to expand a block move operation to a sequence of RTL move
1170 instructions. If not optimizing, or if the block size is not a
1171 constant, or if the block is too large, the expansion fails and GCC
1172 falls back to calling memcpy().
1174 operands[0] is the destination
1175 operands[1] is the source
1176 operands[2] is the length
1177 operands[3] is the alignment */
1180 xtensa_expand_block_move (rtx *operands)
1182 static const enum machine_mode mode_from_align[] =
1184 VOIDmode, QImode, HImode, VOIDmode, SImode,
1187 rtx dst_mem = operands[0];
1188 rtx src_mem = operands[1];
1189 HOST_WIDE_INT bytes, align;
1190 int num_pieces, move_ratio;
1192 enum machine_mode mode[2];
1201 /* If this is not a fixed size move, just call memcpy. */
1202 if (!optimize || (GET_CODE (operands[2]) != CONST_INT))
1205 bytes = INTVAL (operands[2]);
1206 align = INTVAL (operands[3]);
1208 /* Anything to move? */
1212 if (align > MOVE_MAX)
1215 /* Decide whether to expand inline based on the optimization level. */
1218 move_ratio = LARGEST_MOVE_RATIO;
1219 num_pieces = (bytes / align) + (bytes % align); /* Close enough anyway. */
1220 if (num_pieces > move_ratio)
1223 x = XEXP (dst_mem, 0);
1226 x = force_reg (Pmode, x);
1227 dst_mem = replace_equiv_address (dst_mem, x);
1230 x = XEXP (src_mem, 0);
1233 x = force_reg (Pmode, x);
1234 src_mem = replace_equiv_address (src_mem, x);
1237 active[0] = active[1] = false;
1248 next_amount = (bytes >= 4 ? 4 : (bytes >= 2 ? 2 : 1));
1249 next_amount = MIN (next_amount, align);
1251 amount[next] = next_amount;
1252 mode[next] = mode_from_align[next_amount];
1253 temp[next] = gen_reg_rtx (mode[next]);
1255 x = adjust_address (src_mem, mode[next], offset_ld);
1256 emit_insn (gen_rtx_SET (VOIDmode, temp[next], x));
1258 offset_ld += next_amount;
1259 bytes -= next_amount;
1260 active[next] = true;
1265 active[phase] = false;
1267 x = adjust_address (dst_mem, mode[phase], offset_st);
1268 emit_insn (gen_rtx_SET (VOIDmode, x, temp[phase]));
1270 offset_st += amount[phase];
1273 while (active[next]);
1280 xtensa_expand_nonlocal_goto (rtx *operands)
1282 rtx goto_handler = operands[1];
1283 rtx containing_fp = operands[3];
1285 /* Generate a call to "__xtensa_nonlocal_goto" (in libgcc); the code
1286 is too big to generate in-line. */
1288 if (GET_CODE (containing_fp) != REG)
1289 containing_fp = force_reg (Pmode, containing_fp);
1291 emit_library_call (gen_rtx_SYMBOL_REF (Pmode, "__xtensa_nonlocal_goto"),
1293 containing_fp, Pmode,
1294 goto_handler, Pmode);
1298 static struct machine_function *
1299 xtensa_init_machine_status (void)
1301 return ggc_alloc_cleared_machine_function ();
1305 /* Shift VAL of mode MODE left by COUNT bits. */
1308 xtensa_expand_mask_and_shift (rtx val, enum machine_mode mode, rtx count)
1310 val = expand_simple_binop (SImode, AND, val, GEN_INT (GET_MODE_MASK (mode)),
1311 NULL_RTX, 1, OPTAB_DIRECT);
1312 return expand_simple_binop (SImode, ASHIFT, val, count,
1313 NULL_RTX, 1, OPTAB_DIRECT);
1317 /* Structure to hold the initial parameters for a compare_and_swap operation
1318 in HImode and QImode. */
1320 struct alignment_context
1322 rtx memsi; /* SI aligned memory location. */
1323 rtx shift; /* Bit offset with regard to lsb. */
1324 rtx modemask; /* Mask of the HQImode shifted by SHIFT bits. */
1325 rtx modemaski; /* ~modemask */
1329 /* Initialize structure AC for word access to HI and QI mode memory. */
1332 init_alignment_context (struct alignment_context *ac, rtx mem)
1334 enum machine_mode mode = GET_MODE (mem);
1335 rtx byteoffset = NULL_RTX;
1336 bool aligned = (MEM_ALIGN (mem) >= GET_MODE_BITSIZE (SImode));
1339 ac->memsi = adjust_address (mem, SImode, 0); /* Memory is aligned. */
1342 /* Alignment is unknown. */
1345 /* Force the address into a register. */
1346 addr = force_reg (Pmode, XEXP (mem, 0));
1348 /* Align it to SImode. */
1349 align = expand_simple_binop (Pmode, AND, addr,
1350 GEN_INT (-GET_MODE_SIZE (SImode)),
1351 NULL_RTX, 1, OPTAB_DIRECT);
1353 ac->memsi = gen_rtx_MEM (SImode, align);
1354 MEM_VOLATILE_P (ac->memsi) = MEM_VOLATILE_P (mem);
1355 set_mem_alias_set (ac->memsi, ALIAS_SET_MEMORY_BARRIER);
1356 set_mem_align (ac->memsi, GET_MODE_BITSIZE (SImode));
1358 byteoffset = expand_simple_binop (Pmode, AND, addr,
1359 GEN_INT (GET_MODE_SIZE (SImode) - 1),
1360 NULL_RTX, 1, OPTAB_DIRECT);
1363 /* Calculate shiftcount. */
1364 if (TARGET_BIG_ENDIAN)
1366 ac->shift = GEN_INT (GET_MODE_SIZE (SImode) - GET_MODE_SIZE (mode));
1368 ac->shift = expand_simple_binop (SImode, MINUS, ac->shift, byteoffset,
1369 NULL_RTX, 1, OPTAB_DIRECT);
1374 ac->shift = NULL_RTX;
1376 ac->shift = byteoffset;
1379 if (ac->shift != NULL_RTX)
1381 /* Shift is the byte count, but we need the bitcount. */
1382 ac->shift = expand_simple_binop (SImode, MULT, ac->shift,
1383 GEN_INT (BITS_PER_UNIT),
1384 NULL_RTX, 1, OPTAB_DIRECT);
1385 ac->modemask = expand_simple_binop (SImode, ASHIFT,
1386 GEN_INT (GET_MODE_MASK (mode)),
1388 NULL_RTX, 1, OPTAB_DIRECT);
1391 ac->modemask = GEN_INT (GET_MODE_MASK (mode));
1393 ac->modemaski = expand_simple_unop (SImode, NOT, ac->modemask, NULL_RTX, 1);
1397 /* Expand an atomic compare and swap operation for HImode and QImode.
1398 MEM is the memory location, CMP the old value to compare MEM with
1399 and NEW_RTX the value to set if CMP == MEM. */
1402 xtensa_expand_compare_and_swap (rtx target, rtx mem, rtx cmp, rtx new_rtx)
1404 enum machine_mode mode = GET_MODE (mem);
1405 struct alignment_context ac;
1406 rtx tmp, cmpv, newv, val;
1407 rtx oldval = gen_reg_rtx (SImode);
1408 rtx res = gen_reg_rtx (SImode);
1409 rtx csloop = gen_label_rtx ();
1410 rtx csend = gen_label_rtx ();
1412 init_alignment_context (&ac, mem);
1414 if (ac.shift != NULL_RTX)
1416 cmp = xtensa_expand_mask_and_shift (cmp, mode, ac.shift);
1417 new_rtx = xtensa_expand_mask_and_shift (new_rtx, mode, ac.shift);
1420 /* Load the surrounding word into VAL with the MEM value masked out. */
1421 val = force_reg (SImode, expand_simple_binop (SImode, AND, ac.memsi,
1422 ac.modemaski, NULL_RTX, 1,
1424 emit_label (csloop);
1426 /* Patch CMP and NEW_RTX into VAL at correct position. */
1427 cmpv = force_reg (SImode, expand_simple_binop (SImode, IOR, cmp, val,
1428 NULL_RTX, 1, OPTAB_DIRECT));
1429 newv = force_reg (SImode, expand_simple_binop (SImode, IOR, new_rtx, val,
1430 NULL_RTX, 1, OPTAB_DIRECT));
1432 /* Jump to end if we're done. */
1433 emit_insn (gen_sync_compare_and_swapsi (res, ac.memsi, cmpv, newv));
1434 emit_cmp_and_jump_insns (res, cmpv, EQ, const0_rtx, SImode, true, csend);
1436 /* Check for changes outside mode. */
1437 emit_move_insn (oldval, val);
1438 tmp = expand_simple_binop (SImode, AND, res, ac.modemaski,
1439 val, 1, OPTAB_DIRECT);
1441 emit_move_insn (val, tmp);
1443 /* Loop internal if so. */
1444 emit_cmp_and_jump_insns (oldval, val, NE, const0_rtx, SImode, true, csloop);
1448 /* Return the correct part of the bitfield. */
1449 convert_move (target,
1450 (ac.shift == NULL_RTX ? res
1451 : expand_simple_binop (SImode, LSHIFTRT, res, ac.shift,
1452 NULL_RTX, 1, OPTAB_DIRECT)),
1457 /* Expand an atomic operation CODE of mode MODE (either HImode or QImode --
1458 the default expansion works fine for SImode). MEM is the memory location
1459 and VAL the value to play with. If AFTER is true then store the value
1460 MEM holds after the operation, if AFTER is false then store the value MEM
1461 holds before the operation. If TARGET is zero then discard that value, else
1462 store it to TARGET. */
1465 xtensa_expand_atomic (enum rtx_code code, rtx target, rtx mem, rtx val,
1468 enum machine_mode mode = GET_MODE (mem);
1469 struct alignment_context ac;
1470 rtx csloop = gen_label_rtx ();
1472 rtx old = gen_reg_rtx (SImode);
1473 rtx new_rtx = gen_reg_rtx (SImode);
1474 rtx orig = NULL_RTX;
1476 init_alignment_context (&ac, mem);
1478 /* Prepare values before the compare-and-swap loop. */
1479 if (ac.shift != NULL_RTX)
1480 val = xtensa_expand_mask_and_shift (val, mode, ac.shift);
1485 orig = gen_reg_rtx (SImode);
1486 convert_move (orig, val, 1);
1494 case MULT: /* NAND */
1496 /* val = "11..1<val>11..1" */
1497 val = expand_simple_binop (SImode, XOR, val, ac.modemaski,
1498 NULL_RTX, 1, OPTAB_DIRECT);
1505 /* Load full word. Subsequent loads are performed by S32C1I. */
1506 cmp = force_reg (SImode, ac.memsi);
1508 emit_label (csloop);
1509 emit_move_insn (old, cmp);
1515 val = expand_simple_binop (SImode, code, old, orig,
1516 NULL_RTX, 1, OPTAB_DIRECT);
1517 val = expand_simple_binop (SImode, AND, val, ac.modemask,
1518 NULL_RTX, 1, OPTAB_DIRECT);
1521 tmp = expand_simple_binop (SImode, AND, old, ac.modemaski,
1522 NULL_RTX, 1, OPTAB_DIRECT);
1523 tmp = expand_simple_binop (SImode, IOR, tmp, val,
1524 new_rtx, 1, OPTAB_DIRECT);
1530 tmp = expand_simple_binop (SImode, code, old, val,
1531 new_rtx, 1, OPTAB_DIRECT);
1534 case MULT: /* NAND */
1535 tmp = expand_simple_binop (SImode, XOR, old, ac.modemask,
1536 NULL_RTX, 1, OPTAB_DIRECT);
1537 tmp = expand_simple_binop (SImode, AND, tmp, val,
1538 new_rtx, 1, OPTAB_DIRECT);
1546 emit_move_insn (new_rtx, tmp);
1547 emit_insn (gen_sync_compare_and_swapsi (cmp, ac.memsi, old, new_rtx));
1548 emit_cmp_and_jump_insns (cmp, old, NE, const0_rtx, SImode, true, csloop);
1552 tmp = (after ? new_rtx : cmp);
1553 convert_move (target,
1554 (ac.shift == NULL_RTX ? tmp
1555 : expand_simple_binop (SImode, LSHIFTRT, tmp, ac.shift,
1556 NULL_RTX, 1, OPTAB_DIRECT)),
1563 xtensa_setup_frame_addresses (void)
1565 /* Set flag to cause TARGET_FRAME_POINTER_REQUIRED to return true. */
1566 cfun->machine->accesses_prev_frame = 1;
1569 (gen_rtx_SYMBOL_REF (Pmode, "__xtensa_libgcc_window_spill"),
1574 /* Emit the assembly for the end of a zero-cost loop. Normally we just emit
1575 a comment showing where the end of the loop is. However, if there is a
1576 label or a branch at the end of the loop then we need to place a nop
1577 there. If the loop ends with a label we need the nop so that branches
1578 targeting that label will target the nop (and thus remain in the loop),
1579 instead of targeting the instruction after the loop (and thus exiting
1580 the loop). If the loop ends with a branch, we need the nop in case the
1581 branch is targeting a location inside the loop. When the branch
1582 executes it will cause the loop count to be decremented even if it is
1583 taken (because it is the last instruction in the loop), so we need to
1584 nop after the branch to prevent the loop count from being decremented
1585 when the branch is taken. */
1588 xtensa_emit_loop_end (rtx insn, rtx *operands)
1592 for (insn = PREV_INSN (insn); insn && !done; insn = PREV_INSN (insn))
1594 switch (GET_CODE (insn))
1601 output_asm_insn (TARGET_DENSITY ? "nop.n" : "nop", operands);
1607 rtx body = PATTERN (insn);
1609 if (GET_CODE (body) == JUMP_INSN)
1611 output_asm_insn (TARGET_DENSITY ? "nop.n" : "nop", operands);
1614 else if ((GET_CODE (body) != USE)
1615 && (GET_CODE (body) != CLOBBER))
1622 output_asm_insn ("# loop end for %0", operands);
1627 xtensa_emit_branch (bool inverted, bool immed, rtx *operands)
1629 static char result[64];
1633 code = GET_CODE (operands[3]);
1636 case EQ: op = inverted ? "ne" : "eq"; break;
1637 case NE: op = inverted ? "eq" : "ne"; break;
1638 case LT: op = inverted ? "ge" : "lt"; break;
1639 case GE: op = inverted ? "lt" : "ge"; break;
1640 case LTU: op = inverted ? "geu" : "ltu"; break;
1641 case GEU: op = inverted ? "ltu" : "geu"; break;
1642 default: gcc_unreachable ();
1647 if (INTVAL (operands[1]) == 0)
1648 sprintf (result, "b%sz%s\t%%0, %%2", op,
1649 (TARGET_DENSITY && (code == EQ || code == NE)) ? ".n" : "");
1651 sprintf (result, "b%si\t%%0, %%d1, %%2", op);
1654 sprintf (result, "b%s\t%%0, %%1, %%2", op);
1661 xtensa_emit_bit_branch (bool inverted, bool immed, rtx *operands)
1663 static char result[64];
1666 switch (GET_CODE (operands[3]))
1668 case EQ: op = inverted ? "bs" : "bc"; break;
1669 case NE: op = inverted ? "bc" : "bs"; break;
1670 default: gcc_unreachable ();
1675 unsigned bitnum = INTVAL (operands[1]) & 0x1f;
1676 operands[1] = GEN_INT (bitnum);
1677 sprintf (result, "b%si\t%%0, %%d1, %%2", op);
1680 sprintf (result, "b%s\t%%0, %%1, %%2", op);
1687 xtensa_emit_movcc (bool inverted, bool isfp, bool isbool, rtx *operands)
1689 static char result[64];
1693 code = GET_CODE (operands[4]);
1698 case EQ: op = inverted ? "t" : "f"; break;
1699 case NE: op = inverted ? "f" : "t"; break;
1700 default: gcc_unreachable ();
1707 case EQ: op = inverted ? "nez" : "eqz"; break;
1708 case NE: op = inverted ? "eqz" : "nez"; break;
1709 case LT: op = inverted ? "gez" : "ltz"; break;
1710 case GE: op = inverted ? "ltz" : "gez"; break;
1711 default: gcc_unreachable ();
1715 sprintf (result, "mov%s%s\t%%0, %%%d, %%1",
1716 op, isfp ? ".s" : "", inverted ? 3 : 2);
1722 xtensa_emit_call (int callop, rtx *operands)
1724 static char result[64];
1725 rtx tgt = operands[callop];
1727 if (GET_CODE (tgt) == CONST_INT)
1728 sprintf (result, "call8\t0x%lx", INTVAL (tgt));
1729 else if (register_operand (tgt, VOIDmode))
1730 sprintf (result, "callx8\t%%%d", callop);
1732 sprintf (result, "call8\t%%%d", callop);
1739 xtensa_legitimate_address_p (enum machine_mode mode, rtx addr, bool strict)
1741 /* Allow constant pool addresses. */
1742 if (mode != BLKmode && GET_MODE_SIZE (mode) >= UNITS_PER_WORD
1743 && ! TARGET_CONST16 && constantpool_address_p (addr)
1744 && ! xtensa_tls_referenced_p (addr))
1747 while (GET_CODE (addr) == SUBREG)
1748 addr = SUBREG_REG (addr);
1750 /* Allow base registers. */
1751 if (GET_CODE (addr) == REG && BASE_REG_P (addr, strict))
1754 /* Check for "register + offset" addressing. */
1755 if (GET_CODE (addr) == PLUS)
1757 rtx xplus0 = XEXP (addr, 0);
1758 rtx xplus1 = XEXP (addr, 1);
1759 enum rtx_code code0;
1760 enum rtx_code code1;
1762 while (GET_CODE (xplus0) == SUBREG)
1763 xplus0 = SUBREG_REG (xplus0);
1764 code0 = GET_CODE (xplus0);
1766 while (GET_CODE (xplus1) == SUBREG)
1767 xplus1 = SUBREG_REG (xplus1);
1768 code1 = GET_CODE (xplus1);
1770 /* Swap operands if necessary so the register is first. */
1771 if (code0 != REG && code1 == REG)
1773 xplus0 = XEXP (addr, 1);
1774 xplus1 = XEXP (addr, 0);
1775 code0 = GET_CODE (xplus0);
1776 code1 = GET_CODE (xplus1);
1779 if (code0 == REG && BASE_REG_P (xplus0, strict)
1780 && code1 == CONST_INT
1781 && xtensa_mem_offset (INTVAL (xplus1), mode))
1789 /* Construct the SYMBOL_REF for the _TLS_MODULE_BASE_ symbol. */
1791 static GTY(()) rtx xtensa_tls_module_base_symbol;
1794 xtensa_tls_module_base (void)
1796 if (! xtensa_tls_module_base_symbol)
1798 xtensa_tls_module_base_symbol =
1799 gen_rtx_SYMBOL_REF (Pmode, "_TLS_MODULE_BASE_");
1800 SYMBOL_REF_FLAGS (xtensa_tls_module_base_symbol)
1801 |= TLS_MODEL_GLOBAL_DYNAMIC << SYMBOL_FLAG_TLS_SHIFT;
1804 return xtensa_tls_module_base_symbol;
1809 xtensa_call_tls_desc (rtx sym, rtx *retp)
1811 rtx fn, arg, a10, call_insn, insns;
1814 fn = gen_reg_rtx (Pmode);
1815 arg = gen_reg_rtx (Pmode);
1816 a10 = gen_rtx_REG (Pmode, 10);
1818 emit_insn (gen_tls_func (fn, sym));
1819 emit_insn (gen_tls_arg (arg, sym));
1820 emit_move_insn (a10, arg);
1821 call_insn = emit_call_insn (gen_tls_call (a10, fn, sym, const1_rtx));
1822 CALL_INSN_FUNCTION_USAGE (call_insn)
1823 = gen_rtx_EXPR_LIST (VOIDmode, gen_rtx_USE (VOIDmode, a10),
1824 CALL_INSN_FUNCTION_USAGE (call_insn));
1825 insns = get_insns ();
1834 xtensa_legitimize_tls_address (rtx x)
1836 unsigned int model = SYMBOL_REF_TLS_MODEL (x);
1837 rtx dest, tp, ret, modbase, base, addend, insns;
1839 dest = gen_reg_rtx (Pmode);
1842 case TLS_MODEL_GLOBAL_DYNAMIC:
1843 insns = xtensa_call_tls_desc (x, &ret);
1844 emit_libcall_block (insns, dest, ret, x);
1847 case TLS_MODEL_LOCAL_DYNAMIC:
1848 base = gen_reg_rtx (Pmode);
1849 modbase = xtensa_tls_module_base ();
1850 insns = xtensa_call_tls_desc (modbase, &ret);
1851 emit_libcall_block (insns, base, ret, modbase);
1852 addend = force_reg (SImode, gen_sym_DTPOFF (x));
1853 emit_insn (gen_addsi3 (dest, base, addend));
1856 case TLS_MODEL_INITIAL_EXEC:
1857 case TLS_MODEL_LOCAL_EXEC:
1858 tp = gen_reg_rtx (SImode);
1859 emit_insn (gen_load_tp (tp));
1860 addend = force_reg (SImode, gen_sym_TPOFF (x));
1861 emit_insn (gen_addsi3 (dest, tp, addend));
1873 xtensa_legitimize_address (rtx x,
1874 rtx oldx ATTRIBUTE_UNUSED,
1875 enum machine_mode mode)
1877 if (xtensa_tls_symbol_p (x))
1878 return xtensa_legitimize_tls_address (x);
1880 if (GET_CODE (x) == PLUS)
1882 rtx plus0 = XEXP (x, 0);
1883 rtx plus1 = XEXP (x, 1);
1885 if (GET_CODE (plus0) != REG && GET_CODE (plus1) == REG)
1887 plus0 = XEXP (x, 1);
1888 plus1 = XEXP (x, 0);
1891 /* Try to split up the offset to use an ADDMI instruction. */
1892 if (GET_CODE (plus0) == REG
1893 && GET_CODE (plus1) == CONST_INT
1894 && !xtensa_mem_offset (INTVAL (plus1), mode)
1895 && !xtensa_simm8 (INTVAL (plus1))
1896 && xtensa_mem_offset (INTVAL (plus1) & 0xff, mode)
1897 && xtensa_simm8x256 (INTVAL (plus1) & ~0xff))
1899 rtx temp = gen_reg_rtx (Pmode);
1900 rtx addmi_offset = GEN_INT (INTVAL (plus1) & ~0xff);
1901 emit_insn (gen_rtx_SET (Pmode, temp,
1902 gen_rtx_PLUS (Pmode, plus0, addmi_offset)));
1903 return gen_rtx_PLUS (Pmode, temp, GEN_INT (INTVAL (plus1) & 0xff));
1911 /* Helper for xtensa_tls_referenced_p. */
1914 xtensa_tls_referenced_p_1 (rtx *x, void *data ATTRIBUTE_UNUSED)
1916 if (GET_CODE (*x) == SYMBOL_REF)
1917 return SYMBOL_REF_TLS_MODEL (*x) != 0;
1919 /* Ignore TLS references that have already been legitimized. */
1920 if (GET_CODE (*x) == UNSPEC)
1922 switch (XINT (*x, 1))
1926 case UNSPEC_TLS_FUNC:
1927 case UNSPEC_TLS_ARG:
1928 case UNSPEC_TLS_CALL:
1939 /* Return TRUE if X contains any TLS symbol references. */
1942 xtensa_tls_referenced_p (rtx x)
1944 if (! TARGET_HAVE_TLS)
1947 return for_each_rtx (&x, xtensa_tls_referenced_p_1, NULL);
1951 /* Return the debugger register number to use for 'regno'. */
1954 xtensa_dbx_register_number (int regno)
1958 if (GP_REG_P (regno))
1960 regno -= GP_REG_FIRST;
1963 else if (BR_REG_P (regno))
1965 regno -= BR_REG_FIRST;
1968 else if (FP_REG_P (regno))
1970 regno -= FP_REG_FIRST;
1973 else if (ACC_REG_P (regno))
1975 first = 0x200; /* Start of Xtensa special registers. */
1976 regno = 16; /* ACCLO is special register 16. */
1979 /* When optimizing, we sometimes get asked about pseudo-registers
1980 that don't represent hard registers. Return 0 for these. */
1984 return first + regno;
1988 /* Argument support functions. */
1990 /* Initialize CUMULATIVE_ARGS for a function. */
1993 init_cumulative_args (CUMULATIVE_ARGS *cum, int incoming)
1996 cum->incoming = incoming;
2000 /* Advance the argument to the next argument position. */
2003 xtensa_function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode,
2004 const_tree type, bool named ATTRIBUTE_UNUSED)
2009 arg_words = &cum->arg_words;
2010 max = MAX_ARGS_IN_REGISTERS;
2012 words = (((mode != BLKmode)
2013 ? (int) GET_MODE_SIZE (mode)
2014 : int_size_in_bytes (type)) + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
2016 if (*arg_words < max
2017 && (targetm.calls.must_pass_in_stack (mode, type)
2018 || *arg_words + words > max))
2021 *arg_words += words;
2025 /* Return an RTL expression containing the register for the given mode,
2026 or 0 if the argument is to be passed on the stack. INCOMING_P is nonzero
2027 if this is an incoming argument to the current function. */
2030 xtensa_function_arg_1 (const CUMULATIVE_ARGS *cum, enum machine_mode mode,
2031 const_tree type, bool incoming_p)
2033 int regbase, words, max;
2037 arg_words = &cum->arg_words;
2038 regbase = (incoming_p ? GP_ARG_FIRST : GP_OUTGOING_ARG_FIRST);
2039 max = MAX_ARGS_IN_REGISTERS;
2041 words = (((mode != BLKmode)
2042 ? (int) GET_MODE_SIZE (mode)
2043 : int_size_in_bytes (type)) + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
2045 if (type && (TYPE_ALIGN (type) > BITS_PER_WORD))
2047 int align = MIN (TYPE_ALIGN (type), STACK_BOUNDARY) / BITS_PER_WORD;
2048 *arg_words = (*arg_words + align - 1) & -align;
2051 if (*arg_words + words > max)
2054 regno = regbase + *arg_words;
2056 if (cum->incoming && regno <= A7_REG && regno + words > A7_REG)
2057 cfun->machine->need_a7_copy = true;
2059 return gen_rtx_REG (mode, regno);
2062 /* Implement TARGET_FUNCTION_ARG. */
2065 xtensa_function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode,
2066 const_tree type, bool named ATTRIBUTE_UNUSED)
2068 return xtensa_function_arg_1 (cum, mode, type, false);
2071 /* Implement TARGET_FUNCTION_INCOMING_ARG. */
2074 xtensa_function_incoming_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode,
2075 const_tree type, bool named ATTRIBUTE_UNUSED)
2077 return xtensa_function_arg_1 (cum, mode, type, true);
2081 function_arg_boundary (enum machine_mode mode, tree type)
2083 unsigned int alignment;
2085 alignment = type ? TYPE_ALIGN (type) : GET_MODE_ALIGNMENT (mode);
2086 if (alignment < PARM_BOUNDARY)
2087 alignment = PARM_BOUNDARY;
2088 if (alignment > STACK_BOUNDARY)
2089 alignment = STACK_BOUNDARY;
2095 xtensa_return_in_msb (const_tree valtype)
2097 return (TARGET_BIG_ENDIAN
2098 && AGGREGATE_TYPE_P (valtype)
2099 && int_size_in_bytes (valtype) >= UNITS_PER_WORD);
2104 xtensa_option_override (void)
2107 enum machine_mode mode;
2109 if (!TARGET_BOOLEANS && TARGET_HARD_FLOAT)
2110 error ("boolean registers required for the floating-point option");
2112 /* Set up array giving whether a given register can hold a given mode. */
2113 for (mode = VOIDmode;
2114 mode != MAX_MACHINE_MODE;
2115 mode = (enum machine_mode) ((int) mode + 1))
2117 int size = GET_MODE_SIZE (mode);
2118 enum mode_class mclass = GET_MODE_CLASS (mode);
2120 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
2124 if (ACC_REG_P (regno))
2125 temp = (TARGET_MAC16
2126 && (mclass == MODE_INT) && (size <= UNITS_PER_WORD));
2127 else if (GP_REG_P (regno))
2128 temp = ((regno & 1) == 0 || (size <= UNITS_PER_WORD));
2129 else if (FP_REG_P (regno))
2130 temp = (TARGET_HARD_FLOAT && (mode == SFmode));
2131 else if (BR_REG_P (regno))
2132 temp = (TARGET_BOOLEANS && (mode == CCmode));
2136 xtensa_hard_regno_mode_ok[(int) mode][regno] = temp;
2140 init_machine_status = xtensa_init_machine_status;
2142 /* Check PIC settings. PIC is only supported when using L32R
2143 instructions, and some targets need to always use PIC. */
2144 if (flag_pic && TARGET_CONST16)
2145 error ("-f%s is not supported with CONST16 instructions",
2146 (flag_pic > 1 ? "PIC" : "pic"));
2147 else if (TARGET_FORCE_NO_PIC)
2149 else if (XTENSA_ALWAYS_PIC)
2152 error ("PIC is required but not supported with CONST16 instructions");
2155 /* There's no need for -fPIC (as opposed to -fpic) on Xtensa. */
2158 if (flag_pic && !flag_pie)
2161 /* Hot/cold partitioning does not work on this architecture, because of
2162 constant pools (the load instruction cannot necessarily reach that far).
2163 Therefore disable it on this architecture. */
2164 if (flag_reorder_blocks_and_partition)
2166 flag_reorder_blocks_and_partition = 0;
2167 flag_reorder_blocks = 1;
2172 /* A C compound statement to output to stdio stream STREAM the
2173 assembler syntax for an instruction operand X. X is an RTL
2176 CODE is a value that can be used to specify one of several ways
2177 of printing the operand. It is used when identical operands
2178 must be printed differently depending on the context. CODE
2179 comes from the '%' specification that was used to request
2180 printing of the operand. If the specification was just '%DIGIT'
2181 then CODE is 0; if the specification was '%LTR DIGIT' then CODE
2182 is the ASCII code for LTR.
2184 If X is a register, this macro should print the register's name.
2185 The names can be found in an array 'reg_names' whose type is
2186 'char *[]'. 'reg_names' is initialized from 'REGISTER_NAMES'.
2188 When the machine description has a specification '%PUNCT' (a '%'
2189 followed by a punctuation character), this macro is called with
2190 a null pointer for X and the punctuation character for CODE.
2192 'a', 'c', 'l', and 'n' are reserved.
2194 The Xtensa specific codes are:
2196 'd' CONST_INT, print as signed decimal
2197 'x' CONST_INT, print as signed hexadecimal
2198 'K' CONST_INT, print number of bits in mask for EXTUI
2199 'R' CONST_INT, print (X & 0x1f)
2200 'L' CONST_INT, print ((32 - X) & 0x1f)
2201 'D' REG, print second register of double-word register operand
2202 'N' MEM, print address of next word following a memory operand
2203 'v' MEM, if memory reference is volatile, output a MEMW before it
2204 't' any constant, add "@h" suffix for top 16 bits
2205 'b' any constant, add "@l" suffix for bottom 16 bits
2209 printx (FILE *file, signed int val)
2211 /* Print a hexadecimal value in a nice way. */
2212 if ((val > -0xa) && (val < 0xa))
2213 fprintf (file, "%d", val);
2215 fprintf (file, "-0x%x", -val);
2217 fprintf (file, "0x%x", val);
2222 print_operand (FILE *file, rtx x, int letter)
2225 error ("PRINT_OPERAND null pointer");
2230 if (GET_CODE (x) == REG || GET_CODE (x) == SUBREG)
2231 fprintf (file, "%s", reg_names[xt_true_regnum (x) + 1]);
2233 output_operand_lossage ("invalid %%D value");
2237 if (GET_CODE (x) == MEM)
2239 /* For a volatile memory reference, emit a MEMW before the
2241 if (MEM_VOLATILE_P (x) && TARGET_SERIALIZE_VOLATILE)
2242 fprintf (file, "memw\n\t");
2245 output_operand_lossage ("invalid %%v value");
2249 if (GET_CODE (x) == MEM
2250 && (GET_MODE (x) == DFmode || GET_MODE (x) == DImode))
2252 x = adjust_address (x, GET_MODE (x) == DFmode ? SFmode : SImode, 4);
2253 output_address (XEXP (x, 0));
2256 output_operand_lossage ("invalid %%N value");
2260 if (GET_CODE (x) == CONST_INT)
2263 unsigned val = INTVAL (x);
2269 if ((val != 0) || (num_bits == 0) || (num_bits > 16))
2270 fatal_insn ("invalid mask", x);
2272 fprintf (file, "%d", num_bits);
2275 output_operand_lossage ("invalid %%K value");
2279 if (GET_CODE (x) == CONST_INT)
2280 fprintf (file, "%ld", (32 - INTVAL (x)) & 0x1f);
2282 output_operand_lossage ("invalid %%L value");
2286 if (GET_CODE (x) == CONST_INT)
2287 fprintf (file, "%ld", INTVAL (x) & 0x1f);
2289 output_operand_lossage ("invalid %%R value");
2293 if (GET_CODE (x) == CONST_INT)
2294 printx (file, INTVAL (x));
2296 output_operand_lossage ("invalid %%x value");
2300 if (GET_CODE (x) == CONST_INT)
2301 fprintf (file, "%ld", INTVAL (x));
2303 output_operand_lossage ("invalid %%d value");
2308 if (GET_CODE (x) == CONST_INT)
2310 printx (file, INTVAL (x));
2311 fputs (letter == 't' ? "@h" : "@l", file);
2313 else if (GET_CODE (x) == CONST_DOUBLE)
2316 REAL_VALUE_FROM_CONST_DOUBLE (r, x);
2317 if (GET_MODE (x) == SFmode)
2320 REAL_VALUE_TO_TARGET_SINGLE (r, l);
2321 fprintf (file, "0x%08lx@%c", l, letter == 't' ? 'h' : 'l');
2324 output_operand_lossage ("invalid %%t/%%b value");
2326 else if (GET_CODE (x) == CONST)
2328 /* X must be a symbolic constant on ELF. Write an expression
2329 suitable for 'const16' that sets the high or low 16 bits. */
2330 if (GET_CODE (XEXP (x, 0)) != PLUS
2331 || (GET_CODE (XEXP (XEXP (x, 0), 0)) != SYMBOL_REF
2332 && GET_CODE (XEXP (XEXP (x, 0), 0)) != LABEL_REF)
2333 || GET_CODE (XEXP (XEXP (x, 0), 1)) != CONST_INT)
2334 output_operand_lossage ("invalid %%t/%%b value");
2335 print_operand (file, XEXP (XEXP (x, 0), 0), 0);
2336 fputs (letter == 't' ? "@h" : "@l", file);
2337 /* There must be a non-alphanumeric character between 'h' or 'l'
2338 and the number. The '-' is added by print_operand() already. */
2339 if (INTVAL (XEXP (XEXP (x, 0), 1)) >= 0)
2341 print_operand (file, XEXP (XEXP (x, 0), 1), 0);
2345 output_addr_const (file, x);
2346 fputs (letter == 't' ? "@h" : "@l", file);
2351 if (GET_CODE (x) == REG || GET_CODE (x) == SUBREG)
2352 fprintf (file, "%s", reg_names[xt_true_regnum (x)]);
2353 else if (GET_CODE (x) == MEM)
2354 output_address (XEXP (x, 0));
2355 else if (GET_CODE (x) == CONST_INT)
2356 fprintf (file, "%ld", INTVAL (x));
2358 output_addr_const (file, x);
2363 /* A C compound statement to output to stdio stream STREAM the
2364 assembler syntax for an instruction operand that is a memory
2365 reference whose address is ADDR. ADDR is an RTL expression. */
2368 print_operand_address (FILE *file, rtx addr)
2371 error ("PRINT_OPERAND_ADDRESS, null pointer");
2373 switch (GET_CODE (addr))
2376 fatal_insn ("invalid address", addr);
2380 fprintf (file, "%s, 0", reg_names [REGNO (addr)]);
2386 rtx offset = (rtx)0;
2387 rtx arg0 = XEXP (addr, 0);
2388 rtx arg1 = XEXP (addr, 1);
2390 if (GET_CODE (arg0) == REG)
2395 else if (GET_CODE (arg1) == REG)
2401 fatal_insn ("no register in address", addr);
2403 if (CONSTANT_P (offset))
2405 fprintf (file, "%s, ", reg_names [REGNO (reg)]);
2406 output_addr_const (file, offset);
2409 fatal_insn ("address offset not a constant", addr);
2417 output_addr_const (file, addr);
2424 xtensa_output_addr_const_extra (FILE *fp, rtx x)
2426 if (GET_CODE (x) == UNSPEC && XVECLEN (x, 0) == 1)
2428 switch (XINT (x, 1))
2431 output_addr_const (fp, XVECEXP (x, 0, 0));
2432 fputs ("@TPOFF", fp);
2435 output_addr_const (fp, XVECEXP (x, 0, 0));
2436 fputs ("@DTPOFF", fp);
2441 output_addr_const (fp, XVECEXP (x, 0, 0));
2455 xtensa_output_literal (FILE *file, rtx x, enum machine_mode mode, int labelno)
2462 fprintf (file, "\t.literal .LC%u, ", (unsigned) labelno);
2464 switch (GET_MODE_CLASS (mode))
2467 gcc_assert (GET_CODE (x) == CONST_DOUBLE);
2469 REAL_VALUE_FROM_CONST_DOUBLE (r, x);
2473 REAL_VALUE_TO_TARGET_SINGLE (r, value_long[0]);
2474 if (HOST_BITS_PER_LONG > 32)
2475 value_long[0] &= 0xffffffff;
2476 fprintf (file, "0x%08lx\n", value_long[0]);
2480 REAL_VALUE_TO_TARGET_DOUBLE (r, value_long);
2481 if (HOST_BITS_PER_LONG > 32)
2483 value_long[0] &= 0xffffffff;
2484 value_long[1] &= 0xffffffff;
2486 fprintf (file, "0x%08lx, 0x%08lx\n",
2487 value_long[0], value_long[1]);
2497 case MODE_PARTIAL_INT:
2498 size = GET_MODE_SIZE (mode);
2502 output_addr_const (file, x);
2507 split_double (x, &first, &second);
2508 output_addr_const (file, first);
2510 output_addr_const (file, second);
2525 /* Return the bytes needed to compute the frame pointer from the current
2528 #define STACK_BYTES (STACK_BOUNDARY / BITS_PER_UNIT)
2529 #define XTENSA_STACK_ALIGN(LOC) (((LOC) + STACK_BYTES-1) & ~(STACK_BYTES-1))
2532 compute_frame_size (int size)
2534 /* Add space for the incoming static chain value. */
2535 if (cfun->static_chain_decl != NULL)
2536 size += (1 * UNITS_PER_WORD);
2538 xtensa_current_frame_size =
2539 XTENSA_STACK_ALIGN (size
2540 + crtl->outgoing_args_size
2541 + (WINDOW_SIZE * UNITS_PER_WORD));
2542 return xtensa_current_frame_size;
2547 xtensa_frame_pointer_required (void)
2549 /* The code to expand builtin_frame_addr and builtin_return_addr
2550 currently uses the hard_frame_pointer instead of frame_pointer.
2551 This seems wrong but maybe it's necessary for other architectures.
2552 This function is derived from the i386 code. */
2554 if (cfun->machine->accesses_prev_frame)
2561 /* minimum frame = reg save area (4 words) plus static chain (1 word)
2562 and the total number of words must be a multiple of 128 bits. */
2563 #define MIN_FRAME_SIZE (8 * UNITS_PER_WORD)
2566 xtensa_expand_prologue (void)
2568 HOST_WIDE_INT total_size;
2572 total_size = compute_frame_size (get_frame_size ());
2573 size_rtx = GEN_INT (total_size);
2575 if (total_size < (1 << (12+3)))
2576 insn = emit_insn (gen_entry (size_rtx));
2579 /* Use a8 as a temporary since a0-a7 may be live. */
2580 rtx tmp_reg = gen_rtx_REG (Pmode, A8_REG);
2581 emit_insn (gen_entry (GEN_INT (MIN_FRAME_SIZE)));
2582 emit_move_insn (tmp_reg, GEN_INT (total_size - MIN_FRAME_SIZE));
2583 emit_insn (gen_subsi3 (tmp_reg, stack_pointer_rtx, tmp_reg));
2584 insn = emit_insn (gen_movsi (stack_pointer_rtx, tmp_reg));
2587 if (frame_pointer_needed)
2589 if (cfun->machine->set_frame_ptr_insn)
2593 push_topmost_sequence ();
2594 first = get_insns ();
2595 pop_topmost_sequence ();
2597 /* For all instructions prior to set_frame_ptr_insn, replace
2598 hard_frame_pointer references with stack_pointer. */
2600 insn != cfun->machine->set_frame_ptr_insn;
2601 insn = NEXT_INSN (insn))
2605 PATTERN (insn) = replace_rtx (copy_rtx (PATTERN (insn)),
2606 hard_frame_pointer_rtx,
2608 df_insn_rescan (insn);
2613 insn = emit_insn (gen_movsi (hard_frame_pointer_rtx,
2614 stack_pointer_rtx));
2617 /* Create a note to describe the CFA. Because this is only used to set
2618 DW_AT_frame_base for debug info, don't bother tracking changes through
2619 each instruction in the prologue. It just takes up space. */
2620 note_rtx = gen_rtx_SET (VOIDmode, (frame_pointer_needed
2621 ? hard_frame_pointer_rtx
2622 : stack_pointer_rtx),
2623 plus_constant (stack_pointer_rtx, -total_size));
2624 RTX_FRAME_RELATED_P (insn) = 1;
2625 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR,
2626 note_rtx, REG_NOTES (insn));
2630 /* Clear variables at function end. */
2633 xtensa_function_epilogue (FILE *file ATTRIBUTE_UNUSED,
2634 HOST_WIDE_INT size ATTRIBUTE_UNUSED)
2636 xtensa_current_frame_size = 0;
2641 xtensa_return_addr (int count, rtx frame)
2643 rtx result, retaddr, curaddr, label;
2646 retaddr = gen_rtx_REG (Pmode, A0_REG);
2649 rtx addr = plus_constant (frame, -4 * UNITS_PER_WORD);
2650 addr = memory_address (Pmode, addr);
2651 retaddr = gen_reg_rtx (Pmode);
2652 emit_move_insn (retaddr, gen_rtx_MEM (Pmode, addr));
2655 /* The 2 most-significant bits of the return address on Xtensa hold
2656 the register window size. To get the real return address, these
2657 bits must be replaced with the high bits from some address in the
2660 /* Get the 2 high bits of a local label in the code. */
2661 curaddr = gen_reg_rtx (Pmode);
2662 label = gen_label_rtx ();
2664 LABEL_PRESERVE_P (label) = 1;
2665 emit_move_insn (curaddr, gen_rtx_LABEL_REF (Pmode, label));
2666 emit_insn (gen_lshrsi3 (curaddr, curaddr, GEN_INT (30)));
2667 emit_insn (gen_ashlsi3 (curaddr, curaddr, GEN_INT (30)));
2669 /* Clear the 2 high bits of the return address. */
2670 result = gen_reg_rtx (Pmode);
2671 emit_insn (gen_ashlsi3 (result, retaddr, GEN_INT (2)));
2672 emit_insn (gen_lshrsi3 (result, result, GEN_INT (2)));
2674 /* Combine them to get the result. */
2675 emit_insn (gen_iorsi3 (result, result, curaddr));
2680 /* Create the va_list data type.
2682 This structure is set up by __builtin_saveregs. The __va_reg field
2683 points to a stack-allocated region holding the contents of the
2684 incoming argument registers. The __va_ndx field is an index
2685 initialized to the position of the first unnamed (variable)
2686 argument. This same index is also used to address the arguments
2687 passed in memory. Thus, the __va_stk field is initialized to point
2688 to the position of the first argument in memory offset to account
2689 for the arguments passed in registers and to account for the size
2690 of the argument registers not being 16-byte aligned. E.G., there
2691 are 6 argument registers of 4 bytes each, but we want the __va_ndx
2692 for the first stack argument to have the maximal alignment of 16
2693 bytes, so we offset the __va_stk address by 32 bytes so that
2694 __va_stk[32] references the first argument on the stack. */
2697 xtensa_build_builtin_va_list (void)
2699 tree f_stk, f_reg, f_ndx, record, type_decl;
2701 record = (*lang_hooks.types.make_type) (RECORD_TYPE);
2702 type_decl = build_decl (BUILTINS_LOCATION,
2703 TYPE_DECL, get_identifier ("__va_list_tag"), record);
2705 f_stk = build_decl (BUILTINS_LOCATION,
2706 FIELD_DECL, get_identifier ("__va_stk"),
2708 f_reg = build_decl (BUILTINS_LOCATION,
2709 FIELD_DECL, get_identifier ("__va_reg"),
2711 f_ndx = build_decl (BUILTINS_LOCATION,
2712 FIELD_DECL, get_identifier ("__va_ndx"),
2715 DECL_FIELD_CONTEXT (f_stk) = record;
2716 DECL_FIELD_CONTEXT (f_reg) = record;
2717 DECL_FIELD_CONTEXT (f_ndx) = record;
2719 TREE_CHAIN (record) = type_decl;
2720 TYPE_NAME (record) = type_decl;
2721 TYPE_FIELDS (record) = f_stk;
2722 DECL_CHAIN (f_stk) = f_reg;
2723 DECL_CHAIN (f_reg) = f_ndx;
2725 layout_type (record);
2730 /* Save the incoming argument registers on the stack. Returns the
2731 address of the saved registers. */
2734 xtensa_builtin_saveregs (void)
2737 int arg_words = crtl->args.info.arg_words;
2738 int gp_left = MAX_ARGS_IN_REGISTERS - arg_words;
2743 /* Allocate the general-purpose register space. */
2744 gp_regs = assign_stack_local
2745 (BLKmode, MAX_ARGS_IN_REGISTERS * UNITS_PER_WORD, -1);
2746 set_mem_alias_set (gp_regs, get_varargs_alias_set ());
2748 /* Now store the incoming registers. */
2749 cfun->machine->need_a7_copy = true;
2750 cfun->machine->vararg_a7 = true;
2751 move_block_from_reg (GP_ARG_FIRST + arg_words,
2752 adjust_address (gp_regs, BLKmode,
2753 arg_words * UNITS_PER_WORD),
2755 gcc_assert (cfun->machine->vararg_a7_copy != 0);
2756 emit_insn_before (cfun->machine->vararg_a7_copy, get_insns ());
2758 return XEXP (gp_regs, 0);
2762 /* Implement `va_start' for varargs and stdarg. We look at the
2763 current function to fill in an initial va_list. */
2766 xtensa_va_start (tree valist, rtx nextarg ATTRIBUTE_UNUSED)
2774 arg_words = crtl->args.info.arg_words;
2776 f_stk = TYPE_FIELDS (va_list_type_node);
2777 f_reg = DECL_CHAIN (f_stk);
2778 f_ndx = DECL_CHAIN (f_reg);
2780 stk = build3 (COMPONENT_REF, TREE_TYPE (f_stk), valist, f_stk, NULL_TREE);
2781 reg = build3 (COMPONENT_REF, TREE_TYPE (f_reg), unshare_expr (valist),
2783 ndx = build3 (COMPONENT_REF, TREE_TYPE (f_ndx), unshare_expr (valist),
2786 /* Call __builtin_saveregs; save the result in __va_reg */
2787 u = make_tree (sizetype, expand_builtin_saveregs ());
2788 u = fold_convert (ptr_type_node, u);
2789 t = build2 (MODIFY_EXPR, ptr_type_node, reg, u);
2790 TREE_SIDE_EFFECTS (t) = 1;
2791 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
2793 /* Set the __va_stk member to ($arg_ptr - 32). */
2794 u = make_tree (ptr_type_node, virtual_incoming_args_rtx);
2795 u = fold_build2 (POINTER_PLUS_EXPR, ptr_type_node, u, size_int (-32));
2796 t = build2 (MODIFY_EXPR, ptr_type_node, stk, u);
2797 TREE_SIDE_EFFECTS (t) = 1;
2798 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
2800 /* Set the __va_ndx member. If the first variable argument is on
2801 the stack, adjust __va_ndx by 2 words to account for the extra
2802 alignment offset for __va_stk. */
2803 if (arg_words >= MAX_ARGS_IN_REGISTERS)
2805 t = build2 (MODIFY_EXPR, integer_type_node, ndx,
2806 build_int_cst (integer_type_node, arg_words * UNITS_PER_WORD));
2807 TREE_SIDE_EFFECTS (t) = 1;
2808 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
2812 /* Implement `va_arg'. */
2815 xtensa_gimplify_va_arg_expr (tree valist, tree type, gimple_seq *pre_p,
2816 gimple_seq *post_p ATTRIBUTE_UNUSED)
2821 tree type_size, array, orig_ndx, addr, size, va_size, t;
2822 tree lab_false, lab_over, lab_false2;
2825 indirect = pass_by_reference (NULL, TYPE_MODE (type), type, false);
2827 type = build_pointer_type (type);
2829 /* Handle complex values as separate real and imaginary parts. */
2830 if (TREE_CODE (type) == COMPLEX_TYPE)
2832 tree real_part, imag_part;
2834 real_part = xtensa_gimplify_va_arg_expr (valist, TREE_TYPE (type),
2836 real_part = get_initialized_tmp_var (real_part, pre_p, NULL);
2838 imag_part = xtensa_gimplify_va_arg_expr (unshare_expr (valist),
2841 imag_part = get_initialized_tmp_var (imag_part, pre_p, NULL);
2843 return build2 (COMPLEX_EXPR, type, real_part, imag_part);
2846 f_stk = TYPE_FIELDS (va_list_type_node);
2847 f_reg = DECL_CHAIN (f_stk);
2848 f_ndx = DECL_CHAIN (f_reg);
2850 stk = build3 (COMPONENT_REF, TREE_TYPE (f_stk), valist,
2852 reg = build3 (COMPONENT_REF, TREE_TYPE (f_reg), unshare_expr (valist),
2854 ndx = build3 (COMPONENT_REF, TREE_TYPE (f_ndx), unshare_expr (valist),
2857 type_size = size_in_bytes (type);
2858 va_size = round_up (type_size, UNITS_PER_WORD);
2859 gimplify_expr (&va_size, pre_p, NULL, is_gimple_val, fb_rvalue);
2862 /* First align __va_ndx if necessary for this arg:
2864 orig_ndx = (AP).__va_ndx;
2865 if (__alignof__ (TYPE) > 4 )
2866 orig_ndx = ((orig_ndx + __alignof__ (TYPE) - 1)
2867 & -__alignof__ (TYPE)); */
2869 orig_ndx = get_initialized_tmp_var (ndx, pre_p, NULL);
2871 if (TYPE_ALIGN (type) > BITS_PER_WORD)
2873 int align = MIN (TYPE_ALIGN (type), STACK_BOUNDARY) / BITS_PER_UNIT;
2875 t = build2 (PLUS_EXPR, integer_type_node, unshare_expr (orig_ndx),
2876 build_int_cst (integer_type_node, align - 1));
2877 t = build2 (BIT_AND_EXPR, integer_type_node, t,
2878 build_int_cst (integer_type_node, -align));
2879 gimplify_assign (unshare_expr (orig_ndx), t, pre_p);
2883 /* Increment __va_ndx to point past the argument:
2885 (AP).__va_ndx = orig_ndx + __va_size (TYPE); */
2887 t = fold_convert (integer_type_node, va_size);
2888 t = build2 (PLUS_EXPR, integer_type_node, orig_ndx, t);
2889 gimplify_assign (unshare_expr (ndx), t, pre_p);
2892 /* Check if the argument is in registers:
2894 if ((AP).__va_ndx <= __MAX_ARGS_IN_REGISTERS * 4
2895 && !must_pass_in_stack (type))
2896 __array = (AP).__va_reg; */
2898 array = create_tmp_var (ptr_type_node, NULL);
2901 if (!targetm.calls.must_pass_in_stack (TYPE_MODE (type), type))
2903 lab_false = create_artificial_label (UNKNOWN_LOCATION);
2904 lab_over = create_artificial_label (UNKNOWN_LOCATION);
2906 t = build2 (GT_EXPR, boolean_type_node, unshare_expr (ndx),
2907 build_int_cst (integer_type_node,
2908 MAX_ARGS_IN_REGISTERS * UNITS_PER_WORD));
2909 t = build3 (COND_EXPR, void_type_node, t,
2910 build1 (GOTO_EXPR, void_type_node, lab_false),
2912 gimplify_and_add (t, pre_p);
2914 gimplify_assign (unshare_expr (array), reg, pre_p);
2916 t = build1 (GOTO_EXPR, void_type_node, lab_over);
2917 gimplify_and_add (t, pre_p);
2919 t = build1 (LABEL_EXPR, void_type_node, lab_false);
2920 gimplify_and_add (t, pre_p);
2924 /* ...otherwise, the argument is on the stack (never split between
2925 registers and the stack -- change __va_ndx if necessary):
2929 if (orig_ndx <= __MAX_ARGS_IN_REGISTERS * 4)
2930 (AP).__va_ndx = 32 + __va_size (TYPE);
2931 __array = (AP).__va_stk;
2934 lab_false2 = create_artificial_label (UNKNOWN_LOCATION);
2936 t = build2 (GT_EXPR, boolean_type_node, unshare_expr (orig_ndx),
2937 build_int_cst (integer_type_node,
2938 MAX_ARGS_IN_REGISTERS * UNITS_PER_WORD));
2939 t = build3 (COND_EXPR, void_type_node, t,
2940 build1 (GOTO_EXPR, void_type_node, lab_false2),
2942 gimplify_and_add (t, pre_p);
2944 t = size_binop (PLUS_EXPR, unshare_expr (va_size), size_int (32));
2945 t = fold_convert (integer_type_node, t);
2946 gimplify_assign (unshare_expr (ndx), t, pre_p);
2948 t = build1 (LABEL_EXPR, void_type_node, lab_false2);
2949 gimplify_and_add (t, pre_p);
2951 gimplify_assign (array, stk, pre_p);
2955 t = build1 (LABEL_EXPR, void_type_node, lab_over);
2956 gimplify_and_add (t, pre_p);
2960 /* Given the base array pointer (__array) and index to the subsequent
2961 argument (__va_ndx), find the address:
2963 __array + (AP).__va_ndx - (BYTES_BIG_ENDIAN && sizeof (TYPE) < 4
2967 The results are endian-dependent because values smaller than one word
2968 are aligned differently. */
2971 if (BYTES_BIG_ENDIAN && TREE_CODE (type_size) == INTEGER_CST)
2973 t = fold_build2 (GE_EXPR, boolean_type_node, unshare_expr (type_size),
2974 size_int (PARM_BOUNDARY / BITS_PER_UNIT));
2975 t = fold_build3 (COND_EXPR, sizetype, t, unshare_expr (va_size),
2976 unshare_expr (type_size));
2980 size = unshare_expr (va_size);
2982 t = fold_convert (sizetype, unshare_expr (ndx));
2983 t = build2 (MINUS_EXPR, sizetype, t, size);
2984 addr = build2 (POINTER_PLUS_EXPR, ptr_type_node, unshare_expr (array), t);
2986 addr = fold_convert (build_pointer_type (type), addr);
2988 addr = build_va_arg_indirect_ref (addr);
2989 return build_va_arg_indirect_ref (addr);
2997 XTENSA_BUILTIN_UMULSIDI3,
2998 XTENSA_BUILTIN_THREAD_POINTER,
2999 XTENSA_BUILTIN_SET_THREAD_POINTER,
3005 xtensa_init_builtins (void)
3009 ftype = build_function_type_list (unsigned_intDI_type_node,
3010 unsigned_intSI_type_node,
3011 unsigned_intSI_type_node, NULL_TREE);
3013 decl = add_builtin_function ("__builtin_umulsidi3", ftype,
3014 XTENSA_BUILTIN_UMULSIDI3, BUILT_IN_MD,
3015 "__umulsidi3", NULL_TREE);
3016 TREE_NOTHROW (decl) = 1;
3017 TREE_READONLY (decl) = 1;
3019 if (TARGET_THREADPTR)
3021 ftype = build_function_type (ptr_type_node, void_list_node);
3022 decl = add_builtin_function ("__builtin_thread_pointer", ftype,
3023 XTENSA_BUILTIN_THREAD_POINTER, BUILT_IN_MD,
3025 TREE_READONLY (decl) = 1;
3026 TREE_NOTHROW (decl) = 1;
3028 ftype = build_function_type_list (void_type_node, ptr_type_node,
3030 decl = add_builtin_function ("__builtin_set_thread_pointer", ftype,
3031 XTENSA_BUILTIN_SET_THREAD_POINTER,
3032 BUILT_IN_MD, NULL, NULL_TREE);
3033 TREE_NOTHROW (decl) = 1;
3039 xtensa_fold_builtin (tree fndecl, int n_args ATTRIBUTE_UNUSED, tree *args,
3040 bool ignore ATTRIBUTE_UNUSED)
3042 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
3047 case XTENSA_BUILTIN_UMULSIDI3:
3050 if ((TREE_CODE (arg0) == INTEGER_CST && TREE_CODE (arg1) == INTEGER_CST)
3051 || TARGET_MUL32_HIGH)
3052 return fold_build2 (MULT_EXPR, unsigned_intDI_type_node,
3053 fold_convert (unsigned_intDI_type_node, arg0),
3054 fold_convert (unsigned_intDI_type_node, arg1));
3057 case XTENSA_BUILTIN_THREAD_POINTER:
3058 case XTENSA_BUILTIN_SET_THREAD_POINTER:
3062 internal_error ("bad builtin code");
3071 xtensa_expand_builtin (tree exp, rtx target,
3072 rtx subtarget ATTRIBUTE_UNUSED,
3073 enum machine_mode mode ATTRIBUTE_UNUSED,
3076 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
3077 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
3082 case XTENSA_BUILTIN_UMULSIDI3:
3083 /* The umulsidi3 builtin is just a mechanism to avoid calling the real
3084 __umulsidi3 function when the Xtensa configuration can directly
3085 implement it. If not, just call the function. */
3086 return expand_call (exp, target, ignore);
3088 case XTENSA_BUILTIN_THREAD_POINTER:
3089 if (!target || !register_operand (target, Pmode))
3090 target = gen_reg_rtx (Pmode);
3091 emit_insn (gen_load_tp (target));
3094 case XTENSA_BUILTIN_SET_THREAD_POINTER:
3095 arg = expand_normal (CALL_EXPR_ARG (exp, 0));
3096 if (!register_operand (arg, Pmode))
3097 arg = copy_to_mode_reg (Pmode, arg);
3098 emit_insn (gen_set_tp (arg));
3102 internal_error ("bad builtin code");
3109 xtensa_preferred_reload_class (rtx x, enum reg_class rclass, int isoutput)
3111 if (!isoutput && CONSTANT_P (x) && GET_CODE (x) == CONST_DOUBLE)
3114 /* Don't use the stack pointer or hard frame pointer for reloads!
3115 The hard frame pointer would normally be OK except that it may
3116 briefly hold an incoming argument in the prologue, and reload
3117 won't know that it is live because the hard frame pointer is
3118 treated specially. */
3120 if (rclass == AR_REGS || rclass == GR_REGS)
3128 xtensa_secondary_reload (bool in_p, rtx x, reg_class_t rclass,
3129 enum machine_mode mode, secondary_reload_info *sri)
3133 if (in_p && constantpool_mem_p (x))
3135 if (rclass == FP_REGS)
3139 sri->icode = CODE_FOR_reloadqi_literal;
3140 else if (mode == HImode)
3141 sri->icode = CODE_FOR_reloadhi_literal;
3144 regno = xt_true_regnum (x);
3145 if (ACC_REG_P (regno))
3146 return ((rclass == GR_REGS || rclass == RL_REGS) ? NO_REGS : RL_REGS);
3147 if (rclass == ACC_REG)
3148 return (GP_REG_P (regno) ? NO_REGS : RL_REGS);
3155 order_regs_for_local_alloc (void)
3157 if (!leaf_function_p ())
3159 memcpy (reg_alloc_order, reg_nonleaf_alloc_order,
3160 FIRST_PSEUDO_REGISTER * sizeof (int));
3164 int i, num_arg_regs;
3167 /* Use the AR registers in increasing order (skipping a0 and a1)
3168 but save the incoming argument registers for a last resort. */
3169 num_arg_regs = crtl->args.info.arg_words;
3170 if (num_arg_regs > MAX_ARGS_IN_REGISTERS)
3171 num_arg_regs = MAX_ARGS_IN_REGISTERS;
3172 for (i = GP_ARG_FIRST; i < 16 - num_arg_regs; i++)
3173 reg_alloc_order[nxt++] = i + num_arg_regs;
3174 for (i = 0; i < num_arg_regs; i++)
3175 reg_alloc_order[nxt++] = GP_ARG_FIRST + i;
3177 /* List the coprocessor registers in order. */
3178 for (i = 0; i < BR_REG_NUM; i++)
3179 reg_alloc_order[nxt++] = BR_REG_FIRST + i;
3181 /* List the FP registers in order for now. */
3182 for (i = 0; i < 16; i++)
3183 reg_alloc_order[nxt++] = FP_REG_FIRST + i;
3185 /* GCC requires that we list *all* the registers.... */
3186 reg_alloc_order[nxt++] = 0; /* a0 = return address */
3187 reg_alloc_order[nxt++] = 1; /* a1 = stack pointer */
3188 reg_alloc_order[nxt++] = 16; /* pseudo frame pointer */
3189 reg_alloc_order[nxt++] = 17; /* pseudo arg pointer */
3191 reg_alloc_order[nxt++] = ACC_REG_FIRST; /* MAC16 accumulator */
3196 /* Some Xtensa targets support multiple bss sections. If the section
3197 name ends with ".bss", add SECTION_BSS to the flags. */
3200 xtensa_multibss_section_type_flags (tree decl, const char *name, int reloc)
3202 unsigned int flags = default_section_type_flags (decl, name, reloc);
3205 suffix = strrchr (name, '.');
3206 if (suffix && strcmp (suffix, ".bss") == 0)
3208 if (!decl || (TREE_CODE (decl) == VAR_DECL
3209 && DECL_INITIAL (decl) == NULL_TREE))
3210 flags |= SECTION_BSS; /* @nobits */
3212 warning (0, "only uninitialized variables can be placed in a "
3220 /* The literal pool stays with the function. */
3223 xtensa_select_rtx_section (enum machine_mode mode ATTRIBUTE_UNUSED,
3224 rtx x ATTRIBUTE_UNUSED,
3225 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED)
3227 return function_section (current_function_decl);
3231 /* Compute a (partial) cost for rtx X. Return true if the complete
3232 cost has been computed, and false if subexpressions should be
3233 scanned. In either case, *TOTAL contains the cost result. */
3236 xtensa_rtx_costs (rtx x, int code, int outer_code, int *total,
3237 bool speed ATTRIBUTE_UNUSED)
3245 if (xtensa_simm12b (INTVAL (x)))
3252 if (xtensa_simm8 (INTVAL (x))
3253 || xtensa_simm8x256 (INTVAL (x)))
3260 if (xtensa_mask_immediate (INTVAL (x)))
3267 if ((INTVAL (x) == 0) || xtensa_b4const (INTVAL (x)))
3278 /* No way to tell if X is the 2nd operand so be conservative. */
3281 if (xtensa_simm12b (INTVAL (x)))
3283 else if (TARGET_CONST16)
3284 *total = COSTS_N_INSNS (2);
3293 *total = COSTS_N_INSNS (2);
3300 *total = COSTS_N_INSNS (4);
3308 (GET_MODE_SIZE (GET_MODE (x)) > UNITS_PER_WORD) ? 2 : 1;
3310 if (memory_address_p (GET_MODE (x), XEXP ((x), 0)))
3311 *total = COSTS_N_INSNS (num_words);
3313 *total = COSTS_N_INSNS (2*num_words);
3319 *total = COSTS_N_INSNS (TARGET_NSA ? 5 : 50);
3323 *total = COSTS_N_INSNS (TARGET_NSA ? 1 : 50);
3327 *total = COSTS_N_INSNS ((GET_MODE (x) == DImode) ? 3 : 2);
3333 if (GET_MODE (x) == DImode)
3334 *total = COSTS_N_INSNS (2);
3336 *total = COSTS_N_INSNS (1);
3342 if (GET_MODE (x) == DImode)
3343 *total = COSTS_N_INSNS (50);
3345 *total = COSTS_N_INSNS (1);
3350 enum machine_mode xmode = GET_MODE (x);
3351 if (xmode == SFmode)
3352 *total = COSTS_N_INSNS (TARGET_HARD_FLOAT ? 1 : 50);
3353 else if (xmode == DFmode)
3354 *total = COSTS_N_INSNS (50);
3356 *total = COSTS_N_INSNS (4);
3363 enum machine_mode xmode = GET_MODE (x);
3364 if (xmode == SFmode)
3365 *total = COSTS_N_INSNS (TARGET_HARD_FLOAT ? 1 : 50);
3366 else if (xmode == DFmode || xmode == DImode)
3367 *total = COSTS_N_INSNS (50);
3369 *total = COSTS_N_INSNS (1);
3374 *total = COSTS_N_INSNS ((GET_MODE (x) == DImode) ? 4 : 2);
3379 enum machine_mode xmode = GET_MODE (x);
3380 if (xmode == SFmode)
3381 *total = COSTS_N_INSNS (TARGET_HARD_FLOAT ? 4 : 50);
3382 else if (xmode == DFmode)
3383 *total = COSTS_N_INSNS (50);
3384 else if (xmode == DImode)
3385 *total = COSTS_N_INSNS (TARGET_MUL32_HIGH ? 10 : 50);
3386 else if (TARGET_MUL32)
3387 *total = COSTS_N_INSNS (4);
3388 else if (TARGET_MAC16)
3389 *total = COSTS_N_INSNS (16);
3390 else if (TARGET_MUL16)
3391 *total = COSTS_N_INSNS (12);
3393 *total = COSTS_N_INSNS (50);
3400 enum machine_mode xmode = GET_MODE (x);
3401 if (xmode == SFmode)
3403 *total = COSTS_N_INSNS (TARGET_HARD_FLOAT_DIV ? 8 : 50);
3406 else if (xmode == DFmode)
3408 *total = COSTS_N_INSNS (50);
3417 enum machine_mode xmode = GET_MODE (x);
3418 if (xmode == DImode)
3419 *total = COSTS_N_INSNS (50);
3420 else if (TARGET_DIV32)
3421 *total = COSTS_N_INSNS (32);
3423 *total = COSTS_N_INSNS (50);
3428 if (GET_MODE (x) == SFmode)
3429 *total = COSTS_N_INSNS (TARGET_HARD_FLOAT_SQRT ? 8 : 50);
3431 *total = COSTS_N_INSNS (50);
3438 *total = COSTS_N_INSNS (TARGET_MINMAX ? 1 : 50);
3443 *total = COSTS_N_INSNS (TARGET_SEXT ? 1 : 2);
3448 *total = COSTS_N_INSNS (1);
3456 /* Worker function for TARGET_RETURN_IN_MEMORY. */
3459 xtensa_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED)
3461 return ((unsigned HOST_WIDE_INT) int_size_in_bytes (type)
3462 > 4 * UNITS_PER_WORD);
3465 /* Worker function for TARGET_FUNCTION_VALUE. */
3468 xtensa_function_value (const_tree valtype, const_tree func ATTRIBUTE_UNUSED,
3471 return gen_rtx_REG ((INTEGRAL_TYPE_P (valtype)
3472 && TYPE_PRECISION (valtype) < BITS_PER_WORD)
3473 ? SImode : TYPE_MODE (valtype),
3474 outgoing ? GP_OUTGOING_RETURN : GP_RETURN);
3477 /* The static chain is passed in memory. Provide rtx giving 'mem'
3478 expressions that denote where they are stored. */
3481 xtensa_static_chain (const_tree ARG_UNUSED (fndecl), bool incoming_p)
3483 rtx base = incoming_p ? arg_pointer_rtx : stack_pointer_rtx;
3484 return gen_frame_mem (Pmode, plus_constant (base, -5 * UNITS_PER_WORD));
3488 /* TRAMPOLINE_TEMPLATE: For Xtensa, the trampoline must perform an ENTRY
3489 instruction with a minimal stack frame in order to get some free
3490 registers. Once the actual call target is known, the proper stack frame
3491 size is extracted from the ENTRY instruction at the target and the
3492 current frame is adjusted to match. The trampoline then transfers
3493 control to the instruction following the ENTRY at the target. Note:
3494 this assumes that the target begins with an ENTRY instruction. */
3497 xtensa_asm_trampoline_template (FILE *stream)
3499 bool use_call0 = (TARGET_CONST16 || TARGET_ABSOLUTE_LITERALS);
3501 fprintf (stream, "\t.begin no-transform\n");
3502 fprintf (stream, "\tentry\tsp, %d\n", MIN_FRAME_SIZE);
3506 /* Save the return address. */
3507 fprintf (stream, "\tmov\ta10, a0\n");
3509 /* Use a CALL0 instruction to skip past the constants and in the
3510 process get the PC into A0. This allows PC-relative access to
3511 the constants without relying on L32R. */
3512 fprintf (stream, "\tcall0\t.Lskipconsts\n");
3515 fprintf (stream, "\tj\t.Lskipconsts\n");
3517 fprintf (stream, "\t.align\t4\n");
3518 fprintf (stream, ".Lchainval:%s0\n", integer_asm_op (4, TRUE));
3519 fprintf (stream, ".Lfnaddr:%s0\n", integer_asm_op (4, TRUE));
3520 fprintf (stream, ".Lskipconsts:\n");
3522 /* Load the static chain and function address from the trampoline. */
3525 fprintf (stream, "\taddi\ta0, a0, 3\n");
3526 fprintf (stream, "\tl32i\ta9, a0, 0\n");
3527 fprintf (stream, "\tl32i\ta8, a0, 4\n");
3531 fprintf (stream, "\tl32r\ta9, .Lchainval\n");
3532 fprintf (stream, "\tl32r\ta8, .Lfnaddr\n");
3535 /* Store the static chain. */
3536 fprintf (stream, "\ts32i\ta9, sp, %d\n", MIN_FRAME_SIZE - 20);
3538 /* Set the proper stack pointer value. */
3539 fprintf (stream, "\tl32i\ta9, a8, 0\n");
3540 fprintf (stream, "\textui\ta9, a9, %d, 12\n",
3541 TARGET_BIG_ENDIAN ? 8 : 12);
3542 fprintf (stream, "\tslli\ta9, a9, 3\n");
3543 fprintf (stream, "\taddi\ta9, a9, %d\n", -MIN_FRAME_SIZE);
3544 fprintf (stream, "\tsub\ta9, sp, a9\n");
3545 fprintf (stream, "\tmovsp\tsp, a9\n");
3548 /* Restore the return address. */
3549 fprintf (stream, "\tmov\ta0, a10\n");
3551 /* Jump to the instruction following the ENTRY. */
3552 fprintf (stream, "\taddi\ta8, a8, 3\n");
3553 fprintf (stream, "\tjx\ta8\n");
3555 /* Pad size to a multiple of TRAMPOLINE_ALIGNMENT. */
3557 fprintf (stream, "\t.byte\t0\n");
3559 fprintf (stream, "\tnop\n");
3561 fprintf (stream, "\t.end no-transform\n");
3565 xtensa_trampoline_init (rtx m_tramp, tree fndecl, rtx chain)
3567 rtx func = XEXP (DECL_RTL (fndecl), 0);
3568 bool use_call0 = (TARGET_CONST16 || TARGET_ABSOLUTE_LITERALS);
3569 int chain_off = use_call0 ? 12 : 8;
3570 int func_off = use_call0 ? 16 : 12;
3572 emit_block_move (m_tramp, assemble_trampoline_template (),
3573 GEN_INT (TRAMPOLINE_SIZE), BLOCK_OP_NORMAL);
3575 emit_move_insn (adjust_address (m_tramp, SImode, chain_off), chain);
3576 emit_move_insn (adjust_address (m_tramp, SImode, func_off), func);
3577 emit_library_call (gen_rtx_SYMBOL_REF (Pmode, "__xtensa_sync_caches"),
3578 0, VOIDmode, 1, XEXP (m_tramp, 0), Pmode);
3582 #include "gt-xtensa.h"