diff --git a/Source/Interface/Core/Interpreter/InterpreterCore.cpp b/Source/Interface/Core/Interpreter/InterpreterCore.cpp index 3e0929313..f72941009 100644 --- a/Source/Interface/Core/Interpreter/InterpreterCore.cpp +++ b/Source/Interface/Core/Interpreter/InterpreterCore.cpp @@ -1017,7 +1017,6 @@ void InterpreterCore::ExecuteCode(FEXCore::Core::InternalThreadState *Thread) { default: LogMan::Msg::A("Uknown Splat size"); break; } - uint8_t ElementSize = OpSize / Elements; #define CREATE_VECTOR(elementsize, type) \ case elementsize: { \ auto *Dst_d = reinterpret_cast(Tmp); \ @@ -1026,12 +1025,12 @@ void InterpreterCore::ExecuteCode(FEXCore::Core::InternalThreadState *Thread) { Dst_d[i] = *Src_d;\ break; \ } - switch (ElementSize) { + switch (Op->Header.Size) { CREATE_VECTOR(1, uint8_t) CREATE_VECTOR(2, uint16_t) CREATE_VECTOR(4, uint32_t) CREATE_VECTOR(8, uint64_t) - default: LogMan::Msg::A("Unknown Element Size: %d", ElementSize); break; + default: LogMan::Msg::A("Unknown Element Size: %d", Op->Header.Size); break; } #undef CREATE_VECTOR memcpy(GDP, Tmp, OpSize); diff --git a/Source/Interface/Core/JIT/x86_64/JIT.cpp b/Source/Interface/Core/JIT/x86_64/JIT.cpp index 1c742f4d4..7a75e3beb 100644 --- a/Source/Interface/Core/JIT/x86_64/JIT.cpp +++ b/Source/Interface/Core/JIT/x86_64/JIT.cpp @@ -1372,13 +1372,7 @@ void *JITCore::CompileCode([[maybe_unused]] FEXCore::IR::IRListView const case IR::OP_SPLATVECTOR4: { auto Op = IROp->C(); LogMan::Throw::A(OpSize <= 16, "Can't handle a vector of size: %d", OpSize); - uint8_t NumElements{}; - if (IROp->Op == OP_SPLATVECTOR4) - NumElements = 4; - else if (IROp->Op == OP_SPLATVECTOR2) - NumElements = 2; - uint8_t ElementSize = OpSize / NumElements; - switch (ElementSize) { + switch (Op->Header.Size) { case 4: vmovd(GetDst(Node), GetSrc(Op->Header.Args[0].ID()).cvt32()); shufps(GetDst(Node), GetDst(Node), 0); @@ -1387,7 +1381,7 @@ void *JITCore::CompileCode([[maybe_unused]] FEXCore::IR::IRListView const vmovq(GetDst(Node), GetSrc(Op->Header.Args[0].ID()).cvt64()); shufpd(GetDst(Node), GetDst(Node), 0); break; - default: LogMan::Msg::A("Unknown Element Size: %d", ElementSize); break; + default: LogMan::Msg::A("Unknown Element Size: %d", Op->Header.Size); break; } break; } diff --git a/Source/Interface/Core/OpcodeDispatcher.cpp b/Source/Interface/Core/OpcodeDispatcher.cpp index c506107ff..77c8d39e5 100644 --- a/Source/Interface/Core/OpcodeDispatcher.cpp +++ b/Source/Interface/Core/OpcodeDispatcher.cpp @@ -2335,9 +2335,25 @@ void OpDispatchBuilder::VectorALUOp(OpcodeArgs) { template void OpDispatchBuilder::VectorScalarALUOp(OpcodeArgs) { auto Size = GetSrcSize(Op); - OrderedNode *Src = LoadSource(Op, Op->Src1, Op->Flags, -1); OrderedNode *Dest = LoadSource(Op, Op->Dest, Op->Flags, -1); + OrderedNode *Src{}; + if (Op->Src1.TypeNone.Type == FEXCore::X86Tables::DecodedOperand::TYPE_GPR) { + Src = LoadSource(Op, Op->Src1, Op->Flags, -1); + } + else { + // Load a elementsize from memory and move it to a vector register + Src = LoadSource_WithOpSize(Op, Op->Src1, ElementSize, Op->Flags, -1); + switch (ElementSize) { + case 4: + Src = _SplatVector4(Src); + break; + case 8: + Src = _SplatVector2(Src); + break; + } + } + // If OpSize == ElementSize then it only does the lower scalar op auto ALUOp = _VAdd(ElementSize, ElementSize, Dest, Src); // Overwrite our IR's op type ALUOp.first->Header.Op = IROp; @@ -2497,6 +2513,16 @@ void OpDispatchBuilder::MOVDOp(OpcodeArgs) { SrcSize *= 2; } } + else { + // Destination is GPR or mem + // Extract from XMM first + uint8_t ElementSize = 4; + if (Op->Flags & X86Tables::DecodeFlags::FLAG_REX_WIDENING) + ElementSize = 8; + + Src = _VExtractToGPR(GetSrcSize(Op), ElementSize, Src, 0); + } + StoreResult(Op, Op->Dest, Src, -1); } @@ -3664,7 +3690,6 @@ void OpDispatchBuilder::CVT(OpcodeArgs) { else Src = _Zext(32, Src); } - } if (Signed) @@ -3672,6 +3697,10 @@ void OpDispatchBuilder::CVT(OpcodeArgs) { else Src = _UCVTF(Src, DstElementSize); + OrderedNode *Dest = LoadSource(Op, Op->Dest, Op->Flags, -1); + + Src = _VInsElement(16, DstElementSize, 0, 0, Dest, Src); + StoreResult(Op, Src, -1); } @@ -3690,9 +3719,12 @@ void OpDispatchBuilder::FCVT(OpcodeArgs) { template void OpDispatchBuilder::FCVTF(OpcodeArgs) { + OrderedNode *Dest = LoadSource(Op, Op->Dest, Op->Flags, -1); OrderedNode *Src = LoadSource(Op, Op->Src1, Op->Flags, -1); Src = _FCVTF(Src, DstElementSize, SrcElementSize); + Src = _VInsElement(16, DstElementSize, 0, 0, Dest, Src); + StoreResult(Op, Src, -1); } @@ -4120,7 +4152,7 @@ void InstallOpcodeHandlers() { {0x10, 2, &OpDispatchBuilder::MOVSSOp}, {0x19, 7, &OpDispatchBuilder::NOPOp}, {0x2A, 1, &OpDispatchBuilder::CVT<4, true>}, - {0x2C, 1, &OpDispatchBuilder::CVT<4, true>}, + {0x2C, 1, &OpDispatchBuilder::FCVT<4, true>}, {0x58, 1, &OpDispatchBuilder::VectorScalarALUOp}, {0x59, 1, &OpDispatchBuilder::VectorScalarALUOp}, {0x5A, 1, &OpDispatchBuilder::FCVTF<8, 4>}, @@ -4140,6 +4172,7 @@ void InstallOpcodeHandlers() { {0x19, 7, &OpDispatchBuilder::NOPOp}, {0x2A, 1, &OpDispatchBuilder::CVT<8, true>}, {0x2C, 1, &OpDispatchBuilder::FCVT<8, true>}, + {0x5A, 1, &OpDispatchBuilder::FCVTF<4, 8>}, {0x58, 1, &OpDispatchBuilder::VectorScalarALUOp}, {0x59, 1, &OpDispatchBuilder::VectorScalarALUOp}, {0x5C, 1, &OpDispatchBuilder::VectorScalarALUOp}, diff --git a/Source/Interface/Core/X86Tables/SecondaryTables.cpp b/Source/Interface/Core/X86Tables/SecondaryTables.cpp index 36d17b4e2..17847f092 100644 --- a/Source/Interface/Core/X86Tables/SecondaryTables.cpp +++ b/Source/Interface/Core/X86Tables/SecondaryTables.cpp @@ -341,9 +341,9 @@ void InitializeSecondaryTables() { {0x20, 4, X86InstInfo{"", TYPE_COPY_OTHER, FLAGS_NONE, 0, nullptr}}, {0x24, 6, X86InstInfo{"", TYPE_INVALID, FLAGS_NONE, 0, nullptr}}, - {0x2A, 1, X86InstInfo{"CVTSI2SD", TYPE_INST, GenFlagsSameSize(SIZE_64BIT) | FLAGS_MODRM | FLAGS_XMM_FLAGS, 0, nullptr}}, + {0x2A, 1, X86InstInfo{"CVTSI2SD", TYPE_INST, GenFlagsDstSize(SIZE_128BIT) | FLAGS_MODRM | FLAGS_XMM_FLAGS | FLAGS_SF_SRC_GPR, 0, nullptr}}, {0x2B, 1, X86InstInfo{"MOVNTSD", TYPE_INST, GenFlagsSameSize(SIZE_64BIT) | FLAGS_MODRM | FLAGS_SF_MOD_MEM_ONLY | FLAGS_SF_MOD_DST | FLAGS_XMM_FLAGS, 0, nullptr}}, - {0x2C, 1, X86InstInfo{"CVTTSD2SI", TYPE_INST, GenFlagsSameSize(SIZE_64BIT) | FLAGS_MODRM | FLAGS_XMM_FLAGS | FLAGS_SF_DST_GPR, 0, nullptr}}, + {0x2C, 1, X86InstInfo{"CVTTSD2SI", TYPE_INST, GenFlagsSrcSize(SIZE_128BIT) | FLAGS_MODRM | FLAGS_XMM_FLAGS | FLAGS_SF_DST_GPR, 0, nullptr}}, {0x2D, 1, X86InstInfo{"CVTSD2SI", TYPE_INST, GenFlagsSameSize(SIZE_64BIT) | FLAGS_MODRM | FLAGS_XMM_FLAGS | FLAGS_SF_DST_GPR, 0, nullptr}}, {0x2E, 2, X86InstInfo{"", TYPE_INVALID, FLAGS_NONE, 0, nullptr}}, @@ -353,14 +353,14 @@ void InitializeSecondaryTables() { {0x50, 1, X86InstInfo{"", TYPE_INVALID, FLAGS_NONE, 0, nullptr}}, {0x51, 1, X86InstInfo{"SQRTSD", TYPE_INST, GenFlagsSameSize(SIZE_64BIT) | FLAGS_MODRM | FLAGS_XMM_FLAGS, 0, nullptr}}, {0x52, 6, X86InstInfo{"", TYPE_INVALID, FLAGS_NONE, 0, nullptr}}, - {0x58, 1, X86InstInfo{"ADDSD", TYPE_INST, GenFlagsSameSize(SIZE_64BIT) | FLAGS_MODRM | FLAGS_XMM_FLAGS, 0, nullptr}}, - {0x59, 1, X86InstInfo{"MULSD", TYPE_INST, GenFlagsSameSize(SIZE_64BIT) | FLAGS_MODRM | FLAGS_XMM_FLAGS, 0, nullptr}}, - {0x5A, 1, X86InstInfo{"CVTSD2SS", TYPE_INST, GenFlagsSameSize(SIZE_64BIT) | FLAGS_MODRM | FLAGS_XMM_FLAGS, 0, nullptr}}, + {0x58, 1, X86InstInfo{"ADDSD", TYPE_INST, GenFlagsSameSize(SIZE_128BIT) | FLAGS_MODRM | FLAGS_XMM_FLAGS, 0, nullptr}}, + {0x59, 1, X86InstInfo{"MULSD", TYPE_INST, GenFlagsSameSize(SIZE_128BIT) | FLAGS_MODRM | FLAGS_XMM_FLAGS, 0, nullptr}}, + {0x5A, 1, X86InstInfo{"CVTSD2SS", TYPE_INST, GenFlagsSameSize(SIZE_128BIT) | FLAGS_MODRM | FLAGS_XMM_FLAGS, 0, nullptr}}, {0x5B, 1, X86InstInfo{"", TYPE_INVALID, FLAGS_NONE, 0, nullptr}}, - {0x5C, 1, X86InstInfo{"SUBSD", TYPE_INST, GenFlagsSameSize(SIZE_64BIT) | FLAGS_MODRM | FLAGS_XMM_FLAGS, 0, nullptr}}, - {0x5D, 1, X86InstInfo{"MINSD", TYPE_INST, GenFlagsSameSize(SIZE_64BIT) | FLAGS_MODRM | FLAGS_XMM_FLAGS, 0, nullptr}}, - {0x5E, 1, X86InstInfo{"DIVSD", TYPE_INST, GenFlagsSameSize(SIZE_64BIT) | FLAGS_MODRM | FLAGS_XMM_FLAGS, 0, nullptr}}, - {0x5F, 1, X86InstInfo{"MAXSD", TYPE_INST, GenFlagsSameSize(SIZE_64BIT) | FLAGS_MODRM | FLAGS_XMM_FLAGS, 0, nullptr}}, + {0x5C, 1, X86InstInfo{"SUBSD", TYPE_INST, GenFlagsSameSize(SIZE_128BIT) | FLAGS_MODRM | FLAGS_XMM_FLAGS, 0, nullptr}}, + {0x5D, 1, X86InstInfo{"MINSD", TYPE_INST, GenFlagsSameSize(SIZE_128BIT) | FLAGS_MODRM | FLAGS_XMM_FLAGS, 0, nullptr}}, + {0x5E, 1, X86InstInfo{"DIVSD", TYPE_INST, GenFlagsSameSize(SIZE_128BIT) | FLAGS_MODRM | FLAGS_XMM_FLAGS, 0, nullptr}}, + {0x5F, 1, X86InstInfo{"MAXSD", TYPE_INST, GenFlagsSameSize(SIZE_128BIT) | FLAGS_MODRM | FLAGS_XMM_FLAGS, 0, nullptr}}, {0x60, 16, X86InstInfo{"", TYPE_INVALID, FLAGS_NONE, 0, nullptr}},