diff options
author | Namish Kukreja <namikukr@quicinc.com> | 2024-06-03 16:33:59 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-06-03 16:33:59 -0700 |
commit | 43847c1de60ddba26d93c138ad81aa0d3b3c8c31 (patch) | |
tree | 6f3fea040acb186a0b7777ed1fc2847fe3ee31df /llvm/lib | |
parent | 30e983c40c71390c6c9506a8e4f914b85d009c3d (diff) | |
download | llvm-43847c1de60ddba26d93c138ad81aa0d3b3c8c31.zip llvm-43847c1de60ddba26d93c138ad81aa0d3b3c8c31.tar.gz llvm-43847c1de60ddba26d93c138ad81aa0d3b3c8c31.tar.bz2 |
[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
Diffstat (limited to 'llvm/lib')
-rw-r--r-- | llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp | 27 |
1 files changed, 27 insertions, 0 deletions
diff --git a/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp b/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp index 13a68b7..57e4f6d2 100644 --- a/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp +++ b/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp @@ -294,11 +294,13 @@ public: #include "AArch64GenAsmMatcher.inc" }; bool IsILP32; + bool IsWindowsArm64EC; AArch64AsmParser(const MCSubtargetInfo &STI, MCAsmParser &Parser, const MCInstrInfo &MII, const MCTargetOptions &Options) : MCTargetAsmParser(Options, STI, MII) { IsILP32 = STI.getTargetTriple().getEnvironment() == Triple::GNUILP32; + IsWindowsArm64EC = STI.getTargetTriple().isWindowsArm64EC(); MCAsmParserExtension::Initialize(Parser); MCStreamer &S = getParser().getStreamer(); if (S.getTargetStreamer() == nullptr) @@ -5315,6 +5317,31 @@ bool AArch64AsmParser::validateInstruction(MCInst &Inst, SMLoc &IDLoc, } } + // On ARM64EC, only valid registers may be used. Warn against using + // explicitly disallowed registers. + if (IsWindowsArm64EC) { + for (unsigned i = 0; i < Inst.getNumOperands(); ++i) { + if (Inst.getOperand(i).isReg()) { + unsigned Reg = Inst.getOperand(i).getReg(); + // At this point, vector registers are matched to their + // appropriately sized alias. + if ((Reg == AArch64::W13 || Reg == AArch64::X13) || + (Reg == AArch64::W14 || Reg == AArch64::X14) || + (Reg == AArch64::W23 || Reg == AArch64::X23) || + (Reg == AArch64::W24 || Reg == AArch64::X24) || + (Reg == AArch64::W28 || Reg == AArch64::X28) || + (Reg >= AArch64::Q16 && Reg <= AArch64::Q31) || + (Reg >= AArch64::D16 && Reg <= AArch64::D31) || + (Reg >= AArch64::S16 && Reg <= AArch64::S31) || + (Reg >= AArch64::H16 && Reg <= AArch64::H31) || + (Reg >= AArch64::B16 && Reg <= AArch64::B31)) { + Warning(IDLoc, "register " + Twine(RI->getName(Reg)) + + " is disallowed on ARM64EC."); + } + } + } + } + // Check for indexed addressing modes w/ the base register being the // same as a destination/source register or pair load where // the Rt == Rt2. All of those are undefined behaviour. |