mirror of
https://github.com/FEX-Emu/FEX.git
synced 2025-01-10 07:41:41 +00:00
OpcodeDispatcher: Implement handling for BLSR
This commit is contained in:
parent
a393d6609f
commit
ff9190204c
@ -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
|
||||
|
@ -328,6 +328,7 @@ public:
|
||||
void ANDNBMIOp(OpcodeArgs);
|
||||
void BEXTRBMIOp(OpcodeArgs);
|
||||
void BLSIBMIOp(OpcodeArgs);
|
||||
void BLSRBMIOp(OpcodeArgs);
|
||||
|
||||
// X87 Ops
|
||||
template<size_t width>
|
||||
|
@ -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}},
|
||||
};
|
||||
|
32
unittests/ASM/VEX/blsr.asm
Normal file
32
unittests/ASM/VEX/blsr.asm
Normal 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
|
Loading…
Reference in New Issue
Block a user