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