aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog12
-rw-r--r--gcc/config/aarch64/aarch64-protos.h1
-rw-r--r--gcc/config/aarch64/aarch64.c25
-rw-r--r--gcc/config/aarch64/aarch64.h1
-rw-r--r--gcc/config/aarch64/aarch64.md74
5 files changed, 53 insertions, 60 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index cfe5f84..e0aa3ac 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,17 @@
2019-10-01 Richard Sandiford <richard.sandiford@arm.com>
+ PR target/91452
+ * config/aarch64/aarch64.h (ARM_PCS_TLSDESC): New arm_pcs.
+ * config/aarch64/aarch64-protos.h (aarch64_tlsdesc_abi_id): Declare.
+ * config/aarch64/aarch64.c (aarch64_hard_regno_call_part_clobbered):
+ Handle ARM_PCS_TLSDESC.
+ (aarch64_tlsdesc_abi_id): New function.
+ * config/aarch64/aarch64.md (tlsdesc_small_sve_<mode>): Use a call
+ rtx instead of a list of clobbers and clobber_highs.
+ (tlsdesc_small_<mode>): Update accordingly.
+
+2019-10-01 Richard Sandiford <richard.sandiford@arm.com>
+
* config/aarch64/aarch64-protos.h (aarch64_expand_call): Take an
extra callee_abi argument.
* config/aarch64/aarch64.c (aarch64_expand_call): Likewise.
diff --git a/gcc/config/aarch64/aarch64-protos.h b/gcc/config/aarch64/aarch64-protos.h
index 919f2b1..ab27a12 100644
--- a/gcc/config/aarch64/aarch64-protos.h
+++ b/gcc/config/aarch64/aarch64-protos.h
@@ -533,6 +533,7 @@ bool aarch64_uimm12_shift (HOST_WIDE_INT);
bool aarch64_use_return_insn_p (void);
const char *aarch64_output_casesi (rtx *);
+unsigned int aarch64_tlsdesc_abi_id ();
enum aarch64_symbol_type aarch64_classify_symbol (rtx, HOST_WIDE_INT);
enum aarch64_symbol_type aarch64_classify_tls_symbol (rtx);
enum reg_class aarch64_regno_regclass (unsigned);
diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c
index 85c87bb..7ee31a6 100644
--- a/gcc/config/aarch64/aarch64.c
+++ b/gcc/config/aarch64/aarch64.c
@@ -1896,12 +1896,13 @@ aarch64_hard_regno_call_part_clobbered (unsigned int abi_id,
{
if (FP_REGNUM_P (regno))
{
- bool simd_p = (abi_id == ARM_PCS_SIMD);
poly_int64 per_register_size = GET_MODE_SIZE (mode);
unsigned int nregs = hard_regno_nregs (regno, mode);
if (nregs > 1)
per_register_size = exact_div (per_register_size, nregs);
- return maybe_gt (per_register_size, simd_p ? 16 : 8);
+ if (abi_id == ARM_PCS_SIMD || abi_id == ARM_PCS_TLSDESC)
+ return maybe_gt (per_register_size, 16);
+ return maybe_gt (per_register_size, 8);
}
return false;
}
@@ -13953,6 +13954,26 @@ aarch64_can_inline_p (tree caller, tree callee)
return true;
}
+/* Return the ID of the TLDESC ABI, initializing the descriptor if hasn't
+ been already. */
+
+unsigned int
+aarch64_tlsdesc_abi_id ()
+{
+ predefined_function_abi &tlsdesc_abi = function_abis[ARM_PCS_TLSDESC];
+ if (!tlsdesc_abi.initialized_p ())
+ {
+ HARD_REG_SET full_reg_clobbers;
+ CLEAR_HARD_REG_SET (full_reg_clobbers);
+ SET_HARD_REG_BIT (full_reg_clobbers, R0_REGNUM);
+ SET_HARD_REG_BIT (full_reg_clobbers, CC_REGNUM);
+ for (int regno = P0_REGNUM; regno <= P15_REGNUM; ++regno)
+ SET_HARD_REG_BIT (full_reg_clobbers, regno);
+ tlsdesc_abi.initialize (ARM_PCS_TLSDESC, full_reg_clobbers);
+ }
+ return tlsdesc_abi.id ();
+}
+
/* Return true if SYMBOL_REF X binds locally. */
static bool
diff --git a/gcc/config/aarch64/aarch64.h b/gcc/config/aarch64/aarch64.h
index 5aff106..abd14a2 100644
--- a/gcc/config/aarch64/aarch64.h
+++ b/gcc/config/aarch64/aarch64.h
@@ -784,6 +784,7 @@ enum arm_pcs
{
ARM_PCS_AAPCS64, /* Base standard AAPCS for 64 bit. */
ARM_PCS_SIMD, /* For aarch64_vector_pcs functions. */
+ ARM_PCS_TLSDESC, /* For targets of tlsdesc calls. */
ARM_PCS_UNKNOWN
};
diff --git a/gcc/config/aarch64/aarch64.md b/gcc/config/aarch64/aarch64.md
index e483572..e7a6930 100644
--- a/gcc/config/aarch64/aarch64.md
+++ b/gcc/config/aarch64/aarch64.md
@@ -6805,7 +6805,12 @@
"TARGET_TLS_DESC"
{
if (TARGET_SVE)
- emit_insn (gen_tlsdesc_small_sve_<mode> (operands[0]));
+ {
+ rtx abi = gen_int_mode (aarch64_tlsdesc_abi_id (), DImode);
+ rtx_insn *call
+ = emit_call_insn (gen_tlsdesc_small_sve_<mode> (operands[0], abi));
+ RTL_CONST_CALL_P (call) = 1;
+ }
else
emit_insn (gen_tlsdesc_small_advsimd_<mode> (operands[0]));
DONE;
@@ -6827,67 +6832,20 @@
[(set_attr "type" "call")
(set_attr "length" "16")])
-;; For SVE, model tlsdesc calls as clobbering the lower 128 bits of
-;; all vector registers, and clobber all predicate registers, on
-;; top of the usual R0 and LR.
+;; For SVE, model tlsdesc calls as normal calls, with the callee ABI
+;; describing the extra call-preserved guarantees. This would work
+;; for non-SVE too, but avoiding a call is probably better if we can.
(define_insn "tlsdesc_small_sve_<mode>"
[(set (reg:PTR R0_REGNUM)
- (unspec:PTR [(match_operand 0 "aarch64_valid_symref" "S")]
- UNSPEC_TLSDESC))
+ (call (mem:DI (unspec:PTR
+ [(match_operand 0 "aarch64_valid_symref")]
+ UNSPEC_TLSDESC))
+ (const_int 0)))
+ (unspec:DI [(match_operand:DI 1 "const_int_operand")] UNSPEC_CALLEE_ABI)
(clobber (reg:DI LR_REGNUM))
- (clobber (reg:CC CC_REGNUM))
- (clobber_high (reg:TI V0_REGNUM))
- (clobber_high (reg:TI V1_REGNUM))
- (clobber_high (reg:TI V2_REGNUM))
- (clobber_high (reg:TI V3_REGNUM))
- (clobber_high (reg:TI V4_REGNUM))
- (clobber_high (reg:TI V5_REGNUM))
- (clobber_high (reg:TI V6_REGNUM))
- (clobber_high (reg:TI V7_REGNUM))
- (clobber_high (reg:TI V8_REGNUM))
- (clobber_high (reg:TI V9_REGNUM))
- (clobber_high (reg:TI V10_REGNUM))
- (clobber_high (reg:TI V11_REGNUM))
- (clobber_high (reg:TI V12_REGNUM))
- (clobber_high (reg:TI V13_REGNUM))
- (clobber_high (reg:TI V14_REGNUM))
- (clobber_high (reg:TI V15_REGNUM))
- (clobber_high (reg:TI V16_REGNUM))
- (clobber_high (reg:TI V17_REGNUM))
- (clobber_high (reg:TI V18_REGNUM))
- (clobber_high (reg:TI V19_REGNUM))
- (clobber_high (reg:TI V20_REGNUM))
- (clobber_high (reg:TI V21_REGNUM))
- (clobber_high (reg:TI V22_REGNUM))
- (clobber_high (reg:TI V23_REGNUM))
- (clobber_high (reg:TI V24_REGNUM))
- (clobber_high (reg:TI V25_REGNUM))
- (clobber_high (reg:TI V26_REGNUM))
- (clobber_high (reg:TI V27_REGNUM))
- (clobber_high (reg:TI V28_REGNUM))
- (clobber_high (reg:TI V29_REGNUM))
- (clobber_high (reg:TI V30_REGNUM))
- (clobber_high (reg:TI V31_REGNUM))
- (clobber (reg:VNx2BI P0_REGNUM))
- (clobber (reg:VNx2BI P1_REGNUM))
- (clobber (reg:VNx2BI P2_REGNUM))
- (clobber (reg:VNx2BI P3_REGNUM))
- (clobber (reg:VNx2BI P4_REGNUM))
- (clobber (reg:VNx2BI P5_REGNUM))
- (clobber (reg:VNx2BI P6_REGNUM))
- (clobber (reg:VNx2BI P7_REGNUM))
- (clobber (reg:VNx2BI P8_REGNUM))
- (clobber (reg:VNx2BI P9_REGNUM))
- (clobber (reg:VNx2BI P10_REGNUM))
- (clobber (reg:VNx2BI P11_REGNUM))
- (clobber (reg:VNx2BI P12_REGNUM))
- (clobber (reg:VNx2BI P13_REGNUM))
- (clobber (reg:VNx2BI P14_REGNUM))
- (clobber (reg:VNx2BI P15_REGNUM))
- (clobber (match_scratch:DI 1 "=r"))
- (use (reg:DI FP_REGNUM))]
+ (clobber (match_scratch:DI 2 "=r"))]
"TARGET_TLS_DESC && TARGET_SVE"
- "adrp\\tx0, %A0\;ldr\\t%<w>1, [x0, #%L0]\;add\\t<w>0, <w>0, %L0\;.tlsdesccall\\t%0\;blr\\t%1"
+ "adrp\\tx0, %A0\;ldr\\t%<w>2, [x0, #%L0]\;add\\t<w>0, <w>0, %L0\;.tlsdesccall\\t%0\;blr\\t%2"
[(set_attr "type" "call")
(set_attr "length" "16")])