JIT - fctixx: Properly handle numbers > INT_MAX

This commit is contained in:
Dr. Chat
2017-03-05 14:59:52 -06:00
parent ad5748f3e7
commit ea89a5d179
5 changed files with 125 additions and 5 deletions

View File

@@ -670,6 +670,9 @@ static const vec128_t xmm_consts[] = {
0x80000000u),
/* XMMShortMinPS */ vec128f(SHRT_MIN),
/* XMMShortMaxPS */ vec128f(SHRT_MAX),
/* XMMIntMaxPS */ vec128f(float(INT_MAX)),
/* XMMIntMaxPD */ vec128d(INT_MAX),
/* XMMInt64MaxPD */ vec128d(double(INT64_MAX)),
};
// First location to try and place constants.

View File

@@ -89,6 +89,9 @@ enum XmmConst {
XMMSignMaskF32,
XMMShortMinPS,
XMMShortMaxPS,
XMMIntMaxPS,
XMMIntMaxPD,
XMMInt64MaxPD,
};
// Unfortunately due to the design of xbyak we have to pass this to the ctor.

View File

@@ -1429,21 +1429,25 @@ struct CONVERT_I32_F32
: Sequence<CONVERT_I32_F32, I<OPCODE_CONVERT, I32Op, F32Op>> {
static void Emit(X64Emitter& e, const EmitArgType& i) {
// TODO(benvanik): saturation check? cvtt* (trunc?)
e.vcvtss2si(i.dest, i.src1);
e.vminss(e.xmm0, i.src1, e.GetXmmConstPtr(XMMIntMaxPS));
e.vcvtss2si(i.dest, e.xmm0);
}
};
struct CONVERT_I32_F64
: Sequence<CONVERT_I32_F64, I<OPCODE_CONVERT, I32Op, F64Op>> {
static void Emit(X64Emitter& e, const EmitArgType& i) {
// TODO(benvanik): saturation check? cvtt* (trunc?)
e.vcvttsd2si(i.dest, i.src1);
// Intel returns 0x80000000 if the double value does not fit within an int32
// PPC saturates the value instead.
// So, we can clamp the double value to (double)0x7FFFFFFF.
e.vminsd(e.xmm0, i.src1, e.GetXmmConstPtr(XMMIntMaxPD));
e.vcvttsd2si(i.dest, e.xmm0);
}
};
struct CONVERT_I64_F64
: Sequence<CONVERT_I64_F64, I<OPCODE_CONVERT, I64Op, F64Op>> {
static void Emit(X64Emitter& e, const EmitArgType& i) {
// TODO(benvanik): saturation check? cvtt* (trunc?)
e.vcvttsd2si(i.dest, i.src1);
e.vminsd(e.xmm0, i.src1, e.GetXmmConstPtr(XMMInt64MaxPD));
e.vcvttsd2si(i.dest, e.xmm0);
}
};
struct CONVERT_F32_I32