[llvm] MC: X86 intel syntax: Support data32 and data16 better (PR #156287)

Danny Milosavljevic via llvm-commits llvm-commits at lists.llvm.org
Mon Sep 1 11:36:18 PDT 2025


https://github.com/daym updated https://github.com/llvm/llvm-project/pull/156287

>From 45022aaadf7c946dd26e9eb664231ba169139ed3 Mon Sep 17 00:00:00 2001
From: Danny Milosavljevic <dannym at friendly-machines.com>
Date: Mon, 1 Sep 2025 05:21:06 +0200
Subject: [PATCH 1/2] [x86][MC] Fix data32 push.

---
 llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp | 16 ++++++++++++----
 llvm/test/MC/X86/x86-16-intel.s                | 13 +++++++++++++
 llvm/test/MC/X86/x86-16.s                      | 12 ++++++++++++
 3 files changed, 37 insertions(+), 4 deletions(-)
 create mode 100644 llvm/test/MC/X86/x86-16-intel.s

diff --git a/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp b/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp
index d7671ed19589b..6cc6ab8949756 100644
--- a/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp
+++ b/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp
@@ -4538,14 +4538,22 @@ bool X86AsmParser::matchAndEmitIntelInstruction(
     if (X86Op->isImm()) {
       // If it's not a constant fall through and let remainder take care of it.
       const auto *CE = dyn_cast<MCConstantExpr>(X86Op->getImm());
-      unsigned Size = getPointerWidth();
+      // Determine the size. Prioritize the ForcedDataPrefix flag if it was set
+      // by a 'data32' prefix. Otherwise, fall back to the pointer width of the
+      // current mode.
+      unsigned Size = (ForcedDataPrefix == X86::Is32Bit) ? 32
+                    : (ForcedDataPrefix == X86::Is16Bit) ? 16
+                    : getPointerWidth();
+      ForcedDataPrefix = 0;
       if (CE &&
           (isIntN(Size, CE->getValue()) || isUIntN(Size, CE->getValue()))) {
         SmallString<16> Tmp;
         Tmp += Base;
-        Tmp += (is64BitMode())
-                   ? "q"
-                   : (is32BitMode()) ? "l" : (is16BitMode()) ? "w" : " ";
+        // Append the suffix corresponding to the determined size.
+        if (Size == 64) Tmp += "q";
+        else if (Size == 32) Tmp += "l";
+        else if (Size == 16) Tmp += "w";
+        else Tmp += " ";
         Op.setTokenValue(Tmp);
         // Do match in ATT mode to allow explicit suffix usage.
         Match.push_back(MatchInstruction(Operands, Inst, ErrorInfo,
diff --git a/llvm/test/MC/X86/x86-16-intel.s b/llvm/test/MC/X86/x86-16-intel.s
new file mode 100644
index 0000000000000..77ae4ae217218
--- /dev/null
+++ b/llvm/test/MC/X86/x86-16-intel.s
@@ -0,0 +1,13 @@
+// RUN: llvm-mc -triple i386-unknown-unknown-code16 --x86-asm-syntax=intel --show-encoding %s | FileCheck %s
+
+// CHECK: pushl $8
+// CHECK: encoding: [0x66,0x6a,0x08]
+          data32 push 8
+
+// CHECK: pushw $8
+// CHECK: encoding: [0x6a,0x08]
+          push 8
+
+// CHECK: lretl
+// CHECK: encoding: [0x66,0xcb]
+          data32 retf
diff --git a/llvm/test/MC/X86/x86-16.s b/llvm/test/MC/X86/x86-16.s
index b0a4bda56fcbf..b4e116ab1a0fb 100644
--- a/llvm/test/MC/X86/x86-16.s
+++ b/llvm/test/MC/X86/x86-16.s
@@ -1060,3 +1060,15 @@ xresldtrk
 // CHECK:  encoding: [0x66,0x8b,0x1e,A,A]
 // CHECK:  fixup A - offset: 3, value: nearer, kind: FK_Data_2
 movl    nearer, %ebx
+
+// CHECK: pushl $8
+// CHECK:  encoding: [0x66,0x6a,0x08]
+data32 push $8
+
+// CHECK: pushl $8
+// CHECK:  encoding: [0x66,0x6a,0x08]
+pushl $8
+
+// CHECK: pushw $8
+// CHECK:  encoding: [0x6a,0x08]
+push $8

>From 4aa3936ab21b11d01b845550692a97b1e2e0a817 Mon Sep 17 00:00:00 2001
From: Danny Milosavljevic <dannym at friendly-machines.com>
Date: Mon, 1 Sep 2025 20:34:57 +0200
Subject: [PATCH 2/2] [x86][MC]: Fix data16.

---
 .../lib/Target/X86/AsmParser/X86AsmParser.cpp | 22 +++++++++++++--
 llvm/test/MC/X86/x86-32-intel.s               | 28 +++++++++++++++++++
 2 files changed, 48 insertions(+), 2 deletions(-)
 create mode 100644 llvm/test/MC/X86/x86-32-intel.s

diff --git a/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp b/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp
index 6cc6ab8949756..211aa47e48fe3 100644
--- a/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp
+++ b/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp
@@ -3523,8 +3523,26 @@ bool X86AsmParser::parseInstruction(ParseInstructionInfo &Info, StringRef Name,
     PatchedName = Name;
 
   // Hacks to handle 'data16' and 'data32'
-  if (PatchedName == "data16" && is16BitMode()) {
-    return Error(NameLoc, "redundant data16 prefix");
+  if (PatchedName == "data16") {
+    if (is16BitMode())
+        return Error(NameLoc, "redundant data16 prefix");
+    if (is64BitMode())
+      return Error(NameLoc, "'data16' is not supported in 64-bit mode");
+    if (getLexer().isNot(AsmToken::EndOfStatement)) {
+      StringRef Next = Parser.getTok().getString();
+      getLexer().Lex();
+      // data16 effectively changes the instruction suffix.
+      // TODO Generalize.
+      if (Next == "call")
+        Next = "callw";
+      if (Next == "ljmp")
+        Next = "ljmpw";
+
+      Name = Next;
+      PatchedName = Name;
+      ForcedDataPrefix = X86::Is16Bit;
+      IsPrefix = false;
+    }
   }
   if (PatchedName == "data32") {
     if (is32BitMode())
diff --git a/llvm/test/MC/X86/x86-32-intel.s b/llvm/test/MC/X86/x86-32-intel.s
new file mode 100644
index 0000000000000..44fc5104653c2
--- /dev/null
+++ b/llvm/test/MC/X86/x86-32-intel.s
@@ -0,0 +1,28 @@
+// RUN: llvm-mc -triple i386-unknown-unknown --x86-asm-syntax=intel --show-encoding %s | FileCheck %s
+
+// CHECK: encoding: [0x66,0x6a,0x08]
+          data16 push 8
+
+// CHECK: encoding: [0x6a,0x08]
+          push 8
+
+// CxHECK: encoding: [0x66,0xcb]
+     //     data16 retf
+
+// CHECK: encoding: [0xcb]
+          retf
+
+// CHECK: encoding: [0x66,0x9a,0xcd,0xab,0xce,0x7a]
+          data16 call 0x7ace, 0xabcd
+
+// CHECK: encoding: [0x9a,0xcd,0xab,0x00,0x00,0xce,0x7a]
+          call 0x7ace, 0xabcd
+
+// CHECK: encoding: [0xe8,A,A,A,A]
+          call a
+
+// CxHECK: encoding: [0x66,0xea,0xcd,0xab,0xce,0x7a]
+     //     data16 ljmp 0x7ace, 0xabcd
+
+// CHECK: encoding: [0xea,0xcd,0xab,0x00,0x00,0xce,0x7a]
+          ljmp 0x7ace, 0xabcd



More information about the llvm-commits mailing list