[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