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