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