Fixes issues with PSLLDQ and PSRLDQ

These are whole vector shift instructions and they shift by bytes rather
than bits.
You only get an immediate offset for the instruction.
Implements two new IR ops to account for these instructions

This also doesn't match AArch64 behaviour 100%, requires two
instructions to emulate rather than the single one on the x86-side
This commit is contained in:
Ryan Houdek authored and Stefanos Kornilios Mitsis Poiitidis committed 2020-03-06 07:55:59 +02:00
1 parent af6eefb495
commit afdbd9ebdc
6 files changed
+93 -8

No files matched your search

@@ -1022,6 +1022,25 @@ void InterpreterCore::ExecuteCode(FEXCore::Core::InternalThreadState *Thread) {
memcpy(GDP, &Dst, 16);
break;
}
case IR::OP_VSLI: {
auto Op = IROp->C<IR::IROp_VSLI>();
__uint128_t Src1 = *GetSrc<__uint128_t*>(Op->Header.Args[0]);
__uint128_t Src2 = Op->ByteShift;
__uint128_t Dst = Src1 << (Src2 * 8);
memcpy(GDP, &Dst, 16);
break;
}
case IR::OP_VSRI: {
auto Op = IROp->C<IR::IROp_VSRI>();
__uint128_t Src1 = *GetSrc<__uint128_t*>(Op->Header.Args[0]);
__uint128_t Src2 = Op->ByteShift;
__uint128_t Dst = Src1 >> (Src2 * 8);
memcpy(GDP, &Dst, 16);
break;
}
#define DO_VECTOR_OP(size, type, func) \
case size: { \
auto *Dst_d = reinterpret_cast<type*>(Tmp); \
+14
View File
@@ -1480,6 +1480,20 @@ void *JITCore::CompileCode([[maybe_unused]] FEXCore::IR::IRListView<true> const
}
break;
}
case IR::OP_VSLI: {
auto Op = IROp->C<IR::IROp_VSLI>();
eor(VTMP1.V16B(), VTMP1.V16B(), VTMP1.V16B());
sli(VTMP1.V16B(), GetSrc(Op->Header.Args[0].ID()).V16B(), Op->ByteShift);
mov(GetDst(Node).V16B(), VTMP1.V16B());
break;
}
case IR::OP_VSRI: {
auto Op = IROp->C<IR::IROp_VSRI>();
eor(VTMP1.V16B(), VTMP1.V16B(), VTMP1.V16B());
sri(VTMP1.V16B(), GetSrc(Op->Header.Args[0].ID()).V16B(), Op->ByteShift);
mov(GetDst(Node).V16B(), VTMP1.V16B());
break;
}
case IR::OP_VUMIN: {
auto Op = IROp->C<IR::IROp_VUMin>();
switch (Op->ElementSize) {
+14
View File
@@ -1562,6 +1562,20 @@ void *JITCore::CompileCode([[maybe_unused]] FEXCore::IR::IRListView<true> const
break;
}
case IR::OP_VSLI: {
auto Op = IROp->C<IR::IROp_VSLI>();
movapd(xmm15, GetSrc(Op->Header.Args[0].ID()));
pslldq(xmm15, Op->ByteShift);
movapd(GetDst(Node), xmm15);
break;
}
case IR::OP_VSRI: {
auto Op = IROp->C<IR::IROp_VSRI>();
movapd(xmm15, GetSrc(Op->Header.Args[0].ID()));
psrldq(xmm15, Op->ByteShift);
movapd(GetDst(Node), xmm15);
break;
}
case IR::OP_VEXTR: {
auto Op = IROp->C<IR::IROp_VExtr>();
vpalignr(GetDst(Node), GetSrc(Op->Header.Args[0].ID()), GetSrc(Op->Header.Args[1].ID()), Op->Index);
+19 -8
View File
@@ -3136,15 +3136,27 @@ void OpDispatchBuilder::PSLL(OpcodeArgs) {
}
void OpDispatchBuilder::PSRLDQ(OpcodeArgs) {
OrderedNode *Src = LoadSource(Op, Op->Src1, Op->Flags, -1);
LogMan::Throw::A(Op->Src1.TypeNone.Type == FEXCore::X86Tables::DecodedOperand::TYPE_LITERAL, "Src1 needs to be literal here");
uint64_t Shift = Op->Src1.TypeLiteral.Literal;
OrderedNode *Dest = LoadSource(Op, Op->Dest, Op->Flags, -1);
// PSRLDQ shifts by bytes
// Adjust input value by number of bytes
Src = _Lshl(Src, _Constant(3));
auto Size = GetDstSize(Op);
auto Shift = _Lshr(Dest, Src);
StoreResult(Op, Shift, -1);
auto Result = _VSRI(Size, 16, Dest, Shift);
StoreResult(Op, Result, -1);
}
void OpDispatchBuilder::PSLLDQ(OpcodeArgs) {
LogMan::Throw::A(Op->Src1.TypeNone.Type == FEXCore::X86Tables::DecodedOperand::TYPE_LITERAL, "Src1 needs to be literal here");
uint64_t Shift = Op->Src1.TypeLiteral.Literal;
OrderedNode *Dest = LoadSource(Op, Op->Dest, Op->Flags, -1);
auto Size = GetDstSize(Op);
auto Result = _VSLI(Size, 16, Dest, Shift);
StoreResult(Op, Result, -1);
}
void OpDispatchBuilder::MOVDDUPOp(OpcodeArgs) {
@@ -3607,8 +3619,7 @@ constexpr uint16_t PF_F2 = 3;
{OPD(FEXCore::X86Tables::TYPE_GROUP_14, PF_66, 2), 1, &OpDispatchBuilder::PSRLD<4>},
{OPD(FEXCore::X86Tables::TYPE_GROUP_14, PF_66, 6), 1, &OpDispatchBuilder::PSLL<8, true>},
{OPD(FEXCore::X86Tables::TYPE_GROUP_14, PF_66, 3), 1, &OpDispatchBuilder::PSRLDQ},
// XXX: Causes issues with ld.so
// {OPD(FEXCore::X86Tables::TYPE_GROUP_14, PF_66, 7), 1, &OpDispatchBuilder::PSLL<16, true>},
{OPD(FEXCore::X86Tables::TYPE_GROUP_14, PF_66, 7), 1, &OpDispatchBuilder::PSLLDQ},
// GROUP 15
{OPD(FEXCore::X86Tables::TYPE_GROUP_15, PF_NONE, 0), 1, &OpDispatchBuilder::FXSaveOp},
+7
View File
@@ -182,6 +182,7 @@ public:
template<size_t ElementSize, bool Scalar>
void PSLL(OpcodeArgs);
void PSRLDQ(OpcodeArgs);
void PSLLDQ(OpcodeArgs);
void MOVDDUPOp(OpcodeArgs);
template<size_t ElementSize>
@@ -281,6 +282,12 @@ public:
IRPair<IROp_VExtr> _VExtr(uint8_t RegisterSize, uint8_t ElementSize, OrderedNode *ssa0, OrderedNode *ssa1, uint8_t Index) {
return _VExtr(ssa0, ssa1, RegisterSize, ElementSize, Index);
}
IRPair<IROp_VSLI> _VSLI(uint8_t RegisterSize, uint8_t ElementSize, OrderedNode *ssa0, uint8_t ByteShift) {
return _VSLI(ssa0, RegisterSize, ElementSize, ByteShift);
}
IRPair<IROp_VSRI> _VSRI(uint8_t RegisterSize, uint8_t ElementSize, OrderedNode *ssa0, uint8_t ByteShift) {
return _VSRI(ssa0, RegisterSize, ElementSize, ByteShift);
}
IRPair<IROp_Jump> _Jump() {
return _Jump(InvalidNode);
}
+20
View File
@@ -563,6 +563,26 @@
]
},
"VSLI": {
"HasDest": true,
"SSAArgs": "1",
"Args": [
"uint8_t", "RegisterSize",
"uint8_t", "ElementSize",
"uint8_t", "ByteShift"
]
},
"VSRI": {
"HasDest": true,
"SSAArgs": "1",
"Args": [
"uint8_t", "RegisterSize",
"uint8_t", "ElementSize",
"uint8_t", "ByteShift"
]
},
"VBitcast": {
"HasDest": true,
"SSAArgs": "1"