+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.
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.
SYMBOL_SMALL_GOTTPREL,
SYMBOL_TINY_ABSOLUTE,
SYMBOL_TINY_GOT,
+ SYMBOL_TLSLE12,
SYMBOL_TLSLE24,
+ SYMBOL_TLSLE32,
+ SYMBOL_TLSLE48,
SYMBOL_FORCE_TO_MEM
};
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;
}
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;
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;
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:
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
(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
--- /dev/null
+/* { 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 } } */
--- /dev/null
+/* { 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 } } */
--- /dev/null
+/* { 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 } } */
--- /dev/null
+void abort (void);
+
+__thread int t0 = 0x10;
+__thread int t1 = 0x10;
+
+int
+main (int argc, char **argv)
+{
+ if (t0 != t1)
+ abort ();
+
+ return 0;
+}
+
}
}
+# 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.