Commit 75df395f by Maxim Kuvyrkov Committed by Maxim Kuvyrkov

M68K TLS support.

	* configure.ac (m68k-*-*): Check if binutils support TLS.
	* configure: Regenerate.
	* config/m68k/predicates.md (symbolic_operand): Extend comment.
	* config/m68k/constraints.md (Cu): New constraint.
	* config/m68k/m68k.md (UNSPEC_GOTOFF): Remove.
	(UNSPEC_RELOC16, UNSPEC_RELOC32): New constants.
	(movsi): Handle TLS symbols.
	(addsi3_5200): Handle XTLS symbols, indent.
	* config/m68k/m68k-protos.h (m68k_legitimize_tls_address): Declare.
	(m68k_tls_reference_p): Declare.
	(m68k_legitimize_address): Declare.
	(m68k_unwrap_symbol): Declare.
	* config/m68k/m68k.opt (mxtls): New option.
	* config/m68k/m68k.c (ggc.h): Include.
	(m68k_output_dwarf_dtprel): Implement hook.
	(TARGET_HAVE_TLS, TARGET_ASM_OUTPUT_DWARF_DTPREL): Define.
	(m68k_expand_prologue): Load GOT pointer when function needs it.
	(m68k_illegitimate_symbolic_constant_p): Handle TLS symbols.
	(m68k_legitimate_constant_address_p): Same.
	(m68k_decompose_address): Handle TLS references.
	(m68k_get_gp): New static function.
	(enum m68k_reloc): New contants.
	(TLS_RELOC_P): New macro.
	(m68k_wrap_symbol): New static function.
	(m68k_unwrap_symbol): New function.
	(m68k_final_prescan_insn_1): New static function.
	(m68k_final_prescan_insn): New function.
	(m68k_move_to_reg, m68k_wrap_symbol_into_got_ref): New static
	functions.
	(legitimize_pic_address): Handle TLS references..
	(m68k_tls_get_addr, m68k_get_tls_get_addr)
	(m68k_libcall_value_in_a0_p)
	(m68k_call_tls_get_addr, m68k_read_tp, m68k_get_m68k_read_tp)
	(m68k_call_m68k_read_tp): Helper variables and functions for ...
	(m68k_legitimize_tls_address): Handle TLS references.
	(m68k_tls_symbol_p, m68k_tls_reference_p_1, m68k_tls_reference_p):
	New functions.
	(m68k_legitimize_address): Handle TLS symbols.
	(m68k_get_reloc_decoration): New static function.
	(m68k_output_addr_const_extra): Handle UNSPEC_RELOC16 and
	UNSPEC_RELOC32.
	(m68k_output_dwarf_dtprel): Implement hook.
	(print_operand_address): Handle UNSPEC_RELOC16 adn UNSPEC_RELOC32.
	(m68k_libcall_value): Return result in A0 instead of D0 when asked by
	m68k_call_* routines.
	(sched_attr_op_type): Handle TLS symbols.
	(gt-m68k.h): Include.
	* config/m68k/m68k.h (FINAL_PRESCAN_INSN): Define.
	(LEGITIMATE_PIC_OPERAND_P): Support TLS.

	* gcc.target/m68k/tls-ie.c: New test.
	* gcc.target/m68k/tls-le.c: New test.
	* gcc.target/m68k/tls-gd.c: New test.
	* gcc.target/m68k/tls-ld.c: New test.
	* gcc.target/m68k/tls-ie-xgot.c: New test.
	* gcc.target/m68k/tls-le-xtls.c: New test.
	* gcc.target/m68k/tls-gd-xgot.c: New test.
	* gcc.target/m68k/tls-ld-xgot.c: New test.
	* gcc.target/m68k/tls-ld-xtls.c: New test.
	* gcc.target/m68k/tls-ld-xgot-xtls.c: New test.

