Beginning Altivec disassembly/emitting.

This commit is contained in:
Ben Vanik 2013-09-28 09:14:04 -07:00
parent b0481472f2
commit f4f66ff7f1
11 changed files with 3078 additions and 36 deletions

View File

@ -18,6 +18,7 @@ namespace cpu {
namespace ppc { namespace ppc {
void RegisterDisasmCategoryAltivec();
void RegisterDisasmCategoryALU(); void RegisterDisasmCategoryALU();
void RegisterDisasmCategoryControl(); void RegisterDisasmCategoryControl();
void RegisterDisasmCategoryFPU(); void RegisterDisasmCategoryFPU();

File diff suppressed because it is too large Load Diff

View File

@ -350,11 +350,12 @@ void InstrDisasm::Dump(std::string& out_str, size_t pad) {
InstrType* xe::cpu::ppc::GetInstrType(uint32_t code) { InstrType* xe::cpu::ppc::GetInstrType(uint32_t code) {
// Fast lookup via tables.
InstrType* slot = NULL; InstrType* slot = NULL;
switch (code >> 26) { switch (code >> 26) {
case 4: case 4:
// Opcode = 4, index = bits 5-0 (6) // Opcode = 4, index = bits 11-0 (6)
slot = xe::cpu::ppc::tables::instr_table_4[XESELECTBITS(code, 0, 5)]; slot = xe::cpu::ppc::tables::instr_table_4[XESELECTBITS(code, 0, 11)];
break; break;
case 19: case 19:
// Opcode = 19, index = bits 10-1 (10) // Opcode = 19, index = bits 10-1 (10)
@ -390,10 +391,21 @@ InstrType* xe::cpu::ppc::GetInstrType(uint32_t code) {
slot = xe::cpu::ppc::tables::instr_table[XESELECTBITS(code, 26, 31)]; slot = xe::cpu::ppc::tables::instr_table[XESELECTBITS(code, 26, 31)];
break; break;
} }
if (!slot || !slot->opcode) { if (slot && slot->opcode) {
return NULL; return slot;
} }
return slot;
// Slow lookup via linear scan.
// This is primarily due to laziness. It could be made fast like the others.
for (size_t n = 0; n < XECOUNT(xe::cpu::ppc::tables::instr_table_vx128);
n++) {
slot = &(xe::cpu::ppc::tables::instr_table_vx128[n]);
if (slot->opcode == (code & slot->opcode_mask)) {
return slot;
}
}
return NULL;
} }
int xe::cpu::ppc::RegisterInstrDisassemble( int xe::cpu::ppc::RegisterInstrDisassemble(

View File

@ -23,26 +23,44 @@ namespace ppc {
// TODO(benvanik): rename these // TODO(benvanik): rename these
typedef enum { typedef enum {
kXEPPCInstrFormatI = 0, kXEPPCInstrFormatI = 0,
kXEPPCInstrFormatB = 1, kXEPPCInstrFormatB = 1,
kXEPPCInstrFormatSC = 2, kXEPPCInstrFormatSC = 2,
kXEPPCInstrFormatD = 3, kXEPPCInstrFormatD = 3,
kXEPPCInstrFormatDS = 4, kXEPPCInstrFormatDS = 4,
kXEPPCInstrFormatX = 5, kXEPPCInstrFormatX = 5,
kXEPPCInstrFormatXL = 6, kXEPPCInstrFormatXL = 6,
kXEPPCInstrFormatXFX = 7, kXEPPCInstrFormatXFX = 7,
kXEPPCInstrFormatXFL = 8, kXEPPCInstrFormatXFL = 8,
kXEPPCInstrFormatXS = 9, kXEPPCInstrFormatXS = 9,
kXEPPCInstrFormatXO = 10, kXEPPCInstrFormatXO = 10,
kXEPPCInstrFormatA = 11, kXEPPCInstrFormatA = 11,
kXEPPCInstrFormatM = 12, kXEPPCInstrFormatM = 12,
kXEPPCInstrFormatMD = 13, kXEPPCInstrFormatMD = 13,
kXEPPCInstrFormatMDS = 14, kXEPPCInstrFormatMDS = 14,
kXEPPCInstrFormatVA = 15, kXEPPCInstrFormatVXA = 15,
kXEPPCInstrFormatVX = 16, kXEPPCInstrFormatVX = 16,
kXEPPCInstrFormatVXR = 17, kXEPPCInstrFormatVXR = 17,
kXEPPCInstrFormatVX128 = 18,
kXEPPCInstrFormatVX128_1 = 19,
kXEPPCInstrFormatVX128_2 = 20,
kXEPPCInstrFormatVX128_3 = 21,
kXEPPCInstrFormatVX128_4 = 22,
kXEPPCInstrFormatVX128_5 = 23,
kXEPPCInstrFormatVX128_P = 24,
kXEPPCInstrFormatXDSS = 25,
} xe_ppc_instr_format_e; } xe_ppc_instr_format_e;
typedef enum {
kXEPPCInstrMaskVX128 = 0xFC0003D0,
kXEPPCInstrMaskVX128_1 = 0xFC0007F3,
kXEPPCInstrMaskVX128_2 = 0xFC000210,
kXEPPCInstrMaskVX128_3 = 0xFC0007F0,
kXEPPCInstrMaskVX128_4 = 0xFC000730,
kXEPPCInstrMaskVX128_5 = 0xFC000010,
kXEPPCInstrMaskVX128_P = 0xFC000630,
} xe_ppc_instr_mask_e;
typedef enum { typedef enum {
kXEPPCInstrTypeGeneral = (1 << 0), kXEPPCInstrTypeGeneral = (1 << 0),
kXEPPCInstrTypeBranch = (1 << 1), kXEPPCInstrTypeBranch = (1 << 1),
@ -212,9 +230,39 @@ typedef struct {
uint32_t RT : 5; uint32_t RT : 5;
uint32_t : 6; uint32_t : 6;
} MDS; } MDS;
// kXEPPCInstrFormatVA // kXEPPCInstrFormatVXA
struct {
} VXA;
// kXEPPCInstrFormatVX // kXEPPCInstrFormatVX
struct {
} VX;
// kXEPPCInstrFormatVXR // kXEPPCInstrFormatVXR
struct {
} VXR;
// kXEPPCInstrFormatVX128
struct {
} VX128;
// kXEPPCInstrFormatVX128_1
struct {
} VX128_1;
// kXEPPCInstrFormatVX128_2
struct {
} VX128_2;
// kXEPPCInstrFormatVX128_3
struct {
} VX128_3;
// kXEPPCInstrFormatVX128_4
struct {
} VX128_4;
// kXEPPCInstrFormatVX128_5
struct {
} VX128_5;
// kXEPPCInstrFormatVX128_P
struct {
} VX128_P;
// kXEPPCInstrFormatXDSS
struct {
} XDSS;
}; };
} InstrData; } InstrData;
@ -275,6 +323,7 @@ public:
uint64_t cr; // cr7/6/5/4/3/2/1/0 uint64_t cr; // cr7/6/5/4/3/2/1/0
uint64_t gpr; // r31-0 uint64_t gpr; // r31-0
uint64_t fpr; // f31-0 uint64_t fpr; // f31-0
// TODO(benvanik): vr128-0
void Clear(); void Clear();
void Extend(InstrAccessBits& other); void Extend(InstrAccessBits& other);
@ -286,11 +335,12 @@ public:
class InstrDisasm { class InstrDisasm {
public: public:
enum Flags { enum Flags {
kOE = 1 << 0, kOE = 1 << 0,
kRc = 1 << 1, kRc = 1 << 1,
kCA = 1 << 2, kCA = 1 << 2,
kLR = 1 << 4, kLR = 1 << 4,
kFP = 1 << 5, kFP = 1 << 5,
kVMX = 1 << 6,
}; };
const char* name; const char* name;
@ -321,9 +371,10 @@ typedef void* InstrEmitFn;
class InstrType { class InstrType {
public: public:
uint32_t opcode; uint32_t opcode;
uint32_t format; // xe_ppc_instr_format_e uint32_t opcode_mask; // Only used for certain opcodes (altivec, etc).
uint32_t type; // xe_ppc_instr_type_e uint32_t format; // xe_ppc_instr_format_e
uint32_t flags; // xe_ppc_instr_flag_e uint32_t type; // xe_ppc_instr_type_e
uint32_t flags; // xe_ppc_instr_flag_e
char name[16]; char name[16];
InstrDisassembleFn disassemble; InstrDisassembleFn disassemble;

View File

@ -53,6 +53,7 @@ static InstrType** instr_table_prep_63(
#define EMPTY(slot) {0} #define EMPTY(slot) {0}
#define INSTRUCTION(name, opcode, format, type, flag) { \ #define INSTRUCTION(name, opcode, format, type, flag) { \
opcode, \ opcode, \
0, \
kXEPPCInstrFormat##format, \ kXEPPCInstrFormat##format, \
kXEPPCInstrType##type, \ kXEPPCInstrType##type, \
flag, \ flag, \
@ -65,13 +66,169 @@ static InstrType** instr_table_prep_63(
// pem_64bit_v3.0.2005jul15.pdf, A.2 // pem_64bit_v3.0.2005jul15.pdf, A.2
// PowerISA_V2.06B_V2_PUBLIC.pdf // PowerISA_V2.06B_V2_PUBLIC.pdf
// Opcode = 4, index = bits 5-0 (6) // Opcode = 4, index = bits 11-0 (6)
static InstrType instr_table_4_unprep[] = { static InstrType instr_table_4_unprep[] = {
// TODO: all of the vector ops // TODO: all of the vector ops
INSTRUCTION(vperm, 0x1000002B, VA , General , 0), INSTRUCTION(mfvscr, 0x10000604, VX , General , 0),
INSTRUCTION(mtvscr, 0x10000644, VX , General , 0),
INSTRUCTION(vaddcuw, 0x10000180, VX , General , 0),
INSTRUCTION(vaddfp, 0x1000000A, VX , General , 0),
INSTRUCTION(vaddsbs, 0x10000300, VX , General , 0),
INSTRUCTION(vaddshs, 0x10000340, VX , General , 0),
INSTRUCTION(vaddsws, 0x10000380, VX , General , 0),
INSTRUCTION(vaddubm, 0x10000000, VX , General , 0),
INSTRUCTION(vaddubs, 0x10000200, VX , General , 0),
INSTRUCTION(vadduhm, 0x10000040, VX , General , 0),
INSTRUCTION(vadduhs, 0x10000240, VX , General , 0),
INSTRUCTION(vadduwm, 0x10000080, VX , General , 0),
INSTRUCTION(vadduws, 0x10000280, VX , General , 0),
INSTRUCTION(vand, 0x10000404, VX , General , 0),
INSTRUCTION(vandc, 0x10000444, VX , General , 0),
INSTRUCTION(vavgsb, 0x10000502, VX , General , 0),
INSTRUCTION(vavgsh, 0x10000542, VX , General , 0),
INSTRUCTION(vavgsw, 0x10000582, VX , General , 0),
INSTRUCTION(vavgub, 0x10000402, VX , General , 0),
INSTRUCTION(vavguh, 0x10000442, VX , General , 0),
INSTRUCTION(vavguw, 0x10000482, VX , General , 0),
INSTRUCTION(vcfsx, 0x1000034A, VX , General , 0),
INSTRUCTION(vcfux, 0x1000030A, VX , General , 0),
INSTRUCTION(vcmpbfp, 0x100003C6, VXR , General , 0),
INSTRUCTION(vcmpbfp_c, 0x100007C6, VXR , General , 0),
INSTRUCTION(vcmpeqfp, 0x100000C6, VXR , General , 0),
INSTRUCTION(vcmpeqfp_c, 0x100004C6, VXR , General , 0),
INSTRUCTION(vcmpequb, 0x10000006, VXR , General , 0),
INSTRUCTION(vcmpequb_c, 0x10000406, VXR , General , 0),
INSTRUCTION(vcmpequh, 0x10000046, VXR , General , 0),
INSTRUCTION(vcmpequh_c, 0x10000446, VXR , General , 0),
INSTRUCTION(vcmpequw, 0x10000086, VXR , General , 0),
INSTRUCTION(vcmpequw_c, 0x10000486, VXR , General , 0),
INSTRUCTION(vcmpgefp, 0x100001C6, VXR , General , 0),
INSTRUCTION(vcmpgefp_c, 0x100005C6, VXR , General , 0),
INSTRUCTION(vcmpgtfp, 0x100002C6, VXR , General , 0),
INSTRUCTION(vcmpgtfp_c, 0x100006C6, VXR , General , 0),
INSTRUCTION(vcmpgtsb, 0x10000306, VXR , General , 0),
INSTRUCTION(vcmpgtsb_c, 0x10000706, VXR , General , 0),
INSTRUCTION(vcmpgtsh, 0x10000346, VXR , General , 0),
INSTRUCTION(vcmpgtsh_c, 0x10000746, VXR , General , 0),
INSTRUCTION(vcmpgtsw, 0x10000386, VXR , General , 0),
INSTRUCTION(vcmpgtsw_c, 0x10000786, VXR , General , 0),
INSTRUCTION(vcmpgtub, 0x10000206, VXR , General , 0),
INSTRUCTION(vcmpgtub_c, 0x10000606, VXR , General , 0),
INSTRUCTION(vcmpgtuh, 0x10000246, VXR , General , 0),
INSTRUCTION(vcmpgtuh_c, 0x10000646, VXR , General , 0),
INSTRUCTION(vcmpgtuw, 0x10000286, VXR , General , 0),
INSTRUCTION(vcmpgtuw_c, 0x10000686, VXR , General , 0),
INSTRUCTION(vctsxs, 0x100003CA, VX , General , 0),
INSTRUCTION(vctuxs, 0x1000038A, VX , General , 0),
INSTRUCTION(vexptefp, 0x1000018A, VX , General , 0),
INSTRUCTION(vlogefp, 0x100001CA, VX , General , 0),
INSTRUCTION(vmaddfp, 0x1000002E, VXA , General , 0),
INSTRUCTION(vmaxfp, 0x1000040A, VX , General , 0),
INSTRUCTION(vmaxsb, 0x10000102, VX , General , 0),
INSTRUCTION(vmaxsh, 0x10000142, VX , General , 0),
INSTRUCTION(vmaxsw, 0x10000182, VX , General , 0),
INSTRUCTION(vmaxub, 0x10000002, VX , General , 0),
INSTRUCTION(vmaxuh, 0x10000042, VX , General , 0),
INSTRUCTION(vmaxuw, 0x10000082, VX , General , 0),
INSTRUCTION(vmhaddshs, 0x10000020, VXA , General , 0),
INSTRUCTION(vmhraddshs, 0x10000021, VXA , General , 0),
INSTRUCTION(vminfp, 0x1000044A, VX , General , 0),
INSTRUCTION(vminsb, 0x10000302, VX , General , 0),
INSTRUCTION(vminsh, 0x10000342, VX , General , 0),
INSTRUCTION(vminsw, 0x10000382, VX , General , 0),
INSTRUCTION(vminub, 0x10000202, VX , General , 0),
INSTRUCTION(vminuh, 0x10000242, VX , General , 0),
INSTRUCTION(vminuw, 0x10000282, VX , General , 0),
INSTRUCTION(vmladduhm, 0x10000022, VXA , General , 0),
INSTRUCTION(vmrghb, 0x1000000C, VX , General , 0),
INSTRUCTION(vmrghh, 0x1000004C, VX , General , 0),
INSTRUCTION(vmrghw, 0x1000008C, VX , General , 0),
INSTRUCTION(vmrglb, 0x1000010C, VX , General , 0),
INSTRUCTION(vmrglh, 0x1000014C, VX , General , 0),
INSTRUCTION(vmrglw, 0x1000018C, VX , General , 0),
INSTRUCTION(vmsummbm, 0x10000025, VXA , General , 0),
INSTRUCTION(vmsumshm, 0x10000028, VXA , General , 0),
INSTRUCTION(vmsumshs, 0x10000029, VXA , General , 0),
INSTRUCTION(vmsumubm, 0x10000024, VXA , General , 0),
INSTRUCTION(vmsumuhm, 0x10000026, VXA , General , 0),
INSTRUCTION(vmsumuhs, 0x10000027, VXA , General , 0),
INSTRUCTION(vmulesb, 0x10000308, VX , General , 0),
INSTRUCTION(vmulesh, 0x10000348, VX , General , 0),
INSTRUCTION(vmuleub, 0x10000208, VX , General , 0),
INSTRUCTION(vmuleuh, 0x10000248, VX , General , 0),
INSTRUCTION(vmulosb, 0x10000108, VX , General , 0),
INSTRUCTION(vmulosh, 0x10000148, VX , General , 0),
INSTRUCTION(vmuloub, 0x10000008, VX , General , 0),
INSTRUCTION(vmulouh, 0x10000048, VX , General , 0),
INSTRUCTION(vnmsubfp, 0x1000002F, VXA , General , 0),
INSTRUCTION(vnor, 0x10000504, VX , General , 0),
INSTRUCTION(vor, 0x10000484, VX , General , 0),
INSTRUCTION(vperm, 0x1000002B, VXA , General , 0),
INSTRUCTION(vpkpx, 0x1000030E, VX , General , 0),
INSTRUCTION(vpkshss, 0x1000018E, VX , General , 0),
INSTRUCTION(vpkshus, 0x1000010E, VX , General , 0),
INSTRUCTION(vpkswss, 0x100001CE, VX , General , 0),
INSTRUCTION(vpkswus, 0x1000014E, VX , General , 0),
INSTRUCTION(vpkuhum, 0x1000000E, VX , General , 0),
INSTRUCTION(vpkuhus, 0x1000008E, VX , General , 0),
INSTRUCTION(vpkuwum, 0x1000004E, VX , General , 0),
INSTRUCTION(vpkuwus, 0x100000CE, VX , General , 0),
INSTRUCTION(vrefp, 0x1000010A, VX , General , 0),
INSTRUCTION(vrfim, 0x100002CA, VX , General , 0),
INSTRUCTION(vrfin, 0x1000020A, VX , General , 0),
INSTRUCTION(vrfip, 0x1000028A, VX , General , 0),
INSTRUCTION(vrfiz, 0x1000024A, VX , General , 0),
INSTRUCTION(vrlb, 0x10000004, VX , General , 0),
INSTRUCTION(vrlh, 0x10000044, VX , General , 0),
INSTRUCTION(vrlw, 0x10000084, VX , General , 0),
INSTRUCTION(vrsqrtefp, 0x1000014A, VX , General , 0),
INSTRUCTION(vsel, 0x1000002A, VXA , General , 0),
INSTRUCTION(vsl, 0x100001C4, VX , General , 0),
INSTRUCTION(vslb, 0x10000104, VX , General , 0),
INSTRUCTION(vsldoi, 0x1000002C, VXA , General , 0),
INSTRUCTION(vslh, 0x10000144, VX , General , 0),
INSTRUCTION(vslo, 0x1000040C, VX , General , 0),
INSTRUCTION(vslw, 0x10000184, VX , General , 0),
INSTRUCTION(vspltb, 0x1000020C, VX , General , 0),
INSTRUCTION(vsplth, 0x1000024C, VX , General , 0),
INSTRUCTION(vspltisb, 0x1000030C, VX , General , 0),
INSTRUCTION(vspltish, 0x1000034C, VX , General , 0),
INSTRUCTION(vspltisw, 0x1000038C, VX , General , 0),
INSTRUCTION(vspltw, 0x1000028C, VX , General , 0),
INSTRUCTION(vsr, 0x100002C4, VX , General , 0),
INSTRUCTION(vsrab, 0x10000304, VX , General , 0),
INSTRUCTION(vsrah, 0x10000344, VX , General , 0),
INSTRUCTION(vsraw, 0x10000384, VX , General , 0),
INSTRUCTION(vsrb, 0x10000204, VX , General , 0),
INSTRUCTION(vsrh, 0x10000244, VX , General , 0),
INSTRUCTION(vsro, 0x1000044C, VX , General , 0),
INSTRUCTION(vsrw, 0x10000284, VX , General , 0),
INSTRUCTION(vsubcuw, 0x10000580, VX , General , 0),
INSTRUCTION(vsubfp, 0x1000004A, VX , General , 0),
INSTRUCTION(vsubsbs, 0x10000700, VX , General , 0),
INSTRUCTION(vsubshs, 0x10000740, VX , General , 0),
INSTRUCTION(vsubsws, 0x10000780, VX , General , 0),
INSTRUCTION(vsububm, 0x10000400, VX , General , 0),
INSTRUCTION(vsububs, 0x10000600, VX , General , 0),
INSTRUCTION(vsubuhm, 0x10000440, VX , General , 0),
INSTRUCTION(vsubuhs, 0x10000640, VX , General , 0),
INSTRUCTION(vsubuwm, 0x10000480, VX , General , 0),
INSTRUCTION(vsubuws, 0x10000680, VX , General , 0),
INSTRUCTION(vsumsws, 0x10000788, VX , General , 0),
INSTRUCTION(vsum2sws, 0x10000688, VX , General , 0),
INSTRUCTION(vsum4sbs, 0x10000708, VX , General , 0),
INSTRUCTION(vsum4shs, 0x10000648, VX , General , 0),
INSTRUCTION(vsum4ubs, 0x10000608, VX , General , 0),
INSTRUCTION(vupkhpx, 0x1000034E, VX , General , 0),
INSTRUCTION(vupkhsb, 0x1000020E, VX , General , 0),
INSTRUCTION(vupkhsh, 0x1000024E, VX , General , 0),
INSTRUCTION(vupklpx, 0x100003CE, VX , General , 0),
INSTRUCTION(vupklsb, 0x1000028E, VX , General , 0),
INSTRUCTION(vupklsh, 0x100002CE, VX , General , 0),
INSTRUCTION(vxor, 0x100004C4, VX , General , 0),
}; };
static InstrType** instr_table_4 = instr_table_prep( static InstrType** instr_table_4 = instr_table_prep(
instr_table_4_unprep, XECOUNT(instr_table_4_unprep), 0, 5); instr_table_4_unprep, XECOUNT(instr_table_4_unprep), 0, 11);
// Opcode = 19, index = bits 10-1 (10) // Opcode = 19, index = bits 10-1 (10)
static InstrType instr_table_19_unprep[] = { static InstrType instr_table_19_unprep[] = {
@ -115,7 +272,7 @@ static InstrType instr_table_31_unprep[] = {
INSTRUCTION(lvebx, 0x7C00000E, X , General , 0), INSTRUCTION(lvebx, 0x7C00000E, X , General , 0),
INSTRUCTION(subfcx, 0x7C000010, XO , General , 0), INSTRUCTION(subfcx, 0x7C000010, XO , General , 0),
INSTRUCTION(mulhdux, 0x7C000012, XO , General , 0), INSTRUCTION(mulhdux, 0x7C000012, XO , General , 0),
INSTRUCTION(addcx, 0X7C000014, XO , General , 0), INSTRUCTION(addcx, 0x7C000014, XO , General , 0),
INSTRUCTION(mulhwux, 0x7C000016, XO , General , 0), INSTRUCTION(mulhwux, 0x7C000016, XO , General , 0),
INSTRUCTION(mfcr, 0x7C000026, X , General , 0), INSTRUCTION(mfcr, 0x7C000026, X , General , 0),
INSTRUCTION(lwarx, 0x7C000028, X , General , 0), INSTRUCTION(lwarx, 0x7C000028, X , General , 0),
@ -229,6 +386,29 @@ static InstrType instr_table_31_unprep[] = {
INSTRUCTION(stfiwx, 0x7C0007AE, X , General , 0), INSTRUCTION(stfiwx, 0x7C0007AE, X , General , 0),
INSTRUCTION(extswx, 0x7C0007B4, X , General , 0), INSTRUCTION(extswx, 0x7C0007B4, X , General , 0),
INSTRUCTION(dcbz, 0x7C0007EC, X , General , 0), // 0x7C2007EC = DCBZ128 INSTRUCTION(dcbz, 0x7C0007EC, X , General , 0), // 0x7C2007EC = DCBZ128
INSTRUCTION(dst, 0x7C0002AC, XDSS, General , 0),
INSTRUCTION(dstst, 0x7C0002EC, XDSS, General , 0),
INSTRUCTION(dss, 0x7C00066C, XDSS, General , 0),
INSTRUCTION(lvebx, 0x7C00000E, X , General , 0),
INSTRUCTION(lvehx, 0x7C00004E, X , General , 0),
INSTRUCTION(lvewx, 0x7C00008E, X , General , 0),
INSTRUCTION(lvsl, 0x7C00000C, X , General , 0),
INSTRUCTION(lvsr, 0x7C00004C, X , General , 0),
INSTRUCTION(lvx, 0x7C0000CE, X , General , 0),
INSTRUCTION(lvxl, 0x7C0002CE, X , General , 0),
INSTRUCTION(stvebx, 0x7C00010E, X , General , 0),
INSTRUCTION(stvehx, 0x7C00014E, X , General , 0),
INSTRUCTION(stvewx, 0x7C00018E, X , General , 0),
INSTRUCTION(stvx, 0x7C0001CE, X , General , 0),
INSTRUCTION(stvxl, 0x7C0003CE, X , General , 0),
INSTRUCTION(lvlx, 0x7C00040E, X , General , 0),
INSTRUCTION(lvlxl, 0x7C00060E, X , General , 0),
INSTRUCTION(lvrx, 0x7C00044E, X , General , 0),
INSTRUCTION(lvrxl, 0x7C00064E, X , General , 0),
INSTRUCTION(stvlx, 0x7C00050E, X , General , 0),
INSTRUCTION(stvlxl, 0x7C00070E, X , General , 0),
INSTRUCTION(stvrx, 0x7C00054E, X , General , 0),
INSTRUCTION(stvrxl, 0x7C00074E, X , General , 0),
}; };
static InstrType** instr_table_31 = instr_table_prep( static InstrType** instr_table_31 = instr_table_prep(
instr_table_31_unprep, XECOUNT(instr_table_31_unprep), 1, 10); instr_table_31_unprep, XECOUNT(instr_table_31_unprep), 1, 10);
@ -355,6 +535,116 @@ static InstrType instr_table_unprep[64] = {
static InstrType** instr_table = instr_table_prep( static InstrType** instr_table = instr_table_prep(
instr_table_unprep, XECOUNT(instr_table_unprep), 26, 31); instr_table_unprep, XECOUNT(instr_table_unprep), 26, 31);
// Altivec instructions.
// TODO(benvanik): build a table like the other instructions.
// This table is looked up via linear scan of opcodes.
#define VX128_INSTRUCTION(name, opcode, format, type, flag) { \
opcode, \
kXEPPCInstrMask##format, \
kXEPPCInstrFormat##format, \
kXEPPCInstrType##type, \
flag, \
#name, \
}
#define OP(x) ((((uint32_t)(x)) & 0x3f) << 26)
#define VX128(op, xop) (OP(op) | (((uint32_t)(xop)) & 0x3d0))
#define VX128_1(op, xop) (OP(op) | (((uint32_t)(xop)) & 0x7f3))
#define VX128_2(op, xop) (OP(op) | (((uint32_t)(xop)) & 0x210))
#define VX128_3(op, xop) (OP(op) | (((uint32_t)(xop)) & 0x7f0))
#define VX128_4(op, xop) (OP(op) | (((uint32_t)(xop)) & 0x730))
#define VX128_5(op, xop) (OP(op) | (((uint32_t)(xop)) & 0x10))
#define VX128_P(op, xop) (OP(op) | (((uint32_t)(xop)) & 0x630))
static InstrType instr_table_vx128[] = {
VX128_INSTRUCTION(lvsl128, VX128_1(4, 3), VX128_1 , General , 0),
VX128_INSTRUCTION(lvsr128, VX128_1(4, 67), VX128_1 , General , 0),
VX128_INSTRUCTION(lvewx128, VX128_1(4, 131), VX128_1 , General , 0),
VX128_INSTRUCTION(lvx128, VX128_1(4, 195), VX128_1 , General , 0),
VX128_INSTRUCTION(stvewx128, VX128_1(4, 387), VX128_1 , General , 0),
VX128_INSTRUCTION(stvx128, VX128_1(4, 451), VX128_1 , General , 0),
VX128_INSTRUCTION(lvxl128, VX128_1(4, 707), VX128_1 , General , 0),
VX128_INSTRUCTION(stvxl128, VX128_1(4, 963), VX128_1 , General , 0),
VX128_INSTRUCTION(lvlx128, VX128_1(4, 1027), VX128_1 , General , 0),
VX128_INSTRUCTION(lvrx128, VX128_1(4, 1091), VX128_1 , General , 0),
VX128_INSTRUCTION(stvlx128, VX128_1(4, 1283), VX128_1 , General , 0),
VX128_INSTRUCTION(stvrx128, VX128_1(4, 1347), VX128_1 , General , 0),
VX128_INSTRUCTION(lvlxl128, VX128_1(4, 1539), VX128_1 , General , 0),
VX128_INSTRUCTION(lvrxl128, VX128_1(4, 1603), VX128_1 , General , 0),
VX128_INSTRUCTION(stvlxl128, VX128_1(4, 1795), VX128_1 , General , 0),
VX128_INSTRUCTION(stvrxl128, VX128_1(4, 1859), VX128_1 , General , 0),
VX128_INSTRUCTION(vsldoi128, VX128_5(4, 16), VX128_5 , General , 0),
VX128_INSTRUCTION(vperm128, VX128_2(5, 0), VX128_2 , General , 0),
VX128_INSTRUCTION(vaddfp128, VX128(5, 16), VX128 , General , 0),
VX128_INSTRUCTION(vsubfp128, VX128(5, 80), VX128 , General , 0),
VX128_INSTRUCTION(vmulfp128, VX128(5, 144), VX128 , General , 0),
VX128_INSTRUCTION(vmaddfp128, VX128(5, 208), VX128 , General , 0),
VX128_INSTRUCTION(vmaddcfp128, VX128(5, 272), VX128 , General , 0),
VX128_INSTRUCTION(vnmsubfp128, VX128(5, 336), VX128 , General , 0),
VX128_INSTRUCTION(vmsum3fp128, VX128(5, 400), VX128 , General , 0),
VX128_INSTRUCTION(vmsum4fp128, VX128(5, 464), VX128 , General , 0),
VX128_INSTRUCTION(vpkshss128, VX128(5, 512), VX128 , General , 0),
VX128_INSTRUCTION(vand128, VX128(5, 528), VX128 , General , 0),
VX128_INSTRUCTION(vpkshus128, VX128(5, 576), VX128 , General , 0),
VX128_INSTRUCTION(vandc128, VX128(5, 592), VX128 , General , 0),
VX128_INSTRUCTION(vpkswss128, VX128(5, 640), VX128 , General , 0),
VX128_INSTRUCTION(vnor128, VX128(5, 656), VX128 , General , 0),
VX128_INSTRUCTION(vpkswus128, VX128(5, 704), VX128 , General , 0),
VX128_INSTRUCTION(vor128, VX128(5, 720), VX128 , General , 0),
VX128_INSTRUCTION(vpkuhum128, VX128(5, 768), VX128 , General , 0),
VX128_INSTRUCTION(vxor128, VX128(5, 784), VX128 , General , 0),
VX128_INSTRUCTION(vpkuhus128, VX128(5, 832), VX128 , General , 0),
VX128_INSTRUCTION(vsel128, VX128(5, 848), VX128 , General , 0),
VX128_INSTRUCTION(vpkuwum128, VX128(5, 896), VX128 , General , 0),
VX128_INSTRUCTION(vslo128, VX128(5, 912), VX128 , General , 0),
VX128_INSTRUCTION(vpkuwus128, VX128(5, 960), VX128 , General , 0),
VX128_INSTRUCTION(vsro128, VX128(5, 976), VX128 , General , 0),
VX128_INSTRUCTION(vpermwi128, VX128_P(6, 528), VX128_P , General , 0),
VX128_INSTRUCTION(vcfpsxws128, VX128_3(6, 560), VX128_3 , General , 0),
VX128_INSTRUCTION(vcfpuxws128, VX128_3(6, 624), VX128_3 , General , 0),
VX128_INSTRUCTION(vcsxwfp128, VX128_3(6, 688), VX128_3 , General , 0),
VX128_INSTRUCTION(vcuxwfp128, VX128_3(6, 752), VX128_3 , General , 0),
VX128_INSTRUCTION(vrfim128, VX128_3(6, 816), VX128_3 , General , 0),
VX128_INSTRUCTION(vrfin128, VX128_3(6, 880), VX128_3 , General , 0),
VX128_INSTRUCTION(vrfip128, VX128_3(6, 944), VX128_3 , General , 0),
VX128_INSTRUCTION(vrfiz128, VX128_3(6, 1008), VX128_3 , General , 0),
VX128_INSTRUCTION(vpkd3d128, VX128_4(6, 1552), VX128_4 , General , 0),
VX128_INSTRUCTION(vrefp128, VX128_3(6, 1584), VX128_3 , General , 0),
VX128_INSTRUCTION(vrsqrtefp128, VX128_3(6, 1648), VX128_3 , General , 0),
VX128_INSTRUCTION(vexptefp128, VX128_3(6, 1712), VX128_3 , General , 0),
VX128_INSTRUCTION(vlogefp128, VX128_3(6, 1776), VX128_3 , General , 0),
VX128_INSTRUCTION(vrlimi128, VX128_4(6, 1808), VX128_4 , General , 0),
VX128_INSTRUCTION(vspltw128, VX128_3(6, 1840), VX128_3 , General , 0),
VX128_INSTRUCTION(vspltisw128, VX128_3(6, 1904), VX128_3 , General , 0),
VX128_INSTRUCTION(vupkd3d128, VX128_3(6, 2032), VX128_3 , General , 0),
VX128_INSTRUCTION(vcmpeqfp128, VX128(6, 0), VX128 , General , 0),
VX128_INSTRUCTION(vcmpeqfp128c, VX128(6, 64), VX128 , General , 0),
VX128_INSTRUCTION(vrlw128, VX128(6, 80), VX128 , General , 0),
VX128_INSTRUCTION(vcmpgefp128, VX128(6, 128), VX128 , General , 0),
VX128_INSTRUCTION(vcmpgefp128c, VX128(6, 192), VX128 , General , 0),
VX128_INSTRUCTION(vslw128, VX128(6, 208), VX128 , General , 0),
VX128_INSTRUCTION(vcmpgtfp128, VX128(6, 256), VX128 , General , 0),
VX128_INSTRUCTION(vcmpgtfp128c, VX128(6, 320), VX128 , General , 0),
VX128_INSTRUCTION(vsraw128, VX128(6, 336), VX128 , General , 0),
VX128_INSTRUCTION(vcmpbfp128, VX128(6, 384), VX128 , General , 0),
VX128_INSTRUCTION(vcmpbfp128c, VX128(6, 448), VX128 , General , 0),
VX128_INSTRUCTION(vsrw128, VX128(6, 464), VX128 , General , 0),
VX128_INSTRUCTION(vcmpequw128, VX128(6, 512), VX128 , General , 0),
VX128_INSTRUCTION(vcmpequw128c, VX128(6, 576), VX128 , General , 0),
VX128_INSTRUCTION(vmaxfp128, VX128(6, 640), VX128 , General , 0),
VX128_INSTRUCTION(vminfp128, VX128(6, 704), VX128 , General , 0),
VX128_INSTRUCTION(vmrghw128, VX128(6, 768), VX128 , General , 0),
VX128_INSTRUCTION(vmrglw128, VX128(6, 832), VX128 , General , 0),
VX128_INSTRUCTION(vupkhsb128, VX128(6, 896), VX128 , General , 0),
VX128_INSTRUCTION(vupklsb128, VX128(6, 960), VX128 , General , 0),
};
#undef OP
#undef VX128
#undef VX128_1
#undef VX128_2
#undef VX128_3
#undef VX128_4
#undef VX128_5
#undef VX128_P
#undef FLAG #undef FLAG
#undef INSTRUCTION #undef INSTRUCTION

View File

@ -2,6 +2,7 @@
{ {
'sources': [ 'sources': [
'disasm.h', 'disasm.h',
'disasm_altivec.cc',
'disasm_alu.cc', 'disasm_alu.cc',
'disasm_control.cc', 'disasm_control.cc',
'disasm_fpu.cc', 'disasm_fpu.cc',

View File

@ -31,6 +31,7 @@ namespace {
} }
has_initialized = true; has_initialized = true;
ppc::RegisterDisasmCategoryAltivec();
ppc::RegisterDisasmCategoryALU(); ppc::RegisterDisasmCategoryALU();
ppc::RegisterDisasmCategoryControl(); ppc::RegisterDisasmCategoryControl();
ppc::RegisterDisasmCategoryFPU(); ppc::RegisterDisasmCategoryFPU();

View File

@ -4,6 +4,7 @@
'x64_backend.cc', 'x64_backend.cc',
'x64_backend.h', 'x64_backend.h',
'x64_emit.h', 'x64_emit.h',
'x64_emit_altivec.cc',
'x64_emit_alu.cc', 'x64_emit_alu.cc',
'x64_emit_control.cc', 'x64_emit_control.cc',
'x64_emit_fpu.cc', 'x64_emit_fpu.cc',

View File

@ -31,6 +31,7 @@ namespace {
} }
has_initialized = true; has_initialized = true;
X64RegisterEmitCategoryAltivec();
X64RegisterEmitCategoryALU(); X64RegisterEmitCategoryALU();
X64RegisterEmitCategoryControl(); X64RegisterEmitCategoryControl();
X64RegisterEmitCategoryFPU(); X64RegisterEmitCategoryFPU();

View File

@ -20,6 +20,7 @@ namespace cpu {
namespace x64 { namespace x64 {
void X64RegisterEmitCategoryAltivec();
void X64RegisterEmitCategoryALU(); void X64RegisterEmitCategoryALU();
void X64RegisterEmitCategoryControl(); void X64RegisterEmitCategoryControl();
void X64RegisterEmitCategoryFPU(); void X64RegisterEmitCategoryFPU();

View File

@ -0,0 +1,39 @@
/*
******************************************************************************
* Xenia : Xbox 360 Emulator Research Project *
******************************************************************************
* Copyright 2013 Ben Vanik. All rights reserved. *
* Released under the BSD license - see LICENSE in the root for more details. *
******************************************************************************
*/
#include <xenia/cpu/x64/x64_emit.h>
#include <xenia/cpu/cpu-private.h>
using namespace xe::cpu;
using namespace xe::cpu::ppc;
using namespace AsmJit;
namespace xe {
namespace cpu {
namespace x64 {
// XEEMITTER(fnabsx, 0xFC000110, X )(X64Emitter& e, X86Compiler& c, InstrData& i) {
// XEINSTRNOTIMPLEMENTED();
// return 1;
// }
void X64RegisterEmitCategoryAltivec() {
// XEREGISTERINSTR(faddx, 0xFC00002A);
}
} // namespace x64
} // namespace cpu
} // namespace xe