configure.ac (hppa*-*-linux*): Check for a TLS capable gas.

* configure.ac (hppa*-*-linux*: Check for a TLS capable gas.
	* configure: Regenerate.
	* config/pa/pa-protos.h (tls_symbolic_operand): Declare.
	(pa_tls_referenced_p): Declare.
	* config/pa/pa.c (legitimize_pic_address): Reject TLS operands.
	(gen_tls_tga, gen_tls_get_addr, hppa_tls_call): New.
	(legitimize_tls_address): New.
	(hppa_legitimize_address): Handle TLS addresses.
	(pa_tls_symbol_ref_1, pa_tls_referenced_p): New.
	(TARGET_CANNOT_FORCE_CONST_MEM): Define.
	(emit_move_sequence): Handle TLS addresses.
	(pa_encode_section_info): Call default handler to handle common
	sections.
	* config/pa/pa.h (PA_SYMBOL_REF_TLS_P): New.
	(CONSTANT_ADDRESS_P): Reject TLS operands.
	(TARGET_HAVE_TLS) [HAVE_AS_TLS]: Define.
	* config/pa/pa.md (UNSPEC_TP, UNSPEC_TLSGD, UNSPEC_TLSLDM)
	(UNSPEC_TLSLDO, UNSPEC_TLSLDBASE, UNSPEC_TLSIE)
	(UNSPEC_TLSLE): Define new constants.
	(tgd_load, tld_load, tld_offset_load, tp_load, tie_load, tle_load): New.
	* config/pa/predicates.md (symbolic_operand): Reject TLS operands.
	(tls_symbolic_operand, tgd_symbolic_operand, tld_symbolic_operand)
	(tie_symbolic_operand, tle_symbolic_operand): New

From-SVN: r101648
This commit is contained in:
Randolph Chung 2005-07-06 02:18:21 +00:00 committed by John David Anglin
parent f04f1d2c63
commit 51076f9604
8 changed files with 335 additions and 5 deletions

View File

@ -1,3 +1,29 @@
2005-07-05 Randolph Chung <tausq@debian.org>
* configure.ac (hppa*-*-linux*: Check for a TLS capable gas.
* configure: Regenerate.
* config/pa/pa-protos.h (tls_symbolic_operand): Declare.
(pa_tls_referenced_p): Declare.
* config/pa/pa.c (legitimize_pic_address): Reject TLS operands.
(gen_tls_tga, gen_tls_get_addr, hppa_tls_call): New.
(legitimize_tls_address): New.
(hppa_legitimize_address): Handle TLS addresses.
(pa_tls_symbol_ref_1, pa_tls_referenced_p): New.
(TARGET_CANNOT_FORCE_CONST_MEM): Define.
(emit_move_sequence): Handle TLS addresses.
(pa_encode_section_info): Call default handler to handle common
sections.
* config/pa/pa.h (PA_SYMBOL_REF_TLS_P): New.
(CONSTANT_ADDRESS_P): Reject TLS operands.
(TARGET_HAVE_TLS) [HAVE_AS_TLS]: Define.
* config/pa/pa.md (UNSPEC_TP, UNSPEC_TLSGD, UNSPEC_TLSLDM)
(UNSPEC_TLSLDO, UNSPEC_TLSLDBASE, UNSPEC_TLSIE)
(UNSPEC_TLSLE): Define new constants.
(tgd_load, tld_load, tld_offset_load, tp_load, tie_load, tle_load): New.
* config/pa/predicates.md (symbolic_operand): Reject TLS operands.
(tls_symbolic_operand, tgd_symbolic_operand, tld_symbolic_operand)
(tie_symbolic_operand, tle_symbolic_operand): New
2005-07-06 Kelley Cook <kcook@gcc.gnu.org>
* aclocal.m4: Update macros for autoconf 2.59 style.

View File

@ -22,6 +22,7 @@ Boston, MA 02110-1301, USA. */
#ifdef RTX_CODE
/* Prototype function used in various macros. */
extern int symbolic_operand (rtx, enum machine_mode);
extern int tls_symbolic_operand (rtx);
/* Used in insn-*.c. */
extern int following_call (rtx);
@ -67,6 +68,7 @@ extern int adddi3_operand (rtx, enum machine_mode);
extern int indexed_memory_operand (rtx, enum machine_mode);
extern int symbolic_expression_p (rtx);
extern int symbolic_memory_operand (rtx, enum machine_mode);
extern bool pa_tls_referenced_p (rtx);
extern int pa_adjust_insn_length (rtx, int);
extern int int11_operand (rtx, enum machine_mode);
extern int reg_or_cint_move_operand (rtx, enum machine_mode);

View File

@ -292,6 +292,9 @@ static size_t n_deferred_plabels = 0;
#undef TARGET_SCALAR_MODE_SUPPORTED_P
#define TARGET_SCALAR_MODE_SUPPORTED_P pa_scalar_mode_supported_p
#undef TARGET_CANNOT_FORCE_CONST_MEM
#define TARGET_CANNOT_FORCE_CONST_MEM pa_tls_referenced_p
struct gcc_target targetm = TARGET_INITIALIZER;
/* Parse the -mfixed-range= option string. */
@ -595,6 +598,9 @@ legitimize_pic_address (rtx orig, enum machine_mode mode, rtx reg)
{
rtx pic_ref = orig;
if (PA_SYMBOL_REF_TLS_P (orig))
abort();
/* Labels need special handling. */
if (pic_label_operand (orig, mode))
{
@ -671,6 +677,80 @@ legitimize_pic_address (rtx orig, enum machine_mode mode, rtx reg)
return pic_ref;
}
static GTY(()) rtx gen_tls_tga;
static rtx
gen_tls_get_addr (void)
{
if (!gen_tls_tga)
gen_tls_tga = init_one_libfunc ("__tls_get_addr");
return gen_tls_tga;
}
static rtx
hppa_tls_call (rtx arg)
{
rtx ret;
ret = gen_reg_rtx (Pmode);
emit_library_call_value (gen_tls_get_addr (), ret,
LCT_CONST, Pmode, 1, arg, Pmode);
return ret;
}
static rtx
legitimize_tls_address (rtx addr)
{
rtx ret, insn, tmp, t1, t2, tp;
enum tls_model model = SYMBOL_REF_TLS_MODEL (addr);
switch (model)
{
case TLS_MODEL_GLOBAL_DYNAMIC:
tmp = gen_reg_rtx (Pmode);
emit_insn (gen_tgd_load (tmp, addr));
ret = hppa_tls_call (tmp);
break;
case TLS_MODEL_LOCAL_DYNAMIC:
ret = gen_reg_rtx (Pmode);
tmp = gen_reg_rtx (Pmode);
start_sequence ();
emit_insn (gen_tld_load (tmp, addr));
t1 = hppa_tls_call (tmp);
insn = get_insns ();
end_sequence ();
t2 = gen_reg_rtx (Pmode);
emit_libcall_block (insn, t2, t1,
gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
UNSPEC_TLSLDBASE));
emit_insn (gen_tld_offset_load (ret, addr, t2));
break;
case TLS_MODEL_INITIAL_EXEC:
tp = gen_reg_rtx (Pmode);
tmp = gen_reg_rtx (Pmode);
ret = gen_reg_rtx (Pmode);
emit_insn (gen_tp_load (tp));
emit_insn (gen_tie_load (tmp, addr));
emit_move_insn (ret, gen_rtx_PLUS (Pmode, tp, tmp));
break;
case TLS_MODEL_LOCAL_EXEC:
tp = gen_reg_rtx (Pmode);
ret = gen_reg_rtx (Pmode);
emit_insn (gen_tp_load (tp));
emit_insn (gen_tle_load (ret, addr, tp));
break;
default:
abort();
}
return ret;
}
/* Try machine-dependent ways of modifying an illegitimate address
to be legitimate. If we find one, return the new, valid address.
This macro is used in only one place: `memory_address' in explow.c.
@ -740,7 +820,9 @@ hppa_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED,
&& !REG_POINTER (XEXP (x, 1)))
return gen_rtx_PLUS (Pmode, XEXP (x, 1), XEXP (x, 0));
if (flag_pic)
if (PA_SYMBOL_REF_TLS_P (x))
return legitimize_tls_address (x);
else if (flag_pic)
return legitimize_pic_address (x, mode, gen_reg_rtx (Pmode));
/* Strip off CONST. */
@ -1190,6 +1272,25 @@ force_mode (enum machine_mode mode, rtx orig)
return gen_rtx_REG (mode, REGNO (orig));
}
/* Return 1 if *X is a thread-local symbol. */
static int
pa_tls_symbol_ref_1 (rtx *x, void *data ATTRIBUTE_UNUSED)
{
return PA_SYMBOL_REF_TLS_P (*x);
}
/* Return 1 if X contains a thread-local symbol. */
bool
pa_tls_referenced_p (rtx x)
{
if (!TARGET_HAVE_TLS)
return false;
return for_each_rtx (&x, &pa_tls_symbol_ref_1, 0);
}
/* Emit insns to move operands[1] into operands[0].
Return 1 if we have written out everything that needs to be done to
@ -1707,6 +1808,26 @@ emit_move_sequence (rtx *operands, enum machine_mode mode, rtx scratch_reg)
}
return 1;
}
else if (pa_tls_referenced_p (operand1))
{
rtx tmp = operand1;
rtx addend = NULL;
if (GET_CODE (tmp) == CONST && GET_CODE (XEXP (tmp, 0)) == PLUS)
{
addend = XEXP (XEXP (tmp, 0), 1);
tmp = XEXP (XEXP (tmp, 0), 0);
}
gcc_assert (GET_CODE (tmp) == SYMBOL_REF);
tmp = legitimize_tls_address (tmp);
if (addend)
{
tmp = gen_rtx_PLUS (mode, tmp, addend);
tmp = force_operand (tmp, operands[0]);
}
operands[1] = tmp;
}
else if (GET_CODE (operand1) != CONST_INT
|| !cint_ok_for_move (INTVAL (operand1)))
{
@ -7371,6 +7492,8 @@ hppa_encode_label (rtx sym)
static void
pa_encode_section_info (tree decl, rtx rtl, int first)
{
default_encode_section_info (decl, rtl, first);
if (first && TEXT_SPACE_P (decl))
{
SYMBOL_REF_FLAG (XEXP (rtl, 0)) = 1;

View File

@ -1003,13 +1003,18 @@ extern int may_call_alloca;
#define MAX_REGS_PER_ADDRESS 2
/* Non-TLS symbolic references. */
#define PA_SYMBOL_REF_TLS_P(RTX) \
(GET_CODE (RTX) == SYMBOL_REF && SYMBOL_REF_TLS_MODEL (RTX) != 0)
/* Recognize any constant value that is a valid address except
for symbolic addresses. We get better CSE by rejecting them
here and allowing hppa_legitimize_address to break them up. We
use most of the constants accepted by CONSTANT_P, except CONST_DOUBLE. */
#define CONSTANT_ADDRESS_P(X) \
((GET_CODE (X) == LABEL_REF || GET_CODE (X) == SYMBOL_REF \
((GET_CODE (X) == LABEL_REF \
|| (GET_CODE (X) == SYMBOL_REF && !SYMBOL_REF_TLS_MODEL (X)) \
|| GET_CODE (X) == CONST_INT || GET_CODE (X) == CONST \
|| GET_CODE (X) == HIGH) \
&& (reload_in_progress || reload_completed || ! symbolic_expression_p (X)))
@ -1919,3 +1924,8 @@ forget_section (void) \
/* We need a libcall to canonicalize function pointers on TARGET_ELF32. */
#define CANONICALIZE_FUNCPTR_FOR_COMPARE_LIBCALL \
"__canonicalize_funcptr_for_compare"
#ifdef HAVE_AS_TLS
#undef TARGET_HAVE_TLS
#define TARGET_HAVE_TLS true
#endif

View File

@ -32,6 +32,13 @@
[(UNSPEC_CFFC 0) ; canonicalize_funcptr_for_compare
(UNSPEC_GOTO 1) ; indirect_goto
(UNSPEC_DLTIND14R 2) ;
(UNSPEC_TP 3)
(UNSPEC_TLSGD 4)
(UNSPEC_TLSLDM 5)
(UNSPEC_TLSLDO 6)
(UNSPEC_TLSLDBASE 7)
(UNSPEC_TLSIE 8)
(UNSPEC_TLSLE 9)
])
;; UNSPEC_VOLATILE:
@ -9347,3 +9354,83 @@ add,l %2,%3,%3\;bv,n %%r0(%3)"
}
[(set_attr "type" "load")
(set_attr "length" "4")])
;; TLS Support
(define_insn "tgd_load"
[(set (match_operand:SI 0 "register_operand" "=r")
(unspec:SI [(match_operand 1 "tgd_symbolic_operand" "")] UNSPEC_TLSGD))
(clobber (reg:SI 1))]
""
"*
{
if (flag_pic)
return \"addil LT'%1-$tls_gdidx$,%%r19\;ldo RT'%1-$tls_gdidx$(%%r1),%0\";
else
return \"addil LR'%1-$tls_gdidx$,%%r27\;ldo RR'%1-$tls_gdidx$(%%r1),%0\";
}"
[(set_attr "type" "multi")
(set_attr "length" "8")])
(define_insn "tld_load"
[(set (match_operand:SI 0 "register_operand" "=r")
(unspec:SI [(match_operand 1 "tld_symbolic_operand" "")] UNSPEC_TLSLDM))
(clobber (reg:SI 1))]
""
"*
{
if (flag_pic)
return \"addil LT'%1-$tls_ldidx$,%%r19\;ldo RT'%1-$tls_ldidx$(%%r1),%0\";
else
return \"addil LR'%1-$tls_ldidx$,%%r27\;ldo RR'%1-$tls_ldidx$(%%r1),%0\";
}"
[(set_attr "type" "multi")
(set_attr "length" "8")])
(define_insn "tld_offset_load"
[(set (match_operand:SI 0 "register_operand" "=r")
(plus:SI (unspec:SI [(match_operand 1 "tld_symbolic_operand" "")]
UNSPEC_TLSLDO)
(match_operand:SI 2 "register_operand" "r")))
(clobber (reg:SI 1))]
""
"*
{
return \"addil LR'%1-$tls_dtpoff$,%2\;ldo RR'%1-$tls_dtpoff$(%%r1),%0\";
}"
[(set_attr "type" "multi")
(set_attr "length" "8")])
(define_insn "tp_load"
[(set (match_operand:SI 0 "register_operand" "=r")
(unspec:SI [(const_int 0)] UNSPEC_TP))]
""
"{mfctl|mfctl,w} %%cr27,%0"
[(set_attr "type" "multi")
(set_attr "length" "4")])
(define_insn "tie_load"
[(set (match_operand:SI 0 "register_operand" "=r")
(unspec:SI [(match_operand 1 "tie_symbolic_operand" "")] UNSPEC_TLSIE))
(clobber (reg:SI 1))]
""
"*
{
if (flag_pic)
return \"addil LT'%1-$tls_ieoff$,%%r19\;ldw RT'%1-$tls_ieoff$(%%r1),%0\";
else
return \"addil LR'%1-$tls_ieoff$,%%r27\;ldw RR'%1-$tls_ieoff$(%%r1),%0\";
}"
[(set_attr "type" "multi")
(set_attr "length" "8")])
(define_insn "tle_load"
[(set (match_operand:SI 0 "register_operand" "=r")
(plus:SI (unspec:SI [(match_operand 1 "tle_symbolic_operand" "")]
UNSPEC_TLSLE)
(match_operand:SI 2 "register_operand" "r")))
(clobber (reg:SI 1))]
""
"addil LR'%1-$tls_leoff$,%2\;ldo RR'%1-$tls_leoff$(%%r1),%0"
[(set_attr "type" "multi")
(set_attr "length" "8")])

