www.pudn.com > potemkin_sourceforPSP.rar > ARMTables.cpp
#include "stdafx.h"
#include "ARMTables.h"
#include "ARM.h"
#include "ARMCompiler.h"
#include "ARMDis.h"
#include "ARMInfo.h"
#include "ARMLoadStore.h"
#include "ARMBranch.h"
#include "ARMDataProcessing.h"
#include "ARMInterpret.h"
#include "THUMBLoadStore.h"
#include "THUMBBranch.h"
#include "THUMBDataProcessing.h"
const TCHAR *conditionNames[16] =
{
"EQ","NE","CS","CC","MI","PL","VS","VC","HI","LS","GE","LT","GT","LE","","+"
};
const u32 conditionOpposite[16] =
{
COND_NE,COND_EQ,COND_CC,COND_CS,
COND_PL,COND_MI,COND_VC,COND_VS,
COND_LS,COND_HI,COND_LT,COND_GE,
COND_LE,COND_GT,-1,-1
};
const int relevantFlags[16] =
{
FL_Z,FL_Z,FL_C,FL_C,FL_N,FL_N,FL_V,FL_V,
FL_C|FL_Z,FL_C|FL_Z,
FL_N|FL_V,FL_N|FL_V,
FL_Z|FL_N|FL_V,FL_Z|FL_N|FL_V,
0,0
};
typedef void (CDECL *ARMCompileFunc)(u32 opcode);
typedef void (CDECL *ARMDisFunc)(u32 opcode, TCHAR *out);
typedef InstructionInfo (CDECL *ARMInfoFunc)(u32 opcode);
typedef void (CDECL *ARMInterpretFunc)(u32 opcode);
typedef void (CDECL *THUMBCompileFunc)(u16 opcode);
typedef void (CDECL *THUMBDisFunc)(u16 opcode, TCHAR *out);
typedef InstructionInfo (CDECL *THUMBInfoFunc)(u16 opcode);
typedef u32 ARMInstrInfo;
// convert to table index
#define CRUNCH_ARM_OP(op) (((op>>16)&0xFF0)|((op>>4)&0xF))
#define CRUNCH_THUMB_OP(op) (op>>6)
#define ENC(a,b) ((a<<4)|(b))
#define DATAP(a,s) ((a<<5)|(s<<4))
#define IGNORE_I 0x200
#define IGNORE_LOW 0xF
struct ARMInstruction
{
ARMCompileFunc compile;
ARMDisFunc disasm;
ARMInfoFunc getinfo;
ARMInterpretFunc interpret;
u32 encoding;
u32 ignoredbits;
InstructionInfo information;
};
struct THUMBInstruction
{
THUMBCompileFunc compile;
THUMBDisFunc disasm;
THUMBInfoFunc getinfo;
u32 encoding;
u32 ignoredbits;
InstructionInfo information;
};
using namespace ARMInstructions;
using namespace ARMDis;
//arm encoding table
const ARMInstruction arminstructions[] =
{
{Comp_Unimpl,Dis_Unimpl, Info_NN, 0, 0x601, 0x1FE,0}, //could be used for drec hook :) bits 5-24 plus 0-3 are available, 19 bits are more than enough
// DATA PROCESSING INSTRUCTIONS
// S
{Comp_AND, Dis_AND, Info_DP, 0, DATAP(0, 0), 0x20F, {0}},
{Comp_AND, Dis_AND, Info_DP, 0, DATAP(0, 1), 0x20F, {0,FL_N|FL_Z|FL_C}},
{Comp_EOR, Dis_EOR, Info_DP, 0, DATAP(1, 0), 0x20F, {0}},
{Comp_EOR, Dis_EOR, Info_DP, 0, DATAP(1, 1), 0x20F, {0,FL_N|FL_Z|FL_C}},
{Comp_SUB, Dis_SUB, Info_DP, 0, DATAP(2, 0), 0x20F, {0}},
{Comp_SUB, Dis_SUB, Info_DP, 0, DATAP(2, 1), 0x20F, {0,FL_N|FL_Z|FL_C|FL_V}},
{Comp_RSB, Dis_RSB, Info_DP, 0, DATAP(3, 0), 0x20F, {0}},
{Comp_RSB, Dis_RSB, Info_DP, 0, DATAP(3, 1), 0x20F, {0,FL_N|FL_Z|FL_C|FL_V}},
{Comp_ADD, Dis_ADD, Info_DP, 0, DATAP(4, 0), 0x20F, {0}},
{Comp_ADD, Dis_ADD, Info_DP, 0, DATAP(4, 1), 0x20F, {0,FL_N|FL_Z|FL_C|FL_V}},
{Comp_ADC, Dis_ADC, Info_DP, 0, DATAP(5, 0), 0x20F, {FL_C,0}},
{Comp_ADC, Dis_ADC, Info_DP, 0, DATAP(5, 1), 0x20F, {FL_C,FL_N|FL_Z|FL_C|FL_V}},
{Comp_SBC, Dis_SBC, Info_DP, 0, DATAP(6, 0), 0x20F, {FL_C}},
{Comp_SBC, Dis_SBC, Info_DP, 0, DATAP(6, 1), 0x20F, {FL_C,FL_N|FL_Z|FL_C|FL_V}},
{Comp_RSC, Dis_RSC, Info_DP, 0, DATAP(7, 0), 0x20F, {FL_C,0}},
{Comp_RSC, Dis_RSC, Info_DP, 0, DATAP(7, 1), 0x20F, {FL_C,FL_N|FL_Z|FL_C|FL_V}},
//these four have no non-S form
{Comp_Unimpl,Dis_Unknown,Info_DP, 0, DATAP(8, 0), 0x20F, {0}},
{Comp_TST, Dis_TST, Info_DP, 0, DATAP(8, 1), 0x20F, {0,FL_N|FL_Z|FL_C}},
{Comp_Unimpl,Dis_Unknown,Info_DP, 0, DATAP(9, 0), 0x20F, {0}},
{Comp_TEQ, Dis_TEQ, Info_DP, 0, DATAP(9, 1), 0x20F, {0,FL_N|FL_Z|FL_C}},
{Comp_Unimpl,Dis_Unknown,Info_DP, 0, DATAP(10,0), 0x20F, {0}},
{Comp_CMP, Dis_CMP, Info_DP, 0, DATAP(10,1), 0x20F, {0,FL_N|FL_Z|FL_C|FL_V}},
{Comp_Unimpl,Dis_Unknown,Info_DP, 0, DATAP(11,0), 0x20F, {0}},
{Comp_CMN, Dis_CMN, Info_DP, 0, DATAP(11,1), 0x20F, {0,FL_N|FL_Z|FL_C|FL_V}},
{Comp_ORR, Dis_ORR, Info_DP, 0, DATAP(12,0), 0x20F, {0}},
{Comp_ORR, Dis_ORR, Info_DP, 0, DATAP(12,1), 0x20F, {0,FL_N|FL_Z|FL_C}},
{Comp_MOV, Dis_MOV, Info_DP, 0, DATAP(13,0), 0x20F, {0}},
{Comp_MOV, Dis_MOV, Info_DP, 0, DATAP(13,1), 0x20F, {0,FL_N|FL_Z|FL_C}},
{Comp_BIC, Dis_BIC, Info_DP, 0, DATAP(14,0), 0x20F, {0}},
{Comp_BIC, Dis_BIC, Info_DP, 0, DATAP(14,1), 0x20F, {0,FL_N|FL_Z|FL_C}},
{Comp_MVN, Dis_MVN, Info_DP, 0, DATAP(15,0), 0x20F, {0}},
{Comp_MVN, Dis_MVN, Info_DP, 0, DATAP(15,1), 0x20F, {0,FL_N|FL_Z|FL_C}},
//Multiply
{Comp_MUL, Dis_MUL, Info_NN, 0, 0x009,0x000,{0}},
{Comp_MUL, Dis_MUL, Info_NN, 0, 0x019,0x000,{0,FL_N|FL_Z}},
{Comp_MLA, Dis_MLA, Info_NN, 0, 0x029,0x000,{0}},
{Comp_MLA, Dis_MLA, Info_NN, 0, 0x039,0x000,{0,FL_N|FL_Z}},
{Comp_UMULL, Dis_UMULL, Info_NN, 0, 0x089,0x000,{0}},
{Comp_UMULL, Dis_UMULL, Info_NN, 0, 0x099,0x000,{0,FL_N|FL_Z}},
{Comp_UMLAL, Dis_UMLAL, Info_NN, 0, 0x0A9,0x000,{0}},
{Comp_UMLAL, Dis_UMLAL, Info_NN, 0, 0x0B9,0x000,{0,FL_N|FL_Z}},
{Comp_SMULL, Dis_SMULL, Info_NN, 0, 0x0C9,0x000,{0}},
{Comp_SMULL, Dis_SMULL, Info_NN, 0, 0x0D9,0x000,{0,FL_N|FL_Z}},
{Comp_SMLAL, Dis_SMLAL, Info_NN, 0, 0x0E9,0x000,{0}},
{Comp_SMLAL, Dis_SMLAL, Info_NN, 0, 0x0F9,0x000,{0,FL_N|FL_Z}},
// MISC INSTRUCTIONS
{Comp_CLZ, Dis_CLZ, Info_NN, 0, ENC(0x16,1),0,{0}},
{Comp_MRS, Dis_MRS, Info_NN, Int_MRS, ENC(0x10,0),0x040,{0}},
{Comp_MSRreg,Dis_MSRreg, Info_NN, Int_MSRreg, 0x120,0x040,{0}},
{Comp_MSRimm,Dis_MSRimm, Info_NN, Int_MSRimm, 0x320,0x040,{0}},
{Comp_MCR, Dis_MCR, Info_NN, Int_MCR, 0xE01,0x0EE,{0}},
{Comp_MRC, Dis_MRC, Info_NN, Int_MRC, 0xE11,0x0EE,{0}},
//Load/store
{Comp_STR, Dis_STR, Info_NN, 0, 0x400,0x3AF,{0}},
{Comp_LDR, Dis_LDR, Info_LDR, 0, 0x410,0x3AF,{0}},
{Comp_STRB, Dis_STRB, Info_NN, 0, 0x440,0x3AF,{0}},
{Comp_LDRB, Dis_LDRB, Info_NN, 0, 0x450,0x3AF,{0}},
{Comp_STRH, Dis_STRH, Info_NN, 0, 0x00B,0x1E0,{0}},
// {Comp_STRSB, Dis_STRSB, Info_NN, 0, 0x00D,0x1E0,{0}},
// {Comp_STRSH, Dis_STRSH, Info_NN, 0, 0x00F,0x1E0,{0}},
{Comp_LDRH, Dis_LDRH, Info_NN, 0, 0x01B,0x1E0,{0}},
{Comp_LDRSB, Dis_LDRSB, Info_NN, 0, 0x01D,0x1E0,{0}},
{Comp_LDRSH, Dis_LDRSH, Info_NN, 0, 0x01F,0x1E0,{0}},
{Comp_LDC, Dis_LDC, Info_NN, Int_LDC, 0xC10,0x1EF,{0}},
{Comp_STC, Dis_STC, Info_NN, Int_STC, 0xC00,0x1EF,{0}},
//Load/store multiple
{Comp_STM, Dis_STM, Info_NN, 0, 0x800,0x1eF,{0}},
{Comp_LDM, Dis_LDM, Info_LDM, 0, 0x810,0x1eF,{0}},
//Swap
{Comp_SWP, Dis_SWP, Info_NN, 0, 0x109,0x000,{0}},
{Comp_SWPB, Dis_SWPB, Info_NN, 0, 0x149,0x000,{0}},
//{Comp_BKPT, Dis_BKPT, Info_NN, 0x127,0x000,{0}}, //also upper = 0xE
//Software interrupt
{Comp_SWI, Dis_SWI, Info_NN, 0, 0xF00,0x0FF,{0,0,END_BASIC_BLOCK}},
//Branch and link
{Comp_B, Dis_B, Info_NN, 0, 0xA00,0x0FF,{0,0,END_BASIC_BLOCK}},
{Comp_BL, Dis_BL, Info_NN, 0, 0xB00,0x0FF,{0,0,END_BASIC_BLOCK}},
{Comp_BLXr, Dis_BLXr, Info_NN, 0, 0x123,0x000,{0,0,END_BASIC_BLOCK}},
{Comp_BXr, Dis_BXr, Info_NN, 0, 0x121,0x000,{0,0,END_BASIC_BLOCK}},
};
using namespace THUMBInstructions;
//thumb encoding table
const THUMBInstruction thumbinstructions[] =
{
{Comp_T_Unimpl,Dis_T_Unimpl,Info_T_NN, 0xB80,0x03C,0}, //could be used for drec hook :) only 10 bits but can at least point to another table..
///Data processing
{Comp_T_AND, Dis_T_AND, Info_T_NN, 0x400,0x000,{0,FL_N|FL_Z}},
{Comp_T_EOR, Dis_T_EOR, Info_T_NN, 0x404,0x000,{0,FL_N|FL_Z}},
{Comp_T_LSL, Dis_T_LSL, Info_T_NN, 0x408,0x000,{0,FL_N|FL_Z}},
{Comp_T_LSR, Dis_T_LSR, Info_T_NN, 0x40C,0x000,{0,FL_N|FL_Z|FL_C}},
{Comp_T_ASR, Dis_T_ASR, Info_T_NN, 0x410,0x000,{0,FL_N|FL_Z|FL_C}},
{Comp_T_ADC, Dis_T_ADC, Info_T_NN, 0x414,0x000,{FL_C,FL_N|FL_Z|FL_C|FL_V}},
{Comp_T_ROR, Dis_T_ROR, Info_T_NN, 0x41C,0x000,{0,FL_N|FL_Z|FL_C}},
{Comp_T_SBC, Dis_T_SBC, Info_T_NN, 0x418,0x000,{FL_C,FL_N|FL_Z|FL_C|FL_V}},
{Comp_T_TST, Dis_T_TST, Info_T_NN, 0x420,0x000,{0,FL_N|FL_Z}},
{Comp_T_NEG, Dis_T_NEG, Info_T_NN, 0x424,0x000,{0,FL_N|FL_Z|FL_C}},
{Comp_T_CMP, Dis_T_CMP, Info_T_NN, 0x428,0x000,{0,FL_N|FL_Z|FL_C|FL_V}},
{Comp_T_CMN, Dis_T_CMN, Info_T_NN, 0x42C,0x000,{0,FL_N|FL_Z|FL_C|FL_V}},
{Comp_T_ORR, Dis_T_ORR, Info_T_NN, 0x430,0x000,{0,FL_N|FL_Z}},
{Comp_T_MUL, Dis_T_MUL, Info_T_NN, 0x434,0x000,{0,FL_N|FL_Z}},
{Comp_T_BIC, Dis_T_BIC, Info_T_NN, 0x438,0x000,{0,FL_N|FL_Z}},
{Comp_T_MVN, Dis_T_MVN, Info_T_NN, 0x43C,0x000,{0,FL_N|FL_Z}},
{Comp_T_ADDhi, Dis_T_ADDhi, Info_T_ADDhi, 0x440,0x00C,{0,0}}, // no flag change
{Comp_T_CMPhi, Dis_T_CMPhi, Info_T_NN, 0x450,0x00C,{0,FL_N|FL_Z|FL_C|FL_V}},
{Comp_T_MOVhi, Dis_T_MOVhi, Info_T_MOVhi, 0x460,0x00C,{0,0}}, // no flag change
{Comp_T_ADD, Dis_T_ADD, Info_T_NN, 0x180,0x01C,{0,FL_N|FL_Z|FL_C|FL_V}},
{Comp_T_SUB, Dis_T_SUB, Info_T_NN, 0x1A0,0x01C,{0,FL_N|FL_Z|FL_C|FL_V}},
{Comp_T_ADDimm,Dis_T_ADDimm,Info_T_NN, 0x1C0,0x01C,{0,FL_N|FL_Z|FL_C|FL_V}},
{Comp_T_SUBimm,Dis_T_SUBimm,Info_T_NN, 0x1E0,0x01C,{0,FL_N|FL_Z|FL_C|FL_V}},
{Comp_T_LSLimm,Dis_T_LSLimm,Info_T_NN, 0x000,0x07C,{0,FL_N|FL_Z|FL_C}},
{Comp_T_LSRimm,Dis_T_LSRimm,Info_T_NN, 0x080,0x07C,{0,FL_N|FL_Z|FL_C}},
{Comp_T_ASRimm,Dis_T_ASRimm,Info_T_NN, 0x100,0x07C,{0,FL_N|FL_Z|FL_C}},
{Comp_T_MOVimm,Dis_T_MOVimm,Info_T_NN, 0x200,0x07C,{0,FL_N|FL_Z}},
{Comp_T_CMPimm,Dis_T_CMPimm,Info_T_NN, 0x280,0x07C,{0,FL_N|FL_Z|FL_C|FL_V}},
{Comp_T_ADDlim,Dis_T_ADDlim,Info_T_NN, 0x300,0x07C,{0,FL_N|FL_Z|FL_C|FL_V}},
{Comp_T_SUBlim,Dis_T_SUBlim,Info_T_NN, 0x380,0x07C,{0,FL_N|FL_Z|FL_C|FL_V}},
{Comp_T_ADDpc, Dis_T_ADDpc, Info_T_NN, 0xA00,0x07C,{0}}, // no flag change
{Comp_T_ADDsp, Dis_T_ADDsp, Info_T_NN, 0xA80,0x07C,{0}}, // no flag change
{Comp_T_STMIA, Dis_T_STMIA, Info_T_NN, 0xC00,0x07C,{0}},
{Comp_T_LDMIA, Dis_T_LDMIA, Info_T_NN, 0xC80,0x07C,{0}},
{Comp_T_ADDspi,Dis_T_ADDspi,Info_T_NN, 0xB00,0x004,{0}}, // no flag change
{Comp_T_SUBspi,Dis_T_SUBspi,Info_T_NN, 0xB08,0x004,{0}},
///stack
{Comp_T_POP, Dis_T_POP, Info_T_POP, 0xBC0,0x01C,{0}},
{Comp_T_PUSH, Dis_T_PUSH, Info_T_NN, 0xB40,0x01C,{0}},
///branch
{Comp_T_Bcond, Dis_T_Bcond, Info_T_NN, 0xD00,0x0FC,{FL_C|FL_N|FL_Z|FL_V,0,END_BASIC_BLOCK}},
{Comp_T_B, Dis_T_B, Info_T_NN, 0xE00,0x07C,{0,0,END_BASIC_BLOCK}},
{Comp_T_BX, Dis_T_BX, Info_T_NN, 0x470,0x004,{0,0,END_BASIC_BLOCK}},
{Comp_T_BLX, Dis_T_BLX, Info_T_NN, 0x478,0x004,{0,0,END_BASIC_BLOCK}},
{Comp_T_BLbig, Dis_T_BLend, Info_T_NN, 0xE80,0x07C,{0,0,END_BASIC_BLOCK}},
{Comp_T_BLbig, Dis_T_BLbig, Info_T_NN, 0xF00,0x07C,{0}}, //double instruction, handled in the first
{Comp_T_BLbig, Dis_T_BLend, Info_T_NN, 0xF80,0x07C,{0,0,END_BASIC_BLOCK}},
///loadstore
{Comp_T_LDRimm,Dis_T_LDRimm,Info_T_NN, 0x480,0x07C,{0}},
{Comp_T_LDR, Dis_T_LDR, Info_T_NN, 0x680,0x07C,{0}},
{Comp_T_LDRB, Dis_T_LDRB, Info_T_NN, 0x780,0x07C,{0}},
{Comp_T_LDRH, Dis_T_LDRH, Info_T_NN, 0x880,0x07C,{0}},
{Comp_T_LDRisp,Dis_T_LDRisp,Info_T_NN, 0x980,0x07C,{0}},
{Comp_T_STRrof,Dis_T_STRrof,Info_T_NN, 0x500,0x01C,{0}},
{Comp_T_STRHro,Dis_T_STRHro,Info_T_NN, 0x520,0x01C,{0}},
{Comp_T_STRBro,Dis_T_STRBro,Info_T_NN, 0x540,0x01C,{0}},
{Comp_T_LDRSB, Dis_T_LDRSB, Info_T_NN, 0x560,0x01C,{0}},
{Comp_T_LDRrof,Dis_T_LDRrof,Info_T_NN, 0x580,0x01C,{0}},
{Comp_T_LDRHro,Dis_T_LDRHro,Info_T_NN, 0x5A0,0x01C,{0}},
{Comp_T_LDRBro,Dis_T_LDRBro,Info_T_NN, 0x5C0,0x01C,{0}},
{Comp_T_LDRSH, Dis_T_LDRSH, Info_T_NN, 0x5E0,0x01C,{0}},
{Comp_T_STR, Dis_T_STR, Info_T_NN, 0x600,0x07C,{0}},
{Comp_T_STRB, Dis_T_STRB, Info_T_NN, 0x700,0x07C,{0}},
{Comp_T_STRH, Dis_T_STRH, Info_T_NN, 0x800,0x07C,{0}},
{Comp_T_STRisp,Dis_T_STRisp,Info_T_NN, 0x900,0x07C,{0}},
///Software interrupt
{Comp_T_SWI, Dis_T_SWI, Info_T_NN, 0xDF0,0x00C,{0,0,END_BASIC_BLOCK}},
};
struct ARMTableRow
{
ARMCompileFunc compile;
ARMDisFunc disasm;
ARMInfoFunc getinfo;
ARMInterpretFunc interpret;
InstructionInfo information;
};
struct THUMBTableRow
{
THUMBCompileFunc compile;
THUMBDisFunc disasm;
THUMBInfoFunc getinfo;
InstructionInfo information;
};
ARMTableRow atable[0x1000]; //arm table
THUMBTableRow ttable[0x400]; //thumb table
void FillARMTables()
{
for (int i=0; i:)
//this will only take max 1ms anyway..
for (int j=0; j<0x1000; j++)
{
if ((j & ~arminstructions[i].ignoredbits) == arminstructions[i].encoding)
{
atable[j].compile = arminstructions[i].compile;
atable[j].disasm = arminstructions[i].disasm;
atable[j].getinfo = arminstructions[i].getinfo;
atable[j].information = arminstructions[i].information;
atable[j].interpret = arminstructions[i].interpret;
}
}
}
for (int i=0; i<0x1000; i++)
{
if (atable[i].disasm==0)
{
atable[i].compile = Comp_Unimpl;
atable[i].disasm = Dis_Unknown;
atable[i].getinfo = Info_Unimpl;
//atable[i].information;
}
}
}
void FillThumbTables()
{
for (int i=0; i>2)) == (thumbinstructions[i].encoding>>2))
{
ttable[j].compile = thumbinstructions[i].compile;
ttable[j].disasm = thumbinstructions[i].disasm;
ttable[j].getinfo = thumbinstructions[i].getinfo;
ttable[j].information = thumbinstructions[i].information;
}
}
}
for (int i=0; i<0x400; i++)
{
if (ttable[i].disasm==0)
{
ttable[i].compile = Comp_T_Unimpl;
ttable[i].disasm = Dis_T_Unimpl;
ttable[i].getinfo = Info_T_Unimpl;
// ttable[i].information=0;
}
}
}
void ARMCompileOp(u32 op)
{
atable[CRUNCH_ARM_OP(op)].compile(op);
}
void ARMDisAsm(u32 op, u32 pc, char *out)
{
if (op == 0)
{
//ANDEQ R0,R0,R0 is probably not used for legitimate purposes :P
sprintf(out,"---\t---");
}
else
{
disPC = pc;
int crunch = CRUNCH_ARM_OP(op);
atable[crunch].disasm(op,out);
}
}
void ARMInterpret(u32 op) //only for those rare ones
{
if (atable[CRUNCH_ARM_OP(op)].interpret)
atable[CRUNCH_ARM_OP(op)].interpret(op);
else
_dbg_assert_msg_(CPU,0,"Trying to interpret instruction that can't be interpreted");
}
//flags required to evaluate a condition
u8 conditionFlags[16] =
{
FL_Z,
FL_Z,
FL_C,
FL_C,
FL_N,
FL_N,
FL_V,
FL_V,
FL_C|FL_Z,
FL_C|FL_Z,
FL_N|FL_V,
FL_N|FL_V,
FL_N|FL_V|FL_Z,
FL_N|FL_V|FL_Z,
0,
0
};
InstructionInfo ARMGetInfo(u32 op)
{
int crunch = CRUNCH_ARM_OP(op);
int cond = op>>28;
InstructionInfo info = atable[crunch].information;
info.flags |= atable[crunch].getinfo(op).flags;
if ((info.flags & UNCONDITIONAL) == 0)
info.flagsIn |= conditionFlags[cond];
info.cond=cond;
return info;
}
void THUMBCompileOp(u16 op)
{
ttable[CRUNCH_THUMB_OP(op)].compile(op);
}
void THUMBDisAsm(u16 op, u32 pc, char *out)
{
disPC = pc;
int crunch = CRUNCH_THUMB_OP(op);
ttable[crunch].disasm(op,out);
}
InstructionInfo THUMBGetInfo(u16 op)
{
int crunch = CRUNCH_THUMB_OP(op);
InstructionInfo info = ttable[crunch].information;
info.flags |= ttable[crunch].getinfo(op).flags;
info.cond = COND_AL;
return info;
}