diff --git a/src/xenia/cpu/x64/x64_emit_alu.cc b/src/xenia/cpu/x64/x64_emit_alu.cc index c94d9f9a5..923b4bdbd 100644 --- a/src/xenia/cpu/x64/x64_emit_alu.cc +++ b/src/xenia/cpu/x64/x64_emit_alu.cc @@ -870,13 +870,46 @@ XEEMITTER(extsbx, 0x7C000774, X )(X64Emitter& e, X86Compiler& c, InstrDat } XEEMITTER(extshx, 0x7C000734, X )(X64Emitter& e, X86Compiler& c, InstrData& i) { - XEINSTRNOTIMPLEMENTED(); - return 1; + // s <- (RS)[48] + // RA[48:63] <- (RS)[48:63] + // RA[0:47] <- 48.s + + // TODO(benvanik): see if there's a faster way to do this. + GpVar v(c.newGpVar()); + c.mov(v, e.gpr_value(i.X.RT)); + c.cwde(v); + c.cdqe(v); + e.update_gpr_value(i.X.RA, v); + + if (i.X.Rc) { + // Update cr0. + e.update_cr_with_cond(0, v); + } + + e.clear_constant_gpr_value(i.X.RA); + + return 0; } XEEMITTER(extswx, 0x7C0007B4, X )(X64Emitter& e, X86Compiler& c, InstrData& i) { - XEINSTRNOTIMPLEMENTED(); - return 1; + // s <- (RS)[32] + // RA[32:63] <- (RS)[32:63] + // RA[0:31] <- i32.s + + // TODO(benvanik): see if there's a faster way to do this. + GpVar v(c.newGpVar()); + c.mov(v, e.gpr_value(i.X.RT)); + c.cdqe(v); + e.update_gpr_value(i.X.RA, v); + + if (i.X.Rc) { + // Update cr0. + e.update_cr_with_cond(0, v); + } + + e.clear_constant_gpr_value(i.X.RA); + + return 0; } XEEMITTER(nandx, 0x7C0003B8, X )(X64Emitter& e, X86Compiler& c, InstrData& i) { @@ -926,8 +959,22 @@ XEEMITTER(orx, 0x7C000378, X )(X64Emitter& e, X86Compiler& c, InstrDat } XEEMITTER(orcx, 0x7C000338, X )(X64Emitter& e, X86Compiler& c, InstrData& i) { - XEINSTRNOTIMPLEMENTED(); - return 1; + // RA <- (RS) | ¬(RB) + + GpVar v(c.newGpVar()); + c.mov(v, e.gpr_value(i.X.RB)); + c.not_(v); + c.or_(v, e.gpr_value(i.X.RT)); + e.update_gpr_value(i.X.RA, v); + + if (i.X.Rc) { + // With cr0 update. + e.update_cr_with_cond(0, v); + } + + e.clear_constant_gpr_value(i.X.RA); + + return 0; } XEEMITTER(ori, 0x60000000, D )(X64Emitter& e, X86Compiler& c, InstrData& i) { diff --git a/src/xenia/cpu/x64/x64_emit_fpu.cc b/src/xenia/cpu/x64/x64_emit_fpu.cc index 2449c231a..0aed2ada0 100644 --- a/src/xenia/cpu/x64/x64_emit_fpu.cc +++ b/src/xenia/cpu/x64/x64_emit_fpu.cc @@ -290,8 +290,27 @@ XEEMITTER(fsqrtsx, 0xEC00002C, A )(X64Emitter& e, X86Compiler& c, InstrDat // Floating-point multiply-add (A-9) XEEMITTER(fmaddx, 0xFC00003A, A )(X64Emitter& e, X86Compiler& c, InstrData& i) { - XEINSTRNOTIMPLEMENTED(); - return 1; + // frD <- (frA x frC) + frB + + XmmVar v(c.newXmmVar()); + // TODO(benvanik): I'm sure there's an SSE op for this. + // NOTE: we do (frB - [frA x frC]) as that's pretty much the same. + c.movq(v, e.fpr_value(i.A.FRA)); + c.mulsd(v, e.fpr_value(i.A.FRC)); + c.addsd(v, e.fpr_value(i.A.FRB)); + e.update_fpr_value(i.A.FRT, v); + + // TODO(benvanik): update status/control register. + + if (i.A.Rc) { + // With cr0 update. + XEASSERTALWAYS(); + //e.update_cr_with_cond(0, v); + XEINSTRNOTIMPLEMENTED(); + return 1; + } + + return 0; } XEEMITTER(fmaddsx, 0xEC00003A, A )(X64Emitter& e, X86Compiler& c, InstrData& i) {