Beginning Altivec disassembly/emitting.
This commit is contained in:
parent
b0481472f2
commit
f4f66ff7f1
|
@ -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
|
@ -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,12 +391,23 @@ 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(
|
||||||
uint32_t code, InstrDisassembleFn disassemble) {
|
uint32_t code, InstrDisassembleFn disassemble) {
|
||||||
InstrType* instr_type = GetInstrType(code);
|
InstrType* instr_type = GetInstrType(code);
|
||||||
|
|
|
@ -38,11 +38,29 @@ typedef enum {
|
||||||
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);
|
||||||
|
@ -291,6 +340,7 @@ public:
|
||||||
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,6 +371,7 @@ typedef void* InstrEmitFn;
|
||||||
class InstrType {
|
class InstrType {
|
||||||
public:
|
public:
|
||||||
uint32_t opcode;
|
uint32_t opcode;
|
||||||
|
uint32_t opcode_mask; // Only used for certain opcodes (altivec, etc).
|
||||||
uint32_t format; // xe_ppc_instr_format_e
|
uint32_t format; // xe_ppc_instr_format_e
|
||||||
uint32_t type; // xe_ppc_instr_type_e
|
uint32_t type; // xe_ppc_instr_type_e
|
||||||
uint32_t flags; // xe_ppc_instr_flag_e
|
uint32_t flags; // xe_ppc_instr_flag_e
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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',
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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',
|
||||||
|
|
|
@ -31,6 +31,7 @@ namespace {
|
||||||
}
|
}
|
||||||
has_initialized = true;
|
has_initialized = true;
|
||||||
|
|
||||||
|
X64RegisterEmitCategoryAltivec();
|
||||||
X64RegisterEmitCategoryALU();
|
X64RegisterEmitCategoryALU();
|
||||||
X64RegisterEmitCategoryControl();
|
X64RegisterEmitCategoryControl();
|
||||||
X64RegisterEmitCategoryFPU();
|
X64RegisterEmitCategoryFPU();
|
||||||
|
|
|
@ -20,6 +20,7 @@ namespace cpu {
|
||||||
namespace x64 {
|
namespace x64 {
|
||||||
|
|
||||||
|
|
||||||
|
void X64RegisterEmitCategoryAltivec();
|
||||||
void X64RegisterEmitCategoryALU();
|
void X64RegisterEmitCategoryALU();
|
||||||
void X64RegisterEmitCategoryControl();
|
void X64RegisterEmitCategoryControl();
|
||||||
void X64RegisterEmitCategoryFPU();
|
void X64RegisterEmitCategoryFPU();
|
||||||
|
|
|
@ -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
|
Loading…
Reference in New Issue