Skip to content

Commit 3307178

Browse files
committed
Disallow z0-z15 in Arm64EC inline assembly
1 parent 750d125 commit 3307178

File tree

7 files changed

+345
-105
lines changed

7 files changed

+345
-105
lines changed

compiler/rustc_codegen_gcc/src/asm.rs

+16-7
Original file line numberDiff line numberDiff line change
@@ -611,9 +611,12 @@ fn reg_to_gcc(reg: InlineAsmRegOrRegClass) -> ConstraintOrRegister {
611611
}
612612
// They can be retrieved from https://gcc.gnu.org/onlinedocs/gcc/Machine-Constraints.html
613613
InlineAsmRegOrRegClass::RegClass(reg) => match reg {
614-
InlineAsmRegClass::AArch64(AArch64InlineAsmRegClass::reg) => "r",
615-
InlineAsmRegClass::AArch64(AArch64InlineAsmRegClass::vreg) => "w",
616-
InlineAsmRegClass::AArch64(AArch64InlineAsmRegClass::vreg_low16) => "x",
614+
InlineAsmRegClass::AArch64(AArch64InlineAsmRegClass::reg)
615+
| InlineAsmRegClass::Arm64EC(Arm64ECInlineAsmRegClass::reg) => "r",
616+
InlineAsmRegClass::AArch64(AArch64InlineAsmRegClass::vreg)
617+
| InlineAsmRegClass::Arm64EC(Arm64ECInlineAsmRegClass::vreg) => "w",
618+
InlineAsmRegClass::AArch64(AArch64InlineAsmRegClass::vreg_low16)
619+
| InlineAsmRegClass::Arm64EC(Arm64ECInlineAsmRegClass::vreg_low16) => "x",
617620
InlineAsmRegClass::AArch64(AArch64InlineAsmRegClass::preg) => {
618621
unreachable!("clobber-only")
619622
}
@@ -698,9 +701,12 @@ fn reg_to_gcc(reg: InlineAsmRegOrRegClass) -> ConstraintOrRegister {
698701
/// the type is, as long as it is valid for the constraint code.
699702
fn dummy_output_type<'gcc, 'tcx>(cx: &CodegenCx<'gcc, 'tcx>, reg: InlineAsmRegClass) -> Type<'gcc> {
700703
match reg {
701-
InlineAsmRegClass::AArch64(AArch64InlineAsmRegClass::reg) => cx.type_i32(),
704+
InlineAsmRegClass::AArch64(AArch64InlineAsmRegClass::reg)
705+
| InlineAsmRegClass::Arm64EC(Arm64ECInlineAsmRegClass::reg) => cx.type_i32(),
702706
InlineAsmRegClass::AArch64(AArch64InlineAsmRegClass::vreg)
703-
| InlineAsmRegClass::AArch64(AArch64InlineAsmRegClass::vreg_low16) => {
707+
| InlineAsmRegClass::AArch64(AArch64InlineAsmRegClass::vreg_low16)
708+
| InlineAsmRegClass::Arm64EC(Arm64ECInlineAsmRegClass::vreg)
709+
| InlineAsmRegClass::Arm64EC(Arm64ECInlineAsmRegClass::vreg_low16) => {
704710
cx.type_vector(cx.type_i64(), 2)
705711
}
706712
InlineAsmRegClass::AArch64(AArch64InlineAsmRegClass::preg) => {
@@ -863,9 +869,12 @@ fn modifier_to_gcc(
863869
// The modifiers can be retrieved from
864870
// https://gcc.gnu.org/onlinedocs/gcc/Modifiers.html#Modifiers
865871
match reg {
866-
InlineAsmRegClass::AArch64(AArch64InlineAsmRegClass::reg) => modifier,
872+
InlineAsmRegClass::AArch64(AArch64InlineAsmRegClass::reg)
873+
| InlineAsmRegClass::Arm64EC(Arm64ECInlineAsmRegClass::reg) => modifier,
867874
InlineAsmRegClass::AArch64(AArch64InlineAsmRegClass::vreg)
868-
| InlineAsmRegClass::AArch64(AArch64InlineAsmRegClass::vreg_low16) => {
875+
| InlineAsmRegClass::AArch64(AArch64InlineAsmRegClass::vreg_low16)
876+
| InlineAsmRegClass::Arm64EC(Arm64ECInlineAsmRegClass::vreg)
877+
| InlineAsmRegClass::Arm64EC(Arm64ECInlineAsmRegClass::vreg_low16) => {
869878
if modifier == Some('v') { None } else { modifier }
870879
}
871880
InlineAsmRegClass::AArch64(AArch64InlineAsmRegClass::preg) => {

compiler/rustc_codegen_llvm/src/asm.rs

+59-29
Original file line numberDiff line numberDiff line change
@@ -656,9 +656,12 @@ fn reg_to_llvm(reg: InlineAsmRegOrRegClass, layout: Option<&TyAndLayout<'_>>) ->
656656
// The constraints can be retrieved from
657657
// https://llvm.org/docs/LangRef.html#supported-constraint-code-list
658658
InlineAsmRegOrRegClass::RegClass(reg) => match reg {
659-
AArch64(AArch64InlineAsmRegClass::reg) => "r",
660-
AArch64(AArch64InlineAsmRegClass::vreg) => "w",
661-
AArch64(AArch64InlineAsmRegClass::vreg_low16) => "x",
659+
AArch64(AArch64InlineAsmRegClass::reg) | Arm64EC(Arm64ECInlineAsmRegClass::reg) => "r",
660+
AArch64(AArch64InlineAsmRegClass::vreg) | Arm64EC(Arm64ECInlineAsmRegClass::vreg) => {
661+
"w"
662+
}
663+
AArch64(AArch64InlineAsmRegClass::vreg_low16)
664+
| Arm64EC(Arm64ECInlineAsmRegClass::vreg_low16) => "x",
662665
AArch64(AArch64InlineAsmRegClass::preg) => unreachable!("clobber-only"),
663666
Arm(ArmInlineAsmRegClass::reg) => "r",
664667
Arm(ArmInlineAsmRegClass::sreg)
@@ -734,8 +737,11 @@ fn modifier_to_llvm(
734737
// The modifiers can be retrieved from
735738
// https://llvm.org/docs/LangRef.html#asm-template-argument-modifiers
736739
match reg {
737-
AArch64(AArch64InlineAsmRegClass::reg) => modifier,
738-
AArch64(AArch64InlineAsmRegClass::vreg) | AArch64(AArch64InlineAsmRegClass::vreg_low16) => {
740+
AArch64(AArch64InlineAsmRegClass::reg) | Arm64EC(Arm64ECInlineAsmRegClass::reg) => modifier,
741+
AArch64(AArch64InlineAsmRegClass::vreg)
742+
| AArch64(AArch64InlineAsmRegClass::vreg_low16)
743+
| Arm64EC(Arm64ECInlineAsmRegClass::vreg)
744+
| Arm64EC(Arm64ECInlineAsmRegClass::vreg_low16) => {
739745
if modifier == Some('v') {
740746
None
741747
} else {
@@ -817,10 +823,13 @@ fn modifier_to_llvm(
817823
fn dummy_output_type<'ll>(cx: &CodegenCx<'ll, '_>, reg: InlineAsmRegClass) -> &'ll Type {
818824
use InlineAsmRegClass::*;
819825
match reg {
820-
AArch64(AArch64InlineAsmRegClass::reg) => cx.type_i32(),
821-
AArch64(AArch64InlineAsmRegClass::vreg) | AArch64(AArch64InlineAsmRegClass::vreg_low16) => {
822-
cx.type_vector(cx.type_i64(), 2)
826+
AArch64(AArch64InlineAsmRegClass::reg) | Arm64EC(Arm64ECInlineAsmRegClass::reg) => {
827+
cx.type_i32()
823828
}
829+
AArch64(AArch64InlineAsmRegClass::vreg)
830+
| AArch64(AArch64InlineAsmRegClass::vreg_low16)
831+
| Arm64EC(Arm64ECInlineAsmRegClass::vreg)
832+
| Arm64EC(Arm64ECInlineAsmRegClass::vreg_low16) => cx.type_vector(cx.type_i64(), 2),
824833
AArch64(AArch64InlineAsmRegClass::preg) => unreachable!("clobber-only"),
825834
Arm(ArmInlineAsmRegClass::reg) => cx.type_i32(),
826835
Arm(ArmInlineAsmRegClass::sreg) | Arm(ArmInlineAsmRegClass::sreg_low16) => cx.type_f32(),
@@ -922,17 +931,22 @@ fn llvm_fixup_input<'ll, 'tcx>(
922931
use InlineAsmRegClass::*;
923932
let dl = &bx.tcx.data_layout;
924933
match (reg, layout.abi) {
925-
(AArch64(AArch64InlineAsmRegClass::vreg), Abi::Scalar(s)) => {
934+
(
935+
AArch64(AArch64InlineAsmRegClass::vreg) | Arm64EC(Arm64ECInlineAsmRegClass::vreg),
936+
Abi::Scalar(s),
937+
) => {
926938
if let Primitive::Int(Integer::I8, _) = s.primitive() {
927939
let vec_ty = bx.cx.type_vector(bx.cx.type_i8(), 8);
928940
bx.insert_element(bx.const_undef(vec_ty), value, bx.const_i32(0))
929941
} else {
930942
value
931943
}
932944
}
933-
(AArch64(AArch64InlineAsmRegClass::vreg_low16), Abi::Scalar(s))
934-
if s.primitive() != Primitive::Float(Float::F128) =>
935-
{
945+
(
946+
AArch64(AArch64InlineAsmRegClass::vreg_low16)
947+
| Arm64EC(Arm64ECInlineAsmRegClass::vreg_low16),
948+
Abi::Scalar(s),
949+
) if s.primitive() != Primitive::Float(Float::F128) => {
936950
let elem_ty = llvm_asm_scalar_type(bx.cx, s);
937951
let count = 16 / layout.size.bytes();
938952
let vec_ty = bx.cx.type_vector(elem_ty, count);
@@ -943,9 +957,11 @@ fn llvm_fixup_input<'ll, 'tcx>(
943957
}
944958
bx.insert_element(bx.const_undef(vec_ty), value, bx.const_i32(0))
945959
}
946-
(AArch64(AArch64InlineAsmRegClass::vreg_low16), Abi::Vector { element, count })
947-
if layout.size.bytes() == 8 =>
948-
{
960+
(
961+
AArch64(AArch64InlineAsmRegClass::vreg_low16)
962+
| Arm64EC(Arm64ECInlineAsmRegClass::vreg_low16),
963+
Abi::Vector { element, count },
964+
) if layout.size.bytes() == 8 => {
949965
let elem_ty = llvm_asm_scalar_type(bx.cx, element);
950966
let vec_ty = bx.cx.type_vector(elem_ty, count);
951967
let indices: Vec<_> = (0..count * 2).map(|x| bx.const_i32(x as i32)).collect();
@@ -1064,25 +1080,32 @@ fn llvm_fixup_output<'ll, 'tcx>(
10641080
) -> &'ll Value {
10651081
use InlineAsmRegClass::*;
10661082
match (reg, layout.abi) {
1067-
(AArch64(AArch64InlineAsmRegClass::vreg), Abi::Scalar(s)) => {
1083+
(
1084+
AArch64(AArch64InlineAsmRegClass::vreg) | Arm64EC(Arm64ECInlineAsmRegClass::vreg),
1085+
Abi::Scalar(s),
1086+
) => {
10681087
if let Primitive::Int(Integer::I8, _) = s.primitive() {
10691088
bx.extract_element(value, bx.const_i32(0))
10701089
} else {
10711090
value
10721091
}
10731092
}
1074-
(AArch64(AArch64InlineAsmRegClass::vreg_low16), Abi::Scalar(s))
1075-
if s.primitive() != Primitive::Float(Float::F128) =>
1076-
{
1093+
(
1094+
AArch64(AArch64InlineAsmRegClass::vreg_low16)
1095+
| Arm64EC(Arm64ECInlineAsmRegClass::vreg_low16),
1096+
Abi::Scalar(s),
1097+
) if s.primitive() != Primitive::Float(Float::F128) => {
10771098
value = bx.extract_element(value, bx.const_i32(0));
10781099
if let Primitive::Pointer(_) = s.primitive() {
10791100
value = bx.inttoptr(value, layout.llvm_type(bx.cx));
10801101
}
10811102
value
10821103
}
1083-
(AArch64(AArch64InlineAsmRegClass::vreg_low16), Abi::Vector { element, count })
1084-
if layout.size.bytes() == 8 =>
1085-
{
1104+
(
1105+
AArch64(AArch64InlineAsmRegClass::vreg_low16)
1106+
| Arm64EC(Arm64ECInlineAsmRegClass::vreg_low16),
1107+
Abi::Vector { element, count },
1108+
) if layout.size.bytes() == 8 => {
10861109
let elem_ty = llvm_asm_scalar_type(bx.cx, element);
10871110
let vec_ty = bx.cx.type_vector(elem_ty, count * 2);
10881111
let indices: Vec<_> = (0..count).map(|x| bx.const_i32(x as i32)).collect();
@@ -1195,23 +1218,30 @@ fn llvm_fixup_output_type<'ll, 'tcx>(
11951218
) -> &'ll Type {
11961219
use InlineAsmRegClass::*;
11971220
match (reg, layout.abi) {
1198-
(AArch64(AArch64InlineAsmRegClass::vreg), Abi::Scalar(s)) => {
1221+
(
1222+
AArch64(AArch64InlineAsmRegClass::vreg) | Arm64EC(Arm64ECInlineAsmRegClass::vreg),
1223+
Abi::Scalar(s),
1224+
) => {
11991225
if let Primitive::Int(Integer::I8, _) = s.primitive() {
12001226
cx.type_vector(cx.type_i8(), 8)
12011227
} else {
12021228
layout.llvm_type(cx)
12031229
}
12041230
}
1205-
(AArch64(AArch64InlineAsmRegClass::vreg_low16), Abi::Scalar(s))
1206-
if s.primitive() != Primitive::Float(Float::F128) =>
1207-
{
1231+
(
1232+
AArch64(AArch64InlineAsmRegClass::vreg_low16)
1233+
| Arm64EC(Arm64ECInlineAsmRegClass::vreg_low16),
1234+
Abi::Scalar(s),
1235+
) if s.primitive() != Primitive::Float(Float::F128) => {
12081236
let elem_ty = llvm_asm_scalar_type(cx, s);
12091237
let count = 16 / layout.size.bytes();
12101238
cx.type_vector(elem_ty, count)
12111239
}
1212-
(AArch64(AArch64InlineAsmRegClass::vreg_low16), Abi::Vector { element, count })
1213-
if layout.size.bytes() == 8 =>
1214-
{
1240+
(
1241+
AArch64(AArch64InlineAsmRegClass::vreg_low16)
1242+
| Arm64EC(Arm64ECInlineAsmRegClass::vreg_low16),
1243+
Abi::Vector { element, count },
1244+
) if layout.size.bytes() == 8 => {
12151245
let elem_ty = llvm_asm_scalar_type(cx, element);
12161246
cx.type_vector(elem_ty, count * 2)
12171247
}

compiler/rustc_target/src/asm/aarch64.rs

+38-53
Original file line numberDiff line numberDiff line change
@@ -88,20 +88,6 @@ fn reserved_x18(
8888
}
8989
}
9090

91-
fn restricted_for_arm64ec(
92-
arch: InlineAsmArch,
93-
_reloc_model: RelocModel,
94-
_target_features: &FxIndexSet<Symbol>,
95-
_target: &Target,
96-
_is_clobber: bool,
97-
) -> Result<(), &'static str> {
98-
if arch == InlineAsmArch::Arm64EC {
99-
Err("x13, x14, x23, x24, x28, v16-v31, z*, p*, ffr cannot be used for Arm64EC")
100-
} else {
101-
Ok(())
102-
}
103-
}
104-
10591
def_regs! {
10692
AArch64 AArch64InlineAsmReg AArch64InlineAsmRegClass {
10793
x0: reg = ["x0", "w0"],
@@ -117,23 +103,22 @@ def_regs! {
117103
x10: reg = ["x10", "w10"],
118104
x11: reg = ["x11", "w11"],
119105
x12: reg = ["x12", "w12"],
120-
x13: reg = ["x13", "w13"] % restricted_for_arm64ec,
121-
x14: reg = ["x14", "w14"] % restricted_for_arm64ec,
106+
x13: reg = ["x13", "w13"],
107+
x14: reg = ["x14", "w14"],
122108
x15: reg = ["x15", "w15"],
123109
x16: reg = ["x16", "w16"],
124110
x17: reg = ["x17", "w17"],
125111
x18: reg = ["x18", "w18"] % reserved_x18,
126112
x20: reg = ["x20", "w20"],
127113
x21: reg = ["x21", "w21"],
128114
x22: reg = ["x22", "w22"],
129-
x23: reg = ["x23", "w23"] % restricted_for_arm64ec,
130-
x24: reg = ["x24", "w24"] % restricted_for_arm64ec,
115+
x23: reg = ["x23", "w23"],
116+
x24: reg = ["x24", "w24"],
131117
x25: reg = ["x25", "w25"],
132118
x26: reg = ["x26", "w26"],
133119
x27: reg = ["x27", "w27"],
134-
x28: reg = ["x28", "w28"] % restricted_for_arm64ec,
120+
x28: reg = ["x28", "w28"],
135121
x30: reg = ["x30", "w30", "lr", "wlr"],
136-
// FIXME: z* cannot be used for Arm64EC
137122
v0: vreg, vreg_low16 = ["v0", "b0", "h0", "s0", "d0", "q0", "z0"],
138123
v1: vreg, vreg_low16 = ["v1", "b1", "h1", "s1", "d1", "q1", "z1"],
139124
v2: vreg, vreg_low16 = ["v2", "b2", "h2", "s2", "d2", "q2", "z2"],
@@ -150,39 +135,39 @@ def_regs! {
150135
v13: vreg, vreg_low16 = ["v13", "b13", "h13", "s13", "d13", "q13", "z13"],
151136
v14: vreg, vreg_low16 = ["v14", "b14", "h14", "s14", "d14", "q14", "z14"],
152137
v15: vreg, vreg_low16 = ["v15", "b15", "h15", "s15", "d15", "q15", "z15"],
153-
v16: vreg = ["v16", "b16", "h16", "s16", "d16", "q16", "z16"] % restricted_for_arm64ec,
154-
v17: vreg = ["v17", "b17", "h17", "s17", "d17", "q17", "z17"] % restricted_for_arm64ec,
155-
v18: vreg = ["v18", "b18", "h18", "s18", "d18", "q18", "z18"] % restricted_for_arm64ec,
156-
v19: vreg = ["v19", "b19", "h19", "s19", "d19", "q19", "z19"] % restricted_for_arm64ec,
157-
v20: vreg = ["v20", "b20", "h20", "s20", "d20", "q20", "z20"] % restricted_for_arm64ec,
158-
v21: vreg = ["v21", "b21", "h21", "s21", "d21", "q21", "z21"] % restricted_for_arm64ec,
159-
v22: vreg = ["v22", "b22", "h22", "s22", "d22", "q22", "z22"] % restricted_for_arm64ec,
160-
v23: vreg = ["v23", "b23", "h23", "s23", "d23", "q23", "z23"] % restricted_for_arm64ec,
161-
v24: vreg = ["v24", "b24", "h24", "s24", "d24", "q24", "z24"] % restricted_for_arm64ec,
162-
v25: vreg = ["v25", "b25", "h25", "s25", "d25", "q25", "z25"] % restricted_for_arm64ec,
163-
v26: vreg = ["v26", "b26", "h26", "s26", "d26", "q26", "z26"] % restricted_for_arm64ec,
164-
v27: vreg = ["v27", "b27", "h27", "s27", "d27", "q27", "z27"] % restricted_for_arm64ec,
165-
v28: vreg = ["v28", "b28", "h28", "s28", "d28", "q28", "z28"] % restricted_for_arm64ec,
166-
v29: vreg = ["v29", "b29", "h29", "s29", "d29", "q29", "z29"] % restricted_for_arm64ec,
167-
v30: vreg = ["v30", "b30", "h30", "s30", "d30", "q30", "z30"] % restricted_for_arm64ec,
168-
v31: vreg = ["v31", "b31", "h31", "s31", "d31", "q31", "z31"] % restricted_for_arm64ec,
169-
p0: preg = ["p0"] % restricted_for_arm64ec,
170-
p1: preg = ["p1"] % restricted_for_arm64ec,
171-
p2: preg = ["p2"] % restricted_for_arm64ec,
172-
p3: preg = ["p3"] % restricted_for_arm64ec,
173-
p4: preg = ["p4"] % restricted_for_arm64ec,
174-
p5: preg = ["p5"] % restricted_for_arm64ec,
175-
p6: preg = ["p6"] % restricted_for_arm64ec,
176-
p7: preg = ["p7"] % restricted_for_arm64ec,
177-
p8: preg = ["p8"] % restricted_for_arm64ec,
178-
p9: preg = ["p9"] % restricted_for_arm64ec,
179-
p10: preg = ["p10"] % restricted_for_arm64ec,
180-
p11: preg = ["p11"] % restricted_for_arm64ec,
181-
p12: preg = ["p12"] % restricted_for_arm64ec,
182-
p13: preg = ["p13"] % restricted_for_arm64ec,
183-
p14: preg = ["p14"] % restricted_for_arm64ec,
184-
p15: preg = ["p15"] % restricted_for_arm64ec,
185-
ffr: preg = ["ffr"] % restricted_for_arm64ec,
138+
v16: vreg = ["v16", "b16", "h16", "s16", "d16", "q16", "z16"],
139+
v17: vreg = ["v17", "b17", "h17", "s17", "d17", "q17", "z17"],
140+
v18: vreg = ["v18", "b18", "h18", "s18", "d18", "q18", "z18"],
141+
v19: vreg = ["v19", "b19", "h19", "s19", "d19", "q19", "z19"],
142+
v20: vreg = ["v20", "b20", "h20", "s20", "d20", "q20", "z20"],
143+
v21: vreg = ["v21", "b21", "h21", "s21", "d21", "q21", "z21"],
144+
v22: vreg = ["v22", "b22", "h22", "s22", "d22", "q22", "z22"],
145+
v23: vreg = ["v23", "b23", "h23", "s23", "d23", "q23", "z23"],
146+
v24: vreg = ["v24", "b24", "h24", "s24", "d24", "q24", "z24"],
147+
v25: vreg = ["v25", "b25", "h25", "s25", "d25", "q25", "z25"],
148+
v26: vreg = ["v26", "b26", "h26", "s26", "d26", "q26", "z26"],
149+
v27: vreg = ["v27", "b27", "h27", "s27", "d27", "q27", "z27"],
150+
v28: vreg = ["v28", "b28", "h28", "s28", "d28", "q28", "z28"],
151+
v29: vreg = ["v29", "b29", "h29", "s29", "d29", "q29", "z29"],
152+
v30: vreg = ["v30", "b30", "h30", "s30", "d30", "q30", "z30"],
153+
v31: vreg = ["v31", "b31", "h31", "s31", "d31", "q31", "z31"],
154+
p0: preg = ["p0"],
155+
p1: preg = ["p1"],
156+
p2: preg = ["p2"],
157+
p3: preg = ["p3"],
158+
p4: preg = ["p4"],
159+
p5: preg = ["p5"],
160+
p6: preg = ["p6"],
161+
p7: preg = ["p7"],
162+
p8: preg = ["p8"],
163+
p9: preg = ["p9"],
164+
p10: preg = ["p10"],
165+
p11: preg = ["p11"],
166+
p12: preg = ["p12"],
167+
p13: preg = ["p13"],
168+
p14: preg = ["p14"],
169+
p15: preg = ["p15"],
170+
ffr: preg = ["ffr"],
186171
#error = ["x19", "w19"] =>
187172
"x19 is used internally by LLVM and cannot be used as an operand for inline asm",
188173
#error = ["x29", "w29", "fp", "wfp"] =>

0 commit comments

Comments
 (0)