mirror of
https://github.com/FEX-Emu/FEX.git
synced 2025-01-07 06:03:50 +00:00
Merge pull request #3553 from alyssarosenzweig/ra/shifts-rework-easy
OpcodeDispatcher: clean up shifts
This commit is contained in:
commit
c43af8e975
@ -1546,6 +1546,19 @@ void OpDispatchBuilder::CPUIDOp(OpcodeArgs) {
|
||||
StoreGPRRegister(X86State::REG_RCX, _Bfe(OpSize::i64Bit, 32, 0, Result_Upper));
|
||||
}
|
||||
|
||||
uint32_t OpDispatchBuilder::LoadConstantShift(X86Tables::DecodedOp Op, bool Is1Bit) {
|
||||
if (Is1Bit) {
|
||||
return 1;
|
||||
} else {
|
||||
// x86 masks the shift by 0x3F or 0x1F depending on size of op
|
||||
const uint32_t Size = GetSrcBitSize(Op);
|
||||
uint64_t Mask = Size == 64 ? 0x3F : 0x1F;
|
||||
|
||||
LOGMAN_THROW_A_FMT(Op->Src[1].IsLiteral(), "Src1 needs to be literal here");
|
||||
return Op->Src[1].Data.Literal.Value & Mask;
|
||||
}
|
||||
}
|
||||
|
||||
void OpDispatchBuilder::XGetBVOp(OpcodeArgs) {
|
||||
OrderedNode *Function = LoadGPRRegister(X86State::REG_RCX);
|
||||
|
||||
@ -1558,49 +1571,24 @@ void OpDispatchBuilder::XGetBVOp(OpcodeArgs) {
|
||||
StoreGPRRegister(X86State::REG_RDX, Result_Upper);
|
||||
}
|
||||
|
||||
template<bool SHL1Bit>
|
||||
void OpDispatchBuilder::SHLOp(OpcodeArgs) {
|
||||
OrderedNode *Src{};
|
||||
OrderedNode *Dest = LoadSource(GPRClass, Op, Op->Dest, Op->Flags);
|
||||
|
||||
if constexpr (SHL1Bit) {
|
||||
Src = _Constant(1);
|
||||
}
|
||||
else {
|
||||
Src = LoadSource(GPRClass, Op, Op->Src[1], Op->Flags);
|
||||
}
|
||||
const auto Size = GetSrcBitSize(Op);
|
||||
auto Dest = LoadSource(GPRClass, Op, Op->Dest, Op->Flags);
|
||||
auto Src = LoadSource(GPRClass, Op, Op->Src[1], Op->Flags);
|
||||
|
||||
OrderedNode *Result = _Lshl(Size == 64 ? OpSize::i64Bit : OpSize::i32Bit, Dest, Src);
|
||||
StoreResult(GPRClass, Op, Result, -1);
|
||||
|
||||
if (Size < 32) {
|
||||
Result = _Bfe(OpSize::i32Bit, Size, 0, Result);
|
||||
}
|
||||
|
||||
if constexpr (SHL1Bit) {
|
||||
GenerateFlags_ShiftLeftImmediate(Op, Result, Dest, 1);
|
||||
}
|
||||
else {
|
||||
GenerateFlags_ShiftLeft(Op, Result, Dest, Src);
|
||||
}
|
||||
GenerateFlags_ShiftLeft(Op, Result, Dest, Src);
|
||||
}
|
||||
|
||||
template<bool SHL1Bit>
|
||||
void OpDispatchBuilder::SHLImmediateOp(OpcodeArgs) {
|
||||
OrderedNode *Dest = LoadSource(GPRClass, Op, Op->Dest, Op->Flags);
|
||||
|
||||
LOGMAN_THROW_A_FMT(Op->Src[1].IsLiteral(), "Src1 needs to be literal here");
|
||||
|
||||
uint64_t Shift = Op->Src[1].Data.Literal.Value;
|
||||
uint64_t Shift = LoadConstantShift(Op, SHL1Bit);
|
||||
const auto Size = GetSrcBitSize(Op);
|
||||
|
||||
// x86 masks the shift by 0x3F or 0x1F depending on size of op
|
||||
if (Size == 64) {
|
||||
Shift &= 0x3F;
|
||||
} else {
|
||||
Shift &= 0x1F;
|
||||
}
|
||||
|
||||
OrderedNode *Src = _Constant(Size, Shift);
|
||||
OrderedNode *Result = _Lshl(Size == 64 ? OpSize::i64Bit : OpSize::i32Bit, Dest, Src);
|
||||
|
||||
@ -1609,44 +1597,23 @@ void OpDispatchBuilder::SHLImmediateOp(OpcodeArgs) {
|
||||
GenerateFlags_ShiftLeftImmediate(Op, Result, Dest, Shift);
|
||||
}
|
||||
|
||||
template<bool SHR1Bit>
|
||||
void OpDispatchBuilder::SHROp(OpcodeArgs) {
|
||||
OrderedNode *Src;
|
||||
auto Dest = LoadSource(GPRClass, Op, Op->Dest, Op->Flags);
|
||||
|
||||
if constexpr (SHR1Bit) {
|
||||
Src = _Constant(1);
|
||||
}
|
||||
else {
|
||||
Src = LoadSource(GPRClass, Op, Op->Src[1], Op->Flags);
|
||||
}
|
||||
auto Src = LoadSource(GPRClass, Op, Op->Src[1], Op->Flags);
|
||||
|
||||
auto ALUOp = _Lshr(IR::SizeToOpSize(std::max<uint8_t>(4, GetSrcSize(Op))), Dest, Src);
|
||||
StoreResult(GPRClass, Op, ALUOp, -1);
|
||||
|
||||
if constexpr (SHR1Bit) {
|
||||
GenerateFlags_ShiftRightImmediate(Op, ALUOp, Dest, 1);
|
||||
}
|
||||
else {
|
||||
GenerateFlags_ShiftRight(Op, ALUOp, Dest, Src);
|
||||
}
|
||||
GenerateFlags_ShiftRight(Op, ALUOp, Dest, Src);
|
||||
}
|
||||
|
||||
template<bool SHR1Bit>
|
||||
void OpDispatchBuilder::SHRImmediateOp(OpcodeArgs) {
|
||||
auto Dest = LoadSource(GPRClass, Op, Op->Dest, Op->Flags);
|
||||
|
||||
LOGMAN_THROW_A_FMT(Op->Src[1].IsLiteral(), "Src1 needs to be literal here");
|
||||
|
||||
uint64_t Shift = Op->Src[1].Data.Literal.Value;
|
||||
uint64_t Shift = LoadConstantShift(Op, SHR1Bit);
|
||||
const auto Size = GetSrcBitSize(Op);
|
||||
|
||||
// x86 masks the shift by 0x3F or 0x1F depending on size of op
|
||||
if (Size == 64) {
|
||||
Shift &= 0x3F;
|
||||
} else {
|
||||
Shift &= 0x1F;
|
||||
}
|
||||
|
||||
OrderedNode *Src = _Constant(Size, Shift);
|
||||
auto ALUOp = _Lshr(Size == 64 ? OpSize::i64Bit : OpSize::i32Bit, Dest, Src);
|
||||
|
||||
@ -1666,13 +1633,7 @@ void OpDispatchBuilder::SHLDOp(OpcodeArgs) {
|
||||
|
||||
const auto Size = GetSrcBitSize(Op);
|
||||
|
||||
// x86 masks the shift by 0x3F or 0x1F depending on size of op. Arm will mask
|
||||
// by 0x3F when we do 64-bit shifts so we don't need to mask in that case,
|
||||
// since the modulo is preserved even after presubtracting Size=64 for
|
||||
// ShiftRight.
|
||||
//
|
||||
// TODO: Implement this optimization, it requires turning the shift=0 cases
|
||||
// into (shift&0xc0) bit tests which is a bit complicated for now.
|
||||
// x86 masks the shift by 0x3F or 0x1F depending on size of op.
|
||||
if (Size == 64) {
|
||||
Shift = _And(OpSize::i64Bit, Shift, _Constant(0x3F));
|
||||
} else {
|
||||
@ -1712,18 +1673,9 @@ void OpDispatchBuilder::SHLDImmediateOp(OpcodeArgs) {
|
||||
OrderedNode *Src = LoadSource(GPRClass, Op, Op->Src[0], Op->Flags);
|
||||
OrderedNode *Dest = LoadSource(GPRClass, Op, Op->Dest, Op->Flags);
|
||||
|
||||
LOGMAN_THROW_A_FMT(Op->Src[1].IsLiteral(), "Src1 needs to be literal here");
|
||||
|
||||
uint64_t Shift = Op->Src[1].Data.Literal.Value;
|
||||
uint64_t Shift = LoadConstantShift(Op, false);
|
||||
const auto Size = GetSrcBitSize(Op);
|
||||
|
||||
// x86 masks the shift by 0x3F or 0x1F depending on size of op
|
||||
if (Size == 64) {
|
||||
Shift &= 0x3F;
|
||||
} else {
|
||||
Shift &= 0x1F;
|
||||
}
|
||||
|
||||
if (Shift != 0) {
|
||||
OrderedNode *Res{};
|
||||
if (Size < 32) {
|
||||
@ -1784,9 +1736,6 @@ void OpDispatchBuilder::SHRDOp(OpcodeArgs) {
|
||||
|
||||
StoreResult(GPRClass, Op, Res, -1);
|
||||
|
||||
if (Size != 64) {
|
||||
Res = _Bfe(OpSize::i64Bit, Size, 0, Res);
|
||||
}
|
||||
GenerateFlags_ShiftRight(Op, Res, Dest, Shift);
|
||||
}
|
||||
|
||||
@ -1794,20 +1743,10 @@ void OpDispatchBuilder::SHRDImmediateOp(OpcodeArgs) {
|
||||
OrderedNode *Src = LoadSource(GPRClass, Op, Op->Src[0], Op->Flags);
|
||||
OrderedNode *Dest = LoadSource(GPRClass, Op, Op->Dest, Op->Flags);
|
||||
|
||||
LOGMAN_THROW_A_FMT(Op->Src[1].IsLiteral(), "Src1 needs to be literal here");
|
||||
|
||||
uint64_t Shift = Op->Src[1].Data.Literal.Value;
|
||||
uint64_t Shift = LoadConstantShift(Op, false);
|
||||
const auto Size = GetSrcBitSize(Op);
|
||||
|
||||
// x86 masks the shift by 0x3F or 0x1F depending on size of op
|
||||
if (Size == 64) {
|
||||
Shift &= 0x3F;
|
||||
} else {
|
||||
Shift &= 0x1F;
|
||||
}
|
||||
|
||||
if (Shift != 0) {
|
||||
|
||||
OrderedNode *Res{};
|
||||
if (Size < 32) {
|
||||
OrderedNode *ShiftRight = _Constant(Shift);
|
||||
@ -1832,19 +1771,11 @@ void OpDispatchBuilder::SHRDImmediateOp(OpcodeArgs) {
|
||||
}
|
||||
}
|
||||
|
||||
template<bool SHR1Bit>
|
||||
void OpDispatchBuilder::ASHROp(OpcodeArgs) {
|
||||
OrderedNode *Src;
|
||||
OrderedNode *Dest = LoadSource(GPRClass, Op, Op->Dest, Op->Flags);
|
||||
auto Dest = LoadSource(GPRClass, Op, Op->Dest, Op->Flags);
|
||||
auto Src = LoadSource(GPRClass, Op, Op->Src[1], Op->Flags);
|
||||
|
||||
const auto Size = GetSrcBitSize(Op);
|
||||
|
||||
if constexpr (SHR1Bit) {
|
||||
Src = _Constant(Size, 1);
|
||||
} else {
|
||||
Src = LoadSource(GPRClass, Op, Op->Src[1], Op->Flags);
|
||||
}
|
||||
|
||||
if (Size < 32) {
|
||||
Dest = _Sbfe(OpSize::i64Bit, Size, 0, Dest);
|
||||
}
|
||||
@ -1852,28 +1783,16 @@ void OpDispatchBuilder::ASHROp(OpcodeArgs) {
|
||||
OrderedNode *Result = _Ashr(IR::SizeToOpSize(std::max<uint8_t>(4, GetSrcSize(Op))), Dest, Src);
|
||||
StoreResult(GPRClass, Op, Result, -1);
|
||||
|
||||
if constexpr (SHR1Bit) {
|
||||
GenerateFlags_SignShiftRightImmediate(Op, Result, Dest, 1);
|
||||
} else {
|
||||
GenerateFlags_SignShiftRight(Op, Result, Dest, Src);
|
||||
}
|
||||
GenerateFlags_SignShiftRight(Op, Result, Dest, Src);
|
||||
}
|
||||
|
||||
template<bool SHR1Bit>
|
||||
void OpDispatchBuilder::ASHRImmediateOp(OpcodeArgs) {
|
||||
OrderedNode *Dest = LoadSource(GPRClass, Op, Op->Dest, Op->Flags);
|
||||
|
||||
LOGMAN_THROW_A_FMT(Op->Src[1].IsLiteral(), "Src1 needs to be literal here");
|
||||
|
||||
uint64_t Shift = Op->Src[1].Data.Literal.Value;
|
||||
uint64_t Shift = LoadConstantShift(Op, SHR1Bit);
|
||||
const auto Size = GetSrcBitSize(Op);
|
||||
|
||||
// x86 masks the shift by 0x3F or 0x1F depending on size of op
|
||||
if (Size == 64) {
|
||||
Shift &= 0x3F;
|
||||
} else {
|
||||
Shift &= 0x1F;
|
||||
}
|
||||
|
||||
if (Size < 32) {
|
||||
Dest = _Sbfe(OpSize::i64Bit, Size, 0, Dest);
|
||||
}
|
||||
@ -1891,16 +1810,13 @@ void OpDispatchBuilder::RotateOp(OpcodeArgs) {
|
||||
CalculateDeferredFlags();
|
||||
|
||||
auto LoadShift = [this, Op](bool MustMask) -> OrderedNode * {
|
||||
// x86 masks the shift by 0x3F or 0x1F depending on size of op
|
||||
const uint32_t Size = GetSrcBitSize(Op);
|
||||
uint64_t Mask = Size == 64 ? 0x3F : 0x1F;
|
||||
|
||||
if (Is1Bit) {
|
||||
return _Constant(1);
|
||||
} else if (IsImmediate) {
|
||||
LOGMAN_THROW_A_FMT(Op->Src[1].IsLiteral(), "Src1 needs to be literal here");
|
||||
return _Constant(Op->Src[1].Data.Literal.Value & Mask);
|
||||
if (Is1Bit || IsImmediate) {
|
||||
return _Constant(LoadConstantShift(Op, Is1Bit));
|
||||
} else {
|
||||
// x86 masks the shift by 0x3F or 0x1F depending on size of op
|
||||
const uint32_t Size = GetSrcBitSize(Op);
|
||||
uint64_t Mask = Size == 64 ? 0x3F : 0x1F;
|
||||
|
||||
auto Src = LoadSource(GPRClass, Op, Op->Src[1], Op->Flags, {.AllowUpperGarbage = true});
|
||||
return MustMask ? _And(OpSize::i64Bit, Src, _Constant(Mask)) : Src;
|
||||
}
|
||||
@ -6080,55 +5996,55 @@ void InstallOpcodeHandlers(Context::OperatingMode Mode) {
|
||||
{OPD(FEXCore::X86Tables::TYPE_GROUP_2, OpToIndex(0xC0), 1), 1, &OpDispatchBuilder::RotateOp<false, true, false>},
|
||||
{OPD(FEXCore::X86Tables::TYPE_GROUP_2, OpToIndex(0xC0), 2), 1, &OpDispatchBuilder::RCLOp},
|
||||
{OPD(FEXCore::X86Tables::TYPE_GROUP_2, OpToIndex(0xC0), 3), 1, &OpDispatchBuilder::RCROp},
|
||||
{OPD(FEXCore::X86Tables::TYPE_GROUP_2, OpToIndex(0xC0), 4), 1, &OpDispatchBuilder::SHLImmediateOp},
|
||||
{OPD(FEXCore::X86Tables::TYPE_GROUP_2, OpToIndex(0xC0), 5), 1, &OpDispatchBuilder::SHRImmediateOp},
|
||||
{OPD(FEXCore::X86Tables::TYPE_GROUP_2, OpToIndex(0xC0), 6), 1, &OpDispatchBuilder::SHLImmediateOp}, // SAL
|
||||
{OPD(FEXCore::X86Tables::TYPE_GROUP_2, OpToIndex(0xC0), 7), 1, &OpDispatchBuilder::ASHRImmediateOp}, // SAR
|
||||
{OPD(FEXCore::X86Tables::TYPE_GROUP_2, OpToIndex(0xC0), 4), 1, &OpDispatchBuilder::SHLImmediateOp<false>},
|
||||
{OPD(FEXCore::X86Tables::TYPE_GROUP_2, OpToIndex(0xC0), 5), 1, &OpDispatchBuilder::SHRImmediateOp<false>},
|
||||
{OPD(FEXCore::X86Tables::TYPE_GROUP_2, OpToIndex(0xC0), 6), 1, &OpDispatchBuilder::SHLImmediateOp<false>}, // SAL
|
||||
{OPD(FEXCore::X86Tables::TYPE_GROUP_2, OpToIndex(0xC0), 7), 1, &OpDispatchBuilder::ASHRImmediateOp<false>}, // SAR
|
||||
|
||||
{OPD(FEXCore::X86Tables::TYPE_GROUP_2, OpToIndex(0xC1), 0), 1, &OpDispatchBuilder::RotateOp<true, true, false>},
|
||||
{OPD(FEXCore::X86Tables::TYPE_GROUP_2, OpToIndex(0xC1), 1), 1, &OpDispatchBuilder::RotateOp<false, true, false>},
|
||||
{OPD(FEXCore::X86Tables::TYPE_GROUP_2, OpToIndex(0xC1), 2), 1, &OpDispatchBuilder::RCLOp},
|
||||
{OPD(FEXCore::X86Tables::TYPE_GROUP_2, OpToIndex(0xC1), 3), 1, &OpDispatchBuilder::RCROp},
|
||||
{OPD(FEXCore::X86Tables::TYPE_GROUP_2, OpToIndex(0xC1), 4), 1, &OpDispatchBuilder::SHLImmediateOp},
|
||||
{OPD(FEXCore::X86Tables::TYPE_GROUP_2, OpToIndex(0xC1), 5), 1, &OpDispatchBuilder::SHRImmediateOp},
|
||||
{OPD(FEXCore::X86Tables::TYPE_GROUP_2, OpToIndex(0xC1), 6), 1, &OpDispatchBuilder::SHLImmediateOp}, // SAL
|
||||
{OPD(FEXCore::X86Tables::TYPE_GROUP_2, OpToIndex(0xC1), 7), 1, &OpDispatchBuilder::ASHRImmediateOp}, // SAR
|
||||
{OPD(FEXCore::X86Tables::TYPE_GROUP_2, OpToIndex(0xC1), 4), 1, &OpDispatchBuilder::SHLImmediateOp<false>},
|
||||
{OPD(FEXCore::X86Tables::TYPE_GROUP_2, OpToIndex(0xC1), 5), 1, &OpDispatchBuilder::SHRImmediateOp<false>},
|
||||
{OPD(FEXCore::X86Tables::TYPE_GROUP_2, OpToIndex(0xC1), 6), 1, &OpDispatchBuilder::SHLImmediateOp<false>}, // SAL
|
||||
{OPD(FEXCore::X86Tables::TYPE_GROUP_2, OpToIndex(0xC1), 7), 1, &OpDispatchBuilder::ASHRImmediateOp<false>}, // SAR
|
||||
|
||||
{OPD(FEXCore::X86Tables::TYPE_GROUP_2, OpToIndex(0xD0), 0), 1, &OpDispatchBuilder::RotateOp<true, true, true>},
|
||||
{OPD(FEXCore::X86Tables::TYPE_GROUP_2, OpToIndex(0xD0), 1), 1, &OpDispatchBuilder::RotateOp<false, true, true>},
|
||||
{OPD(FEXCore::X86Tables::TYPE_GROUP_2, OpToIndex(0xD0), 2), 1, &OpDispatchBuilder::RCLOp1Bit},
|
||||
{OPD(FEXCore::X86Tables::TYPE_GROUP_2, OpToIndex(0xD0), 3), 1, &OpDispatchBuilder::RCROp8x1Bit},
|
||||
{OPD(FEXCore::X86Tables::TYPE_GROUP_2, OpToIndex(0xD0), 4), 1, &OpDispatchBuilder::SHLOp<true>},
|
||||
{OPD(FEXCore::X86Tables::TYPE_GROUP_2, OpToIndex(0xD0), 5), 1, &OpDispatchBuilder::SHROp<true>}, // 1Bit SHR
|
||||
{OPD(FEXCore::X86Tables::TYPE_GROUP_2, OpToIndex(0xD0), 6), 1, &OpDispatchBuilder::SHLOp<true>}, // SAL
|
||||
{OPD(FEXCore::X86Tables::TYPE_GROUP_2, OpToIndex(0xD0), 7), 1, &OpDispatchBuilder::ASHROp<true>}, // SAR
|
||||
{OPD(FEXCore::X86Tables::TYPE_GROUP_2, OpToIndex(0xD0), 4), 1, &OpDispatchBuilder::SHLImmediateOp<true>},
|
||||
{OPD(FEXCore::X86Tables::TYPE_GROUP_2, OpToIndex(0xD0), 5), 1, &OpDispatchBuilder::SHRImmediateOp<true>}, // 1Bit SHR
|
||||
{OPD(FEXCore::X86Tables::TYPE_GROUP_2, OpToIndex(0xD0), 6), 1, &OpDispatchBuilder::SHLImmediateOp<true>}, // SAL
|
||||
{OPD(FEXCore::X86Tables::TYPE_GROUP_2, OpToIndex(0xD0), 7), 1, &OpDispatchBuilder::ASHRImmediateOp<true>}, // SAR
|
||||
|
||||
{OPD(FEXCore::X86Tables::TYPE_GROUP_2, OpToIndex(0xD1), 0), 1, &OpDispatchBuilder::RotateOp<true, true, true>},
|
||||
{OPD(FEXCore::X86Tables::TYPE_GROUP_2, OpToIndex(0xD1), 1), 1, &OpDispatchBuilder::RotateOp<false, true, true>},
|
||||
{OPD(FEXCore::X86Tables::TYPE_GROUP_2, OpToIndex(0xD1), 2), 1, &OpDispatchBuilder::RCLOp1Bit},
|
||||
{OPD(FEXCore::X86Tables::TYPE_GROUP_2, OpToIndex(0xD1), 3), 1, &OpDispatchBuilder::RCROp1Bit},
|
||||
{OPD(FEXCore::X86Tables::TYPE_GROUP_2, OpToIndex(0xD1), 4), 1, &OpDispatchBuilder::SHLOp<true>},
|
||||
{OPD(FEXCore::X86Tables::TYPE_GROUP_2, OpToIndex(0xD1), 5), 1, &OpDispatchBuilder::SHROp<true>}, // 1Bit SHR
|
||||
{OPD(FEXCore::X86Tables::TYPE_GROUP_2, OpToIndex(0xD1), 6), 1, &OpDispatchBuilder::SHLOp<true>}, // SAL
|
||||
{OPD(FEXCore::X86Tables::TYPE_GROUP_2, OpToIndex(0xD1), 7), 1, &OpDispatchBuilder::ASHROp<true>}, // SAR
|
||||
{OPD(FEXCore::X86Tables::TYPE_GROUP_2, OpToIndex(0xD1), 4), 1, &OpDispatchBuilder::SHLImmediateOp<true>},
|
||||
{OPD(FEXCore::X86Tables::TYPE_GROUP_2, OpToIndex(0xD1), 5), 1, &OpDispatchBuilder::SHRImmediateOp<true>}, // 1Bit SHR
|
||||
{OPD(FEXCore::X86Tables::TYPE_GROUP_2, OpToIndex(0xD1), 6), 1, &OpDispatchBuilder::SHLImmediateOp<true>}, // SAL
|
||||
{OPD(FEXCore::X86Tables::TYPE_GROUP_2, OpToIndex(0xD1), 7), 1, &OpDispatchBuilder::ASHRImmediateOp<true>}, // SAR
|
||||
|
||||
{OPD(FEXCore::X86Tables::TYPE_GROUP_2, OpToIndex(0xD2), 0), 1, &OpDispatchBuilder::RotateOp<true, false, false>},
|
||||
{OPD(FEXCore::X86Tables::TYPE_GROUP_2, OpToIndex(0xD2), 1), 1, &OpDispatchBuilder::RotateOp<false, false, false>},
|
||||
{OPD(FEXCore::X86Tables::TYPE_GROUP_2, OpToIndex(0xD2), 2), 1, &OpDispatchBuilder::RCLSmallerOp},
|
||||
{OPD(FEXCore::X86Tables::TYPE_GROUP_2, OpToIndex(0xD2), 3), 1, &OpDispatchBuilder::RCRSmallerOp},
|
||||
{OPD(FEXCore::X86Tables::TYPE_GROUP_2, OpToIndex(0xD2), 4), 1, &OpDispatchBuilder::SHLOp<false>},
|
||||
{OPD(FEXCore::X86Tables::TYPE_GROUP_2, OpToIndex(0xD2), 5), 1, &OpDispatchBuilder::SHROp<false>}, // SHR by CL
|
||||
{OPD(FEXCore::X86Tables::TYPE_GROUP_2, OpToIndex(0xD2), 6), 1, &OpDispatchBuilder::SHLOp<false>}, // SAL
|
||||
{OPD(FEXCore::X86Tables::TYPE_GROUP_2, OpToIndex(0xD2), 7), 1, &OpDispatchBuilder::ASHROp<false>}, // SAR
|
||||
{OPD(FEXCore::X86Tables::TYPE_GROUP_2, OpToIndex(0xD2), 4), 1, &OpDispatchBuilder::SHLOp},
|
||||
{OPD(FEXCore::X86Tables::TYPE_GROUP_2, OpToIndex(0xD2), 5), 1, &OpDispatchBuilder::SHROp}, // SHR by CL
|
||||
{OPD(FEXCore::X86Tables::TYPE_GROUP_2, OpToIndex(0xD2), 6), 1, &OpDispatchBuilder::SHLOp}, // SAL
|
||||
{OPD(FEXCore::X86Tables::TYPE_GROUP_2, OpToIndex(0xD2), 7), 1, &OpDispatchBuilder::ASHROp}, // SAR
|
||||
|
||||
{OPD(FEXCore::X86Tables::TYPE_GROUP_2, OpToIndex(0xD3), 0), 1, &OpDispatchBuilder::RotateOp<true, false, false>},
|
||||
{OPD(FEXCore::X86Tables::TYPE_GROUP_2, OpToIndex(0xD3), 1), 1, &OpDispatchBuilder::RotateOp<false, false, false>},
|
||||
{OPD(FEXCore::X86Tables::TYPE_GROUP_2, OpToIndex(0xD3), 2), 1, &OpDispatchBuilder::RCLOp},
|
||||
{OPD(FEXCore::X86Tables::TYPE_GROUP_2, OpToIndex(0xD3), 3), 1, &OpDispatchBuilder::RCROp},
|
||||
{OPD(FEXCore::X86Tables::TYPE_GROUP_2, OpToIndex(0xD3), 4), 1, &OpDispatchBuilder::SHLOp<false>},
|
||||
{OPD(FEXCore::X86Tables::TYPE_GROUP_2, OpToIndex(0xD3), 5), 1, &OpDispatchBuilder::SHROp<false>}, // SHR by CL
|
||||
{OPD(FEXCore::X86Tables::TYPE_GROUP_2, OpToIndex(0xD3), 6), 1, &OpDispatchBuilder::SHLOp<false>}, // SAL
|
||||
{OPD(FEXCore::X86Tables::TYPE_GROUP_2, OpToIndex(0xD3), 7), 1, &OpDispatchBuilder::ASHROp<false>}, // SAR
|
||||
{OPD(FEXCore::X86Tables::TYPE_GROUP_2, OpToIndex(0xD3), 4), 1, &OpDispatchBuilder::SHLOp},
|
||||
{OPD(FEXCore::X86Tables::TYPE_GROUP_2, OpToIndex(0xD3), 5), 1, &OpDispatchBuilder::SHROp}, // SHR by CL
|
||||
{OPD(FEXCore::X86Tables::TYPE_GROUP_2, OpToIndex(0xD3), 6), 1, &OpDispatchBuilder::SHLOp}, // SAL
|
||||
{OPD(FEXCore::X86Tables::TYPE_GROUP_2, OpToIndex(0xD3), 7), 1, &OpDispatchBuilder::ASHROp}, // SAR
|
||||
|
||||
// GROUP 3
|
||||
{OPD(FEXCore::X86Tables::TYPE_GROUP_3, OpToIndex(0xF6), 0), 1, &OpDispatchBuilder::TESTOp<1>},
|
||||
|
@ -329,18 +329,19 @@ public:
|
||||
void CMOVOp(OpcodeArgs);
|
||||
void CPUIDOp(OpcodeArgs);
|
||||
void XGetBVOp(OpcodeArgs);
|
||||
template<bool SHL1Bit>
|
||||
uint32_t LoadConstantShift(X86Tables::DecodedOp Op, bool Is1Bit);
|
||||
void SHLOp(OpcodeArgs);
|
||||
template<bool SHL1Bit>
|
||||
void SHLImmediateOp(OpcodeArgs);
|
||||
template<bool SHR1Bit>
|
||||
void SHROp(OpcodeArgs);
|
||||
template<bool SHR1Bit>
|
||||
void SHRImmediateOp(OpcodeArgs);
|
||||
void SHLDOp(OpcodeArgs);
|
||||
void SHLDImmediateOp(OpcodeArgs);
|
||||
void SHRDOp(OpcodeArgs);
|
||||
void SHRDImmediateOp(OpcodeArgs);
|
||||
template<bool SHR1Bit>
|
||||
void ASHROp(OpcodeArgs);
|
||||
template<bool SHR1Bit>
|
||||
void ASHRImmediateOp(OpcodeArgs);
|
||||
template<bool Left, bool IsImmediate, bool Is1Bit>
|
||||
void RotateOp(OpcodeArgs);
|
||||
|
@ -1295,13 +1295,12 @@
|
||||
]
|
||||
},
|
||||
"shl al, 1": {
|
||||
"ExpectedInstructionCount": 8,
|
||||
"ExpectedInstructionCount": 7,
|
||||
"Comment": "GROUP2 0xd0 /4",
|
||||
"ExpectedArm64ASM": [
|
||||
"uxtb w20, w4",
|
||||
"lsl w21, w20, #1",
|
||||
"bfxil x4, x21, #0, #8",
|
||||
"uxtb w26, w21",
|
||||
"lsl w26, w20, #1",
|
||||
"bfxil x4, x26, #0, #8",
|
||||
"cmn wzr, w26, lsl #24",
|
||||
"rmif x20, #6, #nzCv",
|
||||
"eor w20, w26, w20",
|
||||
@ -1326,7 +1325,7 @@
|
||||
"ExpectedArm64ASM": [
|
||||
"uxtb w20, w4",
|
||||
"sxtb x20, w20",
|
||||
"asr w26, w20, #1",
|
||||
"asr x26, x20, #1",
|
||||
"bfxil x4, x26, #0, #8",
|
||||
"cmn wzr, w26, lsl #24",
|
||||
"rmif x20, #63, #nzCv"
|
||||
@ -1471,13 +1470,12 @@
|
||||
]
|
||||
},
|
||||
"shl ax, 1": {
|
||||
"ExpectedInstructionCount": 8,
|
||||
"ExpectedInstructionCount": 7,
|
||||
"Comment": "GROUP2 0xd1 /4",
|
||||
"ExpectedArm64ASM": [
|
||||
"uxth w20, w4",
|
||||
"lsl w21, w20, #1",
|
||||
"bfxil x4, x21, #0, #16",
|
||||
"uxth w26, w21",
|
||||
"lsl w26, w20, #1",
|
||||
"bfxil x4, x26, #0, #16",
|
||||
"cmn wzr, w26, lsl #16",
|
||||
"rmif x20, #14, #nzCv",
|
||||
"eor w20, w26, w20",
|
||||
@ -1552,7 +1550,7 @@
|
||||
"ExpectedArm64ASM": [
|
||||
"uxth w20, w4",
|
||||
"sxth x20, w20",
|
||||
"asr w26, w20, #1",
|
||||
"asr x26, x20, #1",
|
||||
"bfxil x4, x26, #0, #16",
|
||||
"cmn wzr, w26, lsl #16",
|
||||
"rmif x20, #63, #nzCv"
|
||||
@ -1671,14 +1669,13 @@
|
||||
]
|
||||
},
|
||||
"shl al, cl": {
|
||||
"ExpectedInstructionCount": 14,
|
||||
"ExpectedInstructionCount": 13,
|
||||
"Comment": "GROUP2 0xd2 /4",
|
||||
"ExpectedArm64ASM": [
|
||||
"uxtb w20, w4",
|
||||
"uxtb w21, w5",
|
||||
"lsl w22, w20, w21",
|
||||
"bfxil x4, x22, #0, #8",
|
||||
"uxtb w22, w22",
|
||||
"cbz x21, #+0x24",
|
||||
"cmn wzr, w22, lsl #24",
|
||||
"mov w23, #0x8",
|
||||
@ -1939,14 +1936,13 @@
|
||||
]
|
||||
},
|
||||
"shl ax, cl": {
|
||||
"ExpectedInstructionCount": 14,
|
||||
"ExpectedInstructionCount": 13,
|
||||
"Comment": "GROUP2 0xd3 /4",
|
||||
"ExpectedArm64ASM": [
|
||||
"uxth w20, w4",
|
||||
"uxth w21, w5",
|
||||
"lsl w22, w20, w21",
|
||||
"bfxil x4, x22, #0, #16",
|
||||
"uxth w22, w22",
|
||||
"cbz x21, #+0x24",
|
||||
"cmn wzr, w22, lsl #16",
|
||||
"mov w23, #0x10",
|
||||
|
@ -1504,13 +1504,12 @@
|
||||
]
|
||||
},
|
||||
"shl al, 1": {
|
||||
"ExpectedInstructionCount": 12,
|
||||
"ExpectedInstructionCount": 11,
|
||||
"Comment": "GROUP2 0xd0 /4",
|
||||
"ExpectedArm64ASM": [
|
||||
"uxtb w20, w4",
|
||||
"lsl w21, w20, #1",
|
||||
"bfxil x4, x21, #0, #8",
|
||||
"uxtb w26, w21",
|
||||
"lsl w26, w20, #1",
|
||||
"bfxil x4, x26, #0, #8",
|
||||
"cmn wzr, w26, lsl #24",
|
||||
"ubfx x21, x20, #7, #1",
|
||||
"mrs x22, nzcv",
|
||||
@ -1543,7 +1542,7 @@
|
||||
"ExpectedArm64ASM": [
|
||||
"uxtb w20, w4",
|
||||
"sxtb x20, w20",
|
||||
"asr w26, w20, #1",
|
||||
"asr x26, x20, #1",
|
||||
"bfxil x4, x26, #0, #8",
|
||||
"cmn wzr, w26, lsl #24",
|
||||
"ubfx x20, x20, #0, #1",
|
||||
@ -1769,13 +1768,12 @@
|
||||
]
|
||||
},
|
||||
"shl ax, 1": {
|
||||
"ExpectedInstructionCount": 12,
|
||||
"ExpectedInstructionCount": 11,
|
||||
"Comment": "GROUP2 0xd1 /4",
|
||||
"ExpectedArm64ASM": [
|
||||
"uxth w20, w4",
|
||||
"lsl w21, w20, #1",
|
||||
"bfxil x4, x21, #0, #16",
|
||||
"uxth w26, w21",
|
||||
"lsl w26, w20, #1",
|
||||
"bfxil x4, x26, #0, #16",
|
||||
"cmn wzr, w26, lsl #16",
|
||||
"ubfx x21, x20, #15, #1",
|
||||
"mrs x22, nzcv",
|
||||
@ -1874,7 +1872,7 @@
|
||||
"ExpectedArm64ASM": [
|
||||
"uxth w20, w4",
|
||||
"sxth x20, w20",
|
||||
"asr w26, w20, #1",
|
||||
"asr x26, x20, #1",
|
||||
"bfxil x4, x26, #0, #16",
|
||||
"cmn wzr, w26, lsl #16",
|
||||
"ubfx x20, x20, #0, #1",
|
||||
@ -2026,14 +2024,13 @@
|
||||
]
|
||||
},
|
||||
"shl al, cl": {
|
||||
"ExpectedInstructionCount": 18,
|
||||
"ExpectedInstructionCount": 17,
|
||||
"Comment": "GROUP2 0xd2 /4",
|
||||
"ExpectedArm64ASM": [
|
||||
"uxtb w20, w4",
|
||||
"uxtb w21, w5",
|
||||
"lsl w22, w20, w21",
|
||||
"bfxil x4, x22, #0, #8",
|
||||
"uxtb w22, w22",
|
||||
"cbz x21, #+0x34",
|
||||
"cmn wzr, w22, lsl #24",
|
||||
"mov w23, #0x8",
|
||||
@ -2381,14 +2378,13 @@
|
||||
]
|
||||
},
|
||||
"shl ax, cl": {
|
||||
"ExpectedInstructionCount": 18,
|
||||
"ExpectedInstructionCount": 17,
|
||||
"Comment": "GROUP2 0xd3 /4",
|
||||
"ExpectedArm64ASM": [
|
||||
"uxth w20, w4",
|
||||
"uxth w21, w5",
|
||||
"lsl w22, w20, w21",
|
||||
"bfxil x4, x22, #0, #16",
|
||||
"uxth w22, w22",
|
||||
"cbz x21, #+0x34",
|
||||
"cmn wzr, w22, lsl #16",
|
||||
"mov w23, #0x10",
|
||||
|
Loading…
Reference in New Issue
Block a user