Commit cbf5629e by Jiong Wang

[AArch64][TLSLE][3/3] Implement local executable mode for all memory model

2015-08-26  Marcus Shawcroft  <marcus.shawcroft@arm.com>
	    Jiong Wang  <jiong.wang@arm.com>
gcc/
	* config/aarch64/aarch64.c (initialize_aarch64_tls_size): Set default
	tls size for tiny, small, large memory model.
	(aarch64_load_symref_appropriately): Support new symbol types.
	(aarch64_expand_mov_immediate): Likewise.
	(aarch64_print_operand): Likewise.
	(aarch64_classify_tls_symbol): Likewise.
	* config/aarch64/aarch64-protos.h (aarch64_symbol_context): Likewise.
	(aarch64_symbol_type): Likewise.
	* config/aarch64/aarch64.md (tlsle): Deleted.
	(tlsle12_<mode>): New define_insn.
	(tlsle24_<mode>): Likewise.
	(tlsle32_<mode>): Likewise.
	(tlsle48_<mode>): Likewise.
	* doc/sourcebuild.texi (AArch64-specific attributes): Document
	"aarch64_tlsle32".

gcc/testsuite/
	* lib/target-supports.exp (check_effective_target_aarch64_tlsle32):
	New test directive.
	* gcc.target/aarch64/tlsle_1.x: New test source.
	* gcc.target/aarch64/tlsle12_1.c: New testcase.
	* gcc.target/aarch64/tlsle24_1.c: Likewise.
	* gcc.target/aarch64/tlsle32_1.c: Likewise.

