OpcodeDispatcher: Implement handling for BLSR

This commit is contained in:
lioncash 2021-11-06 23:15:59 -04:00
parent a393d6609f
commit ff9190204c
4 changed files with 80 additions and 1 deletions

View File

@ -2261,6 +2261,51 @@ void OpDispatchBuilder::BLSIBMIOp(OpcodeArgs) {
}
}
void OpDispatchBuilder::BLSRBMIOp(OpcodeArgs) {
// Equivalent to: (Src - 1) & Src
auto Zero = _Constant(0);
auto One = _Constant(1);
auto* Src = LoadSource(GPRClass, Op, Op->Src[0], Op->Flags, -1);
auto Result = _And(_Sub(Src, One), Src);
StoreResult(GPRClass, Op, Result, -1);
// Now for flags.
SetRFLAG<X86State::RFLAG_OF_LOC>(Zero);
SetRFLAG<X86State::RFLAG_AF_LOC>(Zero);
if (CTX->Config.ABINoPF) {
_InvalidateFlags(1UL << X86State::RFLAG_PF_LOC);
} else {
SetRFLAG<X86State::RFLAG_PF_LOC>(Zero);
}
// ZF
{
auto ZFOp = _Select(IR::COND_EQ,
Result, Zero,
One, Zero);
SetRFLAG<X86State::RFLAG_ZF_LOC>(ZFOp);
}
// CF
{
auto CFOp = _Select(IR::COND_EQ,
Src, Zero,
Zero, One);
SetRFLAG<X86State::RFLAG_CF_LOC>(CFOp);
}
// SF
{
auto SignBit = _Constant((GetSrcSize(Op) * 8) - 1);
auto SFOp = _Lshr(Result, SignBit);
SetRFLAG<X86State::RFLAG_SF_LOC>(SFOp);
}
}
void OpDispatchBuilder::RCROp1Bit(OpcodeArgs) {
OrderedNode *Dest = LoadSource(GPRClass, Op, Op->Dest, Op->Flags, -1);
auto Size = GetSrcSize(Op) * 8;
@ -5935,6 +5980,7 @@ constexpr uint16_t PF_F2 = 3;
#define OPD(group, pp, opcode) (((group - X86Tables::InstType::TYPE_VEX_GROUP_12) << 4) | (pp << 3) | (opcode))
const std::vector<std::tuple<uint8_t, uint8_t, X86Tables::OpDispatchPtr>> VEXGroupTable = {
{OPD(X86Tables::InstType::TYPE_VEX_GROUP_17, 0, 0b001), 1, &OpDispatchBuilder::BLSRBMIOp},
{OPD(X86Tables::InstType::TYPE_VEX_GROUP_17, 0, 0b011), 1, &OpDispatchBuilder::BLSIBMIOp},
};
#undef OPD

View File

@ -328,6 +328,7 @@ public:
void ANDNBMIOp(OpcodeArgs);
void BEXTRBMIOp(OpcodeArgs);
void BLSIBMIOp(OpcodeArgs);
void BLSRBMIOp(OpcodeArgs);
// X87 Ops
template<size_t width>

View File

@ -503,7 +503,7 @@ void InitializeVEXTables() {
{OPD(TYPE_VEX_GROUP_15, 1, 0b010), 1, X86InstInfo{"VLDMXCSR", TYPE_UNDEC, FLAGS_MODRM, 0, nullptr}},
{OPD(TYPE_VEX_GROUP_15, 1, 0b011), 1, X86InstInfo{"VSTMXCSR", TYPE_UNDEC, FLAGS_MODRM, 0, nullptr}},
{OPD(TYPE_VEX_GROUP_17, 0, 0b001), 1, X86InstInfo{"BLSR", TYPE_UNDEC, FLAGS_MODRM, 0, nullptr}},
{OPD(TYPE_VEX_GROUP_17, 0, 0b001), 1, X86InstInfo{"BLSR", TYPE_INST, FLAGS_MODRM | FLAGS_VEX_DST, 0, nullptr}},
{OPD(TYPE_VEX_GROUP_17, 0, 0b010), 1, X86InstInfo{"BLSMSK", TYPE_UNDEC, FLAGS_MODRM, 0, nullptr}},
{OPD(TYPE_VEX_GROUP_17, 0, 0b011), 1, X86InstInfo{"BLSI", TYPE_INST, FLAGS_MODRM | FLAGS_VEX_DST, 0, nullptr}},
};

View File

@ -0,0 +1,32 @@
%ifdef CONFIG
{
"RegData": {
"RAX": "10",
"RBX": "0xFF00000000000000",
"RCX": "0xFE00000000000000",
"RDX": "10",
"RSI": "0xFF000000",
"RDI": "0xFE000000"
}
}
%endif
; Trivial test, this should result in 10.
mov rax, 11
blsr rax, rax
; Results in 0xFE00000000000000 being placed into RCX
mov rbx, 0xFF00000000000000
blsr rcx, rbx
; Same tests but with 32-bit registers
; Trivial test, this should result in 10.
mov edx, 11
blsr edx, edx
; Results in 0xFE000000 being placed in EDI
mov rsi, 0xFF000000
blsr edi, esi
hlt