diff --git a/FEXCore/Source/Interface/Core/OpcodeDispatcher.cpp b/FEXCore/Source/Interface/Core/OpcodeDispatcher.cpp index 9eef4b00e..440b98ea1 100644 --- a/FEXCore/Source/Interface/Core/OpcodeDispatcher.cpp +++ b/FEXCore/Source/Interface/Core/OpcodeDispatcher.cpp @@ -5231,8 +5231,8 @@ void OpDispatchBuilder::InstallHostSpecificOpcodeHandlers() { {OPD(2, 0b01, 0x09), 1, &OpDispatchBuilder::VPSIGN<2>}, {OPD(2, 0b01, 0x0A), 1, &OpDispatchBuilder::VPSIGN<4>}, {OPD(2, 0b01, 0x0B), 1, &OpDispatchBuilder::VPMULHRSWOp}, - {OPD(2, 0b01, 0x0C), 1, &OpDispatchBuilder::VPERMILRegOp<4>}, - {OPD(2, 0b01, 0x0D), 1, &OpDispatchBuilder::VPERMILRegOp<8>}, + {OPD(2, 0b01, 0x0C), 1, &OpDispatchBuilder::VPERMILRegOp}, + {OPD(2, 0b01, 0x0D), 1, &OpDispatchBuilder::VPERMILRegOp}, {OPD(2, 0b01, 0x0E), 1, &OpDispatchBuilder::VTESTPOp<4>}, {OPD(2, 0b01, 0x0F), 1, &OpDispatchBuilder::VTESTPOp<8>}, diff --git a/FEXCore/Source/Interface/Core/OpcodeDispatcher.h b/FEXCore/Source/Interface/Core/OpcodeDispatcher.h index 35152d5cc..ca6650fb4 100644 --- a/FEXCore/Source/Interface/Core/OpcodeDispatcher.h +++ b/FEXCore/Source/Interface/Core/OpcodeDispatcher.h @@ -629,8 +629,8 @@ public: void VPERMILImmOp(OpcodeArgs, size_t ElementSize); - Ref VPERMILRegOpImpl(OpSize DstSize, size_t ElementSize, Ref Src, Ref Indices); - template + Ref VPERMILRegOpImpl(OpSize DstSize, IR::OpSize ElementSize, Ref Src, Ref Indices); + template void VPERMILRegOp(OpcodeArgs); void VPHADDSWOp(OpcodeArgs); @@ -1110,7 +1110,7 @@ public: void AVX128_VTESTP(OpcodeArgs); void AVX128_PTest(OpcodeArgs); - template + template void AVX128_VPERMILReg(OpcodeArgs); void AVX128_VPERMD(OpcodeArgs); @@ -1409,7 +1409,7 @@ private: Ref PSADBWOpImpl(size_t Size, Ref Src1, Ref Src2); - Ref GeneratePSHUFBMask(uint8_t SrcSize); + Ref GeneratePSHUFBMask(IR::OpSize SrcSize); Ref PSHUFBOpImpl(uint8_t SrcSize, Ref Src1, Ref Src2, Ref MaskVector); Ref PSIGNImpl(OpcodeArgs, size_t ElementSize, Ref Src1, Ref Src2); diff --git a/FEXCore/Source/Interface/Core/OpcodeDispatcher/AVX_128.cpp b/FEXCore/Source/Interface/Core/OpcodeDispatcher/AVX_128.cpp index ba67536c1..16f66cab2 100644 --- a/FEXCore/Source/Interface/Core/OpcodeDispatcher/AVX_128.cpp +++ b/FEXCore/Source/Interface/Core/OpcodeDispatcher/AVX_128.cpp @@ -263,8 +263,8 @@ void OpDispatchBuilder::InstallAVX128Handlers() { {OPD(2, 0b01, 0x09), 1, &OpDispatchBuilder::AVX128_VPSIGN<2>}, {OPD(2, 0b01, 0x0A), 1, &OpDispatchBuilder::AVX128_VPSIGN<4>}, {OPD(2, 0b01, 0x0B), 1, &OpDispatchBuilder::AVX128_VPMULHRSW}, - {OPD(2, 0b01, 0x0C), 1, &OpDispatchBuilder::AVX128_VPERMILReg<4>}, - {OPD(2, 0b01, 0x0D), 1, &OpDispatchBuilder::AVX128_VPERMILReg<8>}, + {OPD(2, 0b01, 0x0C), 1, &OpDispatchBuilder::AVX128_VPERMILReg}, + {OPD(2, 0b01, 0x0D), 1, &OpDispatchBuilder::AVX128_VPERMILReg}, {OPD(2, 0b01, 0x0E), 1, &OpDispatchBuilder::AVX128_VTESTP}, {OPD(2, 0b01, 0x0F), 1, &OpDispatchBuilder::AVX128_VTESTP}, @@ -2331,7 +2331,7 @@ void OpDispatchBuilder::AVX128_PTest(OpcodeArgs) { ZeroPF_AF(); } -template +template void OpDispatchBuilder::AVX128_VPERMILReg(OpcodeArgs) { AVX128_VectorBinaryImpl(Op, GetSrcSize(Op), ElementSize, [this](size_t _ElementSize, Ref Src, Ref Indices) { return VPERMILRegOpImpl(OpSize::i128Bit, ElementSize, Src, Indices); diff --git a/FEXCore/Source/Interface/Core/OpcodeDispatcher/Vector.cpp b/FEXCore/Source/Interface/Core/OpcodeDispatcher/Vector.cpp index 4d3919d5d..eabea2088 100644 --- a/FEXCore/Source/Interface/Core/OpcodeDispatcher/Vector.cpp +++ b/FEXCore/Source/Interface/Core/OpcodeDispatcher/Vector.cpp @@ -837,7 +837,7 @@ void OpDispatchBuilder::VPUNPCKHOp(OpcodeArgs, size_t ElementSize) { StoreResult(FPRClass, Op, Result, OpSize::iInvalid); } -Ref OpDispatchBuilder::GeneratePSHUFBMask(uint8_t SrcSize) { +Ref OpDispatchBuilder::GeneratePSHUFBMask(IR::OpSize SrcSize) { // PSHUFB doesn't 100% match VTBL behaviour // VTBL will set the element zero if the index is greater than // the number of elements in the array @@ -848,7 +848,7 @@ Ref OpDispatchBuilder::GeneratePSHUFBMask(uint8_t SrcSize) { // Bits [6:3] is reserved for 64-bit const uint8_t MaskImm = SrcSize == OpSize::i64Bit ? 0b1000'0111 : 0b1000'1111; - return _VectorImm(SrcSize, 1, MaskImm); + return _VectorImm(SrcSize, OpSize::i8Bit, MaskImm); } Ref OpDispatchBuilder::PSHUFBOpImpl(uint8_t SrcSize, Ref Src1, Ref Src2, Ref MaskVector) { @@ -871,7 +871,7 @@ Ref OpDispatchBuilder::PSHUFBOpImpl(uint8_t SrcSize, Ref Src1, Ref Src2, Ref Mas } void OpDispatchBuilder::PSHUFBOp(OpcodeArgs) { - const auto SrcSize = GetSrcSize(Op); + const auto SrcSize = OpSizeFromSrc(Op); Ref Src1 = LoadSource(FPRClass, Op, Op->Dest, Op->Flags); Ref Src2 = LoadSource(FPRClass, Op, Op->Src[0], Op->Flags); @@ -880,7 +880,7 @@ void OpDispatchBuilder::PSHUFBOp(OpcodeArgs) { } void OpDispatchBuilder::VPSHUFBOp(OpcodeArgs) { - const auto SrcSize = GetSrcSize(Op); + const auto SrcSize = OpSizeFromSrc(Op); Ref Src1 = LoadSource(FPRClass, Op, Op->Src[0], Op->Flags); Ref Src2 = LoadSource(FPRClass, Op, Op->Src[1], Op->Flags); @@ -3314,7 +3314,7 @@ Ref OpDispatchBuilder::PMULHRSWOpImpl(OpSize Size, Ref Src1, Ref Src2) { // Implementation is more efficient for 8byte registers Res = _VSMull(Size * 2, OpSize::i16Bit, Src1, Src2); Res = _VSShrI(Size * 2, OpSize::i32Bit, Res, 14); - auto OneVector = _VectorImm(Size * 2, OpSize::i32Bit, 1); + auto OneVector = _VectorImm(IR::MultiplyOpSize(Size, 2), OpSize::i32Bit, 1); Res = _VAdd(Size * 2, OpSize::i32Bit, Res, OneVector); return _VUShrNI(Size * 2, OpSize::i32Bit, Res, 1); } else { @@ -4558,7 +4558,7 @@ Ref OpDispatchBuilder::VPERMDIndices(OpSize DstSize, Ref Indices, Ref IndexMask, } void OpDispatchBuilder::VPERMDOp(OpcodeArgs) { - const auto DstSize = GetDstSize(Op); + const auto DstSize = OpSizeFromDst(Op); Ref Indices = LoadSource(FPRClass, Op, Op->Src[0], Op->Flags); Ref Src = LoadSource(FPRClass, Op, Op->Src[1], Op->Flags); @@ -4771,7 +4771,7 @@ void OpDispatchBuilder::VPERMILImmOp(OpcodeArgs, size_t ElementSize) { StoreResult(FPRClass, Op, Result, OpSize::iInvalid); } -Ref OpDispatchBuilder::VPERMILRegOpImpl(OpSize DstSize, size_t ElementSize, Ref Src, Ref Indices) { +Ref OpDispatchBuilder::VPERMILRegOpImpl(OpSize DstSize, IR::OpSize ElementSize, Ref Src, Ref Indices) { // NOTE: See implementation of VPERMD for the gist of what we do to make this work. // // The only difference here is that we need to add 16 to the upper lane @@ -4807,7 +4807,7 @@ Ref OpDispatchBuilder::VPERMILRegOpImpl(OpSize DstSize, size_t ElementSize, Ref if (Is256Bit) { const auto ZeroRegister = LoadZeroVector(DstSize); - Ref Vector16 = _VInsElement(DstSize, OpSize::i128Bit, 1, 0, ZeroRegister, _VectorImm(DstSize, 1, 16)); + Ref Vector16 = _VInsElement(DstSize, OpSize::i128Bit, 1, 0, ZeroRegister, _VectorImm(DstSize, OpSize::i8Bit, 16)); Ref IndexOffsets = _VAdd(DstSize, OpSize::i8Bit, VectorConst, Vector16); FinalIndices = _VAdd(DstSize, OpSize::i8Bit, IndexOffsets, ShiftedIndices); @@ -4818,7 +4818,7 @@ Ref OpDispatchBuilder::VPERMILRegOpImpl(OpSize DstSize, size_t ElementSize, Ref return _VTBL1(DstSize, Src, FinalIndices); } -template +template void OpDispatchBuilder::VPERMILRegOp(OpcodeArgs) { Ref Src = LoadSource(FPRClass, Op, Op->Src[0], Op->Flags); Ref Indices = LoadSource(FPRClass, Op, Op->Src[1], Op->Flags); diff --git a/FEXCore/Source/Interface/IR/IR.h b/FEXCore/Source/Interface/IR/IR.h index a8f899aba..a823ff7cc 100644 --- a/FEXCore/Source/Interface/IR/IR.h +++ b/FEXCore/Source/Interface/IR/IR.h @@ -607,6 +607,14 @@ static inline uint8_t OpSizeToSize(IR::OpSize Size) { } } +static inline OpSize MultiplyOpSize(IR::OpSize Size, uint8_t Multiplier) { + return IR::SizeToOpSize(IR::OpSizeToSize(Size) * Multiplier); +} + +static inline OpSize DivideOpSize(IR::OpSize Size, uint8_t Multiplier) { + return IR::SizeToOpSize(IR::OpSizeToSize(Size) / Multiplier); +} + #define IROP_ENUM #define IROP_STRUCTS #define IROP_SIZES diff --git a/FEXCore/Source/Interface/IR/IR.json b/FEXCore/Source/Interface/IR/IR.json index 9e654f681..6161f5049 100644 --- a/FEXCore/Source/Interface/IR/IR.json +++ b/FEXCore/Source/Interface/IR/IR.json @@ -1879,7 +1879,7 @@ "DestSize": "RegisterSize" }, - "FPR = VectorImm u8:#RegisterSize, u8:#ElementSize, u8:$Immediate, u8:$ShiftAmount{0}": { + "FPR = VectorImm OpSize:#RegisterSize, OpSize:#ElementSize, u8:$Immediate, u8:$ShiftAmount{0}": { "Desc": ["Generates a vector with each element containg the immediate zexted" ], "DestSize": "RegisterSize",