LLVM  14.0.0git
MSP430Disassembler.cpp
Go to the documentation of this file.
1 //===-- MSP430Disassembler.cpp - Disassembler for MSP430 ------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file implements the MSP430Disassembler class.
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #include "MSP430.h"
16 #include "llvm/MC/MCContext.h"
19 #include "llvm/MC/MCInst.h"
20 #include "llvm/MC/MCRegisterInfo.h"
22 #include "llvm/Support/Endian.h"
24 
25 using namespace llvm;
26 
27 #define DEBUG_TYPE "msp430-disassembler"
28 
30 
31 namespace {
32 class MSP430Disassembler : public MCDisassembler {
33  DecodeStatus getInstructionI(MCInst &MI, uint64_t &Size,
35  raw_ostream &CStream) const;
36 
37  DecodeStatus getInstructionII(MCInst &MI, uint64_t &Size,
39  raw_ostream &CStream) const;
40 
41  DecodeStatus getInstructionCJ(MCInst &MI, uint64_t &Size,
43  raw_ostream &CStream) const;
44 
45 public:
46  MSP430Disassembler(const MCSubtargetInfo &STI, MCContext &Ctx)
47  : MCDisassembler(STI, Ctx) {}
48 
49  DecodeStatus getInstruction(MCInst &MI, uint64_t &Size,
51  raw_ostream &CStream) const override;
52 };
53 } // end anonymous namespace
54 
56  const MCSubtargetInfo &STI,
57  MCContext &Ctx) {
58  return new MSP430Disassembler(STI, Ctx);
59 }
60 
64 }
65 
66 static const unsigned GR8DecoderTable[] = {
67  MSP430::PCB, MSP430::SPB, MSP430::SRB, MSP430::CGB,
68  MSP430::R4B, MSP430::R5B, MSP430::R6B, MSP430::R7B,
69  MSP430::R8B, MSP430::R9B, MSP430::R10B, MSP430::R11B,
70  MSP430::R12B, MSP430::R13B, MSP430::R14B, MSP430::R15B
71 };
72 
74  uint64_t Address,
75  const void *Decoder) {
76  if (RegNo > 15)
77  return MCDisassembler::Fail;
78 
79  unsigned Reg = GR8DecoderTable[RegNo];
80  MI.addOperand(MCOperand::createReg(Reg));
82 }
83 
84 static const unsigned GR16DecoderTable[] = {
85  MSP430::PC, MSP430::SP, MSP430::SR, MSP430::CG,
86  MSP430::R4, MSP430::R5, MSP430::R6, MSP430::R7,
87  MSP430::R8, MSP430::R9, MSP430::R10, MSP430::R11,
88  MSP430::R12, MSP430::R13, MSP430::R14, MSP430::R15
89 };
90 
92  uint64_t Address,
93  const void *Decoder) {
94  if (RegNo > 15)
95  return MCDisassembler::Fail;
96 
97  unsigned Reg = GR16DecoderTable[RegNo];
98  MI.addOperand(MCOperand::createReg(Reg));
100 }
101 
103  const void *Decoder);
104 
106  uint64_t Address,
107  const void *Decoder);
108 
109 #include "MSP430GenDisassemblerTables.inc"
110 
112  const void *Decoder) {
113  int64_t Imm;
114  switch (Bits) {
115  default:
116  llvm_unreachable("Invalid immediate value");
117  case 0x22: Imm = 4; break;
118  case 0x32: Imm = 8; break;
119  case 0x03: Imm = 0; break;
120  case 0x13: Imm = 1; break;
121  case 0x23: Imm = 2; break;
122  case 0x33: Imm = -1; break;
123  }
124  MI.addOperand(MCOperand::createImm(Imm));
126 }
127 
129  uint64_t Address,
130  const void *Decoder) {
131  unsigned Reg = Bits & 15;
132  unsigned Imm = Bits >> 4;
133 
134  if (DecodeGR16RegisterClass(MI, Reg, Address, Decoder) !=
136  return MCDisassembler::Fail;
137 
138  MI.addOperand(MCOperand::createImm((int16_t)Imm));
140 }
141 
142 enum AddrMode {
152 };
153 
154 static AddrMode DecodeSrcAddrMode(unsigned Rs, unsigned As) {
155  switch (Rs) {
156  case 0:
157  if (As == 1) return amSymbolic;
158  if (As == 2) return amInvalid;
159  if (As == 3) return amImmediate;
160  break;
161  case 2:
162  if (As == 1) return amAbsolute;
163  if (As == 2) return amConstant;
164  if (As == 3) return amConstant;
165  break;
166  case 3:
167  return amConstant;
168  default:
169  break;
170  }
171  switch (As) {
172  case 0: return amRegister;
173  case 1: return amIndexed;
174  case 2: return amIndirect;
175  case 3: return amIndirectPost;
176  default:
177  llvm_unreachable("As out of range");
178  }
179 }
180 
181 static AddrMode DecodeSrcAddrModeI(unsigned Insn) {
182  unsigned Rs = fieldFromInstruction(Insn, 8, 4);
183  unsigned As = fieldFromInstruction(Insn, 4, 2);
184  return DecodeSrcAddrMode(Rs, As);
185 }
186 
187 static AddrMode DecodeSrcAddrModeII(unsigned Insn) {
188  unsigned Rs = fieldFromInstruction(Insn, 0, 4);
189  unsigned As = fieldFromInstruction(Insn, 4, 2);
190  return DecodeSrcAddrMode(Rs, As);
191 }
192 
193 static AddrMode DecodeDstAddrMode(unsigned Insn) {
194  unsigned Rd = fieldFromInstruction(Insn, 0, 4);
195  unsigned Ad = fieldFromInstruction(Insn, 7, 1);
196  switch (Rd) {
197  case 0: return Ad ? amSymbolic : amRegister;
198  case 2: return Ad ? amAbsolute : amRegister;
199  default:
200  break;
201  }
202  return Ad ? amIndexed : amRegister;
203 }
204 
205 static const uint8_t *getDecoderTable(AddrMode SrcAM, unsigned Words) {
206  assert(0 < Words && Words < 4 && "Incorrect number of words");
207  switch (SrcAM) {
208  default:
209  llvm_unreachable("Invalid addressing mode");
210  case amRegister:
211  assert(Words < 3 && "Incorrect number of words");
212  return Words == 2 ? DecoderTableAlpha32 : DecoderTableAlpha16;
213  case amConstant:
214  assert(Words < 3 && "Incorrect number of words");
215  return Words == 2 ? DecoderTableBeta32 : DecoderTableBeta16;
216  case amIndexed:
217  case amSymbolic:
218  case amImmediate:
219  case amAbsolute:
220  assert(Words > 1 && "Incorrect number of words");
221  return Words == 2 ? DecoderTableGamma32 : DecoderTableGamma48;
222  case amIndirect:
223  case amIndirectPost:
224  assert(Words < 3 && "Incorrect number of words");
225  return Words == 2 ? DecoderTableDelta32 : DecoderTableDelta16;
226  }
227 }
228 
229 DecodeStatus MSP430Disassembler::getInstructionI(MCInst &MI, uint64_t &Size,
230  ArrayRef<uint8_t> Bytes,
231  uint64_t Address,
232  raw_ostream &CStream) const {
233  uint64_t Insn = support::endian::read16le(Bytes.data());
234  AddrMode SrcAM = DecodeSrcAddrModeI(Insn);
235  AddrMode DstAM = DecodeDstAddrMode(Insn);
236  if (SrcAM == amInvalid || DstAM == amInvalid) {
237  Size = 2; // skip one word and let disassembler to try further
238  return MCDisassembler::Fail;
239  }
240 
241  unsigned Words = 1;
242  switch (SrcAM) {
243  case amIndexed:
244  case amSymbolic:
245  case amImmediate:
246  case amAbsolute:
247  if (Bytes.size() < (Words + 1) * 2) {
248  Size = 2;
249  return DecodeStatus::Fail;
250  }
251  Insn |= (uint64_t)support::endian::read16le(Bytes.data() + 2) << 16;
252  ++Words;
253  break;
254  default:
255  break;
256  }
257  switch (DstAM) {
258  case amIndexed:
259  case amSymbolic:
260  case amAbsolute:
261  if (Bytes.size() < (Words + 1) * 2) {
262  Size = 2;
263  return DecodeStatus::Fail;
264  }
265  Insn |= (uint64_t)support::endian::read16le(Bytes.data() + Words * 2)
266  << (Words * 16);
267  ++Words;
268  break;
269  default:
270  break;
271  }
272 
273  DecodeStatus Result = decodeInstruction(getDecoderTable(SrcAM, Words), MI,
274  Insn, Address, this, STI);
275  if (Result != MCDisassembler::Fail) {
276  Size = Words * 2;
277  return Result;
278  }
279 
280  Size = 2;
281  return DecodeStatus::Fail;
282 }
283 
284 DecodeStatus MSP430Disassembler::getInstructionII(MCInst &MI, uint64_t &Size,
285  ArrayRef<uint8_t> Bytes,
286  uint64_t Address,
287  raw_ostream &CStream) const {
288  uint64_t Insn = support::endian::read16le(Bytes.data());
289  AddrMode SrcAM = DecodeSrcAddrModeII(Insn);
290  if (SrcAM == amInvalid) {
291  Size = 2; // skip one word and let disassembler to try further
292  return MCDisassembler::Fail;
293  }
294 
295  unsigned Words = 1;
296  switch (SrcAM) {
297  case amIndexed:
298  case amSymbolic:
299  case amImmediate:
300  case amAbsolute:
301  if (Bytes.size() < (Words + 1) * 2) {
302  Size = 2;
303  return DecodeStatus::Fail;
304  }
305  Insn |= (uint64_t)support::endian::read16le(Bytes.data() + 2) << 16;
306  ++Words;
307  break;
308  default:
309  break;
310  }
311 
312  const uint8_t *DecoderTable = Words == 2 ? DecoderTable32 : DecoderTable16;
313  DecodeStatus Result = decodeInstruction(DecoderTable, MI, Insn, Address,
314  this, STI);
315  if (Result != MCDisassembler::Fail) {
316  Size = Words * 2;
317  return Result;
318  }
319 
320  Size = 2;
321  return DecodeStatus::Fail;
322 }
323 
325  switch (Cond) {
326  case 0: return MSP430CC::COND_NE;
327  case 1: return MSP430CC::COND_E;
328  case 2: return MSP430CC::COND_LO;
329  case 3: return MSP430CC::COND_HS;
330  case 4: return MSP430CC::COND_N;
331  case 5: return MSP430CC::COND_GE;
332  case 6: return MSP430CC::COND_L;
333  case 7: return MSP430CC::COND_NONE;
334  default:
335  llvm_unreachable("Cond out of range");
336  }
337 }
338 
339 DecodeStatus MSP430Disassembler::getInstructionCJ(MCInst &MI, uint64_t &Size,
340  ArrayRef<uint8_t> Bytes,
341  uint64_t Address,
342  raw_ostream &CStream) const {
343  uint64_t Insn = support::endian::read16le(Bytes.data());
344  unsigned Cond = fieldFromInstruction(Insn, 10, 3);
345  unsigned Offset = fieldFromInstruction(Insn, 0, 10);
346 
347  MI.addOperand(MCOperand::createImm(SignExtend32(Offset, 10)));
348 
349  if (Cond == 7)
350  MI.setOpcode(MSP430::JMP);
351  else {
352  MI.setOpcode(MSP430::JCC);
353  MI.addOperand(MCOperand::createImm(getCondCode(Cond)));
354  }
355 
356  Size = 2;
357  return DecodeStatus::Success;
358 }
359 
360 DecodeStatus MSP430Disassembler::getInstruction(MCInst &MI, uint64_t &Size,
361  ArrayRef<uint8_t> Bytes,
362  uint64_t Address,
363  raw_ostream &CStream) const {
364  if (Bytes.size() < 2) {
365  Size = 0;
366  return MCDisassembler::Fail;
367  }
368 
369  uint64_t Insn = support::endian::read16le(Bytes.data());
370  unsigned Opc = fieldFromInstruction(Insn, 13, 3);
371  switch (Opc) {
372  case 0:
373  return getInstructionII(MI, Size, Bytes, Address, CStream);
374  case 1:
375  return getInstructionCJ(MI, Size, Bytes, Address, CStream);
376  default:
377  return getInstructionI(MI, Size, Bytes, Address, CStream);
378  }
379 }
llvm::Check::Size
@ Size
Definition: FileCheck.h:73
MCFixedLenDisassembler.h
MI
IRTranslator LLVM IR MI
Definition: IRTranslator.cpp:103
MSP430TargetInfo.h
llvm
---------------------— PointerInfo ------------------------------------—
Definition: AllocatorList.h:23
Reg
unsigned Reg
Definition: MachineSink.cpp:1566
MCDisassembler.h
T
llvm::MCOperand::createImm
static MCOperand createImm(int64_t Val)
Definition: MCInst.h:141
llvm::MCContext
Context object for machine code objects.
Definition: MCContext.h:72
GR8DecoderTable
static const unsigned GR8DecoderTable[]
Definition: MSP430Disassembler.cpp:66
amIndirect
@ amIndirect
Definition: MSP430Disassembler.cpp:146
llvm::Target
Target - Wrapper for Target specific information.
Definition: TargetRegistry.h:137
llvm::support::endian::read16le
uint16_t read16le(const void *P)
Definition: Endian.h:380
amInvalid
@ amInvalid
Definition: MSP430Disassembler.cpp:143
DecodeGR8RegisterClass
static DecodeStatus DecodeGR8RegisterClass(MCInst &MI, uint64_t RegNo, uint64_t Address, const void *Decoder)
Definition: MSP430Disassembler.cpp:73
Fail
#define Fail
Definition: AArch64Disassembler.cpp:261
R4
#define R4(n)
DecodeCGImm
static DecodeStatus DecodeCGImm(MCInst &MI, uint64_t Bits, uint64_t Address, const void *Decoder)
Definition: MSP430Disassembler.cpp:111
llvm::tgtok::Bits
@ Bits
Definition: TGLexer.h:50
llvm::TargetRegistry::RegisterMCDisassembler
static void RegisterMCDisassembler(Target &T, Target::MCDisassemblerCtorTy Fn)
RegisterMCDisassembler - Register a MCDisassembler implementation for the given target.
Definition: TargetRegistry.h:916
Offset
uint64_t Offset
Definition: ELFObjHandler.cpp:81
llvm::MCInst
Instances of this class represent a single low-level machine instruction.
Definition: MCInst.h:184
amRegister
@ amRegister
Definition: MSP430Disassembler.cpp:144
DecodeStatus
MCDisassembler::DecodeStatus DecodeStatus
Definition: MSP430Disassembler.cpp:29
llvm::ArrayRef::data
const T * data() const
Definition: ArrayRef.h:162
DecodeSrcAddrModeI
static AddrMode DecodeSrcAddrModeI(unsigned Insn)
Definition: MSP430Disassembler.cpp:181
MSP430CC::COND_N
@ COND_N
Definition: MSP430.h:29
getCondCode
static MSP430CC::CondCodes getCondCode(unsigned Cond)
Definition: MSP430Disassembler.cpp:324
MCContext.h
llvm::ms_demangle::QualifierMangleMode::Result
@ Result
llvm::MCDisassembler::Success
@ Success
Definition: MCDisassembler.h:103
MCInst.h
DecodeMemOperand
static DecodeStatus DecodeMemOperand(MCInst &MI, uint64_t Bits, uint64_t Address, const void *Decoder)
Definition: MSP430Disassembler.cpp:128
MCSubtargetInfo.h
llvm::raw_ostream
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition: raw_ostream.h:53
amConstant
@ amConstant
Definition: MSP430Disassembler.cpp:151
amIndexed
@ amIndexed
Definition: MSP430Disassembler.cpp:145
DecodeSrcAddrModeII
static AddrMode DecodeSrcAddrModeII(unsigned Insn)
Definition: MSP430Disassembler.cpp:187
llvm::MCDisassembler::DecodeStatus
DecodeStatus
Ternary decode status.
Definition: MCDisassembler.h:100
MSP430MCTargetDesc.h
llvm::SignExtend32
constexpr int32_t SignExtend32(uint32_t X)
Sign-extend the number in the bottom B bits of X to a 32-bit integer.
Definition: MathExtras.h:761
DecodeGR16RegisterClass
static DecodeStatus DecodeGR16RegisterClass(MCInst &MI, uint64_t RegNo, uint64_t Address, const void *Decoder)
Definition: MSP430Disassembler.cpp:91
amAbsolute
@ amAbsolute
Definition: MSP430Disassembler.cpp:150
uint64_t
LLVM_EXTERNAL_VISIBILITY
#define LLVM_EXTERNAL_VISIBILITY
Definition: Compiler.h:132
MSP430CC::CondCodes
CondCodes
Definition: MSP430.h:22
llvm::MCDisassembler
Superclass for all disassemblers.
Definition: MCDisassembler.h:76
LLVMInitializeMSP430Disassembler
LLVM_EXTERNAL_VISIBILITY void LLVMInitializeMSP430Disassembler()
Definition: MSP430Disassembler.cpp:61
MSP430CC::COND_NONE
@ COND_NONE
Definition: MSP430.h:30
MCRegisterInfo.h
MSP430CC::COND_LO
@ COND_LO
Definition: MSP430.h:26
llvm::HighlightColor::Address
@ Address
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
getDecoderTable
static const uint8_t * getDecoderTable(AddrMode SrcAM, unsigned Words)
Definition: MSP430Disassembler.cpp:205
R6
#define R6(n)
amIndirectPost
@ amIndirectPost
Definition: MSP430Disassembler.cpp:147
MSP430CC::COND_L
@ COND_L
Definition: MSP430.h:28
llvm::ArrayRef< uint8_t >
MSP430CC::COND_NE
@ COND_NE
Definition: MSP430.h:24
Cond
SmallVector< MachineOperand, 4 > Cond
Definition: BasicBlockSections.cpp:179
GR16DecoderTable
static const unsigned GR16DecoderTable[]
Definition: MSP430Disassembler.cpp:84
llvm_unreachable
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Definition: ErrorHandling.h:136
llvm::MCOperand::createReg
static MCOperand createReg(unsigned Reg)
Definition: MCInst.h:134
DecodeDstAddrMode
static AddrMode DecodeDstAddrMode(unsigned Insn)
Definition: MSP430Disassembler.cpp:193
amImmediate
@ amImmediate
Definition: MSP430Disassembler.cpp:149
MSP430.h
AddrMode
AddrMode
Definition: MSP430Disassembler.cpp:142
llvm::MCDisassembler::Fail
@ Fail
Definition: MCDisassembler.h:101
Success
#define Success
Definition: AArch64Disassembler.cpp:260
createMSP430Disassembler
static MCDisassembler * createMSP430Disassembler(const Target &T, const MCSubtargetInfo &STI, MCContext &Ctx)
Definition: MSP430Disassembler.cpp:55
llvm::getTheMSP430Target
Target & getTheMSP430Target()
Definition: MSP430TargetInfo.cpp:13
MSP430CC::COND_HS
@ COND_HS
Definition: MSP430.h:25
DecodeSrcAddrMode
static AddrMode DecodeSrcAddrMode(unsigned Rs, unsigned As)
Definition: MSP430Disassembler.cpp:154
amSymbolic
@ amSymbolic
Definition: MSP430Disassembler.cpp:148
llvm::ArrayRef::size
size_t size() const
size - Get the array size.
Definition: ArrayRef.h:165
MSP430CC::COND_E
@ COND_E
Definition: MSP430.h:23
MSP430CC::COND_GE
@ COND_GE
Definition: MSP430.h:27
Endian.h
TargetRegistry.h
llvm::MCSubtargetInfo
Generic base class for all target subtargets.
Definition: MCSubtargetInfo.h:75