1 /* Subroutines for insn-output.c for Tensilica's Xtensa architecture.
2 Copyright 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
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"
31 #include "insn-config.h"
32 #include "conditions.h"
33 #include "insn-flags.h"
34 #include "insn-attr.h"
35 #include "insn-codes.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 /* Cached operands, and operator to compare for use in set/branch on
78 /* what type of branch to use */
79 enum cmp_type branch_type;
81 /* Array giving truth value on whether or not a given hard register
82 can support a given mode. */
83 char xtensa_hard_regno_mode_ok[(int) MAX_MACHINE_MODE][FIRST_PSEUDO_REGISTER];
85 /* Current frame size calculated by compute_frame_size. */
86 unsigned xtensa_current_frame_size;
88 /* Largest block move to handle in-line. */
89 #define LARGEST_MOVE_RATIO 15
91 /* Define the structure for the machine field in struct function. */
92 struct machine_function GTY(())
94 int accesses_prev_frame;
98 rtx set_frame_ptr_insn;
101 /* Vector, indexed by hard register number, which contains 1 for a
102 register that is allowable in a candidate for leaf function
105 const char xtensa_leaf_regs[FIRST_PSEUDO_REGISTER] =
107 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
109 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
113 /* Map hard register number to register class */
114 const enum reg_class xtensa_regno_to_class[FIRST_PSEUDO_REGISTER] =
116 RL_REGS, SP_REG, RL_REGS, RL_REGS,
117 RL_REGS, RL_REGS, RL_REGS, GR_REGS,
118 RL_REGS, RL_REGS, RL_REGS, RL_REGS,
119 RL_REGS, RL_REGS, RL_REGS, RL_REGS,
120 AR_REGS, AR_REGS, BR_REGS,
121 FP_REGS, FP_REGS, FP_REGS, FP_REGS,
122 FP_REGS, FP_REGS, FP_REGS, FP_REGS,
123 FP_REGS, FP_REGS, FP_REGS, FP_REGS,
124 FP_REGS, FP_REGS, FP_REGS, FP_REGS,
128 static enum internal_test map_test_to_internal_test (enum rtx_code);
129 static rtx gen_int_relational (enum rtx_code, rtx, rtx, int *);
130 static rtx gen_float_relational (enum rtx_code, rtx, rtx);
131 static rtx gen_conditional_move (rtx);
132 static rtx fixup_subreg_mem (rtx);
133 static struct machine_function * xtensa_init_machine_status (void);
134 static rtx xtensa_legitimize_tls_address (rtx);
135 static bool xtensa_return_in_msb (const_tree);
136 static void printx (FILE *, signed int);
137 static void xtensa_function_epilogue (FILE *, HOST_WIDE_INT);
138 static rtx xtensa_builtin_saveregs (void);
139 static unsigned int xtensa_multibss_section_type_flags (tree, const char *,
140 int) ATTRIBUTE_UNUSED;
141 static section *xtensa_select_rtx_section (enum machine_mode, rtx,
142 unsigned HOST_WIDE_INT);
143 static bool xtensa_rtx_costs (rtx, int, int, int *, bool);
144 static tree xtensa_build_builtin_va_list (void);
145 static bool xtensa_return_in_memory (const_tree, const_tree);
146 static tree xtensa_gimplify_va_arg_expr (tree, tree, gimple_seq *,
148 static rtx xtensa_function_value (const_tree, const_tree, bool);
149 static void xtensa_init_builtins (void);
150 static tree xtensa_fold_builtin (tree, tree, bool);
151 static rtx xtensa_expand_builtin (tree, rtx, rtx, enum machine_mode, int);
152 static void xtensa_va_start (tree, rtx);
154 static const int reg_nonleaf_alloc_order[FIRST_PSEUDO_REGISTER] =
158 /* This macro generates the assembly code for function exit,
159 on machines that need it. If FUNCTION_EPILOGUE is not defined
160 then individual return instructions are generated for each
161 return statement. Args are same as for FUNCTION_PROLOGUE. */
163 #undef TARGET_ASM_FUNCTION_EPILOGUE
164 #define TARGET_ASM_FUNCTION_EPILOGUE xtensa_function_epilogue
166 /* These hooks specify assembly directives for creating certain kinds
167 of integer object. */
169 #undef TARGET_ASM_ALIGNED_SI_OP
170 #define TARGET_ASM_ALIGNED_SI_OP "\t.word\t"
172 #undef TARGET_ASM_SELECT_RTX_SECTION
173 #define TARGET_ASM_SELECT_RTX_SECTION xtensa_select_rtx_section
175 #undef TARGET_DEFAULT_TARGET_FLAGS
176 #define TARGET_DEFAULT_TARGET_FLAGS (TARGET_DEFAULT | MASK_FUSED_MADD)
178 #undef TARGET_RTX_COSTS
179 #define TARGET_RTX_COSTS xtensa_rtx_costs
180 #undef TARGET_ADDRESS_COST
181 #define TARGET_ADDRESS_COST hook_int_rtx_bool_0
183 #undef TARGET_BUILD_BUILTIN_VA_LIST
184 #define TARGET_BUILD_BUILTIN_VA_LIST xtensa_build_builtin_va_list
186 #undef TARGET_EXPAND_BUILTIN_VA_START
187 #define TARGET_EXPAND_BUILTIN_VA_START xtensa_va_start
189 #undef TARGET_PROMOTE_FUNCTION_ARGS
190 #define TARGET_PROMOTE_FUNCTION_ARGS hook_bool_const_tree_true
191 #undef TARGET_PROMOTE_FUNCTION_RETURN
192 #define TARGET_PROMOTE_FUNCTION_RETURN hook_bool_const_tree_true
193 #undef TARGET_PROMOTE_PROTOTYPES
194 #define TARGET_PROMOTE_PROTOTYPES hook_bool_const_tree_true
196 #undef TARGET_RETURN_IN_MEMORY
197 #define TARGET_RETURN_IN_MEMORY xtensa_return_in_memory
198 #undef TARGET_FUNCTION_VALUE
199 #define TARGET_FUNCTION_VALUE xtensa_function_value
200 #undef TARGET_SPLIT_COMPLEX_ARG
201 #define TARGET_SPLIT_COMPLEX_ARG hook_bool_const_tree_true
202 #undef TARGET_MUST_PASS_IN_STACK
203 #define TARGET_MUST_PASS_IN_STACK must_pass_in_stack_var_size
205 #undef TARGET_EXPAND_BUILTIN_SAVEREGS
206 #define TARGET_EXPAND_BUILTIN_SAVEREGS xtensa_builtin_saveregs
207 #undef TARGET_GIMPLIFY_VA_ARG_EXPR
208 #define TARGET_GIMPLIFY_VA_ARG_EXPR xtensa_gimplify_va_arg_expr
210 #undef TARGET_RETURN_IN_MSB
211 #define TARGET_RETURN_IN_MSB xtensa_return_in_msb
213 #undef TARGET_INIT_BUILTINS
214 #define TARGET_INIT_BUILTINS xtensa_init_builtins
215 #undef TARGET_FOLD_BUILTIN
216 #define TARGET_FOLD_BUILTIN xtensa_fold_builtin
217 #undef TARGET_EXPAND_BUILTIN
218 #define TARGET_EXPAND_BUILTIN xtensa_expand_builtin
220 #undef TARGET_SECONDARY_RELOAD
221 #define TARGET_SECONDARY_RELOAD xtensa_secondary_reload
223 #undef TARGET_HAVE_TLS
224 #define TARGET_HAVE_TLS (TARGET_THREADPTR && HAVE_AS_TLS)
226 #undef TARGET_CANNOT_FORCE_CONST_MEM
227 #define TARGET_CANNOT_FORCE_CONST_MEM xtensa_tls_referenced_p
229 struct gcc_target targetm = TARGET_INITIALIZER;
232 /* Functions to test Xtensa immediate operand validity. */
235 xtensa_simm8 (HOST_WIDE_INT v)
237 return v >= -128 && v <= 127;
242 xtensa_simm8x256 (HOST_WIDE_INT v)
244 return (v & 255) == 0 && (v >= -32768 && v <= 32512);
249 xtensa_simm12b (HOST_WIDE_INT v)
251 return v >= -2048 && v <= 2047;
256 xtensa_uimm8 (HOST_WIDE_INT v)
258 return v >= 0 && v <= 255;
263 xtensa_uimm8x2 (HOST_WIDE_INT v)
265 return (v & 1) == 0 && (v >= 0 && v <= 510);
270 xtensa_uimm8x4 (HOST_WIDE_INT v)
272 return (v & 3) == 0 && (v >= 0 && v <= 1020);
277 xtensa_b4const (HOST_WIDE_INT v)
304 xtensa_b4const_or_zero (HOST_WIDE_INT v)
308 return xtensa_b4const (v);
313 xtensa_b4constu (HOST_WIDE_INT v)
340 xtensa_mask_immediate (HOST_WIDE_INT v)
342 #define MAX_MASK_SIZE 16
345 for (mask_size = 1; mask_size <= MAX_MASK_SIZE; mask_size++)
358 /* This is just like the standard true_regnum() function except that it
359 works even when reg_renumber is not initialized. */
362 xt_true_regnum (rtx x)
364 if (GET_CODE (x) == REG)
367 && REGNO (x) >= FIRST_PSEUDO_REGISTER
368 && reg_renumber[REGNO (x)] >= 0)
369 return reg_renumber[REGNO (x)];
372 if (GET_CODE (x) == SUBREG)
374 int base = xt_true_regnum (SUBREG_REG (x));
375 if (base >= 0 && base < FIRST_PSEUDO_REGISTER)
376 return base + subreg_regno_offset (REGNO (SUBREG_REG (x)),
377 GET_MODE (SUBREG_REG (x)),
378 SUBREG_BYTE (x), GET_MODE (x));
385 xtensa_valid_move (enum machine_mode mode, rtx *operands)
387 /* Either the destination or source must be a register, and the
388 MAC16 accumulator doesn't count. */
390 if (register_operand (operands[0], mode))
392 int dst_regnum = xt_true_regnum (operands[0]);
394 /* The stack pointer can only be assigned with a MOVSP opcode. */
395 if (dst_regnum == STACK_POINTER_REGNUM)
396 return (mode == SImode
397 && register_operand (operands[1], mode)
398 && !ACC_REG_P (xt_true_regnum (operands[1])));
400 if (!ACC_REG_P (dst_regnum))
403 if (register_operand (operands[1], mode))
405 int src_regnum = xt_true_regnum (operands[1]);
406 if (!ACC_REG_P (src_regnum))
414 smalloffset_mem_p (rtx op)
416 if (GET_CODE (op) == MEM)
418 rtx addr = XEXP (op, 0);
419 if (GET_CODE (addr) == REG)
420 return BASE_REG_P (addr, 0);
421 if (GET_CODE (addr) == PLUS)
423 rtx offset = XEXP (addr, 0);
425 if (GET_CODE (offset) != CONST_INT)
426 offset = XEXP (addr, 1);
427 if (GET_CODE (offset) != CONST_INT)
430 val = INTVAL (offset);
431 return (val & 3) == 0 && (val >= 0 && val <= 60);
439 constantpool_address_p (rtx addr)
443 if (GET_CODE (addr) == CONST)
447 /* Only handle (PLUS (SYM, OFFSET)) form. */
448 addr = XEXP (addr, 0);
449 if (GET_CODE (addr) != PLUS)
452 /* Make sure the address is word aligned. */
453 offset = XEXP (addr, 1);
454 if ((GET_CODE (offset) != CONST_INT)
455 || ((INTVAL (offset) & 3) != 0))
458 sym = XEXP (addr, 0);
461 if ((GET_CODE (sym) == SYMBOL_REF)
462 && CONSTANT_POOL_ADDRESS_P (sym))
469 constantpool_mem_p (rtx op)
471 if (GET_CODE (op) == SUBREG)
472 op = SUBREG_REG (op);
473 if (GET_CODE (op) == MEM)
474 return constantpool_address_p (XEXP (op, 0));
479 /* Return TRUE if X is a thread-local symbol. */
482 xtensa_tls_symbol_p (rtx x)
484 if (! TARGET_HAVE_TLS)
487 return GET_CODE (x) == SYMBOL_REF && SYMBOL_REF_TLS_MODEL (x) != 0;
492 xtensa_extend_reg (rtx dst, rtx src)
494 rtx temp = gen_reg_rtx (SImode);
495 rtx shift = GEN_INT (BITS_PER_WORD - GET_MODE_BITSIZE (GET_MODE (src)));
497 /* Generate paradoxical subregs as needed so that the modes match. */
498 src = simplify_gen_subreg (SImode, src, GET_MODE (src), 0);
499 dst = simplify_gen_subreg (SImode, dst, GET_MODE (dst), 0);
501 emit_insn (gen_ashlsi3 (temp, src, shift));
502 emit_insn (gen_ashrsi3 (dst, temp, shift));
507 xtensa_mem_offset (unsigned v, enum machine_mode mode)
512 /* Handle the worst case for block moves. See xtensa_expand_block_move
513 where we emit an optimized block move operation if the block can be
514 moved in < "move_ratio" pieces. The worst case is when the block is
515 aligned but has a size of (3 mod 4) (does this happen?) so that the
516 last piece requires a byte load/store. */
517 return (xtensa_uimm8 (v)
518 && xtensa_uimm8 (v + MOVE_MAX * LARGEST_MOVE_RATIO));
521 return xtensa_uimm8 (v);
524 return xtensa_uimm8x2 (v);
527 return (xtensa_uimm8x4 (v) && xtensa_uimm8x4 (v + 4));
533 return xtensa_uimm8x4 (v);
537 /* Make normal rtx_code into something we can index from an array. */
539 static enum internal_test
540 map_test_to_internal_test (enum rtx_code test_code)
542 enum internal_test test = ITEST_MAX;
547 case EQ: test = ITEST_EQ; break;
548 case NE: test = ITEST_NE; break;
549 case GT: test = ITEST_GT; break;
550 case GE: test = ITEST_GE; break;
551 case LT: test = ITEST_LT; break;
552 case LE: test = ITEST_LE; break;
553 case GTU: test = ITEST_GTU; break;
554 case GEU: test = ITEST_GEU; break;
555 case LTU: test = ITEST_LTU; break;
556 case LEU: test = ITEST_LEU; break;
563 /* Generate the code to compare two integer values. The return value is
564 the comparison expression. */
567 gen_int_relational (enum rtx_code test_code, /* relational test (EQ, etc) */
568 rtx cmp0, /* first operand to compare */
569 rtx cmp1, /* second operand to compare */
570 int *p_invert /* whether branch needs to reverse test */)
574 enum rtx_code test_code; /* test code to use in insn */
575 bool (*const_range_p) (HOST_WIDE_INT); /* range check function */
576 int const_add; /* constant to add (convert LE -> LT) */
577 int reverse_regs; /* reverse registers in test */
578 int invert_const; /* != 0 if invert value if cmp1 is constant */
579 int invert_reg; /* != 0 if invert value if cmp1 is register */
580 int unsignedp; /* != 0 for unsigned comparisons. */
583 static struct cmp_info info[ (int)ITEST_MAX ] = {
585 { EQ, xtensa_b4const_or_zero, 0, 0, 0, 0, 0 }, /* EQ */
586 { NE, xtensa_b4const_or_zero, 0, 0, 0, 0, 0 }, /* NE */
588 { LT, xtensa_b4const_or_zero, 1, 1, 1, 0, 0 }, /* GT */
589 { GE, xtensa_b4const_or_zero, 0, 0, 0, 0, 0 }, /* GE */
590 { LT, xtensa_b4const_or_zero, 0, 0, 0, 0, 0 }, /* LT */
591 { GE, xtensa_b4const_or_zero, 1, 1, 1, 0, 0 }, /* LE */
593 { LTU, xtensa_b4constu, 1, 1, 1, 0, 1 }, /* GTU */
594 { GEU, xtensa_b4constu, 0, 0, 0, 0, 1 }, /* GEU */
595 { LTU, xtensa_b4constu, 0, 0, 0, 0, 1 }, /* LTU */
596 { GEU, xtensa_b4constu, 1, 1, 1, 0, 1 }, /* LEU */
599 enum internal_test test;
600 enum machine_mode mode;
601 struct cmp_info *p_info;
603 test = map_test_to_internal_test (test_code);
604 gcc_assert (test != ITEST_MAX);
606 p_info = &info[ (int)test ];
608 mode = GET_MODE (cmp0);
609 if (mode == VOIDmode)
610 mode = GET_MODE (cmp1);
612 /* Make sure we can handle any constants given to us. */
613 if (GET_CODE (cmp1) == CONST_INT)
615 HOST_WIDE_INT value = INTVAL (cmp1);
616 unsigned HOST_WIDE_INT uvalue = (unsigned HOST_WIDE_INT)value;
618 /* if the immediate overflows or does not fit in the immediate field,
619 spill it to a register */
621 if ((p_info->unsignedp ?
622 (uvalue + p_info->const_add > uvalue) :
623 (value + p_info->const_add > value)) != (p_info->const_add > 0))
625 cmp1 = force_reg (mode, cmp1);
627 else if (!(p_info->const_range_p) (value + p_info->const_add))
629 cmp1 = force_reg (mode, cmp1);
632 else if ((GET_CODE (cmp1) != REG) && (GET_CODE (cmp1) != SUBREG))
634 cmp1 = force_reg (mode, cmp1);
637 /* See if we need to invert the result. */
638 *p_invert = ((GET_CODE (cmp1) == CONST_INT)
639 ? p_info->invert_const
640 : p_info->invert_reg);
642 /* Comparison to constants, may involve adding 1 to change a LT into LE.
643 Comparison between two registers, may involve switching operands. */
644 if (GET_CODE (cmp1) == CONST_INT)
646 if (p_info->const_add != 0)
647 cmp1 = GEN_INT (INTVAL (cmp1) + p_info->const_add);
650 else if (p_info->reverse_regs)
657 return gen_rtx_fmt_ee (p_info->test_code, VOIDmode, cmp0, cmp1);
661 /* Generate the code to compare two float values. The return value is
662 the comparison expression. */
665 gen_float_relational (enum rtx_code test_code, /* relational test (EQ, etc) */
666 rtx cmp0, /* first operand to compare */
667 rtx cmp1 /* second operand to compare */)
669 rtx (*gen_fn) (rtx, rtx, rtx);
671 int reverse_regs, invert;
675 case EQ: reverse_regs = 0; invert = 0; gen_fn = gen_seq_sf; break;
676 case NE: reverse_regs = 0; invert = 1; gen_fn = gen_seq_sf; break;
677 case LE: reverse_regs = 0; invert = 0; gen_fn = gen_sle_sf; break;
678 case GT: reverse_regs = 1; invert = 0; gen_fn = gen_slt_sf; break;
679 case LT: reverse_regs = 0; invert = 0; gen_fn = gen_slt_sf; break;
680 case GE: reverse_regs = 1; invert = 0; gen_fn = gen_sle_sf; break;
681 case UNEQ: reverse_regs = 0; invert = 0; gen_fn = gen_suneq_sf; break;
682 case LTGT: reverse_regs = 0; invert = 1; gen_fn = gen_suneq_sf; break;
683 case UNLE: reverse_regs = 0; invert = 0; gen_fn = gen_sunle_sf; break;
684 case UNGT: reverse_regs = 1; invert = 0; gen_fn = gen_sunlt_sf; break;
685 case UNLT: reverse_regs = 0; invert = 0; gen_fn = gen_sunlt_sf; break;
686 case UNGE: reverse_regs = 1; invert = 0; gen_fn = gen_sunle_sf; break;
688 reverse_regs = 0; invert = 0; gen_fn = gen_sunordered_sf; break;
690 reverse_regs = 0; invert = 1; gen_fn = gen_sunordered_sf; break;
692 fatal_insn ("bad test", gen_rtx_fmt_ee (test_code, VOIDmode, cmp0, cmp1));
693 reverse_regs = 0; invert = 0; gen_fn = 0; /* avoid compiler warnings */
703 brtmp = gen_rtx_REG (CCmode, FPCC_REGNUM);
704 emit_insn (gen_fn (brtmp, cmp0, cmp1));
706 return gen_rtx_fmt_ee (invert ? EQ : NE, VOIDmode, brtmp, const0_rtx);
711 xtensa_expand_conditional_branch (rtx *operands, enum rtx_code test_code)
713 enum cmp_type type = branch_type;
714 rtx cmp0 = branch_cmp[0];
715 rtx cmp1 = branch_cmp[1];
724 fatal_insn ("bad test", gen_rtx_fmt_ee (test_code, VOIDmode, cmp0, cmp1));
728 cmp = gen_int_relational (test_code, cmp0, cmp1, &invert);
732 if (!TARGET_HARD_FLOAT)
733 fatal_insn ("bad test", gen_rtx_fmt_ee (test_code, VOIDmode,
736 cmp = gen_float_relational (test_code, cmp0, cmp1);
740 /* Generate the branch. */
742 label1 = gen_rtx_LABEL_REF (VOIDmode, operands[0]);
751 emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
752 gen_rtx_IF_THEN_ELSE (VOIDmode, cmp,
759 gen_conditional_move (rtx cmp)
761 enum rtx_code code = GET_CODE (cmp);
762 rtx op0 = branch_cmp[0];
763 rtx op1 = branch_cmp[1];
765 if (branch_type == CMP_SI)
767 /* Jump optimization calls get_condition() which canonicalizes
768 comparisons like (GE x <const>) to (GT x <const-1>).
769 Transform those comparisons back to GE, since that is the
770 comparison supported in Xtensa. We shouldn't have to
771 transform <LE x const> comparisons, because neither
772 xtensa_expand_conditional_branch() nor get_condition() will
775 if ((code == GT) && (op1 == constm1_rtx))
780 cmp = gen_rtx_fmt_ee (code, VOIDmode, cc0_rtx, const0_rtx);
782 if (boolean_operator (cmp, VOIDmode))
784 /* Swap the operands to make const0 second. */
785 if (op0 == const0_rtx)
791 /* If not comparing against zero, emit a comparison (subtract). */
792 if (op1 != const0_rtx)
794 op0 = expand_binop (SImode, sub_optab, op0, op1,
795 0, 0, OPTAB_LIB_WIDEN);
799 else if (branch_operator (cmp, VOIDmode))
801 /* Swap the operands to make const0 second. */
802 if (op0 == const0_rtx)
809 case LT: code = GE; break;
810 case GE: code = LT; break;
811 default: gcc_unreachable ();
815 if (op1 != const0_rtx)
821 return gen_rtx_fmt_ee (code, VOIDmode, op0, op1);
824 if (TARGET_HARD_FLOAT && (branch_type == CMP_SF))
825 return gen_float_relational (code, op0, op1);
832 xtensa_expand_conditional_move (rtx *operands, int isflt)
835 rtx (*gen_fn) (rtx, rtx, rtx, rtx, rtx);
837 if (!(cmp = gen_conditional_move (operands[1])))
841 gen_fn = (branch_type == CMP_SI
842 ? gen_movsfcc_internal0
843 : gen_movsfcc_internal1);
845 gen_fn = (branch_type == CMP_SI
846 ? gen_movsicc_internal0
847 : gen_movsicc_internal1);
849 emit_insn (gen_fn (operands[0], XEXP (cmp, 0),
850 operands[2], operands[3], cmp));
856 xtensa_expand_scc (rtx *operands)
858 rtx dest = operands[0];
859 rtx cmp = operands[1];
860 rtx one_tmp, zero_tmp;
861 rtx (*gen_fn) (rtx, rtx, rtx, rtx, rtx);
863 if (!(cmp = gen_conditional_move (cmp)))
866 one_tmp = gen_reg_rtx (SImode);
867 zero_tmp = gen_reg_rtx (SImode);
868 emit_insn (gen_movsi (one_tmp, const_true_rtx));
869 emit_insn (gen_movsi (zero_tmp, const0_rtx));
871 gen_fn = (branch_type == CMP_SI
872 ? gen_movsicc_internal0
873 : gen_movsicc_internal1);
874 emit_insn (gen_fn (dest, XEXP (cmp, 0), one_tmp, zero_tmp, cmp));
879 /* Split OP[1] into OP[2,3] and likewise for OP[0] into OP[0,1]. MODE is
880 for the output, i.e., the input operands are twice as big as MODE. */
883 xtensa_split_operand_pair (rtx operands[4], enum machine_mode mode)
885 switch (GET_CODE (operands[1]))
888 operands[3] = gen_rtx_REG (mode, REGNO (operands[1]) + 1);
889 operands[2] = gen_rtx_REG (mode, REGNO (operands[1]));
893 operands[3] = adjust_address (operands[1], mode, GET_MODE_SIZE (mode));
894 operands[2] = adjust_address (operands[1], mode, 0);
899 split_double (operands[1], &operands[2], &operands[3]);
906 switch (GET_CODE (operands[0]))
909 operands[1] = gen_rtx_REG (mode, REGNO (operands[0]) + 1);
910 operands[0] = gen_rtx_REG (mode, REGNO (operands[0]));
914 operands[1] = adjust_address (operands[0], mode, GET_MODE_SIZE (mode));
915 operands[0] = adjust_address (operands[0], mode, 0);
924 /* Emit insns to move operands[1] into operands[0].
925 Return 1 if we have written out everything that needs to be done to
926 do the move. Otherwise, return 0 and the caller will emit the move
930 xtensa_emit_move_sequence (rtx *operands, enum machine_mode mode)
932 rtx src = operands[1];
935 && (GET_CODE (src) != CONST_INT || ! xtensa_simm12b (INTVAL (src))))
937 rtx dst = operands[0];
939 if (xtensa_tls_referenced_p (src))
943 if (GET_CODE (src) == CONST && GET_CODE (XEXP (src, 0)) == PLUS)
945 addend = XEXP (XEXP (src, 0), 1);
946 src = XEXP (XEXP (src, 0), 0);
949 src = xtensa_legitimize_tls_address (src);
952 src = gen_rtx_PLUS (mode, src, addend);
953 src = force_operand (src, dst);
955 emit_move_insn (dst, src);
959 if (! TARGET_CONST16)
961 src = force_const_mem (SImode, src);
965 /* PC-relative loads are always SImode, and CONST16 is only
966 supported in the movsi pattern, so add a SUBREG for any other
971 if (register_operand (dst, mode))
973 emit_move_insn (simplify_gen_subreg (SImode, dst, mode, 0), src);
978 src = force_reg (SImode, src);
979 src = gen_lowpart_SUBREG (mode, src);
985 if (!(reload_in_progress | reload_completed)
986 && !xtensa_valid_move (mode, operands))
987 operands[1] = force_reg (mode, operands[1]);
989 operands[1] = xtensa_copy_incoming_a7 (operands[1]);
991 /* During reload we don't want to emit (subreg:X (mem:Y)) since that
992 instruction won't be recognized after reload, so we remove the
993 subreg and adjust mem accordingly. */
994 if (reload_in_progress)
996 operands[0] = fixup_subreg_mem (operands[0]);
997 operands[1] = fixup_subreg_mem (operands[1]);
1004 fixup_subreg_mem (rtx x)
1006 if (GET_CODE (x) == SUBREG
1007 && GET_CODE (SUBREG_REG (x)) == REG
1008 && REGNO (SUBREG_REG (x)) >= FIRST_PSEUDO_REGISTER)
1011 gen_rtx_SUBREG (GET_MODE (x),
1012 reg_equiv_mem [REGNO (SUBREG_REG (x))],
1014 x = alter_subreg (&temp);
1020 /* Check if an incoming argument in a7 is expected to be used soon and
1021 if OPND is a register or register pair that includes a7. If so,
1022 create a new pseudo and copy a7 into that pseudo at the very
1023 beginning of the function, followed by the special "set_frame_ptr"
1024 unspec_volatile insn. The return value is either the original
1025 operand, if it is not a7, or the new pseudo containing a copy of
1026 the incoming argument. This is necessary because the register
1027 allocator will ignore conflicts with a7 and may either assign some
1028 other pseudo to a7 or use a7 as the hard_frame_pointer, clobbering
1029 the incoming argument in a7. By copying the argument out of a7 as
1030 the very first thing, and then immediately following that with an
1031 unspec_volatile to keep the scheduler away, we should avoid any
1032 problems. Putting the set_frame_ptr insn at the beginning, with
1033 only the a7 copy before it, also makes it easier for the prologue
1034 expander to initialize the frame pointer after the a7 copy and to
1035 fix up the a7 copy to use the stack pointer instead of the frame
1039 xtensa_copy_incoming_a7 (rtx opnd)
1041 rtx entry_insns = 0;
1043 enum machine_mode mode;
1045 if (!cfun->machine->need_a7_copy)
1048 /* This function should never be called again once a7 has been copied. */
1049 gcc_assert (!cfun->machine->set_frame_ptr_insn);
1051 mode = GET_MODE (opnd);
1053 /* The operand using a7 may come in a later instruction, so just return
1054 the original operand if it doesn't use a7. */
1056 if (GET_CODE (reg) == SUBREG)
1058 gcc_assert (SUBREG_BYTE (reg) == 0);
1059 reg = SUBREG_REG (reg);
1061 if (GET_CODE (reg) != REG
1062 || REGNO (reg) > A7_REG
1063 || REGNO (reg) + HARD_REGNO_NREGS (A7_REG, mode) <= A7_REG)
1066 /* 1-word args will always be in a7; 2-word args in a6/a7. */
1067 gcc_assert (REGNO (reg) + HARD_REGNO_NREGS (A7_REG, mode) - 1 == A7_REG);
1069 cfun->machine->need_a7_copy = false;
1071 /* Copy a7 to a new pseudo at the function entry. Use gen_raw_REG to
1072 create the REG for a7 so that hard_frame_pointer_rtx is not used. */
1075 tmp = gen_reg_rtx (mode);
1081 /* Copy the value out of A7 here but keep the first word in A6 until
1082 after the set_frame_ptr insn. Otherwise, the register allocator
1083 may decide to put "subreg (tmp, 0)" in A7 and clobber the incoming
1085 emit_insn (gen_movsi_internal (gen_rtx_SUBREG (SImode, tmp, 4),
1086 gen_raw_REG (SImode, A7_REG)));
1089 emit_insn (gen_movsf_internal (tmp, gen_raw_REG (mode, A7_REG)));
1092 emit_insn (gen_movsi_internal (tmp, gen_raw_REG (mode, A7_REG)));
1095 emit_insn (gen_movhi_internal (tmp, gen_raw_REG (mode, A7_REG)));
1098 emit_insn (gen_movqi_internal (tmp, gen_raw_REG (mode, A7_REG)));
1104 cfun->machine->set_frame_ptr_insn = emit_insn (gen_set_frame_ptr ());
1106 /* For DF and DI mode arguments, copy the incoming value in A6 now. */
1107 if (mode == DFmode || mode == DImode)
1108 emit_insn (gen_movsi_internal (gen_rtx_SUBREG (SImode, tmp, 0),
1109 gen_rtx_REG (SImode, A7_REG - 1)));
1110 entry_insns = get_insns ();
1113 if (cfun->machine->vararg_a7)
1115 /* This is called from within builtin_saveregs, which will insert the
1116 saveregs code at the function entry, ahead of anything placed at
1117 the function entry now. Instead, save the sequence to be inserted
1118 at the beginning of the saveregs code. */
1119 cfun->machine->vararg_a7_copy = entry_insns;
1123 /* Put entry_insns after the NOTE that starts the function. If
1124 this is inside a start_sequence, make the outer-level insn
1125 chain current, so the code is placed at the start of the
1127 push_topmost_sequence ();
1128 /* Do not use entry_of_function() here. This is called from within
1129 expand_function_start, when the CFG still holds GIMPLE. */
1130 emit_insn_after (entry_insns, get_insns ());
1131 pop_topmost_sequence ();
1138 /* Try to expand a block move operation to a sequence of RTL move
1139 instructions. If not optimizing, or if the block size is not a
1140 constant, or if the block is too large, the expansion fails and GCC
1141 falls back to calling memcpy().
1143 operands[0] is the destination
1144 operands[1] is the source
1145 operands[2] is the length
1146 operands[3] is the alignment */
1149 xtensa_expand_block_move (rtx *operands)
1151 static const enum machine_mode mode_from_align[] =
1153 VOIDmode, QImode, HImode, VOIDmode, SImode,
1156 rtx dst_mem = operands[0];
1157 rtx src_mem = operands[1];
1158 HOST_WIDE_INT bytes, align;
1159 int num_pieces, move_ratio;
1161 enum machine_mode mode[2];
1170 /* If this is not a fixed size move, just call memcpy. */
1171 if (!optimize || (GET_CODE (operands[2]) != CONST_INT))
1174 bytes = INTVAL (operands[2]);
1175 align = INTVAL (operands[3]);
1177 /* Anything to move? */
1181 if (align > MOVE_MAX)
1184 /* Decide whether to expand inline based on the optimization level. */
1187 move_ratio = LARGEST_MOVE_RATIO;
1188 num_pieces = (bytes / align) + (bytes % align); /* Close enough anyway. */
1189 if (num_pieces > move_ratio)
1192 x = XEXP (dst_mem, 0);
1195 x = force_reg (Pmode, x);
1196 dst_mem = replace_equiv_address (dst_mem, x);
1199 x = XEXP (src_mem, 0);
1202 x = force_reg (Pmode, x);
1203 src_mem = replace_equiv_address (src_mem, x);
1206 active[0] = active[1] = false;
1217 next_amount = (bytes >= 4 ? 4 : (bytes >= 2 ? 2 : 1));
1218 next_amount = MIN (next_amount, align);
1220 amount[next] = next_amount;
1221 mode[next] = mode_from_align[next_amount];
1222 temp[next] = gen_reg_rtx (mode[next]);
1224 x = adjust_address (src_mem, mode[next], offset_ld);
1225 emit_insn (gen_rtx_SET (VOIDmode, temp[next], x));
1227 offset_ld += next_amount;
1228 bytes -= next_amount;
1229 active[next] = true;
1234 active[phase] = false;
1236 x = adjust_address (dst_mem, mode[phase], offset_st);
1237 emit_insn (gen_rtx_SET (VOIDmode, x, temp[phase]));
1239 offset_st += amount[phase];
1242 while (active[next]);
1249 xtensa_expand_nonlocal_goto (rtx *operands)
1251 rtx goto_handler = operands[1];
1252 rtx containing_fp = operands[3];
1254 /* Generate a call to "__xtensa_nonlocal_goto" (in libgcc); the code
1255 is too big to generate in-line. */
1257 if (GET_CODE (containing_fp) != REG)
1258 containing_fp = force_reg (Pmode, containing_fp);
1260 emit_library_call (gen_rtx_SYMBOL_REF (Pmode, "__xtensa_nonlocal_goto"),
1262 containing_fp, Pmode,
1263 goto_handler, Pmode);
1267 static struct machine_function *
1268 xtensa_init_machine_status (void)
1270 return GGC_CNEW (struct machine_function);
1274 /* Shift VAL of mode MODE left by COUNT bits. */
1277 xtensa_expand_mask_and_shift (rtx val, enum machine_mode mode, rtx count)
1279 val = expand_simple_binop (SImode, AND, val, GEN_INT (GET_MODE_MASK (mode)),
1280 NULL_RTX, 1, OPTAB_DIRECT);
1281 return expand_simple_binop (SImode, ASHIFT, val, count,
1282 NULL_RTX, 1, OPTAB_DIRECT);
1286 /* Structure to hold the initial parameters for a compare_and_swap operation
1287 in HImode and QImode. */
1289 struct alignment_context
1291 rtx memsi; /* SI aligned memory location. */
1292 rtx shift; /* Bit offset with regard to lsb. */
1293 rtx modemask; /* Mask of the HQImode shifted by SHIFT bits. */
1294 rtx modemaski; /* ~modemask */
1298 /* Initialize structure AC for word access to HI and QI mode memory. */
1301 init_alignment_context (struct alignment_context *ac, rtx mem)
1303 enum machine_mode mode = GET_MODE (mem);
1304 rtx byteoffset = NULL_RTX;
1305 bool aligned = (MEM_ALIGN (mem) >= GET_MODE_BITSIZE (SImode));
1308 ac->memsi = adjust_address (mem, SImode, 0); /* Memory is aligned. */
1311 /* Alignment is unknown. */
1314 /* Force the address into a register. */
1315 addr = force_reg (Pmode, XEXP (mem, 0));
1317 /* Align it to SImode. */
1318 align = expand_simple_binop (Pmode, AND, addr,
1319 GEN_INT (-GET_MODE_SIZE (SImode)),
1320 NULL_RTX, 1, OPTAB_DIRECT);
1322 ac->memsi = gen_rtx_MEM (SImode, align);
1323 MEM_VOLATILE_P (ac->memsi) = MEM_VOLATILE_P (mem);
1324 set_mem_alias_set (ac->memsi, ALIAS_SET_MEMORY_BARRIER);
1325 set_mem_align (ac->memsi, GET_MODE_BITSIZE (SImode));
1327 byteoffset = expand_simple_binop (Pmode, AND, addr,
1328 GEN_INT (GET_MODE_SIZE (SImode) - 1),
1329 NULL_RTX, 1, OPTAB_DIRECT);
1332 /* Calculate shiftcount. */
1333 if (TARGET_BIG_ENDIAN)
1335 ac->shift = GEN_INT (GET_MODE_SIZE (SImode) - GET_MODE_SIZE (mode));
1337 ac->shift = expand_simple_binop (SImode, MINUS, ac->shift, byteoffset,
1338 NULL_RTX, 1, OPTAB_DIRECT);
1343 ac->shift = NULL_RTX;
1345 ac->shift = byteoffset;
1348 if (ac->shift != NULL_RTX)
1350 /* Shift is the byte count, but we need the bitcount. */
1351 ac->shift = expand_simple_binop (SImode, MULT, ac->shift,
1352 GEN_INT (BITS_PER_UNIT),
1353 NULL_RTX, 1, OPTAB_DIRECT);
1354 ac->modemask = expand_simple_binop (SImode, ASHIFT,
1355 GEN_INT (GET_MODE_MASK (mode)),
1357 NULL_RTX, 1, OPTAB_DIRECT);
1360 ac->modemask = GEN_INT (GET_MODE_MASK (mode));
1362 ac->modemaski = expand_simple_unop (SImode, NOT, ac->modemask, NULL_RTX, 1);
1366 /* Expand an atomic compare and swap operation for HImode and QImode.
1367 MEM is the memory location, CMP the old value to compare MEM with
1368 and NEW_RTX the value to set if CMP == MEM. */
1371 xtensa_expand_compare_and_swap (rtx target, rtx mem, rtx cmp, rtx new_rtx)
1373 enum machine_mode mode = GET_MODE (mem);
1374 struct alignment_context ac;
1375 rtx tmp, cmpv, newv, val;
1376 rtx oldval = gen_reg_rtx (SImode);
1377 rtx res = gen_reg_rtx (SImode);
1378 rtx csloop = gen_label_rtx ();
1379 rtx csend = gen_label_rtx ();
1381 init_alignment_context (&ac, mem);
1383 if (ac.shift != NULL_RTX)
1385 cmp = xtensa_expand_mask_and_shift (cmp, mode, ac.shift);
1386 new_rtx = xtensa_expand_mask_and_shift (new_rtx, mode, ac.shift);
1389 /* Load the surrounding word into VAL with the MEM value masked out. */
1390 val = force_reg (SImode, expand_simple_binop (SImode, AND, ac.memsi,
1391 ac.modemaski, NULL_RTX, 1,
1393 emit_label (csloop);
1395 /* Patch CMP and NEW_RTX into VAL at correct position. */
1396 cmpv = force_reg (SImode, expand_simple_binop (SImode, IOR, cmp, val,
1397 NULL_RTX, 1, OPTAB_DIRECT));
1398 newv = force_reg (SImode, expand_simple_binop (SImode, IOR, new_rtx, val,
1399 NULL_RTX, 1, OPTAB_DIRECT));
1401 /* Jump to end if we're done. */
1402 emit_insn (gen_sync_compare_and_swapsi (res, ac.memsi, cmpv, newv));
1403 emit_cmp_and_jump_insns (res, cmpv, EQ, const0_rtx, SImode, true, csend);
1405 /* Check for changes outside mode. */
1406 emit_move_insn (oldval, val);
1407 tmp = expand_simple_binop (SImode, AND, res, ac.modemaski,
1408 val, 1, OPTAB_DIRECT);
1410 emit_move_insn (val, tmp);
1412 /* Loop internal if so. */
1413 emit_cmp_and_jump_insns (oldval, val, NE, const0_rtx, SImode, true, csloop);
1417 /* Return the correct part of the bitfield. */
1418 convert_move (target,
1419 (ac.shift == NULL_RTX ? res
1420 : expand_simple_binop (SImode, LSHIFTRT, res, ac.shift,
1421 NULL_RTX, 1, OPTAB_DIRECT)),
1426 /* Expand an atomic operation CODE of mode MODE (either HImode or QImode --
1427 the default expansion works fine for SImode). MEM is the memory location
1428 and VAL the value to play with. If AFTER is true then store the value
1429 MEM holds after the operation, if AFTER is false then store the value MEM
1430 holds before the operation. If TARGET is zero then discard that value, else
1431 store it to TARGET. */
1434 xtensa_expand_atomic (enum rtx_code code, rtx target, rtx mem, rtx val,
1437 enum machine_mode mode = GET_MODE (mem);
1438 struct alignment_context ac;
1439 rtx csloop = gen_label_rtx ();
1441 rtx old = gen_reg_rtx (SImode);
1442 rtx new_rtx = gen_reg_rtx (SImode);
1443 rtx orig = NULL_RTX;
1445 init_alignment_context (&ac, mem);
1447 /* Prepare values before the compare-and-swap loop. */
1448 if (ac.shift != NULL_RTX)
1449 val = xtensa_expand_mask_and_shift (val, mode, ac.shift);
1454 orig = gen_reg_rtx (SImode);
1455 convert_move (orig, val, 1);
1463 case MULT: /* NAND */
1465 /* val = "11..1<val>11..1" */
1466 val = expand_simple_binop (SImode, XOR, val, ac.modemaski,
1467 NULL_RTX, 1, OPTAB_DIRECT);
1474 /* Load full word. Subsequent loads are performed by S32C1I. */
1475 cmp = force_reg (SImode, ac.memsi);
1477 emit_label (csloop);
1478 emit_move_insn (old, cmp);
1484 val = expand_simple_binop (SImode, code, old, orig,
1485 NULL_RTX, 1, OPTAB_DIRECT);
1486 val = expand_simple_binop (SImode, AND, val, ac.modemask,
1487 NULL_RTX, 1, OPTAB_DIRECT);
1490 tmp = expand_simple_binop (SImode, AND, old, ac.modemaski,
1491 NULL_RTX, 1, OPTAB_DIRECT);
1492 tmp = expand_simple_binop (SImode, IOR, tmp, val,
1493 new_rtx, 1, OPTAB_DIRECT);
1499 tmp = expand_simple_binop (SImode, code, old, val,
1500 new_rtx, 1, OPTAB_DIRECT);
1503 case MULT: /* NAND */
1504 tmp = expand_simple_binop (SImode, XOR, old, ac.modemask,
1505 NULL_RTX, 1, OPTAB_DIRECT);
1506 tmp = expand_simple_binop (SImode, AND, tmp, val,
1507 new_rtx, 1, OPTAB_DIRECT);
1515 emit_move_insn (new_rtx, tmp);
1516 emit_insn (gen_sync_compare_and_swapsi (cmp, ac.memsi, old, new_rtx));
1517 emit_cmp_and_jump_insns (cmp, old, NE, const0_rtx, SImode, true, csloop);
1521 tmp = (after ? new_rtx : cmp);
1522 convert_move (target,
1523 (ac.shift == NULL_RTX ? tmp
1524 : expand_simple_binop (SImode, LSHIFTRT, tmp, ac.shift,
1525 NULL_RTX, 1, OPTAB_DIRECT)),
1532 xtensa_setup_frame_addresses (void)
1534 /* Set flag to cause FRAME_POINTER_REQUIRED to be set. */
1535 cfun->machine->accesses_prev_frame = 1;
1538 (gen_rtx_SYMBOL_REF (Pmode, "__xtensa_libgcc_window_spill"),
1543 /* Emit the assembly for the end of a zero-cost loop. Normally we just emit
1544 a comment showing where the end of the loop is. However, if there is a
1545 label or a branch at the end of the loop then we need to place a nop
1546 there. If the loop ends with a label we need the nop so that branches
1547 targeting that label will target the nop (and thus remain in the loop),
1548 instead of targeting the instruction after the loop (and thus exiting
1549 the loop). If the loop ends with a branch, we need the nop in case the
1550 branch is targeting a location inside the loop. When the branch
1551 executes it will cause the loop count to be decremented even if it is
1552 taken (because it is the last instruction in the loop), so we need to
1553 nop after the branch to prevent the loop count from being decremented
1554 when the branch is taken. */
1557 xtensa_emit_loop_end (rtx insn, rtx *operands)
1561 for (insn = PREV_INSN (insn); insn && !done; insn = PREV_INSN (insn))
1563 switch (GET_CODE (insn))
1570 output_asm_insn (TARGET_DENSITY ? "nop.n" : "nop", operands);
1576 rtx body = PATTERN (insn);
1578 if (GET_CODE (body) == JUMP_INSN)
1580 output_asm_insn (TARGET_DENSITY ? "nop.n" : "nop", operands);
1583 else if ((GET_CODE (body) != USE)
1584 && (GET_CODE (body) != CLOBBER))
1591 output_asm_insn ("# loop end for %0", operands);
1596 xtensa_emit_branch (bool inverted, bool immed, rtx *operands)
1598 static char result[64];
1602 code = GET_CODE (operands[3]);
1605 case EQ: op = inverted ? "ne" : "eq"; break;
1606 case NE: op = inverted ? "eq" : "ne"; break;
1607 case LT: op = inverted ? "ge" : "lt"; break;
1608 case GE: op = inverted ? "lt" : "ge"; break;
1609 case LTU: op = inverted ? "geu" : "ltu"; break;
1610 case GEU: op = inverted ? "ltu" : "geu"; break;
1611 default: gcc_unreachable ();
1616 if (INTVAL (operands[1]) == 0)
1617 sprintf (result, "b%sz%s\t%%0, %%2", op,
1618 (TARGET_DENSITY && (code == EQ || code == NE)) ? ".n" : "");
1620 sprintf (result, "b%si\t%%0, %%d1, %%2", op);
1623 sprintf (result, "b%s\t%%0, %%1, %%2", op);
1630 xtensa_emit_bit_branch (bool inverted, bool immed, rtx *operands)
1632 static char result[64];
1635 switch (GET_CODE (operands[3]))
1637 case EQ: op = inverted ? "bs" : "bc"; break;
1638 case NE: op = inverted ? "bc" : "bs"; break;
1639 default: gcc_unreachable ();
1644 unsigned bitnum = INTVAL (operands[1]) & 0x1f;
1645 operands[1] = GEN_INT (bitnum);
1646 sprintf (result, "b%si\t%%0, %%d1, %%2", op);
1649 sprintf (result, "b%s\t%%0, %%1, %%2", op);
1656 xtensa_emit_movcc (bool inverted, bool isfp, bool isbool, rtx *operands)
1658 static char result[64];
1662 code = GET_CODE (operands[4]);
1667 case EQ: op = inverted ? "t" : "f"; break;
1668 case NE: op = inverted ? "f" : "t"; break;
1669 default: gcc_unreachable ();
1676 case EQ: op = inverted ? "nez" : "eqz"; break;
1677 case NE: op = inverted ? "eqz" : "nez"; break;
1678 case LT: op = inverted ? "gez" : "ltz"; break;
1679 case GE: op = inverted ? "ltz" : "gez"; break;
1680 default: gcc_unreachable ();
1684 sprintf (result, "mov%s%s\t%%0, %%%d, %%1",
1685 op, isfp ? ".s" : "", inverted ? 3 : 2);
1691 xtensa_emit_call (int callop, rtx *operands)
1693 static char result[64];
1694 rtx tgt = operands[callop];
1696 if (GET_CODE (tgt) == CONST_INT)
1697 sprintf (result, "call8\t0x%lx", INTVAL (tgt));
1698 else if (register_operand (tgt, VOIDmode))
1699 sprintf (result, "callx8\t%%%d", callop);
1701 sprintf (result, "call8\t%%%d", callop);
1708 xtensa_legitimate_address_p (enum machine_mode mode, rtx addr, bool strict)
1710 /* Allow constant pool addresses. */
1711 if (mode != BLKmode && GET_MODE_SIZE (mode) >= UNITS_PER_WORD
1712 && ! TARGET_CONST16 && constantpool_address_p (addr)
1713 && ! xtensa_tls_referenced_p (addr))
1716 while (GET_CODE (addr) == SUBREG)
1717 addr = SUBREG_REG (addr);
1719 /* Allow base registers. */
1720 if (GET_CODE (addr) == REG && BASE_REG_P (addr, strict))
1723 /* Check for "register + offset" addressing. */
1724 if (GET_CODE (addr) == PLUS)
1726 rtx xplus0 = XEXP (addr, 0);
1727 rtx xplus1 = XEXP (addr, 1);
1728 enum rtx_code code0;
1729 enum rtx_code code1;
1731 while (GET_CODE (xplus0) == SUBREG)
1732 xplus0 = SUBREG_REG (xplus0);
1733 code0 = GET_CODE (xplus0);
1735 while (GET_CODE (xplus1) == SUBREG)
1736 xplus1 = SUBREG_REG (xplus1);
1737 code1 = GET_CODE (xplus1);
1739 /* Swap operands if necessary so the register is first. */
1740 if (code0 != REG && code1 == REG)
1742 xplus0 = XEXP (addr, 1);
1743 xplus1 = XEXP (addr, 0);
1744 code0 = GET_CODE (xplus0);
1745 code1 = GET_CODE (xplus1);
1748 if (code0 == REG && BASE_REG_P (xplus0, strict)
1749 && code1 == CONST_INT
1750 && xtensa_mem_offset (INTVAL (xplus1), mode))
1758 /* Construct the SYMBOL_REF for the _TLS_MODULE_BASE_ symbol. */
1760 static GTY(()) rtx xtensa_tls_module_base_symbol;
1763 xtensa_tls_module_base (void)
1765 if (! xtensa_tls_module_base_symbol)
1767 xtensa_tls_module_base_symbol =
1768 gen_rtx_SYMBOL_REF (Pmode, "_TLS_MODULE_BASE_");
1769 SYMBOL_REF_FLAGS (xtensa_tls_module_base_symbol)
1770 |= TLS_MODEL_GLOBAL_DYNAMIC << SYMBOL_FLAG_TLS_SHIFT;
1773 return xtensa_tls_module_base_symbol;
1778 xtensa_call_tls_desc (rtx sym, rtx *retp)
1780 rtx fn, arg, a10, call_insn, insns;
1783 fn = gen_reg_rtx (Pmode);
1784 arg = gen_reg_rtx (Pmode);
1785 a10 = gen_rtx_REG (Pmode, 10);
1787 emit_insn (gen_tls_func (fn, sym));
1788 emit_insn (gen_tls_arg (arg, sym));
1789 emit_move_insn (a10, arg);
1790 call_insn = emit_call_insn (gen_tls_call (a10, fn, sym, const1_rtx));
1791 CALL_INSN_FUNCTION_USAGE (call_insn)
1792 = gen_rtx_EXPR_LIST (VOIDmode, gen_rtx_USE (VOIDmode, a10),
1793 CALL_INSN_FUNCTION_USAGE (call_insn));
1794 insns = get_insns ();
1803 xtensa_legitimize_tls_address (rtx x)
1805 unsigned int model = SYMBOL_REF_TLS_MODEL (x);
1806 rtx dest, tp, ret, modbase, base, addend, insns;
1808 dest = gen_reg_rtx (Pmode);
1811 case TLS_MODEL_GLOBAL_DYNAMIC:
1812 insns = xtensa_call_tls_desc (x, &ret);
1813 emit_libcall_block (insns, dest, ret, x);
1816 case TLS_MODEL_LOCAL_DYNAMIC:
1817 base = gen_reg_rtx (Pmode);
1818 modbase = xtensa_tls_module_base ();
1819 insns = xtensa_call_tls_desc (modbase, &ret);
1820 emit_libcall_block (insns, base, ret, modbase);
1821 addend = force_reg (SImode, gen_sym_DTPOFF (x));
1822 emit_insn (gen_addsi3 (dest, base, addend));
1825 case TLS_MODEL_INITIAL_EXEC:
1826 case TLS_MODEL_LOCAL_EXEC:
1827 tp = gen_reg_rtx (SImode);
1828 emit_insn (gen_load_tp (tp));
1829 addend = force_reg (SImode, gen_sym_TPOFF (x));
1830 emit_insn (gen_addsi3 (dest, tp, addend));
1842 xtensa_legitimize_address (rtx x,
1843 rtx oldx ATTRIBUTE_UNUSED,
1844 enum machine_mode mode)
1846 if (xtensa_tls_symbol_p (x))
1847 return xtensa_legitimize_tls_address (x);
1849 if (GET_CODE (x) == PLUS)
1851 rtx plus0 = XEXP (x, 0);
1852 rtx plus1 = XEXP (x, 1);
1854 if (GET_CODE (plus0) != REG && GET_CODE (plus1) == REG)
1856 plus0 = XEXP (x, 1);
1857 plus1 = XEXP (x, 0);
1860 /* Try to split up the offset to use an ADDMI instruction. */
1861 if (GET_CODE (plus0) == REG
1862 && GET_CODE (plus1) == CONST_INT
1863 && !xtensa_mem_offset (INTVAL (plus1), mode)
1864 && !xtensa_simm8 (INTVAL (plus1))
1865 && xtensa_mem_offset (INTVAL (plus1) & 0xff, mode)
1866 && xtensa_simm8x256 (INTVAL (plus1) & ~0xff))
1868 rtx temp = gen_reg_rtx (Pmode);
1869 rtx addmi_offset = GEN_INT (INTVAL (plus1) & ~0xff);
1870 emit_insn (gen_rtx_SET (Pmode, temp,
1871 gen_rtx_PLUS (Pmode, plus0, addmi_offset)));
1872 return gen_rtx_PLUS (Pmode, temp, GEN_INT (INTVAL (plus1) & 0xff));
1880 /* Helper for xtensa_tls_referenced_p. */
1883 xtensa_tls_referenced_p_1 (rtx *x, void *data ATTRIBUTE_UNUSED)
1885 if (GET_CODE (*x) == SYMBOL_REF)
1886 return SYMBOL_REF_TLS_MODEL (*x) != 0;
1888 /* Ignore TLS references that have already been legitimized. */
1889 if (GET_CODE (*x) == UNSPEC)
1891 switch (XINT (*x, 1))
1895 case UNSPEC_TLS_FUNC:
1896 case UNSPEC_TLS_ARG:
1897 case UNSPEC_TLS_CALL:
1908 /* Return TRUE if X contains any TLS symbol references. */
1911 xtensa_tls_referenced_p (rtx x)
1913 if (! TARGET_HAVE_TLS)
1916 return for_each_rtx (&x, xtensa_tls_referenced_p_1, NULL);
1920 /* Return the debugger register number to use for 'regno'. */
1923 xtensa_dbx_register_number (int regno)
1927 if (GP_REG_P (regno))
1929 regno -= GP_REG_FIRST;
1932 else if (BR_REG_P (regno))
1934 regno -= BR_REG_FIRST;
1937 else if (FP_REG_P (regno))
1939 regno -= FP_REG_FIRST;
1942 else if (ACC_REG_P (regno))
1944 first = 0x200; /* Start of Xtensa special registers. */
1945 regno = 16; /* ACCLO is special register 16. */
1948 /* When optimizing, we sometimes get asked about pseudo-registers
1949 that don't represent hard registers. Return 0 for these. */
1953 return first + regno;
1957 /* Argument support functions. */
1959 /* Initialize CUMULATIVE_ARGS for a function. */
1962 init_cumulative_args (CUMULATIVE_ARGS *cum, int incoming)
1965 cum->incoming = incoming;
1969 /* Advance the argument to the next argument position. */
1972 function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode, tree type)
1977 arg_words = &cum->arg_words;
1978 max = MAX_ARGS_IN_REGISTERS;
1980 words = (((mode != BLKmode)
1981 ? (int) GET_MODE_SIZE (mode)
1982 : int_size_in_bytes (type)) + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
1984 if (*arg_words < max
1985 && (targetm.calls.must_pass_in_stack (mode, type)
1986 || *arg_words + words > max))
1989 *arg_words += words;
1993 /* Return an RTL expression containing the register for the given mode,
1994 or 0 if the argument is to be passed on the stack. INCOMING_P is nonzero
1995 if this is an incoming argument to the current function. */
1998 function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode, tree type,
2001 int regbase, words, max;
2005 arg_words = &cum->arg_words;
2006 regbase = (incoming_p ? GP_ARG_FIRST : GP_OUTGOING_ARG_FIRST);
2007 max = MAX_ARGS_IN_REGISTERS;
2009 words = (((mode != BLKmode)
2010 ? (int) GET_MODE_SIZE (mode)
2011 : int_size_in_bytes (type)) + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
2013 if (type && (TYPE_ALIGN (type) > BITS_PER_WORD))
2015 int align = MIN (TYPE_ALIGN (type), STACK_BOUNDARY) / BITS_PER_WORD;
2016 *arg_words = (*arg_words + align - 1) & -align;
2019 if (*arg_words + words > max)
2022 regno = regbase + *arg_words;
2024 if (cum->incoming && regno <= A7_REG && regno + words > A7_REG)
2025 cfun->machine->need_a7_copy = true;
2027 return gen_rtx_REG (mode, regno);
2032 function_arg_boundary (enum machine_mode mode, tree type)
2034 unsigned int alignment;
2036 alignment = type ? TYPE_ALIGN (type) : GET_MODE_ALIGNMENT (mode);
2037 if (alignment < PARM_BOUNDARY)
2038 alignment = PARM_BOUNDARY;
2039 if (alignment > STACK_BOUNDARY)
2040 alignment = STACK_BOUNDARY;
2046 xtensa_return_in_msb (const_tree valtype)
2048 return (TARGET_BIG_ENDIAN
2049 && AGGREGATE_TYPE_P (valtype)
2050 && int_size_in_bytes (valtype) >= UNITS_PER_WORD);
2055 override_options (void)
2058 enum machine_mode mode;
2060 if (!TARGET_BOOLEANS && TARGET_HARD_FLOAT)
2061 error ("boolean registers required for the floating-point option");
2063 /* Set up array giving whether a given register can hold a given mode. */
2064 for (mode = VOIDmode;
2065 mode != MAX_MACHINE_MODE;
2066 mode = (enum machine_mode) ((int) mode + 1))
2068 int size = GET_MODE_SIZE (mode);
2069 enum mode_class mclass = GET_MODE_CLASS (mode);
2071 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
2075 if (ACC_REG_P (regno))
2076 temp = (TARGET_MAC16
2077 && (mclass == MODE_INT) && (size <= UNITS_PER_WORD));
2078 else if (GP_REG_P (regno))
2079 temp = ((regno & 1) == 0 || (size <= UNITS_PER_WORD));
2080 else if (FP_REG_P (regno))
2081 temp = (TARGET_HARD_FLOAT && (mode == SFmode));
2082 else if (BR_REG_P (regno))
2083 temp = (TARGET_BOOLEANS && (mode == CCmode));
2087 xtensa_hard_regno_mode_ok[(int) mode][regno] = temp;
2091 init_machine_status = xtensa_init_machine_status;
2093 /* Check PIC settings. PIC is only supported when using L32R
2094 instructions, and some targets need to always use PIC. */
2095 if (flag_pic && TARGET_CONST16)
2096 error ("-f%s is not supported with CONST16 instructions",
2097 (flag_pic > 1 ? "PIC" : "pic"));
2098 else if (XTENSA_ALWAYS_PIC)
2101 error ("PIC is required but not supported with CONST16 instructions");
2104 /* There's no need for -fPIC (as opposed to -fpic) on Xtensa. */
2107 if (flag_pic && !flag_pie)
2110 /* Hot/cold partitioning does not work on this architecture, because of
2111 constant pools (the load instruction cannot necessarily reach that far).
2112 Therefore disable it on this architecture. */
2113 if (flag_reorder_blocks_and_partition)
2115 flag_reorder_blocks_and_partition = 0;
2116 flag_reorder_blocks = 1;
2121 /* A C compound statement to output to stdio stream STREAM the
2122 assembler syntax for an instruction operand X. X is an RTL
2125 CODE is a value that can be used to specify one of several ways
2126 of printing the operand. It is used when identical operands
2127 must be printed differently depending on the context. CODE
2128 comes from the '%' specification that was used to request
2129 printing of the operand. If the specification was just '%DIGIT'
2130 then CODE is 0; if the specification was '%LTR DIGIT' then CODE
2131 is the ASCII code for LTR.
2133 If X is a register, this macro should print the register's name.
2134 The names can be found in an array 'reg_names' whose type is
2135 'char *[]'. 'reg_names' is initialized from 'REGISTER_NAMES'.
2137 When the machine description has a specification '%PUNCT' (a '%'
2138 followed by a punctuation character), this macro is called with
2139 a null pointer for X and the punctuation character for CODE.
2141 'a', 'c', 'l', and 'n' are reserved.
2143 The Xtensa specific codes are:
2145 'd' CONST_INT, print as signed decimal
2146 'x' CONST_INT, print as signed hexadecimal
2147 'K' CONST_INT, print number of bits in mask for EXTUI
2148 'R' CONST_INT, print (X & 0x1f)
2149 'L' CONST_INT, print ((32 - X) & 0x1f)
2150 'D' REG, print second register of double-word register operand
2151 'N' MEM, print address of next word following a memory operand
2152 'v' MEM, if memory reference is volatile, output a MEMW before it
2153 't' any constant, add "@h" suffix for top 16 bits
2154 'b' any constant, add "@l" suffix for bottom 16 bits
2158 printx (FILE *file, signed int val)
2160 /* Print a hexadecimal value in a nice way. */
2161 if ((val > -0xa) && (val < 0xa))
2162 fprintf (file, "%d", val);
2164 fprintf (file, "-0x%x", -val);
2166 fprintf (file, "0x%x", val);
2171 print_operand (FILE *file, rtx x, int letter)
2174 error ("PRINT_OPERAND null pointer");
2179 if (GET_CODE (x) == REG || GET_CODE (x) == SUBREG)
2180 fprintf (file, "%s", reg_names[xt_true_regnum (x) + 1]);
2182 output_operand_lossage ("invalid %%D value");
2186 if (GET_CODE (x) == MEM)
2188 /* For a volatile memory reference, emit a MEMW before the
2190 if (MEM_VOLATILE_P (x) && TARGET_SERIALIZE_VOLATILE)
2191 fprintf (file, "memw\n\t");
2194 output_operand_lossage ("invalid %%v value");
2198 if (GET_CODE (x) == MEM
2199 && (GET_MODE (x) == DFmode || GET_MODE (x) == DImode))
2201 x = adjust_address (x, GET_MODE (x) == DFmode ? SFmode : SImode, 4);
2202 output_address (XEXP (x, 0));
2205 output_operand_lossage ("invalid %%N value");
2209 if (GET_CODE (x) == CONST_INT)
2212 unsigned val = INTVAL (x);
2218 if ((val != 0) || (num_bits == 0) || (num_bits > 16))
2219 fatal_insn ("invalid mask", x);
2221 fprintf (file, "%d", num_bits);
2224 output_operand_lossage ("invalid %%K value");
2228 if (GET_CODE (x) == CONST_INT)
2229 fprintf (file, "%ld", (32 - INTVAL (x)) & 0x1f);
2231 output_operand_lossage ("invalid %%L value");
2235 if (GET_CODE (x) == CONST_INT)
2236 fprintf (file, "%ld", INTVAL (x) & 0x1f);
2238 output_operand_lossage ("invalid %%R value");
2242 if (GET_CODE (x) == CONST_INT)
2243 printx (file, INTVAL (x));
2245 output_operand_lossage ("invalid %%x value");
2249 if (GET_CODE (x) == CONST_INT)
2250 fprintf (file, "%ld", INTVAL (x));
2252 output_operand_lossage ("invalid %%d value");
2257 if (GET_CODE (x) == CONST_INT)
2259 printx (file, INTVAL (x));
2260 fputs (letter == 't' ? "@h" : "@l", file);
2262 else if (GET_CODE (x) == CONST_DOUBLE)
2265 REAL_VALUE_FROM_CONST_DOUBLE (r, x);
2266 if (GET_MODE (x) == SFmode)
2269 REAL_VALUE_TO_TARGET_SINGLE (r, l);
2270 fprintf (file, "0x%08lx@%c", l, letter == 't' ? 'h' : 'l');
2273 output_operand_lossage ("invalid %%t/%%b value");
2275 else if (GET_CODE (x) == CONST)
2277 /* X must be a symbolic constant on ELF. Write an expression
2278 suitable for 'const16' that sets the high or low 16 bits. */
2279 if (GET_CODE (XEXP (x, 0)) != PLUS
2280 || (GET_CODE (XEXP (XEXP (x, 0), 0)) != SYMBOL_REF
2281 && GET_CODE (XEXP (XEXP (x, 0), 0)) != LABEL_REF)
2282 || GET_CODE (XEXP (XEXP (x, 0), 1)) != CONST_INT)
2283 output_operand_lossage ("invalid %%t/%%b value");
2284 print_operand (file, XEXP (XEXP (x, 0), 0), 0);
2285 fputs (letter == 't' ? "@h" : "@l", file);
2286 /* There must be a non-alphanumeric character between 'h' or 'l'
2287 and the number. The '-' is added by print_operand() already. */
2288 if (INTVAL (XEXP (XEXP (x, 0), 1)) >= 0)
2290 print_operand (file, XEXP (XEXP (x, 0), 1), 0);
2294 output_addr_const (file, x);
2295 fputs (letter == 't' ? "@h" : "@l", file);
2300 if (GET_CODE (x) == REG || GET_CODE (x) == SUBREG)
2301 fprintf (file, "%s", reg_names[xt_true_regnum (x)]);
2302 else if (GET_CODE (x) == MEM)
2303 output_address (XEXP (x, 0));
2304 else if (GET_CODE (x) == CONST_INT)
2305 fprintf (file, "%ld", INTVAL (x));
2307 output_addr_const (file, x);
2312 /* A C compound statement to output to stdio stream STREAM the
2313 assembler syntax for an instruction operand that is a memory
2314 reference whose address is ADDR. ADDR is an RTL expression. */
2317 print_operand_address (FILE *file, rtx addr)
2320 error ("PRINT_OPERAND_ADDRESS, null pointer");
2322 switch (GET_CODE (addr))
2325 fatal_insn ("invalid address", addr);
2329 fprintf (file, "%s, 0", reg_names [REGNO (addr)]);
2335 rtx offset = (rtx)0;
2336 rtx arg0 = XEXP (addr, 0);
2337 rtx arg1 = XEXP (addr, 1);
2339 if (GET_CODE (arg0) == REG)
2344 else if (GET_CODE (arg1) == REG)
2350 fatal_insn ("no register in address", addr);
2352 if (CONSTANT_P (offset))
2354 fprintf (file, "%s, ", reg_names [REGNO (reg)]);
2355 output_addr_const (file, offset);
2358 fatal_insn ("address offset not a constant", addr);
2366 output_addr_const (file, addr);
2373 xtensa_output_addr_const_extra (FILE *fp, rtx x)
2375 if (GET_CODE (x) == UNSPEC && XVECLEN (x, 0) == 1)
2377 switch (XINT (x, 1))
2380 output_addr_const (fp, XVECEXP (x, 0, 0));
2381 fputs ("@TPOFF", fp);
2384 output_addr_const (fp, XVECEXP (x, 0, 0));
2385 fputs ("@DTPOFF", fp);
2390 output_addr_const (fp, XVECEXP (x, 0, 0));
2404 xtensa_output_literal (FILE *file, rtx x, enum machine_mode mode, int labelno)
2411 fprintf (file, "\t.literal .LC%u, ", (unsigned) labelno);
2413 switch (GET_MODE_CLASS (mode))
2416 gcc_assert (GET_CODE (x) == CONST_DOUBLE);
2418 REAL_VALUE_FROM_CONST_DOUBLE (r, x);
2422 REAL_VALUE_TO_TARGET_SINGLE (r, value_long[0]);
2423 if (HOST_BITS_PER_LONG > 32)
2424 value_long[0] &= 0xffffffff;
2425 fprintf (file, "0x%08lx\n", value_long[0]);
2429 REAL_VALUE_TO_TARGET_DOUBLE (r, value_long);
2430 if (HOST_BITS_PER_LONG > 32)
2432 value_long[0] &= 0xffffffff;
2433 value_long[1] &= 0xffffffff;
2435 fprintf (file, "0x%08lx, 0x%08lx\n",
2436 value_long[0], value_long[1]);
2446 case MODE_PARTIAL_INT:
2447 size = GET_MODE_SIZE (mode);
2451 output_addr_const (file, x);
2456 split_double (x, &first, &second);
2457 output_addr_const (file, first);
2459 output_addr_const (file, second);
2474 /* Return the bytes needed to compute the frame pointer from the current
2477 #define STACK_BYTES (STACK_BOUNDARY / BITS_PER_UNIT)
2478 #define XTENSA_STACK_ALIGN(LOC) (((LOC) + STACK_BYTES-1) & ~(STACK_BYTES-1))
2481 compute_frame_size (int size)
2483 /* Add space for the incoming static chain value. */
2484 if (cfun->static_chain_decl != NULL)
2485 size += (1 * UNITS_PER_WORD);
2487 xtensa_current_frame_size =
2488 XTENSA_STACK_ALIGN (size
2489 + crtl->outgoing_args_size
2490 + (WINDOW_SIZE * UNITS_PER_WORD));
2491 return xtensa_current_frame_size;
2496 xtensa_frame_pointer_required (void)
2498 /* The code to expand builtin_frame_addr and builtin_return_addr
2499 currently uses the hard_frame_pointer instead of frame_pointer.
2500 This seems wrong but maybe it's necessary for other architectures.
2501 This function is derived from the i386 code. */
2503 if (cfun->machine->accesses_prev_frame)
2510 /* minimum frame = reg save area (4 words) plus static chain (1 word)
2511 and the total number of words must be a multiple of 128 bits. */
2512 #define MIN_FRAME_SIZE (8 * UNITS_PER_WORD)
2515 xtensa_expand_prologue (void)
2517 HOST_WIDE_INT total_size;
2521 total_size = compute_frame_size (get_frame_size ());
2522 size_rtx = GEN_INT (total_size);
2524 if (total_size < (1 << (12+3)))
2525 insn = emit_insn (gen_entry (size_rtx));
2528 /* Use a8 as a temporary since a0-a7 may be live. */
2529 rtx tmp_reg = gen_rtx_REG (Pmode, A8_REG);
2530 emit_insn (gen_entry (GEN_INT (MIN_FRAME_SIZE)));
2531 emit_move_insn (tmp_reg, GEN_INT (total_size - MIN_FRAME_SIZE));
2532 emit_insn (gen_subsi3 (tmp_reg, stack_pointer_rtx, tmp_reg));
2533 insn = emit_insn (gen_movsi (stack_pointer_rtx, tmp_reg));
2536 if (frame_pointer_needed)
2538 if (cfun->machine->set_frame_ptr_insn)
2542 push_topmost_sequence ();
2543 first = get_insns ();
2544 pop_topmost_sequence ();
2546 /* For all instructions prior to set_frame_ptr_insn, replace
2547 hard_frame_pointer references with stack_pointer. */
2549 insn != cfun->machine->set_frame_ptr_insn;
2550 insn = NEXT_INSN (insn))
2554 PATTERN (insn) = replace_rtx (copy_rtx (PATTERN (insn)),
2555 hard_frame_pointer_rtx,
2557 df_insn_rescan (insn);
2562 insn = emit_insn (gen_movsi (hard_frame_pointer_rtx,
2563 stack_pointer_rtx));
2566 /* Create a note to describe the CFA. Because this is only used to set
2567 DW_AT_frame_base for debug info, don't bother tracking changes through
2568 each instruction in the prologue. It just takes up space. */
2569 note_rtx = gen_rtx_SET (VOIDmode, (frame_pointer_needed
2570 ? hard_frame_pointer_rtx
2571 : stack_pointer_rtx),
2572 plus_constant (stack_pointer_rtx, -total_size));
2573 RTX_FRAME_RELATED_P (insn) = 1;
2574 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR,
2575 note_rtx, REG_NOTES (insn));
2579 /* Clear variables at function end. */
2582 xtensa_function_epilogue (FILE *file ATTRIBUTE_UNUSED,
2583 HOST_WIDE_INT size ATTRIBUTE_UNUSED)
2585 xtensa_current_frame_size = 0;
2590 xtensa_return_addr (int count, rtx frame)
2592 rtx result, retaddr, curaddr, label;
2595 retaddr = gen_rtx_REG (Pmode, A0_REG);
2598 rtx addr = plus_constant (frame, -4 * UNITS_PER_WORD);
2599 addr = memory_address (Pmode, addr);
2600 retaddr = gen_reg_rtx (Pmode);
2601 emit_move_insn (retaddr, gen_rtx_MEM (Pmode, addr));
2604 /* The 2 most-significant bits of the return address on Xtensa hold
2605 the register window size. To get the real return address, these
2606 bits must be replaced with the high bits from some address in the
2609 /* Get the 2 high bits of a local label in the code. */
2610 curaddr = gen_reg_rtx (Pmode);
2611 label = gen_label_rtx ();
2613 LABEL_PRESERVE_P (label) = 1;
2614 emit_move_insn (curaddr, gen_rtx_LABEL_REF (Pmode, label));
2615 emit_insn (gen_lshrsi3 (curaddr, curaddr, GEN_INT (30)));
2616 emit_insn (gen_ashlsi3 (curaddr, curaddr, GEN_INT (30)));
2618 /* Clear the 2 high bits of the return address. */
2619 result = gen_reg_rtx (Pmode);
2620 emit_insn (gen_ashlsi3 (result, retaddr, GEN_INT (2)));
2621 emit_insn (gen_lshrsi3 (result, result, GEN_INT (2)));
2623 /* Combine them to get the result. */
2624 emit_insn (gen_iorsi3 (result, result, curaddr));
2629 /* Create the va_list data type.
2631 This structure is set up by __builtin_saveregs. The __va_reg field
2632 points to a stack-allocated region holding the contents of the
2633 incoming argument registers. The __va_ndx field is an index
2634 initialized to the position of the first unnamed (variable)
2635 argument. This same index is also used to address the arguments
2636 passed in memory. Thus, the __va_stk field is initialized to point
2637 to the position of the first argument in memory offset to account
2638 for the arguments passed in registers and to account for the size
2639 of the argument registers not being 16-byte aligned. E.G., there
2640 are 6 argument registers of 4 bytes each, but we want the __va_ndx
2641 for the first stack argument to have the maximal alignment of 16
2642 bytes, so we offset the __va_stk address by 32 bytes so that
2643 __va_stk[32] references the first argument on the stack. */
2646 xtensa_build_builtin_va_list (void)
2648 tree f_stk, f_reg, f_ndx, record, type_decl;
2650 record = (*lang_hooks.types.make_type) (RECORD_TYPE);
2651 type_decl = build_decl (TYPE_DECL, get_identifier ("__va_list_tag"), record);
2653 f_stk = build_decl (FIELD_DECL, get_identifier ("__va_stk"),
2655 f_reg = build_decl (FIELD_DECL, get_identifier ("__va_reg"),
2657 f_ndx = build_decl (FIELD_DECL, get_identifier ("__va_ndx"),
2660 DECL_FIELD_CONTEXT (f_stk) = record;
2661 DECL_FIELD_CONTEXT (f_reg) = record;
2662 DECL_FIELD_CONTEXT (f_ndx) = record;
2664 TREE_CHAIN (record) = type_decl;
2665 TYPE_NAME (record) = type_decl;
2666 TYPE_FIELDS (record) = f_stk;
2667 TREE_CHAIN (f_stk) = f_reg;
2668 TREE_CHAIN (f_reg) = f_ndx;
2670 layout_type (record);
2675 /* Save the incoming argument registers on the stack. Returns the
2676 address of the saved registers. */
2679 xtensa_builtin_saveregs (void)
2682 int arg_words = crtl->args.info.arg_words;
2683 int gp_left = MAX_ARGS_IN_REGISTERS - arg_words;
2688 /* Allocate the general-purpose register space. */
2689 gp_regs = assign_stack_local
2690 (BLKmode, MAX_ARGS_IN_REGISTERS * UNITS_PER_WORD, -1);
2691 set_mem_alias_set (gp_regs, get_varargs_alias_set ());
2693 /* Now store the incoming registers. */
2694 cfun->machine->need_a7_copy = true;
2695 cfun->machine->vararg_a7 = true;
2696 move_block_from_reg (GP_ARG_FIRST + arg_words,
2697 adjust_address (gp_regs, BLKmode,
2698 arg_words * UNITS_PER_WORD),
2700 gcc_assert (cfun->machine->vararg_a7_copy != 0);
2701 emit_insn_before (cfun->machine->vararg_a7_copy, get_insns ());
2703 return XEXP (gp_regs, 0);
2707 /* Implement `va_start' for varargs and stdarg. We look at the
2708 current function to fill in an initial va_list. */
2711 xtensa_va_start (tree valist, rtx nextarg ATTRIBUTE_UNUSED)
2719 arg_words = crtl->args.info.arg_words;
2721 f_stk = TYPE_FIELDS (va_list_type_node);
2722 f_reg = TREE_CHAIN (f_stk);
2723 f_ndx = TREE_CHAIN (f_reg);
2725 stk = build3 (COMPONENT_REF, TREE_TYPE (f_stk), valist, f_stk, NULL_TREE);
2726 reg = build3 (COMPONENT_REF, TREE_TYPE (f_reg), unshare_expr (valist),
2728 ndx = build3 (COMPONENT_REF, TREE_TYPE (f_ndx), unshare_expr (valist),
2731 /* Call __builtin_saveregs; save the result in __va_reg */
2732 u = make_tree (sizetype, expand_builtin_saveregs ());
2733 u = fold_convert (ptr_type_node, u);
2734 t = build2 (MODIFY_EXPR, ptr_type_node, reg, u);
2735 TREE_SIDE_EFFECTS (t) = 1;
2736 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
2738 /* Set the __va_stk member to ($arg_ptr - 32). */
2739 u = make_tree (ptr_type_node, virtual_incoming_args_rtx);
2740 u = fold_build2 (POINTER_PLUS_EXPR, ptr_type_node, u, size_int (-32));
2741 t = build2 (MODIFY_EXPR, ptr_type_node, stk, u);
2742 TREE_SIDE_EFFECTS (t) = 1;
2743 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
2745 /* Set the __va_ndx member. If the first variable argument is on
2746 the stack, adjust __va_ndx by 2 words to account for the extra
2747 alignment offset for __va_stk. */
2748 if (arg_words >= MAX_ARGS_IN_REGISTERS)
2750 t = build2 (MODIFY_EXPR, integer_type_node, ndx,
2751 build_int_cst (integer_type_node, arg_words * UNITS_PER_WORD));
2752 TREE_SIDE_EFFECTS (t) = 1;
2753 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
2757 /* Implement `va_arg'. */
2760 xtensa_gimplify_va_arg_expr (tree valist, tree type, gimple_seq *pre_p,
2761 gimple_seq *post_p ATTRIBUTE_UNUSED)
2766 tree type_size, array, orig_ndx, addr, size, va_size, t;
2767 tree lab_false, lab_over, lab_false2;
2770 indirect = pass_by_reference (NULL, TYPE_MODE (type), type, false);
2772 type = build_pointer_type (type);
2774 /* Handle complex values as separate real and imaginary parts. */
2775 if (TREE_CODE (type) == COMPLEX_TYPE)
2777 tree real_part, imag_part;
2779 real_part = xtensa_gimplify_va_arg_expr (valist, TREE_TYPE (type),
2781 real_part = get_initialized_tmp_var (real_part, pre_p, NULL);
2783 imag_part = xtensa_gimplify_va_arg_expr (unshare_expr (valist),
2786 imag_part = get_initialized_tmp_var (imag_part, pre_p, NULL);
2788 return build2 (COMPLEX_EXPR, type, real_part, imag_part);
2791 f_stk = TYPE_FIELDS (va_list_type_node);
2792 f_reg = TREE_CHAIN (f_stk);
2793 f_ndx = TREE_CHAIN (f_reg);
2795 stk = build3 (COMPONENT_REF, TREE_TYPE (f_stk), valist,
2797 reg = build3 (COMPONENT_REF, TREE_TYPE (f_reg), unshare_expr (valist),
2799 ndx = build3 (COMPONENT_REF, TREE_TYPE (f_ndx), unshare_expr (valist),
2802 type_size = size_in_bytes (type);
2803 va_size = round_up (type_size, UNITS_PER_WORD);
2804 gimplify_expr (&va_size, pre_p, NULL, is_gimple_val, fb_rvalue);
2807 /* First align __va_ndx if necessary for this arg:
2809 orig_ndx = (AP).__va_ndx;
2810 if (__alignof__ (TYPE) > 4 )
2811 orig_ndx = ((orig_ndx + __alignof__ (TYPE) - 1)
2812 & -__alignof__ (TYPE)); */
2814 orig_ndx = get_initialized_tmp_var (ndx, pre_p, NULL);
2816 if (TYPE_ALIGN (type) > BITS_PER_WORD)
2818 int align = MIN (TYPE_ALIGN (type), STACK_BOUNDARY) / BITS_PER_UNIT;
2820 t = build2 (PLUS_EXPR, integer_type_node, unshare_expr (orig_ndx),
2821 build_int_cst (integer_type_node, align - 1));
2822 t = build2 (BIT_AND_EXPR, integer_type_node, t,
2823 build_int_cst (integer_type_node, -align));
2824 gimplify_assign (unshare_expr (orig_ndx), t, pre_p);
2828 /* Increment __va_ndx to point past the argument:
2830 (AP).__va_ndx = orig_ndx + __va_size (TYPE); */
2832 t = fold_convert (integer_type_node, va_size);
2833 t = build2 (PLUS_EXPR, integer_type_node, orig_ndx, t);
2834 gimplify_assign (unshare_expr (ndx), t, pre_p);
2837 /* Check if the argument is in registers:
2839 if ((AP).__va_ndx <= __MAX_ARGS_IN_REGISTERS * 4
2840 && !must_pass_in_stack (type))
2841 __array = (AP).__va_reg; */
2843 array = create_tmp_var (ptr_type_node, NULL);
2846 if (!targetm.calls.must_pass_in_stack (TYPE_MODE (type), type))
2848 lab_false = create_artificial_label ();
2849 lab_over = create_artificial_label ();
2851 t = build2 (GT_EXPR, boolean_type_node, unshare_expr (ndx),
2852 build_int_cst (integer_type_node,
2853 MAX_ARGS_IN_REGISTERS * UNITS_PER_WORD));
2854 t = build3 (COND_EXPR, void_type_node, t,
2855 build1 (GOTO_EXPR, void_type_node, lab_false),
2857 gimplify_and_add (t, pre_p);
2859 gimplify_assign (unshare_expr (array), reg, pre_p);
2861 t = build1 (GOTO_EXPR, void_type_node, lab_over);
2862 gimplify_and_add (t, pre_p);
2864 t = build1 (LABEL_EXPR, void_type_node, lab_false);
2865 gimplify_and_add (t, pre_p);
2869 /* ...otherwise, the argument is on the stack (never split between
2870 registers and the stack -- change __va_ndx if necessary):
2874 if (orig_ndx <= __MAX_ARGS_IN_REGISTERS * 4)
2875 (AP).__va_ndx = 32 + __va_size (TYPE);
2876 __array = (AP).__va_stk;
2879 lab_false2 = create_artificial_label ();
2881 t = build2 (GT_EXPR, boolean_type_node, unshare_expr (orig_ndx),
2882 build_int_cst (integer_type_node,
2883 MAX_ARGS_IN_REGISTERS * UNITS_PER_WORD));
2884 t = build3 (COND_EXPR, void_type_node, t,
2885 build1 (GOTO_EXPR, void_type_node, lab_false2),
2887 gimplify_and_add (t, pre_p);
2889 t = size_binop (PLUS_EXPR, unshare_expr (va_size), size_int (32));
2890 t = fold_convert (integer_type_node, t);
2891 gimplify_assign (unshare_expr (ndx), t, pre_p);
2893 t = build1 (LABEL_EXPR, void_type_node, lab_false2);
2894 gimplify_and_add (t, pre_p);
2896 gimplify_assign (array, stk, pre_p);
2900 t = build1 (LABEL_EXPR, void_type_node, lab_over);
2901 gimplify_and_add (t, pre_p);
2905 /* Given the base array pointer (__array) and index to the subsequent
2906 argument (__va_ndx), find the address:
2908 __array + (AP).__va_ndx - (BYTES_BIG_ENDIAN && sizeof (TYPE) < 4
2912 The results are endian-dependent because values smaller than one word
2913 are aligned differently. */
2916 if (BYTES_BIG_ENDIAN && TREE_CODE (type_size) == INTEGER_CST)
2918 t = fold_build2 (GE_EXPR, boolean_type_node, unshare_expr (type_size),
2919 size_int (PARM_BOUNDARY / BITS_PER_UNIT));
2920 t = fold_build3 (COND_EXPR, sizetype, t, unshare_expr (va_size),
2921 unshare_expr (type_size));
2925 size = unshare_expr (va_size);
2927 t = fold_convert (sizetype, unshare_expr (ndx));
2928 t = build2 (MINUS_EXPR, sizetype, t, size);
2929 addr = build2 (POINTER_PLUS_EXPR, ptr_type_node, unshare_expr (array), t);
2931 addr = fold_convert (build_pointer_type (type), addr);
2933 addr = build_va_arg_indirect_ref (addr);
2934 return build_va_arg_indirect_ref (addr);
2942 XTENSA_BUILTIN_UMULSIDI3,
2943 XTENSA_BUILTIN_THREAD_POINTER,
2944 XTENSA_BUILTIN_SET_THREAD_POINTER,
2950 xtensa_init_builtins (void)
2954 ftype = build_function_type_list (unsigned_intDI_type_node,
2955 unsigned_intSI_type_node,
2956 unsigned_intSI_type_node, NULL_TREE);
2958 decl = add_builtin_function ("__builtin_umulsidi3", ftype,
2959 XTENSA_BUILTIN_UMULSIDI3, BUILT_IN_MD,
2960 "__umulsidi3", NULL_TREE);
2961 TREE_NOTHROW (decl) = 1;
2962 TREE_READONLY (decl) = 1;
2964 if (TARGET_THREADPTR)
2966 ftype = build_function_type (ptr_type_node, void_list_node);
2967 decl = add_builtin_function ("__builtin_thread_pointer", ftype,
2968 XTENSA_BUILTIN_THREAD_POINTER, BUILT_IN_MD,
2970 TREE_READONLY (decl) = 1;
2971 TREE_NOTHROW (decl) = 1;
2973 ftype = build_function_type_list (void_type_node, ptr_type_node,
2975 decl = add_builtin_function ("__builtin_set_thread_pointer", ftype,
2976 XTENSA_BUILTIN_SET_THREAD_POINTER,
2977 BUILT_IN_MD, NULL, NULL_TREE);
2978 TREE_NOTHROW (decl) = 1;
2984 xtensa_fold_builtin (tree fndecl, tree arglist, bool ignore ATTRIBUTE_UNUSED)
2986 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
2991 case XTENSA_BUILTIN_UMULSIDI3:
2992 arg0 = TREE_VALUE (arglist);
2993 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
2994 if ((TREE_CODE (arg0) == INTEGER_CST && TREE_CODE (arg1) == INTEGER_CST)
2995 || TARGET_MUL32_HIGH)
2996 return fold_build2 (MULT_EXPR, unsigned_intDI_type_node,
2997 fold_convert (unsigned_intDI_type_node, arg0),
2998 fold_convert (unsigned_intDI_type_node, arg1));
3001 case XTENSA_BUILTIN_THREAD_POINTER:
3002 case XTENSA_BUILTIN_SET_THREAD_POINTER:
3006 internal_error ("bad builtin code");
3015 xtensa_expand_builtin (tree exp, rtx target,
3016 rtx subtarget ATTRIBUTE_UNUSED,
3017 enum machine_mode mode ATTRIBUTE_UNUSED,
3020 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
3021 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
3026 case XTENSA_BUILTIN_UMULSIDI3:
3027 /* The umulsidi3 builtin is just a mechanism to avoid calling the real
3028 __umulsidi3 function when the Xtensa configuration can directly
3029 implement it. If not, just call the function. */
3030 return expand_call (exp, target, ignore);
3032 case XTENSA_BUILTIN_THREAD_POINTER:
3033 if (!target || !register_operand (target, Pmode))
3034 target = gen_reg_rtx (Pmode);
3035 emit_insn (gen_load_tp (target));
3038 case XTENSA_BUILTIN_SET_THREAD_POINTER:
3039 arg = expand_normal (CALL_EXPR_ARG (exp, 0));
3040 if (!register_operand (arg, Pmode))
3041 arg = copy_to_mode_reg (Pmode, arg);
3042 emit_insn (gen_set_tp (arg));
3046 internal_error ("bad builtin code");
3053 xtensa_preferred_reload_class (rtx x, enum reg_class rclass, int isoutput)
3055 if (!isoutput && CONSTANT_P (x) && GET_CODE (x) == CONST_DOUBLE)
3058 /* Don't use the stack pointer or hard frame pointer for reloads!
3059 The hard frame pointer would normally be OK except that it may
3060 briefly hold an incoming argument in the prologue, and reload
3061 won't know that it is live because the hard frame pointer is
3062 treated specially. */
3064 if (rclass == AR_REGS || rclass == GR_REGS)
3072 xtensa_secondary_reload (bool in_p, rtx x, enum reg_class rclass,
3073 enum machine_mode mode, secondary_reload_info *sri)
3077 if (in_p && constantpool_mem_p (x))
3079 if (rclass == FP_REGS)
3083 sri->icode = CODE_FOR_reloadqi_literal;
3084 else if (mode == HImode)
3085 sri->icode = CODE_FOR_reloadhi_literal;
3088 regno = xt_true_regnum (x);
3089 if (ACC_REG_P (regno))
3090 return ((rclass == GR_REGS || rclass == RL_REGS) ? NO_REGS : RL_REGS);
3091 if (rclass == ACC_REG)
3092 return (GP_REG_P (regno) ? NO_REGS : RL_REGS);
3099 order_regs_for_local_alloc (void)
3101 if (!leaf_function_p ())
3103 memcpy (reg_alloc_order, reg_nonleaf_alloc_order,
3104 FIRST_PSEUDO_REGISTER * sizeof (int));
3108 int i, num_arg_regs;
3111 /* Use the AR registers in increasing order (skipping a0 and a1)
3112 but save the incoming argument registers for a last resort. */
3113 num_arg_regs = crtl->args.info.arg_words;
3114 if (num_arg_regs > MAX_ARGS_IN_REGISTERS)
3115 num_arg_regs = MAX_ARGS_IN_REGISTERS;
3116 for (i = GP_ARG_FIRST; i < 16 - num_arg_regs; i++)
3117 reg_alloc_order[nxt++] = i + num_arg_regs;
3118 for (i = 0; i < num_arg_regs; i++)
3119 reg_alloc_order[nxt++] = GP_ARG_FIRST + i;
3121 /* List the coprocessor registers in order. */
3122 for (i = 0; i < BR_REG_NUM; i++)
3123 reg_alloc_order[nxt++] = BR_REG_FIRST + i;
3125 /* List the FP registers in order for now. */
3126 for (i = 0; i < 16; i++)
3127 reg_alloc_order[nxt++] = FP_REG_FIRST + i;
3129 /* GCC requires that we list *all* the registers.... */
3130 reg_alloc_order[nxt++] = 0; /* a0 = return address */
3131 reg_alloc_order[nxt++] = 1; /* a1 = stack pointer */
3132 reg_alloc_order[nxt++] = 16; /* pseudo frame pointer */
3133 reg_alloc_order[nxt++] = 17; /* pseudo arg pointer */
3135 reg_alloc_order[nxt++] = ACC_REG_FIRST; /* MAC16 accumulator */
3140 /* Some Xtensa targets support multiple bss sections. If the section
3141 name ends with ".bss", add SECTION_BSS to the flags. */
3144 xtensa_multibss_section_type_flags (tree decl, const char *name, int reloc)
3146 unsigned int flags = default_section_type_flags (decl, name, reloc);
3149 suffix = strrchr (name, '.');
3150 if (suffix && strcmp (suffix, ".bss") == 0)
3152 if (!decl || (TREE_CODE (decl) == VAR_DECL
3153 && DECL_INITIAL (decl) == NULL_TREE))
3154 flags |= SECTION_BSS; /* @nobits */
3156 warning (0, "only uninitialized variables can be placed in a "
3164 /* The literal pool stays with the function. */
3167 xtensa_select_rtx_section (enum machine_mode mode ATTRIBUTE_UNUSED,
3168 rtx x ATTRIBUTE_UNUSED,
3169 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED)
3171 return function_section (current_function_decl);
3175 /* Compute a (partial) cost for rtx X. Return true if the complete
3176 cost has been computed, and false if subexpressions should be
3177 scanned. In either case, *TOTAL contains the cost result. */
3180 xtensa_rtx_costs (rtx x, int code, int outer_code, int *total,
3181 bool speed ATTRIBUTE_UNUSED)
3189 if (xtensa_simm12b (INTVAL (x)))
3196 if (xtensa_simm8 (INTVAL (x))
3197 || xtensa_simm8x256 (INTVAL (x)))
3204 if (xtensa_mask_immediate (INTVAL (x)))
3211 if ((INTVAL (x) == 0) || xtensa_b4const (INTVAL (x)))
3222 /* No way to tell if X is the 2nd operand so be conservative. */
3225 if (xtensa_simm12b (INTVAL (x)))
3227 else if (TARGET_CONST16)
3228 *total = COSTS_N_INSNS (2);
3237 *total = COSTS_N_INSNS (2);
3244 *total = COSTS_N_INSNS (4);
3252 (GET_MODE_SIZE (GET_MODE (x)) > UNITS_PER_WORD) ? 2 : 1;
3254 if (memory_address_p (GET_MODE (x), XEXP ((x), 0)))
3255 *total = COSTS_N_INSNS (num_words);
3257 *total = COSTS_N_INSNS (2*num_words);
3263 *total = COSTS_N_INSNS (TARGET_NSA ? 5 : 50);
3267 *total = COSTS_N_INSNS (TARGET_NSA ? 1 : 50);
3271 *total = COSTS_N_INSNS ((GET_MODE (x) == DImode) ? 3 : 2);
3277 if (GET_MODE (x) == DImode)
3278 *total = COSTS_N_INSNS (2);
3280 *total = COSTS_N_INSNS (1);
3286 if (GET_MODE (x) == DImode)
3287 *total = COSTS_N_INSNS (50);
3289 *total = COSTS_N_INSNS (1);
3294 enum machine_mode xmode = GET_MODE (x);
3295 if (xmode == SFmode)
3296 *total = COSTS_N_INSNS (TARGET_HARD_FLOAT ? 1 : 50);
3297 else if (xmode == DFmode)
3298 *total = COSTS_N_INSNS (50);
3300 *total = COSTS_N_INSNS (4);
3307 enum machine_mode xmode = GET_MODE (x);
3308 if (xmode == SFmode)
3309 *total = COSTS_N_INSNS (TARGET_HARD_FLOAT ? 1 : 50);
3310 else if (xmode == DFmode || xmode == DImode)
3311 *total = COSTS_N_INSNS (50);
3313 *total = COSTS_N_INSNS (1);
3318 *total = COSTS_N_INSNS ((GET_MODE (x) == DImode) ? 4 : 2);
3323 enum machine_mode xmode = GET_MODE (x);
3324 if (xmode == SFmode)
3325 *total = COSTS_N_INSNS (TARGET_HARD_FLOAT ? 4 : 50);
3326 else if (xmode == DFmode)
3327 *total = COSTS_N_INSNS (50);
3328 else if (xmode == DImode)
3329 *total = COSTS_N_INSNS (TARGET_MUL32_HIGH ? 10 : 50);
3330 else if (TARGET_MUL32)
3331 *total = COSTS_N_INSNS (4);
3332 else if (TARGET_MAC16)
3333 *total = COSTS_N_INSNS (16);
3334 else if (TARGET_MUL16)
3335 *total = COSTS_N_INSNS (12);
3337 *total = COSTS_N_INSNS (50);
3344 enum machine_mode xmode = GET_MODE (x);
3345 if (xmode == SFmode)
3347 *total = COSTS_N_INSNS (TARGET_HARD_FLOAT_DIV ? 8 : 50);
3350 else if (xmode == DFmode)
3352 *total = COSTS_N_INSNS (50);
3361 enum machine_mode xmode = GET_MODE (x);
3362 if (xmode == DImode)
3363 *total = COSTS_N_INSNS (50);
3364 else if (TARGET_DIV32)
3365 *total = COSTS_N_INSNS (32);
3367 *total = COSTS_N_INSNS (50);
3372 if (GET_MODE (x) == SFmode)
3373 *total = COSTS_N_INSNS (TARGET_HARD_FLOAT_SQRT ? 8 : 50);
3375 *total = COSTS_N_INSNS (50);
3382 *total = COSTS_N_INSNS (TARGET_MINMAX ? 1 : 50);
3387 *total = COSTS_N_INSNS (TARGET_SEXT ? 1 : 2);
3392 *total = COSTS_N_INSNS (1);
3400 /* Worker function for TARGET_RETURN_IN_MEMORY. */
3403 xtensa_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED)
3405 return ((unsigned HOST_WIDE_INT) int_size_in_bytes (type)
3406 > 4 * UNITS_PER_WORD);
3409 /* Worker function for TARGET_FUNCTION_VALUE. */
3412 xtensa_function_value (const_tree valtype, const_tree func ATTRIBUTE_UNUSED,
3415 return gen_rtx_REG ((INTEGRAL_TYPE_P (valtype)
3416 && TYPE_PRECISION (valtype) < BITS_PER_WORD)
3417 ? SImode : TYPE_MODE (valtype),
3418 outgoing ? GP_OUTGOING_RETURN : GP_RETURN);
3421 /* TRAMPOLINE_TEMPLATE: For Xtensa, the trampoline must perform an ENTRY
3422 instruction with a minimal stack frame in order to get some free
3423 registers. Once the actual call target is known, the proper stack frame
3424 size is extracted from the ENTRY instruction at the target and the
3425 current frame is adjusted to match. The trampoline then transfers
3426 control to the instruction following the ENTRY at the target. Note:
3427 this assumes that the target begins with an ENTRY instruction. */
3430 xtensa_trampoline_template (FILE *stream)
3432 bool use_call0 = (TARGET_CONST16 || TARGET_ABSOLUTE_LITERALS);
3434 fprintf (stream, "\t.begin no-transform\n");
3435 fprintf (stream, "\tentry\tsp, %d\n", MIN_FRAME_SIZE);
3439 /* Save the return address. */
3440 fprintf (stream, "\tmov\ta10, a0\n");
3442 /* Use a CALL0 instruction to skip past the constants and in the
3443 process get the PC into A0. This allows PC-relative access to
3444 the constants without relying on L32R. */
3445 fprintf (stream, "\tcall0\t.Lskipconsts\n");
3448 fprintf (stream, "\tj\t.Lskipconsts\n");
3450 fprintf (stream, "\t.align\t4\n");
3451 fprintf (stream, ".Lchainval:%s0\n", integer_asm_op (4, TRUE));
3452 fprintf (stream, ".Lfnaddr:%s0\n", integer_asm_op (4, TRUE));
3453 fprintf (stream, ".Lskipconsts:\n");
3455 /* Load the static chain and function address from the trampoline. */
3458 fprintf (stream, "\taddi\ta0, a0, 3\n");
3459 fprintf (stream, "\tl32i\ta9, a0, 0\n");
3460 fprintf (stream, "\tl32i\ta8, a0, 4\n");
3464 fprintf (stream, "\tl32r\ta9, .Lchainval\n");
3465 fprintf (stream, "\tl32r\ta8, .Lfnaddr\n");
3468 /* Store the static chain. */
3469 fprintf (stream, "\ts32i\ta9, sp, %d\n", MIN_FRAME_SIZE - 20);
3471 /* Set the proper stack pointer value. */
3472 fprintf (stream, "\tl32i\ta9, a8, 0\n");
3473 fprintf (stream, "\textui\ta9, a9, %d, 12\n",
3474 TARGET_BIG_ENDIAN ? 8 : 12);
3475 fprintf (stream, "\tslli\ta9, a9, 3\n");
3476 fprintf (stream, "\taddi\ta9, a9, %d\n", -MIN_FRAME_SIZE);
3477 fprintf (stream, "\tsub\ta9, sp, a9\n");
3478 fprintf (stream, "\tmovsp\tsp, a9\n");
3481 /* Restore the return address. */
3482 fprintf (stream, "\tmov\ta0, a10\n");
3484 /* Jump to the instruction following the ENTRY. */
3485 fprintf (stream, "\taddi\ta8, a8, 3\n");
3486 fprintf (stream, "\tjx\ta8\n");
3488 /* Pad size to a multiple of TRAMPOLINE_ALIGNMENT. */
3490 fprintf (stream, "\t.byte\t0\n");
3492 fprintf (stream, "\tnop\n");
3494 fprintf (stream, "\t.end no-transform\n");
3499 xtensa_initialize_trampoline (rtx addr, rtx func, rtx chain)
3501 bool use_call0 = (TARGET_CONST16 || TARGET_ABSOLUTE_LITERALS);
3502 int chain_off = use_call0 ? 12 : 8;
3503 int func_off = use_call0 ? 16 : 12;
3504 emit_move_insn (gen_rtx_MEM (SImode, plus_constant (addr, chain_off)), chain);
3505 emit_move_insn (gen_rtx_MEM (SImode, plus_constant (addr, func_off)), func);
3506 emit_library_call (gen_rtx_SYMBOL_REF (Pmode, "__xtensa_sync_caches"),
3507 0, VOIDmode, 1, addr, Pmode);
3511 #include "gt-xtensa.h"