Skip to content

Commit 43847c1

Browse files
authored
[ARM64EC] Warn on using disallowed registers in assembly src. (#93618)
ARM64EC designates a set of disallowed registers, because a mapping does not exist from them to x64. The MSVC assembler (armasm64) has a warning for this. A test is also included as part of the patch. See the list of disallowed registers below: https://learn.microsoft.com/en-us/cpp/build/arm64ec-windows-abi-conventions?view=msvc-170#register-mapping
1 parent 30e983c commit 43847c1

File tree

2 files changed

+118
-0
lines changed

2 files changed

+118
-0
lines changed

llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -294,11 +294,13 @@ class AArch64AsmParser : public MCTargetAsmParser {
294294
#include "AArch64GenAsmMatcher.inc"
295295
};
296296
bool IsILP32;
297+
bool IsWindowsArm64EC;
297298

298299
AArch64AsmParser(const MCSubtargetInfo &STI, MCAsmParser &Parser,
299300
const MCInstrInfo &MII, const MCTargetOptions &Options)
300301
: MCTargetAsmParser(Options, STI, MII) {
301302
IsILP32 = STI.getTargetTriple().getEnvironment() == Triple::GNUILP32;
303+
IsWindowsArm64EC = STI.getTargetTriple().isWindowsArm64EC();
302304
MCAsmParserExtension::Initialize(Parser);
303305
MCStreamer &S = getParser().getStreamer();
304306
if (S.getTargetStreamer() == nullptr)
@@ -5315,6 +5317,31 @@ bool AArch64AsmParser::validateInstruction(MCInst &Inst, SMLoc &IDLoc,
53155317
}
53165318
}
53175319

5320+
// On ARM64EC, only valid registers may be used. Warn against using
5321+
// explicitly disallowed registers.
5322+
if (IsWindowsArm64EC) {
5323+
for (unsigned i = 0; i < Inst.getNumOperands(); ++i) {
5324+
if (Inst.getOperand(i).isReg()) {
5325+
unsigned Reg = Inst.getOperand(i).getReg();
5326+
// At this point, vector registers are matched to their
5327+
// appropriately sized alias.
5328+
if ((Reg == AArch64::W13 || Reg == AArch64::X13) ||
5329+
(Reg == AArch64::W14 || Reg == AArch64::X14) ||
5330+
(Reg == AArch64::W23 || Reg == AArch64::X23) ||
5331+
(Reg == AArch64::W24 || Reg == AArch64::X24) ||
5332+
(Reg == AArch64::W28 || Reg == AArch64::X28) ||
5333+
(Reg >= AArch64::Q16 && Reg <= AArch64::Q31) ||
5334+
(Reg >= AArch64::D16 && Reg <= AArch64::D31) ||
5335+
(Reg >= AArch64::S16 && Reg <= AArch64::S31) ||
5336+
(Reg >= AArch64::H16 && Reg <= AArch64::H31) ||
5337+
(Reg >= AArch64::B16 && Reg <= AArch64::B31)) {
5338+
Warning(IDLoc, "register " + Twine(RI->getName(Reg)) +
5339+
" is disallowed on ARM64EC.");
5340+
}
5341+
}
5342+
}
5343+
}
5344+
53185345
// Check for indexed addressing modes w/ the base register being the
53195346
// same as a destination/source register or pair load where
53205347
// the Rt == Rt2. All of those are undefined behaviour.
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
// RUN: llvm-mc -triple arm64ec-pc-windows-msvc < %s 2> %t.log
2+
// RUN: FileCheck %s --check-prefix=CHECK-ERR < %t.log
3+
// RUN: llvm-mc -triple aarch64-windows-msvc < %s > %t.log 2>&1
4+
// RUN: FileCheck %s --check-prefix=CHECK-NOEC < %t.log
5+
6+
// ---- disallowed x registers ----
7+
orr x13, x0, x1 // x13
8+
// CHECK-ERR: warning: register X13 is disallowed on ARM64EC.
9+
orr x14, x2, x3 // x14
10+
// CHECK-ERR: warning: register X14 is disallowed on ARM64EC.
11+
orr x4, x23, x5 // x23
12+
// CHECK-ERR: warning: register X23 is disallowed on ARM64EC.
13+
orr x6, x7, x24 // x24
14+
// CHECK-ERR: warning: register X24 is disallowed on ARM64EC.
15+
orr x28, x8, x9 // x28
16+
// CHECK-ERR: warning: register X28 is disallowed on ARM64EC.
17+
18+
// ---- disallowed w registers ----
19+
orr w0, w13, w1 // w13
20+
// CHECK-ERR: warning: register W13 is disallowed on ARM64EC.
21+
orr w14, w2, w3 // w14
22+
// CHECK-ERR: warning: register W14 is disallowed on ARM64EC.
23+
orr w4, w23, w5 // w23
24+
// CHECK-ERR: warning: register W23 is disallowed on ARM64EC.
25+
orr w6, w7, w24 // W24
26+
// CHECK-ERR: warning: register W24 is disallowed on ARM64EC.
27+
orr w28, w8, w9 // w28
28+
// CHECK-ERR: warning: register W28 is disallowed on ARM64EC.
29+
30+
// ---- disallowed vector registers ----
31+
orn v1.8b, v16.8b, v2.8b // v16
32+
// CHECK-ERR: warning: register D16 is disallowed on ARM64EC.
33+
orn v2.16b, v17.16b, v3.16b // v17
34+
// CHECK-ERR: warning: register Q17 is disallowed on ARM64EC.
35+
orn v3.8b, v18.8b, v4.8b // v18
36+
// CHECK-ERR: warning: register D18 is disallowed on ARM64EC.
37+
orn v4.16b, v19.16b, v5.16b // v19
38+
// CHECK-ERR: warning: register Q19 is disallowed on ARM64EC.
39+
orn v5.8b, v20.8b, v6.8b // v20
40+
// CHECK-ERR: warning: register D20 is disallowed on ARM64EC.
41+
orn v21.8b, v6.8b, v7.8b // v21
42+
// CHECK-ERR: warning: register D21 is disallowed on ARM64EC.
43+
orn v7.16b, v8.16b, v22.16b // v22
44+
// CHECK-ERR: warning: register Q22 is disallowed on ARM64EC.
45+
orn v23.8b, v8.8b, v9.8b // v23
46+
// CHECK-ERR: warning: register D23 is disallowed on ARM64EC.
47+
orn v9.16b, v24.16b, v10.16b // v24
48+
// CHECK-ERR: warning: register Q24 is disallowed on ARM64EC.
49+
orn v10.8b, v25.8b, v11.8b // v25
50+
// CHECK-ERR: warning: register D25 is disallowed on ARM64EC.
51+
orn v11.8b, v12.8b, v26.8b // v26
52+
// CHECK-ERR: warning: register D26 is disallowed on ARM64EC.
53+
orn v12.8b, v27.8b, v13.8b // v27
54+
// CHECK-ERR: warning: register D27 is disallowed on ARM64EC.
55+
orn v13.16b, v28.16b, v14.16b // v28
56+
// CHECK-ERR: warning: register Q28 is disallowed on ARM64EC.
57+
orn v14.8b, v29.8b, v15.8b // v29
58+
// CHECK-ERR: warning: register D29 is disallowed on ARM64EC.
59+
orn v15.8b, v30.8b, v15.8b // v30
60+
// CHECK-ERR: warning: register D30 is disallowed on ARM64EC.
61+
orn v1.16b, v31.16b, v1.16b // v31
62+
// CHECK-ERR: warning: register Q31 is disallowed on ARM64EC.
63+
64+
// ---- random tests on h, b, d, s registers ----
65+
orn.16b v1, v16, v2
66+
// CHECK-ERR: warning: register Q16 is disallowed on ARM64EC.
67+
str d17, [x0]
68+
// CHECK-ERR: warning: register D17 is disallowed on ARM64EC.
69+
fmul d2, d18, d11
70+
// CHECK-ERR: warning: register D18 is disallowed on ARM64EC.
71+
clz.8h v3, v19
72+
// CHECK-ERR: warning: register Q19 is disallowed on ARM64EC.
73+
add.4s v0, v20, v1
74+
// CHECK-ERR: warning: register Q20 is disallowed on ARM64EC.
75+
add.2d v0, v20, v1
76+
// CHECK-ERR: warning: register Q20 is disallowed on ARM64EC.
77+
str b17, [x28]
78+
// CHECK-ERR: warning: register B17 is disallowed on ARM64EC.
79+
// CHECK-ERR: warning: register X28 is disallowed on ARM64EC.
80+
addv h21, v22.4h
81+
// CHECK-ERR: warning: register H21 is disallowed on ARM64EC.
82+
// CHECK-ERR: warning: register D22 is disallowed on ARM64EC.
83+
mov w14, v24.s[0]
84+
// CHECK-ERR: warning: register W14 is disallowed on ARM64EC.
85+
// CHECK-ERR: warning: register Q24 is disallowed on ARM64EC.
86+
add x13, x14, x28
87+
// CHECK-ERR: warning: register X13 is disallowed on ARM64EC.
88+
// CHECK-ERR: warning: register X14 is disallowed on ARM64EC.
89+
// CHECK-ERR: warning: register X28 is disallowed on ARM64EC.
90+
91+
// CHECK-NOEC-NOT: warning:

0 commit comments

Comments
 (0)