mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-03-19 22:41:28 +08:00
configure.ac: Add HAVE_AS_TLS check for Xtensa.
* configure.ac: Add HAVE_AS_TLS check for Xtensa. * config/xtensa/predicates.md (tls_symbol_operand): New. * config/xtensa/xtensa.c (TARGET_HAVE_TLS): Define. (TARGET_CANNOT_FORCE_MEM): Define. (xtensa_tls_symbol_p): New. (xtensa_emit_move_sequence): Check for and legitimize TLS addresses. (xtensa_legitimate_address_p): Disallow constant pool TLS references. (xtensa_tls_module_base): New. (xtensa_call_tls_desc): New. (xtensa_legitimize_tls_address): New. (xtensa_legitimize_address): Handle TLS symbols. (xtensa_tls_referenced_p_1): New. (xtensa_tls_referenced_p): New. (xtensa_output_addr_const_extra): Handle UNSPEC_TPOFF and UNSPEC_DTPOFF. (XTENSA_BUILTIN_THREAD_POINTER): New. (XTENSA_BUILTIN_SET_THREAD_POINTER): New. (xtensa_init_builtins): Set NOTHROW and READONLY for umulsidi3 builtin. Add declarations for __builtin_thread_pointer and __builtin_set_thread_pointer. (xtensa_fold_builtin): Recognize new builtins. (xtensa_expand_builtin): Expand new builtins. * config/xtensa/xtensa.h (XCHAL_HAVE_THREADPTR): Define default value. (TARGET_THREADPTR): Define. (HAVE_AS_TLS): Define default value. (LEGITIMATE_CONSTANT_P): Disallow TLS references. * config/xtensa/xtensa.md (UNSPEC_TPOFF, UNSPEC_DTPOFF): New. (UNSPEC_TLS_FUNC, UNSPEC_TLS_ARG, UNSPEC_TLS_CALL, UNSPEC_TP): New. (UNSPECV_SET_TP): New. (sym_TPOFF, sym_DTPOFF): New. (load_tp, set_tp, tls_func, tls_arg, tls_call): New. * config/xtensa/xtensa-protos.h (xtensa_tls_referenced_p): Declare. * configure: Regenerated. From-SVN: r140482
This commit is contained in:
parent
342f11d55a
commit
6a7a462cbf
@ -1,3 +1,38 @@
|
||||
2008-09-18 Bob Wilson <bob.wilson@acm.org>
|
||||
|
||||
* configure.ac: Add HAVE_AS_TLS check for Xtensa.
|
||||
* config/xtensa/predicates.md (tls_symbol_operand): New.
|
||||
* config/xtensa/xtensa.c (TARGET_HAVE_TLS): Define.
|
||||
(TARGET_CANNOT_FORCE_MEM): Define.
|
||||
(xtensa_tls_symbol_p): New.
|
||||
(xtensa_emit_move_sequence): Check for and legitimize TLS addresses.
|
||||
(xtensa_legitimate_address_p): Disallow constant pool TLS references.
|
||||
(xtensa_tls_module_base): New.
|
||||
(xtensa_call_tls_desc): New.
|
||||
(xtensa_legitimize_tls_address): New.
|
||||
(xtensa_legitimize_address): Handle TLS symbols.
|
||||
(xtensa_tls_referenced_p_1): New.
|
||||
(xtensa_tls_referenced_p): New.
|
||||
(xtensa_output_addr_const_extra): Handle UNSPEC_TPOFF and UNSPEC_DTPOFF.
|
||||
(XTENSA_BUILTIN_THREAD_POINTER): New.
|
||||
(XTENSA_BUILTIN_SET_THREAD_POINTER): New.
|
||||
(xtensa_init_builtins): Set NOTHROW and READONLY for umulsidi3 builtin.
|
||||
Add declarations for __builtin_thread_pointer and
|
||||
__builtin_set_thread_pointer.
|
||||
(xtensa_fold_builtin): Recognize new builtins.
|
||||
(xtensa_expand_builtin): Expand new builtins.
|
||||
* config/xtensa/xtensa.h (XCHAL_HAVE_THREADPTR): Define default value.
|
||||
(TARGET_THREADPTR): Define.
|
||||
(HAVE_AS_TLS): Define default value.
|
||||
(LEGITIMATE_CONSTANT_P): Disallow TLS references.
|
||||
* config/xtensa/xtensa.md (UNSPEC_TPOFF, UNSPEC_DTPOFF): New.
|
||||
(UNSPEC_TLS_FUNC, UNSPEC_TLS_ARG, UNSPEC_TLS_CALL, UNSPEC_TP): New.
|
||||
(UNSPECV_SET_TP): New.
|
||||
(sym_TPOFF, sym_DTPOFF): New.
|
||||
(load_tp, set_tp, tls_func, tls_arg, tls_call): New.
|
||||
* config/xtensa/xtensa-protos.h (xtensa_tls_referenced_p): Declare.
|
||||
* configure: Regenerated.
|
||||
|
||||
2008-09-18 H.J. Lu <hongjiu.lu@intel.com>
|
||||
|
||||
PR target/37394
|
||||
|
@ -166,3 +166,7 @@
|
||||
|
||||
(define_predicate "boolean_operator"
|
||||
(match_code "eq,ne"))
|
||||
|
||||
(define_predicate "tls_symbol_operand"
|
||||
(and (match_code "symbol_ref")
|
||||
(match_test "SYMBOL_REF_TLS_MODEL (op) != 0")))
|
||||
|
@ -56,6 +56,7 @@ extern char *xtensa_emit_movcc (bool, bool, bool, rtx *);
|
||||
extern char *xtensa_emit_call (int, rtx *);
|
||||
extern bool xtensa_legitimate_address_p (enum machine_mode, rtx, bool);
|
||||
extern rtx xtensa_legitimize_address (rtx, rtx, enum machine_mode);
|
||||
extern bool xtensa_tls_referenced_p (rtx);
|
||||
|
||||
#ifdef TREE_CODE
|
||||
extern void init_cumulative_args (CUMULATIVE_ARGS *, int);
|
||||
|
@ -131,6 +131,7 @@ static rtx gen_float_relational (enum rtx_code, rtx, rtx);
|
||||
static rtx gen_conditional_move (rtx);
|
||||
static rtx fixup_subreg_mem (rtx);
|
||||
static struct machine_function * xtensa_init_machine_status (void);
|
||||
static rtx xtensa_legitimize_tls_address (rtx);
|
||||
static bool xtensa_return_in_msb (const_tree);
|
||||
static void printx (FILE *, signed int);
|
||||
static void xtensa_function_epilogue (FILE *, HOST_WIDE_INT);
|
||||
@ -219,6 +220,12 @@ static const int reg_nonleaf_alloc_order[FIRST_PSEUDO_REGISTER] =
|
||||
#undef TARGET_SECONDARY_RELOAD
|
||||
#define TARGET_SECONDARY_RELOAD xtensa_secondary_reload
|
||||
|
||||
#undef TARGET_HAVE_TLS
|
||||
#define TARGET_HAVE_TLS (TARGET_THREADPTR && HAVE_AS_TLS)
|
||||
|
||||
#undef TARGET_CANNOT_FORCE_CONST_MEM
|
||||
#define TARGET_CANNOT_FORCE_CONST_MEM xtensa_tls_referenced_p
|
||||
|
||||
struct gcc_target targetm = TARGET_INITIALIZER;
|
||||
|
||||
|
||||
@ -469,6 +476,18 @@ constantpool_mem_p (rtx op)
|
||||
}
|
||||
|
||||
|
||||
/* Return TRUE if X is a thread-local symbol. */
|
||||
|
||||
static bool
|
||||
xtensa_tls_symbol_p (rtx x)
|
||||
{
|
||||
if (! TARGET_HAVE_TLS)
|
||||
return false;
|
||||
|
||||
return GET_CODE (x) == SYMBOL_REF && SYMBOL_REF_TLS_MODEL (x) != 0;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
xtensa_extend_reg (rtx dst, rtx src)
|
||||
{
|
||||
@ -910,12 +929,38 @@ xtensa_split_operand_pair (rtx operands[4], enum machine_mode mode)
|
||||
int
|
||||
xtensa_emit_move_sequence (rtx *operands, enum machine_mode mode)
|
||||
{
|
||||
if (CONSTANT_P (operands[1])
|
||||
&& (GET_CODE (operands[1]) != CONST_INT
|
||||
|| !xtensa_simm12b (INTVAL (operands[1]))))
|
||||
rtx src = operands[1];
|
||||
|
||||
if (CONSTANT_P (src)
|
||||
&& (GET_CODE (src) != CONST_INT || ! xtensa_simm12b (INTVAL (src))))
|
||||
{
|
||||
if (!TARGET_CONST16)
|
||||
operands[1] = force_const_mem (SImode, operands[1]);
|
||||
rtx dst = operands[0];
|
||||
|
||||
if (xtensa_tls_referenced_p (src))
|
||||
{
|
||||
rtx addend = NULL;
|
||||
|
||||
if (GET_CODE (src) == CONST && GET_CODE (XEXP (src, 0)) == PLUS)
|
||||
{
|
||||
addend = XEXP (XEXP (src, 0), 1);
|
||||
src = XEXP (XEXP (src, 0), 0);
|
||||
}
|
||||
|
||||
src = xtensa_legitimize_tls_address (src);
|
||||
if (addend)
|
||||
{
|
||||
src = gen_rtx_PLUS (mode, src, addend);
|
||||
src = force_operand (src, dst);
|
||||
}
|
||||
emit_move_insn (dst, src);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (! TARGET_CONST16)
|
||||
{
|
||||
src = force_const_mem (SImode, src);
|
||||
operands[1] = src;
|
||||
}
|
||||
|
||||
/* PC-relative loads are always SImode, and CONST16 is only
|
||||
supported in the movsi pattern, so add a SUBREG for any other
|
||||
@ -923,16 +968,16 @@ xtensa_emit_move_sequence (rtx *operands, enum machine_mode mode)
|
||||
|
||||
if (mode != SImode)
|
||||
{
|
||||
if (register_operand (operands[0], mode))
|
||||
if (register_operand (dst, mode))
|
||||
{
|
||||
operands[0] = simplify_gen_subreg (SImode, operands[0], mode, 0);
|
||||
emit_move_insn (operands[0], operands[1]);
|
||||
emit_move_insn (simplify_gen_subreg (SImode, dst, mode, 0), src);
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
operands[1] = force_reg (SImode, operands[1]);
|
||||
operands[1] = gen_lowpart_SUBREG (mode, operands[1]);
|
||||
src = force_reg (SImode, src);
|
||||
src = gen_lowpart_SUBREG (mode, src);
|
||||
operands[1] = src;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1664,7 +1709,8 @@ xtensa_legitimate_address_p (enum machine_mode mode, rtx addr, bool strict)
|
||||
{
|
||||
/* Allow constant pool addresses. */
|
||||
if (mode != BLKmode && GET_MODE_SIZE (mode) >= UNITS_PER_WORD
|
||||
&& ! TARGET_CONST16 && constantpool_address_p (addr))
|
||||
&& ! TARGET_CONST16 && constantpool_address_p (addr)
|
||||
&& ! xtensa_tls_referenced_p (addr))
|
||||
return true;
|
||||
|
||||
while (GET_CODE (addr) == SUBREG)
|
||||
@ -1709,11 +1755,97 @@ xtensa_legitimate_address_p (enum machine_mode mode, rtx addr, bool strict)
|
||||
}
|
||||
|
||||
|
||||
/* Construct the SYMBOL_REF for the _TLS_MODULE_BASE_ symbol. */
|
||||
|
||||
static GTY(()) rtx xtensa_tls_module_base_symbol;
|
||||
|
||||
static rtx
|
||||
xtensa_tls_module_base (void)
|
||||
{
|
||||
if (! xtensa_tls_module_base_symbol)
|
||||
{
|
||||
xtensa_tls_module_base_symbol =
|
||||
gen_rtx_SYMBOL_REF (Pmode, "_TLS_MODULE_BASE_");
|
||||
SYMBOL_REF_FLAGS (xtensa_tls_module_base_symbol)
|
||||
|= TLS_MODEL_GLOBAL_DYNAMIC << SYMBOL_FLAG_TLS_SHIFT;
|
||||
}
|
||||
|
||||
return xtensa_tls_module_base_symbol;
|
||||
}
|
||||
|
||||
|
||||
static rtx
|
||||
xtensa_call_tls_desc (rtx sym, rtx *retp)
|
||||
{
|
||||
rtx fn, arg, a10, call_insn, insns;
|
||||
|
||||
start_sequence ();
|
||||
fn = gen_reg_rtx (Pmode);
|
||||
arg = gen_reg_rtx (Pmode);
|
||||
a10 = gen_rtx_REG (Pmode, 10);
|
||||
|
||||
emit_insn (gen_tls_func (fn, sym));
|
||||
emit_insn (gen_tls_arg (arg, sym));
|
||||
emit_move_insn (a10, arg);
|
||||
call_insn = emit_call_insn (gen_tls_call (a10, fn, sym, const1_rtx));
|
||||
CALL_INSN_FUNCTION_USAGE (call_insn)
|
||||
= gen_rtx_EXPR_LIST (VOIDmode, gen_rtx_USE (VOIDmode, a10),
|
||||
CALL_INSN_FUNCTION_USAGE (call_insn));
|
||||
insns = get_insns ();
|
||||
end_sequence ();
|
||||
|
||||
*retp = a10;
|
||||
return insns;
|
||||
}
|
||||
|
||||
|
||||
static rtx
|
||||
xtensa_legitimize_tls_address (rtx x)
|
||||
{
|
||||
unsigned int model = SYMBOL_REF_TLS_MODEL (x);
|
||||
rtx dest, tp, ret, modbase, base, addend, insns;
|
||||
|
||||
dest = gen_reg_rtx (Pmode);
|
||||
switch (model)
|
||||
{
|
||||
case TLS_MODEL_GLOBAL_DYNAMIC:
|
||||
insns = xtensa_call_tls_desc (x, &ret);
|
||||
emit_libcall_block (insns, dest, ret, x);
|
||||
break;
|
||||
|
||||
case TLS_MODEL_LOCAL_DYNAMIC:
|
||||
base = gen_reg_rtx (Pmode);
|
||||
modbase = xtensa_tls_module_base ();
|
||||
insns = xtensa_call_tls_desc (modbase, &ret);
|
||||
emit_libcall_block (insns, base, ret, modbase);
|
||||
addend = force_reg (SImode, gen_sym_DTPOFF (x));
|
||||
emit_insn (gen_addsi3 (dest, base, addend));
|
||||
break;
|
||||
|
||||
case TLS_MODEL_INITIAL_EXEC:
|
||||
case TLS_MODEL_LOCAL_EXEC:
|
||||
tp = gen_reg_rtx (SImode);
|
||||
emit_insn (gen_load_tp (tp));
|
||||
addend = force_reg (SImode, gen_sym_TPOFF (x));
|
||||
emit_insn (gen_addsi3 (dest, tp, addend));
|
||||
break;
|
||||
|
||||
default:
|
||||
gcc_unreachable ();
|
||||
}
|
||||
|
||||
return dest;
|
||||
}
|
||||
|
||||
|
||||
rtx
|
||||
xtensa_legitimize_address (rtx x,
|
||||
rtx oldx ATTRIBUTE_UNUSED,
|
||||
enum machine_mode mode)
|
||||
{
|
||||
if (xtensa_tls_symbol_p (x))
|
||||
return xtensa_legitimize_tls_address (x);
|
||||
|
||||
if (GET_CODE (x) == PLUS)
|
||||
{
|
||||
rtx plus0 = XEXP (x, 0);
|
||||
@ -1745,6 +1877,46 @@ xtensa_legitimize_address (rtx x,
|
||||
}
|
||||
|
||||
|
||||
/* Helper for xtensa_tls_referenced_p. */
|
||||
|
||||
static int
|
||||
xtensa_tls_referenced_p_1 (rtx *x, void *data ATTRIBUTE_UNUSED)
|
||||
{
|
||||
if (GET_CODE (*x) == SYMBOL_REF)
|
||||
return SYMBOL_REF_TLS_MODEL (*x) != 0;
|
||||
|
||||
/* Ignore TLS references that have already been legitimized. */
|
||||
if (GET_CODE (*x) == UNSPEC)
|
||||
{
|
||||
switch (XINT (*x, 1))
|
||||
{
|
||||
case UNSPEC_TPOFF:
|
||||
case UNSPEC_DTPOFF:
|
||||
case UNSPEC_TLS_FUNC:
|
||||
case UNSPEC_TLS_ARG:
|
||||
case UNSPEC_TLS_CALL:
|
||||
return -1;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* Return TRUE if X contains any TLS symbol references. */
|
||||
|
||||
bool
|
||||
xtensa_tls_referenced_p (rtx x)
|
||||
{
|
||||
if (! TARGET_HAVE_TLS)
|
||||
return false;
|
||||
|
||||
return for_each_rtx (&x, xtensa_tls_referenced_p_1, NULL);
|
||||
}
|
||||
|
||||
|
||||
/* Return the debugger register number to use for 'regno'. */
|
||||
|
||||
int
|
||||
@ -2204,6 +2376,14 @@ xtensa_output_addr_const_extra (FILE *fp, rtx x)
|
||||
{
|
||||
switch (XINT (x, 1))
|
||||
{
|
||||
case UNSPEC_TPOFF:
|
||||
output_addr_const (fp, XVECEXP (x, 0, 0));
|
||||
fputs ("@TPOFF", fp);
|
||||
return true;
|
||||
case UNSPEC_DTPOFF:
|
||||
output_addr_const (fp, XVECEXP (x, 0, 0));
|
||||
fputs ("@DTPOFF", fp);
|
||||
return true;
|
||||
case UNSPEC_PLT:
|
||||
if (flag_pic)
|
||||
{
|
||||
@ -2760,6 +2940,8 @@ xtensa_gimplify_va_arg_expr (tree valist, tree type, gimple_seq *pre_p,
|
||||
enum xtensa_builtin
|
||||
{
|
||||
XTENSA_BUILTIN_UMULSIDI3,
|
||||
XTENSA_BUILTIN_THREAD_POINTER,
|
||||
XTENSA_BUILTIN_SET_THREAD_POINTER,
|
||||
XTENSA_BUILTIN_max
|
||||
};
|
||||
|
||||
@ -2767,15 +2949,34 @@ enum xtensa_builtin
|
||||
static void
|
||||
xtensa_init_builtins (void)
|
||||
{
|
||||
tree ftype;
|
||||
tree ftype, decl;
|
||||
|
||||
ftype = build_function_type_list (unsigned_intDI_type_node,
|
||||
unsigned_intSI_type_node,
|
||||
unsigned_intSI_type_node, NULL_TREE);
|
||||
|
||||
add_builtin_function ("__builtin_umulsidi3", ftype,
|
||||
XTENSA_BUILTIN_UMULSIDI3, BUILT_IN_MD,
|
||||
"__umulsidi3", NULL_TREE);
|
||||
decl = add_builtin_function ("__builtin_umulsidi3", ftype,
|
||||
XTENSA_BUILTIN_UMULSIDI3, BUILT_IN_MD,
|
||||
"__umulsidi3", NULL_TREE);
|
||||
TREE_NOTHROW (decl) = 1;
|
||||
TREE_READONLY (decl) = 1;
|
||||
|
||||
if (TARGET_THREADPTR)
|
||||
{
|
||||
ftype = build_function_type (ptr_type_node, void_list_node);
|
||||
decl = add_builtin_function ("__builtin_thread_pointer", ftype,
|
||||
XTENSA_BUILTIN_THREAD_POINTER, BUILT_IN_MD,
|
||||
NULL, NULL_TREE);
|
||||
TREE_READONLY (decl) = 1;
|
||||
TREE_NOTHROW (decl) = 1;
|
||||
|
||||
ftype = build_function_type_list (void_type_node, ptr_type_node,
|
||||
NULL_TREE);
|
||||
decl = add_builtin_function ("__builtin_set_thread_pointer", ftype,
|
||||
XTENSA_BUILTIN_SET_THREAD_POINTER,
|
||||
BUILT_IN_MD, NULL, NULL_TREE);
|
||||
TREE_NOTHROW (decl) = 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -2785,8 +2986,9 @@ xtensa_fold_builtin (tree fndecl, tree arglist, bool ignore ATTRIBUTE_UNUSED)
|
||||
unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
|
||||
tree arg0, arg1;
|
||||
|
||||
if (fcode == XTENSA_BUILTIN_UMULSIDI3)
|
||||
switch (fcode)
|
||||
{
|
||||
case XTENSA_BUILTIN_UMULSIDI3:
|
||||
arg0 = TREE_VALUE (arglist);
|
||||
arg1 = TREE_VALUE (TREE_CHAIN (arglist));
|
||||
if ((TREE_CODE (arg0) == INTEGER_CST && TREE_CODE (arg1) == INTEGER_CST)
|
||||
@ -2794,11 +2996,17 @@ xtensa_fold_builtin (tree fndecl, tree arglist, bool ignore ATTRIBUTE_UNUSED)
|
||||
return fold_build2 (MULT_EXPR, unsigned_intDI_type_node,
|
||||
fold_convert (unsigned_intDI_type_node, arg0),
|
||||
fold_convert (unsigned_intDI_type_node, arg1));
|
||||
else
|
||||
return NULL;
|
||||
break;
|
||||
|
||||
case XTENSA_BUILTIN_THREAD_POINTER:
|
||||
case XTENSA_BUILTIN_SET_THREAD_POINTER:
|
||||
break;
|
||||
|
||||
default:
|
||||
internal_error ("bad builtin code");
|
||||
break;
|
||||
}
|
||||
|
||||
internal_error ("bad builtin code");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -2811,14 +3019,32 @@ xtensa_expand_builtin (tree exp, rtx target,
|
||||
{
|
||||
tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
|
||||
unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
|
||||
rtx arg;
|
||||
|
||||
/* The umulsidi3 builtin is just a mechanism to avoid calling the real
|
||||
__umulsidi3 function when the Xtensa configuration can directly
|
||||
implement it. If not, just call the function. */
|
||||
if (fcode == XTENSA_BUILTIN_UMULSIDI3)
|
||||
return expand_call (exp, target, ignore);
|
||||
switch (fcode)
|
||||
{
|
||||
case XTENSA_BUILTIN_UMULSIDI3:
|
||||
/* The umulsidi3 builtin is just a mechanism to avoid calling the real
|
||||
__umulsidi3 function when the Xtensa configuration can directly
|
||||
implement it. If not, just call the function. */
|
||||
return expand_call (exp, target, ignore);
|
||||
|
||||
internal_error ("bad builtin code");
|
||||
case XTENSA_BUILTIN_THREAD_POINTER:
|
||||
if (!target || !register_operand (target, Pmode))
|
||||
target = gen_reg_rtx (Pmode);
|
||||
emit_insn (gen_load_tp (target));
|
||||
return target;
|
||||
|
||||
case XTENSA_BUILTIN_SET_THREAD_POINTER:
|
||||
arg = expand_normal (CALL_EXPR_ARG (exp, 0));
|
||||
if (!register_operand (arg, Pmode))
|
||||
arg = copy_to_mode_reg (Pmode, arg);
|
||||
emit_insn (gen_set_tp (arg));
|
||||
return const0_rtx;
|
||||
|
||||
default:
|
||||
internal_error ("bad builtin code");
|
||||
}
|
||||
return NULL_RTX;
|
||||
}
|
||||
|
||||
|
@ -51,6 +51,9 @@ extern unsigned xtensa_current_frame_size;
|
||||
#ifndef XCHAL_HAVE_S32C1I
|
||||
#define XCHAL_HAVE_S32C1I 0
|
||||
#endif
|
||||
#ifndef XCHAL_HAVE_THREADPTR
|
||||
#define XCHAL_HAVE_THREADPTR 0
|
||||
#endif
|
||||
#define TARGET_BIG_ENDIAN XCHAL_HAVE_BE
|
||||
#define TARGET_DENSITY XCHAL_HAVE_DENSITY
|
||||
#define TARGET_MAC16 XCHAL_HAVE_MAC16
|
||||
@ -72,11 +75,16 @@ extern unsigned xtensa_current_frame_size;
|
||||
#define TARGET_RELEASE_SYNC XCHAL_HAVE_RELEASE_SYNC
|
||||
#define TARGET_S32C1I XCHAL_HAVE_S32C1I
|
||||
#define TARGET_ABSOLUTE_LITERALS XSHAL_USE_ABSOLUTE_LITERALS
|
||||
#define TARGET_THREADPTR XCHAL_HAVE_THREADPTR
|
||||
|
||||
#define TARGET_DEFAULT \
|
||||
((XCHAL_HAVE_L32R ? 0 : MASK_CONST16) | \
|
||||
MASK_SERIALIZE_VOLATILE)
|
||||
|
||||
#ifndef HAVE_AS_TLS
|
||||
#define HAVE_AS_TLS 0
|
||||
#endif
|
||||
|
||||
#define OVERRIDE_OPTIONS override_options ()
|
||||
|
||||
/* Reordering blocks for Xtensa is not a good idea unless the compiler
|
||||
@ -791,7 +799,7 @@ typedef struct xtensa_args
|
||||
|
||||
/* Nonzero if the constant value X is a legitimate general operand.
|
||||
It is given that X satisfies CONSTANT_P or is a CONST_DOUBLE. */
|
||||
#define LEGITIMATE_CONSTANT_P(X) 1
|
||||
#define LEGITIMATE_CONSTANT_P(X) (! xtensa_tls_referenced_p (X))
|
||||
|
||||
/* A C expression that is nonzero if X is a legitimate immediate
|
||||
operand on the target machine when generating position independent
|
||||
|
@ -29,6 +29,12 @@
|
||||
(UNSPEC_NOP 2)
|
||||
(UNSPEC_PLT 3)
|
||||
(UNSPEC_RET_ADDR 4)
|
||||
(UNSPEC_TPOFF 5)
|
||||
(UNSPEC_DTPOFF 6)
|
||||
(UNSPEC_TLS_FUNC 7)
|
||||
(UNSPEC_TLS_ARG 8)
|
||||
(UNSPEC_TLS_CALL 9)
|
||||
(UNSPEC_TP 10)
|
||||
|
||||
(UNSPECV_SET_FP 1)
|
||||
(UNSPECV_ENTRY 2)
|
||||
@ -36,6 +42,7 @@
|
||||
(UNSPECV_S32RI 4)
|
||||
(UNSPECV_S32C1I 5)
|
||||
(UNSPECV_EH_RETURN 6)
|
||||
(UNSPECV_SET_TP 7)
|
||||
])
|
||||
|
||||
;; This code iterator allows signed and unsigned widening multiplications
|
||||
@ -1560,9 +1567,9 @@
|
||||
})
|
||||
|
||||
(define_insn "call_value_internal"
|
||||
[(set (match_operand 0 "register_operand" "=a")
|
||||
(call (mem (match_operand:SI 1 "call_insn_operand" "nir"))
|
||||
(match_operand 2 "" "i")))]
|
||||
[(set (match_operand 0 "register_operand" "=a")
|
||||
(call (mem (match_operand:SI 1 "call_insn_operand" "nir"))
|
||||
(match_operand 2 "" "i")))]
|
||||
""
|
||||
{
|
||||
return xtensa_emit_call (1, operands);
|
||||
@ -1697,6 +1704,69 @@
|
||||
(set_attr "mode" "none")
|
||||
(set_attr "length" "0")])
|
||||
|
||||
|
||||
;; TLS support
|
||||
|
||||
(define_expand "sym_TPOFF"
|
||||
[(const (unspec [(match_operand:SI 0 "" "")] UNSPEC_TPOFF))]
|
||||
""
|
||||
"")
|
||||
|
||||
(define_expand "sym_DTPOFF"
|
||||
[(const (unspec [(match_operand:SI 0 "" "")] UNSPEC_DTPOFF))]
|
||||
""
|
||||
"")
|
||||
|
||||
(define_insn "load_tp"
|
||||
[(set (match_operand:SI 0 "register_operand" "=a")
|
||||
(unspec:SI [(const_int 0)] UNSPEC_TP))]
|
||||
"TARGET_THREADPTR"
|
||||
"rur\t%0, THREADPTR"
|
||||
[(set_attr "type" "rsr")
|
||||
(set_attr "mode" "SI")
|
||||
(set_attr "length" "3")])
|
||||
|
||||
(define_insn "set_tp"
|
||||
[(unspec_volatile [(match_operand:SI 0 "register_operand" "r")]
|
||||
UNSPECV_SET_TP)]
|
||||
"TARGET_THREADPTR"
|
||||
"wur\t%0, THREADPTR"
|
||||
[(set_attr "type" "wsr")
|
||||
(set_attr "mode" "SI")
|
||||
(set_attr "length" "3")])
|
||||
|
||||
(define_insn "tls_func"
|
||||
[(set (match_operand:SI 0 "register_operand" "=a")
|
||||
(unspec:SI [(match_operand:SI 1 "tls_symbol_operand" "")]
|
||||
UNSPEC_TLS_FUNC))]
|
||||
"TARGET_THREADPTR && HAVE_AS_TLS"
|
||||
"movi\t%0, %1@TLSFUNC"
|
||||
[(set_attr "type" "load")
|
||||
(set_attr "mode" "SI")
|
||||
(set_attr "length" "3")])
|
||||
|
||||
(define_insn "tls_arg"
|
||||
[(set (match_operand:SI 0 "register_operand" "=a")
|
||||
(unspec:SI [(match_operand:SI 1 "tls_symbol_operand" "")]
|
||||
UNSPEC_TLS_ARG))]
|
||||
"TARGET_THREADPTR && HAVE_AS_TLS"
|
||||
"movi\t%0, %1@TLSARG"
|
||||
[(set_attr "type" "load")
|
||||
(set_attr "mode" "SI")
|
||||
(set_attr "length" "3")])
|
||||
|
||||
(define_insn "tls_call"
|
||||
[(set (match_operand:SI 0 "register_operand" "=a")
|
||||
(call (mem:SI (unspec:SI [(match_operand:SI 1 "register_operand" "r")
|
||||
(match_operand:SI 2 "tls_symbol_operand" "")]
|
||||
UNSPEC_TLS_CALL))
|
||||
(match_operand 3 "" "i")))]
|
||||
"TARGET_THREADPTR && HAVE_AS_TLS"
|
||||
"callx8.tls %1, %2@TLSCALL"
|
||||
[(set_attr "type" "call")
|
||||
(set_attr "mode" "none")
|
||||
(set_attr "length" "3")])
|
||||
|
||||
|
||||
;; Instructions for the Xtensa "boolean" option.
|
||||
|
||||
|
13
gcc/configure
vendored
13
gcc/configure
vendored
@ -21194,7 +21194,7 @@ cat >>confdefs.h <<_ACEOF
|
||||
_ACEOF
|
||||
|
||||
|
||||
# Thread-local storage - the check is heavily parametrized.
|
||||
# Thread-local storage - the check is heavily parameterized.
|
||||
conftest_s=
|
||||
tls_first_major=
|
||||
tls_first_minor=
|
||||
@ -21526,6 +21526,17 @@ foo: .long 25
|
||||
tls_as_opt="-32 --fatal-warnings"
|
||||
fi
|
||||
;;
|
||||
xtensa*-*-*)
|
||||
conftest_s='
|
||||
.section ".tdata","awT",@progbits
|
||||
foo: .long 25
|
||||
.text
|
||||
movi a8, foo@TLSFUNC
|
||||
movi a10, foo@TLSARG
|
||||
callx8.tls a8, foo@TLSCALL'
|
||||
tls_first_major=2
|
||||
tls_first_minor=19
|
||||
;;
|
||||
esac
|
||||
set_have_as_tls=no
|
||||
if test "x$enable_tls" = xno ; then
|
||||
|
@ -2322,7 +2322,7 @@ AC_DEFINE_UNQUOTED(HAVE_COMDAT_GROUP,
|
||||
[`if test $gcc_cv_as_comdat_group = yes || test $gcc_cv_as_comdat_group_percent = yes; then echo 1; else echo 0; fi`],
|
||||
[Define 0/1 if your assembler and linker support COMDAT groups.])
|
||||
|
||||
# Thread-local storage - the check is heavily parametrized.
|
||||
# Thread-local storage - the check is heavily parameterized.
|
||||
conftest_s=
|
||||
tls_first_major=
|
||||
tls_first_minor=
|
||||
@ -2655,6 +2655,17 @@ foo: .long 25
|
||||
tls_as_opt="-32 --fatal-warnings"
|
||||
fi
|
||||
;;
|
||||
xtensa*-*-*)
|
||||
conftest_s='
|
||||
.section ".tdata","awT",@progbits
|
||||
foo: .long 25
|
||||
.text
|
||||
movi a8, foo@TLSFUNC
|
||||
movi a10, foo@TLSARG
|
||||
callx8.tls a8, foo@TLSCALL'
|
||||
tls_first_major=2
|
||||
tls_first_minor=19
|
||||
;;
|
||||
changequote([,])dnl
|
||||
esac
|
||||
set_have_as_tls=no
|
||||
|
Loading…
x
Reference in New Issue
Block a user