[llvm] c40b158 - [M68k][Disassembler] Use custom decoder for 32-bit immediates

Min-Yih Hsu via llvm-commits llvm-commits at lists.llvm.org
Tue Jan 24 22:02:58 PST 2023


Author: Min-Yih Hsu
Date: 2023-01-24T21:59:24-08:00
New Revision: c40b158ea003ddb741d816ad4a8a38fddc4004e9

URL: https://github.com/llvm/llvm-project/commit/c40b158ea003ddb741d816ad4a8a38fddc4004e9
DIFF: https://github.com/llvm/llvm-project/commit/c40b158ea003ddb741d816ad4a8a38fddc4004e9.diff

LOG: [M68k][Disassembler] Use custom decoder for 32-bit immediates

32-bit immediates require special cares because they go across the
normal word (16 bits) boundaries.
This patch also fixes some incorrect disassembler test cases.

Differential Revision: https://reviews.llvm.org/D142080

Added: 
    

Modified: 
    llvm/lib/Target/M68k/Disassembler/M68kDisassembler.cpp
    llvm/lib/Target/M68k/M68kInstrFormats.td
    llvm/lib/Target/M68k/MCTargetDesc/M68kBaseInfo.h
    llvm/lib/Target/M68k/MCTargetDesc/M68kMCCodeEmitter.cpp
    llvm/test/MC/Disassembler/M68k/arithmetic.txt
    llvm/test/MC/Disassembler/M68k/data.txt

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Target/M68k/Disassembler/M68kDisassembler.cpp b/llvm/lib/Target/M68k/Disassembler/M68kDisassembler.cpp
index 31b59c17c0ca..ffe4869e8fe5 100644
--- a/llvm/lib/Target/M68k/Disassembler/M68kDisassembler.cpp
+++ b/llvm/lib/Target/M68k/Disassembler/M68kDisassembler.cpp
@@ -94,6 +94,12 @@ static DecodeStatus DecodeCCRCRegisterClass(MCInst &Inst, APInt &Insn,
   llvm_unreachable("unimplemented");
 }
 
+static DecodeStatus DecodeImm32(MCInst &Inst, uint64_t Imm, uint64_t Address,
+                                const void *Decoder) {
+  Inst.addOperand(MCOperand::createImm(M68k::swapWord<uint32_t>(Imm)));
+  return DecodeStatus::Success;
+}
+
 #include "M68kGenDisassemblerTable.inc"
 
 /// A disassembler class for M68k.

