[llvm] f38c83c - [AArch64][llvm] Disassemble instructions in `SYS` alias encoding space more correctly (#153905)
via llvm-commits
llvm-commits at lists.llvm.org
Mon Aug 18 06:41:44 PDT 2025
Author: Jonathan Thackray
Date: 2025-08-18T14:41:41+01:00
New Revision: f38c83c582cb9de04556c32bc6b18ad1aeda74af
URL: https://github.com/llvm/llvm-project/commit/f38c83c582cb9de04556c32bc6b18ad1aeda74af
DIFF: https://github.com/llvm/llvm-project/commit/f38c83c582cb9de04556c32bc6b18ad1aeda74af.diff
LOG: [AArch64][llvm] Disassemble instructions in `SYS` alias encoding space more correctly (#153905)
For instructions in the `SYS` alias encoding space which take no
register operands, and where the unused 5 register bits are not all set
(0x31, 0b11111), then disassemble to a `SYS` alias and not the
instruction, since it is not considered valid.
This is because it is specified in the Arm ARM in text similar to this
(e.g. page C5-1037 of DDI0487L.b for `TLBI ALLE1`, or page C5-1585 for
`GCSPOPX`):
```
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.
```
Since we want to follow "should" directives, and not encourage undefined
behaviour, only assemble or disassemble instructions considered valid.
Add an extra test-case for this, and all existing test-cases are
continuing to pass.
Added:
Modified:
llvm/lib/Target/AArch64/MCTargetDesc/AArch64InstPrinter.cpp
llvm/test/MC/AArch64/arm64-aliases.s
Removed:
################################################################################
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
More information about the llvm-commits
mailing list