[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