10b57cec5SDimitry Andric //===-- MSP430Disassembler.cpp - Disassembler for MSP430 ------------------===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric //
90b57cec5SDimitry Andric // This file implements the MSP430Disassembler class.
100b57cec5SDimitry Andric //
110b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
120b57cec5SDimitry Andric
130b57cec5SDimitry Andric #include "MCTargetDesc/MSP430MCTargetDesc.h"
14349cc55cSDimitry Andric #include "MSP430.h"
150b57cec5SDimitry Andric #include "TargetInfo/MSP430TargetInfo.h"
160b57cec5SDimitry Andric #include "llvm/MC/MCContext.h"
17*81ad6265SDimitry Andric #include "llvm/MC/MCDecoderOps.h"
180b57cec5SDimitry Andric #include "llvm/MC/MCDisassembler/MCDisassembler.h"
190b57cec5SDimitry Andric #include "llvm/MC/MCInst.h"
200b57cec5SDimitry Andric #include "llvm/MC/MCRegisterInfo.h"
210b57cec5SDimitry Andric #include "llvm/MC/MCSubtargetInfo.h"
22349cc55cSDimitry Andric #include "llvm/MC/TargetRegistry.h"
230b57cec5SDimitry Andric #include "llvm/Support/Endian.h"
240b57cec5SDimitry Andric
250b57cec5SDimitry Andric using namespace llvm;
260b57cec5SDimitry Andric
270b57cec5SDimitry Andric #define DEBUG_TYPE "msp430-disassembler"
280b57cec5SDimitry Andric
290b57cec5SDimitry Andric typedef MCDisassembler::DecodeStatus DecodeStatus;
300b57cec5SDimitry Andric
310b57cec5SDimitry Andric namespace {
320b57cec5SDimitry Andric class MSP430Disassembler : public MCDisassembler {
330b57cec5SDimitry Andric DecodeStatus getInstructionI(MCInst &MI, uint64_t &Size,
340b57cec5SDimitry Andric ArrayRef<uint8_t> Bytes, uint64_t Address,
350b57cec5SDimitry Andric raw_ostream &CStream) const;
360b57cec5SDimitry Andric
370b57cec5SDimitry Andric DecodeStatus getInstructionII(MCInst &MI, uint64_t &Size,
380b57cec5SDimitry Andric ArrayRef<uint8_t> Bytes, uint64_t Address,
390b57cec5SDimitry Andric raw_ostream &CStream) const;
400b57cec5SDimitry Andric
410b57cec5SDimitry Andric DecodeStatus getInstructionCJ(MCInst &MI, uint64_t &Size,
420b57cec5SDimitry Andric ArrayRef<uint8_t> Bytes, uint64_t Address,
430b57cec5SDimitry Andric raw_ostream &CStream) const;
440b57cec5SDimitry Andric
450b57cec5SDimitry Andric public:
MSP430Disassembler(const MCSubtargetInfo & STI,MCContext & Ctx)460b57cec5SDimitry Andric MSP430Disassembler(const MCSubtargetInfo &STI, MCContext &Ctx)
470b57cec5SDimitry Andric : MCDisassembler(STI, Ctx) {}
480b57cec5SDimitry Andric
490b57cec5SDimitry Andric DecodeStatus getInstruction(MCInst &MI, uint64_t &Size,
500b57cec5SDimitry Andric ArrayRef<uint8_t> Bytes, uint64_t Address,
510b57cec5SDimitry Andric raw_ostream &CStream) const override;
520b57cec5SDimitry Andric };
530b57cec5SDimitry Andric } // end anonymous namespace
540b57cec5SDimitry Andric
createMSP430Disassembler(const Target & T,const MCSubtargetInfo & STI,MCContext & Ctx)550b57cec5SDimitry Andric static MCDisassembler *createMSP430Disassembler(const Target &T,
560b57cec5SDimitry Andric const MCSubtargetInfo &STI,
570b57cec5SDimitry Andric MCContext &Ctx) {
580b57cec5SDimitry Andric return new MSP430Disassembler(STI, Ctx);
590b57cec5SDimitry Andric }
600b57cec5SDimitry Andric
LLVMInitializeMSP430Disassembler()61480093f4SDimitry Andric extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeMSP430Disassembler() {
620b57cec5SDimitry Andric TargetRegistry::RegisterMCDisassembler(getTheMSP430Target(),
630b57cec5SDimitry Andric createMSP430Disassembler);
640b57cec5SDimitry Andric }
650b57cec5SDimitry Andric
660b57cec5SDimitry Andric static const unsigned GR8DecoderTable[] = {
670b57cec5SDimitry Andric MSP430::PCB, MSP430::SPB, MSP430::SRB, MSP430::CGB,
685ffd83dbSDimitry Andric MSP430::R4B, MSP430::R5B, MSP430::R6B, MSP430::R7B,
690b57cec5SDimitry Andric MSP430::R8B, MSP430::R9B, MSP430::R10B, MSP430::R11B,
700b57cec5SDimitry Andric MSP430::R12B, MSP430::R13B, MSP430::R14B, MSP430::R15B
710b57cec5SDimitry Andric };
720b57cec5SDimitry Andric
DecodeGR8RegisterClass(MCInst & MI,uint64_t RegNo,uint64_t Address,const MCDisassembler * Decoder)730b57cec5SDimitry Andric static DecodeStatus DecodeGR8RegisterClass(MCInst &MI, uint64_t RegNo,
740b57cec5SDimitry Andric uint64_t Address,
75*81ad6265SDimitry Andric const MCDisassembler *Decoder) {
760b57cec5SDimitry Andric if (RegNo > 15)
770b57cec5SDimitry Andric return MCDisassembler::Fail;
780b57cec5SDimitry Andric
790b57cec5SDimitry Andric unsigned Reg = GR8DecoderTable[RegNo];
800b57cec5SDimitry Andric MI.addOperand(MCOperand::createReg(Reg));
810b57cec5SDimitry Andric return MCDisassembler::Success;
820b57cec5SDimitry Andric }
830b57cec5SDimitry Andric
840b57cec5SDimitry Andric static const unsigned GR16DecoderTable[] = {
850b57cec5SDimitry Andric MSP430::PC, MSP430::SP, MSP430::SR, MSP430::CG,
865ffd83dbSDimitry Andric MSP430::R4, MSP430::R5, MSP430::R6, MSP430::R7,
870b57cec5SDimitry Andric MSP430::R8, MSP430::R9, MSP430::R10, MSP430::R11,
880b57cec5SDimitry Andric MSP430::R12, MSP430::R13, MSP430::R14, MSP430::R15
890b57cec5SDimitry Andric };
900b57cec5SDimitry Andric
DecodeGR16RegisterClass(MCInst & MI,uint64_t RegNo,uint64_t Address,const MCDisassembler * Decoder)910b57cec5SDimitry Andric static DecodeStatus DecodeGR16RegisterClass(MCInst &MI, uint64_t RegNo,
920b57cec5SDimitry Andric uint64_t Address,
93*81ad6265SDimitry Andric const MCDisassembler *Decoder) {
940b57cec5SDimitry Andric if (RegNo > 15)
950b57cec5SDimitry Andric return MCDisassembler::Fail;
960b57cec5SDimitry Andric
970b57cec5SDimitry Andric unsigned Reg = GR16DecoderTable[RegNo];
980b57cec5SDimitry Andric MI.addOperand(MCOperand::createReg(Reg));
990b57cec5SDimitry Andric return MCDisassembler::Success;
1000b57cec5SDimitry Andric }
1010b57cec5SDimitry Andric
1020b57cec5SDimitry Andric static DecodeStatus DecodeCGImm(MCInst &MI, uint64_t Bits, uint64_t Address,
103*81ad6265SDimitry Andric const MCDisassembler *Decoder);
1040b57cec5SDimitry Andric
1050b57cec5SDimitry Andric static DecodeStatus DecodeMemOperand(MCInst &MI, uint64_t Bits,
1060b57cec5SDimitry Andric uint64_t Address,
107*81ad6265SDimitry Andric const MCDisassembler *Decoder);
1080b57cec5SDimitry Andric
1090b57cec5SDimitry Andric #include "MSP430GenDisassemblerTables.inc"
1100b57cec5SDimitry Andric
DecodeCGImm(MCInst & MI,uint64_t Bits,uint64_t Address,const MCDisassembler * Decoder)1110b57cec5SDimitry Andric static DecodeStatus DecodeCGImm(MCInst &MI, uint64_t Bits, uint64_t Address,
112*81ad6265SDimitry Andric const MCDisassembler *Decoder) {
1130b57cec5SDimitry Andric int64_t Imm;
1140b57cec5SDimitry Andric switch (Bits) {
1150b57cec5SDimitry Andric default:
1160b57cec5SDimitry Andric llvm_unreachable("Invalid immediate value");
1170b57cec5SDimitry Andric case 0x22: Imm = 4; break;
1180b57cec5SDimitry Andric case 0x32: Imm = 8; break;
1190b57cec5SDimitry Andric case 0x03: Imm = 0; break;
1200b57cec5SDimitry Andric case 0x13: Imm = 1; break;
1210b57cec5SDimitry Andric case 0x23: Imm = 2; break;
1220b57cec5SDimitry Andric case 0x33: Imm = -1; break;
1230b57cec5SDimitry Andric }
1240b57cec5SDimitry Andric MI.addOperand(MCOperand::createImm(Imm));
1250b57cec5SDimitry Andric return MCDisassembler::Success;
1260b57cec5SDimitry Andric }
1270b57cec5SDimitry Andric
DecodeMemOperand(MCInst & MI,uint64_t Bits,uint64_t Address,const MCDisassembler * Decoder)1280b57cec5SDimitry Andric static DecodeStatus DecodeMemOperand(MCInst &MI, uint64_t Bits,
1290b57cec5SDimitry Andric uint64_t Address,
130*81ad6265SDimitry Andric const MCDisassembler *Decoder) {
1310b57cec5SDimitry Andric unsigned Reg = Bits & 15;
1320b57cec5SDimitry Andric unsigned Imm = Bits >> 4;
1330b57cec5SDimitry Andric
1340b57cec5SDimitry Andric if (DecodeGR16RegisterClass(MI, Reg, Address, Decoder) !=
1350b57cec5SDimitry Andric MCDisassembler::Success)
1360b57cec5SDimitry Andric return MCDisassembler::Fail;
1370b57cec5SDimitry Andric
1380b57cec5SDimitry Andric MI.addOperand(MCOperand::createImm((int16_t)Imm));
1390b57cec5SDimitry Andric return MCDisassembler::Success;
1400b57cec5SDimitry Andric }
1410b57cec5SDimitry Andric
1420b57cec5SDimitry Andric enum AddrMode {
1430b57cec5SDimitry Andric amInvalid = 0,
1440b57cec5SDimitry Andric amRegister,
1450b57cec5SDimitry Andric amIndexed,
1460b57cec5SDimitry Andric amIndirect,
1470b57cec5SDimitry Andric amIndirectPost,
1480b57cec5SDimitry Andric amSymbolic,
1490b57cec5SDimitry Andric amImmediate,
1500b57cec5SDimitry Andric amAbsolute,
1510b57cec5SDimitry Andric amConstant
1520b57cec5SDimitry Andric };
1530b57cec5SDimitry Andric
DecodeSrcAddrMode(unsigned Rs,unsigned As)1540b57cec5SDimitry Andric static AddrMode DecodeSrcAddrMode(unsigned Rs, unsigned As) {
1550b57cec5SDimitry Andric switch (Rs) {
1560b57cec5SDimitry Andric case 0:
1570b57cec5SDimitry Andric if (As == 1) return amSymbolic;
1580b57cec5SDimitry Andric if (As == 2) return amInvalid;
1590b57cec5SDimitry Andric if (As == 3) return amImmediate;
1600b57cec5SDimitry Andric break;
1610b57cec5SDimitry Andric case 2:
1620b57cec5SDimitry Andric if (As == 1) return amAbsolute;
1630b57cec5SDimitry Andric if (As == 2) return amConstant;
1640b57cec5SDimitry Andric if (As == 3) return amConstant;
1650b57cec5SDimitry Andric break;
1660b57cec5SDimitry Andric case 3:
1670b57cec5SDimitry Andric return amConstant;
1680b57cec5SDimitry Andric default:
1690b57cec5SDimitry Andric break;
1700b57cec5SDimitry Andric }
1710b57cec5SDimitry Andric switch (As) {
1720b57cec5SDimitry Andric case 0: return amRegister;
1730b57cec5SDimitry Andric case 1: return amIndexed;
1740b57cec5SDimitry Andric case 2: return amIndirect;
1750b57cec5SDimitry Andric case 3: return amIndirectPost;
1760b57cec5SDimitry Andric default:
1770b57cec5SDimitry Andric llvm_unreachable("As out of range");
1780b57cec5SDimitry Andric }
1790b57cec5SDimitry Andric }
1800b57cec5SDimitry Andric
DecodeSrcAddrModeI(unsigned Insn)1810b57cec5SDimitry Andric static AddrMode DecodeSrcAddrModeI(unsigned Insn) {
1820b57cec5SDimitry Andric unsigned Rs = fieldFromInstruction(Insn, 8, 4);
1830b57cec5SDimitry Andric unsigned As = fieldFromInstruction(Insn, 4, 2);
1840b57cec5SDimitry Andric return DecodeSrcAddrMode(Rs, As);
1850b57cec5SDimitry Andric }
1860b57cec5SDimitry Andric
DecodeSrcAddrModeII(unsigned Insn)1870b57cec5SDimitry Andric static AddrMode DecodeSrcAddrModeII(unsigned Insn) {
1880b57cec5SDimitry Andric unsigned Rs = fieldFromInstruction(Insn, 0, 4);
1890b57cec5SDimitry Andric unsigned As = fieldFromInstruction(Insn, 4, 2);
1900b57cec5SDimitry Andric return DecodeSrcAddrMode(Rs, As);
1910b57cec5SDimitry Andric }
1920b57cec5SDimitry Andric
DecodeDstAddrMode(unsigned Insn)1930b57cec5SDimitry Andric static AddrMode DecodeDstAddrMode(unsigned Insn) {
1940b57cec5SDimitry Andric unsigned Rd = fieldFromInstruction(Insn, 0, 4);
1950b57cec5SDimitry Andric unsigned Ad = fieldFromInstruction(Insn, 7, 1);
1960b57cec5SDimitry Andric switch (Rd) {
1970b57cec5SDimitry Andric case 0: return Ad ? amSymbolic : amRegister;
1980b57cec5SDimitry Andric case 2: return Ad ? amAbsolute : amRegister;
1990b57cec5SDimitry Andric default:
2000b57cec5SDimitry Andric break;
2010b57cec5SDimitry Andric }
2020b57cec5SDimitry Andric return Ad ? amIndexed : amRegister;
2030b57cec5SDimitry Andric }
2040b57cec5SDimitry Andric
getDecoderTable(AddrMode SrcAM,unsigned Words)2050b57cec5SDimitry Andric static const uint8_t *getDecoderTable(AddrMode SrcAM, unsigned Words) {
2060b57cec5SDimitry Andric assert(0 < Words && Words < 4 && "Incorrect number of words");
2070b57cec5SDimitry Andric switch (SrcAM) {
2080b57cec5SDimitry Andric default:
2090b57cec5SDimitry Andric llvm_unreachable("Invalid addressing mode");
2100b57cec5SDimitry Andric case amRegister:
2110b57cec5SDimitry Andric assert(Words < 3 && "Incorrect number of words");
2120b57cec5SDimitry Andric return Words == 2 ? DecoderTableAlpha32 : DecoderTableAlpha16;
2130b57cec5SDimitry Andric case amConstant:
2140b57cec5SDimitry Andric assert(Words < 3 && "Incorrect number of words");
2150b57cec5SDimitry Andric return Words == 2 ? DecoderTableBeta32 : DecoderTableBeta16;
2160b57cec5SDimitry Andric case amIndexed:
2170b57cec5SDimitry Andric case amSymbolic:
2180b57cec5SDimitry Andric case amImmediate:
2190b57cec5SDimitry Andric case amAbsolute:
2200b57cec5SDimitry Andric assert(Words > 1 && "Incorrect number of words");
2210b57cec5SDimitry Andric return Words == 2 ? DecoderTableGamma32 : DecoderTableGamma48;
2220b57cec5SDimitry Andric case amIndirect:
2230b57cec5SDimitry Andric case amIndirectPost:
2240b57cec5SDimitry Andric assert(Words < 3 && "Incorrect number of words");
2250b57cec5SDimitry Andric return Words == 2 ? DecoderTableDelta32 : DecoderTableDelta16;
2260b57cec5SDimitry Andric }
2270b57cec5SDimitry Andric }
2280b57cec5SDimitry Andric
getInstructionI(MCInst & MI,uint64_t & Size,ArrayRef<uint8_t> Bytes,uint64_t Address,raw_ostream & CStream) const2290b57cec5SDimitry Andric DecodeStatus MSP430Disassembler::getInstructionI(MCInst &MI, uint64_t &Size,
2300b57cec5SDimitry Andric ArrayRef<uint8_t> Bytes,
2310b57cec5SDimitry Andric uint64_t Address,
2320b57cec5SDimitry Andric raw_ostream &CStream) const {
2330b57cec5SDimitry Andric uint64_t Insn = support::endian::read16le(Bytes.data());
2340b57cec5SDimitry Andric AddrMode SrcAM = DecodeSrcAddrModeI(Insn);
2350b57cec5SDimitry Andric AddrMode DstAM = DecodeDstAddrMode(Insn);
2360b57cec5SDimitry Andric if (SrcAM == amInvalid || DstAM == amInvalid) {
2370b57cec5SDimitry Andric Size = 2; // skip one word and let disassembler to try further
2380b57cec5SDimitry Andric return MCDisassembler::Fail;
2390b57cec5SDimitry Andric }
2400b57cec5SDimitry Andric
2410b57cec5SDimitry Andric unsigned Words = 1;
2420b57cec5SDimitry Andric switch (SrcAM) {
2430b57cec5SDimitry Andric case amIndexed:
2440b57cec5SDimitry Andric case amSymbolic:
2450b57cec5SDimitry Andric case amImmediate:
2460b57cec5SDimitry Andric case amAbsolute:
2470b57cec5SDimitry Andric if (Bytes.size() < (Words + 1) * 2) {
2480b57cec5SDimitry Andric Size = 2;
2490b57cec5SDimitry Andric return DecodeStatus::Fail;
2500b57cec5SDimitry Andric }
2510b57cec5SDimitry Andric Insn |= (uint64_t)support::endian::read16le(Bytes.data() + 2) << 16;
2520b57cec5SDimitry Andric ++Words;
2530b57cec5SDimitry Andric break;
2540b57cec5SDimitry Andric default:
2550b57cec5SDimitry Andric break;
2560b57cec5SDimitry Andric }
2570b57cec5SDimitry Andric switch (DstAM) {
2580b57cec5SDimitry Andric case amIndexed:
2590b57cec5SDimitry Andric case amSymbolic:
2600b57cec5SDimitry Andric case amAbsolute:
2610b57cec5SDimitry Andric if (Bytes.size() < (Words + 1) * 2) {
2620b57cec5SDimitry Andric Size = 2;
2630b57cec5SDimitry Andric return DecodeStatus::Fail;
2640b57cec5SDimitry Andric }
2650b57cec5SDimitry Andric Insn |= (uint64_t)support::endian::read16le(Bytes.data() + Words * 2)
2660b57cec5SDimitry Andric << (Words * 16);
2670b57cec5SDimitry Andric ++Words;
2680b57cec5SDimitry Andric break;
2690b57cec5SDimitry Andric default:
2700b57cec5SDimitry Andric break;
2710b57cec5SDimitry Andric }
2720b57cec5SDimitry Andric
2730b57cec5SDimitry Andric DecodeStatus Result = decodeInstruction(getDecoderTable(SrcAM, Words), MI,
2740b57cec5SDimitry Andric Insn, Address, this, STI);
2750b57cec5SDimitry Andric if (Result != MCDisassembler::Fail) {
2760b57cec5SDimitry Andric Size = Words * 2;
2770b57cec5SDimitry Andric return Result;
2780b57cec5SDimitry Andric }
2790b57cec5SDimitry Andric
2800b57cec5SDimitry Andric Size = 2;
2810b57cec5SDimitry Andric return DecodeStatus::Fail;
2820b57cec5SDimitry Andric }
2830b57cec5SDimitry Andric
getInstructionII(MCInst & MI,uint64_t & Size,ArrayRef<uint8_t> Bytes,uint64_t Address,raw_ostream & CStream) const2840b57cec5SDimitry Andric DecodeStatus MSP430Disassembler::getInstructionII(MCInst &MI, uint64_t &Size,
2850b57cec5SDimitry Andric ArrayRef<uint8_t> Bytes,
2860b57cec5SDimitry Andric uint64_t Address,
2870b57cec5SDimitry Andric raw_ostream &CStream) const {
2880b57cec5SDimitry Andric uint64_t Insn = support::endian::read16le(Bytes.data());
2890b57cec5SDimitry Andric AddrMode SrcAM = DecodeSrcAddrModeII(Insn);
2900b57cec5SDimitry Andric if (SrcAM == amInvalid) {
2910b57cec5SDimitry Andric Size = 2; // skip one word and let disassembler to try further
2920b57cec5SDimitry Andric return MCDisassembler::Fail;
2930b57cec5SDimitry Andric }
2940b57cec5SDimitry Andric
2950b57cec5SDimitry Andric unsigned Words = 1;
2960b57cec5SDimitry Andric switch (SrcAM) {
2970b57cec5SDimitry Andric case amIndexed:
2980b57cec5SDimitry Andric case amSymbolic:
2990b57cec5SDimitry Andric case amImmediate:
3000b57cec5SDimitry Andric case amAbsolute:
3010b57cec5SDimitry Andric if (Bytes.size() < (Words + 1) * 2) {
3020b57cec5SDimitry Andric Size = 2;
3030b57cec5SDimitry Andric return DecodeStatus::Fail;
3040b57cec5SDimitry Andric }
3050b57cec5SDimitry Andric Insn |= (uint64_t)support::endian::read16le(Bytes.data() + 2) << 16;
3060b57cec5SDimitry Andric ++Words;
3070b57cec5SDimitry Andric break;
3080b57cec5SDimitry Andric default:
3090b57cec5SDimitry Andric break;
3100b57cec5SDimitry Andric }
3110b57cec5SDimitry Andric
3120b57cec5SDimitry Andric const uint8_t *DecoderTable = Words == 2 ? DecoderTable32 : DecoderTable16;
3130b57cec5SDimitry Andric DecodeStatus Result = decodeInstruction(DecoderTable, MI, Insn, Address,
3140b57cec5SDimitry Andric this, STI);
3150b57cec5SDimitry Andric if (Result != MCDisassembler::Fail) {
3160b57cec5SDimitry Andric Size = Words * 2;
3170b57cec5SDimitry Andric return Result;
3180b57cec5SDimitry Andric }
3190b57cec5SDimitry Andric
3200b57cec5SDimitry Andric Size = 2;
3210b57cec5SDimitry Andric return DecodeStatus::Fail;
3220b57cec5SDimitry Andric }
3230b57cec5SDimitry Andric
getCondCode(unsigned Cond)3240b57cec5SDimitry Andric static MSP430CC::CondCodes getCondCode(unsigned Cond) {
3250b57cec5SDimitry Andric switch (Cond) {
3260b57cec5SDimitry Andric case 0: return MSP430CC::COND_NE;
3270b57cec5SDimitry Andric case 1: return MSP430CC::COND_E;
3280b57cec5SDimitry Andric case 2: return MSP430CC::COND_LO;
3290b57cec5SDimitry Andric case 3: return MSP430CC::COND_HS;
3300b57cec5SDimitry Andric case 4: return MSP430CC::COND_N;
3310b57cec5SDimitry Andric case 5: return MSP430CC::COND_GE;
3320b57cec5SDimitry Andric case 6: return MSP430CC::COND_L;
3330b57cec5SDimitry Andric case 7: return MSP430CC::COND_NONE;
3340b57cec5SDimitry Andric default:
3350b57cec5SDimitry Andric llvm_unreachable("Cond out of range");
3360b57cec5SDimitry Andric }
3370b57cec5SDimitry Andric }
3380b57cec5SDimitry Andric
getInstructionCJ(MCInst & MI,uint64_t & Size,ArrayRef<uint8_t> Bytes,uint64_t Address,raw_ostream & CStream) const3390b57cec5SDimitry Andric DecodeStatus MSP430Disassembler::getInstructionCJ(MCInst &MI, uint64_t &Size,
3400b57cec5SDimitry Andric ArrayRef<uint8_t> Bytes,
3410b57cec5SDimitry Andric uint64_t Address,
3420b57cec5SDimitry Andric raw_ostream &CStream) const {
3430b57cec5SDimitry Andric uint64_t Insn = support::endian::read16le(Bytes.data());
3440b57cec5SDimitry Andric unsigned Cond = fieldFromInstruction(Insn, 10, 3);
3450b57cec5SDimitry Andric unsigned Offset = fieldFromInstruction(Insn, 0, 10);
3460b57cec5SDimitry Andric
3470b57cec5SDimitry Andric MI.addOperand(MCOperand::createImm(SignExtend32(Offset, 10)));
3480b57cec5SDimitry Andric
3490b57cec5SDimitry Andric if (Cond == 7)
3500b57cec5SDimitry Andric MI.setOpcode(MSP430::JMP);
3510b57cec5SDimitry Andric else {
3520b57cec5SDimitry Andric MI.setOpcode(MSP430::JCC);
3530b57cec5SDimitry Andric MI.addOperand(MCOperand::createImm(getCondCode(Cond)));
3540b57cec5SDimitry Andric }
3550b57cec5SDimitry Andric
3560b57cec5SDimitry Andric Size = 2;
3570b57cec5SDimitry Andric return DecodeStatus::Success;
3580b57cec5SDimitry Andric }
3590b57cec5SDimitry Andric
getInstruction(MCInst & MI,uint64_t & Size,ArrayRef<uint8_t> Bytes,uint64_t Address,raw_ostream & CStream) const3600b57cec5SDimitry Andric DecodeStatus MSP430Disassembler::getInstruction(MCInst &MI, uint64_t &Size,
3610b57cec5SDimitry Andric ArrayRef<uint8_t> Bytes,
3620b57cec5SDimitry Andric uint64_t Address,
3630b57cec5SDimitry Andric raw_ostream &CStream) const {
3640b57cec5SDimitry Andric if (Bytes.size() < 2) {
3650b57cec5SDimitry Andric Size = 0;
3660b57cec5SDimitry Andric return MCDisassembler::Fail;
3670b57cec5SDimitry Andric }
3680b57cec5SDimitry Andric
3690b57cec5SDimitry Andric uint64_t Insn = support::endian::read16le(Bytes.data());
3700b57cec5SDimitry Andric unsigned Opc = fieldFromInstruction(Insn, 13, 3);
3710b57cec5SDimitry Andric switch (Opc) {
3720b57cec5SDimitry Andric case 0:
373480093f4SDimitry Andric return getInstructionII(MI, Size, Bytes, Address, CStream);
3740b57cec5SDimitry Andric case 1:
375480093f4SDimitry Andric return getInstructionCJ(MI, Size, Bytes, Address, CStream);
3760b57cec5SDimitry Andric default:
377480093f4SDimitry Andric return getInstructionI(MI, Size, Bytes, Address, CStream);
3780b57cec5SDimitry Andric }
3790b57cec5SDimitry Andric }
380