mirror of
https://github.com/FEX-Emu/FEX.git
synced 2026-10-27 21:01:06 +01:00
Merge pull request #1354 from lioncash/bmishift
OpcodeDispatcher: Implement BMI2 SARX/SHLX/SHRX
This commit is contained in:
6 files changed
+136
-4
No files matched your search
@@ -2333,6 +2333,39 @@ void OpDispatchBuilder::BLSRBMIOp(OpcodeArgs) {
|
||||
}
|
||||
}
|
||||
|
||||
void OpDispatchBuilder::BMI2Shift(OpcodeArgs) {
|
||||
// Handles SARX, SHLX, and SHRX
|
||||
|
||||
auto* Src = LoadSource(GPRClass, Op, Op->Src[0], Op->Flags, -1);
|
||||
auto* Shift = LoadSource(GPRClass, Op, Op->Src[1], Op->Flags, -1);
|
||||
const auto OperandSize = GetSrcSize(Op) * 8;
|
||||
|
||||
// x86 masks the shift by 0x3F or 0x1F depending on size of op
|
||||
auto SanitizedShift = [&] {
|
||||
if (OperandSize == 64) {
|
||||
return _And(Shift, _Constant(0x3F));
|
||||
} else {
|
||||
return _And(Shift, _Constant(0x1F));
|
||||
}
|
||||
}();
|
||||
|
||||
auto* Result = [&]() -> OrderedNode* {
|
||||
// SARX
|
||||
if (Op->OP == 0x6F7) {
|
||||
return _Ashr(Src, SanitizedShift);
|
||||
}
|
||||
// SHLX
|
||||
if (Op->OP == 0x5F7) {
|
||||
return _Lshl(Src, SanitizedShift);
|
||||
}
|
||||
|
||||
// SHRX
|
||||
return _Lshr(Src, SanitizedShift);
|
||||
}();
|
||||
|
||||
StoreResult(GPRClass, Op, Result, -1);
|
||||
}
|
||||
|
||||
void OpDispatchBuilder::RCROp1Bit(OpcodeArgs) {
|
||||
OrderedNode *Dest = LoadSource(GPRClass, Op, Op->Dest, Op->Flags, -1);
|
||||
auto Size = GetSrcSize(Op) * 8;
|
||||
@@ -6002,6 +6035,9 @@ constexpr uint16_t PF_F2 = 3;
|
||||
|
||||
{OPD(2, 0b00, 0xF2), 1, &OpDispatchBuilder::ANDNBMIOp},
|
||||
{OPD(2, 0b00, 0xF7), 1, &OpDispatchBuilder::BEXTRBMIOp},
|
||||
{OPD(2, 0b01, 0xF7), 1, &OpDispatchBuilder::BMI2Shift},
|
||||
{OPD(2, 0b10, 0xF7), 1, &OpDispatchBuilder::BMI2Shift},
|
||||
{OPD(2, 0b11, 0xF7), 1, &OpDispatchBuilder::BMI2Shift},
|
||||
};
|
||||
#undef OPD
|
||||
|
||||
|
||||
@@ -324,13 +324,16 @@ public:
|
||||
template<size_t ElementSize>
|
||||
void PSIGN(OpcodeArgs);
|
||||
|
||||
// BMI Ops
|
||||
// BMI1 Ops
|
||||
void ANDNBMIOp(OpcodeArgs);
|
||||
void BEXTRBMIOp(OpcodeArgs);
|
||||
void BLSIBMIOp(OpcodeArgs);
|
||||
void BLSMSKBMIOp(OpcodeArgs);
|
||||
void BLSRBMIOp(OpcodeArgs);
|
||||
|
||||
// BMI2 Ops
|
||||
void BMI2Shift(OpcodeArgs);
|
||||
|
||||
// X87 Ops
|
||||
template<size_t width>
|
||||
void FLD(OpcodeArgs);
|
||||
|
||||
@@ -400,9 +400,9 @@ void InitializeVEXTables() {
|
||||
{OPD(2, 0b11, 0xF6), 1, X86InstInfo{"MULX", TYPE_UNDEC, FLAGS_NONE, 0, nullptr}},
|
||||
|
||||
{OPD(2, 0b00, 0xF7), 1, X86InstInfo{"BEXTR", TYPE_INST, FLAGS_MODRM | FLAGS_VEX_2ND_SRC, 0, nullptr}},
|
||||
{OPD(2, 0b01, 0xF7), 1, X86InstInfo{"SHLX", TYPE_UNDEC, FLAGS_NONE, 0, nullptr}},
|
||||
{OPD(2, 0b10, 0xF7), 1, X86InstInfo{"SARX", TYPE_UNDEC, FLAGS_NONE, 0, nullptr}},
|
||||
{OPD(2, 0b11, 0xF7), 1, X86InstInfo{"SHRX", TYPE_UNDEC, FLAGS_NONE, 0, nullptr}},
|
||||
{OPD(2, 0b01, 0xF7), 1, X86InstInfo{"SHLX", TYPE_INST, FLAGS_MODRM | FLAGS_VEX_2ND_SRC, 0, nullptr}},
|
||||
{OPD(2, 0b10, 0xF7), 1, X86InstInfo{"SARX", TYPE_INST, FLAGS_MODRM | FLAGS_VEX_2ND_SRC, 0, nullptr}},
|
||||
{OPD(2, 0b11, 0xF7), 1, X86InstInfo{"SHRX", TYPE_INST, FLAGS_MODRM | FLAGS_VEX_2ND_SRC, 0, nullptr}},
|
||||
|
||||
// VEX Map 3
|
||||
{OPD(3, 0b01, 0x00), 1, X86InstInfo{"VPERMQ", TYPE_UNDEC, FLAGS_NONE, 0, nullptr}},
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
%ifdef CONFIG
|
||||
{
|
||||
"RegData": {
|
||||
"RAX": "0xF800000000000000",
|
||||
"RBX": "4",
|
||||
"RCX": "0xFFFFFFFFFFFFFFFF",
|
||||
"RDX": "127",
|
||||
"RSI": "63",
|
||||
"RDI": "0x00000000FFFFFFFF"
|
||||
}
|
||||
}
|
||||
%endif
|
||||
|
||||
; Trivial right shift
|
||||
mov rax, 0x8000000000000000
|
||||
mov rbx, 4
|
||||
sarx rax, rax, rbx
|
||||
|
||||
; This is really a shift by 63. This just ensures we properly
|
||||
; mask the shift value according to the ISA manual.
|
||||
mov rcx, 0x8000000000000000
|
||||
mov rdx, 127
|
||||
sarx rcx, rcx, rdx
|
||||
|
||||
; This is really a shift by 31. This just ensures we properly
|
||||
; mask the shift value according to the ISA manual.
|
||||
mov edi, 0x80000000
|
||||
mov esi, 63
|
||||
sarx edi, edi, esi
|
||||
|
||||
hlt
|
||||
@@ -0,0 +1,31 @@
|
||||
%ifdef CONFIG
|
||||
{
|
||||
"RegData": {
|
||||
"RAX": "0x10",
|
||||
"RBX": "4",
|
||||
"RCX": "0x8000000000000000",
|
||||
"RDX": "127",
|
||||
"RSI": "63",
|
||||
"RDI": "0x80000000"
|
||||
}
|
||||
}
|
||||
%endif
|
||||
|
||||
; Trivial left shift
|
||||
mov rax, 1
|
||||
mov rbx, 4
|
||||
shlx rax, rax, rbx
|
||||
|
||||
; This is really a shift by 63. This just ensures we properly
|
||||
; mask the shift value according to the ISA manual.
|
||||
mov rcx, 1
|
||||
mov rdx, 127
|
||||
shlx rcx, rcx, rdx
|
||||
|
||||
; This is really a shift by 31. This just ensures we properly
|
||||
; mask the shift value according to the ISA manual.
|
||||
mov edi, 1
|
||||
mov esi, 63
|
||||
shlx edi, edi, esi
|
||||
|
||||
hlt
|
||||
@@ -0,0 +1,31 @@
|
||||
%ifdef CONFIG
|
||||
{
|
||||
"RegData": {
|
||||
"RAX": "0x0800000000000000",
|
||||
"RBX": "4",
|
||||
"RCX": "1",
|
||||
"RDX": "127",
|
||||
"RSI": "63",
|
||||
"RDI": "1"
|
||||
}
|
||||
}
|
||||
%endif
|
||||
|
||||
; Trivial right shift
|
||||
mov rax, 0x8000000000000000
|
||||
mov rbx, 4
|
||||
shrx rax, rax, rbx
|
||||
|
||||
; This is really a shift by 63. This just ensures we properly
|
||||
; mask the shift value according to the ISA manual.
|
||||
mov rcx, 0x8000000000000000
|
||||
mov rdx, 127
|
||||
shrx rcx, rcx, rdx
|
||||
|
||||
; This is really a shift by 31. This just ensures we properly
|
||||
; mask the shift value according to the ISA manual.
|
||||
mov edi, 0x80000000
|
||||
mov esi, 63
|
||||
shrx edi, edi, esi
|
||||
|
||||
hlt
|
||||
Reference in new issue
Block a user