View File

@ -68,11 +68,13 @@
switch (GET_CODE (op))
{
case SYMBOL_REF:
return !SYMBOL_REF_TLS_MODEL (op);
case LABEL_REF:
return 1;
case CONST:
op = XEXP (op, 0);
return ((GET_CODE (XEXP (op, 0)) == SYMBOL_REF
return (((GET_CODE (XEXP (op, 0)) == SYMBOL_REF
&& !SYMBOL_REF_TLS_MODEL (XEXP (op, 0)))
|| GET_CODE (XEXP (op, 0)) == LABEL_REF)
&& GET_CODE (XEXP (op, 1)) == CONST_INT);
default:
@ -91,10 +93,32 @@
if (GET_CODE (op) != MEM)
return 0;
op = XEXP (op, 0);
return (GET_CODE (op) == SYMBOL_REF || GET_CODE (op) == CONST
|| GET_CODE (op) == HIGH || GET_CODE (op) == LABEL_REF);
return ((GET_CODE (op) == SYMBOL_REF && !SYMBOL_REF_TLS_MODEL (op))
|| GET_CODE (op) == CONST || GET_CODE (op) == HIGH
|| GET_CODE (op) == LABEL_REF);
})
;; Return true if OP is a symbolic operand for the TLS Global Dynamic model.
(define_predicate "tgd_symbolic_operand"
(and (match_code "symbol_ref")
(match_test "SYMBOL_REF_TLS_MODEL (op) == TLS_MODEL_GLOBAL_DYNAMIC")))
;; Return true if OP is a symbolic operand for the TLS Local Dynamic model.
(define_predicate "tld_symbolic_operand"
(and (match_code "symbol_ref")
(match_test "SYMBOL_REF_TLS_MODEL (op) == TLS_MODEL_LOCAL_DYNAMIC")))
;; Return true if OP is a symbolic operand for the TLS Initial Exec model.
(define_predicate "tie_symbolic_operand"
(and (match_code "symbol_ref")
(match_test "SYMBOL_REF_TLS_MODEL (op) == TLS_MODEL_INITIAL_EXEC")))
;; Return true if OP is a symbolic operand for the TLS Local Exec model.
(define_predicate "tle_symbolic_operand"
(and (match_code "symbol_ref")
(match_test "SYMBOL_REF_TLS_MODEL (op) == TLS_MODEL_LOCAL_EXEC")))
;; Return 1 if the operand is a register operand or a non-symbolic
;; memory operand after reload. This predicate is used for branch
;; patterns that internally handle register reloading. We need to

29
gcc/configure vendored
View File

@ -14015,6 +14015,35 @@ x: .long 25
tls_first_major=2
tls_first_minor=14
;;
hppa*-*-linux*)
conftest_s='
t1: .reg %r20
t2: .reg %r21
gp: .reg %r19
.section ".tdata","awT",@progbits
foo: .long 25
.text
.align 4
addil LT%foo-$tls_gdidx$,gp
ldo RT%foo-$tls_gdidx$(%r1),%arg0
b __tls_get_addr
nop
addil LT%foo-$tls_ldidx$,gp
b __tls_get_addr
ldo RT%foo-$tls_ldidx$(%r1),%arg0
addil LR%foo-$tls_dtpoff$,%ret0
ldo RR%foo-$tls_dtpoff$(%r1),%t1
mfctl %cr27,%t1
addil LT%foo-$tls_ieoff$,gp
ldw RT%foo-$tls_ieoff$(%r1),%t2
add %t1,%t2,%t3
mfctl %cr27,%t1
addil LR%foo-$tls_leoff$,%t1
ldo RR%foo-$tls_leoff$(%r1),%t2'
tls_first_major=2
tls_first_minor=15
tls_as_opt=--fatal-warnings
;;
i[34567]86-*-*)
conftest_s='
.section ".tdata","awT",@progbits

View File

@ -2189,6 +2189,35 @@ x: .long 25
tls_first_major=2
tls_first_minor=14
;;
hppa*-*-linux*)
conftest_s='
t1: .reg %r20
t2: .reg %r21
gp: .reg %r19
.section ".tdata","awT",@progbits
foo: .long 25
.text
.align 4
addil LT%foo-$tls_gdidx$,gp
ldo RT%foo-$tls_gdidx$(%r1),%arg0
b __tls_get_addr
nop
addil LT%foo-$tls_ldidx$,gp
b __tls_get_addr
ldo RT%foo-$tls_ldidx$(%r1),%arg0
addil LR%foo-$tls_dtpoff$,%ret0
ldo RR%foo-$tls_dtpoff$(%r1),%t1
mfctl %cr27,%t1
addil LT%foo-$tls_ieoff$,gp
ldw RT%foo-$tls_ieoff$(%r1),%t2
add %t1,%t2,%t3
mfctl %cr27,%t1
addil LR%foo-$tls_leoff$,%t1
ldo RR%foo-$tls_leoff$(%r1),%t2'
tls_first_major=2
tls_first_minor=15
tls_as_opt=--fatal-warnings
;;
i[34567]86-*-*)
conftest_s='
.section ".tdata","awT",@progbits