diff --git a/src/xenia/cpu/ppc/disasm_altivec.cc b/src/xenia/cpu/ppc/disasm_altivec.cc index 08b23b43c..8bd9b9787 100644 --- a/src/xenia/cpu/ppc/disasm_altivec.cc +++ b/src/xenia/cpu/ppc/disasm_altivec.cc @@ -347,13 +347,16 @@ XEDISASMR(vaddcuw, 0x10000180, VX )(InstrData& i, InstrDisasm& d) { XEDISASMR(vaddfp, 0x1000000A, VX )(InstrData& i, InstrDisasm& d) { d.Init("vaddfp", "Vector Add Floating Point", InstrDisasm::kVMX); - return 1; + 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(vaddfp128, VX128(5, 16), VX128 )(InstrData& i, InstrDisasm& d) { d.Init("vaddfp128", "Vector128 Add Floating Point", InstrDisasm::kVMX); - return 1; + return GeneralVX128(i, d); } XEDISASMR(vaddsbs, 0x10000300, VX )(InstrData& i, InstrDisasm& d) { @@ -1168,7 +1171,11 @@ XEDISASMR(vrfin, 0x1000020A, VX )(InstrData& i, InstrDisasm& d) { XEDISASMR(vrfin128, VX128_3(6, 880), VX128_3)(InstrData& i, InstrDisasm& d) { d.Init("vrfin128", "Vector128 Round to Floating-Point Integer Nearest", InstrDisasm::kVMX); - return 1; + 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(); } XEDISASMR(vrfip, 0x1000028A, VX )(InstrData& i, InstrDisasm& d) { diff --git a/src/xenia/cpu/x64/x64_emit_altivec.cc b/src/xenia/cpu/x64/x64_emit_altivec.cc index 2d24234d9..24120f112 100644 --- a/src/xenia/cpu/x64/x64_emit_altivec.cc +++ b/src/xenia/cpu/x64/x64_emit_altivec.cc @@ -489,14 +489,20 @@ XEEMITTER(vaddcuw, 0x10000180, VX )(X64Emitter& e, X86Compiler& c, Instr return 1; } -XEEMITTER(vaddfp, 0x1000000A, VX )(X64Emitter& e, X86Compiler& c, InstrData& i) { - XEINSTRNOTIMPLEMENTED(); - return 1; +int InstrEmit_vaddfp_(X64Emitter& e, X86Compiler& c, uint32_t vd, uint32_t va, uint32_t vb) { + // (VD) <- (VA) + (VB) (4 x fp) + XmmVar v(c.newXmmVar()); + c.movaps(v, e.vr_value(va)); + c.addps(v, e.vr_value(vb)); + e.update_vr_value(vd, v); + e.TraceVR(vd, va, vb); + return 0; +} +XEEMITTER(vaddfp, 0x1000000A, VX )(X64Emitter& e, X86Compiler& c, InstrData& i) { + return InstrEmit_vaddfp_(e, c, i.VX.VD, i.VX.VA, i.VX.VB); } - XEEMITTER(vaddfp128, VX128(5, 16), VX128 )(X64Emitter& e, X86Compiler& c, InstrData& i) { - XEINSTRNOTIMPLEMENTED(); - return 1; + return InstrEmit_vaddfp_(e, c, VX128_VD128, VX128_VA128, VX128_VB128); } XEEMITTER(vaddsbs, 0x10000300, VX )(X64Emitter& e, X86Compiler& c, InstrData& i) { @@ -1450,13 +1456,21 @@ XEEMITTER(vrfim128, VX128_3(6, 816), VX128_3)(X64Emitter& e, X86Compiler& return 1; } +int InstrEmit_vrfin_(X64Emitter& e, X86Compiler& c, uint32_t vd, uint32_t vb) { + // (VD) <- RoundToNearest(VB) + // TODO(benvanik): check if this is right - may want to leave as dq. + XmmVar v(c.newXmmVar()); + c.cvtps2dq(v, e.vr_value(vd)); + c.cvtdq2ps(v, v); + e.update_vr_value(vd, v); + e.TraceVR(vd, vb); + return 0; +} XEEMITTER(vrfin, 0x1000020A, VX )(X64Emitter& e, X86Compiler& c, InstrData& i) { - XEINSTRNOTIMPLEMENTED(); - return 1; + return InstrEmit_vrfin_(e, c, i.VX.VD, i.VX.VB); } XEEMITTER(vrfin128, VX128_3(6, 880), VX128_3)(X64Emitter& e, X86Compiler& c, InstrData& i) { - XEINSTRNOTIMPLEMENTED(); - return 1; + return InstrEmit_vrfin_(e, c, VX128_3_VD128, VX128_3_VB128); } XEEMITTER(vrfip, 0x1000028A, VX )(X64Emitter& e, X86Compiler& c, InstrData& i) {