diff --git a/src/xenia/cpu/frontend/ppc_emit_altivec.cc b/src/xenia/cpu/frontend/ppc_emit_altivec.cc index e47c7543c..0c15a5736 100644 --- a/src/xenia/cpu/frontend/ppc_emit_altivec.cc +++ b/src/xenia/cpu/frontend/ppc_emit_altivec.cc @@ -597,20 +597,20 @@ int InstrEmit_vcmpbfp_(PPCHIRBuilder& f, InstrData& i, uint32_t vd, uint32_t va, // if vA or vB are NaN, the 2 high-order bits are set (0xC0000000) Value* va_value = f.LoadVR(va); Value* vb_value = f.LoadVR(vb); - Value* ge = f.VectorCompareSGE(va_value, vb_value, FLOAT32_TYPE); - Value* le = - f.Not(f.VectorCompareSGT(va_value, f.Neg(vb_value), FLOAT32_TYPE)); + Value* gt = f.VectorCompareSGT(va_value, vb_value, FLOAT32_TYPE); + Value* lt = + f.Not(f.VectorCompareSGE(va_value, f.Neg(vb_value), FLOAT32_TYPE)); Value* v = - f.Or(f.And(ge, f.LoadConstantVec128(vec128i(0x80000000, 0x80000000, + f.Or(f.And(gt, f.LoadConstantVec128(vec128i(0x80000000, 0x80000000, 0x80000000, 0x80000000))), - f.And(le, f.LoadConstantVec128(vec128i(0x40000000, 0x40000000, + f.And(lt, f.LoadConstantVec128(vec128i(0x40000000, 0x40000000, 0x40000000, 0x40000000)))); f.StoreVR(vd, v); if (rc) { // CR0:4 = 0; CR0:5 = VT == 0; CR0:6 = CR0:7 = 0; // If all of the elements are within bounds, CR6[2] is set // FIXME: Does not affect CR6[0], but the following function does. - f.UpdateCR6(f.Or(ge, le)); + f.UpdateCR6(f.Or(gt, lt)); } return 0; } diff --git a/src/xenia/cpu/frontend/testing/instr_vcmpxxfp.s b/src/xenia/cpu/frontend/testing/instr_vcmpxxfp.s index b73bbc406..ceaf3fb65 100644 --- a/src/xenia/cpu/frontend/testing/instr_vcmpxxfp.s +++ b/src/xenia/cpu/frontend/testing/instr_vcmpxxfp.s @@ -30,3 +30,39 @@ test_vcmpxxfp_3: #_ REGISTER_OUT v4 [3f800000, 3f800000, 3f800000, 3f800000] #_ REGISTER_OUT v5 [3f800001, 3f800001, 3f800001, 3f800001] #_ REGISTER_OUT r3 0x00000020 + +test_vcmpbfp_1: + # [5.0, 5.0, 5.0, 5.0] + #_ REGISTER_IN v4 [40A00000, 40A00000, 40A00000, 40A00000] + #_ REGISTER_IN v5 [40A00000, 40A00000, 40A00000, 40A00000] + vcmpbfp. v3, v4, v5 + mfocrf r3, 2 # cr6 + blr + #_ REGISTER_OUT v4 [40A00000, 40A00000, 40A00000, 40A00000] + #_ REGISTER_OUT v5 [40A00000, 40A00000, 40A00000, 40A00000] + #_ REGISTER_OUT v3 [00000000, 00000000, 00000000, 00000000] + #_ REGISTER_OUT r3 0x00000020 + +test_vcmpbfp_2: + # [-5.0, -5.0, -5.0, -5.0] + #_ REGISTER_IN v4 [C0A00000, C0A00000, C0A00000, C0A00000] + #_ REGISTER_IN v5 [40A00000, 40A00000, 40A00000, 40A00000] + vcmpbfp. v3, v4, v5 + mfocrf r3, 2 # cr6 + blr + #_ REGISTER_OUT v4 [C0A00000, C0A00000, C0A00000, C0A00000] + #_ REGISTER_OUT v5 [40A00000, 40A00000, 40A00000, 40A00000] + #_ REGISTER_OUT v3 [00000000, 00000000, 00000000, 00000000] + #_ REGISTER_OUT r3 0x00000020 + +test_vcmpbfp_3: + # [7.0, -7.0, 5.0, 5.0] + #_ REGISTER_IN v4 [40E00000, C0E00000, 40A00000, 40A00000] + #_ REGISTER_IN v5 [40A00000, 40A00000, 40A00000, 40A00000] + vcmpbfp. v3, v4, v5 + mfocrf r3, 2 # cr6 + blr + #_ REGISTER_OUT v4 [40E00000, C0E00000, 40A00000, 40A00000] + #_ REGISTER_OUT v5 [40A00000, 40A00000, 40A00000, 40A00000] + #_ REGISTER_OUT v3 [80000000, 40000000, 00000000, 00000000] + #_ REGISTER_OUT r3 0x00000000