diff  --git a/llvm/lib/Target/M68k/M68kInstrFormats.td b/llvm/lib/Target/M68k/M68kInstrFormats.td
index 78aed521f13a..2071a169545a 100644
--- a/llvm/lib/Target/M68k/M68kInstrFormats.td
+++ b/llvm/lib/Target/M68k/M68kInstrFormats.td
@@ -346,7 +346,8 @@ class MxEncAddrMode_abs<string opnd_name, bit size_w_l = false> : MxEncMemOp {
   // Absolute address
   let Supplement = !if(size_w_l,
     // abs.L
-    (operand "$"#opnd_name, 32, (encoder "encodeRelocImm<32>")),
+    (operand "$"#opnd_name, 32, (encoder "encodeRelocImm<32>"),
+                                (decoder "DecodeImm32")),
     // abs.W
     (operand "$"#opnd_name, 16, (encoder "encodeRelocImm<16>"))
   );

diff  --git a/llvm/lib/Target/M68k/MCTargetDesc/M68kBaseInfo.h b/llvm/lib/Target/M68k/MCTargetDesc/M68kBaseInfo.h
index 4883f647e214..bd2964ab84b1 100644
--- a/llvm/lib/Target/M68k/MCTargetDesc/M68kBaseInfo.h
+++ b/llvm/lib/Target/M68k/MCTargetDesc/M68kBaseInfo.h
@@ -21,6 +21,7 @@
 
 #include "llvm/MC/MCExpr.h"
 #include "llvm/Support/DataTypes.h"
+#include "llvm/Support/Endian.h"
 #include "llvm/Support/ErrorHandling.h"
 
 #define GET_INSTRINFO_MI_OPS_INFO
@@ -46,6 +47,24 @@ enum { MemDisp = 0, MemBase = 1, MemIndex = 2, MemOuter = 3 };
 /// ([bd,PC],Xn,od)
 /// ([bd,PC,Xn],od)
 enum { PCRelDisp = 0, PCRelIndex = 1, PCRelOuter = 2 };
+
+// On a LE host:
+// MSB                   LSB    MSB                   LSB
+// | 0x12 0x34 | 0xAB 0xCD | -> | 0xAB 0xCD | 0x12 0x34 |
+// (On a BE host nothing changes)
+template <typename value_t> value_t swapWord(value_t Val) {
+  const unsigned NumWords = sizeof(Val) / 2;
+  if (NumWords <= 1)
+    return Val;
+  Val = support::endian::byte_swap(Val, support::big);
+  value_t NewVal = 0;
+  for (unsigned i = 0U; i != NumWords; ++i) {
+    uint16_t Part = (Val >> (i * 16)) & 0xFFFF;
+    Part = support::endian::byte_swap(Part, support::big);
+    NewVal |= (Part << (i * 16));
+  }
+  return NewVal;
+}
 } // namespace M68k
 
 namespace M68kBeads {

diff  --git a/llvm/lib/Target/M68k/MCTargetDesc/M68kMCCodeEmitter.cpp b/llvm/lib/Target/M68k/MCTargetDesc/M68kMCCodeEmitter.cpp
index 6b093623a106..d4fc0510f944 100644
--- a/llvm/lib/Target/M68k/MCTargetDesc/M68kMCCodeEmitter.cpp
+++ b/llvm/lib/Target/M68k/MCTargetDesc/M68kMCCodeEmitter.cpp
@@ -84,24 +84,6 @@ template <unsigned Size> struct select_uint_t {
                                     uint64_t>::type>::type>::type;
 };
 
-// On a LE host:
-// MSB                   LSB    MSB                   LSB
-// | 0x12 0x34 | 0xAB 0xCD | -> | 0xAB 0xCD | 0x12 0x34 |
-// (On a BE host nothing changes)
-template <typename value_t> static value_t swapWord(value_t Val) {
-  const unsigned NumWords = sizeof(Val) / 2;
-  if (NumWords <= 1)
-    return Val;
-  Val = support::endian::byte_swap(Val, support::big);
-  value_t NewVal = 0;
-  for (unsigned i = 0U; i != NumWords; ++i) {
-    uint16_t Part = (Val >> (i * 16)) & 0xFFFF;
-    Part = support::endian::byte_swap(Part, support::big);
-    NewVal |= (Part << (i * 16));
-  }
-  return NewVal;
-}
-
 // Figure out which byte we're at in big endian mode.
 template <unsigned Size> static unsigned getBytePosition(unsigned BitPos) {
   if (Size % 16) {
@@ -135,14 +117,14 @@ void M68kMCCodeEmitter::encodeRelocImm(const MCInst &MI, unsigned OpIdx,
   using value_t = typename select_uint_t<Size>::type;
   const MCOperand &MCO = MI.getOperand(OpIdx);
   if (MCO.isImm()) {
-    Value |= swapWord<value_t>(static_cast<value_t>(MCO.getImm()));
+    Value |= M68k::swapWord<value_t>(static_cast<value_t>(MCO.getImm()));
   } else if (MCO.isExpr()) {
     const MCExpr *Expr = MCO.getExpr();
 
     // Absolute address
     int64_t Addr;
     if (Expr->evaluateAsAbsolute(Addr)) {
-      Value |= swapWord<value_t>(static_cast<value_t>(Addr));
+      Value |= M68k::swapWord<value_t>(static_cast<value_t>(Addr));
       return;
     }
 
@@ -162,7 +144,7 @@ void M68kMCCodeEmitter::encodePCRelImm(const MCInst &MI, unsigned OpIdx,
   const MCOperand &MCO = MI.getOperand(OpIdx);
   if (MCO.isImm()) {
     using value_t = typename select_uint_t<Size>::type;
-    Value |= swapWord<value_t>(static_cast<value_t>(MCO.getImm()));
+    Value |= M68k::swapWord<value_t>(static_cast<value_t>(MCO.getImm()));
   } else if (MCO.isExpr()) {
     const MCExpr *Expr = MCO.getExpr();
     unsigned InsertByte = getBytePosition<Size>(InsertPos);

diff  --git a/llvm/test/MC/Disassembler/M68k/arithmetic.txt b/llvm/test/MC/Disassembler/M68k/arithmetic.txt
index 18cfdc96b65c..f7dd64360038 100644
--- a/llvm/test/MC/Disassembler/M68k/arithmetic.txt
+++ b/llvm/test/MC/Disassembler/M68k/arithmetic.txt
@@ -59,7 +59,7 @@
 # CHECK: add.l    (4660,%sp), %d5
 0xda 0xaf 0x12 0x34
 
-# CHECK: cmpi.w  #769, $3012022
+# CHECK: cmpi.w  #769, $20220301
 0x0c 0x79 0x03 0x01 0x20 0x22 0x03 0x01
 
 # CHECK: cmpi.w  #5416, %d7
@@ -74,7 +74,7 @@
 # CHECK: cmpi.l  #50403411, $1
 0x0c 0xb9 0x03 0x01 0x18 0x53 0x00 0x01 0x00 0x00
 
-# CHECK: cmpi.b  #64, $15400301
+# CHECK: cmpi.b  #64, $3011540
 0x0c 0x39 0x00 0x40 0x03 0x01 0x15 0x40
 
 # CHECK: cmp.b   %d5, %d7

diff  --git a/llvm/test/MC/Disassembler/M68k/data.txt b/llvm/test/MC/Disassembler/M68k/data.txt
index 6a8460fe7ca9..8e2fb3f13560 100644
--- a/llvm/test/MC/Disassembler/M68k/data.txt
+++ b/llvm/test/MC/Disassembler/M68k/data.txt
@@ -37,9 +37,9 @@
 0x20 0x37 0x88 0x40
 
 # CHECK: move.l $f0000000, %a5
-0x2a 0x79 0x00 0x00 0xf0 0x00
+0x2a 0x79 0xf0 0x00 0x00 0x00
 
-# CHECK: move.l $1, %d0
+# CHECK: move.l $10000, %d0
 0x20 0x39 0x00 0x01 0x00 0x00
 
 # CHECK: move.l (32768,%pc), %a2


        


More information about the llvm-commits mailing list