diff --git a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64InstPrinter.cpp b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64InstPrinter.cpp index 3c8b5712c1f0c..54b58e948daf2 100644 --- a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64InstPrinter.cpp +++ b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64InstPrinter.cpp @@ -1017,14 +1017,22 @@ bool AArch64InstPrinter::printSysAlias(const MCInst *MI, else return false; + StringRef Reg = getRegisterName(MI->getOperand(4).getReg()); + bool NotXZR = Reg != "xzr"; + + // If a mandatory is not specified in the TableGen + // (i.e. no register operand should be present), and the register value + // is not xzr/x31, then disassemble to a SYS alias instead. + if (NotXZR && !NeedsReg) + return false; + std::string Str = Ins + Name; llvm::transform(Str, Str.begin(), ::tolower); O << '\t' << Str; - if (NeedsReg) { - O << ", "; - printRegName(O, MI->getOperand(4).getReg()); - } + + if (NeedsReg) + O << ", " << Reg; return true; } diff --git a/llvm/test/MC/AArch64/arm64-aliases.s b/llvm/test/MC/AArch64/arm64-aliases.s index 3ace7a0f7183b..ae157c676c95f 100644 --- a/llvm/test/MC/AArch64/arm64-aliases.s +++ b/llvm/test/MC/AArch64/arm64-aliases.s @@ -512,6 +512,20 @@ foo: sys #4, c8, c3, #6 ; CHECK: tlbi vmalls12e1is +; Check that all 5 register bits are set (0x31): +; (from Arm ARM regarding TLBI instructions without operands) +; "Rt should be encoded as 0b11111. If the Rt field is not set to 0b11111, +; it is CONSTRAINED UNPREDICTABLE whether: +; * The instruction is UNDEFINED. +; * The instruction behaves as if the Rt field is set to 0b11111." +; +; Do not disassemble this to `tlbi` but a SYS alias instead +; + sys #4, c8, c7, #6, x30 +; CHECK: sys #0x4, c8, c7, #0x6, x30 + sys #4, c8, c7, #6, x31 +; CHECK: tlbi vmalls12e1 + ic ialluis ; CHECK: ic ialluis ; encoding: [0x1f,0x71,0x08,0xd5] ic iallu