From-SVN: r147654
parent 676fd528
2009-05-18 Maxim Kuvyrkov <maxim@codesourcery.com>
M68K TLS support.
* configure.ac (m68k-*-*): Check if binutils support TLS.
* configure: Regenerate.
* config/m68k/predicates.md (symbolic_operand): Extend comment.
* config/m68k/constraints.md (Cu): New constraint.
* config/m68k/m68k.md (UNSPEC_GOTOFF): Remove.
(UNSPEC_RELOC16, UNSPEC_RELOC32): New constants.
(movsi): Handle TLS symbols.
(addsi3_5200): Handle XTLS symbols, indent.
* config/m68k/m68k-protos.h (m68k_legitimize_tls_address): Declare.
(m68k_tls_reference_p): Declare.
(m68k_legitimize_address): Declare.
(m68k_unwrap_symbol): Declare.
* config/m68k/m68k.opt (mxtls): New option.
* config/m68k/m68k.c (ggc.h): Include.
(m68k_output_dwarf_dtprel): Implement hook.
(TARGET_HAVE_TLS, TARGET_ASM_OUTPUT_DWARF_DTPREL): Define.
(m68k_expand_prologue): Load GOT pointer when function needs it.
(m68k_illegitimate_symbolic_constant_p): Handle TLS symbols.
(m68k_legitimate_constant_address_p): Same.
(m68k_decompose_address): Handle TLS references.
(m68k_get_gp): New static function.
(enum m68k_reloc): New contants.
(TLS_RELOC_P): New macro.
(m68k_wrap_symbol): New static function.
(m68k_unwrap_symbol): New function.
(m68k_final_prescan_insn_1): New static function.
(m68k_final_prescan_insn): New function.
(m68k_move_to_reg, m68k_wrap_symbol_into_got_ref): New static
functions.
(legitimize_pic_address): Handle TLS references..
(m68k_tls_get_addr, m68k_get_tls_get_addr)
(m68k_libcall_value_in_a0_p)
(m68k_call_tls_get_addr, m68k_read_tp, m68k_get_m68k_read_tp)
(m68k_call_m68k_read_tp): Helper variables and functions for ...
(m68k_legitimize_tls_address): Handle TLS references.
(m68k_tls_symbol_p, m68k_tls_reference_p_1, m68k_tls_reference_p):
New functions.
(m68k_legitimize_address): Handle TLS symbols.
(m68k_get_reloc_decoration): New static function.
(m68k_output_addr_const_extra): Handle UNSPEC_RELOC16 and
UNSPEC_RELOC32.
(m68k_output_dwarf_dtprel): Implement hook.
(print_operand_address): Handle UNSPEC_RELOC16 adn UNSPEC_RELOC32.
(m68k_libcall_value): Return result in A0 instead of D0 when asked by
m68k_call_* routines.
(sched_attr_op_type): Handle TLS symbols.
(gt-m68k.h): Include.
* config/m68k/m68k.h (FINAL_PRESCAN_INSN): Define.
(LEGITIMATE_PIC_OPERAND_P): Support TLS.
2009-05-18 Martin Jambor <mjambor@suse.cz>
* ipa-prop.c (ipa_check_stmt_modifications): Removed.
......
......@@ -129,6 +129,11 @@
(and (match_code "const_int")
(match_test "ival < -0x8000 || ival > 0x7FFF")))
(define_constraint "Cu"
"16-bit offset for wrapped symbols"
(and (match_code "const")
(match_test "m68k_unwrap_symbol (op, false) != op")))
(define_constraint "CQ"
"Integers valid for mvq."
(and (match_code "const_int")
......
......@@ -59,13 +59,20 @@ extern bool m68k_illegitimate_symbolic_constant_p (rtx);
extern bool m68k_matches_q_p (rtx);
extern bool m68k_matches_u_p (rtx);
extern rtx legitimize_pic_address (rtx, enum machine_mode, rtx);
extern rtx m68k_legitimize_tls_address (rtx);
extern bool m68k_tls_reference_p (rtx, bool);
extern int valid_dbcc_comparison_p_2 (rtx, enum machine_mode);
extern rtx m68k_libcall_value (enum machine_mode);
extern rtx m68k_function_value (const_tree, const_tree);
extern int emit_move_sequence (rtx *, enum machine_mode, rtx);
extern bool m68k_movem_pattern_p (rtx, rtx, HOST_WIDE_INT, bool);
extern const char *m68k_output_movem (rtx *, rtx, HOST_WIDE_INT, bool);
extern void m68k_final_prescan_insn (rtx, rtx *, int);
/* Functions from m68k.c used in constraints.md. */
extern rtx m68k_unwrap_symbol (rtx, bool);
/* Functions from m68k.c used in genattrtab. */
#ifdef HAVE_ATTR_cpu
extern enum attr_cpu m68k_sched_cpu;
extern enum attr_mac m68k_sched_mac;
......
......@@ -750,7 +750,8 @@ __transfer_from_trampoline () \
#define LEGITIMATE_PIC_OPERAND_P(X) \
(!symbolic_operand (X, VOIDmode) \
|| (TARGET_PCREL && REG_STRICT_P))
|| (TARGET_PCREL && REG_STRICT_P) \
|| m68k_tls_reference_p (X, true))
#define REG_OK_FOR_BASE_P(X) \
m68k_legitimate_base_reg_p (X, REG_STRICT_P)
......@@ -967,6 +968,9 @@ do { if (cc_prev_status.flags & CC_IN_68881) \
assemble_name ((FILE), (NAME)), \
fprintf ((FILE), ",%u\n", (int)(ROUNDED)))
#define FINAL_PRESCAN_INSN(INSN, OPVEC, NOPERANDS) \
m68k_final_prescan_insn (INSN, OPVEC, NOPERANDS)
/* On the 68000, we use several CODE characters:
'.' for dot needed in Motorola-style opcode names.
'-' for an operand pushing on the stack:
......
......@@ -116,7 +116,8 @@
(UNSPEC_GOT 3)
(UNSPEC_IB 4)
(UNSPEC_TIE 5)
(UNSPEC_GOTOFF 6)
(UNSPEC_RELOC16 6)
(UNSPEC_RELOC32 7)
])
;; UNSPEC_VOLATILE usage:
......@@ -869,7 +870,41 @@
{
rtx tmp, base, offset;
if (flag_pic && !TARGET_PCREL && symbolic_operand (operands[1], SImode))
/* Recognize the case where operand[1] is a reference to thread-local
data and load its address to a register. */
if (!TARGET_PCREL && m68k_tls_reference_p (operands[1], false))
{
rtx tmp = operands[1];
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);
gcc_assert (SYMBOL_REF_TLS_MODEL (tmp) != 0);
tmp = m68k_legitimize_tls_address (tmp);
if (addend)
{
if (!REG_P (tmp))
{
rtx reg;
reg = gen_reg_rtx (Pmode);
emit_move_insn (reg, tmp);
tmp = reg;
}
tmp = gen_rtx_PLUS (SImode, tmp, addend);
}
operands[1] = tmp;
}
else if (flag_pic && !TARGET_PCREL && symbolic_operand (operands[1], SImode))
{
/* The source is an address which requires PIC relocation.
Call legitimize_pic_address with the source, mode, and a relocation
......@@ -2428,9 +2463,9 @@
"* return output_addsi3 (operands);")
(define_insn_and_split "*addsi3_5200"
[(set (match_operand:SI 0 "nonimmediate_operand" "=mr,mr,a,m,r, ?a, ?a,?a,?a")
(plus:SI (match_operand:SI 1 "general_operand" "%0, 0, 0,0,0, a, a, r, a")
(match_operand:SI 2 "general_src_operand" " I, L, J,d,mrKi,Cj, r, a, J")))]
[(set (match_operand:SI 0 "nonimmediate_operand" "=mr,mr,a, m,r, ?a, ?a,?a,?a")
(plus:SI (match_operand:SI 1 "general_operand" "%0, 0, 0, 0,0, a, a, r, a")
(match_operand:SI 2 "general_src_operand" " I, L, JCu,d,mrKi,Cj, r, a, JCu")))]
"TARGET_COLDFIRE"
{
switch (which_alternative)
......@@ -2472,9 +2507,9 @@
(plus:SI (match_dup 0)
(match_dup 1)))]
""
[(set_attr "type" "aluq_l,aluq_l,lea,alu_l,alu_l,*,lea,lea,lea")
(set_attr "opy" "2,2,*,2,2,*,*,*,*")
(set_attr "opy_type" "*,*,mem5,*,*,*,mem6,mem6,mem5")])
[(set_attr "type" "aluq_l,aluq_l,lea, alu_l,alu_l,*,lea, lea, lea")
(set_attr "opy" "2, 2, *, 2, 2, *,*, *, *")
(set_attr "opy_type" "*, *, mem5,*, *, *,mem6,mem6,mem5")])
(define_insn ""
[(set (match_operand:SI 0 "nonimmediate_operand" "=a")
......
......@@ -182,3 +182,7 @@ Tune for the specified target CPU or architecture
mxgot
Target Report Mask(XGOT)
Support more than 8192 GOT entries on ColdFire
mxtls
Target Report Mask(XTLS)
Support TLS segment larger than 64K
......@@ -135,7 +135,9 @@
(match_code "sign_extend,zero_extend"))
;; Returns true if OP is either a symbol reference or a sum of a
;; symbol reference and a constant.
;; symbol reference and a constant. This predicate is for "raw"
;; symbol references not yet processed by legitimize*_address,
;; hence we do not handle UNSPEC_{XGOT, TLS, XTLS} here.
(define_predicate "symbolic_operand"
(match_code "symbol_ref,label_ref,const")
......
......@@ -21984,6 +21984,22 @@ x:
tls_first_minor=16
tls_as_opt='-32 --fatal-warnings'
;;
m68k-*-*)
conftest_s='
.section .tdata,"awT",@progbits
x:
.word 2
.text
foo:
move.l x@TLSGD(%a5),%a0
move.l x@TLSLDM(%a5),%a0
move.l x@TLSLDO(%a5),%a0
move.l x@TLSIE(%a5),%a0
move.l x@TLSLE(%a5),%a0'
tls_first_major=2
tls_first_minor=19
tls_as_opt='--fatal-warnings'
;;
powerpc-*-*)
conftest_s='
.section ".tdata","awT",@progbits
......
......@@ -2570,6 +2570,22 @@ x:
tls_first_minor=16
tls_as_opt='-32 --fatal-warnings'
;;
m68k-*-*)
conftest_s='
.section .tdata,"awT",@progbits
x:
.word 2
.text
foo:
move.l x@TLSGD(%a5),%a0
move.l x@TLSLDM(%a5),%a0
move.l x@TLSLDO(%a5),%a0
move.l x@TLSIE(%a5),%a0
move.l x@TLSLE(%a5),%a0'
tls_first_major=2
tls_first_minor=19
tls_as_opt='--fatal-warnings'
;;
powerpc-*-*)
conftest_s='
.section ".tdata","awT",@progbits
......
2009-05-18 Maxim Kuvyrkov <maxim@codesourcery.com>
* gcc.target/m68k/tls-ie.c: New test.
* gcc.target/m68k/tls-le.c: New test.
* gcc.target/m68k/tls-gd.c: New test.
* gcc.target/m68k/tls-ld.c: New test.
* gcc.target/m68k/tls-ie-xgot.c: New test.
* gcc.target/m68k/tls-le-xtls.c: New test.
* gcc.target/m68k/tls-gd-xgot.c: New test.
* gcc.target/m68k/tls-ld-xgot.c: New test.
* gcc.target/m68k/tls-ld-xtls.c: New test.
* gcc.target/m68k/tls-ld-xgot-xtls.c: New test.
2009-05-18 Martin Jambor <mjambor@suse.cz>
* gcc.dg/ipa/modif-1.c: Do not check for unmodified int parameter.
......
/* { dg-do compile } */
/* { dg-skip-if "" { ! *-linux-* } { "*" } { "" } } */
/* { dg-options "-O2 -fpic -mxgot" } */
/* { dg-final { scan-assembler "#foo@TLSGD,\%\[ad\]\[0-7\]" } } */
/* { dg-final { scan-assembler "bsr.l __tls_get_addr@PLTPC" } } */
extern int __thread foo;
int *
bar (void)
{
return &foo;
}
/* { dg-do compile } */
/* { dg-skip-if "" { ! *-linux-* } { "*" } { "" } } */
/* { dg-options "-O2 -fpic" } */
/* { dg-final { scan-assembler "foo@TLSGD\\(\%a5\\)" } } */
/* { dg-final { scan-assembler "bsr.l __tls_get_addr@PLTPC" } } */
extern int __thread foo;
int *
bar (void)
{
return &foo;
}
/* { dg-do compile } */
/* { dg-skip-if "" { ! *-linux-* } { "*" } { "" } } */
/* { dg-options "-O2 -mxgot" } */
/* { dg-final { scan-assembler "jsr __m68k_read_tp" } } */
/* { dg-final { scan-assembler "#foo@TLSIE,\%\[ad\]\[0-7\]" } } */
extern int __thread foo;
int *
bar (void)
{
return &foo;
}
/* { dg-do compile } */
/* { dg-skip-if "" { ! *-linux-* } { "*" } { "" } } */
/* { dg-options "-O2" } */
/* { dg-final { scan-assembler "jsr __m68k_read_tp" } } */
/* { dg-final { scan-assembler "foo@TLSIE\\(\%a5\\)" } } */
extern int __thread foo;
int *
bar (void)
{
return &foo;
}
/* { dg-do compile } */
/* { dg-skip-if "" { ! *-linux-* } { "*" } { "" } } */
/* { dg-options "-O2 -fpic -mxgot -mxtls" } */
/* { dg-final { scan-assembler "#foo@TLSLDM,\%\[ad\]\[0-7\]" } } */
/* { dg-final { scan-assembler "bsr.l __tls_get_addr@PLTPC" } } */
/* { dg-final { scan-assembler "#foo@TLSLDO,\%\[ad\]\[0-7\]" } } */
static int __thread foo;
int *
bar (void)
{
return &foo;
}
/* { dg-do compile } */
/* { dg-skip-if "" { ! *-linux-* } { "*" } { "" } } */
/* { dg-options "-O2 -fpic -mxgot" } */
/* { dg-final { scan-assembler "#foo@TLSLDM,\%\[ad\]\[0-7\]" } } */
/* { dg-final { scan-assembler "bsr.l __tls_get_addr@PLTPC" } } */
/* { dg-final { scan-assembler "lea \\(foo@TLSLDO,\%a0\\)" } } */
static int __thread foo;
int *
bar (void)
{
return &foo;
}
/* { dg-do compile } */
/* { dg-skip-if "" { ! *-linux-* } { "*" } { "" } } */
/* { dg-options "-O2 -fpic -mxtls" } */
/* { dg-final { scan-assembler "foo@TLSLDM\\(\%a5\\)" } } */
/* { dg-final { scan-assembler "bsr.l __tls_get_addr@PLTPC" } } */
/* { dg-final { scan-assembler "#foo@TLSLDO,\%\[ad\]\[0-7\]" } } */
static int __thread foo;
int *
bar (void)
{
return &foo;
}
/* { dg-do compile } */
/* { dg-skip-if "" { ! *-linux-* } { "*" } { "" } } */
/* { dg-options "-O2 -fpic" } */
/* { dg-final { scan-assembler "foo@TLSLDM\\(\%a5\\)" } } */
/* { dg-final { scan-assembler "bsr.l __tls_get_addr@PLTPC" } } */
/* { dg-final { scan-assembler "lea \\(foo@TLSLDO,\%a0\\)" } } */
static int __thread foo;
int *
bar (void)
{
return &foo;
}
/* { dg-do compile } */
/* { dg-skip-if "" { ! *-linux-* } { "*" } { "" } } */
/* { dg-options "-O2 -mxtls" } */
/* { dg-final { scan-assembler "jsr __m68k_read_tp" } } */
/* { dg-final { scan-assembler "#foo@TLSLE,\%\[ad\]\[0-7\]" } } */
static int __thread foo;
int *
bar (void)
{
return &foo;
}
/* { dg-do compile } */
/* { dg-skip-if "" { ! *-linux-* } { "*" } { "" } } */
/* { dg-options "-O2" } */
/* { dg-final { scan-assembler "jsr __m68k_read_tp" } } */
/* { dg-final { scan-assembler "lea \\(foo@TLSLE,\%a0\\)" } } */
static int __thread foo;
int *
bar (void)
{
return &foo;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment