Implement PAVGB/PAVGW

This commit is contained in:
Stefanos Kornilios Mitsis Poiitidis committed 2020-07-04 19:30:53 +03:00
1 parent 82e43ad35d
commit c19e8b3d2f
13 files changed
+367 -2

No files matched your search

@@ -2539,6 +2539,23 @@ void InterpreterCore::ExecuteCode(FEXCore::Core::InternalThreadState *Thread) {
memcpy(GDP, Tmp, Op->Header.ElementSize);
break;
}
case IR::OP_VURAVG: {
auto Op = IROp->C<IR::IROp_VURAvg>();
void *Src1 = GetSrc<void*>(Op->Header.Args[0]);
void *Src2 = GetSrc<void*>(Op->Header.Args[1]);
uint8_t Tmp[16];
uint8_t Elements = OpSize / Op->Header.ElementSize;
auto Func = [](auto a, auto b) { return (a + b + 1) >> 1; };
switch (Op->Header.ElementSize) {
DO_VECTOR_OP(1, uint8_t, Func)
DO_VECTOR_OP(2, uint16_t, Func)
default: LogMan::Msg::A("Unknown Element Size: %d", Op->Header.ElementSize); break;
}
memcpy(GDP, Tmp, OpSize);
break;
}
case IR::OP_VABS: {
auto Op = IROp->C<IR::IROp_VAbs>();
void *Src = GetSrc<void*>(Op->Header.Args[0]);
@@ -276,6 +276,21 @@ DEF_OP(VAddV) {
}
}
DEF_OP(VURAvg) {
auto Op = IROp->C<IR::IROp_VURAvg>();
switch (Op->Header.ElementSize) {
case 1: {
urhadd(GetDst(Node).V16B(), GetSrc(Op->Header.Args[0].ID()).V16B(), GetSrc(Op->Header.Args[1].ID()).V16B());
break;
}
case 2: {
urhadd(GetDst(Node).V8H(), GetSrc(Op->Header.Args[0].ID()).V8H(), GetSrc(Op->Header.Args[1].ID()).V8H());
break;
}
default: LogMan::Msg::A("Unknown Element Size: %d", Op->Header.ElementSize); break;
}
}
DEF_OP(VAbs) {
auto Op = IROp->C<IR::IROp_VAbs>();
uint8_t OpSize = IROp->Size;
@@ -2404,6 +2404,21 @@ void *JITCore::CompileCode([[maybe_unused]] FEXCore::IR::IRListView<true> const
movaps(Dest, xmm15);
break;
}
case IR::OP_VURAVG: {
auto Op = IROp->C<IR::IROp_VURAvg>();
switch (Op->Header.ElementSize) {
case 1: {
vpavgb(GetDst(Node), GetSrc(Op->Header.Args[0].ID()), GetSrc(Op->Header.Args[1].ID()));
break;
}
case 2: {
vpavgw(GetDst(Node), GetSrc(Op->Header.Args[0].ID()), GetSrc(Op->Header.Args[1].ID()));
break;
}
default: LogMan::Msg::A("Unknown Element Size: %d", Op->Header.ElementSize); break;
}
break;
}
case IR::OP_VABS: {
auto Op = IROp->C<IR::IROp_VAbs>();
switch (Op->Header.ElementSize) {
@@ -626,6 +626,41 @@ private:
return Result;
}
llvm::Value *VURAVG(llvm::Value *Arg1, llvm::Value *Arg2, uint8_t RegisterSize, uint8_t ElementSize) {
uint8_t NumElements = RegisterSize / ElementSize;
std::vector<llvm::Value*> Values1;
std::vector<llvm::Value*> Values2;
std::vector<llvm::Value*> Results;
// XXX: these need to be widening to ElementSize * 2 for overflows
for (size_t i = 0; i < NumElements; ++i) {
Values1.emplace_back(JITState.IRBuilder->CreateExtractElement(Arg1, i));;
Values2.emplace_back(JITState.IRBuilder->CreateExtractElement(Arg2, i));;
}
for (size_t i = 0; i < NumElements; ++i) {
// XXX: These need to operate on ElementSize * 2 for overflows
auto sum = JITState.IRBuilder->CreateAdd(Values1[i], Values2[i]);
sum = JITState.IRBuilder->CreateAdd(sum, JITState.IRBuilder->getIntN(ElementSize, 1));
// XXX: This needs to be narrowing to ElementSize
auto Result = JITState.IRBuilder->CreateLShr(sum, JITState.IRBuilder->getIntN(ElementSize, 1));
Results.emplace_back(Result);
}
// Cast to the type we want
llvm::Value *Result = llvm::UndefValue::get(Arg1->getType());
for (size_t i = 0; i < NumElements; ++i) {
Result = JITState.IRBuilder->CreateInsertElement(Result, Results[i], i);
}
return Result;
}
llvm::Value *VADDV(llvm::Value *Arg, uint8_t RegisterSize, uint8_t ElementSize) {
uint8_t NumElements = RegisterSize / ElementSize;
std::vector<llvm::Value*> Values;
@@ -2693,6 +2728,20 @@ void LLVMJITCore::HandleIR(FEXCore::IR::IRListView<true> const *IR, IR::NodeWrap
SetDest(*WrapperOp, Result);
break;
}
case IR::OP_VURAVG: {
auto Op = IROp->C<IR::IROp_VURAvg>();
auto Src1 = GetSrc(Op->Header.Args[0]);
auto Src2 = GetSrc(Op->Header.Args[1]);
// Cast to the type we want
Src1 = CastVectorToType(Src1, true, OpSize, Op->Header.ElementSize);
Src2 = CastVectorToType(Src2, true, OpSize, Op->Header.ElementSize);
auto Result = VURAVG(Src1, Src2, OpSize, Op->Header.ElementSize);
SetDest(*WrapperOp, Result);
break;
}
case IR::OP_VABS: {
auto Op = IROp->C<IR::IROp_VAbs>();
auto Src = GetSrc(Op->Header.Args[0]);
@@ -5133,6 +5133,16 @@ void OpDispatchBuilder::PSRAIOp(OpcodeArgs) {
StoreResult(FPRClass, Op, Result, -1);
}
template<size_t ElementSize>
void OpDispatchBuilder::PAVGOp(OpcodeArgs) {
auto Size = GetSrcSize(Op);
OrderedNode *Src = LoadSource(FPRClass, Op, Op->Src[0], Op->Flags, -1);
OrderedNode *Dest = LoadSource(FPRClass, Op, Op->Dest, Op->Flags, -1);
auto Result = _VURAvg(Size, ElementSize, Dest, Src);
StoreResult(FPRClass, Op, Result, -1);
}
void OpDispatchBuilder::MOVDDUPOp(OpcodeArgs) {
OrderedNode *Src = LoadSource(FPRClass, Op, Op->Src[0], Op->Flags, -1);
OrderedNode *Res = _SplatVector2(Src);
@@ -7171,8 +7181,10 @@ void InstallOpcodeHandlers(Context::OperatingMode Mode) {
{0xDD, 1, &OpDispatchBuilder::PADDSOp<2, false>},
{0xDE, 1, &OpDispatchBuilder::PMAXUOp<1>},
{0xDF, 1, &OpDispatchBuilder::ANDNOp},
{0xE0, 1, &OpDispatchBuilder::PAVGOp<1>},
{0xE1, 1, &OpDispatchBuilder::PSRAOp<2, true, 0>},
{0xE2, 1, &OpDispatchBuilder::PSRAOp<4, true, 0>},
{0xE3, 1, &OpDispatchBuilder::PAVGOp<2>},
{0xE4, 1, &OpDispatchBuilder::PMULHW<false>},
{0xE5, 1, &OpDispatchBuilder::PMULHW<true>},
{0xE7, 1, &OpDispatchBuilder::MOVUPSOp},
@@ -7437,8 +7449,10 @@ void InstallOpcodeHandlers(Context::OperatingMode Mode) {
{0xDD, 1, &OpDispatchBuilder::VectorALUOp<IR::OP_VUQADD, 2>},
{0xDE, 1, &OpDispatchBuilder::PMAXUOp<1>},
{0xDF, 1, &OpDispatchBuilder::ANDNOp},
{0xE0, 1, &OpDispatchBuilder::PAVGOp<1>},
{0xE1, 1, &OpDispatchBuilder::PSRAOp<2, true, 0>},
{0xE2, 1, &OpDispatchBuilder::PSRAOp<4, true, 0>},
{0xE3, 1, &OpDispatchBuilder::PAVGOp<2>},
{0xE4, 1, &OpDispatchBuilder::PMULHW<false>},
{0xE5, 1, &OpDispatchBuilder::PMULHW<true>},
{0xE6, 1, &OpDispatchBuilder::Vector_CVT_Float_To_Int<8, true, true>},
@@ -258,6 +258,8 @@ public:
void PSLLDQ(OpcodeArgs);
template<size_t ElementSize>
void PSRAIOp(OpcodeArgs);
template<size_t ElementSize>
void PAVGOp(OpcodeArgs);
void MOVDDUPOp(OpcodeArgs);
template<size_t DstElementSize, bool Signed>
void CVTGPR_To_FPR(OpcodeArgs);
@@ -215,10 +215,10 @@ void InitializeSecondaryTables() {
{0xDE, 1, X86InstInfo{"PMAXUB", TYPE_INST, GenFlagsSameSize(SIZE_64BIT) | FLAGS_MODRM | FLAGS_XMM_FLAGS | FLAGS_SF_MMX, 0, nullptr}},
{0xDF, 1, X86InstInfo{"PANDN", TYPE_INST, GenFlagsSameSize(SIZE_64BIT) | FLAGS_MODRM | FLAGS_XMM_FLAGS | FLAGS_SF_MMX, 0, nullptr}},
{0xE0, 1, X86InstInfo{"PAVGB", TYPE_MMX, GenFlagsSameSize(SIZE_64BIT) | FLAGS_MODRM | FLAGS_XMM_FLAGS | FLAGS_SF_MMX, 0, nullptr}},
{0xE0, 1, X86InstInfo{"PAVGB", TYPE_INST, GenFlagsSameSize(SIZE_64BIT) | FLAGS_MODRM | FLAGS_XMM_FLAGS | FLAGS_SF_MMX, 0, nullptr}},
{0xE1, 1, X86InstInfo{"PSRAW", TYPE_INST, GenFlagsSameSize(SIZE_64BIT) | FLAGS_MODRM | FLAGS_XMM_FLAGS | FLAGS_SF_MMX, 0, nullptr}},
{0xE2, 1, X86InstInfo{"PSRAD", TYPE_INST, GenFlagsSameSize(SIZE_64BIT) | FLAGS_MODRM | FLAGS_XMM_FLAGS | FLAGS_SF_MMX, 0, nullptr}},
{0xE3, 1, X86InstInfo{"PAVGW", TYPE_MMX, GenFlagsSameSize(SIZE_64BIT) | FLAGS_MODRM | FLAGS_XMM_FLAGS | FLAGS_SF_MMX, 0, nullptr}},
{0xE3, 1, X86InstInfo{"PAVGW", TYPE_INST, GenFlagsSameSize(SIZE_64BIT) | FLAGS_MODRM | FLAGS_XMM_FLAGS | FLAGS_SF_MMX, 0, nullptr}},
{0xE4, 1, X86InstInfo{"PMULHUW", TYPE_INST, GenFlagsSameSize(SIZE_64BIT) | FLAGS_MODRM | FLAGS_XMM_FLAGS | FLAGS_SF_MMX, 0, nullptr}},
{0xE5, 1, X86InstInfo{"PMULHW", TYPE_INST, GenFlagsSameSize(SIZE_64BIT) | FLAGS_MODRM | FLAGS_XMM_FLAGS | FLAGS_SF_MMX, 0, nullptr}},
{0xE6, 1, X86InstInfo{"", TYPE_INVALID, FLAGS_NONE, 0, nullptr}},
+18
View File
@@ -1533,6 +1533,24 @@
]
},
"VURAvg": {
"OpClass": "Vector",
"Desc": ["Does an unsigned rounded average", "dst_elem = (src1_elem + src2_elem + 1) >> 1"],
"HasDest": true,
"DestClass": "FPR",
"DestSize": "RegisterSize",
"NumElements": "RegisterSize / ElementSize",
"SSAArgs": "2",
"SSANames": [
"Vector1",
"Vector2"
],
"HelperArgs": [
"uint8_t", "RegisterSize",
"uint8_t", "ElementSize"
]
},
"VAbs": {
"OpClass": "Vector",
"Desc": ["Does an signed integer absolute"
+3
View File
@@ -127,6 +127,9 @@ friend class FEXCore::IR::PassManager;
IRPair<IROp_VAddV> _VAddV(uint8_t RegisterSize, uint8_t ElementSize, OrderedNode *ssa0) {
return _VAddV(ssa0, RegisterSize, ElementSize);
}
IRPair<IROp_VURAvg> _VURAvg(uint8_t RegisterSize, uint8_t ElementSize, OrderedNode *ssa0, OrderedNode *ssa1) {
return _VURAvg(ssa0, ssa1, RegisterSize, ElementSize);
}
IRPair<IROp_VAbs> _VAbs(uint8_t RegisterSize, uint8_t ElementSize, OrderedNode *ssa0) {
return _VAbs(ssa0, RegisterSize, ElementSize);
}
+58
View File
@@ -0,0 +1,58 @@
%ifdef CONFIG
{
"RegData": {
"XMM0": ["0x2179b0697d5378c4", "0x3b8e6eae8c165248"],
"XMM1": ["0x1ed68638699d35ca", "0x5e2e7560ab7b5262"],
"XMM2": ["0x165c42291f28194c", "0x0923643c32130145"],
"XMM3": ["0x2179b0697d5378c4", "0x3b8e6eae8c165248"],
"XMM4": ["0x1ed68638699d35ca", "0x5e2e7560ab7b5262"],
"XMM5": ["0x165c42291f28194c", "0x0923643c32130145"]
},
"MemoryRegions": {
"0x100000000": "4096"
}
}
%endif
mov rdx, 0xe0000000
mov rax, 0x2bb883523d4f3197
mov [rdx + 8 * 0], rax
mov rax, 0x1246c77764260189
mov [rdx + 8 * 1], rax
mov rax, 0x163add80bc57bef1
mov [rdx + 8 * 2], rax
mov rax, 0x64d615e5b405a306
mov [rdx + 8 * 3], rax
mov rax, 0x11f4881d94eb39fc
mov [rdx + 8 * 4], rax
mov rax, 0xa9162248f2d0a23a
mov [rdx + 8 * 5], rax
mov rax, 0x0
mov [rdx + 8 * 6], rax
mov rax, 0x0
mov [rdx + 8 * 7], rax
movapd xmm0, [rdx + 8 * 0]
movapd xmm1, [rdx + 8 * 0]
movapd xmm2, [rdx + 8 * 0]
movapd xmm3, [rdx + 8 * 0]
movapd xmm4, [rdx + 8 * 0]
movapd xmm5, [rdx + 8 * 0]
movapd xmm6, [rdx + 8 * 2]
movapd xmm7, [rdx + 8 * 4]
movapd xmm8, [rdx + 8 * 6]
pavgb xmm0, xmm6
pavgb xmm1, xmm7
pavgb xmm2, xmm8
pavgb xmm3, [rdx + 8 * 2]
pavgb xmm4, [rdx + 8 * 4]
pavgb xmm5, [rdx + 8 * 6]
hlt
+58
View File
@@ -0,0 +1,58 @@
%ifdef CONFIG
{
"RegData": {
"XMM0": ["0x20f9b0697cd37844", "0x3b8e6eae8c165248"],
"XMM1": ["0x1ed685b8691d35ca", "0x5dae74e0ab7b51e2"],
"XMM2": ["0x15dc41a91ea818cc", "0x092363bc321300c5"],
"XMM3": ["0x20f9b0697cd37844", "0x3b8e6eae8c165248"],
"XMM4": ["0x1ed685b8691d35ca", "0x5dae74e0ab7b51e2"],
"XMM5": ["0x15dc41a91ea818cc", "0x092363bc321300c5"]
},
"MemoryRegions": {
"0x100000000": "4096"
}
}
%endif
mov rdx, 0xe0000000
mov rax, 0x2bb883523d4f3197
mov [rdx + 8 * 0], rax
mov rax, 0x1246c77764260189
mov [rdx + 8 * 1], rax
mov rax, 0x163add80bc57bef1
mov [rdx + 8 * 2], rax
mov rax, 0x64d615e5b405a306
mov [rdx + 8 * 3], rax
mov rax, 0x11f4881d94eb39fc
mov [rdx + 8 * 4], rax
mov rax, 0xa9162248f2d0a23a
mov [rdx + 8 * 5], rax
mov rax, 0x0
mov [rdx + 8 * 6], rax
mov rax, 0x0
mov [rdx + 8 * 7], rax
movapd xmm0, [rdx + 8 * 0]
movapd xmm1, [rdx + 8 * 0]
movapd xmm2, [rdx + 8 * 0]
movapd xmm3, [rdx + 8 * 0]
movapd xmm4, [rdx + 8 * 0]
movapd xmm5, [rdx + 8 * 0]
movapd xmm6, [rdx + 8 * 2]
movapd xmm7, [rdx + 8 * 4]
movapd xmm8, [rdx + 8 * 6]
pavgw xmm0, xmm6
pavgw xmm1, xmm7
pavgw xmm2, xmm8
pavgw xmm3, [rdx + 8 * 2]
pavgw xmm4, [rdx + 8 * 4]
pavgw xmm5, [rdx + 8 * 6]
hlt
+58
View File
@@ -0,0 +1,58 @@
%ifdef CONFIG
{
"RegData": {
"MM0": ["0x2179b0697d5378c4", "0x0"],
"MM1": ["0x1ed68638699d35ca", "0x0"],
"MM2": ["0x165c42291f28194c", "0x0"],
"MM3": ["0x2179b0697d5378c4", "0x0"],
"MM4": ["0x1ed68638699d35ca", "0x0"],
"MM5": ["0x165c42291f28194c", "0x0"]
},
"MemoryRegions": {
"0x100000000": "4096"
}
}
%endif
mov rdx, 0xe0000000
mov rax, 0x2bb883523d4f3197
mov [rdx + 8 * 0], rax
mov rax, 0x1246c77764260189
mov [rdx + 8 * 1], rax
mov rax, 0x163add80bc57bef1
mov [rdx + 8 * 2], rax
mov rax, 0x64d615e5b405a306
mov [rdx + 8 * 3], rax
mov rax, 0x11f4881d94eb39fc
mov [rdx + 8 * 4], rax
mov rax, 0xa9162248f2d0a23a
mov [rdx + 8 * 5], rax
mov rax, 0x0
mov [rdx + 8 * 6], rax
mov rax, 0x0
mov [rdx + 8 * 7], rax
movq mm0, [rdx + 8 * 0]
movq mm1, [rdx + 8 * 0]
movq mm2, [rdx + 8 * 0]
movq mm3, [rdx + 8 * 0]
movq mm4, [rdx + 8 * 0]
movq mm5, [rdx + 8 * 0]
movq mm6, [rdx + 8 * 2]
movq mm7, [rdx + 8 * 4]
pavgb mm0, mm6
pavgb mm1, mm7
movq mm7, [rdx + 8 * 6]
pavgb mm2, mm7
pavgb mm3, [rdx + 8 * 2]
pavgb mm4, [rdx + 8 * 4]
pavgb mm5, [rdx + 8 * 6]
hlt
+58
View File
@@ -0,0 +1,58 @@
%ifdef CONFIG
{
"RegData": {
"MM0": ["0x20f9b0697cd37844", "0x0"],
"MM1": ["0x1ed685b8691d35ca", "0x0"],
"MM2": ["0x15dc41a91ea818cc", "0x0"],
"MM3": ["0x20f9b0697cd37844", "0x0"],
"MM4": ["0x1ed685b8691d35ca", "0x0"],
"MM5": ["0x15dc41a91ea818cc", "0x0"]
},
"MemoryRegions": {
"0x100000000": "4096"
}
}
%endif
mov rdx, 0xe0000000
mov rax, 0x2bb883523d4f3197
mov [rdx + 8 * 0], rax
mov rax, 0x1246c77764260189
mov [rdx + 8 * 1], rax
mov rax, 0x163add80bc57bef1
mov [rdx + 8 * 2], rax
mov rax, 0x64d615e5b405a306
mov [rdx + 8 * 3], rax
mov rax, 0x11f4881d94eb39fc
mov [rdx + 8 * 4], rax
mov rax, 0xa9162248f2d0a23a
mov [rdx + 8 * 5], rax
mov rax, 0x0
mov [rdx + 8 * 6], rax
mov rax, 0x0
mov [rdx + 8 * 7], rax
movq mm0, [rdx + 8 * 0]
movq mm1, [rdx + 8 * 0]
movq mm2, [rdx + 8 * 0]
movq mm3, [rdx + 8 * 0]
movq mm4, [rdx + 8 * 0]
movq mm5, [rdx + 8 * 0]
movq mm6, [rdx + 8 * 2]
movq mm7, [rdx + 8 * 4]
pavgw mm0, mm6
pavgw mm1, mm7
movq mm7, [rdx + 8 * 6]
pavgw mm2, mm7
pavgw mm3, [rdx + 8 * 2]
pavgw mm4, [rdx + 8 * 4]
pavgw mm5, [rdx + 8 * 6]
hlt