mirror of
https://github.com/FEX-Emu/FEX.git
synced 2026-10-29 04:01:27 +01:00
Merge pull request #424 from Sonicadvance1/mmx_cvt
Implements missing mmx conversion ops
This commit is contained in:
commit
8662fb0db7
7 files changed
+156
-11
No files matched your search
@@ -3792,7 +3792,7 @@ void InterpreterCore::ExecuteCode(FEXCore::Core::InternalThreadState *Thread) {
|
||||
break;
|
||||
}
|
||||
case 0x0408: { // Float <- Double
|
||||
uint8_t Elements = OpSize / Op->SrcElementSize;
|
||||
uint8_t Elements = (OpSize << 1) / Op->SrcElementSize;
|
||||
switch (Op->SrcElementSize) {
|
||||
DO_VECTOR_1SRC_2TYPE_OP(8, float, double, Func, 0, 0)
|
||||
}
|
||||
|
||||
+45
-7
@@ -5903,24 +5903,59 @@ void OpDispatchBuilder::MMX_To_XMM_Vector_CVT_Int_To_Float(OpcodeArgs) {
|
||||
OrderedNode *Src = LoadSource(FPRClass, Op, Op->Src[0], Op->Flags, -1);
|
||||
|
||||
size_t ElementSize = SrcElementSize;
|
||||
size_t Size = GetSrcSize(Op);
|
||||
size_t DstSize = GetDstSize(Op);
|
||||
if (Widen) {
|
||||
Src = _VSXTL(Src, Size, ElementSize);
|
||||
Src = _VSXTL(Src, DstSize, ElementSize);
|
||||
ElementSize <<= 1;
|
||||
}
|
||||
|
||||
if (Signed)
|
||||
Src = _Vector_SToF(Src, Size, ElementSize);
|
||||
Src = _Vector_SToF(Src, DstSize, ElementSize);
|
||||
else
|
||||
Src = _Vector_UToF(Src, Size, ElementSize);
|
||||
Src = _Vector_UToF(Src, DstSize, ElementSize);
|
||||
|
||||
OrderedNode *Dest = LoadSource_WithOpSize(FPRClass, Op, Op->Dest, GetDstSize(Op), Op->Flags, -1);
|
||||
// Insert the lower bits
|
||||
Dest = _VInsElement(GetDstSize(Op), 8, 0, 0, Dest, Src);
|
||||
OrderedNode *Dest{};
|
||||
|
||||
if (Widen) {
|
||||
Dest = Src;
|
||||
}
|
||||
else {
|
||||
Dest = LoadSource_WithOpSize(FPRClass, Op, Op->Dest, DstSize, Op->Flags, -1);
|
||||
// Insert the lower bits
|
||||
Dest = _VInsElement(GetDstSize(Op), 8, 0, 0, Dest, Src);
|
||||
}
|
||||
|
||||
StoreResult(FPRClass, Op, Dest, -1);
|
||||
}
|
||||
|
||||
template<size_t SrcElementSize, bool Signed, 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);
|
||||
|
||||
size_t ElementSize = SrcElementSize;
|
||||
size_t Size = GetDstSize(Op);
|
||||
|
||||
if (Narrow) {
|
||||
Src = _Vector_FToF(Size, SrcElementSize >> 1, SrcElementSize, Src);
|
||||
ElementSize >>= 1;
|
||||
}
|
||||
|
||||
if (HostRoundingMode) {
|
||||
if (Signed)
|
||||
Src = _Vector_FToS(Src, Size, ElementSize);
|
||||
else
|
||||
Src = _Vector_FToU(Src, Size, ElementSize);
|
||||
}
|
||||
else {
|
||||
if (Signed)
|
||||
Src = _Vector_FToZS(Src, Size, ElementSize);
|
||||
else
|
||||
Src = _Vector_FToZU(Src, Size, ElementSize);
|
||||
}
|
||||
|
||||
StoreResult_WithOpSize(FPRClass, Op, Op->Dest, Src, Size, -1);
|
||||
}
|
||||
|
||||
void OpDispatchBuilder::MASKMOVOp(OpcodeArgs) {
|
||||
// Until we get correct PHI nodes this is required to be a loop unroll
|
||||
uint8_t GPRSize = CTX->Config.Is64BitMode ? 8 : 4;
|
||||
@@ -8042,6 +8077,9 @@ void InstallOpcodeHandlers(Context::OperatingMode Mode) {
|
||||
{0x16, 2, &OpDispatchBuilder::MOVHPDOp},
|
||||
{0x19, 7, &OpDispatchBuilder::NOPOp},
|
||||
{0x28, 2, &OpDispatchBuilder::MOVAPSOp},
|
||||
{0x2A, 1, &OpDispatchBuilder::MMX_To_XMM_Vector_CVT_Int_To_Float<4, true, true>},
|
||||
{0x2C, 1, &OpDispatchBuilder::XMM_To_MMX_Vector_CVT_Float_To_Int<8, true, true, true>},
|
||||
{0x2D, 1, &OpDispatchBuilder::XMM_To_MMX_Vector_CVT_Float_To_Int<8, true, true, false>},
|
||||
{0x2E, 2, &OpDispatchBuilder::UCOMISxOp<8>},
|
||||
|
||||
{0x40, 16, &OpDispatchBuilder::CMOVOp},
|
||||
|
||||
@@ -286,6 +286,8 @@ public:
|
||||
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>
|
||||
void XMM_To_MMX_Vector_CVT_Float_To_Int(OpcodeArgs);
|
||||
void MASKMOVOp(OpcodeArgs);
|
||||
void MOVBetweenGPR_FPR(OpcodeArgs);
|
||||
void TZCNT(OpcodeArgs);
|
||||
|
||||
@@ -431,10 +431,10 @@ void InitializeSecondaryTables() {
|
||||
|
||||
{0x28, 1, X86InstInfo{"MOVAPD", TYPE_INST, GenFlagsSameSize(SIZE_128BIT) | FLAGS_MODRM | FLAGS_XMM_FLAGS, 0, nullptr}},
|
||||
{0x29, 1, X86InstInfo{"MOVAPD", TYPE_INST, GenFlagsSameSize(SIZE_128BIT) | FLAGS_MODRM | FLAGS_SF_MOD_DST | FLAGS_XMM_FLAGS, 0, nullptr}},
|
||||
{0x2A, 1, X86InstInfo{"CVTPI2PD", TYPE_MMX, FLAGS_NONE, 0, nullptr}},
|
||||
{0x2A, 1, X86InstInfo{"CVTPI2PD", TYPE_INST, GenFlagsSizes(SIZE_128BIT, SIZE_64BIT) | FLAGS_MODRM | FLAGS_XMM_FLAGS | FLAGS_SF_MMX_SRC, 0, nullptr}},
|
||||
{0x2B, 1, X86InstInfo{"MOVNTPD", TYPE_INST, GenFlagsSameSize(SIZE_128BIT) | FLAGS_MODRM | FLAGS_SF_MOD_MEM_ONLY | FLAGS_SF_MOD_DST | FLAGS_XMM_FLAGS, 0, nullptr}},
|
||||
{0x2C, 1, X86InstInfo{"CVTTPD2PI", TYPE_MMX, GenFlagsSameSize(SIZE_128BIT) | FLAGS_MODRM | FLAGS_XMM_FLAGS, 0, nullptr}},
|
||||
{0x2D, 1, X86InstInfo{"CVTPD2PI", TYPE_MMX, GenFlagsSameSize(SIZE_128BIT) | FLAGS_MODRM | FLAGS_XMM_FLAGS, 0, nullptr}},
|
||||
{0x2C, 1, X86InstInfo{"CVTTPD2PI", TYPE_INST, GenFlagsSizes(SIZE_64BIT, SIZE_128BIT) | FLAGS_MODRM | FLAGS_XMM_FLAGS | FLAGS_SF_MMX_DST, 0, nullptr}},
|
||||
{0x2D, 1, X86InstInfo{"CVTPD2PI", TYPE_INST, GenFlagsSizes(SIZE_64BIT, SIZE_128BIT) | FLAGS_MODRM | FLAGS_XMM_FLAGS | FLAGS_SF_MMX_DST, 0, nullptr}},
|
||||
{0x2E, 1, X86InstInfo{"UCOMISD", TYPE_INST, GenFlagsSizes(SIZE_128BIT, SIZE_64BIT) | FLAGS_MODRM | FLAGS_XMM_FLAGS, 0, nullptr}},
|
||||
{0x2F, 1, X86InstInfo{"COMISD", TYPE_INST, GenFlagsSizes(SIZE_128BIT, SIZE_64BIT) | FLAGS_MODRM | FLAGS_XMM_FLAGS, 0, nullptr}},
|
||||
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
%ifdef CONFIG
|
||||
{
|
||||
"RegData": {
|
||||
"XMM0": ["0x3ff0000000000000", "0x0"],
|
||||
"XMM1": ["0xc000000000000000", "0xbff0000000000000"]
|
||||
},
|
||||
"MemoryRegions": {
|
||||
"0x100000000": "4096"
|
||||
}
|
||||
}
|
||||
%endif
|
||||
|
||||
mov rdx, 0xe0000000
|
||||
|
||||
mov rax, 0x0000000000000001
|
||||
mov [rdx + 8 * 0], rax
|
||||
mov rax, 0xFFFFFFFFFFFFFFFE
|
||||
mov [rdx + 8 * 1], rax
|
||||
|
||||
movq mm0, [rdx]
|
||||
cvtpi2pd xmm0, mm0
|
||||
cvtpi2pd xmm1, [rdx + 8 * 1]
|
||||
|
||||
hlt
|
||||
@@ -0,0 +1,38 @@
|
||||
%ifdef CONFIG
|
||||
{
|
||||
"RegData": {
|
||||
"MM0": "0x0000000200000001",
|
||||
"MM1": "0xFFFFFFFEFFFFFFFF"
|
||||
},
|
||||
"MemoryRegions": {
|
||||
"0x100000000": "4096"
|
||||
}
|
||||
}
|
||||
%endif
|
||||
|
||||
mov rdx, 0xe0000000
|
||||
|
||||
mov rax, 0x3ff0000000000000
|
||||
mov [rdx + 8 * 0], rax
|
||||
mov rax, 0x4000000000000000
|
||||
mov [rdx + 8 * 1], rax
|
||||
|
||||
mov rax, 0xbff0000000000000
|
||||
mov [rdx + 8 * 2], rax
|
||||
mov rax, 0xc000000000000000
|
||||
mov [rdx + 8 * 3], rax
|
||||
|
||||
mov rax, 0x4142434445464748
|
||||
mov [rdx + 8 * 4], rax
|
||||
mov rax, 0x5152535455565758
|
||||
mov [rdx + 8 * 5], rax
|
||||
|
||||
movq mm0, [rdx + 8 * 4]
|
||||
movq mm1, [rdx + 8 * 4]
|
||||
|
||||
movapd xmm2, [rdx + 8 * 0]
|
||||
|
||||
cvttpd2pi mm0, xmm2
|
||||
cvttpd2pi mm1, [rdx + 8 * 2]
|
||||
|
||||
hlt
|
||||
@@ -0,0 +1,43 @@
|
||||
%ifdef CONFIG
|
||||
{
|
||||
"RegData": {
|
||||
"MM0": "0x0000000200000001",
|
||||
"MM1": "0xFFFFFFFEFFFFFFFF"
|
||||
},
|
||||
"MemoryRegions": {
|
||||
"0x100000000": "4096"
|
||||
}
|
||||
}
|
||||
%endif
|
||||
|
||||
mov rdx, 0xe0000000
|
||||
|
||||
; Set up MXCSR to truncate
|
||||
mov eax, 0x7F80
|
||||
mov [rdx + 8 * 0], eax
|
||||
ldmxcsr [rdx + 8 * 0]
|
||||
|
||||
mov rax, 0x3ff0000000000000
|
||||
mov [rdx + 8 * 0], rax
|
||||
mov rax, 0x4000000000000000
|
||||
mov [rdx + 8 * 1], rax
|
||||
|
||||
mov rax, 0xbff0000000000000
|
||||
mov [rdx + 8 * 2], rax
|
||||
mov rax, 0xc000000000000000
|
||||
mov [rdx + 8 * 3], rax
|
||||
|
||||
mov rax, 0x4142434445464748
|
||||
mov [rdx + 8 * 4], rax
|
||||
mov rax, 0x5152535455565758
|
||||
mov [rdx + 8 * 5], rax
|
||||
|
||||
movq mm0, [rdx + 8 * 4]
|
||||
movq mm1, [rdx + 8 * 4]
|
||||
|
||||
movapd xmm2, [rdx + 8 * 0]
|
||||
|
||||
cvtpd2pi mm0, xmm2
|
||||
cvtpd2pi mm1, [rdx + 8 * 2]
|
||||
|
||||
hlt
|
||||
Reference in new issue
Block a user