You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
628 lines
16 KiB
628 lines
16 KiB
/* Capstone Disassembly Engine */ |
|
/* TMS320C64x Backend by Fotis Loukos <me@fotisl.com> 2016 */ |
|
|
|
#ifdef CAPSTONE_HAS_TMS320C64X |
|
|
|
#include <string.h> |
|
|
|
#include "../../cs_priv.h" |
|
#include "../../utils.h" |
|
|
|
#include "TMS320C64xDisassembler.h" |
|
|
|
#include "../../MCInst.h" |
|
#include "../../MCInstrDesc.h" |
|
#include "../../MCFixedLenDisassembler.h" |
|
#include "../../MCRegisterInfo.h" |
|
#include "../../MCDisassembler.h" |
|
#include "../../MathExtras.h" |
|
|
|
static uint64_t getFeatureBits(int mode); |
|
|
|
static DecodeStatus DecodeGPRegsRegisterClass(MCInst *Inst, unsigned RegNo, |
|
uint64_t Address, void *Decoder); |
|
|
|
static DecodeStatus DecodeControlRegsRegisterClass(MCInst *Inst, unsigned RegNo, |
|
uint64_t Address, void *Decoder); |
|
|
|
static DecodeStatus DecodeScst5(MCInst *Inst, unsigned Val, |
|
uint64_t Address, void *Decoder); |
|
|
|
static DecodeStatus DecodeScst16(MCInst *Inst, unsigned Val, |
|
uint64_t Address, void *Decoder); |
|
|
|
static DecodeStatus DecodePCRelScst7(MCInst *Inst, unsigned Val, |
|
uint64_t Address, void *Decoder); |
|
|
|
static DecodeStatus DecodePCRelScst10(MCInst *Inst, unsigned Val, |
|
uint64_t Address, void *Decoder); |
|
|
|
static DecodeStatus DecodePCRelScst12(MCInst *Inst, unsigned Val, |
|
uint64_t Address, void *Decoder); |
|
|
|
static DecodeStatus DecodePCRelScst21(MCInst *Inst, unsigned Val, |
|
uint64_t Address, void *Decoder); |
|
|
|
static DecodeStatus DecodeMemOperand(MCInst *Inst, unsigned Val, |
|
uint64_t Address, void *Decoder); |
|
|
|
static DecodeStatus DecodeMemOperandSc(MCInst *Inst, unsigned Val, |
|
uint64_t Address, void *Decoder); |
|
|
|
static DecodeStatus DecodeMemOperand2(MCInst *Inst, unsigned Val, |
|
uint64_t Address, void *Decoder); |
|
|
|
static DecodeStatus DecodeRegPair5(MCInst *Inst, unsigned RegNo, |
|
uint64_t Address, void *Decoder); |
|
|
|
static DecodeStatus DecodeRegPair4(MCInst *Inst, unsigned RegNo, |
|
uint64_t Address, void *Decoder); |
|
|
|
static DecodeStatus DecodeCondRegister(MCInst *Inst, unsigned Val, |
|
uint64_t Address, void *Decoder); |
|
|
|
static DecodeStatus DecodeCondRegisterZero(MCInst *Inst, unsigned Val, |
|
uint64_t Address, void *Decoder); |
|
|
|
static DecodeStatus DecodeSide(MCInst *Inst, unsigned Val, |
|
uint64_t Address, void *Decoder); |
|
|
|
static DecodeStatus DecodeParallel(MCInst *Inst, unsigned Val, |
|
uint64_t Address, void *Decoder); |
|
|
|
static DecodeStatus DecodeCrosspathX1(MCInst *Inst, unsigned Val, |
|
uint64_t Address, void *Decoder); |
|
|
|
static DecodeStatus DecodeCrosspathX2(MCInst *Inst, unsigned Val, |
|
uint64_t Address, void *Decoder); |
|
|
|
static DecodeStatus DecodeCrosspathX3(MCInst *Inst, unsigned Val, |
|
uint64_t Address, void *Decoder); |
|
|
|
static DecodeStatus DecodeNop(MCInst *Inst, unsigned Val, |
|
uint64_t Address, void *Decoder); |
|
|
|
#include "TMS320C64xGenDisassemblerTables.inc" |
|
|
|
#define GET_REGINFO_ENUM |
|
#define GET_REGINFO_MC_DESC |
|
#include "TMS320C64xGenRegisterInfo.inc" |
|
|
|
static const unsigned GPRegsDecoderTable[] = { |
|
TMS320C64x_A0, TMS320C64x_A1, TMS320C64x_A2, TMS320C64x_A3, |
|
TMS320C64x_A4, TMS320C64x_A5, TMS320C64x_A6, TMS320C64x_A7, |
|
TMS320C64x_A8, TMS320C64x_A9, TMS320C64x_A10, TMS320C64x_A11, |
|
TMS320C64x_A12, TMS320C64x_A13, TMS320C64x_A14, TMS320C64x_A15, |
|
TMS320C64x_A16, TMS320C64x_A17, TMS320C64x_A18, TMS320C64x_A19, |
|
TMS320C64x_A20, TMS320C64x_A21, TMS320C64x_A22, TMS320C64x_A23, |
|
TMS320C64x_A24, TMS320C64x_A25, TMS320C64x_A26, TMS320C64x_A27, |
|
TMS320C64x_A28, TMS320C64x_A29, TMS320C64x_A30, TMS320C64x_A31 |
|
}; |
|
|
|
static const unsigned ControlRegsDecoderTable[] = { |
|
TMS320C64x_AMR, TMS320C64x_CSR, TMS320C64x_ISR, TMS320C64x_ICR, |
|
TMS320C64x_IER, TMS320C64x_ISTP, TMS320C64x_IRP, TMS320C64x_NRP, |
|
~0U, ~0U, TMS320C64x_TSCL, TMS320C64x_TSCH, |
|
~0U, TMS320C64x_ILC, TMS320C64x_RILC, TMS320C64x_REP, |
|
TMS320C64x_PCE1, TMS320C64x_DNUM, ~0U, ~0U, |
|
~0U, TMS320C64x_SSR, TMS320C64x_GPLYA, TMS320C64x_GPLYB, |
|
TMS320C64x_GFPGFR, TMS320C64x_DIER, TMS320C64x_TSR, TMS320C64x_ITSR, |
|
TMS320C64x_NTSR, TMS320C64x_ECR, ~0U, TMS320C64x_IERR |
|
}; |
|
|
|
static uint64_t getFeatureBits(int mode) |
|
{ |
|
// support everything |
|
return (uint64_t)-1; |
|
} |
|
|
|
static unsigned getReg(const unsigned *RegTable, unsigned RegNo) |
|
{ |
|
if(RegNo > 31) |
|
return ~0U; |
|
return RegTable[RegNo]; |
|
} |
|
|
|
static DecodeStatus DecodeGPRegsRegisterClass(MCInst *Inst, unsigned RegNo, |
|
uint64_t Address, void *Decoder) |
|
{ |
|
unsigned Reg; |
|
|
|
if(RegNo > 31) |
|
return MCDisassembler_Fail; |
|
|
|
Reg = getReg(GPRegsDecoderTable, RegNo); |
|
if(Reg == ~0U) |
|
return MCDisassembler_Fail; |
|
MCOperand_CreateReg0(Inst, Reg); |
|
|
|
return MCDisassembler_Success; |
|
} |
|
|
|
static DecodeStatus DecodeControlRegsRegisterClass(MCInst *Inst, unsigned RegNo, |
|
uint64_t Address, void *Decoder) |
|
{ |
|
unsigned Reg; |
|
|
|
if(RegNo > 31) |
|
return MCDisassembler_Fail; |
|
|
|
Reg = getReg(ControlRegsDecoderTable, RegNo); |
|
if(Reg == ~0U) |
|
return MCDisassembler_Fail; |
|
MCOperand_CreateReg0(Inst, Reg); |
|
|
|
return MCDisassembler_Success; |
|
} |
|
|
|
static DecodeStatus DecodeScst5(MCInst *Inst, unsigned Val, |
|
uint64_t Address, void *Decoder) |
|
{ |
|
int32_t imm; |
|
|
|
imm = Val; |
|
/* Sign extend 5 bit value */ |
|
if(imm & (1 << (5 - 1))) |
|
imm |= ~((1 << 5) - 1); |
|
|
|
MCOperand_CreateImm0(Inst, imm); |
|
|
|
return MCDisassembler_Success; |
|
} |
|
|
|
static DecodeStatus DecodeScst16(MCInst *Inst, unsigned Val, |
|
uint64_t Address, void *Decoder) |
|
{ |
|
int32_t imm; |
|
|
|
imm = Val; |
|
/* Sign extend 16 bit value */ |
|
if(imm & (1 << (16 - 1))) |
|
imm |= ~((1 << 16) - 1); |
|
|
|
MCOperand_CreateImm0(Inst, imm); |
|
|
|
return MCDisassembler_Success; |
|
} |
|
|
|
static DecodeStatus DecodePCRelScst7(MCInst *Inst, unsigned Val, |
|
uint64_t Address, void *Decoder) |
|
{ |
|
int32_t imm; |
|
|
|
imm = Val; |
|
/* Sign extend 7 bit value */ |
|
if(imm & (1 << (7 - 1))) |
|
imm |= ~((1 << 7) - 1); |
|
|
|
/* Address is relative to the address of the first instruction in the fetch packet */ |
|
MCOperand_CreateImm0(Inst, (Address & ~31) + (imm * 4)); |
|
|
|
return MCDisassembler_Success; |
|
} |
|
|
|
static DecodeStatus DecodePCRelScst10(MCInst *Inst, unsigned Val, |
|
uint64_t Address, void *Decoder) |
|
{ |
|
int32_t imm; |
|
|
|
imm = Val; |
|
/* Sign extend 10 bit value */ |
|
if(imm & (1 << (10 - 1))) |
|
imm |= ~((1 << 10) - 1); |
|
|
|
/* Address is relative to the address of the first instruction in the fetch packet */ |
|
MCOperand_CreateImm0(Inst, (Address & ~31) + (imm * 4)); |
|
|
|
return MCDisassembler_Success; |
|
} |
|
|
|
static DecodeStatus DecodePCRelScst12(MCInst *Inst, unsigned Val, |
|
uint64_t Address, void *Decoder) |
|
{ |
|
int32_t imm; |
|
|
|
imm = Val; |
|
/* Sign extend 12 bit value */ |
|
if(imm & (1 << (12 - 1))) |
|
imm |= ~((1 << 12) - 1); |
|
|
|
/* Address is relative to the address of the first instruction in the fetch packet */ |
|
MCOperand_CreateImm0(Inst, (Address & ~31) + (imm * 4)); |
|
|
|
return MCDisassembler_Success; |
|
} |
|
|
|
static DecodeStatus DecodePCRelScst21(MCInst *Inst, unsigned Val, |
|
uint64_t Address, void *Decoder) |
|
{ |
|
int32_t imm; |
|
|
|
imm = Val; |
|
/* Sign extend 21 bit value */ |
|
if(imm & (1 << (21 - 1))) |
|
imm |= ~((1 << 21) - 1); |
|
|
|
/* Address is relative to the address of the first instruction in the fetch packet */ |
|
MCOperand_CreateImm0(Inst, (Address & ~31) + (imm * 4)); |
|
|
|
return MCDisassembler_Success; |
|
} |
|
|
|
static DecodeStatus DecodeMemOperand(MCInst *Inst, unsigned Val, |
|
uint64_t Address, void *Decoder) |
|
{ |
|
return DecodeMemOperandSc(Inst, Val | (1 << 15), Address, Decoder); |
|
} |
|
|
|
static DecodeStatus DecodeMemOperandSc(MCInst *Inst, unsigned Val, |
|
uint64_t Address, void *Decoder) |
|
{ |
|
uint8_t scaled, base, offset, mode, unit; |
|
unsigned basereg, offsetreg; |
|
|
|
scaled = (Val >> 15) & 1; |
|
base = (Val >> 10) & 0x1f; |
|
offset = (Val >> 5) & 0x1f; |
|
mode = (Val >> 1) & 0xf; |
|
unit = Val & 1; |
|
|
|
if((base >= TMS320C64X_REG_A0) && (base <= TMS320C64X_REG_A31)) |
|
base = (base - TMS320C64X_REG_A0 + TMS320C64X_REG_B0); |
|
else if((base >= TMS320C64X_REG_B0) && (base <= TMS320C64X_REG_B31)) |
|
base = (base - TMS320C64X_REG_B0 + TMS320C64X_REG_A0); |
|
basereg = getReg(GPRegsDecoderTable, base); |
|
if (basereg == ~0U) |
|
return MCDisassembler_Fail; |
|
|
|
switch(mode) { |
|
case 0: |
|
case 1: |
|
case 8: |
|
case 9: |
|
case 10: |
|
case 11: |
|
MCOperand_CreateImm0(Inst, (scaled << 19) | (basereg << 12) | (offset << 5) | (mode << 1) | unit); |
|
break; |
|
case 4: |
|
case 5: |
|
case 12: |
|
case 13: |
|
case 14: |
|
case 15: |
|
if((offset >= TMS320C64X_REG_A0) && (offset <= TMS320C64X_REG_A31)) |
|
offset = (offset - TMS320C64X_REG_A0 + TMS320C64X_REG_B0); |
|
else if((offset >= TMS320C64X_REG_B0) && (offset <= TMS320C64X_REG_B31)) |
|
offset = (offset - TMS320C64X_REG_B0 + TMS320C64X_REG_A0); |
|
offsetreg = getReg(GPRegsDecoderTable, offset); |
|
if (offsetreg == ~0U) |
|
return MCDisassembler_Fail; |
|
MCOperand_CreateImm0(Inst, (scaled << 19) | (basereg << 12) | (offsetreg << 5) | (mode << 1) | unit); |
|
break; |
|
default: |
|
return MCDisassembler_Fail; |
|
} |
|
|
|
return MCDisassembler_Success; |
|
} |
|
|
|
static DecodeStatus DecodeMemOperand2(MCInst *Inst, unsigned Val, |
|
uint64_t Address, void *Decoder) |
|
{ |
|
uint16_t offset; |
|
unsigned basereg; |
|
|
|
if(Val & 1) |
|
basereg = TMS320C64X_REG_B15; |
|
else |
|
basereg = TMS320C64X_REG_B14; |
|
|
|
offset = (Val >> 1) & 0x7fff; |
|
MCOperand_CreateImm0(Inst, (offset << 7) | basereg); |
|
|
|
return MCDisassembler_Success; |
|
} |
|
|
|
static DecodeStatus DecodeRegPair5(MCInst *Inst, unsigned RegNo, |
|
uint64_t Address, void *Decoder) |
|
{ |
|
unsigned Reg; |
|
|
|
if(RegNo > 31) |
|
return MCDisassembler_Fail; |
|
|
|
Reg = getReg(GPRegsDecoderTable, RegNo); |
|
MCOperand_CreateReg0(Inst, Reg); |
|
|
|
return MCDisassembler_Success; |
|
} |
|
|
|
static DecodeStatus DecodeRegPair4(MCInst *Inst, unsigned RegNo, |
|
uint64_t Address, void *Decoder) |
|
{ |
|
unsigned Reg; |
|
|
|
if(RegNo > 15) |
|
return MCDisassembler_Fail; |
|
|
|
Reg = getReg(GPRegsDecoderTable, RegNo << 1); |
|
MCOperand_CreateReg0(Inst, Reg); |
|
|
|
return MCDisassembler_Success; |
|
} |
|
|
|
static DecodeStatus DecodeCondRegister(MCInst *Inst, unsigned Val, |
|
uint64_t Address, void *Decoder) |
|
{ |
|
DecodeStatus ret = MCDisassembler_Success; |
|
|
|
if(!Inst->flat_insn->detail) |
|
return MCDisassembler_Success; |
|
|
|
switch(Val) { |
|
case 0: |
|
case 7: |
|
Inst->flat_insn->detail->tms320c64x.condition.reg = TMS320C64X_REG_INVALID; |
|
break; |
|
case 1: |
|
Inst->flat_insn->detail->tms320c64x.condition.reg = TMS320C64X_REG_B0; |
|
break; |
|
case 2: |
|
Inst->flat_insn->detail->tms320c64x.condition.reg = TMS320C64X_REG_B1; |
|
break; |
|
case 3: |
|
Inst->flat_insn->detail->tms320c64x.condition.reg = TMS320C64X_REG_B2; |
|
break; |
|
case 4: |
|
Inst->flat_insn->detail->tms320c64x.condition.reg = TMS320C64X_REG_A1; |
|
break; |
|
case 5: |
|
Inst->flat_insn->detail->tms320c64x.condition.reg = TMS320C64X_REG_A2; |
|
break; |
|
case 6: |
|
Inst->flat_insn->detail->tms320c64x.condition.reg = TMS320C64X_REG_A0; |
|
break; |
|
default: |
|
Inst->flat_insn->detail->tms320c64x.condition.reg = TMS320C64X_REG_INVALID; |
|
ret = MCDisassembler_Fail; |
|
break; |
|
} |
|
|
|
return ret; |
|
} |
|
|
|
static DecodeStatus DecodeCondRegisterZero(MCInst *Inst, unsigned Val, |
|
uint64_t Address, void *Decoder) |
|
{ |
|
DecodeStatus ret = MCDisassembler_Success; |
|
|
|
if(!Inst->flat_insn->detail) |
|
return MCDisassembler_Success; |
|
|
|
switch(Val) { |
|
case 0: |
|
Inst->flat_insn->detail->tms320c64x.condition.zero = 0; |
|
break; |
|
case 1: |
|
Inst->flat_insn->detail->tms320c64x.condition.zero = 1; |
|
break; |
|
default: |
|
Inst->flat_insn->detail->tms320c64x.condition.zero = 0; |
|
ret = MCDisassembler_Fail; |
|
break; |
|
} |
|
|
|
return ret; |
|
} |
|
|
|
static DecodeStatus DecodeSide(MCInst *Inst, unsigned Val, |
|
uint64_t Address, void *Decoder) |
|
{ |
|
DecodeStatus ret = MCDisassembler_Success; |
|
MCOperand *op; |
|
int i; |
|
|
|
/* This is pretty messy, probably we should find a better way */ |
|
if(Val == 1) { |
|
for(i = 0; i < Inst->size; i++) { |
|
op = &Inst->Operands[i]; |
|
if(op->Kind == kRegister) { |
|
if((op->RegVal >= TMS320C64X_REG_A0) && (op->RegVal <= TMS320C64X_REG_A31)) |
|
op->RegVal = (op->RegVal - TMS320C64X_REG_A0 + TMS320C64X_REG_B0); |
|
else if((op->RegVal >= TMS320C64X_REG_B0) && (op->RegVal <= TMS320C64X_REG_B31)) |
|
op->RegVal = (op->RegVal - TMS320C64X_REG_B0 + TMS320C64X_REG_A0); |
|
} |
|
} |
|
} |
|
|
|
if(!Inst->flat_insn->detail) |
|
return MCDisassembler_Success; |
|
|
|
switch(Val) { |
|
case 0: |
|
Inst->flat_insn->detail->tms320c64x.funit.side = 1; |
|
break; |
|
case 1: |
|
Inst->flat_insn->detail->tms320c64x.funit.side = 2; |
|
break; |
|
default: |
|
Inst->flat_insn->detail->tms320c64x.funit.side = 0; |
|
ret = MCDisassembler_Fail; |
|
break; |
|
} |
|
|
|
return ret; |
|
} |
|
|
|
static DecodeStatus DecodeParallel(MCInst *Inst, unsigned Val, |
|
uint64_t Address, void *Decoder) |
|
{ |
|
DecodeStatus ret = MCDisassembler_Success; |
|
|
|
if(!Inst->flat_insn->detail) |
|
return MCDisassembler_Success; |
|
|
|
switch(Val) { |
|
case 0: |
|
Inst->flat_insn->detail->tms320c64x.parallel = 0; |
|
break; |
|
case 1: |
|
Inst->flat_insn->detail->tms320c64x.parallel = 1; |
|
break; |
|
default: |
|
Inst->flat_insn->detail->tms320c64x.parallel = -1; |
|
ret = MCDisassembler_Fail; |
|
break; |
|
} |
|
|
|
return ret; |
|
} |
|
|
|
static DecodeStatus DecodeCrosspathX1(MCInst *Inst, unsigned Val, |
|
uint64_t Address, void *Decoder) |
|
{ |
|
DecodeStatus ret = MCDisassembler_Success; |
|
MCOperand *op; |
|
|
|
if(!Inst->flat_insn->detail) |
|
return MCDisassembler_Success; |
|
|
|
switch(Val) { |
|
case 0: |
|
Inst->flat_insn->detail->tms320c64x.funit.crosspath = 0; |
|
break; |
|
case 1: |
|
Inst->flat_insn->detail->tms320c64x.funit.crosspath = 1; |
|
op = &Inst->Operands[0]; |
|
if(op->Kind == kRegister) { |
|
if((op->RegVal >= TMS320C64X_REG_A0) && (op->RegVal <= TMS320C64X_REG_A31)) |
|
op->RegVal = (op->RegVal - TMS320C64X_REG_A0 + TMS320C64X_REG_B0); |
|
else if((op->RegVal >= TMS320C64X_REG_B0) && (op->RegVal <= TMS320C64X_REG_B31)) |
|
op->RegVal = (op->RegVal - TMS320C64X_REG_B0 + TMS320C64X_REG_A0); |
|
} |
|
break; |
|
default: |
|
Inst->flat_insn->detail->tms320c64x.funit.crosspath = -1; |
|
ret = MCDisassembler_Fail; |
|
break; |
|
} |
|
|
|
return ret; |
|
} |
|
|
|
static DecodeStatus DecodeCrosspathX2(MCInst *Inst, unsigned Val, |
|
uint64_t Address, void *Decoder) |
|
{ |
|
DecodeStatus ret = MCDisassembler_Success; |
|
MCOperand *op; |
|
|
|
if(!Inst->flat_insn->detail) |
|
return MCDisassembler_Success; |
|
|
|
switch(Val) { |
|
case 0: |
|
Inst->flat_insn->detail->tms320c64x.funit.crosspath = 0; |
|
break; |
|
case 1: |
|
Inst->flat_insn->detail->tms320c64x.funit.crosspath = 1; |
|
op = &Inst->Operands[1]; |
|
if(op->Kind == kRegister) { |
|
if((op->RegVal >= TMS320C64X_REG_A0) && (op->RegVal <= TMS320C64X_REG_A31)) |
|
op->RegVal = (op->RegVal - TMS320C64X_REG_A0 + TMS320C64X_REG_B0); |
|
else if((op->RegVal >= TMS320C64X_REG_B0) && (op->RegVal <= TMS320C64X_REG_B31)) |
|
op->RegVal = (op->RegVal - TMS320C64X_REG_B0 + TMS320C64X_REG_A0); |
|
} |
|
break; |
|
default: |
|
Inst->flat_insn->detail->tms320c64x.funit.crosspath = -1; |
|
ret = MCDisassembler_Fail; |
|
break; |
|
} |
|
|
|
return ret; |
|
} |
|
|
|
static DecodeStatus DecodeCrosspathX3(MCInst *Inst, unsigned Val, |
|
uint64_t Address, void *Decoder) |
|
{ |
|
DecodeStatus ret = MCDisassembler_Success; |
|
MCOperand *op; |
|
|
|
if(!Inst->flat_insn->detail) |
|
return MCDisassembler_Success; |
|
|
|
switch(Val) { |
|
case 0: |
|
Inst->flat_insn->detail->tms320c64x.funit.crosspath = 0; |
|
break; |
|
case 1: |
|
Inst->flat_insn->detail->tms320c64x.funit.crosspath = 2; |
|
op = &Inst->Operands[2]; |
|
if(op->Kind == kRegister) { |
|
if((op->RegVal >= TMS320C64X_REG_A0) && (op->RegVal <= TMS320C64X_REG_A31)) |
|
op->RegVal = (op->RegVal - TMS320C64X_REG_A0 + TMS320C64X_REG_B0); |
|
else if((op->RegVal >= TMS320C64X_REG_B0) && (op->RegVal <= TMS320C64X_REG_B31)) |
|
op->RegVal = (op->RegVal - TMS320C64X_REG_B0 + TMS320C64X_REG_A0); |
|
} |
|
break; |
|
default: |
|
Inst->flat_insn->detail->tms320c64x.funit.crosspath = -1; |
|
ret = MCDisassembler_Fail; |
|
break; |
|
} |
|
|
|
return ret; |
|
} |
|
|
|
|
|
static DecodeStatus DecodeNop(MCInst *Inst, unsigned Val, |
|
uint64_t Address, void *Decoder) |
|
{ |
|
MCOperand_CreateImm0(Inst, Val + 1); |
|
|
|
return MCDisassembler_Success; |
|
} |
|
|
|
#define GET_INSTRINFO_ENUM |
|
#include "TMS320C64xGenInstrInfo.inc" |
|
|
|
bool TMS320C64x_getInstruction(csh ud, const uint8_t *code, size_t code_len, |
|
MCInst *MI, uint16_t *size, uint64_t address, void *info) |
|
{ |
|
uint32_t insn; |
|
DecodeStatus result; |
|
|
|
if(code_len < 4) { |
|
*size = 0; |
|
return MCDisassembler_Fail; |
|
} |
|
|
|
if(MI->flat_insn->detail) |
|
memset(MI->flat_insn->detail, 0, offsetof(cs_detail, tms320c64x)+sizeof(cs_tms320c64x)); |
|
|
|
insn = (code[3] << 0) | (code[2] << 8) | (code[1] << 16) | ((uint32_t) code[0] << 24); |
|
result = decodeInstruction_4(DecoderTable32, MI, insn, address, info, 0); |
|
|
|
if(result == MCDisassembler_Success) { |
|
*size = 4; |
|
return true; |
|
} |
|
|
|
MCInst_clear(MI); |
|
*size = 0; |
|
return false; |
|
} |
|
|
|
void TMS320C64x_init(MCRegisterInfo *MRI) |
|
{ |
|
MCRegisterInfo_InitMCRegisterInfo(MRI, TMS320C64xRegDesc, 90, |
|
0, 0, |
|
TMS320C64xMCRegisterClasses, 7, |
|
0, 0, |
|
TMS320C64xRegDiffLists, |
|
0, |
|
TMS320C64xSubRegIdxLists, 1, |
|
0); |
|
} |
|
|
|
#endif
|
|
|