diff --git a/src/xenia/cpu/ppc/disasm_altivec.cc b/src/xenia/cpu/ppc/disasm_altivec.cc index c7f03932c..dc9569e56 100644 --- a/src/xenia/cpu/ppc/disasm_altivec.cc +++ b/src/xenia/cpu/ppc/disasm_altivec.cc @@ -33,6 +33,32 @@ namespace ppc { #define VX128_P(op, xop) (OP(op) | (((uint32_t)(xop)) & 0x630)) +namespace { + +int GeneralVX128(InstrData& i, InstrDisasm& d) { + const uint32_t vd = i.VX128.VD128l | (i.VX128.VD128h << 5); + const uint32_t va = i.VX128.VA128l | (i.VX128.VA128h << 5) | + (i.VX128.VA128H << 6); + const uint32_t vb = i.VX128.VB128l | (i.VX128.VB128h << 5); + d.AddRegOperand(InstrRegister::kVMX, vd, InstrRegister::kWrite); + d.AddRegOperand(InstrRegister::kVMX, va, InstrRegister::kRead); + d.AddRegOperand(InstrRegister::kVMX, vb, InstrRegister::kRead); + return d.Finish(); +} + +int GeneralVX128_3(InstrData& i, InstrDisasm& d) { + const uint32_t vd = i.VX128_3.VD128l | (i.VX128_3.VD128h << 5); + const uint32_t vb = i.VX128_3.VB128l | (i.VX128_3.VB128h << 5); + const uint32_t uimm = i.VX128_3.IMM; + d.AddRegOperand(InstrRegister::kVMX, vd, InstrRegister::kWrite); + d.AddRegOperand(InstrRegister::kVMX, vb, InstrRegister::kRead); + d.AddUImmOperand(uimm, 1); + return d.Finish(); +} + +} + + XEDISASMR(dst, 0x7C0002AC, XDSS)(InstrData& i, InstrDisasm& d) { d.Init("dst", "Data Stream Touch", InstrDisasm::kVMX); @@ -135,36 +161,54 @@ XEDISASMR(lvsr128, VX128_1(4, 67), VX128_1)(InstrData& i, InstrDisasm& XEDISASMR(lvx, 0x7C0000CE, X )(InstrData& i, InstrDisasm& d) { d.Init("lvx", "Load Vector Indexed", InstrDisasm::kVMX); - //d.AddRegOperand(InstrRegister::kVMX, i.VX.FRT, InstrRegister::kWrite); - //d.AddRegOperand(InstrRegister::kVMX, i.VX.FRA, InstrRegister::kRead); - //d.AddRegOperand(InstrRegister::kVMX, i.VX.FRB, InstrRegister::kRead); + d.AddRegOperand(InstrRegister::kVMX, i.X.RT, InstrRegister::kWrite); + if (i.X.RA) { + d.AddRegOperand(InstrRegister::kGPR, i.X.RA, InstrRegister::kRead); + } else { + d.AddUImmOperand(0, 1); + } + d.AddRegOperand(InstrRegister::kGPR, i.X.RB, InstrRegister::kRead); return d.Finish(); } XEDISASMR(lvx128, VX128_1(4, 195), VX128_1)(InstrData& i, InstrDisasm& d) { d.Init("lvx128", "Load Vector128 Indexed", InstrDisasm::kVMX); - //d.AddRegOperand(InstrRegister::kVMX, i.VX.FRT, InstrRegister::kWrite); - //d.AddRegOperand(InstrRegister::kVMX, i.VX.FRA, InstrRegister::kRead); - //d.AddRegOperand(InstrRegister::kVMX, i.VX.FRB, InstrRegister::kRead); + const uint32_t vd = i.VX128_1.VD128l | (i.VX128_1.VD128h << 5); + d.AddRegOperand(InstrRegister::kVMX, vd, InstrRegister::kWrite); + if (i.VX128_1.RA) { + d.AddRegOperand(InstrRegister::kGPR, i.VX128_1.RA, InstrRegister::kRead); + } else { + d.AddUImmOperand(0, 1); + } + d.AddRegOperand(InstrRegister::kGPR, i.VX128_1.RB, InstrRegister::kRead); return d.Finish(); } XEDISASMR(lvxl, 0x7C0002CE, X )(InstrData& i, InstrDisasm& d) { d.Init("lvxl", "Load Vector Indexed LRU", InstrDisasm::kVMX); - //d.AddRegOperand(InstrRegister::kVMX, i.VX.FRT, InstrRegister::kWrite); - //d.AddRegOperand(InstrRegister::kVMX, i.VX.FRA, InstrRegister::kRead); - //d.AddRegOperand(InstrRegister::kVMX, i.VX.FRB, InstrRegister::kRead); + d.AddRegOperand(InstrRegister::kVMX, i.X.RT, InstrRegister::kWrite); + if (i.X.RA) { + d.AddRegOperand(InstrRegister::kGPR, i.X.RA, InstrRegister::kRead); + } else { + d.AddUImmOperand(0, 1); + } + d.AddRegOperand(InstrRegister::kGPR, i.X.RB, InstrRegister::kRead); return d.Finish(); } XEDISASMR(lvxl128, VX128_1(4, 707), VX128_1)(InstrData& i, InstrDisasm& d) { d.Init("lvxl128", "Load Vector128 Left Indexed", InstrDisasm::kVMX); - //d.AddRegOperand(InstrRegister::kVMX, i.VX.FRT, InstrRegister::kWrite); - //d.AddRegOperand(InstrRegister::kVMX, i.VX.FRA, InstrRegister::kRead); - //d.AddRegOperand(InstrRegister::kVMX, i.VX.FRB, InstrRegister::kRead); + const uint32_t vd = i.VX128_1.VD128l | (i.VX128_1.VD128h << 5); + d.AddRegOperand(InstrRegister::kVMX, vd, InstrRegister::kWrite); + if (i.VX128_1.RA) { + d.AddRegOperand(InstrRegister::kGPR, i.VX128_1.RA, InstrRegister::kRead); + } else { + d.AddUImmOperand(0, 1); + } + d.AddRegOperand(InstrRegister::kGPR, i.VX128_1.RB, InstrRegister::kRead); return d.Finish(); } @@ -207,36 +251,54 @@ XEDISASMR(stvewx128, VX128_1(4, 387), VX128_1)(InstrData& i, InstrDisasm& XEDISASMR(stvx, 0x7C0001CE, X )(InstrData& i, InstrDisasm& d) { d.Init("stvx", "Store Vector Indexed", InstrDisasm::kVMX); - //d.AddRegOperand(InstrRegister::kVMX, i.VX.FRT, InstrRegister::kWrite); - //d.AddRegOperand(InstrRegister::kVMX, i.VX.FRA, InstrRegister::kRead); - //d.AddRegOperand(InstrRegister::kVMX, i.VX.FRB, InstrRegister::kRead); + d.AddRegOperand(InstrRegister::kVMX, i.X.RT, InstrRegister::kRead); + if (i.X.RA) { + d.AddRegOperand(InstrRegister::kGPR, i.X.RA, InstrRegister::kRead); + } else { + d.AddUImmOperand(0, 1); + } + d.AddRegOperand(InstrRegister::kGPR, i.X.RB, InstrRegister::kRead); return d.Finish(); } XEDISASMR(stvx128, VX128_1(4, 451), VX128_1)(InstrData& i, InstrDisasm& d) { d.Init("stvx128", "Store Vector128 Indexed", InstrDisasm::kVMX); - //d.AddRegOperand(InstrRegister::kVMX, i.VX.FRT, InstrRegister::kWrite); - //d.AddRegOperand(InstrRegister::kVMX, i.VX.FRA, InstrRegister::kRead); - //d.AddRegOperand(InstrRegister::kVMX, i.VX.FRB, InstrRegister::kRead); + const uint32_t vd = i.VX128_1.VD128l | (i.VX128_1.VD128h << 5); + d.AddRegOperand(InstrRegister::kVMX, vd, InstrRegister::kRead); + if (i.VX128_1.RA) { + d.AddRegOperand(InstrRegister::kGPR, i.VX128_1.RA, InstrRegister::kRead); + } else { + d.AddUImmOperand(0, 1); + } + d.AddRegOperand(InstrRegister::kGPR, i.VX128_1.RB, InstrRegister::kRead); return d.Finish(); } XEDISASMR(stvxl, 0x7C0003CE, X )(InstrData& i, InstrDisasm& d) { d.Init("stvxl", "Store Vector Indexed LRU", InstrDisasm::kVMX); - //d.AddRegOperand(InstrRegister::kVMX, i.VX.FRT, InstrRegister::kWrite); - //d.AddRegOperand(InstrRegister::kVMX, i.VX.FRA, InstrRegister::kRead); - //d.AddRegOperand(InstrRegister::kVMX, i.VX.FRB, InstrRegister::kRead); + d.AddRegOperand(InstrRegister::kVMX, i.X.RT, InstrRegister::kRead); + if (i.X.RA) { + d.AddRegOperand(InstrRegister::kGPR, i.X.RA, InstrRegister::kRead); + } else { + d.AddUImmOperand(0, 1); + } + d.AddRegOperand(InstrRegister::kGPR, i.X.RB, InstrRegister::kRead); return d.Finish(); } XEDISASMR(stvxl128, VX128_1(4, 963), VX128_1)(InstrData& i, InstrDisasm& d) { d.Init("stvxl128", "Store Vector128 Indexed LRU", InstrDisasm::kVMX); - //d.AddRegOperand(InstrRegister::kVMX, i.VX.FRT, InstrRegister::kWrite); - //d.AddRegOperand(InstrRegister::kVMX, i.VX.FRA, InstrRegister::kRead); - //d.AddRegOperand(InstrRegister::kVMX, i.VX.FRB, InstrRegister::kRead); + const uint32_t vd = i.VX128_1.VD128l | (i.VX128_1.VD128h << 5); + d.AddRegOperand(InstrRegister::kVMX, vd, InstrRegister::kRead); + if (i.VX128_1.RA) { + d.AddRegOperand(InstrRegister::kGPR, i.VX128_1.RA, InstrRegister::kRead); + } else { + d.AddUImmOperand(0, 1); + } + d.AddRegOperand(InstrRegister::kGPR, i.VX128_1.RB, InstrRegister::kRead); return d.Finish(); } @@ -513,19 +575,16 @@ XEDISASMR(vadduws, 0x10000280, VX )(InstrData& i, InstrDisasm& d) { XEDISASMR(vand, 0x10000404, VX )(InstrData& i, InstrDisasm& d) { d.Init("vand", "Vector Logical AND", InstrDisasm::kVMX); - //d.AddRegOperand(InstrRegister::kVMX, i.VX.FRT, InstrRegister::kWrite); - //d.AddRegOperand(InstrRegister::kVMX, i.VX.FRA, InstrRegister::kRead); - //d.AddRegOperand(InstrRegister::kVMX, i.VX.FRB, InstrRegister::kRead); + // d.AddRegOperand(InstrRegister::kVMX, i.VX.VD, InstrRegister::kWrite); + // d.AddRegOperand(InstrRegister::kVMX, i.VX.VA, InstrRegister::kRead); + // d.AddRegOperand(InstrRegister::kVMX, i.VX.VB, InstrRegister::kRead); return d.Finish(); } XEDISASMR(vand128, VX128(5, 528), VX128 )(InstrData& i, InstrDisasm& d) { d.Init("vand128", "Vector128 Logical AND", InstrDisasm::kVMX); - //d.AddRegOperand(InstrRegister::kVMX, i.VX.FRT, InstrRegister::kWrite); - //d.AddRegOperand(InstrRegister::kVMX, i.VX.FRA, InstrRegister::kRead); - //d.AddRegOperand(InstrRegister::kVMX, i.VX.FRB, InstrRegister::kRead); - return d.Finish(); + return GeneralVX128(i, d); } XEDISASMR(vandc, 0x10000444, VX )(InstrData& i, InstrDisasm& d) { @@ -540,10 +599,7 @@ XEDISASMR(vandc, 0x10000444, VX )(InstrData& i, InstrDisasm& d) { XEDISASMR(vandc128, VX128(5, 592), VX128 )(InstrData& i, InstrDisasm& d) { d.Init("vandc128", "Vector128 Logical AND with Complement", InstrDisasm::kVMX); - //d.AddRegOperand(InstrRegister::kVMX, i.VX.FRT, InstrRegister::kWrite); - //d.AddRegOperand(InstrRegister::kVMX, i.VX.FRA, InstrRegister::kRead); - //d.AddRegOperand(InstrRegister::kVMX, i.VX.FRB, InstrRegister::kRead); - return d.Finish(); + return GeneralVX128(i, d); } XEDISASMR(vavgsb, 0x10000502, VX )(InstrData& i, InstrDisasm& d) { @@ -612,19 +668,13 @@ XEDISASMR(vcfsx, 0x1000034A, VX )(InstrData& i, InstrDisasm& d) { XEDISASMR(vcsxwfp128, VX128_3(6, 688), VX128_3)(InstrData& i, InstrDisasm& d) { d.Init("vcsxwfp128", "Vector128 Convert From Signed Fixed-Point Word to Floating-Point", InstrDisasm::kVMX); - //d.AddRegOperand(InstrRegister::kVMX, i.VX.FRT, InstrRegister::kWrite); - //d.AddRegOperand(InstrRegister::kVMX, i.VX.FRA, InstrRegister::kRead); - //d.AddRegOperand(InstrRegister::kVMX, i.VX.FRB, InstrRegister::kRead); - return d.Finish(); + return GeneralVX128_3(i, d); } XEDISASMR(vcfpsxws128, VX128_3(6, 560), VX128_3)(InstrData& i, InstrDisasm& d) { d.Init("vcfpsxws128", "Vector128 Convert From Floating-Point to Signed Fixed-Point Word Saturate", InstrDisasm::kVMX); - //d.AddRegOperand(InstrRegister::kVMX, i.VX.FRT, InstrRegister::kWrite); - //d.AddRegOperand(InstrRegister::kVMX, i.VX.FRA, InstrRegister::kRead); - //d.AddRegOperand(InstrRegister::kVMX, i.VX.FRB, InstrRegister::kRead); - return d.Finish(); + return GeneralVX128_3(i, d); } XEDISASMR(vcfux, 0x1000030A, VX )(InstrData& i, InstrDisasm& d) { @@ -702,19 +752,13 @@ XEDISASMR(vcmpeqfp, 0x100000C6, VXR )(InstrData& i, InstrDisasm& d) { XEDISASMR(vcmpeqfp128, VX128(6, 0), VX128 )(InstrData& i, InstrDisasm& d) { d.Init("vcmpeqfp128", "Vector128 Compare Equal-to Floating Point", InstrDisasm::kVMX); - //d.AddRegOperand(InstrRegister::kVMX, i.VX.FRT, InstrRegister::kWrite); - //d.AddRegOperand(InstrRegister::kVMX, i.VX.FRA, InstrRegister::kRead); - //d.AddRegOperand(InstrRegister::kVMX, i.VX.FRB, InstrRegister::kRead); - return d.Finish(); + return GeneralVX128(i, d); } XEDISASMR(vcmpeqfp_c, 0x100004C6, VXR )(InstrData& i, InstrDisasm& d) { d.Init("vcmpeqfp", "Vector Compare Equal-to Floating Point", InstrDisasm::kVMX | InstrDisasm::kRc); - //d.AddRegOperand(InstrRegister::kVMX, i.VX.FRT, InstrRegister::kWrite); - //d.AddRegOperand(InstrRegister::kVMX, i.VX.FRA, InstrRegister::kRead); - //d.AddRegOperand(InstrRegister::kVMX, i.VX.FRB, InstrRegister::kRead); - return d.Finish(); + return GeneralVX128(i, d); } XEDISASMR(vcmpeqfp128c, VX128(6, 64), VX128 )(InstrData& i, InstrDisasm& d) { @@ -774,10 +818,7 @@ XEDISASMR(vcmpequw, 0x10000086, VXR )(InstrData& i, InstrDisasm& d) { XEDISASMR(vcmpequw128, VX128(6, 512), VX128 )(InstrData& i, InstrDisasm& d) { d.Init("vcmpequw128", "Vector128 Compare Equal-to Unsigned Word", InstrDisasm::kVMX); - //d.AddRegOperand(InstrRegister::kVMX, i.VX.FRT, InstrRegister::kWrite); - //d.AddRegOperand(InstrRegister::kVMX, i.VX.FRA, InstrRegister::kRead); - //d.AddRegOperand(InstrRegister::kVMX, i.VX.FRB, InstrRegister::kRead); - return d.Finish(); + return GeneralVX128(i, d); } XEDISASMR(vcmpequw_c, 0x10000486, VXR )(InstrData& i, InstrDisasm& d) { @@ -792,10 +833,7 @@ XEDISASMR(vcmpequw_c, 0x10000486, VXR )(InstrData& i, InstrDisasm& d) { XEDISASMR(vcmpequw128c, VX128(6, 576), VX128 )(InstrData& i, InstrDisasm& d) { d.Init("vcmpequw128", "Vector Compare Equal-to Unsigned Word", InstrDisasm::kVMX | InstrDisasm::kRc); - //d.AddRegOperand(InstrRegister::kVMX, i.VX.FRT, InstrRegister::kWrite); - //d.AddRegOperand(InstrRegister::kVMX, i.VX.FRA, InstrRegister::kRead); - //d.AddRegOperand(InstrRegister::kVMX, i.VX.FRB, InstrRegister::kRead); - return d.Finish(); + return GeneralVX128(i, d); } XEDISASMR(vcmpgefp, 0x100001C6, VXR )(InstrData& i, InstrDisasm& d) { @@ -1035,27 +1073,38 @@ XEDISASMR(vlogefp128, VX128_3(6, 1776), VX128_3)(InstrData& i, InstrDisasm& XEDISASMR(vmaddfp, 0x1000002E, VXA )(InstrData& i, InstrDisasm& d) { d.Init("vmaddfp", "Vector Multiply-Add Floating Point", InstrDisasm::kVMX); - //d.AddRegOperand(InstrRegister::kVMX, i.VX.FRT, InstrRegister::kWrite); - //d.AddRegOperand(InstrRegister::kVMX, i.VX.FRA, InstrRegister::kRead); - //d.AddRegOperand(InstrRegister::kVMX, i.VX.FRB, InstrRegister::kRead); + d.AddRegOperand(InstrRegister::kVMX, i.VXA.VD, InstrRegister::kWrite); + d.AddRegOperand(InstrRegister::kVMX, i.VXA.VA, InstrRegister::kRead); + d.AddRegOperand(InstrRegister::kVMX, i.VXA.VC, InstrRegister::kRead); + d.AddRegOperand(InstrRegister::kVMX, i.VXA.VB, InstrRegister::kRead); return d.Finish(); } XEDISASMR(vmaddfp128, VX128(5, 208), VX128 )(InstrData& i, InstrDisasm& d) { d.Init("vmaddfp128", "Vector128 Multiply Add Floating Point", InstrDisasm::kVMX); - //d.AddRegOperand(InstrRegister::kVMX, i.VX.FRT, InstrRegister::kWrite); - //d.AddRegOperand(InstrRegister::kVMX, i.VX.FRA, InstrRegister::kRead); - //d.AddRegOperand(InstrRegister::kVMX, i.VX.FRB, InstrRegister::kRead); + const uint32_t vd = i.VX128.VD128l | (i.VX128.VD128h << 5); + const uint32_t va = i.VX128.VA128l | (i.VX128.VA128h << 5) | + (i.VX128.VA128H << 6); + const uint32_t vb = i.VX128.VB128l | (i.VX128.VB128h << 5); + d.AddRegOperand(InstrRegister::kVMX, vd, InstrRegister::kWrite); + d.AddRegOperand(InstrRegister::kVMX, va, InstrRegister::kRead); + d.AddRegOperand(InstrRegister::kVMX, vb, InstrRegister::kRead); + d.AddRegOperand(InstrRegister::kVMX, vd, InstrRegister::kRead); return d.Finish(); } XEDISASMR(vmaddcfp128, VX128(5, 272), VX128 )(InstrData& i, InstrDisasm& d) { d.Init("vmaddcfp128", "Vector128 Multiply Add Floating Point", InstrDisasm::kVMX); - //d.AddRegOperand(InstrRegister::kVMX, i.VX.FRT, InstrRegister::kWrite); - //d.AddRegOperand(InstrRegister::kVMX, i.VX.FRA, InstrRegister::kRead); - //d.AddRegOperand(InstrRegister::kVMX, i.VX.FRB, InstrRegister::kRead); + const uint32_t vd = i.VX128.VD128l | (i.VX128.VD128h << 5); + const uint32_t va = i.VX128.VA128l | (i.VX128.VA128h << 5) | + (i.VX128.VA128H << 6); + const uint32_t vb = i.VX128.VB128l | (i.VX128.VB128h << 5); + d.AddRegOperand(InstrRegister::kVMX, vd, InstrRegister::kWrite); + d.AddRegOperand(InstrRegister::kVMX, va, InstrRegister::kRead); + d.AddRegOperand(InstrRegister::kVMX, vd, InstrRegister::kRead); + d.AddRegOperand(InstrRegister::kVMX, vb, InstrRegister::kRead); return d.Finish(); } @@ -1260,10 +1309,7 @@ XEDISASMR(vmrghw, 0x1000008C, VX )(InstrData& i, InstrDisasm& d) { XEDISASMR(vmrghw128, VX128(6, 768), VX128 )(InstrData& i, InstrDisasm& d) { d.Init("vmrghw128", "Vector128 Merge High Word", InstrDisasm::kVMX); - //d.AddRegOperand(InstrRegister::kVMX, i.VX.FRT, InstrRegister::kWrite); - //d.AddRegOperand(InstrRegister::kVMX, i.VX.FRA, InstrRegister::kRead); - //d.AddRegOperand(InstrRegister::kVMX, i.VX.FRB, InstrRegister::kRead); - return d.Finish(); + return GeneralVX128(i, d); } XEDISASMR(vmrglb, 0x1000010C, VX )(InstrData& i, InstrDisasm& d) { @@ -1296,10 +1342,7 @@ XEDISASMR(vmrglw, 0x1000018C, VX )(InstrData& i, InstrDisasm& d) { XEDISASMR(vmrglw128, VX128(6, 832), VX128 )(InstrData& i, InstrDisasm& d) { d.Init("vmrglw128", "Vector128 Merge Low Word", InstrDisasm::kVMX); - //d.AddRegOperand(InstrRegister::kVMX, i.VX.FRT, InstrRegister::kWrite); - //d.AddRegOperand(InstrRegister::kVMX, i.VX.FRA, InstrRegister::kRead); - //d.AddRegOperand(InstrRegister::kVMX, i.VX.FRB, InstrRegister::kRead); - return d.Finish(); + return GeneralVX128(i, d); } XEDISASMR(vmsummbm, 0x10000025, VXA )(InstrData& i, InstrDisasm& d) { @@ -1359,19 +1402,13 @@ XEDISASMR(vmsumuhs, 0x10000027, VXA )(InstrData& i, InstrDisasm& d) { XEDISASMR(vmsum3fp128, VX128(5, 400), VX128 )(InstrData& i, InstrDisasm& d) { d.Init("vmsum3fp128", "Vector128 Multiply Sum 3-way Floating Point", InstrDisasm::kVMX); - //d.AddRegOperand(InstrRegister::kVMX, i.VX.FRT, InstrRegister::kWrite); - //d.AddRegOperand(InstrRegister::kVMX, i.VX.FRA, InstrRegister::kRead); - //d.AddRegOperand(InstrRegister::kVMX, i.VX.FRB, InstrRegister::kRead); - return d.Finish(); + return GeneralVX128(i, d); } XEDISASMR(vmsum4fp128, VX128(5, 464), VX128 )(InstrData& i, InstrDisasm& d) { d.Init("vmsum4fp128", "Vector128 Multiply Sum 4-way Floating-Point", InstrDisasm::kVMX); - //d.AddRegOperand(InstrRegister::kVMX, i.VX.FRT, InstrRegister::kWrite); - //d.AddRegOperand(InstrRegister::kVMX, i.VX.FRA, InstrRegister::kRead); - //d.AddRegOperand(InstrRegister::kVMX, i.VX.FRB, InstrRegister::kRead); - return d.Finish(); + return GeneralVX128(i, d); } XEDISASMR(vmulesb, 0x10000308, VX )(InstrData& i, InstrDisasm& d) { @@ -1449,10 +1486,7 @@ XEDISASMR(vmulouh, 0x10000048, VX )(InstrData& i, InstrDisasm& d) { XEDISASMR(vmulfp128, VX128(5, 144), VX128 )(InstrData& i, InstrDisasm& d) { d.Init("vmulfp128", "Vector128 Multiply Floating-Point", InstrDisasm::kVMX); - //d.AddRegOperand(InstrRegister::kVMX, i.VX.FRT, InstrRegister::kWrite); - //d.AddRegOperand(InstrRegister::kVMX, i.VX.FRA, InstrRegister::kRead); - //d.AddRegOperand(InstrRegister::kVMX, i.VX.FRB, InstrRegister::kRead); - return d.Finish(); + return GeneralVX128(i, d); } XEDISASMR(vnmsubfp, 0x1000002F, VXA )(InstrData& i, InstrDisasm& d) { @@ -1503,10 +1537,7 @@ XEDISASMR(vor, 0x10000484, VX )(InstrData& i, InstrDisasm& d) { XEDISASMR(vor128, VX128(5, 720), VX128 )(InstrData& i, InstrDisasm& d) { d.Init("vor128", "Vector128 Logical OR", InstrDisasm::kVMX); - //d.AddRegOperand(InstrRegister::kVMX, i.VX.FRT, InstrRegister::kWrite); - //d.AddRegOperand(InstrRegister::kVMX, i.VX.FRA, InstrRegister::kRead); - //d.AddRegOperand(InstrRegister::kVMX, i.VX.FRB, InstrRegister::kRead); - return d.Finish(); + return GeneralVX128(i, d); } XEDISASMR(vperm, 0x1000002B, VXA )(InstrData& i, InstrDisasm& d) { @@ -1521,18 +1552,25 @@ XEDISASMR(vperm, 0x1000002B, VXA )(InstrData& i, InstrDisasm& d) { XEDISASMR(vperm128, VX128_2(5, 0), VX128_2)(InstrData& i, InstrDisasm& d) { d.Init("vperm128", "Vector128 Permute", InstrDisasm::kVMX); - //d.AddRegOperand(InstrRegister::kVMX, i.VX.FRT, InstrRegister::kWrite); - //d.AddRegOperand(InstrRegister::kVMX, i.VX.FRA, InstrRegister::kRead); - //d.AddRegOperand(InstrRegister::kVMX, i.VX.FRB, InstrRegister::kRead); + const uint32_t vd = i.VX128_2.VD128l | (i.VX128_2.VD128h << 5); + const uint32_t va = i.VX128_2.VA128l | (i.VX128_2.VA128h << 5) | + (i.VX128_2.VA128H << 6); + const uint32_t vb = i.VX128_2.VB128l | (i.VX128_2.VB128h << 5); + d.AddRegOperand(InstrRegister::kVMX, vd, InstrRegister::kWrite); + d.AddRegOperand(InstrRegister::kVMX, va, InstrRegister::kRead); + d.AddRegOperand(InstrRegister::kVMX, vb, InstrRegister::kRead); + d.AddRegOperand(InstrRegister::kVMX, i.VX128_2.VC, InstrRegister::kRead); return d.Finish(); } XEDISASMR(vpermwi128, VX128_P(6, 528), VX128_P)(InstrData& i, InstrDisasm& d) { d.Init("vpermwi128", "Vector128 Permutate Word Immediate", InstrDisasm::kVMX); - //d.AddRegOperand(InstrRegister::kVMX, i.VX.FRT, InstrRegister::kWrite); - //d.AddRegOperand(InstrRegister::kVMX, i.VX.FRA, InstrRegister::kRead); - //d.AddRegOperand(InstrRegister::kVMX, i.VX.FRB, InstrRegister::kRead); + const uint32_t vd = i.VX128_P.VD128l | (i.VX128_P.VD128h << 5); + const uint32_t vb = i.VX128_P.VB128l | (i.VX128_P.VB128h << 5); + d.AddRegOperand(InstrRegister::kVMX, vd, InstrRegister::kWrite); + d.AddRegOperand(InstrRegister::kVMX, vb, InstrRegister::kRead); + d.AddUImmOperand(i.VX128_P.PERMl | (i.VX128_P.PERMh << 5), 1); return d.Finish(); } @@ -1827,9 +1865,12 @@ XEDISASMR(vrlw128, VX128(6, 80), VX128 )(InstrData& i, InstrDisasm& XEDISASMR(vrlimi128, VX128_4(6, 1808), VX128_4)(InstrData& i, InstrDisasm& d) { d.Init("vrlimi128", "Vector128 Rotate Left Immediate and Mask Insert", InstrDisasm::kVMX); - //d.AddRegOperand(InstrRegister::kVMX, i.VX.FRT, InstrRegister::kWrite); - //d.AddRegOperand(InstrRegister::kVMX, i.VX.FRA, InstrRegister::kRead); - //d.AddRegOperand(InstrRegister::kVMX, i.VX.FRB, InstrRegister::kRead); + const uint32_t vd = i.VX128_4.VD128l | (i.VX128_4.VD128h << 5); + const uint32_t vb = i.VX128_4.VB128l | (i.VX128_4.VB128h << 5); + d.AddRegOperand(InstrRegister::kVMX, vd, InstrRegister::kWrite); + d.AddRegOperand(InstrRegister::kVMX, vb, InstrRegister::kRead); + d.AddUImmOperand(i.VX128_4.IMM, 1); + d.AddUImmOperand(i.VX128_4.z, 1); return d.Finish(); } @@ -1845,9 +1886,10 @@ XEDISASMR(vrsqrtefp, 0x1000014A, VX )(InstrData& i, InstrDisasm& d) { XEDISASMR(vrsqrtefp128, VX128_3(6, 1648), VX128_3)(InstrData& i, InstrDisasm& d) { d.Init("vrsqrtefp128", "Vector128 Reciprocal Square Root Estimate Floating Point", InstrDisasm::kVMX); - //d.AddRegOperand(InstrRegister::kVMX, i.VX.FRT, InstrRegister::kWrite); - //d.AddRegOperand(InstrRegister::kVMX, i.VX.FRA, InstrRegister::kRead); - //d.AddRegOperand(InstrRegister::kVMX, i.VX.FRB, InstrRegister::kRead); + const uint32_t vd = i.VX128_3.VD128l | (i.VX128_3.VD128h << 5); + const uint32_t vb = i.VX128_3.VB128l | (i.VX128_3.VB128h << 5); + d.AddRegOperand(InstrRegister::kVMX, vd, InstrRegister::kWrite); + d.AddRegOperand(InstrRegister::kVMX, vb, InstrRegister::kRead); return d.Finish(); } @@ -1944,10 +1986,7 @@ XEDISASMR(vslw, 0x10000184, VX )(InstrData& i, InstrDisasm& d) { XEDISASMR(vslw128, VX128(6, 208), VX128 )(InstrData& i, InstrDisasm& d) { d.Init("vslw128", "Vector128 Shift Left Integer Word", InstrDisasm::kVMX); - //d.AddRegOperand(InstrRegister::kVMX, i.VX.FRT, InstrRegister::kWrite); - //d.AddRegOperand(InstrRegister::kVMX, i.VX.FRA, InstrRegister::kRead); - //d.AddRegOperand(InstrRegister::kVMX, i.VX.FRB, InstrRegister::kRead); - return d.Finish(); + return GeneralVX128(i, d); } XEDISASMR(vspltb, 0x1000020C, VX )(InstrData& i, InstrDisasm& d) { @@ -1998,10 +2037,7 @@ XEDISASMR(vspltisw, 0x1000038C, VX )(InstrData& i, InstrDisasm& d) { XEDISASMR(vspltisw128, VX128_3(6, 1904), VX128_3)(InstrData& i, InstrDisasm& d) { d.Init("vspltisw128", "Vector128 Splat Immediate Signed Word", InstrDisasm::kVMX); - //d.AddRegOperand(InstrRegister::kVMX, i.VX.FRT, InstrRegister::kWrite); - //d.AddRegOperand(InstrRegister::kVMX, i.VX.FRA, InstrRegister::kRead); - //d.AddRegOperand(InstrRegister::kVMX, i.VX.FRB, InstrRegister::kRead); - return d.Finish(); + return GeneralVX128_3(i, d); } XEDISASMR(vspltw, 0x1000028C, VX )(InstrData& i, InstrDisasm& d) { @@ -2016,10 +2052,7 @@ XEDISASMR(vspltw, 0x1000028C, VX )(InstrData& i, InstrDisasm& d) { XEDISASMR(vspltw128, VX128_3(6, 1840), VX128_3)(InstrData& i, InstrDisasm& d) { d.Init("vspltw128", " Vector128 Splat Word", InstrDisasm::kVMX); - //d.AddRegOperand(InstrRegister::kVMX, i.VX.FRT, InstrRegister::kWrite); - //d.AddRegOperand(InstrRegister::kVMX, i.VX.FRA, InstrRegister::kRead); - //d.AddRegOperand(InstrRegister::kVMX, i.VX.FRB, InstrRegister::kRead); - return d.Finish(); + return GeneralVX128_3(i, d); } XEDISASMR(vsr, 0x100002C4, VX )(InstrData& i, InstrDisasm& d) { @@ -2142,10 +2175,7 @@ XEDISASMR(vsubfp, 0x1000004A, VX )(InstrData& i, InstrDisasm& d) { XEDISASMR(vsubfp128, VX128(5, 80), VX128 )(InstrData& i, InstrDisasm& d) { d.Init("vsubfp128", "Vector128 Subtract Floating Point", InstrDisasm::kVMX); - //d.AddRegOperand(InstrRegister::kVMX, i.VX.FRT, InstrRegister::kWrite); - //d.AddRegOperand(InstrRegister::kVMX, i.VX.FRA, InstrRegister::kRead); - //d.AddRegOperand(InstrRegister::kVMX, i.VX.FRB, InstrRegister::kRead); - return d.Finish(); + return GeneralVX128(i, d); } XEDISASMR(vsubsbs, 0x10000700, VX )(InstrData& i, InstrDisasm& d) { @@ -2349,9 +2379,11 @@ XEDISASMR(vupklsh, 0x100002CE, VX )(InstrData& i, InstrDisasm& d) { XEDISASMR(vupkd3d128, VX128_3(6, 2032), VX128_3)(InstrData& i, InstrDisasm& d) { d.Init("vupkd3d128", "Vector128 Unpack D3Dtype", InstrDisasm::kVMX); - //d.AddRegOperand(InstrRegister::kVMX, i.VX.FRT, InstrRegister::kWrite); - //d.AddRegOperand(InstrRegister::kVMX, i.VX.FRA, InstrRegister::kRead); - //d.AddRegOperand(InstrRegister::kVMX, i.VX.FRB, InstrRegister::kRead); + const uint32_t vd = i.VX128_3.VD128l | (i.VX128_3.VD128h << 5); + const uint32_t vb = i.VX128_3.VB128l | (i.VX128_3.VB128h << 5); + d.AddRegOperand(InstrRegister::kVMX, vd, InstrRegister::kWrite); + d.AddRegOperand(InstrRegister::kVMX, vb, InstrRegister::kRead); + d.AddUImmOperand(i.VX128_3.IMM, 1); return d.Finish(); } @@ -2367,10 +2399,7 @@ XEDISASMR(vxor, 0x100004C4, VX )(InstrData& i, InstrDisasm& d) { XEDISASMR(vxor128, VX128(5, 784), VX128 )(InstrData& i, InstrDisasm& d) { d.Init("vxor128", "Vector128 Logical XOR", InstrDisasm::kVMX); - //d.AddRegOperand(InstrRegister::kVMX, i.VX.FRT, InstrRegister::kWrite); - //d.AddRegOperand(InstrRegister::kVMX, i.VX.FRA, InstrRegister::kRead); - //d.AddRegOperand(InstrRegister::kVMX, i.VX.FRB, InstrRegister::kRead); - return d.Finish(); + return GeneralVX128(i, d); } diff --git a/src/xenia/cpu/ppc/instr.cc b/src/xenia/cpu/ppc/instr.cc index 3ea4b8b1a..50a77f4b1 100644 --- a/src/xenia/cpu/ppc/instr.cc +++ b/src/xenia/cpu/ppc/instr.cc @@ -50,7 +50,7 @@ void InstrOperand::Dump(std::string& out_str) { xesnprintfa(buffer, max_count, "f%d", reg.ordinal); break; case InstrRegister::kVMX: - xesnprintfa(buffer, max_count, "v%d", reg.ordinal); + xesnprintfa(buffer, max_count, "vr%d", reg.ordinal); break; } break; @@ -100,6 +100,10 @@ void InstrAccessBits::Extend(InstrAccessBits& other) { cr |= other.cr; gpr |= other.gpr; fpr |= other.fpr; + vr31_0 |= other.vr31_0; + vr63_32 |= other.vr63_32; + vr95_64 |= other.vr95_64; + vr127_96 |= other.vr127_96; } void InstrAccessBits::MarkAccess(InstrRegister& reg) { @@ -133,8 +137,18 @@ void InstrAccessBits::MarkAccess(InstrRegister& reg) { case InstrRegister::kFPR: fpr |= bits << (2 * reg.ordinal); break; - default: case InstrRegister::kVMX: + if (reg.ordinal < 32) { + vr31_0 |= bits << (2 * reg.ordinal); + } else if (reg.ordinal < 64) { + vr63_32 |= bits << (2 * (reg.ordinal - 32)); + } else if (reg.ordinal < 96) { + vr95_64 |= bits << (2 * (reg.ordinal - 64)); + } else { + vr127_96 |= bits << (2 * (reg.ordinal - 96)); + } + break; + default: XEASSERTALWAYS(); break; } @@ -213,6 +227,55 @@ void InstrAccessBits::Dump(std::string& out_str) { } } + if (vr31_0) { + uint64_t vr31_0_t = vr31_0; + for (size_t n = 0; n < 32; n++) { + if (vr31_0_t & 0x3) { + str << "vr" << n << " ["; + str << ((vr31_0_t & 1) ? "R" : " "); + str << ((vr31_0_t & 2) ? "W" : " "); + str << "] "; + } + vr31_0_t >>= 2; + } + } + if (vr63_32) { + uint64_t vr63_32_t = vr63_32; + for (size_t n = 0; n < 32; n++) { + if (vr63_32_t & 0x3) { + str << "vr" << (n + 32) << " ["; + str << ((vr63_32_t & 1) ? "R" : " "); + str << ((vr63_32_t & 2) ? "W" : " "); + str << "] "; + } + vr63_32_t >>= 2; + } + } + if (vr95_64) { + uint64_t vr95_64_t = vr95_64; + for (size_t n = 0; n < 32; n++) { + if (vr95_64_t & 0x3) { + str << "vr" << (n + 64) << " ["; + str << ((vr95_64_t & 1) ? "R" : " "); + str << ((vr95_64_t & 2) ? "W" : " "); + str << "] "; + } + vr95_64_t >>= 2; + } + } + if (vr127_96) { + uint64_t vr127_96_t = vr127_96; + for (size_t n = 0; n < 32; n++) { + if (vr127_96_t & 0x3) { + str << "vr" << (n + 96) << " ["; + str << ((vr127_96_t & 1) ? "R" : " "); + str << ((vr127_96_t & 2) ? "W" : " "); + str << "] "; + } + vr127_96_t >>= 2; + } + } + out_str = str.str(); } diff --git a/src/xenia/cpu/ppc/instr.h b/src/xenia/cpu/ppc/instr.h index 347ddf579..b35ad33fe 100644 --- a/src/xenia/cpu/ppc/instr.h +++ b/src/xenia/cpu/ppc/instr.h @@ -232,6 +232,12 @@ typedef struct { } MDS; // kXEPPCInstrFormatVXA struct { + uint32_t : 6; + uint32_t VC : 5; + uint32_t VB : 5; + uint32_t VA : 5; + uint32_t VD : 5; + uint32_t : 6; } VXA; // kXEPPCInstrFormatVX struct { @@ -241,24 +247,91 @@ typedef struct { } VXR; // kXEPPCInstrFormatVX128 struct { + // VD128 = VD128l | (VD128h << 5) + // VA128 = VA128l | (VA128h << 5) | (VA128H << 6) + // VB128 = VB128l | (VB128h << 5) + uint32_t VB128h : 2; + uint32_t VD128h : 2; + uint32_t : 1; + uint32_t VA128h : 1; + uint32_t : 4; + uint32_t VA128H : 1; + uint32_t VB128l : 5; + uint32_t VA128l : 5; + uint32_t VD128l : 5; + uint32_t : 6; } VX128; // kXEPPCInstrFormatVX128_1 struct { + // VD128 = VD128l | (VD128h << 5) + uint32_t : 2; + uint32_t VD128h : 2; + uint32_t : 7; + uint32_t RB : 5; + uint32_t RA : 5; + uint32_t VD128l : 5; + uint32_t : 6; } VX128_1; // kXEPPCInstrFormatVX128_2 struct { + // VD128 = VD128l | (VD128h << 5) + // VA128 = VA128l | (VA128h << 5) | (VA128H << 6) + // VB128 = VB128l | (VB128h << 5) + uint32_t VB128h : 2; + uint32_t VD128h : 2; + uint32_t : 1; + uint32_t VA128h : 1; + uint32_t VC : 3; + uint32_t : 1; + uint32_t VA128H : 1; + uint32_t VB128l : 5; + uint32_t VA128l : 5; + uint32_t VD128l : 5; + uint32_t : 6; } VX128_2; // kXEPPCInstrFormatVX128_3 struct { + // VD128 = VD128l | (VD128h << 5) + // VB128 = VB128l | (VB128h << 5) + uint32_t VB128h : 2; + uint32_t VD128h : 2; + uint32_t : 7; + uint32_t VB128l : 5; + uint32_t IMM : 5; + uint32_t VD128l : 5; + uint32_t : 6; } VX128_3; // kXEPPCInstrFormatVX128_4 struct { + // VD128 = VD128l | (VD128h << 5) + // VB128 = VB128l | (VB128h << 5) + uint32_t VB128h : 2; + uint32_t VD128h : 2; + uint32_t : 2; + uint32_t z : 2; + uint32_t : 3; + uint32_t VB128l : 5; + uint32_t IMM : 5; + uint32_t VD128l : 5; + uint32_t : 6; } VX128_4; // kXEPPCInstrFormatVX128_5 struct { } VX128_5; // kXEPPCInstrFormatVX128_P struct { + // VD128 = VD128l | (VD128h << 5) + // VB128 = VB128l | (VB128h << 5) + // PERM = PERMl | (PERMh << 5) + uint32_t VB128h : 2; + uint32_t VD128h : 2; + uint32_t : 2; + uint32_t PERMh : 3; + uint32_t : 2; + uint32_t VB128l : 5; + uint32_t PERMl : 5; + uint32_t VD128l : 5; + uint32_t : 6; } VX128_P; // kXEPPCInstrFormatXDSS struct { @@ -314,7 +387,10 @@ typedef struct { class InstrAccessBits { public: - InstrAccessBits() : spr(0), cr(0), gpr(0), fpr(0) {} + InstrAccessBits() : + spr(0), cr(0), gpr(0), fpr(0), + vr31_0(0), vr63_32(0), vr95_64(0), vr127_96(0) { + } // Bitmasks derived from the accesses to registers. // Format is 2 bits for each register, even bits indicating reads and odds @@ -323,7 +399,10 @@ public: uint64_t cr; // cr7/6/5/4/3/2/1/0 uint64_t gpr; // r31-0 uint64_t fpr; // f31-0 - // TODO(benvanik): vr128-0 + uint64_t vr31_0; + uint64_t vr63_32; + uint64_t vr95_64; + uint64_t vr127_96; void Clear(); void Extend(InstrAccessBits& other); @@ -360,7 +439,7 @@ public: void AddUImmOperand(uint64_t value, size_t width, const char* display = NULL); int Finish(); - void Dump(std::string& out_str, size_t pad = 8); + void Dump(std::string& out_str, size_t pad = 13); };