Cleans up and renames the CVT ops

Fixes issue #14.

A lot of these were named in very confusing ways.
Makes them very explicit about what the operation is doing
This commit is contained in:
Ryan Houdek committed 2020-03-13 17:42:39 -07:00
1 parent 121bed017c
commit 79ffd11c1d
7 files changed
+233 -221

No files matched your search

@@ -1086,17 +1086,6 @@ void InterpreterCore::ExecuteCode(FEXCore::Core::InternalThreadState *Thread) {
GD = CompResult ? ArgTrue : ArgFalse;
break;
}
case IR::OP_EXTRACTELEMENT: {
auto ExtractElementOp = IROp->C<IR::IROp_ExtractElement>();
uintptr_t DstPtr = GetDest<uintptr_t>(*WrapperOp);
uintptr_t SrcPtr = GetSrc<uintptr_t>(ExtractElementOp->Header.Args[0]);
// Offset to the element offset
SrcPtr += IROp->Size * ExtractElementOp->Idx;
memcpy(reinterpret_cast<void*>(DstPtr), reinterpret_cast<void*>(SrcPtr), IROp->Size);
break;
}
case IR::OP_CAS: {
auto Op = IROp->C<IR::IROp_CAS>();
auto Size = OpSize;
@@ -2399,8 +2388,8 @@ void InterpreterCore::ExecuteCode(FEXCore::Core::InternalThreadState *Thread) {
memcpy(GDP, Tmp, Op->RegisterSize);
break;
}
case IR::OP_VUCVTF: {
auto Op = IROp->C<IR::IROp_VUCVTF>();
case IR::OP_VECTOR_UTOF: {
auto Op = IROp->C<IR::IROp_Vector_UToF>();
void *Src = GetSrc<void*>(Op->Header.Args[0]);
uint8_t Tmp[16];
@@ -2415,8 +2404,8 @@ void InterpreterCore::ExecuteCode(FEXCore::Core::InternalThreadState *Thread) {
memcpy(GDP, Tmp, Op->RegisterSize);
break;
}
case IR::OP_VSCVTF: {
auto Op = IROp->C<IR::IROp_VSCVTF>();
case IR::OP_VECTOR_STOF: {
auto Op = IROp->C<IR::IROp_Vector_SToF>();
void *Src = GetSrc<void*>(Op->Header.Args[0]);
uint8_t Tmp[16];
@@ -2431,6 +2420,38 @@ void InterpreterCore::ExecuteCode(FEXCore::Core::InternalThreadState *Thread) {
memcpy(GDP, Tmp, Op->RegisterSize);
break;
}
case IR::OP_VECTOR_FTOZU: {
auto Op = IROp->C<IR::IROp_Vector_FToZU>();
void *Src = GetSrc<void*>(Op->Header.Args[0]);
uint8_t Tmp[16];
uint8_t Elements = Op->RegisterSize / Op->ElementSize;
auto Func = [](auto a, auto max) { return a; };
switch (Op->ElementSize) {
DO_VECTOR_1SRC_2TYPE_OP(4, uint32_t, float, Func, 0)
DO_VECTOR_1SRC_2TYPE_OP(8, uint64_t, double, Func, 0)
default: LogMan::Msg::A("Unknown Element Size: %d", Op->ElementSize); break;
}
memcpy(GDP, Tmp, Op->RegisterSize);
break;
}
case IR::OP_VECTOR_FTOZS: {
auto Op = IROp->C<IR::IROp_Vector_FToZS>();
void *Src = GetSrc<void*>(Op->Header.Args[0]);
uint8_t Tmp[16];
uint8_t Elements = Op->RegisterSize / Op->ElementSize;
auto Func = [](auto a, auto max) { return a; };
switch (Op->ElementSize) {
DO_VECTOR_1SRC_2TYPE_OP(4, int32_t, float, Func, 0)
DO_VECTOR_1SRC_2TYPE_OP(8, int64_t, double, Func, 0)
default: LogMan::Msg::A("Unknown Element Size: %d", Op->ElementSize); break;
}
memcpy(GDP, Tmp, Op->RegisterSize);
break;
}
case IR::OP_VUMULL: {
auto Op = IROp->C<IR::IROp_VUMull>();
void *Src1 = GetSrc<void*>(Op->Header.Args[0]);
@@ -2469,36 +2490,6 @@ void InterpreterCore::ExecuteCode(FEXCore::Core::InternalThreadState *Thread) {
memcpy(GDP, Tmp, Op->RegisterSize);
break;
}
case IR::OP_VFCVTL: {
auto Op = IROp->C<IR::IROp_VFCVTL>();
void *Src = GetSrc<void*>(Op->Header.Args[0]);
uint8_t Tmp[16];
uint8_t Elements = Op->RegisterSize / Op->ElementSize;
auto Func = [](auto a, auto max) { return a; };
switch (Op->ElementSize) {
DO_VECTOR_1SRC_2TYPE_OP(4, double, float, Func, 0)
default: LogMan::Msg::A("Unknown Element Size: %d", Op->ElementSize); break;
}
memcpy(GDP, Tmp, Op->RegisterSize);
break;
}
case IR::OP_VFCVTN: {
auto Op = IROp->C<IR::IROp_VFCVTN>();
void *Src = GetSrc<void*>(Op->Header.Args[0]);
uint8_t Tmp[16];
uint8_t Elements = Op->RegisterSize / Op->ElementSize;
auto Func = [](auto a, auto max) { return a; };
switch (Op->ElementSize) {
DO_VECTOR_1SRC_2TYPE_OP(8, float, double, Func, 0)
default: LogMan::Msg::A("Unknown Element Size: %d", Op->ElementSize); break;
}
memcpy(GDP, Tmp, Op->RegisterSize);
break;
}
case IR::OP_VSXTL: {
auto Op = IROp->C<IR::IROp_VSXTL>();
void *Src = GetSrc<void*>(Op->Header.Args[0]);
@@ -3055,9 +3046,8 @@ void InterpreterCore::ExecuteCode(FEXCore::Core::InternalThreadState *Thread) {
memcpy(GDP, &Dst, Op->RegisterSize);
break;
}
case IR::OP_SCVTF: {
auto Op = IROp->C<IR::IROp_SCVTF>();
case IR::OP_FLOAT_FROMGPR_S: {
auto Op = IROp->C<IR::IROp_Float_FromGPR_S>();
if (Op->ElementSize == 8) {
double Dst = (double)*GetSrc<int64_t*>(Op->Header.Args[0]);
memcpy(GDP, &Dst, Op->ElementSize);
@@ -3068,8 +3058,20 @@ void InterpreterCore::ExecuteCode(FEXCore::Core::InternalThreadState *Thread) {
}
break;
}
case IR::OP_FCVTZS: {
auto Op = IROp->C<IR::IROp_SCVTF>();
case IR::OP_FLOAT_FROMGPR_U: {
auto Op = IROp->C<IR::IROp_Float_FromGPR_U>();
if (Op->ElementSize == 8) {
double Dst = (double)*GetSrc<uint64_t*>(Op->Header.Args[0]);
memcpy(GDP, &Dst, Op->ElementSize);
}
else {
float Dst = (float)*GetSrc<uint32_t*>(Op->Header.Args[0]);
memcpy(GDP, &Dst, Op->ElementSize);
}
break;
}
case IR::OP_FLOAT_TOGPR_ZS: {
auto Op = IROp->C<IR::IROp_Float_ToGPR_ZS>();
if (Op->ElementSize == 8) {
int64_t Dst = (int64_t)*GetSrc<double*>(Op->Header.Args[0]);
memcpy(GDP, &Dst, Op->ElementSize);
@@ -3080,8 +3082,20 @@ void InterpreterCore::ExecuteCode(FEXCore::Core::InternalThreadState *Thread) {
}
break;
}
case IR::OP_FCVTF: {
auto Op = IROp->C<IR::IROp_FCVTF>();
case IR::OP_FLOAT_TOGPR_ZU: {
auto Op = IROp->C<IR::IROp_Float_ToGPR_ZU>();
if (Op->ElementSize == 8) {
uint64_t Dst = (uint64_t)*GetSrc<double*>(Op->Header.Args[0]);
memcpy(GDP, &Dst, Op->ElementSize);
}
else {
uint32_t Dst = (uint32_t)*GetSrc<float*>(Op->Header.Args[0]);
memcpy(GDP, &Dst, Op->ElementSize);
}
break;
}
case IR::OP_FLOAT_FTOF: {
auto Op = IROp->C<IR::IROp_Float_FToF>();
uint16_t Conv = (Op->DstElementSize << 8) | Op->SrcElementSize;
switch (Conv) {
case 0x0804: { // Double <- Float
@@ -3098,6 +3112,36 @@ void InterpreterCore::ExecuteCode(FEXCore::Core::InternalThreadState *Thread) {
}
break;
}
case IR::OP_VECTOR_FTOF: {
auto Op = IROp->C<IR::IROp_Vector_FToF>();
void *Src = GetSrc<void*>(Op->Header.Args[0]);
uint8_t Tmp[16];
uint16_t Conv = (Op->DstElementSize << 8) | Op->SrcElementSize;
auto Func = [](auto a, auto max) { return a; };
switch (Conv) {
case 0x0804: { // Double <- float
uint8_t Elements = Op->RegisterSize / Op->SrcElementSize;
switch (Op->SrcElementSize) {
DO_VECTOR_1SRC_2TYPE_OP(4, double, float, Func, 0)
}
break;
}
case 0x0408: { // Float <- Double
uint8_t Elements = Op->RegisterSize / Op->SrcElementSize;
switch (Op->SrcElementSize) {
DO_VECTOR_1SRC_2TYPE_OP(8, float, double, Func, 0)
}
break;
break;
}
default: LogMan::Msg::A("Unknown Conversion Type : 0%04x", Conv); break;
}
memcpy(GDP, Tmp, Op->RegisterSize);
break;
}
#define DO_SCALAR_COMPARE_OP(size, type, type2, func) \
case size: { \
auto *Dst_d = reinterpret_cast<type2*>(Tmp); \
+8 -28
View File
@@ -511,26 +511,6 @@ void *JITCore::CompileCode([[maybe_unused]] FEXCore::IR::IRListView<true> const
break;
}
case IR::OP_EXTRACTELEMENT: {
auto Op = IROp->C<IR::IROp_ExtractElement>();
uint64_t PhysReg = RAPass->GetNodeRegister(Op->Header.Args[0].ID());
if (PhysReg >= FPRBase) {
switch (OpSize) {
case 4:
umov(GetDst<RA_32>(Node), GetSrc(Op->Header.Args[0].ID()).V4S(), Op->Idx);
break;
case 8:
umov(GetDst<RA_64>(Node), GetSrc(Op->Header.Args[0].ID()).V2D(), Op->Idx);
break;
default: LogMan::Msg::A("Unhandled ExtractElementSize: %d", OpSize);
}
}
else {
LogMan::Msg::A("Can't handle extract from GPR yet");
}
break;
}
case IR::OP_VEXTRACTTOGPR: {
auto Op = IROp->C<IR::IROp_VExtractToGPR>();
switch (OpSize) {
@@ -773,14 +753,14 @@ void *JITCore::CompileCode([[maybe_unused]] FEXCore::IR::IRListView<true> const
}
case IR::OP_NEG: {
auto Op = IROp->C<IR::IROp_Neg>();
switch (Op->SrcSize / 8) {
switch (OpSize) {
case 4:
neg(GetDst<RA_32>(Node), GetSrc<RA_32>(Op->Header.Args[0].ID()));
break;
case 8:
neg(GetDst<RA_64>(Node), GetSrc<RA_64>(Op->Header.Args[0].ID()));
break;
default: LogMan::Msg::A("Unsupported Not size: %d", Op->SrcSize / 8);
default: LogMan::Msg::A("Unsupported Not size: %d", OpSize);
}
break;
}
@@ -917,14 +897,14 @@ void *JITCore::CompileCode([[maybe_unused]] FEXCore::IR::IRListView<true> const
}
case IR::OP_NOT: {
auto Op = IROp->C<IR::IROp_Not>();
switch (Op->SrcSize / 8) {
switch (OpSize) {
case 4:
mvn(GetDst<RA_32>(Node), GetSrc<RA_32>(Op->Header.Args[0].ID()));
break;
case 8:
mvn(GetDst<RA_64>(Node), GetSrc<RA_64>(Op->Header.Args[0].ID()));
break;
default: LogMan::Msg::A("Unsupported Not size: %d", Op->SrcSize / 8);
default: LogMan::Msg::A("Unsupported Not size: %d", OpSize);
}
break;
}
@@ -2256,8 +2236,8 @@ void *JITCore::CompileCode([[maybe_unused]] FEXCore::IR::IRListView<true> const
}
break;
}
case IR::OP_SCVTF: {
auto Op = IROp->C<IR::IROp_SCVTF>();
case IR::OP_FLOAT_FROMGPR_S: {
auto Op = IROp->C<IR::IROp_Float_FromGPR_S>();
if (Op->ElementSize == 8) {
scvtf(GetDst(Node), GetSrc<RA_64>(Op->Header.Args[0].ID()));
}
@@ -2265,8 +2245,8 @@ void *JITCore::CompileCode([[maybe_unused]] FEXCore::IR::IRListView<true> const
scvtf(GetDst(Node), GetSrc<RA_64>(Op->Header.Args[0].ID()));
break;
}
case IR::OP_FCVTZS: {
auto Op = IROp->C<IR::IROp_SCVTF>();
case IR::OP_FLOAT_TOGPR_ZS: {
auto Op = IROp->C<IR::IROp_Float_ToGPR_ZS>();
if (Op->ElementSize == 8) {
fcvtzs(GetDst<RA_64>(Node), GetSrc(Op->Header.Args[0].ID()));
}
+20 -49
View File
@@ -1905,32 +1905,6 @@ void *JITCore::CompileCode([[maybe_unused]] FEXCore::IR::IRListView<true> const
}
break;
}
case IR::OP_EXTRACTELEMENT: {
auto Op = IROp->C<IR::IROp_ExtractElement>();
uint64_t PhysReg = RAPass->GetNodeRegister(Op->Header.Args[0].ID());
if (PhysReg >= XMMBase) {
switch (OpSize) {
case 1:
pextrb(GetDst<RA_8>(Node), GetSrc(Op->Header.Args[0].ID()), Op->Idx);
break;
case 2:
pextrw(GetDst<RA_16>(Node), GetSrc(Op->Header.Args[0].ID()), Op->Idx);
break;
case 4:
pextrd(GetDst<RA_32>(Node), GetSrc(Op->Header.Args[0].ID()), Op->Idx);
break;
case 8:
pextrq(GetDst<RA_64>(Node), GetSrc(Op->Header.Args[0].ID()), Op->Idx);
break;
default: LogMan::Msg::A("Unhandled ExtractElementSize: %d", OpSize);
}
}
else {
LogMan::Msg::A("Can't handle extract from GPR yet");
}
break;
}
case IR::OP_VINSELEMENT: {
auto Op = IROp->C<IR::IROp_VInsElement>();
movapd(xmm15, GetSrc(Op->Header.Args[0].ID()));
@@ -2443,8 +2417,8 @@ void *JITCore::CompileCode([[maybe_unused]] FEXCore::IR::IRListView<true> const
}
break;
}
case IR::OP_VSCVTF: {
auto Op = IROp->C<IR::IROp_VSCVTF>();
case IR::OP_VECTOR_STOF: {
auto Op = IROp->C<IR::IROp_Vector_SToF>();
switch (Op->ElementSize) {
case 4:
cvtdq2ps(GetDst(Node), GetSrc(Op->Header.Args[0].ID()));
@@ -2465,23 +2439,20 @@ void *JITCore::CompileCode([[maybe_unused]] FEXCore::IR::IRListView<true> const
}
break;
}
case IR::OP_VFCVTL: {
auto Op = IROp->C<IR::IROp_VFCVTL>();
switch (Op->ElementSize) {
case 4:
case IR::OP_VECTOR_FTOF: {
auto Op = IROp->C<IR::IROp_Vector_FToF>();
uint16_t Conv = (Op->DstElementSize << 8) | Op->SrcElementSize;
switch (Conv) {
case 0x0804: { // Double <- Float
cvtps2pd(GetDst(Node), GetSrc(Op->Header.Args[0].ID()));
break;
default: LogMan::Msg::A("Unknown Element Size: %d", Op->ElementSize); break;
}
break;
}
case IR::OP_VFCVTN: {
auto Op = IROp->C<IR::IROp_VFCVTN>();
switch (Op->ElementSize) {
case 8:
break;
}
case 0x0408: { // Float <- Double
cvtpd2ps(GetDst(Node), GetSrc(Op->Header.Args[0].ID()));
break;
default: LogMan::Msg::A("Unknown Element Size: %d", Op->ElementSize); break;
break;
}
default: LogMan::Msg::A("Unknown Conversion Type : 0%04x", Conv); break;
}
break;
}
@@ -2895,8 +2866,8 @@ void *JITCore::CompileCode([[maybe_unused]] FEXCore::IR::IRListView<true> const
}
break;
}
case IR::OP_SCVTF: {
auto Op = IROp->C<IR::IROp_SCVTF>();
case IR::OP_FLOAT_FROMGPR_S: {
auto Op = IROp->C<IR::IROp_Float_FromGPR_S>();
if (Op->ElementSize == 8) {
cvtsi2sd(GetDst(Node), GetSrc<RA_64>(Op->Header.Args[0].ID()));
}
@@ -2904,8 +2875,8 @@ void *JITCore::CompileCode([[maybe_unused]] FEXCore::IR::IRListView<true> const
cvtsi2ss(GetDst(Node), GetSrc<RA_64>(Op->Header.Args[0].ID()));
break;
}
case IR::OP_FCVTZS: {
auto Op = IROp->C<IR::IROp_SCVTF>();
case IR::OP_FLOAT_TOGPR_ZS: {
auto Op = IROp->C<IR::IROp_Float_ToGPR_ZS>();
if (Op->ElementSize == 8) {
cvttsd2si(GetDst<RA_64>(Node), GetSrc(Op->Header.Args[0].ID()));
}
@@ -2913,8 +2884,8 @@ void *JITCore::CompileCode([[maybe_unused]] FEXCore::IR::IRListView<true> const
cvttss2si(GetDst<RA_32>(Node), GetSrc(Op->Header.Args[0].ID()));
break;
}
case IR::OP_FCVTF: {
auto Op = IROp->C<IR::IROp_FCVTF>();
case IR::OP_FLOAT_FTOF: {
auto Op = IROp->C<IR::IROp_Float_FToF>();
uint16_t Conv = (Op->DstElementSize << 8) | Op->SrcElementSize;
switch (Conv) {
case 0x0804: { // Double <- Float
@@ -940,15 +940,6 @@ void LLVMJITCore::HandleIR(FEXCore::IR::IRListView<true> const *IR, IR::NodeWrap
SetDest(*WrapperOp, Result);
break;
}
// The IR's current representation of vectors is actually an array
case IR::OP_EXTRACTELEMENT: {
auto Op = IROp->C<IR::IROp_ExtractElement>();
auto Src = GetSrc(Op->Header.Args[0]);
std::vector<unsigned> Idxs = {Op->Idx};
auto Result = JITState.IRBuilder->CreateExtractValue(Src, Idxs);
SetDest(*WrapperOp, Result);
break;
}
case IR::OP_LOADCONTEXT: {
auto Op = IROp->C<IR::IROp_LoadContext>();
auto Value = CreateContextPtr(Op->Offset, Op->Size);
+71 -58
View File
@@ -1099,10 +1099,10 @@ void OpDispatchBuilder::CPUIDOp(OpcodeArgs) {
OrderedNode *Src = LoadSource(FPRClass, Op, Op->Src[0], Op->Flags, -1);
auto Res = _CPUID(Src);
_StoreContext(FPRClass, 8, offsetof(FEXCore::Core::CPUState, gregs[FEXCore::X86State::REG_RAX]), _ExtractElement(Res, 0));
_StoreContext(FPRClass, 8, offsetof(FEXCore::Core::CPUState, gregs[FEXCore::X86State::REG_RBX]), _ExtractElement(Res, 1));
_StoreContext(FPRClass, 8, offsetof(FEXCore::Core::CPUState, gregs[FEXCore::X86State::REG_RDX]), _ExtractElement(Res, 2));
_StoreContext(FPRClass, 8, offsetof(FEXCore::Core::CPUState, gregs[FEXCore::X86State::REG_RCX]), _ExtractElement(Res, 3));
_StoreContext(GPRClass, 8, offsetof(FEXCore::Core::CPUState, gregs[FEXCore::X86State::REG_RAX]), _Zext(32, _VExtractToGPR(16, 4, Res, 0)));
_StoreContext(GPRClass, 8, offsetof(FEXCore::Core::CPUState, gregs[FEXCore::X86State::REG_RBX]), _Zext(32, _VExtractToGPR(16, 4, Res, 1)));
_StoreContext(GPRClass, 8, offsetof(FEXCore::Core::CPUState, gregs[FEXCore::X86State::REG_RDX]), _Zext(32, _VExtractToGPR(16, 4, Res, 2)));
_StoreContext(GPRClass, 8, offsetof(FEXCore::Core::CPUState, gregs[FEXCore::X86State::REG_RCX]), _Zext(32, _VExtractToGPR(16, 4, Res, 3)));
}
template<bool SHL1Bit>
@@ -2723,33 +2723,6 @@ void OpDispatchBuilder::PCMPGTOp(OpcodeArgs) {
StoreResult(FPRClass, Op, ALUOp, -1);
}
void OpDispatchBuilder::MOVDOp(OpcodeArgs) {
if (Op->Dest.TypeNone.Type == FEXCore::X86Tables::DecodedOperand::TYPE_GPR &&
Op->Dest.TypeGPR.GPR >= FEXCore::X86State::REG_XMM_0) {
OrderedNode *Src = LoadSource(GPRClass, Op, Op->Src[0], Op->Flags, -1);
// When destination is XMM then it is zext to 128bit
uint64_t SrcSize = GetSrcSize(Op) * 8;
while (SrcSize != 128) {
Src = _Zext(SrcSize, Src);
SrcSize *= 2;
}
StoreResult(FPRClass, Op, Op->Dest, Src, -1);
}
else {
// Destination is GPR or mem
// Extract from XMM first
uint8_t ElementSize = 4;
if (Op->Flags & X86Tables::DecodeFlags::FLAG_REX_WIDENING)
ElementSize = 8;
OrderedNode *Src = LoadSource(FPRClass, Op, Op->Src[0],Op->Flags, -1);
Src = _VExtractToGPR(GetSrcSize(Op), ElementSize, Src, 0);
StoreResult(GPRClass, Op, Op->Dest, Src, -1);
}
}
void OpDispatchBuilder::CMPXCHGOp(OpcodeArgs) {
// CMPXCHG ModRM, reg, {RAX}
// MemData = *ModRM.dest
@@ -3921,7 +3894,6 @@ void OpDispatchBuilder::PSLLI(OpcodeArgs) {
StoreResult(FPRClass, Op, Shift, -1);
}
template<size_t ElementSize, bool Scalar, uint32_t SrcIndex>
void OpDispatchBuilder::PSLL(OpcodeArgs) {
OrderedNode *Src = LoadSource(FPRClass, Op, Op->Src[SrcIndex], Op->Flags, -1);
@@ -4004,7 +3976,7 @@ void OpDispatchBuilder::MOVDDUPOp(OpcodeArgs) {
}
template<size_t DstElementSize, bool Signed>
void OpDispatchBuilder::CVT(OpcodeArgs) {
void OpDispatchBuilder::CVTGPR_To_FPR(OpcodeArgs) {
OrderedNode *Src = LoadSource(GPRClass, Op, Op->Src[0], Op->Flags, -1);
if (Op->Flags & X86Tables::DecodeFlags::FLAG_REX_WIDENING) {
@@ -4024,9 +3996,9 @@ void OpDispatchBuilder::CVT(OpcodeArgs) {
}
if (Signed)
Src = _SCVTF(Src, DstElementSize);
Src = _Float_FromGPR_S(Src, DstElementSize);
else
Src = _UCVTF(Src, DstElementSize);
Src = _Float_FromGPR_U(Src, DstElementSize);
OrderedNode *Dest = LoadSource_WithOpSize(FPRClass, Op, Op->Dest, 16, Op->Flags, -1);
@@ -4036,19 +4008,19 @@ void OpDispatchBuilder::CVT(OpcodeArgs) {
}
template<size_t SrcElementSize, bool Signed>
void OpDispatchBuilder::FCVT(OpcodeArgs) {
void OpDispatchBuilder::CVTFPR_To_GPR(OpcodeArgs) {
OrderedNode *Src = LoadSource(FPRClass, Op, Op->Src[0], Op->Flags, -1);
if (Signed)
Src = _FCVTZS(Src, SrcElementSize);
Src = _Float_ToGPR_ZS(Src, SrcElementSize);
else
Src = _FCVTZU(Src, SrcElementSize);
Src = _Float_ToGPR_ZU(Src, SrcElementSize);
StoreResult_WithOpSize(GPRClass, Op, Op->Dest, Src, SrcElementSize, -1);
}
template<size_t SrcElementSize, bool Signed, bool Widen>
void OpDispatchBuilder::VFCVT(OpcodeArgs) {
void OpDispatchBuilder::Vector_CVT_Int_To_Float(OpcodeArgs) {
OrderedNode *Src = LoadSource(FPRClass, Op, Op->Src[0], Op->Flags, -1);
size_t ElementSize = SrcElementSize;
@@ -4059,39 +4031,77 @@ void OpDispatchBuilder::VFCVT(OpcodeArgs) {
}
if (Signed)
Src = _VSCVTF(Src, Size, ElementSize);
Src = _Vector_SToF(Src, Size, ElementSize);
else
Src = _VUCVTF(Src, Size, ElementSize);
Src = _Vector_UToF(Src, Size, ElementSize);
StoreResult(FPRClass, Op, Src, -1);
}
template<size_t SrcElementSize, bool Signed>
void OpDispatchBuilder::Vector_CVT_Float_To_Int(OpcodeArgs) {
OrderedNode *Src = LoadSource(FPRClass, Op, Op->Src[0], Op->Flags, -1);
if (Signed)
Src = _Vector_FToZS(Src, 16, SrcElementSize);
else
Src = _Vector_FToZU(Src, 16, SrcElementSize);
StoreResult_WithOpSize(FPRClass, Op, Op->Dest, Src, SrcElementSize, -1);
}
template<size_t DstElementSize, size_t SrcElementSize>
void OpDispatchBuilder::FCVTF(OpcodeArgs) {
void OpDispatchBuilder::Scalar_CVT_Float_To_Float(OpcodeArgs) {
OrderedNode *Dest = LoadSource(FPRClass, Op, Op->Dest, Op->Flags, -1);
OrderedNode *Src = LoadSource(FPRClass, Op, Op->Src[0], Op->Flags, -1);
Src = _FCVTF(Src, DstElementSize, SrcElementSize);
Src = _Float_FToF(Src, DstElementSize, SrcElementSize);
Src = _VInsElement(16, DstElementSize, 0, 0, Dest, Src);
StoreResult(FPRClass, Op, Src, -1);
}
template<size_t DstElementSize, size_t SrcElementSize>
void OpDispatchBuilder::VFCVTF(OpcodeArgs) {
void OpDispatchBuilder::Vector_CVT_Float_To_Float(OpcodeArgs) {
OrderedNode *Src = LoadSource(FPRClass, Op, Op->Src[0], Op->Flags, -1);
size_t Size = GetDstSize(Op);
if (DstElementSize > SrcElementSize) {
Src = _VFCVTL(Src, Size, SrcElementSize);
Src = _Vector_FToF(Src, Size, SrcElementSize << 1, SrcElementSize);
}
else {
Src = _VFCVTN(Src, Size, SrcElementSize);
Src = _Vector_FToF(Src, Size, SrcElementSize >> 1, SrcElementSize);
}
StoreResult(FPRClass, Op, Src, -1);
}
void OpDispatchBuilder::MOVBetweenGPR_FPR(OpcodeArgs) {
if (Op->Dest.TypeNone.Type == FEXCore::X86Tables::DecodedOperand::TYPE_GPR &&
Op->Dest.TypeGPR.GPR >= FEXCore::X86State::REG_XMM_0) {
OrderedNode *Src = LoadSource(GPRClass, Op, Op->Src[0], Op->Flags, -1);
// When destination is XMM then it is zext to 128bit
uint64_t SrcSize = GetSrcSize(Op) * 8;
while (SrcSize != 128) {
Src = _Zext(SrcSize, Src);
SrcSize *= 2;
}
StoreResult(FPRClass, Op, Op->Dest, Src, -1);
}
else {
// Destination is GPR or mem
// Extract from XMM first
uint8_t ElementSize = 4;
if (Op->Flags & X86Tables::DecodeFlags::FLAG_REX_WIDENING)
ElementSize = 8;
OrderedNode *Src = LoadSource(FPRClass, Op, Op->Src[0],Op->Flags, -1);
Src = _VExtractToGPR(GetSrcSize(Op), ElementSize, Src, 0);
StoreResult(GPRClass, Op, Op->Dest, Src, -1);
}
}
void OpDispatchBuilder::TZCNT(OpcodeArgs) {
OrderedNode *Src = LoadSource(GPRClass, Op, Op->Src[0], Op->Flags, -1);
@@ -4620,14 +4630,16 @@ void InstallOpcodeHandlers() {
{0x17, 1, &OpDispatchBuilder::MOVUPSOp},
{0x28, 2, &OpDispatchBuilder::MOVUPSOp},
{0x50, 1, &OpDispatchBuilder::MOVMSKOp<4>},
{0x51, 1, &OpDispatchBuilder::VectorUnaryOp<IR::OP_VFSQRT, 4, false>},
{0x52, 1, &OpDispatchBuilder::VectorUnaryOp<IR::OP_VFRSQRT, 4, false>},
{0x54, 1, &OpDispatchBuilder::VectorALUOp<IR::OP_VAND, 16>},
{0x55, 1, &OpDispatchBuilder::ANDNOp},
{0x56, 1, &OpDispatchBuilder::VectorALUOp<IR::OP_VOR, 16>},
{0x57, 1, &OpDispatchBuilder::VectorALUOp<IR::OP_VXOR, 16>},
{0x58, 1, &OpDispatchBuilder::VectorALUOp<IR::OP_VFADD, 4>},
{0x59, 1, &OpDispatchBuilder::VectorALUOp<IR::OP_VFMUL, 4>},
{0x5A, 1, &OpDispatchBuilder::VFCVTF<8, 4>},
{0x5B, 1, &OpDispatchBuilder::VFCVT<4, true, false>},
{0x5A, 1, &OpDispatchBuilder::Vector_CVT_Float_To_Float<8, 4>},
{0x5B, 1, &OpDispatchBuilder::Vector_CVT_Int_To_Float<4, true, 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>},
@@ -4752,13 +4764,13 @@ void InstallOpcodeHandlers() {
{0x10, 2, &OpDispatchBuilder::MOVSSOp},
{0x16, 1, &OpDispatchBuilder::MOVSHDUPOp},
{0x19, 7, &OpDispatchBuilder::NOPOp},
{0x2A, 1, &OpDispatchBuilder::CVT<4, true>},
{0x2C, 1, &OpDispatchBuilder::FCVT<4, true>},
{0x2A, 1, &OpDispatchBuilder::CVTGPR_To_FPR<4, true>},
{0x2C, 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>},
{0x58, 1, &OpDispatchBuilder::VectorScalarALUOp<IR::OP_VFADD, 4>},
{0x59, 1, &OpDispatchBuilder::VectorScalarALUOp<IR::OP_VFMUL, 4>},
{0x5A, 1, &OpDispatchBuilder::FCVTF<8, 4>},
{0x5A, 1, &OpDispatchBuilder::Scalar_CVT_Float_To_Float<8, 4>},
{0x5C, 1, &OpDispatchBuilder::VectorScalarALUOp<IR::OP_VFSUB, 4>},
{0x5D, 1, &OpDispatchBuilder::VectorScalarALUOp<IR::OP_VFMIN, 4>},
{0x5E, 1, &OpDispatchBuilder::VectorScalarALUOp<IR::OP_VFDIV, 4>},
@@ -4770,20 +4782,20 @@ void InstallOpcodeHandlers() {
{0xB8, 1, &OpDispatchBuilder::PopcountOp},
{0xBC, 2, &OpDispatchBuilder::TZCNT},
{0xC2, 1, &OpDispatchBuilder::VFCMPOp<4, true>},
{0xE6, 1, &OpDispatchBuilder::VFCVT<4, true, true>},
{0xE6, 1, &OpDispatchBuilder::Vector_CVT_Int_To_Float<4, true, 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::CVT<8, true>},
{0x2C, 1, &OpDispatchBuilder::FCVT<8, true>},
{0x2A, 1, &OpDispatchBuilder::CVTGPR_To_FPR<8, true>},
{0x2C, 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>},
{0x59, 1, &OpDispatchBuilder::VectorScalarALUOp<IR::OP_VFMUL, 8>},
{0x5A, 1, &OpDispatchBuilder::FCVTF<4, 8>},
{0x5A, 1, &OpDispatchBuilder::Scalar_CVT_Float_To_Float<4, 8>},
{0x5C, 1, &OpDispatchBuilder::VectorScalarALUOp<IR::OP_VFSUB, 8>},
{0x5D, 1, &OpDispatchBuilder::VectorScalarALUOp<IR::OP_VFMIN, 8>},
{0x5E, 1, &OpDispatchBuilder::VectorScalarALUOp<IR::OP_VFDIV, 8>},
@@ -4810,7 +4822,8 @@ void InstallOpcodeHandlers() {
{0x57, 1, &OpDispatchBuilder::VectorALUOp<IR::OP_VXOR, 16>},
{0x58, 1, &OpDispatchBuilder::VectorALUOp<IR::OP_VFADD, 8>},
{0x59, 1, &OpDispatchBuilder::VectorALUOp<IR::OP_VFMUL, 8>},
{0x5A, 1, &OpDispatchBuilder::VFCVTF<4, 8>},
{0x5A, 1, &OpDispatchBuilder::Vector_CVT_Float_To_Float<4, 8>},
{0x5B, 1, &OpDispatchBuilder::CVTFPR_To_GPR<4, 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>},
@@ -4827,7 +4840,7 @@ void InstallOpcodeHandlers() {
{0x6A, 1, &OpDispatchBuilder::PUNPCKHOp<4>},
{0x6C, 1, &OpDispatchBuilder::PUNPCKLOp<8>},
{0x6D, 1, &OpDispatchBuilder::PUNPCKHOp<8>},
{0x6E, 1, &OpDispatchBuilder::MOVDOp},
{0x6E, 1, &OpDispatchBuilder::MOVBetweenGPR_FPR},
{0x6F, 1, &OpDispatchBuilder::MOVUPSOp},
{0x70, 1, &OpDispatchBuilder::PSHUFDOp<4, true>},
@@ -4836,7 +4849,7 @@ void InstallOpcodeHandlers() {
{0x75, 1, &OpDispatchBuilder::PCMPEQOp<2>},
{0x76, 1, &OpDispatchBuilder::PCMPEQOp<4>},
{0x78, 1, nullptr}, // GROUP 17
{0x7E, 1, &OpDispatchBuilder::MOVDOp},
{0x7E, 1, &OpDispatchBuilder::MOVBetweenGPR_FPR},
{0x7F, 1, &OpDispatchBuilder::MOVUPSOp},
{0xC2, 1, &OpDispatchBuilder::VFCMPOp<8, false>},
{0xC4, 1, &OpDispatchBuilder::PINSROp<2>},
+8 -5
View File
@@ -233,15 +233,18 @@ public:
void PSRAIOp(OpcodeArgs);
void MOVDDUPOp(OpcodeArgs);
template<size_t DstElementSize, bool Signed>
void CVT(OpcodeArgs);
void CVTGPR_To_FPR(OpcodeArgs);
template<size_t SrcElementSize, bool Signed>
void FCVT(OpcodeArgs);
void CVTFPR_To_GPR(OpcodeArgs);
template<size_t SrcElementSize, bool Signed, bool Widen>
void VFCVT(OpcodeArgs);
void Vector_CVT_Int_To_Float(OpcodeArgs);
template<size_t DstElementSize, size_t SrcElementSize>
void FCVTF(OpcodeArgs);
void Scalar_CVT_Float_To_Float(OpcodeArgs);
template<size_t DstElementSize, size_t SrcElementSize>
void VFCVTF(OpcodeArgs);
void Vector_CVT_Float_To_Float(OpcodeArgs);
template<size_t SrcElementSize, bool Signed>
void Vector_CVT_Float_To_Int(OpcodeArgs);
void MOVBetweenGPR_FPR(OpcodeArgs);
void TZCNT(OpcodeArgs);
void MOVSSOp(OpcodeArgs);
template<size_t ElementSize, bool Scalar>
+30 -20
View File
@@ -544,7 +544,7 @@
]
},
"FCVTZU": {
"Float_ToGPR_ZU": {
"HasDest": true,
"DestSize": "ElementSize",
"SSAArgs": "1",
@@ -553,7 +553,7 @@
]
},
"FCVTZS": {
"Float_ToGPR_ZS": {
"HasDest": true,
"DestSize": "ElementSize",
"SSAArgs": "1",
@@ -562,15 +562,6 @@
]
},
"ExtractElement": {
"HasDest": true,
"DestSize": "GetOpSize(ssa0)",
"SSAArgs": "1",
"Args": [
"uint8_t", "Idx"
]
},
"Print": {
"SSAArgs": "1"
},
@@ -1114,7 +1105,8 @@
]
},
"UCVTF": {
"Float_FromGPR_U": {
"Desc": "Scalar op: Converts unsigned GPR to Scalar float",
"HasDest": true,
"SSAArgs": "1",
"Args": [
@@ -1122,7 +1114,8 @@
]
},
"SCVTF": {
"Float_FromGPR_S": {
"Desc": "Scalar op: Converts signed GPR to Scalar float",
"HasDest": true,
"SSAArgs": "1",
"Args": [
@@ -1130,15 +1123,18 @@
]
},
"VUCVTF": {
"Float_FToF": {
"Desc": "Scalar op: Converts float from one size to another",
"HasDest": true,
"SSAArgs": "1",
"Args": [
"uint8_t", "RegisterSize",
"uint8_t", "ElementSize"
"uint8_t", "DstElementSize",
"uint8_t", "SrcElementSize"
]
},
"VSCVTF": {
"Vector_UToF": {
"Desc": "Vector op: Converts unsigned integer to same size float",
"HasDest": true,
"SSAArgs": "1",
"Args": [
@@ -1147,7 +1143,8 @@
]
},
"VFCVTL": {
"Vector_SToF": {
"Desc": "Vector op: Converts signed integer to same size float",
"HasDest": true,
"SSAArgs": "1",
"Args": [
@@ -1156,7 +1153,8 @@
]
},
"VFCVTN": {
"Vector_FToZU": {
"Desc": "Vector op: Converts float to unsigned integer, rounding towards zero",
"HasDest": true,
"SSAArgs": "1",
"Args": [
@@ -1165,10 +1163,22 @@
]
},
"FCVTF": {
"Vector_FToZS": {
"Desc": "Vector op: Converts float to signed integer, rounding towards zero",
"HasDest": true,
"SSAArgs": "1",
"Args": [
"uint8_t", "RegisterSize",
"uint8_t", "ElementSize"
]
},
"Vector_FToF": {
"Desc": "Vector op: Converts float from source element size to destination size (fp32<->fp64)",
"HasDest": true,
"SSAArgs": "1",
"Args": [
"uint8_t", "RegisterSize",
"uint8_t", "DstElementSize",
"uint8_t", "SrcElementSize"
]