Merge commit '802798ce3c8baa4697120580f87bc1ee377306d3' as 'external/capstone'
This commit is contained in:
@@ -0,0 +1,682 @@
|
||||
/* 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);
|
||||
// base cannot be a B register, because it was ANDed above with 0x1f.
|
||||
// And the TMS320C64X_REG_B0 > 31
|
||||
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);
|
||||
// offset cannot be a B register, because it was ANDed above with 0x1f.
|
||||
// And the TMS320C64X_REG_B0 > 31
|
||||
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 = readBytes32(MI, code);
|
||||
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
|
||||
Reference in New Issue
Block a user