diff --git a/FEXCore/Source/Interface/Core/OpcodeDispatcher.cpp b/FEXCore/Source/Interface/Core/OpcodeDispatcher.cpp index 1fad04e56..f3f04e15c 100644 --- a/FEXCore/Source/Interface/Core/OpcodeDispatcher.cpp +++ b/FEXCore/Source/Interface/Core/OpcodeDispatcher.cpp @@ -5238,6 +5238,7 @@ void OpDispatchBuilder::InstallHostSpecificOpcodeHandlers() { {OPD(2, 0b01, 0x0E), 1, &OpDispatchBuilder::VTESTPOp<4>}, {OPD(2, 0b01, 0x0F), 1, &OpDispatchBuilder::VTESTPOp<8>}, + {OPD(2, 0b01, 0x13), 1, &OpDispatchBuilder::VCVTPH2PSOp}, {OPD(2, 0b01, 0x16), 1, &OpDispatchBuilder::VPERMDOp}, {OPD(2, 0b01, 0x17), 1, &OpDispatchBuilder::PTestOp}, {OPD(2, 0b01, 0x18), 1, &OpDispatchBuilder::VBROADCASTOp<4>}, diff --git a/FEXCore/Source/Interface/Core/OpcodeDispatcher.h b/FEXCore/Source/Interface/Core/OpcodeDispatcher.h index b4324e3e0..ac312b3cc 100644 --- a/FEXCore/Source/Interface/Core/OpcodeDispatcher.h +++ b/FEXCore/Source/Interface/Core/OpcodeDispatcher.h @@ -663,8 +663,9 @@ public: void VPCMPISTRIOp(OpcodeArgs); void VPCMPISTRMOp(OpcodeArgs); - Ref VPERMDIndices(OpSize DstSize, Ref Indices, Ref IndexMask, Ref Repeating3210); + void VCVTPH2PSOp(OpcodeArgs); + Ref VPERMDIndices(OpSize DstSize, Ref Indices, Ref IndexMask, Ref Repeating3210); void VPERM2Op(OpcodeArgs); void VPERMDOp(OpcodeArgs); void VPERMQOp(OpcodeArgs); diff --git a/FEXCore/Source/Interface/Core/OpcodeDispatcher/Vector.cpp b/FEXCore/Source/Interface/Core/OpcodeDispatcher/Vector.cpp index 956a58879..a084ce32c 100644 --- a/FEXCore/Source/Interface/Core/OpcodeDispatcher/Vector.cpp +++ b/FEXCore/Source/Interface/Core/OpcodeDispatcher/Vector.cpp @@ -4464,6 +4464,19 @@ void OpDispatchBuilder::VINSERTOp(OpcodeArgs) { StoreResult(FPRClass, Op, Result, -1); } +void OpDispatchBuilder::VCVTPH2PSOp(OpcodeArgs) { + // In the event that a memory operand is used as the source operand, + // the access width will always be half the size of the destination vector width + // (i.e. 128-bit vector -> 64-bit mem, 256-bit vector -> 128-bit mem) + const auto DstSize = GetDstSize(Op); + const auto SrcLoadSize = Op->Src[0].IsGPR() ? DstSize : DstSize / 2; + + Ref Src = LoadSource_WithOpSize(FPRClass, Op, Op->Src[0], SrcLoadSize, Op->Flags); + Ref Result = _Vector_FToF(DstSize, 4, Src, 2); + + StoreResult(FPRClass, Op, Result, -1); +} + void OpDispatchBuilder::VPERM2Op(OpcodeArgs) { const auto DstSize = GetDstSize(Op); Ref Src1 = LoadSource(FPRClass, Op, Op->Src[0], Op->Flags); diff --git a/FEXCore/Source/Interface/Core/X86Tables/VEXTables.cpp b/FEXCore/Source/Interface/Core/X86Tables/VEXTables.cpp index fb120eae7..7d631d921 100644 --- a/FEXCore/Source/Interface/Core/X86Tables/VEXTables.cpp +++ b/FEXCore/Source/Interface/Core/X86Tables/VEXTables.cpp @@ -282,7 +282,7 @@ std::array VEXTableOps = []() consteval { {OPD(2, 0b01, 0x0E), 1, X86InstInfo{"VTESTPS", TYPE_INST, GenFlagsSameSize(SIZE_128BIT) | FLAGS_MODRM | FLAGS_XMM_FLAGS, 0, nullptr}}, {OPD(2, 0b01, 0x0F), 1, X86InstInfo{"VTESTPD", TYPE_INST, GenFlagsSameSize(SIZE_128BIT) | FLAGS_MODRM | FLAGS_XMM_FLAGS, 0, nullptr}}, - {OPD(2, 0b01, 0x13), 1, X86InstInfo{"VCVTPH2PS", TYPE_UNDEC, FLAGS_NONE, 0, nullptr}}, + {OPD(2, 0b01, 0x13), 1, X86InstInfo{"VCVTPH2PS", TYPE_INST, GenFlagsSizes(SIZE_128BIT, SIZE_64BIT) | FLAGS_MODRM | FLAGS_XMM_FLAGS, 0, nullptr}}, {OPD(2, 0b01, 0x16), 1, X86InstInfo{"VPERMPS", TYPE_INST, GenFlagsSameSize(SIZE_256BIT) | FLAGS_MODRM | FLAGS_VEX_1ST_SRC | FLAGS_XMM_FLAGS, 0, nullptr}}, {OPD(2, 0b01, 0x17), 1, X86InstInfo{"VPTEST", TYPE_INST, GenFlagsSameSize(SIZE_128BIT) | FLAGS_MODRM | FLAGS_XMM_FLAGS, 0, nullptr}}, diff --git a/unittests/ASM/VEX/vcvtph2ps.asm b/unittests/ASM/VEX/vcvtph2ps.asm new file mode 100644 index 000000000..92ee21f75 --- /dev/null +++ b/unittests/ASM/VEX/vcvtph2ps.asm @@ -0,0 +1,67 @@ +%ifdef CONFIG +{ + "HostFeatures": ["AVX"], + "RegData": { + "XMM0": ["0xFC007C00BC003C00", "0x42487E0003FF0001", "0", "0"], + "XMM1": ["0x800000007BFFFBFF", "0x42A53DC534D136F3", "0", "0"], + "XMM2": ["0xBF8000003F800000", "0xFF8000007F800000", "0", "0"], + "XMM3": ["0x477FE000C77FE000", "0x8000000000000000", "0", "0"], + "XMM4": ["0xBF8000003F800000", "0xFF8000007F800000", "0", "0"], + "XMM5": ["0x387FC00033800000", "0x404900007FC00000", "0", "0"], + "XMM6": ["0xFC007C00BC003C00", "0x42487E0003FF0001", "0x800000007BFFFBFF", "0x42A53DC534D136F3"], + "XMM7": ["0xBF8000003F800000", "0xFF8000007F800000", "0x387FC00033800000", "0x404900007FC00000"], + "XMM8": ["0xBF8000003F800000", "0xFF8000007F800000", "0x387FC00033800000", "0x404900007FC00000"], + "XMM9": ["0x477FE000C77FE000", "0x8000000000000000", "0x3E9A20003EDE6000", "0x4054A0003FB8A000"] + } +} +%endif + +lea rdx, [rel .data] + +; 128-bit + +vmovapd xmm0, [rdx] +vmovapd xmm1, [rdx + 16] + +; 128-bit register +vcvtph2ps xmm2, xmm0 +vcvtph2ps xmm3, xmm1 + +; 128-bit memory +vcvtph2ps xmm4, [rdx] +vcvtph2ps xmm5, [rdx + 8] + +; 256-bit + +vmovapd ymm6, [rdx] + +; 256-bit register +vcvtph2ps ymm7, xmm6 + +; 256-bit memory +vcvtph2ps ymm8, [rdx] +vcvtph2ps ymm9, [rdx + 16] + +hlt + +align 32 +.data: +dw 0x3C00 ; 1.0 +dw 0xBC00 ; -1.0 +dw 0x7C00 ; +inf +dw 0xFC00 ; -inf + +dw 0x0001 ; min positive subnormal +dw 0x03FF ; max subnormal +dw 0x7E00 ; NaN +dw 0x4248 ; pi + +dw 0xFBFF ; min finite value +dw 0x7BFF ; max finite value +dw 0x0000 ; +0.0 +dw 0x8000 ; -0.0 + +dw 0x36F3 ; log_10(e) +dw 0x34D1 ; log_10(2) +dw 0x3DC5 ; log_2(e) +dw 0x42A5 ; log_2(10) diff --git a/unittests/InstructionCountCI/VEX_map2.json b/unittests/InstructionCountCI/VEX_map2.json index 6abb9cc06..ab6aa1313 100644 --- a/unittests/InstructionCountCI/VEX_map2.json +++ b/unittests/InstructionCountCI/VEX_map2.json @@ -603,17 +603,43 @@ ] }, "vcvtph2ps xmm0, xmm1": { - "ExpectedInstructionCount": -1, - "Skip": "Yes", + "ExpectedInstructionCount": 1, "Comment": [ "Map 2 0b01 0x13 128-bit" + ], + "ExpectedArm64ASM": [ + "fcvtl v16.4s, v17.4h" + ] + }, + "vcvtph2ps xmm0, [rax]": { + "ExpectedInstructionCount": 2, + "Comment": [ + "Map 2 0b01 0x13 128-bit" + ], + "ExpectedArm64ASM": [ + "ldr d2, [x4]", + "fcvtl v16.4s, v2.4h" ] }, "vcvtph2ps ymm0, xmm1": { - "ExpectedInstructionCount": -1, - "Skip": "Yes", + "ExpectedInstructionCount": 2, "Comment": [ "Map 2 0b01 0x13 256-bit" + ], + "ExpectedArm64ASM": [ + "zip1 z16.h, z17.h, z17.h", + "fcvtlt z16.s, p7/m, z16.h" + ] + }, + "vcvtph2ps ymm0, [rax]": { + "ExpectedInstructionCount": 3, + "Comment": [ + "Map 2 0b01 0x13 256-bit" + ], + "ExpectedArm64ASM": [ + "ldr q2, [x4]", + "zip1 z16.h, z2.h, z2.h", + "fcvtlt z16.s, p7/m, z16.h" ] }, "vpermps ymm0, ymm1, ymm2": {