diff --git a/src/xenia/cpu/frontend/ppc_emit_fpu.cc b/src/xenia/cpu/frontend/ppc_emit_fpu.cc index 519a401aa..e7a1e9d61 100644 --- a/src/xenia/cpu/frontend/ppc_emit_fpu.cc +++ b/src/xenia/cpu/frontend/ppc_emit_fpu.cc @@ -130,8 +130,17 @@ XEEMITTER(fresx, 0xEC000030, A)(PPCHIRBuilder& f, InstrData& i) { } XEEMITTER(frsqrtex, 0xFC000034, A)(PPCHIRBuilder& f, InstrData& i) { - XEINSTRNOTIMPLEMENTED(); - return 1; + // Double precision: + // frD <- 1/sqrt(frB) + Value* v = f.RSqrt(f.LoadFPR(i.A.FRB)); + f.StoreFPR(i.A.FRT, v); + // f.UpdateFPRF(v); + if (i.A.Rc) { + // e.update_cr_with_cond(1, v); + XEINSTRNOTIMPLEMENTED(); + return 1; + } + return 0; } XEEMITTER(fsubx, 0xFC000028, A)(PPCHIRBuilder& f, InstrData& i) { @@ -179,7 +188,7 @@ XEEMITTER(fselx, 0xFC00002E, A)(PPCHIRBuilder& f, InstrData& i) { XEEMITTER(fsqrtx, 0xFC00002C, A)(PPCHIRBuilder& f, InstrData& i) { // Double precision: // frD <- sqrt(frB) - Value* v = f.Sqrt(f.LoadFPR(i.A.FRA)); + Value* v = f.Sqrt(f.LoadFPR(i.A.FRB)); f.StoreFPR(i.A.FRT, v); // f.UpdateFPRF(v); if (i.A.Rc) { @@ -193,7 +202,7 @@ XEEMITTER(fsqrtx, 0xFC00002C, A)(PPCHIRBuilder& f, InstrData& i) { XEEMITTER(fsqrtsx, 0xEC00002C, A)(PPCHIRBuilder& f, InstrData& i) { // Single precision: // frD <- sqrt(frB) - Value* v = f.Sqrt(f.LoadFPR(i.A.FRA)); + Value* v = f.Sqrt(f.LoadFPR(i.A.FRB)); v = f.Convert(f.Convert(v, FLOAT32_TYPE), FLOAT64_TYPE); f.StoreFPR(i.A.FRT, v); // f.UpdateFPRF(v); diff --git a/src/xenia/cpu/frontend/test/bin/instr_frsqrte.bin b/src/xenia/cpu/frontend/test/bin/instr_frsqrte.bin new file mode 100644 index 000000000..129ed931c Binary files /dev/null and b/src/xenia/cpu/frontend/test/bin/instr_frsqrte.bin differ diff --git a/src/xenia/cpu/frontend/test/bin/instr_frsqrte.dis b/src/xenia/cpu/frontend/test/bin/instr_frsqrte.dis new file mode 100644 index 000000000..e1b5dc245 --- /dev/null +++ b/src/xenia/cpu/frontend/test/bin/instr_frsqrte.dis @@ -0,0 +1,13 @@ +Disassembly of section .text: + +0000000000100000 : + 100000: fc 20 08 34 frsqrte f1,f1 + 100004: 4e 80 00 20 blr + +0000000000100008 : + 100008: fc 20 08 34 frsqrte f1,f1 + 10000c: 4e 80 00 20 blr + +0000000000100010 : + 100010: fc 20 08 34 frsqrte f1,f1 + 100014: 4e 80 00 20 blr diff --git a/src/xenia/cpu/frontend/test/bin/instr_frsqrte.map b/src/xenia/cpu/frontend/test/bin/instr_frsqrte.map new file mode 100644 index 000000000..85f7b9d38 --- /dev/null +++ b/src/xenia/cpu/frontend/test/bin/instr_frsqrte.map @@ -0,0 +1,3 @@ +0000000000000000 t test_frsqrte_1 +0000000000000008 t test_frsqrte_2 +0000000000000010 t test_frsqrte_3 diff --git a/src/xenia/cpu/frontend/test/bin/instr_fsqrt.bin b/src/xenia/cpu/frontend/test/bin/instr_fsqrt.bin new file mode 100644 index 000000000..a836e2784 Binary files /dev/null and b/src/xenia/cpu/frontend/test/bin/instr_fsqrt.bin differ diff --git a/src/xenia/cpu/frontend/test/bin/instr_fsqrt.dis b/src/xenia/cpu/frontend/test/bin/instr_fsqrt.dis new file mode 100644 index 000000000..23a32cb35 --- /dev/null +++ b/src/xenia/cpu/frontend/test/bin/instr_fsqrt.dis @@ -0,0 +1,13 @@ +Disassembly of section .text: + +0000000000100000 : + 100000: fc 20 08 2c fsqrt f1,f1 + 100004: 4e 80 00 20 blr + +0000000000100008 : + 100008: fc 20 08 2c fsqrt f1,f1 + 10000c: 4e 80 00 20 blr + +0000000000100010 : + 100010: fc 20 08 2c fsqrt f1,f1 + 100014: 4e 80 00 20 blr diff --git a/src/xenia/cpu/frontend/test/bin/instr_fsqrt.map b/src/xenia/cpu/frontend/test/bin/instr_fsqrt.map new file mode 100644 index 000000000..88dff4f80 --- /dev/null +++ b/src/xenia/cpu/frontend/test/bin/instr_fsqrt.map @@ -0,0 +1,3 @@ +0000000000000000 t test_fsqrt_1 +0000000000000008 t test_fsqrt_2 +0000000000000010 t test_fsqrt_3 diff --git a/src/xenia/cpu/frontend/test/instr_frsqrte.s b/src/xenia/cpu/frontend/test/instr_frsqrte.s new file mode 100644 index 000000000..bdec55422 --- /dev/null +++ b/src/xenia/cpu/frontend/test/instr_frsqrte.s @@ -0,0 +1,19 @@ +test_frsqrte_1: + #_ REGISTER_IN f1 1.0 + frsqrte f1, f1 + blr + #_ REGISTER_OUT f1 0.99975585937500000 + # want: 0.97 + +test_frsqrte_2: + #_ REGISTER_IN f1 64.0 + frsqrte f1, f1 + blr + #_ REGISTER_OUT f1 0.12496948242187500 + +test_frsqrte_3: + #_ REGISTER_IN f1 0.5 + frsqrte f1, f1 + blr + #_ REGISTER_OUT f1 1.4138183593750000 + # want: 1.375 diff --git a/src/xenia/cpu/frontend/test/instr_fsqrt.s b/src/xenia/cpu/frontend/test/instr_fsqrt.s new file mode 100644 index 000000000..792cf3fef --- /dev/null +++ b/src/xenia/cpu/frontend/test/instr_fsqrt.s @@ -0,0 +1,17 @@ +test_fsqrt_1: + #_ REGISTER_IN f1 1.0 + fsqrt f1, f1 + blr + #_ REGISTER_OUT f1 1.0000000000000000 + +test_fsqrt_2: + #_ REGISTER_IN f1 64.0 + fsqrt f1, f1 + blr + #_ REGISTER_OUT f1 8.0000000000000000 + +test_fsqrt_3: + #_ REGISTER_IN f1 0.5 + fsqrt f1, f1 + blr + #_ REGISTER_OUT f1 0.70710678118654757