From-SVN: r227215
parent 427388a4
2015-08-26 Marcus Shawcroft <marcus.shawcroft@arm.com>
Jiong Wang <jiong.wang@arm.com>
* config/aarch64/aarch64.c (initialize_aarch64_tls_size): Set default
tls size for tiny, small, large memory model.
(aarch64_load_symref_appropriately): Support new symbol types.
(aarch64_expand_mov_immediate): Likewise.
(aarch64_print_operand): Likewise.
(aarch64_classify_tls_symbol): Likewise.
* config/aarch64/aarch64-protos.h (aarch64_symbol_context): Likewise.
(aarch64_symbol_type): Likewise.
* config/aarch64/aarch64.md (tlsle): Deleted.
(tlsle12_<mode>): New define_insn.
(tlsle24_<mode>): Likewise.
(tlsle32_<mode>): Likewise.
(tlsle48_<mode>): Likewise.
* doc/sourcebuild.texi (AArch64-specific attributes): Document
"aarch64_tlsle32".
2015-08-26 Matthew Wahab <matthew.wahab@arm.com>
* config/arm/arm-protos.h (FL_NONE): New.
......
......@@ -74,7 +74,10 @@ enum aarch64_symbol_context
SYMBOL_SMALL_TLSGD
SYMBOL_SMALL_TLSDESC
SYMBOL_SMALL_GOTTPREL
SYMBOL_TLSLE12
SYMBOL_TLSLE24
SYMBOL_TLSLE32
SYMBOL_TLSLE48
Each of these represents a thread-local symbol, and corresponds to the
thread local storage relocation operator for the symbol being referred to.
......@@ -111,7 +114,10 @@ enum aarch64_symbol_type
SYMBOL_SMALL_GOTTPREL,
SYMBOL_TINY_ABSOLUTE,
SYMBOL_TINY_GOT,
SYMBOL_TLSLE12,
SYMBOL_TLSLE24,
SYMBOL_TLSLE32,
SYMBOL_TLSLE48,
SYMBOL_FORCE_TO_MEM
};
......
......@@ -1114,14 +1114,43 @@ aarch64_load_symref_appropriately (rtx dest, rtx imm,
return;
}
case SYMBOL_TLSLE12:
case SYMBOL_TLSLE24:
case SYMBOL_TLSLE32:
case SYMBOL_TLSLE48:
{
machine_mode mode = GET_MODE (dest);
rtx tp = aarch64_load_tp (NULL);
if (GET_MODE (dest) != Pmode)
tp = gen_lowpart (GET_MODE (dest), tp);
if (mode != Pmode)
tp = gen_lowpart (mode, tp);
switch (type)
{
case SYMBOL_TLSLE12:
emit_insn ((mode == DImode ? gen_tlsle12_di : gen_tlsle12_si)
(dest, tp, imm));
break;
case SYMBOL_TLSLE24:
emit_insn ((mode == DImode ? gen_tlsle24_di : gen_tlsle24_si)
(dest, tp, imm));
break;
case SYMBOL_TLSLE32:
emit_insn ((mode == DImode ? gen_tlsle32_di : gen_tlsle32_si)
(dest, imm));
emit_insn ((mode == DImode ? gen_adddi3 : gen_addsi3)
(dest, dest, tp));
break;
case SYMBOL_TLSLE48:
emit_insn ((mode == DImode ? gen_tlsle48_di : gen_tlsle48_si)
(dest, imm));
emit_insn ((mode == DImode ? gen_adddi3 : gen_addsi3)
(dest, dest, tp));
break;
default:
gcc_unreachable ();
}
emit_insn (gen_tlsle (dest, tp, imm));
set_unique_reg_note (get_last_insn (), REG_EQUIV, imm);
return;
}
......@@ -1676,7 +1705,10 @@ aarch64_expand_mov_immediate (rtx dest, rtx imm)
case SYMBOL_SMALL_ABSOLUTE:
case SYMBOL_TINY_ABSOLUTE:
case SYMBOL_TLSLE12:
case SYMBOL_TLSLE24:
case SYMBOL_TLSLE32:
case SYMBOL_TLSLE48:
aarch64_load_symref_appropriately (dest, imm, sty);
return;
......@@ -4579,6 +4611,10 @@ aarch64_print_operand (FILE *f, rtx x, char code)
asm_fprintf (asm_out_file, ":gottprel_lo12:");
break;
case SYMBOL_TLSLE12:
asm_fprintf (asm_out_file, ":tprel_lo12:");
break;
case SYMBOL_TLSLE24:
asm_fprintf (asm_out_file, ":tprel_lo12_nc:");
break;
......@@ -8695,7 +8731,16 @@ aarch64_classify_tls_symbol (rtx x)
return SYMBOL_SMALL_GOTTPREL;
case TLS_MODEL_LOCAL_EXEC:
return SYMBOL_TLSLE24;
if (aarch64_tls_size == 12)
return SYMBOL_TLSLE12;
else if (aarch64_tls_size == 24)
return SYMBOL_TLSLE24;
else if (aarch64_tls_size == 32)
return SYMBOL_TLSLE32;
else if (aarch64_tls_size == 48)
return SYMBOL_TLSLE48;
else
gcc_unreachable ();
case TLS_MODEL_EMULATED:
case TLS_MODEL_NONE:
......
......@@ -117,7 +117,10 @@
UNSPEC_ST4_LANE
UNSPEC_TLS
UNSPEC_TLSDESC
UNSPEC_TLSLE
UNSPEC_TLSLE12
UNSPEC_TLSLE24
UNSPEC_TLSLE32
UNSPEC_TLSLE48
UNSPEC_USHL_2S
UNSPEC_VSTRUCTDUMMY
UNSPEC_SP_SET
......@@ -4512,31 +4515,48 @@
(set_attr "length" "8")]
)
(define_expand "tlsle"
[(set (match_operand 0 "register_operand" "=r")
(unspec [(match_operand 1 "register_operand" "r")
(match_operand 2 "aarch64_tls_le_symref" "S")]
UNSPEC_TLSLE))]
(define_insn "tlsle12_<mode>"
[(set (match_operand:P 0 "register_operand" "=r")
(unspec:P [(match_operand:P 1 "register_operand" "r")
(match_operand 2 "aarch64_tls_le_symref" "S")]
UNSPEC_TLSLE12))]
""
{
machine_mode mode = GET_MODE (operands[0]);
emit_insn ((mode == DImode
? gen_tlsle_di
: gen_tlsle_si) (operands[0], operands[1], operands[2]));
DONE;
})
"add\\t%<w>0, %<w>1, #%L2";
[(set_attr "type" "alu_sreg")
(set_attr "length" "4")]
)
(define_insn "tlsle_<mode>"
(define_insn "tlsle24_<mode>"
[(set (match_operand:P 0 "register_operand" "=r")
(unspec:P [(match_operand:P 1 "register_operand" "r")
(match_operand 2 "aarch64_tls_le_symref" "S")]
UNSPEC_TLSLE))]
(unspec:P [(match_operand:P 1 "register_operand" "r")
(match_operand 2 "aarch64_tls_le_symref" "S")]
UNSPEC_TLSLE24))]
""
"add\\t%<w>0, %<w>1, #%G2, lsl #12\;add\\t%<w>0, %<w>0, #%L2"
[(set_attr "type" "alu_sreg")
[(set_attr "type" "multiple")
(set_attr "length" "8")]
)
(define_insn "tlsle32_<mode>"
[(set (match_operand:P 0 "register_operand" "=r")
(unspec:P [(match_operand 1 "aarch64_tls_le_symref" "S")]
UNSPEC_TLSLE32))]
""
"movz\\t%<w>0, #:tprel_g1:%1\;movk\\t%<w>0, #:tprel_g0_nc:%1"
[(set_attr "type" "multiple")
(set_attr "length" "8")]
)
(define_insn "tlsle48_<mode>"
[(set (match_operand:P 0 "register_operand" "=r")
(unspec:P [(match_operand 1 "aarch64_tls_le_symref" "S")]
UNSPEC_TLSLE48))]
""
"movz\\t%<w>0, #:tprel_g2:%1\;movk\\t%<w>0, #:tprel_g1_nc:%1\;movk\\t%<w>0, #:tprel_g0_nc:%1"
[(set_attr "type" "multiple")
(set_attr "length" "12")]
)
(define_insn "tlsdesc_small_<mode>"
[(set (reg:PTR R0_REGNUM)
(unspec:PTR [(match_operand 0 "aarch64_valid_symref" "S")]
......
2015-08-26 Jiong Wang <jiong.wang@arm.com>
* lib/target-supports.exp (check_effective_target_aarch64_tlsle32):
New test directive.
* gcc.target/aarch64/tlsle_1.x: New test source.
* gcc.target/aarch64/tlsle12_1.c: New testcase.
* gcc.target/aarch64/tlsle24_1.c: Likewise.
* gcc.target/aarch64/tlsle32_1.c: Likewise.
2015-08-26 Francois-Xavier Coudert <fxcoudert@gcc.gnu.org>
PR fortran/29600
......
/* { dg-do run } */
/* { dg-require-effective-target tls_native } */
/* { dg-options "-O2 -fpic -ftls-model=local-exec -mtls-size=12 --save-temps" } */
#include "tlsle_1.x"
/* { dg-final { scan-assembler-times "#:tprel_lo12" 2 } } */
/* { dg-final { cleanup-saved-temps } } */
/* { dg-do run } */
/* { dg-require-effective-target tls_native } */
/* { dg-options "-O2 -fpic -ftls-model=local-exec -mtls-size=24 --save-temps" } */
#include "tlsle_1.x"
/* { dg-final { scan-assembler-times "#:tprel_lo12_nc" 2 } } */
/* { dg-final { scan-assembler-times "#:tprel_hi12" 2 } } */
/* { dg-final { cleanup-saved-temps } } */
/* { dg-do run } */
/* { dg-require-effective-target tls_native } */
/* { dg-require-effective-target aarch64_tlsle32 } */
/* { dg-options "-O2 -fpic -ftls-model=local-exec -mtls-size=32 --save-temps" } */
#include "tlsle_1.x"
/* { dg-final { scan-assembler-times "#:tprel_g1" 2 } } */
/* { dg-final { scan-assembler-times "#:tprel_g0_nc" 2 } } */
/* { dg-final { cleanup-saved-temps } } */
void abort (void);
__thread int t0 = 0x10;
__thread int t1 = 0x10;
int
main (int argc, char **argv)
{
if (t0 != t1)
abort ();
return 0;
}
......@@ -977,6 +977,23 @@ proc check_effective_target_aarch64_small_fpic { } {
}
}
# On AArch64, instruction sequence for TLS LE under -mtls-size=32 will utilize
# the relocation modifier "tprel_g0_nc" together with MOVK, it's only supported
# in binutils since 2015-03-04 as PR gas/17843.
#
# This test directive make sure binutils support all features needed by TLS LE
# under -mtls-size=32 on AArch64.
proc check_effective_target_aarch64_tlsle32 { } {
if { [istarget aarch64*-*-*] } {
return [check_no_compiler_messages aarch64_tlsle32 object {
void foo (void) { asm ("movk x1,#:tprel_g0_nc:t1"); }
}]
} else {
return 0
}
}
# Return 1 if -shared is supported, as in no warnings or errors
# emitted, 0 otherwise.
......
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