mirror of
https://github.com/FEX-Emu/FEX.git
synced 2026-10-29 04:01:27 +01:00
Merge pull request #3385 from alyssarosenzweig/opt/bmi
Optimize bit manipulation instructions
This commit is contained in:
12 files changed
+408
-373
No files matched your search
@@ -2133,17 +2133,17 @@ void OpDispatchBuilder::BEXTRBMIOp(OpcodeArgs) {
|
||||
|
||||
// Now handle the length specifier.
|
||||
auto Length = _Bfe(OpSizeFromSrc(Op), 8, 8, Src2);
|
||||
auto SanitizedLength = _Select(IR::COND_ULE,
|
||||
Length, MaxSrcBitOp,
|
||||
Length, MaxSrcBitOp);
|
||||
|
||||
// Now build up the mask
|
||||
// (1 << SanitizedLength) - 1
|
||||
auto One = _Constant(SrcSize, 1);
|
||||
auto Mask = _Sub(IR::SizeToOpSize(Size), _Lshl(IR::SizeToOpSize(Size), One, SanitizedLength), One);
|
||||
// (1 << Length) - 1 = ~(~0 << Length)
|
||||
auto AllOnes = _Constant(~0ull);
|
||||
auto InvertedMask = _Lshl(IR::SizeToOpSize(Size), AllOnes, Length);
|
||||
|
||||
// Now put it all together and make the result.
|
||||
auto Dest = _And(IR::SizeToOpSize(Size), SanitizedShifted, Mask);
|
||||
auto Masked = _Andn(IR::SizeToOpSize(Size), SanitizedShifted, InvertedMask);
|
||||
|
||||
// Sanitize the length. If it is above the max, we don't do the masking.
|
||||
auto Dest = _Select(IR::COND_ULE, Length, MaxSrcBitOp, Masked, SanitizedShifted);
|
||||
|
||||
// Finally store the result.
|
||||
StoreResult(GPRClass, Op, Dest, -1);
|
||||
@@ -2175,7 +2175,7 @@ void OpDispatchBuilder::BLSMSKBMIOp(OpcodeArgs) {
|
||||
auto Result = _Xor(Size, _Sub(Size, Src, _Constant(1)), Src);
|
||||
|
||||
StoreResult(GPRClass, Op, Result, -1);
|
||||
GenerateFlags_BLSMSK(Op, Src);
|
||||
GenerateFlags_BLSMSK(Op, Result, Src);
|
||||
}
|
||||
|
||||
void OpDispatchBuilder::BLSRBMIOp(OpcodeArgs) {
|
||||
@@ -5378,7 +5378,7 @@ void OpDispatchBuilder::TZCNT(OpcodeArgs) {
|
||||
Src = _FindTrailingZeroes(OpSizeFromSrc(Op), Src);
|
||||
StoreResult(GPRClass, Op, Src, -1);
|
||||
|
||||
GenerateFlags_TZCNT(Op, Src);
|
||||
GenerateFlags_ZCNT(Op, Src);
|
||||
}
|
||||
|
||||
void OpDispatchBuilder::LZCNT(OpcodeArgs) {
|
||||
@@ -5387,7 +5387,7 @@ void OpDispatchBuilder::LZCNT(OpcodeArgs) {
|
||||
|
||||
auto Res = _CountLeadingZeroes(OpSizeFromSrc(Op), Src);
|
||||
StoreResult(GPRClass, Op, Res, -1);
|
||||
GenerateFlags_LZCNT(Op, Src);
|
||||
GenerateFlags_ZCNT(Op, Res);
|
||||
}
|
||||
|
||||
void OpDispatchBuilder::MOVBEOp(OpcodeArgs) {
|
||||
|
||||
@@ -102,8 +102,7 @@ public:
|
||||
TYPE_BLSR,
|
||||
TYPE_POPCOUNT,
|
||||
TYPE_BZHI,
|
||||
TYPE_TZCNT,
|
||||
TYPE_LZCNT,
|
||||
TYPE_ZCNT,
|
||||
TYPE_RDRAND,
|
||||
};
|
||||
|
||||
@@ -1604,11 +1603,11 @@ private:
|
||||
OrderedNode *Res{};
|
||||
|
||||
union {
|
||||
// UMUL, BEXTR, BLSI, BLSMSK, POPCOUNT, TZCNT, LZCNT, RDRAND
|
||||
// UMUL, BEXTR, BLSI, POPCOUNT, ZCNT, RDRAND
|
||||
struct {
|
||||
} NoSource;
|
||||
|
||||
// MUL, BLSR, BZHI
|
||||
// MUL, BLSR, BLSMSKB, BZHI
|
||||
struct {
|
||||
OrderedNode *Src1;
|
||||
} OneSource;
|
||||
@@ -1740,12 +1739,11 @@ private:
|
||||
void CalculateFlags_RotateLeftImmediate(uint8_t SrcSize, OrderedNode *Res, OrderedNode *Src1, uint64_t Shift);
|
||||
void CalculateFlags_BEXTR(OrderedNode *Src);
|
||||
void CalculateFlags_BLSI(uint8_t SrcSize, OrderedNode *Src);
|
||||
void CalculateFlags_BLSMSK(OrderedNode *Src);
|
||||
void CalculateFlags_BLSMSK(uint8_t SrcSize, OrderedNode *Res, OrderedNode *Src);
|
||||
void CalculateFlags_BLSR(uint8_t SrcSize, OrderedNode *Res, OrderedNode *Src);
|
||||
void CalculateFlags_POPCOUNT(OrderedNode *Src);
|
||||
void CalculateFlags_BZHI(uint8_t SrcSize, OrderedNode *Result, OrderedNode *Src);
|
||||
void CalculateFlags_TZCNT(OrderedNode *Src);
|
||||
void CalculateFlags_LZCNT(uint8_t SrcSize, OrderedNode *Src);
|
||||
void CalculateFlags_ZCNT(uint8_t SrcSize, OrderedNode *Result);
|
||||
void CalculateFlags_RDRAND(OrderedNode *Src);
|
||||
/** @} */
|
||||
|
||||
@@ -2064,11 +2062,16 @@ private:
|
||||
};
|
||||
}
|
||||
|
||||
void GenerateFlags_BLSMSK(FEXCore::X86Tables::DecodedOp Op, OrderedNode *Src) {
|
||||
void GenerateFlags_BLSMSK(FEXCore::X86Tables::DecodedOp Op, OrderedNode *Res, OrderedNode *Src) {
|
||||
CurrentDeferredFlags = DeferredFlagData {
|
||||
.Type = FlagsGenerationType::TYPE_BLSMSK,
|
||||
.SrcSize = GetSrcSize(Op),
|
||||
.Res = Src,
|
||||
.Res = Res,
|
||||
.Sources = {
|
||||
.OneSource = {
|
||||
.Src1 = Src,
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
@@ -2106,17 +2109,9 @@ private:
|
||||
};
|
||||
}
|
||||
|
||||
void GenerateFlags_TZCNT(FEXCore::X86Tables::DecodedOp Op, OrderedNode *Src) {
|
||||
void GenerateFlags_ZCNT(FEXCore::X86Tables::DecodedOp Op, OrderedNode *Src) {
|
||||
CurrentDeferredFlags = DeferredFlagData {
|
||||
.Type = FlagsGenerationType::TYPE_TZCNT,
|
||||
.SrcSize = GetSrcSize(Op),
|
||||
.Res = Src,
|
||||
};
|
||||
}
|
||||
|
||||
void GenerateFlags_LZCNT(FEXCore::X86Tables::DecodedOp Op, OrderedNode *Src) {
|
||||
CurrentDeferredFlags = DeferredFlagData {
|
||||
.Type = FlagsGenerationType::TYPE_LZCNT,
|
||||
.Type = FlagsGenerationType::TYPE_ZCNT,
|
||||
.SrcSize = GetSrcSize(Op),
|
||||
.Res = Src,
|
||||
};
|
||||
|
||||
@@ -444,7 +444,10 @@ void OpDispatchBuilder::CalculateDeferredFlags(uint32_t FlagsToCalculateMask) {
|
||||
CurrentDeferredFlags.Res);
|
||||
break;
|
||||
case FlagsGenerationType::TYPE_BLSMSK:
|
||||
CalculateFlags_BLSMSK(CurrentDeferredFlags.Res);
|
||||
CalculateFlags_BLSMSK(
|
||||
CurrentDeferredFlags.SrcSize,
|
||||
CurrentDeferredFlags.Res,
|
||||
CurrentDeferredFlags.Sources.OneSource.Src1);
|
||||
break;
|
||||
case FlagsGenerationType::TYPE_BLSR:
|
||||
CalculateFlags_BLSR(
|
||||
@@ -461,11 +464,8 @@ void OpDispatchBuilder::CalculateDeferredFlags(uint32_t FlagsToCalculateMask) {
|
||||
CurrentDeferredFlags.Res,
|
||||
CurrentDeferredFlags.Sources.OneSource.Src1);
|
||||
break;
|
||||
case FlagsGenerationType::TYPE_TZCNT:
|
||||
CalculateFlags_TZCNT(CurrentDeferredFlags.Res);
|
||||
break;
|
||||
case FlagsGenerationType::TYPE_LZCNT:
|
||||
CalculateFlags_LZCNT(
|
||||
case FlagsGenerationType::TYPE_ZCNT:
|
||||
CalculateFlags_ZCNT(
|
||||
CurrentDeferredFlags.SrcSize,
|
||||
CurrentDeferredFlags.Res);
|
||||
break;
|
||||
@@ -976,112 +976,67 @@ void OpDispatchBuilder::CalculateFlags_RotateLeftImmediate(uint8_t SrcSize, Orde
|
||||
}
|
||||
|
||||
void OpDispatchBuilder::CalculateFlags_BEXTR(OrderedNode *Src) {
|
||||
auto Zero = _Constant(0);
|
||||
auto One = _Constant(1);
|
||||
// ZF is set properly. CF and OF are defined as being set to zero. SF, PF, and
|
||||
// AF are undefined.
|
||||
SetNZ_ZeroCV(GetOpSize(Src), Src);
|
||||
|
||||
// Handle flag setting.
|
||||
//
|
||||
// All that matters primarily for this instruction is
|
||||
// that we only set the ZF flag properly.
|
||||
//
|
||||
// CF and OF are defined as being set to zero
|
||||
//
|
||||
// Every other flag is considered undefined after a
|
||||
// BEXTR instruction, but we opt to reliably clear them.
|
||||
//
|
||||
ZeroMultipleFlags(FullNZCVMask);
|
||||
|
||||
// PF/AF undefined
|
||||
_InvalidateFlags((1UL << X86State::RFLAG_PF_RAW_LOC) |
|
||||
(1UL << X86State::RFLAG_AF_RAW_LOC));
|
||||
|
||||
// ZF
|
||||
auto ZeroOp = _Select(IR::COND_EQ,
|
||||
Src, Zero,
|
||||
One, Zero);
|
||||
SetRFLAG<X86State::RFLAG_ZF_RAW_LOC>(ZeroOp);
|
||||
}
|
||||
|
||||
void OpDispatchBuilder::CalculateFlags_BLSI(uint8_t SrcSize, OrderedNode *Src) {
|
||||
// Now for the flags:
|
||||
void OpDispatchBuilder::CalculateFlags_BLSI(uint8_t SrcSize, OrderedNode *Result) {
|
||||
// CF is cleared if Src is zero, otherwise it's set. However, Src is zero iff
|
||||
// Result is zero, so we can test the result instead. So, CF is just the
|
||||
// inverted ZF.
|
||||
//
|
||||
// Only CF, SF, ZF and OF are defined as being updated
|
||||
// CF is cleared if Src is zero, otherwise it's set.
|
||||
// SF is set to the value of the most significant operand bit of Result.
|
||||
// OF is always cleared
|
||||
// ZF is set, as usual, if Result is zero or not.
|
||||
// ZF/SF/OF set as usual.
|
||||
SetNZ_ZeroCV(SrcSize, Result);
|
||||
|
||||
auto Zero = _Constant(0);
|
||||
auto One = _Constant(1);
|
||||
|
||||
SetNZ_ZeroCV(SrcSize, Src);
|
||||
auto CFOp = GetRFLAG(X86State::RFLAG_ZF_RAW_LOC, true /* Invert */);
|
||||
SetRFLAG<X86State::RFLAG_CF_RAW_LOC>(CFOp);
|
||||
|
||||
// PF/AF undefined
|
||||
_InvalidateFlags((1UL << X86State::RFLAG_PF_RAW_LOC) |
|
||||
(1UL << X86State::RFLAG_AF_RAW_LOC));
|
||||
|
||||
|
||||
// CF
|
||||
{
|
||||
auto CFOp = _Select(IR::COND_NEQ, Src, Zero, One, Zero);
|
||||
SetRFLAG<X86State::RFLAG_CF_RAW_LOC>(CFOp);
|
||||
}
|
||||
}
|
||||
|
||||
void OpDispatchBuilder::CalculateFlags_BLSMSK(OrderedNode *Src) {
|
||||
// Now for the flags.
|
||||
|
||||
auto Zero = _Constant(0);
|
||||
auto One = _Constant(1);
|
||||
|
||||
uint32_t FlagsMaskToZero =
|
||||
(1U << X86State::RFLAG_ZF_RAW_LOC) |
|
||||
(1U << X86State::RFLAG_OF_RAW_LOC);
|
||||
|
||||
ZeroMultipleFlags(FlagsMaskToZero);
|
||||
|
||||
void OpDispatchBuilder::CalculateFlags_BLSMSK(uint8_t SrcSize, OrderedNode *Result, OrderedNode *Src) {
|
||||
// PF/AF undefined
|
||||
_InvalidateFlags((1UL << X86State::RFLAG_PF_RAW_LOC) |
|
||||
(1UL << X86State::RFLAG_AF_RAW_LOC));
|
||||
|
||||
auto CFOp = _Select(IR::COND_NEQ, Src, Zero, One, Zero);
|
||||
// CF set according to the Src
|
||||
auto Zero = _Constant(0);
|
||||
auto One = _Constant(1);
|
||||
auto CFOp = _Select(IR::COND_EQ, Src, Zero, One, Zero);
|
||||
|
||||
// The output of BLSMSK is always nonzero, so TST will clear Z (along with C
|
||||
// and O) while setting S.
|
||||
SetNZ_ZeroCV(SrcSize, Result);
|
||||
SetRFLAG<X86State::RFLAG_CF_RAW_LOC>(CFOp);
|
||||
}
|
||||
|
||||
void OpDispatchBuilder::CalculateFlags_BLSR(uint8_t SrcSize, OrderedNode *Result, OrderedNode *Src) {
|
||||
// Now for flags.
|
||||
auto Zero = _Constant(0);
|
||||
auto One = _Constant(1);
|
||||
auto CFOp = _Select(IR::COND_EQ, Src, Zero, One, Zero);
|
||||
|
||||
SetNZ_ZeroCV(SrcSize, Result);
|
||||
SetRFLAG<X86State::RFLAG_CF_RAW_LOC>(CFOp);
|
||||
|
||||
// PF/AF undefined
|
||||
_InvalidateFlags((1UL << X86State::RFLAG_PF_RAW_LOC) |
|
||||
(1UL << X86State::RFLAG_AF_RAW_LOC));
|
||||
|
||||
// CF
|
||||
{
|
||||
auto CFOp = _Select(IR::COND_NEQ, Src, Zero, One, Zero);
|
||||
SetRFLAG<X86State::RFLAG_CF_RAW_LOC>(CFOp);
|
||||
}
|
||||
}
|
||||
|
||||
void OpDispatchBuilder::CalculateFlags_POPCOUNT(OrderedNode *Src) {
|
||||
// Set ZF
|
||||
auto Zero = _Constant(0);
|
||||
auto ZFResult = _Select(FEXCore::IR::COND_EQ,
|
||||
Src, Zero,
|
||||
_Constant(1), Zero);
|
||||
void OpDispatchBuilder::CalculateFlags_POPCOUNT(OrderedNode *Result) {
|
||||
// We need to set ZF while clearing the rest of NZCV. The result of a popcount
|
||||
// is in the range [0, 63]. In particular, it is always positive. So a
|
||||
// combined NZ test will correctly zero SF/CF/OF while setting ZF.
|
||||
SetNZ_ZeroCV(OpSize::i32Bit, Result);
|
||||
|
||||
// Set flags
|
||||
uint32_t FlagsMaskToZero =
|
||||
FullNZCVMask |
|
||||
(1U << X86State::RFLAG_AF_RAW_LOC) |
|
||||
(1U << X86State::RFLAG_PF_RAW_LOC);
|
||||
|
||||
ZeroMultipleFlags(FlagsMaskToZero);
|
||||
|
||||
SetRFLAG<FEXCore::X86State::RFLAG_ZF_RAW_LOC>(ZFResult);
|
||||
ZeroMultipleFlags((1U << X86State::RFLAG_AF_RAW_LOC) |
|
||||
(1U << X86State::RFLAG_PF_RAW_LOC));
|
||||
}
|
||||
|
||||
void OpDispatchBuilder::CalculateFlags_BZHI(uint8_t SrcSize, OrderedNode *Result, OrderedNode *Src) {
|
||||
@@ -1093,32 +1048,16 @@ void OpDispatchBuilder::CalculateFlags_BZHI(uint8_t SrcSize, OrderedNode *Result
|
||||
SetRFLAG<X86State::RFLAG_CF_RAW_LOC>(Src);
|
||||
}
|
||||
|
||||
void OpDispatchBuilder::CalculateFlags_TZCNT(OrderedNode *Src) {
|
||||
void OpDispatchBuilder::CalculateFlags_ZCNT(uint8_t SrcSize, OrderedNode *Result) {
|
||||
// OF, SF, AF, PF all undefined
|
||||
ZeroNZCV();
|
||||
// Test ZF of result, SF is undefined so this is ok.
|
||||
SetNZ_ZeroCV(SrcSize, Result);
|
||||
|
||||
auto Zero = _Constant(0);
|
||||
auto ZFResult = _Select(FEXCore::IR::COND_EQ,
|
||||
Src, Zero,
|
||||
_Constant(1), Zero);
|
||||
|
||||
// Set flags
|
||||
SetRFLAG<FEXCore::X86State::RFLAG_CF_RAW_LOC>(ZFResult);
|
||||
SetRFLAG<FEXCore::X86State::RFLAG_ZF_RAW_LOC>(Src, 0, true);
|
||||
}
|
||||
|
||||
void OpDispatchBuilder::CalculateFlags_LZCNT(uint8_t SrcSize, OrderedNode *Src) {
|
||||
// OF, SF, AF, PF all undefined
|
||||
ZeroNZCV();
|
||||
|
||||
auto Zero = _Constant(0);
|
||||
auto ZFResult = _Select(FEXCore::IR::COND_EQ,
|
||||
Src, Zero,
|
||||
_Constant(1), Zero);
|
||||
|
||||
// Set flags
|
||||
SetRFLAG<FEXCore::X86State::RFLAG_CF_RAW_LOC>(ZFResult);
|
||||
SetRFLAG<FEXCore::X86State::RFLAG_ZF_RAW_LOC>(Src, SrcSize * 8 - 1, true);
|
||||
// Now set CF if the Result = SrcSize * 8. Since SrcSize is a power-of-two and
|
||||
// Result is <= SrcSize * 8, we equivalently check if the log2(SrcSize * 8)
|
||||
// bit is set. No masking is needed because no higher bits could be set.
|
||||
unsigned CarryBit = FEXCore::ilog2(SrcSize * 8u);
|
||||
SetRFLAG<FEXCore::X86State::RFLAG_CF_RAW_LOC>(Result, CarryBit);
|
||||
}
|
||||
|
||||
void OpDispatchBuilder::CalculateFlags_RDRAND(OrderedNode *Src) {
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
%ifdef CONFIG
|
||||
{
|
||||
"RegData": {
|
||||
"RDX": "0xcafe"
|
||||
},
|
||||
"HostFeatures": ["BMI1"]
|
||||
}
|
||||
%endif
|
||||
|
||||
; Source 0 sets ZF
|
||||
mov rax, 0
|
||||
blsi rax, rax
|
||||
|
||||
js fexi_fexi_im_so_broken
|
||||
jnz fexi_fexi_im_so_broken
|
||||
jc fexi_fexi_im_so_broken
|
||||
jo fexi_fexi_im_so_broken
|
||||
|
||||
; Source 1 sets CF
|
||||
mov rax, 1
|
||||
blsi rax, rax
|
||||
|
||||
js fexi_fexi_im_so_broken
|
||||
jz fexi_fexi_im_so_broken
|
||||
jnc fexi_fexi_im_so_broken
|
||||
jo fexi_fexi_im_so_broken
|
||||
|
||||
; Source all-1's sets CF
|
||||
mov rax, 0xffffffffffffffff
|
||||
blsi rax, rax
|
||||
|
||||
js fexi_fexi_im_so_broken
|
||||
jz fexi_fexi_im_so_broken
|
||||
jnc fexi_fexi_im_so_broken
|
||||
jo fexi_fexi_im_so_broken
|
||||
|
||||
; Source 1<<63 sets CF and SF
|
||||
mov rax, 0x8000000000000000
|
||||
blsi rax, rax
|
||||
|
||||
jns fexi_fexi_im_so_broken
|
||||
jz fexi_fexi_im_so_broken
|
||||
jnc fexi_fexi_im_so_broken
|
||||
jo fexi_fexi_im_so_broken
|
||||
|
||||
; Make sure we're correctly clearing the overflow flag
|
||||
mov rbx, 5
|
||||
mov al, 0x7F
|
||||
inc al
|
||||
jno fexi_fexi_im_so_broken
|
||||
blsi rax, rax
|
||||
jo fexi_fexi_im_so_broken
|
||||
|
||||
; Happy ending
|
||||
mov rdx, 0xcafe
|
||||
hlt
|
||||
|
||||
fexi_fexi_im_so_broken:
|
||||
mov rdx, 0xdead
|
||||
hlt
|
||||
@@ -0,0 +1,63 @@
|
||||
%ifdef CONFIG
|
||||
{
|
||||
"RegData": {
|
||||
"RDX": "0xcafe",
|
||||
"RBX": "5"
|
||||
},
|
||||
"HostFeatures": ["BMI1"]
|
||||
}
|
||||
%endif
|
||||
|
||||
; Result in all-1's due to underflow so SF/CF set
|
||||
mov rbx, 1
|
||||
mov rax, 0
|
||||
blsmsk rax, rax
|
||||
|
||||
jns fexi_fexi_im_so_broken
|
||||
jz fexi_fexi_im_so_broken
|
||||
jnc fexi_fexi_im_so_broken
|
||||
jo fexi_fexi_im_so_broken
|
||||
|
||||
; Result in 1, so all flags clear
|
||||
mov rbx, 2
|
||||
mov rax, 11
|
||||
blsmsk rax, rax
|
||||
|
||||
js fexi_fexi_im_so_broken
|
||||
jz fexi_fexi_im_so_broken
|
||||
jc fexi_fexi_im_so_broken
|
||||
jo fexi_fexi_im_so_broken
|
||||
|
||||
; Result in all-1's without carry, so SF set
|
||||
mov rbx, 3
|
||||
mov rax, 0x8000000000000000
|
||||
blsmsk rax, rax
|
||||
|
||||
jns fexi_fexi_im_so_broken
|
||||
jz fexi_fexi_im_so_broken
|
||||
jc fexi_fexi_im_so_broken
|
||||
jo fexi_fexi_im_so_broken
|
||||
|
||||
; Make sure we're correctly clearing the zero flag
|
||||
mov rbx, 4
|
||||
mov rax, 0
|
||||
add rax, rax
|
||||
jnz fexi_fexi_im_so_broken
|
||||
blsmsk rax, rax
|
||||
jz fexi_fexi_im_so_broken
|
||||
|
||||
; Make sure we're correctly clearing the overflow flag
|
||||
mov rbx, 5
|
||||
mov al, 0x7F
|
||||
inc al
|
||||
jno fexi_fexi_im_so_broken
|
||||
blsmsk rax, rax
|
||||
jo fexi_fexi_im_so_broken
|
||||
|
||||
; Happy ending
|
||||
mov rdx, 0xcafe
|
||||
hlt
|
||||
|
||||
fexi_fexi_im_so_broken:
|
||||
mov rdx, 0xdead
|
||||
hlt
|
||||
@@ -0,0 +1,60 @@
|
||||
%ifdef CONFIG
|
||||
{
|
||||
"RegData": {
|
||||
"RDX": "0xcafe"
|
||||
},
|
||||
"HostFeatures": ["BMI1"]
|
||||
}
|
||||
%endif
|
||||
|
||||
; Source 0 sets CF and ZF
|
||||
mov rax, 0
|
||||
blsr rax, rax
|
||||
|
||||
js fexi_fexi_im_so_broken
|
||||
jnz fexi_fexi_im_so_broken
|
||||
jnc fexi_fexi_im_so_broken
|
||||
jo fexi_fexi_im_so_broken
|
||||
|
||||
; Source 1 sets ZF
|
||||
mov rax, 1
|
||||
blsr rax, rax
|
||||
|
||||
js fexi_fexi_im_so_broken
|
||||
jnz fexi_fexi_im_so_broken
|
||||
jc fexi_fexi_im_so_broken
|
||||
jo fexi_fexi_im_so_broken
|
||||
|
||||
; Source 3 sets nothing
|
||||
mov rax, 3
|
||||
blsr rax, rax
|
||||
|
||||
js fexi_fexi_im_so_broken
|
||||
jz fexi_fexi_im_so_broken
|
||||
jc fexi_fexi_im_so_broken
|
||||
jo fexi_fexi_im_so_broken
|
||||
|
||||
; Source all-1's sets SF
|
||||
mov rax, 0xffffffffffffffff
|
||||
blsr rax, rax
|
||||
|
||||
jns fexi_fexi_im_so_broken
|
||||
jz fexi_fexi_im_so_broken
|
||||
jc fexi_fexi_im_so_broken
|
||||
jo fexi_fexi_im_so_broken
|
||||
|
||||
; Make sure we're correctly clearing the overflow flag
|
||||
mov rbx, 5
|
||||
mov al, 0x7F
|
||||
inc al
|
||||
jno fexi_fexi_im_so_broken
|
||||
blsr rax, rax
|
||||
jo fexi_fexi_im_so_broken
|
||||
|
||||
; Happy ending
|
||||
mov rdx, 0xcafe
|
||||
hlt
|
||||
|
||||
fexi_fexi_im_so_broken:
|
||||
mov rdx, 0xdead
|
||||
hlt
|
||||
@@ -14,7 +14,7 @@
|
||||
},
|
||||
"Instructions": {
|
||||
"popcnt ax, bx": {
|
||||
"ExpectedInstructionCount": 12,
|
||||
"ExpectedInstructionCount": 9,
|
||||
"Comment": "0xf3 0x0f 0xb8",
|
||||
"ExpectedArm64ASM": [
|
||||
"uxth w20, w7",
|
||||
@@ -23,124 +23,97 @@
|
||||
"addp v0.8b, v0.8b, v0.8b",
|
||||
"umov w20, v0.b[0]",
|
||||
"bfxil x4, x20, #0, #16",
|
||||
"tst w20, w20",
|
||||
"mov w27, #0x0",
|
||||
"mov w26, #0x1",
|
||||
"cmp x20, #0x0 (0)",
|
||||
"cset x20, eq",
|
||||
"lsl x20, x20, #30",
|
||||
"msr nzcv, x20"
|
||||
"mov w26, #0x1"
|
||||
]
|
||||
},
|
||||
"popcnt eax, ebx": {
|
||||
"ExpectedInstructionCount": 10,
|
||||
"ExpectedInstructionCount": 7,
|
||||
"Comment": "0xf3 0x0f 0xb8",
|
||||
"ExpectedArm64ASM": [
|
||||
"fmov s0, w7",
|
||||
"cnt v0.8b, v0.8b",
|
||||
"addv b0, v0.8b",
|
||||
"umov w4, v0.b[0]",
|
||||
"tst w4, w4",
|
||||
"mov w27, #0x0",
|
||||
"mov w26, #0x1",
|
||||
"cmp x4, #0x0 (0)",
|
||||
"cset x20, eq",
|
||||
"lsl x20, x20, #30",
|
||||
"msr nzcv, x20"
|
||||
"mov w26, #0x1"
|
||||
]
|
||||
},
|
||||
"popcnt rax, rbx": {
|
||||
"ExpectedInstructionCount": 10,
|
||||
"ExpectedInstructionCount": 7,
|
||||
"Comment": "0xf3 0x0f 0xb8",
|
||||
"ExpectedArm64ASM": [
|
||||
"fmov d0, x7",
|
||||
"cnt v0.8b, v0.8b",
|
||||
"addv b0, v0.8b",
|
||||
"umov w4, v0.b[0]",
|
||||
"tst w4, w4",
|
||||
"mov w27, #0x0",
|
||||
"mov w26, #0x1",
|
||||
"cmp x4, #0x0 (0)",
|
||||
"cset x20, eq",
|
||||
"lsl x20, x20, #30",
|
||||
"msr nzcv, x20"
|
||||
"mov w26, #0x1"
|
||||
]
|
||||
},
|
||||
"tzcnt ax, bx": {
|
||||
"ExpectedInstructionCount": 9,
|
||||
"ExpectedInstructionCount": 6,
|
||||
"Comment": "0xf3 0x0f 0xbc",
|
||||
"ExpectedArm64ASM": [
|
||||
"rbit w20, w7",
|
||||
"orr w20, w20, #0x8000",
|
||||
"clz w20, w20",
|
||||
"bfxil x4, x20, #0, #16",
|
||||
"cmp x20, #0x0 (0)",
|
||||
"cset x21, eq",
|
||||
"lsl x21, x21, #29",
|
||||
"msr nzcv, x21",
|
||||
"rmif x20, #62, #nZcv"
|
||||
"cmn wzr, w20, lsl #16",
|
||||
"rmif x20, #3, #nzCv"
|
||||
]
|
||||
},
|
||||
"tzcnt eax, ebx": {
|
||||
"ExpectedInstructionCount": 7,
|
||||
"ExpectedInstructionCount": 4,
|
||||
"Comment": "0xf3 0x0f 0xbc",
|
||||
"ExpectedArm64ASM": [
|
||||
"rbit w4, w7",
|
||||
"clz w4, w4",
|
||||
"cmp x4, #0x0 (0)",
|
||||
"cset x20, eq",
|
||||
"lsl x20, x20, #29",
|
||||
"msr nzcv, x20",
|
||||
"rmif x4, #62, #nZcv"
|
||||
"tst w4, w4",
|
||||
"rmif x4, #4, #nzCv"
|
||||
]
|
||||
},
|
||||
"tzcnt rax, rbx": {
|
||||
"ExpectedInstructionCount": 7,
|
||||
"ExpectedInstructionCount": 4,
|
||||
"Comment": "0xf3 0x0f 0xbc",
|
||||
"ExpectedArm64ASM": [
|
||||
"rbit x4, x7",
|
||||
"clz x4, x4",
|
||||
"cmp x4, #0x0 (0)",
|
||||
"cset x20, eq",
|
||||
"lsl x20, x20, #29",
|
||||
"msr nzcv, x20",
|
||||
"rmif x4, #62, #nZcv"
|
||||
"tst x4, x4",
|
||||
"rmif x4, #5, #nzCv"
|
||||
]
|
||||
},
|
||||
"lzcnt ax, bx": {
|
||||
"ExpectedInstructionCount": 9,
|
||||
"ExpectedInstructionCount": 6,
|
||||
"Comment": "0xf3 0x0f 0xbd",
|
||||
"ExpectedArm64ASM": [
|
||||
"lsl w20, w7, #16",
|
||||
"orr w20, w20, #0x8000",
|
||||
"clz w20, w20",
|
||||
"bfxil x4, x20, #0, #16",
|
||||
"cmp x7, #0x0 (0)",
|
||||
"cset x20, eq",
|
||||
"lsl x20, x20, #29",
|
||||
"msr nzcv, x20",
|
||||
"rmif x7, #13, #nZcv"
|
||||
"cmn wzr, w20, lsl #16",
|
||||
"rmif x20, #3, #nzCv"
|
||||
]
|
||||
},
|
||||
"lzcnt eax, ebx": {
|
||||
"ExpectedInstructionCount": 6,
|
||||
"ExpectedInstructionCount": 3,
|
||||
"Comment": "0xf3 0x0f 0xbd",
|
||||
"ExpectedArm64ASM": [
|
||||
"clz w4, w7",
|
||||
"cmp x7, #0x0 (0)",
|
||||
"cset x20, eq",
|
||||
"lsl x20, x20, #29",
|
||||
"msr nzcv, x20",
|
||||
"rmif x7, #29, #nZcv"
|
||||
"tst w4, w4",
|
||||
"rmif x4, #4, #nzCv"
|
||||
]
|
||||
},
|
||||
"lzcnt rax, rbx": {
|
||||
"ExpectedInstructionCount": 6,
|
||||
"ExpectedInstructionCount": 3,
|
||||
"Comment": "0xf3 0x0f 0xbd",
|
||||
"ExpectedArm64ASM": [
|
||||
"clz x4, x7",
|
||||
"cmp x7, #0x0 (0)",
|
||||
"cset x20, eq",
|
||||
"lsl x20, x20, #29",
|
||||
"msr nzcv, x20",
|
||||
"rmif x7, #61, #nZcv"
|
||||
"tst x4, x4",
|
||||
"rmif x4, #5, #nzCv"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -442,53 +442,43 @@
|
||||
]
|
||||
},
|
||||
"bextr eax, ebx, ecx": {
|
||||
"ExpectedInstructionCount": 17,
|
||||
"ExpectedInstructionCount": 12,
|
||||
"Comment": [
|
||||
"Map 2 0b00 0xf7 32-bit"
|
||||
],
|
||||
"ExpectedArm64ASM": [
|
||||
"mov w20, #0x1f",
|
||||
"uxtb w21, w5",
|
||||
"lsr w22, w7, w21",
|
||||
"mov w23, #0x0",
|
||||
"uxtb w20, w5",
|
||||
"lsr w21, w7, w20",
|
||||
"mov w22, #0x0",
|
||||
"cmp w20, #0x1f (31)",
|
||||
"csel w20, w21, w22, ls",
|
||||
"ubfx w21, w5, #8, #8",
|
||||
"mov x22, #0xffffffffffffffff",
|
||||
"lsl w22, w22, w21",
|
||||
"bic w22, w20, w22",
|
||||
"cmp w21, #0x1f (31)",
|
||||
"csel w21, w22, w23, ls",
|
||||
"ubfx w22, w5, #8, #8",
|
||||
"cmp w22, #0x1f (31)",
|
||||
"csel w20, w22, w20, ls",
|
||||
"mov w22, #0x1",
|
||||
"lsl w20, w22, w20",
|
||||
"sub w20, w20, #0x1 (1)",
|
||||
"and w4, w21, w20",
|
||||
"cmp x4, #0x0 (0)",
|
||||
"cset x20, eq",
|
||||
"lsl x20, x20, #30",
|
||||
"msr nzcv, x20"
|
||||
"csel w4, w22, w20, ls",
|
||||
"tst w4, w4"
|
||||
]
|
||||
},
|
||||
"bextr rax, rbx, rcx": {
|
||||
"ExpectedInstructionCount": 17,
|
||||
"ExpectedInstructionCount": 12,
|
||||
"Comment": [
|
||||
"Map 2 0b00 0xf7 64-bit"
|
||||
],
|
||||
"ExpectedArm64ASM": [
|
||||
"mov w20, #0x3f",
|
||||
"uxtb x21, w5",
|
||||
"lsr x22, x7, x21",
|
||||
"mov w23, #0x0",
|
||||
"uxtb x20, w5",
|
||||
"lsr x21, x7, x20",
|
||||
"mov w22, #0x0",
|
||||
"cmp x20, #0x3f (63)",
|
||||
"csel x20, x21, x22, ls",
|
||||
"ubfx x21, x5, #8, #8",
|
||||
"mov x22, #0xffffffffffffffff",
|
||||
"lsl x22, x22, x21",
|
||||
"bic x22, x20, x22",
|
||||
"cmp x21, #0x3f (63)",
|
||||
"csel x21, x22, x23, ls",
|
||||
"ubfx x22, x5, #8, #8",
|
||||
"cmp x22, #0x3f (63)",
|
||||
"csel x20, x22, x20, ls",
|
||||
"mov w22, #0x1",
|
||||
"lsl x20, x22, x20",
|
||||
"sub x20, x20, #0x1 (1)",
|
||||
"and x4, x21, x20",
|
||||
"cmp x4, #0x0 (0)",
|
||||
"cset x20, eq",
|
||||
"lsl x20, x20, #30",
|
||||
"msr nzcv, x20"
|
||||
"csel x4, x22, x20, ls",
|
||||
"tst x4, x4"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,73 +10,63 @@
|
||||
},
|
||||
"Instructions": {
|
||||
"blsr eax, ebx": {
|
||||
"ExpectedInstructionCount": 8,
|
||||
"ExpectedInstructionCount": 6,
|
||||
"Comment": [
|
||||
"Map group 17 0b001 32-bit"
|
||||
],
|
||||
"ExpectedArm64ASM": [
|
||||
"sub w20, w7, #0x1 (1)",
|
||||
"and w4, w20, w7",
|
||||
"tst w4, w4",
|
||||
"mrs x20, nzcv",
|
||||
"cmp x7, #0x0 (0)",
|
||||
"cset x21, ne",
|
||||
"orr w20, w20, w21, lsl #29",
|
||||
"msr nzcv, x20"
|
||||
"cset x20, eq",
|
||||
"tst w4, w4",
|
||||
"rmif x20, #63, #nzCv"
|
||||
]
|
||||
},
|
||||
"blsr rax, rbx": {
|
||||
"ExpectedInstructionCount": 8,
|
||||
"ExpectedInstructionCount": 6,
|
||||
"Comment": [
|
||||
"Map group 17 0b001 64-bit"
|
||||
],
|
||||
"ExpectedArm64ASM": [
|
||||
"sub x20, x7, #0x1 (1)",
|
||||
"and x4, x20, x7",
|
||||
"tst x4, x4",
|
||||
"mrs x20, nzcv",
|
||||
"cmp x7, #0x0 (0)",
|
||||
"cset x21, ne",
|
||||
"orr w20, w20, w21, lsl #29",
|
||||
"msr nzcv, x20"
|
||||
"cset x20, eq",
|
||||
"tst x4, x4",
|
||||
"rmif x20, #63, #nzCv"
|
||||
]
|
||||
},
|
||||
"blsmsk eax, ebx": {
|
||||
"ExpectedInstructionCount": 9,
|
||||
"ExpectedInstructionCount": 6,
|
||||
"Comment": [
|
||||
"Map group 17 0b010 32-bit"
|
||||
],
|
||||
"ExpectedArm64ASM": [
|
||||
"sub w20, w7, #0x1 (1)",
|
||||
"eor w4, w20, w7",
|
||||
"mov w20, #0x50000000",
|
||||
"mrs x21, nzcv",
|
||||
"bic x20, x21, x20",
|
||||
"cmp x7, #0x0 (0)",
|
||||
"cset x21, ne",
|
||||
"msr nzcv, x20",
|
||||
"rmif x21, #63, #nzCv"
|
||||
"cset x20, eq",
|
||||
"tst w4, w4",
|
||||
"rmif x20, #63, #nzCv"
|
||||
]
|
||||
},
|
||||
"blsmsk rax, rbx": {
|
||||
"ExpectedInstructionCount": 9,
|
||||
"ExpectedInstructionCount": 6,
|
||||
"Comment": [
|
||||
"Map group 17 0b010 64-bit"
|
||||
],
|
||||
"ExpectedArm64ASM": [
|
||||
"sub x20, x7, #0x1 (1)",
|
||||
"eor x4, x20, x7",
|
||||
"mov w20, #0x50000000",
|
||||
"mrs x21, nzcv",
|
||||
"bic x20, x21, x20",
|
||||
"cmp x7, #0x0 (0)",
|
||||
"cset x21, ne",
|
||||
"msr nzcv, x20",
|
||||
"rmif x21, #63, #nzCv"
|
||||
"cset x20, eq",
|
||||
"tst x4, x4",
|
||||
"rmif x20, #63, #nzCv"
|
||||
]
|
||||
},
|
||||
"blsi eax, ebx": {
|
||||
"ExpectedInstructionCount": 8,
|
||||
"ExpectedInstructionCount": 5,
|
||||
"Comment": [
|
||||
"Map group 17 0b011 32-bit"
|
||||
],
|
||||
@@ -84,15 +74,12 @@
|
||||
"neg w20, w7",
|
||||
"and w4, w7, w20",
|
||||
"tst w4, w4",
|
||||
"mrs x20, nzcv",
|
||||
"cmp x4, #0x0 (0)",
|
||||
"cset x21, ne",
|
||||
"orr w20, w20, w21, lsl #29",
|
||||
"msr nzcv, x20"
|
||||
"cset w20, ne",
|
||||
"rmif x20, #63, #nzCv"
|
||||
]
|
||||
},
|
||||
"blsi rax, rbx": {
|
||||
"ExpectedInstructionCount": 8,
|
||||
"ExpectedInstructionCount": 5,
|
||||
"Comment": [
|
||||
"Map group 17 0b011 64-bit"
|
||||
],
|
||||
@@ -100,11 +87,8 @@
|
||||
"neg x20, x7",
|
||||
"and x4, x7, x20",
|
||||
"tst x4, x4",
|
||||
"mrs x20, nzcv",
|
||||
"cmp x4, #0x0 (0)",
|
||||
"cset x21, ne",
|
||||
"orr w20, w20, w21, lsl #29",
|
||||
"msr nzcv, x20"
|
||||
"cset w20, ne",
|
||||
"rmif x20, #63, #nzCv"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -399,7 +399,7 @@
|
||||
]
|
||||
},
|
||||
"popcnt ax, bx": {
|
||||
"ExpectedInstructionCount": 12,
|
||||
"ExpectedInstructionCount": 9,
|
||||
"Comment": "0xf3 0x0f 0xb8",
|
||||
"ExpectedArm64ASM": [
|
||||
"uxth w20, w7",
|
||||
@@ -408,129 +408,114 @@
|
||||
"addp v0.8b, v0.8b, v0.8b",
|
||||
"umov w20, v0.b[0]",
|
||||
"bfxil x4, x20, #0, #16",
|
||||
"tst w20, w20",
|
||||
"mov w27, #0x0",
|
||||
"mov w26, #0x1",
|
||||
"cmp x20, #0x0 (0)",
|
||||
"cset x20, eq",
|
||||
"lsl x20, x20, #30",
|
||||
"msr nzcv, x20"
|
||||
"mov w26, #0x1"
|
||||
]
|
||||
},
|
||||
"popcnt eax, ebx": {
|
||||
"ExpectedInstructionCount": 10,
|
||||
"ExpectedInstructionCount": 7,
|
||||
"Comment": "0xf3 0x0f 0xb8",
|
||||
"ExpectedArm64ASM": [
|
||||
"fmov s0, w7",
|
||||
"cnt v0.8b, v0.8b",
|
||||
"addv b0, v0.8b",
|
||||
"umov w4, v0.b[0]",
|
||||
"tst w4, w4",
|
||||
"mov w27, #0x0",
|
||||
"mov w26, #0x1",
|
||||
"cmp x4, #0x0 (0)",
|
||||
"cset x20, eq",
|
||||
"lsl x20, x20, #30",
|
||||
"msr nzcv, x20"
|
||||
"mov w26, #0x1"
|
||||
]
|
||||
},
|
||||
"popcnt rax, rbx": {
|
||||
"ExpectedInstructionCount": 10,
|
||||
"ExpectedInstructionCount": 7,
|
||||
"Comment": "0xf3 0x0f 0xb8",
|
||||
"ExpectedArm64ASM": [
|
||||
"fmov d0, x7",
|
||||
"cnt v0.8b, v0.8b",
|
||||
"addv b0, v0.8b",
|
||||
"umov w4, v0.b[0]",
|
||||
"tst w4, w4",
|
||||
"mov w27, #0x0",
|
||||
"mov w26, #0x1",
|
||||
"cmp x4, #0x0 (0)",
|
||||
"cset x20, eq",
|
||||
"lsl x20, x20, #30",
|
||||
"msr nzcv, x20"
|
||||
"mov w26, #0x1"
|
||||
]
|
||||
},
|
||||
"tzcnt ax, bx": {
|
||||
"ExpectedInstructionCount": 10,
|
||||
"ExpectedInstructionCount": 9,
|
||||
"Comment": "0xf3 0x0f 0xbc",
|
||||
"ExpectedArm64ASM": [
|
||||
"rbit w20, w7",
|
||||
"orr w20, w20, #0x8000",
|
||||
"clz w20, w20",
|
||||
"bfxil x4, x20, #0, #16",
|
||||
"cmp x20, #0x0 (0)",
|
||||
"cset x21, eq",
|
||||
"lsl x21, x21, #29",
|
||||
"ubfx x20, x20, #0, #1",
|
||||
"orr w20, w21, w20, lsl #30",
|
||||
"cmn wzr, w20, lsl #16",
|
||||
"mrs x21, nzcv",
|
||||
"ubfx x20, x20, #4, #1",
|
||||
"orr w20, w21, w20, lsl #29",
|
||||
"msr nzcv, x20"
|
||||
]
|
||||
},
|
||||
"tzcnt eax, ebx": {
|
||||
"ExpectedInstructionCount": 8,
|
||||
"ExpectedInstructionCount": 7,
|
||||
"Comment": "0xf3 0x0f 0xbc",
|
||||
"ExpectedArm64ASM": [
|
||||
"rbit w4, w7",
|
||||
"clz w4, w4",
|
||||
"cmp x4, #0x0 (0)",
|
||||
"cset x20, eq",
|
||||
"lsl x20, x20, #29",
|
||||
"ubfx x21, x4, #0, #1",
|
||||
"orr w20, w20, w21, lsl #30",
|
||||
"tst w4, w4",
|
||||
"mrs x20, nzcv",
|
||||
"ubfx x21, x4, #5, #1",
|
||||
"orr w20, w20, w21, lsl #29",
|
||||
"msr nzcv, x20"
|
||||
]
|
||||
},
|
||||
"tzcnt rax, rbx": {
|
||||
"ExpectedInstructionCount": 8,
|
||||
"ExpectedInstructionCount": 7,
|
||||
"Comment": "0xf3 0x0f 0xbc",
|
||||
"ExpectedArm64ASM": [
|
||||
"rbit x4, x7",
|
||||
"clz x4, x4",
|
||||
"cmp x4, #0x0 (0)",
|
||||
"cset x20, eq",
|
||||
"lsl x20, x20, #29",
|
||||
"ubfx x21, x4, #0, #1",
|
||||
"orr w20, w20, w21, lsl #30",
|
||||
"tst x4, x4",
|
||||
"mrs x20, nzcv",
|
||||
"ubfx x21, x4, #6, #1",
|
||||
"orr w20, w20, w21, lsl #29",
|
||||
"msr nzcv, x20"
|
||||
]
|
||||
},
|
||||
"lzcnt ax, bx": {
|
||||
"ExpectedInstructionCount": 10,
|
||||
"ExpectedInstructionCount": 9,
|
||||
"Comment": "0xf3 0x0f 0xbd",
|
||||
"ExpectedArm64ASM": [
|
||||
"lsl w20, w7, #16",
|
||||
"orr w20, w20, #0x8000",
|
||||
"clz w20, w20",
|
||||
"bfxil x4, x20, #0, #16",
|
||||
"cmp x7, #0x0 (0)",
|
||||
"cset x20, eq",
|
||||
"lsl x20, x20, #29",
|
||||
"ubfx x21, x7, #15, #1",
|
||||
"orr w20, w20, w21, lsl #30",
|
||||
"cmn wzr, w20, lsl #16",
|
||||
"mrs x21, nzcv",
|
||||
"ubfx x20, x20, #4, #1",
|
||||
"orr w20, w21, w20, lsl #29",
|
||||
"msr nzcv, x20"
|
||||
]
|
||||
},
|
||||
"lzcnt eax, ebx": {
|
||||
"ExpectedInstructionCount": 7,
|
||||
"ExpectedInstructionCount": 6,
|
||||
"Comment": "0xf3 0x0f 0xbd",
|
||||
"ExpectedArm64ASM": [
|
||||
"clz w4, w7",
|
||||
"cmp x7, #0x0 (0)",
|
||||
"cset x20, eq",
|
||||
"lsl x20, x20, #29",
|
||||
"ubfx x21, x7, #31, #1",
|
||||
"orr w20, w20, w21, lsl #30",
|
||||
"tst w4, w4",
|
||||
"mrs x20, nzcv",
|
||||
"ubfx x21, x4, #5, #1",
|
||||
"orr w20, w20, w21, lsl #29",
|
||||
"msr nzcv, x20"
|
||||
]
|
||||
},
|
||||
"lzcnt rax, rbx": {
|
||||
"ExpectedInstructionCount": 7,
|
||||
"ExpectedInstructionCount": 6,
|
||||
"Comment": "0xf3 0x0f 0xbd",
|
||||
"ExpectedArm64ASM": [
|
||||
"clz x4, x7",
|
||||
"cmp x7, #0x0 (0)",
|
||||
"cset x20, eq",
|
||||
"lsl x20, x20, #29",
|
||||
"lsr x21, x7, #63",
|
||||
"orr w20, w20, w21, lsl #30",
|
||||
"tst x4, x4",
|
||||
"mrs x20, nzcv",
|
||||
"ubfx x21, x4, #6, #1",
|
||||
"orr w20, w20, w21, lsl #29",
|
||||
"msr nzcv, x20"
|
||||
]
|
||||
},
|
||||
|
||||
@@ -3381,53 +3381,43 @@
|
||||
]
|
||||
},
|
||||
"bextr eax, ebx, ecx": {
|
||||
"ExpectedInstructionCount": 17,
|
||||
"ExpectedInstructionCount": 12,
|
||||
"Comment": [
|
||||
"Map 2 0b00 0xf7 32-bit"
|
||||
],
|
||||
"ExpectedArm64ASM": [
|
||||
"mov w20, #0x1f",
|
||||
"uxtb w21, w5",
|
||||
"lsr w22, w7, w21",
|
||||
"mov w23, #0x0",
|
||||
"uxtb w20, w5",
|
||||
"lsr w21, w7, w20",
|
||||
"mov w22, #0x0",
|
||||
"cmp w20, #0x1f (31)",
|
||||
"csel w20, w21, w22, ls",
|
||||
"ubfx w21, w5, #8, #8",
|
||||
"mov x22, #0xffffffffffffffff",
|
||||
"lsl w22, w22, w21",
|
||||
"bic w22, w20, w22",
|
||||
"cmp w21, #0x1f (31)",
|
||||
"csel w21, w22, w23, ls",
|
||||
"ubfx w22, w5, #8, #8",
|
||||
"cmp w22, #0x1f (31)",
|
||||
"csel w20, w22, w20, ls",
|
||||
"mov w22, #0x1",
|
||||
"lsl w20, w22, w20",
|
||||
"sub w20, w20, #0x1 (1)",
|
||||
"and w4, w21, w20",
|
||||
"cmp x4, #0x0 (0)",
|
||||
"cset x20, eq",
|
||||
"lsl x20, x20, #30",
|
||||
"msr nzcv, x20"
|
||||
"csel w4, w22, w20, ls",
|
||||
"tst w4, w4"
|
||||
]
|
||||
},
|
||||
"bextr rax, rbx, rcx": {
|
||||
"ExpectedInstructionCount": 17,
|
||||
"ExpectedInstructionCount": 12,
|
||||
"Comment": [
|
||||
"Map 2 0b00 0xf7 64-bit"
|
||||
],
|
||||
"ExpectedArm64ASM": [
|
||||
"mov w20, #0x3f",
|
||||
"uxtb x21, w5",
|
||||
"lsr x22, x7, x21",
|
||||
"mov w23, #0x0",
|
||||
"uxtb x20, w5",
|
||||
"lsr x21, x7, x20",
|
||||
"mov w22, #0x0",
|
||||
"cmp x20, #0x3f (63)",
|
||||
"csel x20, x21, x22, ls",
|
||||
"ubfx x21, x5, #8, #8",
|
||||
"mov x22, #0xffffffffffffffff",
|
||||
"lsl x22, x22, x21",
|
||||
"bic x22, x20, x22",
|
||||
"cmp x21, #0x3f (63)",
|
||||
"csel x21, x22, x23, ls",
|
||||
"ubfx x22, x5, #8, #8",
|
||||
"cmp x22, #0x3f (63)",
|
||||
"csel x20, x22, x20, ls",
|
||||
"mov w22, #0x1",
|
||||
"lsl x20, x22, x20",
|
||||
"sub x20, x20, #0x1 (1)",
|
||||
"and x4, x21, x20",
|
||||
"cmp x4, #0x0 (0)",
|
||||
"cset x20, eq",
|
||||
"lsl x20, x20, #30",
|
||||
"msr nzcv, x20"
|
||||
"csel x4, x22, x20, ls",
|
||||
"tst x4, x4"
|
||||
]
|
||||
},
|
||||
"shlx eax, ebx, ecx": {
|
||||
|
||||
@@ -616,11 +616,11 @@
|
||||
"ExpectedArm64ASM": [
|
||||
"sub w20, w7, #0x1 (1)",
|
||||
"and w4, w20, w7",
|
||||
"tst w4, w4",
|
||||
"mrs x20, nzcv",
|
||||
"cmp x7, #0x0 (0)",
|
||||
"cset x21, ne",
|
||||
"orr w20, w20, w21, lsl #29",
|
||||
"cset x20, eq",
|
||||
"tst w4, w4",
|
||||
"mrs x21, nzcv",
|
||||
"orr w20, w21, w20, lsl #29",
|
||||
"msr nzcv, x20"
|
||||
]
|
||||
},
|
||||
@@ -632,50 +632,48 @@
|
||||
"ExpectedArm64ASM": [
|
||||
"sub x20, x7, #0x1 (1)",
|
||||
"and x4, x20, x7",
|
||||
"tst x4, x4",
|
||||
"mrs x20, nzcv",
|
||||
"cmp x7, #0x0 (0)",
|
||||
"cset x21, ne",
|
||||
"orr w20, w20, w21, lsl #29",
|
||||
"cset x20, eq",
|
||||
"tst x4, x4",
|
||||
"mrs x21, nzcv",
|
||||
"orr w20, w21, w20, lsl #29",
|
||||
"msr nzcv, x20"
|
||||
]
|
||||
},
|
||||
"blsmsk eax, ebx": {
|
||||
"ExpectedInstructionCount": 9,
|
||||
"ExpectedInstructionCount": 8,
|
||||
"Comment": [
|
||||
"Map group 17 0b010 32-bit"
|
||||
],
|
||||
"ExpectedArm64ASM": [
|
||||
"sub w20, w7, #0x1 (1)",
|
||||
"eor w4, w20, w7",
|
||||
"mov w20, #0x50000000",
|
||||
"mrs x21, nzcv",
|
||||
"bic x20, x21, x20",
|
||||
"cmp x7, #0x0 (0)",
|
||||
"cset x21, ne",
|
||||
"bfi w20, w21, #29, #1",
|
||||
"cset x20, eq",
|
||||
"tst w4, w4",
|
||||
"mrs x21, nzcv",
|
||||
"orr w20, w21, w20, lsl #29",
|
||||
"msr nzcv, x20"
|
||||
]
|
||||
},
|
||||
"blsmsk rax, rbx": {
|
||||
"ExpectedInstructionCount": 9,
|
||||
"ExpectedInstructionCount": 8,
|
||||
"Comment": [
|
||||
"Map group 17 0b010 64-bit"
|
||||
],
|
||||
"ExpectedArm64ASM": [
|
||||
"sub x20, x7, #0x1 (1)",
|
||||
"eor x4, x20, x7",
|
||||
"mov w20, #0x50000000",
|
||||
"mrs x21, nzcv",
|
||||
"bic x20, x21, x20",
|
||||
"cmp x7, #0x0 (0)",
|
||||
"cset x21, ne",
|
||||
"bfi w20, w21, #29, #1",
|
||||
"cset x20, eq",
|
||||
"tst x4, x4",
|
||||
"mrs x21, nzcv",
|
||||
"orr w20, w21, w20, lsl #29",
|
||||
"msr nzcv, x20"
|
||||
]
|
||||
},
|
||||
"blsi eax, ebx": {
|
||||
"ExpectedInstructionCount": 8,
|
||||
"ExpectedInstructionCount": 7,
|
||||
"Comment": [
|
||||
"Map group 17 0b011 32-bit"
|
||||
],
|
||||
@@ -684,14 +682,13 @@
|
||||
"and w4, w7, w20",
|
||||
"tst w4, w4",
|
||||
"mrs x20, nzcv",
|
||||
"cmp x4, #0x0 (0)",
|
||||
"cset x21, ne",
|
||||
"cset w21, ne",
|
||||
"orr w20, w20, w21, lsl #29",
|
||||
"msr nzcv, x20"
|
||||
]
|
||||
},
|
||||
"blsi rax, rbx": {
|
||||
"ExpectedInstructionCount": 8,
|
||||
"ExpectedInstructionCount": 7,
|
||||
"Comment": [
|
||||
"Map group 17 0b011 64-bit"
|
||||
],
|
||||
@@ -700,8 +697,7 @@
|
||||
"and x4, x7, x20",
|
||||
"tst x4, x4",
|
||||
"mrs x20, nzcv",
|
||||
"cmp x4, #0x0 (0)",
|
||||
"cset x21, ne",
|
||||
"cset w21, ne",
|
||||
"orr w20, w20, w21, lsl #29",
|
||||
"msr nzcv, x20"
|
||||
]
|
||||
|
||||
Reference in new issue
Block a user