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; 
}