mirror of
https://github.com/FEX-Emu/FEX.git
synced 2026-10-24 16:01:15 +02:00
Fixes floating point conversion rounding bugs
When floats and doubles were converting to integers we weren't doing the correct transformation. AArch64 provides direct ops for all four of the op types. So lets use them - f32 -> int64 - f32 -> int32 - f64 -> int64 - f64 -> int32 Doesn't fully fix the case of overflow for AArch64 since overflow behaviour is different. x86 returns 0x8000'0000 or 0x8000'0000'0000'0000 while AArch64 saturates to the maximum signed integers. Can't work around that without checking overflow flags. This does solve the typical case though. Fixes audio problems in all FMod games.
This commit is contained in:
1 parent
18fe049976
commit
d57a034220
11 files changed
+160
-397
No files matched your search
@@ -3349,22 +3349,6 @@ void InterpreterOps::InterpretIR(FEXCore::Core::InternalThreadState *Thread, uin
|
||||
memcpy(GDP, Tmp, OpSize);
|
||||
break;
|
||||
}
|
||||
case IR::OP_VECTOR_UTOF: {
|
||||
auto Op = IROp->C<IR::IROp_Vector_UToF>();
|
||||
void *Src = GetSrc<void*>(SSAData, Op->Header.Args[0]);
|
||||
uint8_t Tmp[16];
|
||||
|
||||
uint8_t Elements = OpSize / Op->Header.ElementSize;
|
||||
|
||||
auto Func = [](auto a, auto min, auto max) { return a; };
|
||||
switch (Op->Header.ElementSize) {
|
||||
DO_VECTOR_1SRC_2TYPE_OP(4, float, uint32_t, Func, 0, 0)
|
||||
DO_VECTOR_1SRC_2TYPE_OP(8, double, uint64_t, Func, 0, 0)
|
||||
default: LOGMAN_MSG_A("Unknown Element Size: %d", Op->Header.ElementSize); break;
|
||||
}
|
||||
memcpy(GDP, Tmp, OpSize);
|
||||
break;
|
||||
}
|
||||
case IR::OP_VECTOR_STOF: {
|
||||
auto Op = IROp->C<IR::IROp_Vector_SToF>();
|
||||
void *Src = GetSrc<void*>(SSAData, Op->Header.Args[0]);
|
||||
@@ -3381,22 +3365,6 @@ void InterpreterOps::InterpretIR(FEXCore::Core::InternalThreadState *Thread, uin
|
||||
memcpy(GDP, Tmp, OpSize);
|
||||
break;
|
||||
}
|
||||
case IR::OP_VECTOR_FTOZU: {
|
||||
auto Op = IROp->C<IR::IROp_Vector_FToZU>();
|
||||
void *Src = GetSrc<void*>(SSAData, Op->Header.Args[0]);
|
||||
uint8_t Tmp[16];
|
||||
|
||||
uint8_t Elements = OpSize / Op->Header.ElementSize;
|
||||
|
||||
auto Func = [](auto a, auto min, auto max) { return a; };
|
||||
switch (Op->Header.ElementSize) {
|
||||
DO_VECTOR_1SRC_2TYPE_OP(4, uint32_t, float, Func, 0, 0)
|
||||
DO_VECTOR_1SRC_2TYPE_OP(8, uint64_t, double, Func, 0, 0)
|
||||
default: LOGMAN_MSG_A("Unknown Element Size: %d", Op->Header.ElementSize); break;
|
||||
}
|
||||
memcpy(GDP, Tmp, OpSize);
|
||||
break;
|
||||
}
|
||||
case IR::OP_VECTOR_FTOZS: {
|
||||
auto Op = IROp->C<IR::IROp_Vector_FToZS>();
|
||||
void *Src = GetSrc<void*>(SSAData, Op->Header.Args[0]);
|
||||
@@ -3404,7 +3372,7 @@ void InterpreterOps::InterpretIR(FEXCore::Core::InternalThreadState *Thread, uin
|
||||
|
||||
uint8_t Elements = OpSize / Op->Header.ElementSize;
|
||||
|
||||
auto Func = [](auto a, auto min, auto max) { return a; };
|
||||
auto Func = [](auto a, auto min, auto max) { return std::trunc(a); };
|
||||
switch (Op->Header.ElementSize) {
|
||||
DO_VECTOR_1SRC_2TYPE_OP(4, int32_t, float, Func, 0, 0)
|
||||
DO_VECTOR_1SRC_2TYPE_OP(8, int64_t, double, Func, 0, 0)
|
||||
@@ -3413,22 +3381,6 @@ void InterpreterOps::InterpretIR(FEXCore::Core::InternalThreadState *Thread, uin
|
||||
memcpy(GDP, Tmp, OpSize);
|
||||
break;
|
||||
}
|
||||
case IR::OP_VECTOR_FTOU: {
|
||||
auto Op = IROp->C<IR::IROp_Vector_FToU>();
|
||||
void *Src = GetSrc<void*>(SSAData, Op->Header.Args[0]);
|
||||
uint8_t Tmp[16];
|
||||
|
||||
uint8_t Elements = OpSize / Op->Header.ElementSize;
|
||||
|
||||
auto Func = [](auto a, auto min, auto max) { return a; };
|
||||
switch (Op->Header.ElementSize) {
|
||||
DO_VECTOR_1SRC_2TYPE_OP(4, uint32_t, float, Func, 0, 0)
|
||||
DO_VECTOR_1SRC_2TYPE_OP(8, uint64_t, double, Func, 0, 0)
|
||||
default: LOGMAN_MSG_A("Unknown Element Size: %d", Op->Header.ElementSize); break;
|
||||
}
|
||||
memcpy(GDP, Tmp, OpSize);
|
||||
break;
|
||||
}
|
||||
case IR::OP_VECTOR_FTOS: {
|
||||
auto Op = IROp->C<IR::IROp_Vector_FToS>();
|
||||
void *Src = GetSrc<void*>(SSAData, Op->Header.Args[0]);
|
||||
@@ -3436,7 +3388,7 @@ void InterpreterOps::InterpretIR(FEXCore::Core::InternalThreadState *Thread, uin
|
||||
|
||||
uint8_t Elements = OpSize / Op->Header.ElementSize;
|
||||
|
||||
auto Func = [](auto a, auto min, auto max) { return a; };
|
||||
auto Func = [](auto a, auto min, auto max) { return std::nearbyint(a); };
|
||||
switch (Op->Header.ElementSize) {
|
||||
DO_VECTOR_1SRC_2TYPE_OP(4, int32_t, float, Func, 0, 0)
|
||||
DO_VECTOR_1SRC_2TYPE_OP(8, int64_t, double, Func, 0, 0)
|
||||
@@ -4381,78 +4333,57 @@ void InterpreterOps::InterpretIR(FEXCore::Core::InternalThreadState *Thread, uin
|
||||
}
|
||||
break;
|
||||
}
|
||||
case IR::OP_FLOAT_FROMGPR_U: {
|
||||
auto Op = IROp->C<IR::IROp_Float_FromGPR_U>();
|
||||
uint16_t Conv = (Op->Header.ElementSize << 8) | Op->SrcElementSize;
|
||||
switch (Conv) {
|
||||
case 0x0404: { // Float <- int32_t
|
||||
float Dst = (float)*GetSrc<uint32_t*>(SSAData, Op->Header.Args[0]);
|
||||
memcpy(GDP, &Dst, Op->Header.ElementSize);
|
||||
break;
|
||||
}
|
||||
case 0x0408: { // Float <- int64_t
|
||||
float Dst = (float)*GetSrc<uint64_t*>(SSAData, Op->Header.Args[0]);
|
||||
memcpy(GDP, &Dst, Op->Header.ElementSize);
|
||||
break;
|
||||
}
|
||||
case 0x0804: { // Double <- int32_t
|
||||
double Dst = (double)*GetSrc<uint32_t*>(SSAData, Op->Header.Args[0]);
|
||||
memcpy(GDP, &Dst, Op->Header.ElementSize);
|
||||
break;
|
||||
}
|
||||
case 0x0808: { // Double <- int64_t
|
||||
double Dst = (double)*GetSrc<uint64_t*>(SSAData, Op->Header.Args[0]);
|
||||
memcpy(GDP, &Dst, Op->Header.ElementSize);
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case IR::OP_FLOAT_TOGPR_ZS: {
|
||||
auto Op = IROp->C<IR::IROp_Float_ToGPR_ZS>();
|
||||
if (Op->Header.ElementSize == 8) {
|
||||
int64_t Dst = (int64_t)*GetSrc<double*>(SSAData, Op->Header.Args[0]);
|
||||
memcpy(GDP, &Dst, Op->Header.ElementSize);
|
||||
}
|
||||
else {
|
||||
int32_t Dst = (int32_t)*GetSrc<float*>(SSAData, Op->Header.Args[0]);
|
||||
memcpy(GDP, &Dst, Op->Header.ElementSize);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case IR::OP_FLOAT_TOGPR_ZU: {
|
||||
auto Op = IROp->C<IR::IROp_Float_ToGPR_ZU>();
|
||||
if (Op->Header.ElementSize == 8) {
|
||||
uint64_t Dst = (uint64_t)*GetSrc<double*>(SSAData, Op->Header.Args[0]);
|
||||
memcpy(GDP, &Dst, Op->Header.ElementSize);
|
||||
}
|
||||
else {
|
||||
uint32_t Dst = (uint32_t)*GetSrc<float*>(SSAData, Op->Header.Args[0]);
|
||||
memcpy(GDP, &Dst, Op->Header.ElementSize);
|
||||
uint16_t Conv = (IROp->Size << 8) | Op->SrcElementSize;
|
||||
switch (Conv) {
|
||||
case 0x0804: { // int64_t <- float
|
||||
int64_t Dst = (int64_t)std::trunc(*GetSrc<float*>(SSAData, Op->Header.Args[0]));
|
||||
memcpy(GDP, &Dst, IROp->Size);
|
||||
break;
|
||||
}
|
||||
case 0x0808: { // int64_t <- double
|
||||
int64_t Dst = (int64_t)std::trunc(*GetSrc<double*>(SSAData, Op->Header.Args[0]));
|
||||
memcpy(GDP, &Dst, IROp->Size);
|
||||
break;
|
||||
}
|
||||
case 0x0404: { // int32_t <- float
|
||||
int32_t Dst = (int32_t)std::trunc(*GetSrc<float*>(SSAData, Op->Header.Args[0]));
|
||||
memcpy(GDP, &Dst, IROp->Size);
|
||||
break;
|
||||
}
|
||||
case 0x0408: { // int32_t <- double
|
||||
int32_t Dst = (int32_t)std::trunc(*GetSrc<double*>(SSAData, Op->Header.Args[0]));
|
||||
memcpy(GDP, &Dst, IROp->Size);
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case IR::OP_FLOAT_TOGPR_S: {
|
||||
auto Op = IROp->C<IR::IROp_Float_ToGPR_S>();
|
||||
if (Op->Header.ElementSize == 8) {
|
||||
int64_t Dst = (int64_t)*GetSrc<double*>(SSAData, Op->Header.Args[0]);
|
||||
memcpy(GDP, &Dst, Op->Header.ElementSize);
|
||||
}
|
||||
else {
|
||||
int32_t Dst = (int32_t)*GetSrc<float*>(SSAData, Op->Header.Args[0]);
|
||||
memcpy(GDP, &Dst, Op->Header.ElementSize);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case IR::OP_FLOAT_TOGPR_U: {
|
||||
auto Op = IROp->C<IR::IROp_Float_ToGPR_U>();
|
||||
if (Op->Header.ElementSize == 8) {
|
||||
uint64_t Dst = (uint64_t)*GetSrc<double*>(SSAData, Op->Header.Args[0]);
|
||||
memcpy(GDP, &Dst, Op->Header.ElementSize);
|
||||
}
|
||||
else {
|
||||
uint32_t Dst = (uint32_t)*GetSrc<float*>(SSAData, Op->Header.Args[0]);
|
||||
memcpy(GDP, &Dst, Op->Header.ElementSize);
|
||||
uint16_t Conv = (IROp->Size << 8) | Op->SrcElementSize;
|
||||
switch (Conv) {
|
||||
case 0x0804: { // int64_t <- float
|
||||
int64_t Dst = (int64_t)std::nearbyint(*GetSrc<float*>(SSAData, Op->Header.Args[0]));
|
||||
memcpy(GDP, &Dst, IROp->Size);
|
||||
break;
|
||||
}
|
||||
case 0x0808: { // int64_t <- double
|
||||
int64_t Dst = (int64_t)std::nearbyint(*GetSrc<double*>(SSAData, Op->Header.Args[0]));
|
||||
memcpy(GDP, &Dst, IROp->Size);
|
||||
break;
|
||||
}
|
||||
case 0x0404: { // int32_t <- float
|
||||
int32_t Dst = (int32_t)std::nearbyint(*GetSrc<float*>(SSAData, Op->Header.Args[0]));
|
||||
memcpy(GDP, &Dst, IROp->Size);
|
||||
break;
|
||||
}
|
||||
case 0x0408: { // int32_t <- double
|
||||
int32_t Dst = (int32_t)std::nearbyint(*GetSrc<double*>(SSAData, Op->Header.Args[0]));
|
||||
memcpy(GDP, &Dst, IROp->Size);
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
+28
-15
@@ -969,34 +969,49 @@ DEF_OP(VExtractToGPR) {
|
||||
}
|
||||
}
|
||||
|
||||
DEF_OP(Float_ToGPR_ZU) {
|
||||
LogMan::Msg::D("Unimplemented");
|
||||
}
|
||||
|
||||
DEF_OP(Float_ToGPR_ZS) {
|
||||
auto Op = IROp->C<IR::IROp_Float_ToGPR_ZS>();
|
||||
if (Op->Header.ElementSize == 8) {
|
||||
fcvtzs(GetReg<RA_64>(Node), GetSrc(Op->Header.Args[0].ID()).D());
|
||||
aarch64::Register Dst{};
|
||||
aarch64::VRegister Src{};
|
||||
if (Op->SrcElementSize == 8) {
|
||||
Src = GetSrc(Op->Header.Args[0].ID()).D();
|
||||
}
|
||||
else {
|
||||
fcvtzs(GetReg<RA_32>(Node), GetSrc(Op->Header.Args[0].ID()).S());
|
||||
Src = GetSrc(Op->Header.Args[0].ID()).S();
|
||||
}
|
||||
}
|
||||
|
||||
DEF_OP(Float_ToGPR_U) {
|
||||
LogMan::Msg::D("Unimplemented");
|
||||
if (IROp->Size == 8) {
|
||||
Dst = GetReg<RA_64>(Node);
|
||||
}
|
||||
else {
|
||||
Dst = GetReg<RA_32>(Node);
|
||||
}
|
||||
|
||||
fcvtzs(Dst, Src);
|
||||
}
|
||||
|
||||
DEF_OP(Float_ToGPR_S) {
|
||||
auto Op = IROp->C<IR::IROp_Float_ToGPR_S>();
|
||||
if (Op->Header.ElementSize == 8) {
|
||||
|
||||
aarch64::Register Dst{};
|
||||
aarch64::VRegister Src{};
|
||||
if (Op->SrcElementSize == 8) {
|
||||
frinti(VTMP1.D(), GetSrc(Op->Header.Args[0].ID()).D());
|
||||
fcvtzs(GetReg<RA_64>(Node), VTMP1.D());
|
||||
Src = VTMP1.D();
|
||||
}
|
||||
else {
|
||||
frinti(VTMP1.S(), GetSrc(Op->Header.Args[0].ID()).S());
|
||||
fcvtzs(GetReg<RA_32>(Node), VTMP1.S());
|
||||
Src = VTMP1.S();
|
||||
}
|
||||
|
||||
if (IROp->Size == 8) {
|
||||
Dst = GetReg<RA_64>(Node);
|
||||
}
|
||||
else {
|
||||
Dst = GetReg<RA_32>(Node);
|
||||
}
|
||||
|
||||
fcvtzs(Dst, Src);
|
||||
}
|
||||
|
||||
DEF_OP(FCmp) {
|
||||
@@ -1087,9 +1102,7 @@ void Arm64JITCore::RegisterALUHandlers() {
|
||||
REGISTER_OP(SBFE, Sbfe);
|
||||
REGISTER_OP(SELECT, Select);
|
||||
REGISTER_OP(VEXTRACTTOGPR, VExtractToGPR);
|
||||
REGISTER_OP(FLOAT_TOGPR_ZU, Float_ToGPR_ZU);
|
||||
REGISTER_OP(FLOAT_TOGPR_ZS, Float_ToGPR_ZS);
|
||||
REGISTER_OP(FLOAT_TOGPR_U, Float_ToGPR_U);
|
||||
REGISTER_OP(FLOAT_TOGPR_S, Float_ToGPR_S);
|
||||
REGISTER_OP(FCMP, FCmp);
|
||||
|
||||
|
||||
@@ -56,10 +56,6 @@ DEF_OP(VCastFromGPR) {
|
||||
}
|
||||
}
|
||||
|
||||
DEF_OP(Float_FromGPR_U) {
|
||||
LOGMAN_MSG_A("Unimplemented");
|
||||
}
|
||||
|
||||
DEF_OP(Float_FromGPR_S) {
|
||||
auto Op = IROp->C<IR::IROp_Float_FromGPR_S>();
|
||||
uint16_t Conv = (Op->Header.ElementSize << 8) | Op->SrcElementSize;
|
||||
@@ -99,19 +95,6 @@ DEF_OP(Float_FToF) {
|
||||
}
|
||||
}
|
||||
|
||||
DEF_OP(Vector_UToF) {
|
||||
auto Op = IROp->C<IR::IROp_Vector_UToF>();
|
||||
switch (Op->Header.ElementSize) {
|
||||
case 4:
|
||||
ucvtf(GetDst(Node).V4S(), GetSrc(Op->Header.Args[0].ID()).V4S());
|
||||
break;
|
||||
case 8:
|
||||
ucvtf(GetDst(Node).V2D(), GetSrc(Op->Header.Args[0].ID()).V2D());
|
||||
break;
|
||||
default: LOGMAN_MSG_A("Unknown castGPR element size: %d", Op->Header.ElementSize);
|
||||
}
|
||||
}
|
||||
|
||||
DEF_OP(Vector_SToF) {
|
||||
auto Op = IROp->C<IR::IROp_Vector_SToF>();
|
||||
switch (Op->Header.ElementSize) {
|
||||
@@ -125,19 +108,6 @@ DEF_OP(Vector_SToF) {
|
||||
}
|
||||
}
|
||||
|
||||
DEF_OP(Vector_FToZU) {
|
||||
auto Op = IROp->C<IR::IROp_Vector_FToZU>();
|
||||
switch (Op->Header.ElementSize) {
|
||||
case 4:
|
||||
fcvtzu(GetDst(Node).V4S(), GetSrc(Op->Header.Args[0].ID()).V4S());
|
||||
break;
|
||||
case 8:
|
||||
fcvtzu(GetDst(Node).V2D(), GetSrc(Op->Header.Args[0].ID()).V2D());
|
||||
break;
|
||||
default: LOGMAN_MSG_A("Unknown castGPR element size: %d", Op->Header.ElementSize);
|
||||
}
|
||||
}
|
||||
|
||||
DEF_OP(Vector_FToZS) {
|
||||
auto Op = IROp->C<IR::IROp_Vector_FToZS>();
|
||||
switch (Op->Header.ElementSize) {
|
||||
@@ -151,21 +121,6 @@ DEF_OP(Vector_FToZS) {
|
||||
}
|
||||
}
|
||||
|
||||
DEF_OP(Vector_FToU) {
|
||||
auto Op = IROp->C<IR::IROp_Vector_FToU>();
|
||||
switch (Op->Header.ElementSize) {
|
||||
case 4:
|
||||
frinti(GetDst(Node).V4S(), GetSrc(Op->Header.Args[0].ID()).V4S());
|
||||
fcvtzu(GetDst(Node).V4S(), GetDst(Node).V4S());
|
||||
break;
|
||||
case 8:
|
||||
frinti(GetDst(Node).V2D(), GetSrc(Op->Header.Args[0].ID()).V2D());
|
||||
fcvtzu(GetDst(Node).V2D(), GetDst(Node).V2D());
|
||||
break;
|
||||
default: LOGMAN_MSG_A("Unknown castGPR element size: %d", Op->Header.ElementSize);
|
||||
}
|
||||
}
|
||||
|
||||
DEF_OP(Vector_FToS) {
|
||||
auto Op = IROp->C<IR::IROp_Vector_FToS>();
|
||||
switch (Op->Header.ElementSize) {
|
||||
@@ -259,14 +214,10 @@ void Arm64JITCore::RegisterConversionHandlers() {
|
||||
#define REGISTER_OP(op, x) OpHandlers[FEXCore::IR::IROps::OP_##op] = &Arm64JITCore::Op_##x
|
||||
REGISTER_OP(VINSGPR, VInsGPR);
|
||||
REGISTER_OP(VCASTFROMGPR, VCastFromGPR);
|
||||
REGISTER_OP(FLOAT_FROMGPR_U, Float_FromGPR_U);
|
||||
REGISTER_OP(FLOAT_FROMGPR_S, Float_FromGPR_S);
|
||||
REGISTER_OP(FLOAT_FTOF, Float_FToF);
|
||||
REGISTER_OP(VECTOR_UTOF, Vector_UToF);
|
||||
REGISTER_OP(VECTOR_STOF, Vector_SToF);
|
||||
REGISTER_OP(VECTOR_FTOZU, Vector_FToZU);
|
||||
REGISTER_OP(VECTOR_FTOZS, Vector_FToZS);
|
||||
REGISTER_OP(VECTOR_FTOU, Vector_FToU);
|
||||
REGISTER_OP(VECTOR_FTOS, Vector_FToS);
|
||||
REGISTER_OP(VECTOR_FTOF, Vector_FToF);
|
||||
REGISTER_OP(VECTOR_FTOI, Vector_FToI);
|
||||
|
||||
@@ -240,7 +240,6 @@ private:
|
||||
DEF_OP(VExtractToGPR);
|
||||
DEF_OP(Float_ToGPR_ZU);
|
||||
DEF_OP(Float_ToGPR_ZS);
|
||||
DEF_OP(Float_ToGPR_U);
|
||||
DEF_OP(Float_ToGPR_S);
|
||||
DEF_OP(FCmp);
|
||||
|
||||
@@ -277,14 +276,10 @@ private:
|
||||
///< Conversion ops
|
||||
DEF_OP(VInsGPR);
|
||||
DEF_OP(VCastFromGPR);
|
||||
DEF_OP(Float_FromGPR_U);
|
||||
DEF_OP(Float_FromGPR_S);
|
||||
DEF_OP(Float_FToF);
|
||||
DEF_OP(Vector_UToF);
|
||||
DEF_OP(Vector_SToF);
|
||||
DEF_OP(Vector_FToZU);
|
||||
DEF_OP(Vector_FToZS);
|
||||
DEF_OP(Vector_FToU);
|
||||
DEF_OP(Vector_FToS);
|
||||
DEF_OP(Vector_FToF);
|
||||
DEF_OP(Vector_FToI);
|
||||
|
||||
+42
-23
@@ -1108,42 +1108,63 @@ DEF_OP(VExtractToGPR) {
|
||||
}
|
||||
}
|
||||
|
||||
DEF_OP(Float_ToGPR_ZU) {
|
||||
LogMan::Msg::D("Unimplemented");
|
||||
}
|
||||
|
||||
DEF_OP(Float_ToGPR_ZS) {
|
||||
auto Op = IROp->C<IR::IROp_Float_ToGPR_ZS>();
|
||||
if (Op->Header.ElementSize == 8) {
|
||||
cvttsd2si(GetDst<RA_64>(Node), GetSrc(Op->Header.Args[0].ID()));
|
||||
}
|
||||
else {
|
||||
cvttss2si(GetDst<RA_32>(Node), GetSrc(Op->Header.Args[0].ID()));
|
||||
}
|
||||
}
|
||||
|
||||
DEF_OP(Float_ToGPR_U) {
|
||||
LogMan::Msg::D("Unimplemented");
|
||||
uint16_t Conv = (IROp->Size << 8) | Op->SrcElementSize;
|
||||
switch (Conv) {
|
||||
case 0x0804: // int64_t <- float
|
||||
cvttss2si(GetDst<RA_64>(Node), GetSrc(Op->Header.Args[0].ID()));
|
||||
break;
|
||||
case 0x0808: // int64_t <- double
|
||||
cvttsd2si(GetDst<RA_64>(Node), GetSrc(Op->Header.Args[0].ID()));
|
||||
break;
|
||||
case 0x0404: // int32_t <- float
|
||||
cvttss2si(GetDst<RA_32>(Node), GetSrc(Op->Header.Args[0].ID()));
|
||||
break;
|
||||
case 0x0408: // int32_t <- double
|
||||
cvttsd2si(GetDst<RA_32>(Node), GetSrc(Op->Header.Args[0].ID()));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
DEF_OP(Float_ToGPR_S) {
|
||||
auto Op = IROp->C<IR::IROp_Float_ToGPR_S>();
|
||||
if (Op->Header.ElementSize == 8) {
|
||||
cvtsd2si(GetDst<RA_64>(Node), GetSrc(Op->Header.Args[0].ID()));
|
||||
}
|
||||
else {
|
||||
cvtss2si(GetDst<RA_32>(Node), GetSrc(Op->Header.Args[0].ID()));
|
||||
uint16_t Conv = (IROp->Size << 8) | Op->SrcElementSize;
|
||||
switch (Conv) {
|
||||
case 0x0804: // int64_t <- float
|
||||
cvtss2si(GetDst<RA_64>(Node), GetSrc(Op->Header.Args[0].ID()));
|
||||
break;
|
||||
case 0x0808: // int64_t <- double
|
||||
cvtsd2si(GetDst<RA_64>(Node), GetSrc(Op->Header.Args[0].ID()));
|
||||
break;
|
||||
case 0x0404: // int32_t <- float
|
||||
cvtss2si(GetDst<RA_32>(Node), GetSrc(Op->Header.Args[0].ID()));
|
||||
break;
|
||||
case 0x0408: // int32_t <- double
|
||||
cvtsd2si(GetDst<RA_32>(Node), GetSrc(Op->Header.Args[0].ID()));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
DEF_OP(FCmp) {
|
||||
auto Op = IROp->C<IR::IROp_FCmp>();
|
||||
|
||||
if (Op->ElementSize == 4) {
|
||||
ucomiss(GetSrc(Op->Header.Args[0].ID()), GetSrc(Op->Header.Args[1].ID()));
|
||||
if (Op->Flags & (1 << IR::FCMP_FLAG_UNORDERED)) {
|
||||
if (Op->ElementSize == 4) {
|
||||
ucomiss(GetSrc(Op->Header.Args[0].ID()), GetSrc(Op->Header.Args[1].ID()));
|
||||
}
|
||||
else {
|
||||
ucomisd(GetSrc(Op->Header.Args[0].ID()), GetSrc(Op->Header.Args[1].ID()));
|
||||
}
|
||||
}
|
||||
else {
|
||||
ucomisd(GetSrc(Op->Header.Args[0].ID()), GetSrc(Op->Header.Args[1].ID()));
|
||||
if (Op->ElementSize == 4) {
|
||||
comiss(GetSrc(Op->Header.Args[0].ID()), GetSrc(Op->Header.Args[1].ID()));
|
||||
}
|
||||
else {
|
||||
comisd(GetSrc(Op->Header.Args[0].ID()), GetSrc(Op->Header.Args[1].ID()));
|
||||
}
|
||||
}
|
||||
mov (rdx, 0);
|
||||
|
||||
@@ -1217,9 +1238,7 @@ void X86JITCore::RegisterALUHandlers() {
|
||||
REGISTER_OP(SBFE, Sbfe);
|
||||
REGISTER_OP(SELECT, Select);
|
||||
REGISTER_OP(VEXTRACTTOGPR, VExtractToGPR);
|
||||
REGISTER_OP(FLOAT_TOGPR_ZU, Float_ToGPR_ZU);
|
||||
REGISTER_OP(FLOAT_TOGPR_ZS, Float_ToGPR_ZS);
|
||||
REGISTER_OP(FLOAT_TOGPR_U, Float_ToGPR_U);
|
||||
REGISTER_OP(FLOAT_TOGPR_S, Float_ToGPR_S);
|
||||
REGISTER_OP(FCMP, FCmp);
|
||||
#undef REGISTER_OP
|
||||
|
||||
@@ -56,10 +56,6 @@ DEF_OP(VCastFromGPR) {
|
||||
}
|
||||
}
|
||||
|
||||
DEF_OP(Float_FromGPR_U) {
|
||||
LOGMAN_MSG_A("Unimplemented");
|
||||
}
|
||||
|
||||
DEF_OP(Float_FromGPR_S) {
|
||||
auto Op = IROp->C<IR::IROp_Float_FromGPR_S>();
|
||||
uint16_t Conv = (Op->Header.ElementSize << 8) | Op->SrcElementSize;
|
||||
@@ -99,10 +95,6 @@ DEF_OP(Float_FToF) {
|
||||
}
|
||||
}
|
||||
|
||||
DEF_OP(Vector_UToF) {
|
||||
LOGMAN_MSG_A("Unimplemented");
|
||||
}
|
||||
|
||||
DEF_OP(Vector_SToF) {
|
||||
auto Op = IROp->C<IR::IROp_Vector_SToF>();
|
||||
switch (Op->Header.ElementSize) {
|
||||
@@ -125,10 +117,6 @@ DEF_OP(Vector_SToF) {
|
||||
}
|
||||
}
|
||||
|
||||
DEF_OP(Vector_FToZU) {
|
||||
LOGMAN_MSG_A("Unimplemented");
|
||||
}
|
||||
|
||||
DEF_OP(Vector_FToZS) {
|
||||
auto Op = IROp->C<IR::IROp_Vector_FToZS>();
|
||||
switch (Op->Header.ElementSize) {
|
||||
@@ -142,10 +130,6 @@ DEF_OP(Vector_FToZS) {
|
||||
}
|
||||
}
|
||||
|
||||
DEF_OP(Vector_FToU) {
|
||||
LOGMAN_MSG_A("Unimplemented");
|
||||
}
|
||||
|
||||
DEF_OP(Vector_FToS) {
|
||||
auto Op = IROp->C<IR::IROp_Vector_FToS>();
|
||||
switch (Op->Header.ElementSize) {
|
||||
@@ -213,14 +197,10 @@ void X86JITCore::RegisterConversionHandlers() {
|
||||
#define REGISTER_OP(op, x) OpHandlers[FEXCore::IR::IROps::OP_##op] = &X86JITCore::Op_##x
|
||||
REGISTER_OP(VINSGPR, VInsGPR);
|
||||
REGISTER_OP(VCASTFROMGPR, VCastFromGPR);
|
||||
REGISTER_OP(FLOAT_FROMGPR_U, Float_FromGPR_U);
|
||||
REGISTER_OP(FLOAT_FROMGPR_S, Float_FromGPR_S);
|
||||
REGISTER_OP(FLOAT_FTOF, Float_FToF);
|
||||
REGISTER_OP(VECTOR_UTOF, Vector_UToF);
|
||||
REGISTER_OP(VECTOR_STOF, Vector_SToF);
|
||||
REGISTER_OP(VECTOR_FTOZU, Vector_FToZU);
|
||||
REGISTER_OP(VECTOR_FTOZS, Vector_FToZS);
|
||||
REGISTER_OP(VECTOR_FTOU, Vector_FToU);
|
||||
REGISTER_OP(VECTOR_FTOS, Vector_FToS);
|
||||
REGISTER_OP(VECTOR_FTOF, Vector_FToF);
|
||||
REGISTER_OP(VECTOR_FTOI, Vector_FToI);
|
||||
|
||||
@@ -241,9 +241,7 @@ private:
|
||||
DEF_OP(Sbfe);
|
||||
DEF_OP(Select);
|
||||
DEF_OP(VExtractToGPR);
|
||||
DEF_OP(Float_ToGPR_ZU);
|
||||
DEF_OP(Float_ToGPR_ZS);
|
||||
DEF_OP(Float_ToGPR_U);
|
||||
DEF_OP(Float_ToGPR_S);
|
||||
DEF_OP(FCmp);
|
||||
DEF_OP(F80Cmp);
|
||||
@@ -281,14 +279,11 @@ private:
|
||||
///< Conversion ops
|
||||
DEF_OP(VInsGPR);
|
||||
DEF_OP(VCastFromGPR);
|
||||
DEF_OP(Float_FromGPR_U);
|
||||
DEF_OP(Float_FromGPR_S);
|
||||
DEF_OP(Float_FToF);
|
||||
DEF_OP(Vector_UToF);
|
||||
DEF_OP(Vector_SToF);
|
||||
DEF_OP(Vector_FToZU);
|
||||
DEF_OP(Vector_FToZS);
|
||||
DEF_OP(Vector_FToU);
|
||||
DEF_OP(Vector_FToS);
|
||||
DEF_OP(Vector_FToF);
|
||||
DEF_OP(Vector_FToI);
|
||||
|
||||
+30
-62
@@ -6163,16 +6163,13 @@ void OpDispatchBuilder::MOVDDUPOp(OpcodeArgs) {
|
||||
StoreResult(FPRClass, Op, Res, -1);
|
||||
}
|
||||
|
||||
template<size_t DstElementSize, bool Signed>
|
||||
template<size_t DstElementSize>
|
||||
void OpDispatchBuilder::CVTGPR_To_FPR(OpcodeArgs) {
|
||||
OrderedNode *Src = LoadSource(GPRClass, Op, Op->Src[0], Op->Flags, -1);
|
||||
|
||||
size_t GPRSize = GetSrcSize(Op);
|
||||
|
||||
if (Signed)
|
||||
Src = _Float_FromGPR_S(DstElementSize, GPRSize, Src);
|
||||
else
|
||||
Src = _Float_FromGPR_U(DstElementSize, GPRSize, Src);
|
||||
Src = _Float_FromGPR_S(DstElementSize, GPRSize, Src);
|
||||
|
||||
OrderedNode *Dest = LoadSource_WithOpSize(FPRClass, Op, Op->Dest, 16, Op->Flags, -1);
|
||||
|
||||
@@ -6181,7 +6178,7 @@ void OpDispatchBuilder::CVTGPR_To_FPR(OpcodeArgs) {
|
||||
StoreResult(FPRClass, Op, Src, -1);
|
||||
}
|
||||
|
||||
template<size_t SrcElementSize, bool Signed, bool HostRoundingMode>
|
||||
template<size_t SrcElementSize, bool HostRoundingMode>
|
||||
void OpDispatchBuilder::CVTFPR_To_GPR(OpcodeArgs) {
|
||||
OrderedNode *Src = LoadSource(FPRClass, Op, Op->Src[0], Op->Flags, -1);
|
||||
|
||||
@@ -6189,32 +6186,18 @@ void OpDispatchBuilder::CVTFPR_To_GPR(OpcodeArgs) {
|
||||
// Source Element size is determined by instruction
|
||||
size_t GPRSize = GetDstSize(Op);
|
||||
|
||||
size_t ElementSize = SrcElementSize;
|
||||
if (HostRoundingMode) {
|
||||
if (Signed)
|
||||
Src = _Float_ToGPR_S(Src, SrcElementSize);
|
||||
else
|
||||
Src = _Float_ToGPR_U(Src, SrcElementSize);
|
||||
Src = _Float_ToGPR_S(Src, ElementSize, GPRSize);
|
||||
}
|
||||
else {
|
||||
if (Signed)
|
||||
Src = _Float_ToGPR_ZS(Src, SrcElementSize);
|
||||
else
|
||||
Src = _Float_ToGPR_ZU(Src, SrcElementSize);
|
||||
}
|
||||
|
||||
if (GPRSize > SrcElementSize) {
|
||||
if (Signed) {
|
||||
Src = _Sext(SrcElementSize * 8, Src);
|
||||
}
|
||||
else {
|
||||
Src = _Bfe(SrcElementSize * 8, 0, Src);
|
||||
}
|
||||
Src = _Float_ToGPR_ZS(Src, ElementSize, GPRSize);
|
||||
}
|
||||
|
||||
StoreResult_WithOpSize(GPRClass, Op, Op->Dest, Src, GPRSize, -1);
|
||||
}
|
||||
|
||||
template<size_t SrcElementSize, bool Signed, bool Widen>
|
||||
template<size_t SrcElementSize, bool Widen>
|
||||
void OpDispatchBuilder::Vector_CVT_Int_To_Float(OpcodeArgs) {
|
||||
OrderedNode *Src = LoadSource(FPRClass, Op, Op->Src[0], Op->Flags, -1);
|
||||
|
||||
@@ -6225,15 +6208,12 @@ void OpDispatchBuilder::Vector_CVT_Int_To_Float(OpcodeArgs) {
|
||||
ElementSize <<= 1;
|
||||
}
|
||||
|
||||
if (Signed)
|
||||
Src = _Vector_SToF(Src, Size, ElementSize);
|
||||
else
|
||||
Src = _Vector_UToF(Src, Size, ElementSize);
|
||||
Src = _Vector_SToF(Src, Size, ElementSize);
|
||||
|
||||
StoreResult(FPRClass, Op, Src, -1);
|
||||
}
|
||||
|
||||
template<size_t SrcElementSize, bool Signed, bool Narrow, bool HostRoundingMode>
|
||||
template<size_t SrcElementSize, bool Narrow, bool HostRoundingMode>
|
||||
void OpDispatchBuilder::Vector_CVT_Float_To_Int(OpcodeArgs) {
|
||||
OrderedNode *Src = LoadSource(FPRClass, Op, Op->Src[0], Op->Flags, -1);
|
||||
|
||||
@@ -6246,16 +6226,10 @@ void OpDispatchBuilder::Vector_CVT_Float_To_Int(OpcodeArgs) {
|
||||
}
|
||||
|
||||
if (HostRoundingMode) {
|
||||
if (Signed)
|
||||
Src = _Vector_FToS(Src, Size, ElementSize);
|
||||
else
|
||||
Src = _Vector_FToU(Src, Size, ElementSize);
|
||||
Src = _Vector_FToS(Src, Size, ElementSize);
|
||||
}
|
||||
else {
|
||||
if (Signed)
|
||||
Src = _Vector_FToZS(Src, Size, ElementSize);
|
||||
else
|
||||
Src = _Vector_FToZU(Src, Size, ElementSize);
|
||||
Src = _Vector_FToZS(Src, Size, ElementSize);
|
||||
}
|
||||
|
||||
StoreResult_WithOpSize(FPRClass, Op, Op->Dest, Src, Size, -1);
|
||||
@@ -6317,7 +6291,7 @@ void OpDispatchBuilder::MMX_To_XMM_Vector_CVT_Int_To_Float(OpcodeArgs) {
|
||||
StoreResult(FPRClass, Op, Dest, -1);
|
||||
}
|
||||
|
||||
template<size_t SrcElementSize, bool Signed, bool Narrow, bool HostRoundingMode>
|
||||
template<size_t SrcElementSize, bool Narrow, bool HostRoundingMode>
|
||||
void OpDispatchBuilder::XMM_To_MMX_Vector_CVT_Float_To_Int(OpcodeArgs) {
|
||||
OrderedNode *Src = LoadSource(FPRClass, Op, Op->Src[0], Op->Flags, -1);
|
||||
|
||||
@@ -6330,16 +6304,10 @@ void OpDispatchBuilder::XMM_To_MMX_Vector_CVT_Float_To_Int(OpcodeArgs) {
|
||||
}
|
||||
|
||||
if (HostRoundingMode) {
|
||||
if (Signed)
|
||||
Src = _Vector_FToS(Src, Size, ElementSize);
|
||||
else
|
||||
Src = _Vector_FToU(Src, Size, ElementSize);
|
||||
Src = _Vector_FToS(Src, Size, ElementSize);
|
||||
}
|
||||
else {
|
||||
if (Signed)
|
||||
Src = _Vector_FToZS(Src, Size, ElementSize);
|
||||
else
|
||||
Src = _Vector_FToZU(Src, Size, ElementSize);
|
||||
Src = _Vector_FToZS(Src, Size, ElementSize);
|
||||
}
|
||||
|
||||
StoreResult_WithOpSize(FPRClass, Op, Op->Dest, Src, Size, -1);
|
||||
@@ -8846,8 +8814,8 @@ void InstallOpcodeHandlers(Context::OperatingMode Mode) {
|
||||
{0x28, 2, &OpDispatchBuilder::MOVUPSOp},
|
||||
{0x2A, 1, &OpDispatchBuilder::MMX_To_XMM_Vector_CVT_Int_To_Float<4, true, false>},
|
||||
{0x2B, 1, &OpDispatchBuilder::MOVAPSOp},
|
||||
{0x2C, 1, &OpDispatchBuilder::Vector_CVT_Float_To_Int<4, true, false, false>},
|
||||
{0x2D, 1, &OpDispatchBuilder::Vector_CVT_Float_To_Int<4, true, false, true>},
|
||||
{0x2C, 1, &OpDispatchBuilder::Vector_CVT_Float_To_Int<4, false, false>},
|
||||
{0x2D, 1, &OpDispatchBuilder::Vector_CVT_Float_To_Int<4, false, true>},
|
||||
{0x2E, 2, &OpDispatchBuilder::UCOMISxOp<4>},
|
||||
{0x50, 1, &OpDispatchBuilder::MOVMSKOp<4>},
|
||||
{0x51, 1, &OpDispatchBuilder::VectorUnaryOp<IR::OP_VFSQRT, 4, false>},
|
||||
@@ -8860,7 +8828,7 @@ void InstallOpcodeHandlers(Context::OperatingMode Mode) {
|
||||
{0x58, 1, &OpDispatchBuilder::VectorALUOp<IR::OP_VFADD, 4>},
|
||||
{0x59, 1, &OpDispatchBuilder::VectorALUOp<IR::OP_VFMUL, 4>},
|
||||
{0x5A, 1, &OpDispatchBuilder::Vector_CVT_Float_To_Float<8, 4>},
|
||||
{0x5B, 1, &OpDispatchBuilder::Vector_CVT_Int_To_Float<4, true, false>},
|
||||
{0x5B, 1, &OpDispatchBuilder::Vector_CVT_Int_To_Float<4, false>},
|
||||
{0x5C, 1, &OpDispatchBuilder::VectorALUOp<IR::OP_VFSUB, 4>},
|
||||
{0x5D, 1, &OpDispatchBuilder::VectorALUOp<IR::OP_VFMIN, 4>},
|
||||
{0x5E, 1, &OpDispatchBuilder::VectorALUOp<IR::OP_VFDIV, 4>},
|
||||
@@ -9072,17 +9040,17 @@ void InstallOpcodeHandlers(Context::OperatingMode Mode) {
|
||||
{0x12, 1, &OpDispatchBuilder::MOVSLDUPOp},
|
||||
{0x16, 1, &OpDispatchBuilder::MOVSHDUPOp},
|
||||
{0x19, 7, &OpDispatchBuilder::NOPOp},
|
||||
{0x2A, 1, &OpDispatchBuilder::CVTGPR_To_FPR<4, true>},
|
||||
{0x2A, 1, &OpDispatchBuilder::CVTGPR_To_FPR<4>},
|
||||
{0x2B, 1, &OpDispatchBuilder::MOVVectorOp},
|
||||
{0x2C, 1, &OpDispatchBuilder::CVTFPR_To_GPR<4, true, false>},
|
||||
{0x2D, 1, &OpDispatchBuilder::CVTFPR_To_GPR<4, true, true>},
|
||||
{0x2C, 1, &OpDispatchBuilder::CVTFPR_To_GPR<4, false>},
|
||||
{0x2D, 1, &OpDispatchBuilder::CVTFPR_To_GPR<4, true>},
|
||||
{0x51, 1, &OpDispatchBuilder::VectorUnaryOp<IR::OP_VFSQRT, 4, true>},
|
||||
{0x52, 1, &OpDispatchBuilder::VectorUnaryOp<IR::OP_VFRSQRT, 4, true>},
|
||||
{0x53, 1, &OpDispatchBuilder::VectorUnaryOp<IR::OP_VFRECP, 4, true>},
|
||||
{0x58, 1, &OpDispatchBuilder::VectorScalarALUOp<IR::OP_VFADD, 4>},
|
||||
{0x59, 1, &OpDispatchBuilder::VectorScalarALUOp<IR::OP_VFMUL, 4>},
|
||||
{0x5A, 1, &OpDispatchBuilder::Scalar_CVT_Float_To_Float<8, 4>},
|
||||
{0x5B, 1, &OpDispatchBuilder::Vector_CVT_Float_To_Int<4, true, false, false>},
|
||||
{0x5B, 1, &OpDispatchBuilder::Vector_CVT_Float_To_Int<4, false, false>},
|
||||
{0x5C, 1, &OpDispatchBuilder::VectorScalarALUOp<IR::OP_VFSUB, 4>},
|
||||
{0x5D, 1, &OpDispatchBuilder::VectorScalarALUOp<IR::OP_VFMIN, 4>},
|
||||
{0x5E, 1, &OpDispatchBuilder::VectorScalarALUOp<IR::OP_VFDIV, 4>},
|
||||
@@ -9096,17 +9064,17 @@ void InstallOpcodeHandlers(Context::OperatingMode Mode) {
|
||||
{0xBD, 1, &OpDispatchBuilder::LZCNT},
|
||||
{0xC2, 1, &OpDispatchBuilder::VFCMPOp<4, true>},
|
||||
{0xD6, 1, &OpDispatchBuilder::MOVQ2DQ<true>},
|
||||
{0xE6, 1, &OpDispatchBuilder::Vector_CVT_Int_To_Float<4, true, true>},
|
||||
{0xE6, 1, &OpDispatchBuilder::Vector_CVT_Int_To_Float<4, true>},
|
||||
};
|
||||
|
||||
const std::vector<std::tuple<uint8_t, uint8_t, FEXCore::X86Tables::OpDispatchPtr>> RepNEModOpTable = {
|
||||
{0x10, 2, &OpDispatchBuilder::MOVSDOp},
|
||||
{0x12, 1, &OpDispatchBuilder::MOVDDUPOp},
|
||||
{0x19, 7, &OpDispatchBuilder::NOPOp},
|
||||
{0x2A, 1, &OpDispatchBuilder::CVTGPR_To_FPR<8, true>},
|
||||
{0x2A, 1, &OpDispatchBuilder::CVTGPR_To_FPR<8>},
|
||||
{0x2B, 1, &OpDispatchBuilder::MOVVectorOp},
|
||||
{0x2C, 1, &OpDispatchBuilder::CVTFPR_To_GPR<8, true, false>},
|
||||
{0x2D, 1, &OpDispatchBuilder::CVTFPR_To_GPR<8, true, true>},
|
||||
{0x2C, 1, &OpDispatchBuilder::CVTFPR_To_GPR<8, false>},
|
||||
{0x2D, 1, &OpDispatchBuilder::CVTFPR_To_GPR<8, true>},
|
||||
{0x51, 1, &OpDispatchBuilder::VectorUnaryOp<IR::OP_VFSQRT, 8, true>},
|
||||
//x52 = Invalid
|
||||
{0x58, 1, &OpDispatchBuilder::VectorScalarALUOp<IR::OP_VFADD, 8>},
|
||||
@@ -9122,7 +9090,7 @@ void InstallOpcodeHandlers(Context::OperatingMode Mode) {
|
||||
{0xD0, 1, &OpDispatchBuilder::ADDSUBPOp<4>},
|
||||
{0xD6, 1, &OpDispatchBuilder::MOVQ2DQ<false>},
|
||||
{0xC2, 1, &OpDispatchBuilder::VFCMPOp<8, true>},
|
||||
{0xE6, 1, &OpDispatchBuilder::Vector_CVT_Float_To_Int<8, true, true, true>},
|
||||
{0xE6, 1, &OpDispatchBuilder::Vector_CVT_Float_To_Int<8, true, true>},
|
||||
{0xF0, 1, &OpDispatchBuilder::MOVVectorOp},
|
||||
};
|
||||
|
||||
@@ -9136,8 +9104,8 @@ void InstallOpcodeHandlers(Context::OperatingMode Mode) {
|
||||
{0x28, 2, &OpDispatchBuilder::MOVAPSOp},
|
||||
{0x2A, 1, &OpDispatchBuilder::MMX_To_XMM_Vector_CVT_Int_To_Float<4, true, true>},
|
||||
{0x2B, 1, &OpDispatchBuilder::MOVAPSOp},
|
||||
{0x2C, 1, &OpDispatchBuilder::XMM_To_MMX_Vector_CVT_Float_To_Int<8, true, true, false>},
|
||||
{0x2D, 1, &OpDispatchBuilder::XMM_To_MMX_Vector_CVT_Float_To_Int<8, true, true, true>},
|
||||
{0x2C, 1, &OpDispatchBuilder::XMM_To_MMX_Vector_CVT_Float_To_Int<8, true, false>},
|
||||
{0x2D, 1, &OpDispatchBuilder::XMM_To_MMX_Vector_CVT_Float_To_Int<8, true, true>},
|
||||
{0x2E, 2, &OpDispatchBuilder::UCOMISxOp<8>},
|
||||
|
||||
{0x40, 16, &OpDispatchBuilder::CMOVOp},
|
||||
@@ -9150,7 +9118,7 @@ void InstallOpcodeHandlers(Context::OperatingMode Mode) {
|
||||
{0x58, 1, &OpDispatchBuilder::VectorALUOp<IR::OP_VFADD, 8>},
|
||||
{0x59, 1, &OpDispatchBuilder::VectorALUOp<IR::OP_VFMUL, 8>},
|
||||
{0x5A, 1, &OpDispatchBuilder::Vector_CVT_Float_To_Float<4, 8>},
|
||||
{0x5B, 1, &OpDispatchBuilder::Vector_CVT_Float_To_Int<4, true, false, true>},
|
||||
{0x5B, 1, &OpDispatchBuilder::Vector_CVT_Float_To_Int<4, false, true>},
|
||||
{0x5C, 1, &OpDispatchBuilder::VectorALUOp<IR::OP_VFSUB, 8>},
|
||||
{0x5D, 1, &OpDispatchBuilder::VectorALUOp<IR::OP_VFMIN, 8>},
|
||||
{0x5E, 1, &OpDispatchBuilder::VectorALUOp<IR::OP_VFDIV, 8>},
|
||||
@@ -9208,7 +9176,7 @@ void InstallOpcodeHandlers(Context::OperatingMode Mode) {
|
||||
{0xE3, 1, &OpDispatchBuilder::PAVGOp<2>},
|
||||
{0xE4, 1, &OpDispatchBuilder::PMULHW<false>},
|
||||
{0xE5, 1, &OpDispatchBuilder::PMULHW<true>},
|
||||
{0xE6, 1, &OpDispatchBuilder::Vector_CVT_Float_To_Int<8, true, true, false>},
|
||||
{0xE6, 1, &OpDispatchBuilder::Vector_CVT_Float_To_Int<8, true, false>},
|
||||
{0xE7, 1, &OpDispatchBuilder::MOVVectorOp},
|
||||
{0xE8, 1, &OpDispatchBuilder::VectorALUOp<IR::OP_VSQSUB, 1>},
|
||||
{0xE9, 1, &OpDispatchBuilder::VectorALUOp<IR::OP_VSQSUB, 2>},
|
||||
|
||||
@@ -287,21 +287,21 @@ public:
|
||||
template<size_t ElementSize>
|
||||
void PAVGOp(OpcodeArgs);
|
||||
void MOVDDUPOp(OpcodeArgs);
|
||||
template<size_t DstElementSize, bool Signed>
|
||||
template<size_t DstElementSize>
|
||||
void CVTGPR_To_FPR(OpcodeArgs);
|
||||
template<size_t SrcElementSize, bool Signed, bool HostRoundingMode>
|
||||
template<size_t SrcElementSize, bool HostRoundingMode>
|
||||
void CVTFPR_To_GPR(OpcodeArgs);
|
||||
template<size_t SrcElementSize, bool Signed, bool Widen>
|
||||
template<size_t SrcElementSize, bool Widen>
|
||||
void Vector_CVT_Int_To_Float(OpcodeArgs);
|
||||
template<size_t DstElementSize, size_t SrcElementSize>
|
||||
void Scalar_CVT_Float_To_Float(OpcodeArgs);
|
||||
template<size_t DstElementSize, size_t SrcElementSize>
|
||||
void Vector_CVT_Float_To_Float(OpcodeArgs);
|
||||
template<size_t SrcElementSize, bool Signed, bool Narrow, bool HostRoundingMode>
|
||||
template<size_t SrcElementSize, bool Narrow, bool HostRoundingMode>
|
||||
void Vector_CVT_Float_To_Int(OpcodeArgs);
|
||||
template<size_t SrcElementSize, bool Signed, bool Widen>
|
||||
void MMX_To_XMM_Vector_CVT_Int_To_Float(OpcodeArgs);
|
||||
template<size_t SrcElementSize, bool Signed, bool Narrow, bool HostRoundingMode>
|
||||
template<size_t SrcElementSize, bool Narrow, bool HostRoundingMode>
|
||||
void XMM_To_MMX_Vector_CVT_Float_To_Int(OpcodeArgs);
|
||||
void MASKMOVOp(OpcodeArgs);
|
||||
void MOVBetweenGPR_FPR(OpcodeArgs);
|
||||
|
||||
+9
-95
@@ -1483,24 +1483,6 @@
|
||||
]
|
||||
},
|
||||
|
||||
"Float_ToGPR_U": {
|
||||
"Desc": ["Moves the scalar element to a GPR with conversion",
|
||||
"Converts the 32bit or 64bit float to an unsigned integer",
|
||||
"Rounding mode determined by host flag's rounding mode"
|
||||
],
|
||||
"OpClass": "ALU",
|
||||
"HasDest": true,
|
||||
"DestClass": "GPR",
|
||||
"DestSize": "ElementSize",
|
||||
"SSAArgs": "1",
|
||||
"SSANames": [
|
||||
"Scalar"
|
||||
],
|
||||
"Args": [
|
||||
"uint8_t", "ElementSize"
|
||||
]
|
||||
},
|
||||
|
||||
"Float_ToGPR_S": {
|
||||
"Desc": ["Moves the scalar element to a GPR with conversion",
|
||||
"Converts the 32bit or 64bit float to an signed integer",
|
||||
@@ -1509,30 +1491,16 @@
|
||||
"OpClass": "ALU",
|
||||
"HasDest": true,
|
||||
"DestClass": "GPR",
|
||||
"DestSize": "ElementSize",
|
||||
"DestSize": "DestElementSize",
|
||||
"SSAArgs": "1",
|
||||
"SSANames": [
|
||||
"Scalar"
|
||||
],
|
||||
"Args": [
|
||||
"uint8_t", "ElementSize"
|
||||
]
|
||||
},
|
||||
|
||||
"Float_ToGPR_ZU": {
|
||||
"Desc": ["Moves the scalar element to a GPR with conversion",
|
||||
"Converts the 32bit or 64bit float to an unsigned integer rounding towards zero (Truncating)"
|
||||
],
|
||||
"OpClass": "ALU",
|
||||
"HasDest": true,
|
||||
"DestClass": "GPR",
|
||||
"DestSize": "ElementSize",
|
||||
"SSAArgs": "1",
|
||||
"SSANames": [
|
||||
"Scalar"
|
||||
"HelperArgs": [
|
||||
"uint8_t", "DestElementSize"
|
||||
],
|
||||
"Args": [
|
||||
"uint8_t", "ElementSize"
|
||||
"uint8_t", "SrcElementSize"
|
||||
]
|
||||
},
|
||||
|
||||
@@ -1543,13 +1511,16 @@
|
||||
"OpClass": "ALU",
|
||||
"HasDest": true,
|
||||
"DestClass": "GPR",
|
||||
"DestSize": "ElementSize",
|
||||
"DestSize": "DestElementSize",
|
||||
"SSAArgs": "1",
|
||||
"SSANames": [
|
||||
"Scalar"
|
||||
],
|
||||
"HelperArgs": [
|
||||
"uint8_t", "DestElementSize"
|
||||
],
|
||||
"Args": [
|
||||
"uint8_t", "ElementSize"
|
||||
"uint8_t", "SrcElementSize"
|
||||
]
|
||||
},
|
||||
|
||||
@@ -3049,27 +3020,6 @@
|
||||
]
|
||||
},
|
||||
|
||||
"Float_FromGPR_U": {
|
||||
"OpClass": "Conv",
|
||||
"Desc": ["Scalar op: Converts unsigned GPR to Scalar float",
|
||||
"Zeroes the upper bits of the vector register"
|
||||
],
|
||||
"HasDest": true,
|
||||
"DestClass": "FPR",
|
||||
"DestSize": "DstElementSize",
|
||||
"NumElements": "1",
|
||||
"SSAArgs": "1",
|
||||
"SSANames": [
|
||||
"GPR"
|
||||
],
|
||||
"HelperArgs": [
|
||||
"uint8_t", "DstElementSize"
|
||||
],
|
||||
"Args": [
|
||||
"uint8_t", "SrcElementSize"
|
||||
]
|
||||
},
|
||||
|
||||
"Float_FromGPR_S": {
|
||||
"OpClass": "Conv",
|
||||
"Desc": ["Scalar op: Converts signed GPR to Scalar float",
|
||||
@@ -3146,25 +3096,6 @@
|
||||
]
|
||||
},
|
||||
|
||||
"Vector_FToU": {
|
||||
"OpClass": "Conv",
|
||||
"Desc": ["Vector op: Converts float to unsigned integer",
|
||||
"Rounding mode determined by host rounding mode"
|
||||
],
|
||||
"HasDest": true,
|
||||
"DestClass": "FPR",
|
||||
"DestSize": "RegisterSize",
|
||||
"NumElements": "RegisterSize / ElementSize",
|
||||
"SSAArgs": "1",
|
||||
"SSANames": [
|
||||
"Vector"
|
||||
],
|
||||
"HelperArgs": [
|
||||
"uint8_t", "RegisterSize",
|
||||
"uint8_t", "ElementSize"
|
||||
]
|
||||
},
|
||||
|
||||
"Vector_FToS": {
|
||||
"OpClass": "Conv",
|
||||
"Desc": ["Vector op: Converts float to signed integer, rounding towards zero",
|
||||
@@ -3184,23 +3115,6 @@
|
||||
]
|
||||
},
|
||||
|
||||
"Vector_FToZU": {
|
||||
"OpClass": "Conv",
|
||||
"Desc": "Vector op: Converts float to unsigned integer, rounding towards zero",
|
||||
"HasDest": true,
|
||||
"DestClass": "FPR",
|
||||
"DestSize": "RegisterSize",
|
||||
"NumElements": "RegisterSize / ElementSize",
|
||||
"SSAArgs": "1",
|
||||
"SSANames": [
|
||||
"Vector"
|
||||
],
|
||||
"HelperArgs": [
|
||||
"uint8_t", "RegisterSize",
|
||||
"uint8_t", "ElementSize"
|
||||
]
|
||||
},
|
||||
|
||||
"Vector_FToZS": {
|
||||
"OpClass": "Conv",
|
||||
"Desc": "Vector op: Converts float to signed integer, rounding towards zero",
|
||||
|
||||
@@ -315,9 +315,6 @@ friend class FEXCore::IR::PassManager;
|
||||
IRPair<IROp_Vector_FToF> _Vector_FToF(uint8_t RegisterSize, uint8_t DstElementSize, uint8_t SrcElementSize, OrderedNode *ssa0) {
|
||||
return _Vector_FToF(ssa0, SrcElementSize, RegisterSize, DstElementSize);
|
||||
}
|
||||
IRPair<IROp_Float_FromGPR_U> _Float_FromGPR_U(uint8_t DstElementSize, uint8_t SrcElementSize, OrderedNode *ssa0) {
|
||||
return _Float_FromGPR_U(ssa0, SrcElementSize, DstElementSize);
|
||||
}
|
||||
IRPair<IROp_Float_FromGPR_S> _Float_FromGPR_S(uint8_t DstElementSize, uint8_t SrcElementSize, OrderedNode *ssa0) {
|
||||
return _Float_FromGPR_S(ssa0, SrcElementSize, DstElementSize);
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user