{
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;
}
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
"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;
[(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")])