diff --git a/src/xenia/cpu/backend/x64/x64_sequences.cc b/src/xenia/cpu/backend/x64/x64_sequences.cc index dc642603d..6a5880d5f 100644 --- a/src/xenia/cpu/backend/x64/x64_sequences.cc +++ b/src/xenia/cpu/backend/x64/x64_sequences.cc @@ -1453,12 +1453,32 @@ struct CONVERT_I32_F64 struct CONVERT_I64_F64 : Sequence> { static void Emit(X64Emitter& e, const EmitArgType& i) { + // Copy src1. + e.movq(e.rcx, i.src1); + // TODO(benvanik): saturation check? cvtt* (trunc?) if (i.instr->flags == ROUND_TO_ZERO) { e.vcvttsd2si(i.dest, i.src1); } else { e.vcvtsd2si(i.dest, i.src1); } + + // 0x8000000000000000 + e.mov(e.rax, 0x1); + e.shl(e.rax, 63); + + // Saturate positive overflow + // TODO(DrChat): Find a shorter equivalent sequence. + // if (result ind. && src1 >= 0) + // result = 0x7FFFFFFFFFFFFFFF; + e.cmp(e.rax, i.dest); + e.sete(e.al); + e.movzx(e.rax, e.al); + e.shr(e.rcx, 63); + e.xor_(e.rcx, 0x01); + e.and_(e.rax, e.rcx); + + e.sub(i.dest, e.rax); } }; struct CONVERT_F32_I32 diff --git a/src/xenia/cpu/ppc/testing/instr_fcti.s b/src/xenia/cpu/ppc/testing/instr_fctixz.s similarity index 50% rename from src/xenia/cpu/ppc/testing/instr_fcti.s rename to src/xenia/cpu/ppc/testing/instr_fctixz.s index 3ea41eeec..c2df12eaf 100644 --- a/src/xenia/cpu/ppc/testing/instr_fcti.s +++ b/src/xenia/cpu/ppc/testing/instr_fctixz.s @@ -95,3 +95,100 @@ test_fctiwz_10: # blr # #_ REGISTER_OUT f0 0xfff4000000000000 # #_ REGISTER_OUT f1 0x0000000080000000 + +# +0 +test_fctidz_1: + #_ REGISTER_IN f0 0x0000000000000000 + fctidz f1, f0 + blr + #_ REGISTER_OUT f0 0x0000000000000000 + #_ REGISTER_OUT f1 0x0000000000000000 + +# -0 +test_fctidz_2: + #_ REGISTER_IN f0 0x8000000000000000 + fctidz f1, f0 + blr + #_ REGISTER_OUT f0 0x8000000000000000 + #_ REGISTER_OUT f1 0x0000000000000000 + +# smallest positive subnormal +test_fctidz_3: + #_ REGISTER_IN f0 0x0000000000000001 + fctidz f1, f0 + blr + #_ REGISTER_OUT f0 0x0000000000000001 + #_ REGISTER_OUT f1 0x0000000000000000 + +# largest subnormal +test_fctidz_4: + #_ REGISTER_IN f0 0x000fffffffffffff + fctidz f1, f0 + blr + #_ REGISTER_OUT f0 0x000fffffffffffff + #_ REGISTER_OUT f1 0x0000000000000000 + +# +1 +test_fctidz_5: + #_ REGISTER_IN f0 0x3ff0000000000000 + fctidz f1, f0 + blr + #_ REGISTER_OUT f0 0x3ff0000000000000 + #_ REGISTER_OUT f1 0x0000000000000001 + +# -1 +test_fctidz_6: + #_ REGISTER_IN f0 0xbff0000000000000 + fctidz f1, f0 + blr + #_ REGISTER_OUT f0 0xbff0000000000000 + #_ REGISTER_OUT f1 0xffffffffffffffff + +# -(2^31) +test_fctidz_7: + #_ REGISTER_IN f0 0xc1e0000000000000 + fctidz f1, f0 + blr + #_ REGISTER_OUT f0 0xc1e0000000000000 + #_ REGISTER_OUT f1 0xffffffff80000000 + +# 2^31 - 1 +test_fctidz_8: + #_ REGISTER_IN f0 0x41dfffffffc00000 + fctidz f1, f0 + blr + #_ REGISTER_OUT f0 0x41dfffffffc00000 + #_ REGISTER_OUT f1 0x000000007fffffff + +# +infinity +test_fctidz_9: + #_ REGISTER_IN f0 0x7ff0000000000000 + fctidz f1, f0 + blr + #_ REGISTER_OUT f0 0x7ff0000000000000 + #_ REGISTER_OUT f1 0x7fffffffffffffff + +# -infinity +test_fctidz_10: + #_ REGISTER_IN f0 0xfff0000000000000 + fctidz f1, f0 + blr + #_ REGISTER_OUT f0 0xfff0000000000000 + #_ REGISTER_OUT f1 0x8000000000000000 + +# TODO(DrChat): Xenia doesn't handle NaNs yet. +# # QNaN +# test_fctidz_11: +# #_ REGISTER_IN f0 0xfff8000000000000 +# fctidz f1, f0 +# blr +# #_ REGISTER_OUT f0 0xfff8000000000000 +# #_ REGISTER_OUT f1 0x8000000000000000 +# +# # SNaN +# test_fctidz_12: +# #_ REGISTER_IN f0 0xfff4000000000000 +# fctidz f1, f0 +# blr +# #_ REGISTER_OUT f0 0xfff4000000000000 +# #_ REGISTER_OUT f1 0x8000000000000000