Fix clobber_abi and disallow SVE-related registers in Arm64EC inline assembly
This commit is contained in:
parent
8f8bee4f60
commit
d858dfedbb
@ -64,6 +64,7 @@ pub fn supported_types(
|
|||||||
neon: I8, I16, I32, I64, F16, F32, F64, F128,
|
neon: I8, I16, I32, I64, F16, F32, F64, F128,
|
||||||
VecI8(8), VecI16(4), VecI32(2), VecI64(1), VecF16(4), VecF32(2), VecF64(1),
|
VecI8(8), VecI16(4), VecI32(2), VecI64(1), VecF16(4), VecF32(2), VecF64(1),
|
||||||
VecI8(16), VecI16(8), VecI32(4), VecI64(2), VecF16(8), VecF32(4), VecF64(2);
|
VecI8(16), VecI16(8), VecI32(4), VecI64(2), VecF16(8), VecF32(4), VecF64(2);
|
||||||
|
// Note: When adding support for SVE vector types, they must be rejected for Arm64EC.
|
||||||
},
|
},
|
||||||
Self::preg => &[],
|
Self::preg => &[],
|
||||||
}
|
}
|
||||||
@ -96,7 +97,7 @@ fn restricted_for_arm64ec(
|
|||||||
_is_clobber: bool,
|
_is_clobber: bool,
|
||||||
) -> Result<(), &'static str> {
|
) -> Result<(), &'static str> {
|
||||||
if arch == InlineAsmArch::Arm64EC {
|
if arch == InlineAsmArch::Arm64EC {
|
||||||
Err("x13, x14, x23, x24, x28, v16-v31 cannot be used for Arm64EC")
|
Err("x13, x14, x23, x24, x28, v16-v31, p*, ffr cannot be used for Arm64EC")
|
||||||
} else {
|
} else {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@ -165,23 +166,23 @@ fn restricted_for_arm64ec(
|
|||||||
v29: vreg = ["v29", "b29", "h29", "s29", "d29", "q29", "z29"] % restricted_for_arm64ec,
|
v29: vreg = ["v29", "b29", "h29", "s29", "d29", "q29", "z29"] % restricted_for_arm64ec,
|
||||||
v30: vreg = ["v30", "b30", "h30", "s30", "d30", "q30", "z30"] % restricted_for_arm64ec,
|
v30: vreg = ["v30", "b30", "h30", "s30", "d30", "q30", "z30"] % restricted_for_arm64ec,
|
||||||
v31: vreg = ["v31", "b31", "h31", "s31", "d31", "q31", "z31"] % restricted_for_arm64ec,
|
v31: vreg = ["v31", "b31", "h31", "s31", "d31", "q31", "z31"] % restricted_for_arm64ec,
|
||||||
p0: preg = ["p0"],
|
p0: preg = ["p0"] % restricted_for_arm64ec,
|
||||||
p1: preg = ["p1"],
|
p1: preg = ["p1"] % restricted_for_arm64ec,
|
||||||
p2: preg = ["p2"],
|
p2: preg = ["p2"] % restricted_for_arm64ec,
|
||||||
p3: preg = ["p3"],
|
p3: preg = ["p3"] % restricted_for_arm64ec,
|
||||||
p4: preg = ["p4"],
|
p4: preg = ["p4"] % restricted_for_arm64ec,
|
||||||
p5: preg = ["p5"],
|
p5: preg = ["p5"] % restricted_for_arm64ec,
|
||||||
p6: preg = ["p6"],
|
p6: preg = ["p6"] % restricted_for_arm64ec,
|
||||||
p7: preg = ["p7"],
|
p7: preg = ["p7"] % restricted_for_arm64ec,
|
||||||
p8: preg = ["p8"],
|
p8: preg = ["p8"] % restricted_for_arm64ec,
|
||||||
p9: preg = ["p9"],
|
p9: preg = ["p9"] % restricted_for_arm64ec,
|
||||||
p10: preg = ["p10"],
|
p10: preg = ["p10"] % restricted_for_arm64ec,
|
||||||
p11: preg = ["p11"],
|
p11: preg = ["p11"] % restricted_for_arm64ec,
|
||||||
p12: preg = ["p12"],
|
p12: preg = ["p12"] % restricted_for_arm64ec,
|
||||||
p13: preg = ["p13"],
|
p13: preg = ["p13"] % restricted_for_arm64ec,
|
||||||
p14: preg = ["p14"],
|
p14: preg = ["p14"] % restricted_for_arm64ec,
|
||||||
p15: preg = ["p15"],
|
p15: preg = ["p15"] % restricted_for_arm64ec,
|
||||||
ffr: preg = ["ffr"],
|
ffr: preg = ["ffr"] % restricted_for_arm64ec,
|
||||||
#error = ["x19", "w19"] =>
|
#error = ["x19", "w19"] =>
|
||||||
"x19 is used internally by LLVM and cannot be used as an operand for inline asm",
|
"x19 is used internally by LLVM and cannot be used as an operand for inline asm",
|
||||||
#error = ["x29", "w29", "fp", "wfp"] =>
|
#error = ["x29", "w29", "fp", "wfp"] =>
|
||||||
|
@ -890,6 +890,7 @@ pub enum InlineAsmClobberAbi {
|
|||||||
Arm,
|
Arm,
|
||||||
AArch64,
|
AArch64,
|
||||||
AArch64NoX18,
|
AArch64NoX18,
|
||||||
|
Arm64EC,
|
||||||
RiscV,
|
RiscV,
|
||||||
LoongArch,
|
LoongArch,
|
||||||
S390x,
|
S390x,
|
||||||
@ -932,7 +933,7 @@ pub fn parse(
|
|||||||
_ => Err(&["C", "system", "efiapi"]),
|
_ => Err(&["C", "system", "efiapi"]),
|
||||||
},
|
},
|
||||||
InlineAsmArch::Arm64EC => match name {
|
InlineAsmArch::Arm64EC => match name {
|
||||||
"C" | "system" => Ok(InlineAsmClobberAbi::AArch64NoX18),
|
"C" | "system" => Ok(InlineAsmClobberAbi::Arm64EC),
|
||||||
_ => Err(&["C", "system"]),
|
_ => Err(&["C", "system"]),
|
||||||
},
|
},
|
||||||
InlineAsmArch::RiscV32 | InlineAsmArch::RiscV64 => match name {
|
InlineAsmArch::RiscV32 | InlineAsmArch::RiscV64 => match name {
|
||||||
@ -1033,7 +1034,6 @@ macro_rules! clobbered_regs {
|
|||||||
p0, p1, p2, p3, p4, p5, p6, p7,
|
p0, p1, p2, p3, p4, p5, p6, p7,
|
||||||
p8, p9, p10, p11, p12, p13, p14, p15,
|
p8, p9, p10, p11, p12, p13, p14, p15,
|
||||||
ffr,
|
ffr,
|
||||||
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
InlineAsmClobberAbi::AArch64NoX18 => clobbered_regs! {
|
InlineAsmClobberAbi::AArch64NoX18 => clobbered_regs! {
|
||||||
@ -1052,7 +1052,20 @@ macro_rules! clobbered_regs {
|
|||||||
p0, p1, p2, p3, p4, p5, p6, p7,
|
p0, p1, p2, p3, p4, p5, p6, p7,
|
||||||
p8, p9, p10, p11, p12, p13, p14, p15,
|
p8, p9, p10, p11, p12, p13, p14, p15,
|
||||||
ffr,
|
ffr,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
InlineAsmClobberAbi::Arm64EC => clobbered_regs! {
|
||||||
|
AArch64 AArch64InlineAsmReg {
|
||||||
|
// x13 and x14 cannot be used in Arm64EC.
|
||||||
|
x0, x1, x2, x3, x4, x5, x6, x7,
|
||||||
|
x8, x9, x10, x11, x12, x15,
|
||||||
|
x16, x17, x30,
|
||||||
|
|
||||||
|
// Technically the low 64 bits of v8-v15 are preserved, but
|
||||||
|
// we have no way of expressing this using clobbers.
|
||||||
|
v0, v1, v2, v3, v4, v5, v6, v7,
|
||||||
|
v8, v9, v10, v11, v12, v13, v14, v15,
|
||||||
|
// v16-v31, p*, and ffr cannot be used in Arm64EC.
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
InlineAsmClobberAbi::Arm => clobbered_regs! {
|
InlineAsmClobberAbi::Arm => clobbered_regs! {
|
||||||
|
36
tests/codegen/asm-arm64ec-clobbers.rs
Normal file
36
tests/codegen/asm-arm64ec-clobbers.rs
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
//@ assembly-output: emit-asm
|
||||||
|
//@ compile-flags: --target arm64ec-pc-windows-msvc
|
||||||
|
//@ needs-llvm-components: aarch64
|
||||||
|
|
||||||
|
#![crate_type = "rlib"]
|
||||||
|
#![feature(no_core, rustc_attrs, lang_items, asm_experimental_arch)]
|
||||||
|
#![no_core]
|
||||||
|
|
||||||
|
#[lang = "sized"]
|
||||||
|
trait Sized {}
|
||||||
|
|
||||||
|
#[rustc_builtin_macro]
|
||||||
|
macro_rules! asm {
|
||||||
|
() => {};
|
||||||
|
}
|
||||||
|
|
||||||
|
// CHECK-LABEL: @cc_clobber
|
||||||
|
// CHECK: call void asm sideeffect "", "~{cc}"()
|
||||||
|
#[no_mangle]
|
||||||
|
pub unsafe fn cc_clobber() {
|
||||||
|
asm!("", options(nostack, nomem));
|
||||||
|
}
|
||||||
|
|
||||||
|
// CHECK-LABEL: @no_clobber
|
||||||
|
// CHECK: call void asm sideeffect "", ""()
|
||||||
|
#[no_mangle]
|
||||||
|
pub unsafe fn no_clobber() {
|
||||||
|
asm!("", options(nostack, nomem, preserves_flags));
|
||||||
|
}
|
||||||
|
|
||||||
|
// CHECK-LABEL: @clobber_abi
|
||||||
|
// CHECK: asm sideeffect "", "={w0},={w1},={w2},={w3},={w4},={w5},={w6},={w7},={w8},={w9},={w10},={w11},={w12},={w15},={w16},={w17},={w30},={q0},={q1},={q2},={q3},={q4},={q5},={q6},={q7},={q8},={q9},={q10},={q11},={q12},={q13},={q14},={q15}"()
|
||||||
|
#[no_mangle]
|
||||||
|
pub unsafe fn clobber_abi() {
|
||||||
|
asm!("", clobber_abi("C"), options(nostack, nomem, preserves_flags));
|
||||||
|
}
|
28
tests/ui/asm/aarch64/aarch64-sve.rs
Normal file
28
tests/ui/asm/aarch64/aarch64-sve.rs
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
//@ only-aarch64
|
||||||
|
//@ build-pass
|
||||||
|
//@ needs-asm-support
|
||||||
|
|
||||||
|
#![crate_type = "rlib"]
|
||||||
|
#![feature(no_core, rustc_attrs, lang_items)]
|
||||||
|
#![no_core]
|
||||||
|
|
||||||
|
// AArch64 test corresponding to arm64ec-sve.rs.
|
||||||
|
|
||||||
|
#[lang = "sized"]
|
||||||
|
trait Sized {}
|
||||||
|
#[lang = "copy"]
|
||||||
|
trait Copy {}
|
||||||
|
|
||||||
|
impl Copy for f64 {}
|
||||||
|
|
||||||
|
#[rustc_builtin_macro]
|
||||||
|
macro_rules! asm {
|
||||||
|
() => {};
|
||||||
|
}
|
||||||
|
|
||||||
|
fn f(x: f64) {
|
||||||
|
unsafe {
|
||||||
|
asm!("", out("p0") _);
|
||||||
|
asm!("", out("ffr") _);
|
||||||
|
}
|
||||||
|
}
|
31
tests/ui/asm/aarch64/arm64ec-sve.rs
Normal file
31
tests/ui/asm/aarch64/arm64ec-sve.rs
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
//@ compile-flags: --target arm64ec-pc-windows-msvc
|
||||||
|
//@ needs-asm-support
|
||||||
|
//@ needs-llvm-components: aarch64
|
||||||
|
|
||||||
|
#![crate_type = "rlib"]
|
||||||
|
#![feature(no_core, rustc_attrs, lang_items, asm_experimental_arch)]
|
||||||
|
#![no_core]
|
||||||
|
|
||||||
|
// SVE cannot be used for Arm64EC
|
||||||
|
// https://github.com/rust-lang/rust/pull/131332#issuecomment-2401189142
|
||||||
|
|
||||||
|
#[lang = "sized"]
|
||||||
|
trait Sized {}
|
||||||
|
#[lang = "copy"]
|
||||||
|
trait Copy {}
|
||||||
|
|
||||||
|
impl Copy for f64 {}
|
||||||
|
|
||||||
|
#[rustc_builtin_macro]
|
||||||
|
macro_rules! asm {
|
||||||
|
() => {};
|
||||||
|
}
|
||||||
|
|
||||||
|
fn f(x: f64) {
|
||||||
|
unsafe {
|
||||||
|
asm!("", out("p0") _);
|
||||||
|
//~^ ERROR cannot use register `p0`
|
||||||
|
asm!("", out("ffr") _);
|
||||||
|
//~^ ERROR cannot use register `ffr`
|
||||||
|
}
|
||||||
|
}
|
14
tests/ui/asm/aarch64/arm64ec-sve.stderr
Normal file
14
tests/ui/asm/aarch64/arm64ec-sve.stderr
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
error: cannot use register `p0`: x13, x14, x23, x24, x28, v16-v31, p*, ffr cannot be used for Arm64EC
|
||||||
|
--> $DIR/arm64ec-sve.rs:26:18
|
||||||
|
|
|
||||||
|
LL | asm!("", out("p0") _);
|
||||||
|
| ^^^^^^^^^^^
|
||||||
|
|
||||||
|
error: cannot use register `ffr`: x13, x14, x23, x24, x28, v16-v31, p*, ffr cannot be used for Arm64EC
|
||||||
|
--> $DIR/arm64ec-sve.rs:28:18
|
||||||
|
|
|
||||||
|
LL | asm!("", out("ffr") _);
|
||||||
|
| ^^^^^^^^^^^^
|
||||||
|
|
||||||
|
error: aborting due to 2 previous errors
|
||||||
|
|
Loading…
Reference in New Issue
Block a user