mirror of
https://github.com/FEX-Emu/FEX.git
synced 2026-10-08 12:00:17 +02:00
OpcodeDispatcher: Handle PCMPESTRI/VPCMPESTRI
This commit is contained in:
1 parent
30cb1aaaed
commit
39c73d975b
13 files changed
+1420
-4
No files matched your search
@@ -5978,6 +5978,8 @@ void OpDispatchBuilder::InstallHostSpecificOpcodeHandlers() {
|
||||
{OPD(3, 0b01, 0x4B), 1, &OpDispatchBuilder::AVXVectorVariableBlend<8>},
|
||||
{OPD(3, 0b01, 0x4C), 1, &OpDispatchBuilder::AVXVectorVariableBlend<1>},
|
||||
|
||||
{OPD(3, 0b01, 0x61), 1, &OpDispatchBuilder::VPCMPESTRIOp},
|
||||
|
||||
{OPD(3, 0b01, 0xDF), 1, &OpDispatchBuilder::VAESKeyGenAssistOp},
|
||||
};
|
||||
#undef OPD
|
||||
@@ -7266,6 +7268,8 @@ constexpr uint16_t PF_F2 = 3;
|
||||
{OPD(0, PF_3A_66, 0x41), 1, &OpDispatchBuilder::DPPOp<8>},
|
||||
{OPD(0, PF_3A_66, 0x42), 1, &OpDispatchBuilder::MPSADBWOp},
|
||||
|
||||
{OPD(0, PF_3A_66, 0x61), 1, &OpDispatchBuilder::VPCMPESTRIOp},
|
||||
|
||||
{OPD(0, PF_3A_NONE, 0xCC), 1, &OpDispatchBuilder::SHA1RNDS4Op},
|
||||
};
|
||||
#undef PF_3A_NONE
|
||||
|
||||
@@ -487,6 +487,8 @@ public:
|
||||
|
||||
void VPALIGNROp(OpcodeArgs);
|
||||
|
||||
void VPCMPESTRIOp(OpcodeArgs);
|
||||
|
||||
void VPERM2Op(OpcodeArgs);
|
||||
void VPERMDOp(OpcodeArgs);
|
||||
void VPERMQOp(OpcodeArgs);
|
||||
@@ -853,6 +855,11 @@ private:
|
||||
const X86Tables::DecodedOperand& Src2,
|
||||
const X86Tables::DecodedOperand& Imm);
|
||||
|
||||
OrderedNode* PCMPESTRXOpImpl(OpcodeArgs,
|
||||
const X86Tables::DecodedOperand& Src1,
|
||||
const X86Tables::DecodedOperand& Src2,
|
||||
const X86Tables::DecodedOperand& Imm);
|
||||
|
||||
OrderedNode* PHADDSOpImpl(OpcodeArgs, const X86Tables::DecodedOperand& Src1,
|
||||
const X86Tables::DecodedOperand& Src2);
|
||||
|
||||
|
||||
@@ -4552,4 +4552,77 @@ void OpDispatchBuilder::VPERMILRegOp<4>(OpcodeArgs);
|
||||
template
|
||||
void OpDispatchBuilder::VPERMILRegOp<8>(OpcodeArgs);
|
||||
|
||||
OrderedNode* OpDispatchBuilder::PCMPESTRXOpImpl(OpcodeArgs,
|
||||
const X86Tables::DecodedOperand& Src1Op,
|
||||
const X86Tables::DecodedOperand& Src2Op,
|
||||
const X86Tables::DecodedOperand& Imm) {
|
||||
LOGMAN_THROW_A_FMT(Imm.IsLiteral(), "Imm needs to be a literal");
|
||||
const auto Control = Imm.Data.Literal.Value;
|
||||
|
||||
// Will be 4 in the absence of a REX.W bit and 8 in the presence of a REX.W bit.
|
||||
const auto SrcSize = GetSrcSize(Op);
|
||||
|
||||
// SSE4.2 string instructions modify flags, so invalidate
|
||||
// any previously deferred flags.
|
||||
InvalidateDeferredFlags();
|
||||
|
||||
// NOTE: Unlike most other SSE/AVX instructions, the SSE4.2 string and text
|
||||
// instructions do *not* require memory operands to be aligned on a 16 byte
|
||||
// boundary (see "Other Exceptions" descriptions for the relevant
|
||||
// instructions in the Intel Software Development Manual).
|
||||
//
|
||||
// So, we specify Src2 as having an alignment of 1 to indicate this.
|
||||
OrderedNode *Src1 = LoadSource_WithOpSize(FPRClass, Op, Src1Op, 16, Op->Flags, -1);
|
||||
OrderedNode *Src2 = LoadSource_WithOpSize(FPRClass, Op, Src2Op, 16, Op->Flags, 1);
|
||||
|
||||
OrderedNode *SrcRAX = LoadGPRRegister(X86State::REG_RAX);
|
||||
OrderedNode *SrcRDX = LoadGPRRegister(X86State::REG_RDX);
|
||||
|
||||
OrderedNode *IntermediateResult = _VPCMPESTRX(SrcSize, Src1, Src2, SrcRAX, SrcRDX, Control);
|
||||
OrderedNode *ResultNoFlags = _And(IntermediateResult, _Constant(0xFFFF));
|
||||
|
||||
// For the indexed variant of the instructions, if control[6] is set, then we
|
||||
// store the index of the most significant bit into ECX. If it's not set,
|
||||
// then we store the least significant bit.
|
||||
OrderedNode *ZeroConst = _Constant(0);
|
||||
|
||||
const auto ECXResult = [&]() -> OrderedNode* {
|
||||
const auto UseMSBIndex = (Control & 0b0100'0000) != 0;
|
||||
|
||||
OrderedNode *IfZero = _Constant(16 >> (Control & 1));
|
||||
OrderedNode *IfNotZero = UseMSBIndex ? _FindMSB(ResultNoFlags)
|
||||
: _FindLSB(ResultNoFlags);
|
||||
|
||||
return _Select(IR::COND_EQ, ResultNoFlags, ZeroConst,
|
||||
IfZero, IfNotZero);
|
||||
}();
|
||||
|
||||
// Set all of the necessary flags.
|
||||
// We use the top 16-bits of the result to store the flags
|
||||
// in the form:
|
||||
//
|
||||
// Bit: 19 18 17 16
|
||||
// [OF | CF | SF | ZF]
|
||||
//
|
||||
const auto GetFlagBit = [this, IntermediateResult](int BitIndex) {
|
||||
return _Bfe(1, BitIndex, IntermediateResult);
|
||||
};
|
||||
|
||||
SetRFLAG<X86State::RFLAG_ZF_LOC>(GetFlagBit(16));
|
||||
SetRFLAG<X86State::RFLAG_SF_LOC>(GetFlagBit(17));
|
||||
SetRFLAG<X86State::RFLAG_CF_LOC>(GetFlagBit(18));
|
||||
SetRFLAG<X86State::RFLAG_OF_LOC>(GetFlagBit(19));
|
||||
|
||||
SetRFLAG<X86State::RFLAG_AF_LOC>(ZeroConst);
|
||||
SetRFLAG<X86State::RFLAG_PF_LOC>(ZeroConst);
|
||||
|
||||
// ... and we're done!
|
||||
return ECXResult;
|
||||
}
|
||||
|
||||
void OpDispatchBuilder::VPCMPESTRIOp(OpcodeArgs) {
|
||||
OrderedNode *Result = PCMPESTRXOpImpl(Op, Op->Dest, Op->Src[0], Op->Src[1]);
|
||||
StoreGPRRegister(X86State::REG_RCX, Result, 4);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -45,9 +45,9 @@ void InitializeH0F3ATables(Context::OperatingMode Mode) {
|
||||
{OPD(0, PF_3A_66, 0x44), 1, X86InstInfo{"PCLMULQDQ", TYPE_INST, GenFlagsSameSize(SIZE_128BIT) | FLAGS_MODRM | FLAGS_XMM_FLAGS, 1, nullptr}},
|
||||
|
||||
{OPD(0, PF_3A_66, 0x60), 1, X86InstInfo{"PCMPESTRM", TYPE_UNDEC, FLAGS_NONE, 0, nullptr}},
|
||||
{OPD(0, PF_3A_66, 0x61), 1, X86InstInfo{"PCMPESTRI", TYPE_UNDEC, FLAGS_NONE, 0, nullptr}},
|
||||
{OPD(0, PF_3A_66, 0x61), 1, X86InstInfo{"PCMPESTRI", TYPE_INST, GenFlagsSizes(SIZE_128BIT, SIZE_32BIT) | FLAGS_MODRM | FLAGS_XMM_FLAGS, 1, nullptr}},
|
||||
{OPD(0, PF_3A_66, 0x62), 1, X86InstInfo{"PCMPISTRM", TYPE_UNDEC, FLAGS_NONE, 0, nullptr}},
|
||||
{OPD(0, PF_3A_66, 0x63), 1, X86InstInfo{"PCMPISTRI", TYPE_INST, GenFlagsSameSize(SIZE_128BIT) | FLAGS_MODRM | FLAGS_XMM_FLAGS, 1, nullptr}},
|
||||
{OPD(0, PF_3A_66, 0x63), 1, X86InstInfo{"PCMPISTRI", TYPE_UNDEC, FLAGS_NONE, 0, nullptr}},
|
||||
|
||||
{OPD(0, PF_3A_NONE, 0xCC), 1, X86InstInfo{"SHA1RNDS4", TYPE_INST, GenFlagsSameSize(SIZE_128BIT) | FLAGS_MODRM | FLAGS_XMM_FLAGS, 1, nullptr}},
|
||||
|
||||
|
||||
@@ -453,9 +453,9 @@ void InitializeVEXTables() {
|
||||
{OPD(3, 0b01, 0x5F), 1, X86InstInfo{"VFMSUBADDPD", TYPE_UNDEC, FLAGS_NONE, 0, nullptr}},
|
||||
|
||||
{OPD(3, 0b01, 0x60), 1, X86InstInfo{"VPCMPESTRM", TYPE_UNDEC, FLAGS_NONE, 0, nullptr}},
|
||||
{OPD(3, 0b01, 0x61), 1, X86InstInfo{"VPCMPESTRI", TYPE_UNDEC, FLAGS_NONE, 0, nullptr}},
|
||||
{OPD(3, 0b01, 0x61), 1, X86InstInfo{"VPCMPESTRI", TYPE_INST, GenFlagsSizes(SIZE_128BIT, SIZE_32BIT) | FLAGS_MODRM | FLAGS_XMM_FLAGS, 1, nullptr}},
|
||||
{OPD(3, 0b01, 0x62), 1, X86InstInfo{"VPCMPISTRM", TYPE_UNDEC, FLAGS_NONE, 0, nullptr}},
|
||||
{OPD(3, 0b01, 0x63), 1, X86InstInfo{"VPCMPISTRI", TYPE_INST, FLAGS_MODRM | FLAGS_XMM_FLAGS, 1, nullptr}},
|
||||
{OPD(3, 0b01, 0x63), 1, X86InstInfo{"VPCMPISTRI", TYPE_UNDEC, FLAGS_NONE, 0, nullptr}},
|
||||
|
||||
{OPD(3, 0b01, 0x68), 1, X86InstInfo{"VFMADDPS", TYPE_UNDEC, FLAGS_NONE, 0, nullptr}},
|
||||
{OPD(3, 0b01, 0x69), 1, X86InstInfo{"VFMADDPD", TYPE_UNDEC, FLAGS_NONE, 0, nullptr}},
|
||||
|
||||
@@ -0,0 +1,153 @@
|
||||
%ifdef CONFIG
|
||||
{
|
||||
"RegData": {
|
||||
"RAX": ["15"],
|
||||
"RDX": ["16"],
|
||||
"XMM0": ["0x04070F000F000E05", "0x0000000000040404"],
|
||||
"XMM1": ["0x0121313131311111", "0x0000000000010101"],
|
||||
"XMM2": ["0x306F8A9E672C65E5", "0x000030443057697D"],
|
||||
"XMM3": ["0x306F8A9E672C65E5", "0x00003044305796E3"]
|
||||
}
|
||||
}
|
||||
%endif
|
||||
|
||||
; Adjusts the result from LAHF and SETO so that we have a set of flags organized
|
||||
; like [OF, SF, ZF, AF, PF, CF] for storing into the .flags region
|
||||
; of memory.
|
||||
;
|
||||
; The first parameter is the byte offset to store the flag result
|
||||
; at in the .flags region of memory.
|
||||
;
|
||||
%macro ArrangeAndStoreFLAGS 1
|
||||
lahf
|
||||
seto bl
|
||||
movzx bx, bl
|
||||
|
||||
shr ax, 8
|
||||
shl bx, 5
|
||||
|
||||
mov di, ax
|
||||
mov si, ax
|
||||
|
||||
; Mask and shift
|
||||
and di, 0b0000_0000_0000_0100 ; PF
|
||||
and si, 0b0000_0000_0001_0000 ; AF
|
||||
shr di, 1
|
||||
shr si, 2
|
||||
|
||||
; OR all of them together
|
||||
or bx, di
|
||||
or bx, si
|
||||
|
||||
; Reclaim DI for getting ZF/SF and shift into place
|
||||
mov di, ax
|
||||
and di, 0b0000_0000_1100_0000 ; ZF and SF
|
||||
shr di, 3
|
||||
|
||||
; Finally mask and OR all of the bits together
|
||||
and ax, 0b0000_0000_0000_0001 ; CF
|
||||
or bx, ax
|
||||
or bx, di
|
||||
|
||||
; Store result to .flags memory
|
||||
mov [rel .flags + %1], bl
|
||||
%endmacro
|
||||
|
||||
; Performs the string comparison and moves the result from RCX to
|
||||
; a region of memory in the .indices section specified by a byte
|
||||
; offset.
|
||||
;
|
||||
; The first parameter is the byte offset to store the RCX result to.
|
||||
; The second parameter is the control values to pass to pcmpestri
|
||||
;
|
||||
%macro CompareAndStore 2
|
||||
pcmpestri xmm2, xmm3, %2
|
||||
mov [rel .indices + %1], cl
|
||||
|
||||
mov r15, rax
|
||||
ArrangeAndStoreFLAGS %1
|
||||
mov rax, r15
|
||||
%endmacro
|
||||
|
||||
movaps xmm2, [rel .data]
|
||||
movaps xmm3, [rel .data + 32]
|
||||
|
||||
; Unsigned byte character check (lsb, positive polarity)
|
||||
mov rax, 15 ; Exclude 'l'
|
||||
mov rdx, 16
|
||||
CompareAndStore 0, 0b00000000
|
||||
|
||||
; Unsigned byte character check (msb, positive polarity)
|
||||
CompareAndStore 1, 0b01000000
|
||||
|
||||
; Unsigned byte character check (lsb, negative polarity)
|
||||
CompareAndStore 2, 0b00010000
|
||||
|
||||
; Unsigned byte character check (msb, negative polarity)
|
||||
CompareAndStore 3, 0b01010000
|
||||
|
||||
; Unsigned byte character check (lsb, negative masked)
|
||||
CompareAndStore 4, 0b00110000
|
||||
|
||||
; Unsigned byte character check (msb, negative masked)
|
||||
CompareAndStore 5, 0b01110000
|
||||
|
||||
; --- 16-bit unsigned word tests ---
|
||||
movaps xmm2, [rel .data16]
|
||||
movaps xmm3, [rel .data16 + 32]
|
||||
|
||||
; Unsigned word character check (msb, positive polarity)
|
||||
CompareAndStore 6, 0b01000001
|
||||
|
||||
; Unsigned word character check (lsb, negative polarity)
|
||||
CompareAndStore 7, 0b00010001
|
||||
|
||||
; Unsigned word character check (msb, negative polarity)
|
||||
CompareAndStore 8, 0b01010001
|
||||
|
||||
; Unsigned word character check (lsb, negative masked)
|
||||
CompareAndStore 9, 0b00110001
|
||||
|
||||
; Unsigned word character check (msb, negative masked)
|
||||
CompareAndStore 10, 0b01110001
|
||||
|
||||
; Load all our stored indices and flags for result comparing
|
||||
movaps xmm0, [rel .indices]
|
||||
movaps xmm1, [rel .flags]
|
||||
|
||||
hlt
|
||||
|
||||
align 32
|
||||
.data:
|
||||
dq 0x6463626144434241 ; "ABCDabcd"
|
||||
dq 0x6C6B6A694C4B4A49 ; "IJKLijkl"
|
||||
dq 0xFFFFFFFFFFFFFFFF
|
||||
dq 0xEEEEEEEEEEEEEEEE
|
||||
|
||||
dq 0x4120492065726548 ; "Here I A"
|
||||
dq 0x6C4C612759202C6D ; "m, Y'aLl"
|
||||
dq 0xDDDDDDDDDDDDDDDD
|
||||
dq 0xCCCCCCCCCCCCCCCC
|
||||
|
||||
.data16:
|
||||
dq 0x306F8A9E672C65E5 ; "日本語は"
|
||||
dq 0x000030443057697D ; "楽しい\0" (Japanese is fun)
|
||||
dq 0xAAAAAAAAAAAAAAAA
|
||||
dq 0xBBBBBBBBBBBBBBBB
|
||||
|
||||
dq 0x306F8A9E672C65E5 ; "日本語は"
|
||||
dq 0x00003044305796E3 ; "難しい\0" (Japanese is hard)
|
||||
dq 0x8888888888888888
|
||||
dq 0x9999999999999999
|
||||
|
||||
.indices:
|
||||
dq 0x0000000000000000
|
||||
dq 0x0000000000000000
|
||||
dq 0x0000000000000000
|
||||
dq 0x0000000000000000
|
||||
|
||||
.flags:
|
||||
dq 0x0000000000000000
|
||||
dq 0x0000000000000000
|
||||
dq 0x0000000000000000
|
||||
dq 0x0000000000000000
|
||||
@@ -0,0 +1,203 @@
|
||||
%ifdef CONFIG
|
||||
{
|
||||
"RegData": {
|
||||
"RAX": ["4"],
|
||||
"RDX": ["3"],
|
||||
"XMM0": ["0x0F000B060B060F00", "0x040407000F060706"],
|
||||
"XMM1": ["0x3939010101012121", "0x0101212119191919"],
|
||||
"XMM2": ["0x306F8A9E672C65E5", "0x000030443057697D"],
|
||||
"XMM3": ["0x306F8A9E672C65E5", "0x00003044305796E3"],
|
||||
"XMM4": ["0x0704030307000404", "0x0000000000000000"],
|
||||
"XMM5": ["0x1919191939390101", "0x0000000000000000"]
|
||||
}
|
||||
}
|
||||
%endif
|
||||
|
||||
; Adjusts the result from LAHF and SETO so that we have a set of flags organized
|
||||
; like [OF, SF, ZF, AF, PF, CF] for storing into the .flags region
|
||||
; of memory.
|
||||
;
|
||||
; The first parameter is the byte offset to store the flag result
|
||||
; at in the .flags region of memory.
|
||||
;
|
||||
%macro ArrangeAndStoreFLAGS 1
|
||||
lahf
|
||||
seto bl
|
||||
movzx bx, bl
|
||||
|
||||
shr ax, 8
|
||||
shl bx, 5
|
||||
|
||||
mov di, ax
|
||||
mov si, ax
|
||||
|
||||
; Mask and shift
|
||||
and di, 0b0000_0000_0000_0100 ; PF
|
||||
and si, 0b0000_0000_0001_0000 ; AF
|
||||
shr di, 1
|
||||
shr si, 2
|
||||
|
||||
; OR all of them together
|
||||
or bx, di
|
||||
or bx, si
|
||||
|
||||
; Reclaim DI for getting ZF/SF and shift into place
|
||||
mov di, ax
|
||||
and di, 0b0000_0000_1100_0000 ; ZF and SF
|
||||
shr di, 3
|
||||
|
||||
; Finally mask and OR all of the bits together
|
||||
and ax, 0b0000_0000_0000_0001 ; CF
|
||||
or bx, ax
|
||||
or bx, di
|
||||
|
||||
; Store result to .flags memory
|
||||
mov [rel .flags + %1], bl
|
||||
%endmacro
|
||||
|
||||
; Performs the string comparison and moves the result from RCX to
|
||||
; a region of memory in the .indices section specified by a byte
|
||||
; offset.
|
||||
;
|
||||
; The first parameter is the byte offset to store the RCX result to.
|
||||
; The second parameter is the control values to pass to pcmpestri
|
||||
;
|
||||
%macro CompareAndStore 2
|
||||
pcmpestri xmm2, xmm3, %2
|
||||
mov [rel .indices + %1], cl
|
||||
|
||||
mov r15, rax
|
||||
ArrangeAndStoreFLAGS %1
|
||||
mov rax, r15
|
||||
%endmacro
|
||||
|
||||
movaps xmm2, [rel .data]
|
||||
movaps xmm3, [rel .data + 32]
|
||||
|
||||
; Full length unsigned byte string check (lsb, positive polarity)
|
||||
mov rax, 16
|
||||
mov rdx, 16
|
||||
CompareAndStore 0, 0b00001000
|
||||
|
||||
; Full length unsigned byte string check (msb, positive polarity)
|
||||
CompareAndStore 1, 0b01001000
|
||||
|
||||
; Full length unsigned byte string check (lsb, negative polarity)
|
||||
CompareAndStore 2, 0b00011000
|
||||
|
||||
; Full length unsigned byte string check (msb, negative polarity)
|
||||
CompareAndStore 3, 0b01011000
|
||||
|
||||
; Full length unsigned byte string check (lsb, negative masked)
|
||||
CompareAndStore 4, 0b00111000
|
||||
|
||||
; Full length unsigned byte string check (msb, negative masked)
|
||||
CompareAndStore 5, 0b01111000
|
||||
|
||||
; Non-full length unsigned byte string check (lsb, positive polarity)
|
||||
mov rax, 8
|
||||
mov rdx, 7
|
||||
CompareAndStore 6, 0b00001000
|
||||
|
||||
; Non-full length unsigned byte string check (msb, positive polarity)
|
||||
CompareAndStore 7, 0b01001000
|
||||
|
||||
; Non-full length unsigned byte string check (lsb, negative polarity)
|
||||
CompareAndStore 8, 0b00011000
|
||||
|
||||
; Non-full length unsigned byte string check (msb, negative polarity)
|
||||
CompareAndStore 9, 0b01011000
|
||||
|
||||
; Non-full length unsigned byte string check (lsb, negative masked)
|
||||
CompareAndStore 10, 0b00111000
|
||||
|
||||
; Non-full length unsigned byte string check (msb, negative masked)
|
||||
CompareAndStore 11, 0b01111000
|
||||
|
||||
; --- 16-bit unsigned word tests ---
|
||||
|
||||
movaps xmm2, [rel .data16]
|
||||
movaps xmm3, [rel .data16 + 32]
|
||||
|
||||
; Full length unsigned word string check (lsb, positive polarity)
|
||||
mov rax, 8
|
||||
mov rdx, 8
|
||||
CompareAndStore 12, 0b00001001
|
||||
|
||||
; Full length unsigned word string check (msb, positive polarity)
|
||||
CompareAndStore 13, 0b01001001
|
||||
|
||||
; Full length unsigned word string check (lsb, negative polarity)
|
||||
CompareAndStore 14, 0b00011001
|
||||
|
||||
; Full length unsigned word string check (msb, negative polarity)
|
||||
CompareAndStore 15, 0b01011001
|
||||
|
||||
; Full length unsigned word string check (lsb, negative masked)
|
||||
CompareAndStore 16, 0b00111001
|
||||
|
||||
; Full length unsigned word string check (msb, negative masked)
|
||||
CompareAndStore 17, 0b01111001
|
||||
|
||||
; Non-full length unsigned word string check (lsb, positive polarity)
|
||||
mov rax, 4
|
||||
mov rdx, 3
|
||||
CompareAndStore 18, 0b00001001
|
||||
|
||||
; Non-full length unsigned word string check (msb, positive polarity)
|
||||
CompareAndStore 19, 0b01001001
|
||||
|
||||
; Non-full length unsigned word string check (lsb, negative polarity)
|
||||
CompareAndStore 20, 0b00011001
|
||||
|
||||
; Non-full length unsigned word string check (msb, negative polarity)
|
||||
CompareAndStore 21, 0b01011001
|
||||
|
||||
; Non-full length unsigned word string check (lsb, negative masked)
|
||||
CompareAndStore 22, 0b00111001
|
||||
|
||||
; Non-full length unsigned word string check (msb, negative masked)
|
||||
CompareAndStore 23, 0b01111001
|
||||
|
||||
; Load all our stored indices and flags for result comparing
|
||||
movaps xmm0, [rel .indices]
|
||||
movaps xmm4, [rel .indices + 16]
|
||||
movaps xmm1, [rel .flags]
|
||||
movaps xmm5, [rel .flags + 16]
|
||||
|
||||
hlt
|
||||
|
||||
align 32
|
||||
.data:
|
||||
dq 0x6550206F6C6C6548 ; "Hello Pe"
|
||||
dq 0x21212121656C706F ; "ople!!!!"
|
||||
dq 0xFFFFFFFFFFFFFFFF
|
||||
dq 0xEEEEEEEEEEEEEEEE
|
||||
|
||||
dq 0x2759206F6C6C6548 ; "Hello Y'"
|
||||
dq 0x21212121216C6C61 ; "all!!!!!"
|
||||
dq 0xDDDDDDDDDDDDDDDD
|
||||
dq 0xCCCCCCCCCCCCCCCC
|
||||
|
||||
.data16:
|
||||
dq 0x306F8A9E672C65E5 ; "日本語は"
|
||||
dq 0x000030443057697D ; "楽しい\0" (Japanese is fun)
|
||||
dq 0xAAAAAAAAAAAAAAAA
|
||||
dq 0xBBBBBBBBBBBBBBBB
|
||||
|
||||
dq 0x306F8A9E672C65E5 ; "日本語は"
|
||||
dq 0x00003044305796E3 ; "難しい\0" (Japanese is hard)
|
||||
dq 0x8888888888888888
|
||||
dq 0x9999999999999999
|
||||
|
||||
.indices:
|
||||
dq 0x0000000000000000
|
||||
dq 0x0000000000000000
|
||||
dq 0x0000000000000000
|
||||
dq 0x0000000000000000
|
||||
|
||||
.flags:
|
||||
dq 0x0000000000000000
|
||||
dq 0x0000000000000000
|
||||
dq 0x0000000000000000
|
||||
dq 0x0000000000000000
|
||||
@@ -0,0 +1,156 @@
|
||||
%ifdef CONFIG
|
||||
{
|
||||
"RegData": {
|
||||
"RAX": ["2"],
|
||||
"RDX": ["16"],
|
||||
"XMM0": ["0x05050F000F000902", "0x0000000007000700"],
|
||||
"XMM1": ["0x1111313131311111", "0x0000000031313131"],
|
||||
"XMM2": ["0x306F8A9E30443057", "0x000030443057697D"],
|
||||
"XMM3": ["0x306F8A9E672C65E5", "0x00003044305796E3"]
|
||||
}
|
||||
}
|
||||
%endif
|
||||
|
||||
; Adjusts the result from LAHF and SETO so that we have a set of flags organized
|
||||
; like [OF, SF, ZF, AF, PF, CF] for storing into the .flags region
|
||||
; of memory.
|
||||
;
|
||||
; The first parameter is the byte offset to store the flag result
|
||||
; at in the .flags region of memory.
|
||||
;
|
||||
%macro ArrangeAndStoreFLAGS 1
|
||||
lahf
|
||||
seto bl
|
||||
movzx bx, bl
|
||||
|
||||
shr ax, 8
|
||||
shl bx, 5
|
||||
|
||||
mov di, ax
|
||||
mov si, ax
|
||||
|
||||
; Mask and shift
|
||||
and di, 0b0000_0000_0000_0100 ; PF
|
||||
and si, 0b0000_0000_0001_0000 ; AF
|
||||
shr di, 1
|
||||
shr si, 2
|
||||
|
||||
; OR all of them together
|
||||
or bx, di
|
||||
or bx, si
|
||||
|
||||
; Reclaim DI for getting ZF/SF and shift into place
|
||||
mov di, ax
|
||||
and di, 0b0000_0000_1100_0000 ; ZF and SF
|
||||
shr di, 3
|
||||
|
||||
; Finally mask and OR all of the bits together
|
||||
and ax, 0b0000_0000_0000_0001 ; CF
|
||||
or bx, ax
|
||||
or bx, di
|
||||
|
||||
; Store result to .flags memory
|
||||
mov [rel .flags + %1], bl
|
||||
%endmacro
|
||||
|
||||
; Performs the string comparison and moves the result from RCX to
|
||||
; a region of memory in the .indices section specified by a byte
|
||||
; offset.
|
||||
;
|
||||
; The first parameter is the byte offset to store the RCX result to.
|
||||
; The second parameter is the control values to pass to pcmpestri
|
||||
;
|
||||
%macro CompareAndStore 2
|
||||
pcmpestri xmm2, xmm3, %2
|
||||
mov [rel .indices + %1], cl
|
||||
|
||||
mov r15, rax
|
||||
ArrangeAndStoreFLAGS %1
|
||||
mov rax, r15
|
||||
%endmacro
|
||||
|
||||
movaps xmm2, [rel .data]
|
||||
movaps xmm3, [rel .data + 32]
|
||||
|
||||
; Unsigned byte string check (lsb, positive polarity)
|
||||
mov rax, 2
|
||||
mov rdx, 16
|
||||
CompareAndStore 0, 0b00001100
|
||||
|
||||
; Unsigned byte string check (msb, positive polarity)
|
||||
CompareAndStore 1, 0b01001100
|
||||
|
||||
; Unsigned byte string check (lsb, negative polarity)
|
||||
CompareAndStore 2, 0b00011100
|
||||
|
||||
; Unsigned byte string check (msb, negative polarity)
|
||||
CompareAndStore 3, 0b01011100
|
||||
|
||||
; Unsigned byte string check (lsb, negative masked)
|
||||
CompareAndStore 4, 0b00111100
|
||||
|
||||
; Unsigned byte string check (msb, negative masked)
|
||||
CompareAndStore 5, 0b01111100
|
||||
|
||||
; --- 16-bit unsigned word tests ---
|
||||
; Intentionally don't reset RDX to 8 here to test upper bounds clamping.
|
||||
movaps xmm2, [rel .data16]
|
||||
movaps xmm3, [rel .data16 + 32]
|
||||
|
||||
CompareAndStore 6, 0b00001101
|
||||
|
||||
; Unsigned word string check (msb, positive polarity)
|
||||
CompareAndStore 7, 0b01001101
|
||||
|
||||
; Unsigned word string check (lsb, negative polarity)
|
||||
CompareAndStore 8, 0b00011101
|
||||
|
||||
; Unsigned word string check (msb, negative polarity)
|
||||
CompareAndStore 9, 0b01011101
|
||||
|
||||
; Unsigned word string check (lsb, negative masked)
|
||||
CompareAndStore 10, 0b00111101
|
||||
|
||||
; Unsigned word string check (msb, negative masked)
|
||||
CompareAndStore 11, 0b01111101
|
||||
|
||||
; Load all our stored indices and flags for result comparing
|
||||
movaps xmm0, [rel .indices]
|
||||
movaps xmm1, [rel .flags]
|
||||
|
||||
hlt
|
||||
|
||||
align 32
|
||||
.data:
|
||||
dq 0x6550206F6FFF6C6C ; "ll" with junk following it
|
||||
dq 0x21212121656C706F
|
||||
dq 0xFFFFFFFFFFFFFFFF
|
||||
dq 0xEEEEEEEEEEEEEEEE
|
||||
|
||||
dq 0x2759206F6C6C6548 ; "Hello Y'"
|
||||
dq 0x21212121216C6C61 ; "all!!!!!"
|
||||
dq 0xDDDDDDDDDDDDDDDD
|
||||
dq 0xCCCCCCCCCCCCCCCC
|
||||
|
||||
.data16:
|
||||
dq 0x306F8A9E30443057 ; "しい" followed by junk
|
||||
dq 0x000030443057697D
|
||||
dq 0xAAAAAAAAAAAAAAAA
|
||||
dq 0xBBBBBBBBBBBBBBBB
|
||||
|
||||
dq 0x306F8A9E672C65E5 ; "日本語は"
|
||||
dq 0x00003044305796E3 ; "難しい\0" (Japanese is hard)
|
||||
dq 0x8888888888888888
|
||||
dq 0x9999999999999999
|
||||
|
||||
.indices:
|
||||
dq 0x0000000000000000
|
||||
dq 0x0000000000000000
|
||||
dq 0x0000000000000000
|
||||
dq 0x0000000000000000
|
||||
|
||||
.flags:
|
||||
dq 0x0000000000000000
|
||||
dq 0x0000000000000000
|
||||
dq 0x0000000000000000
|
||||
dq 0x0000000000000000
|
||||
@@ -0,0 +1,154 @@
|
||||
%ifdef CONFIG
|
||||
{
|
||||
"RegData": {
|
||||
"RAX": ["4"],
|
||||
"RDX": ["16"],
|
||||
"XMM0": ["0x00060F000F000D01", "0x0000000000070007"],
|
||||
"XMM1": ["0x3111313131311111", "0x0000000000313131"],
|
||||
"XMM2": ["0x005A0041007A0061", "0x55AACCBBFF223344"],
|
||||
"XMM3": ["0x006500200027003F", "0x00210065004F0065"]
|
||||
}
|
||||
}
|
||||
%endif
|
||||
|
||||
; Adjusts the result from LAHF and SETO so that we have a set of flags organized
|
||||
; like [OF, SF, ZF, AF, PF, CF] for storing into the .flags region
|
||||
; of memory.
|
||||
;
|
||||
; The first parameter is the byte offset to store the flag result
|
||||
; at in the .flags region of memory.
|
||||
;
|
||||
%macro ArrangeAndStoreFLAGS 1
|
||||
lahf
|
||||
seto bl
|
||||
movzx bx, bl
|
||||
|
||||
shr ax, 8
|
||||
shl bx, 5
|
||||
|
||||
mov di, ax
|
||||
mov si, ax
|
||||
|
||||
; Mask and shift
|
||||
and di, 0b0000_0000_0000_0100 ; PF
|
||||
and si, 0b0000_0000_0001_0000 ; AF
|
||||
shr di, 1
|
||||
shr si, 2
|
||||
|
||||
; OR all of them together
|
||||
or bx, di
|
||||
or bx, si
|
||||
|
||||
; Reclaim DI for getting ZF/SF and shift into place
|
||||
mov di, ax
|
||||
and di, 0b0000_0000_1100_0000 ; ZF and SF
|
||||
shr di, 3
|
||||
|
||||
; Finally mask and OR all of the bits together
|
||||
and ax, 0b0000_0000_0000_0001 ; CF
|
||||
or bx, ax
|
||||
or bx, di
|
||||
|
||||
; Store result to .flags memory
|
||||
mov [rel .flags + %1], bl
|
||||
%endmacro
|
||||
|
||||
; Performs the string comparison and moves the result from RCX to
|
||||
; a region of memory in the .indices section specified by a byte
|
||||
; offset.
|
||||
;
|
||||
; The first parameter is the byte offset to store the RCX result to.
|
||||
; The second parameter is the control values to pass to pcmpestri
|
||||
;
|
||||
%macro CompareAndStore 2
|
||||
pcmpestri xmm2, xmm3, %2
|
||||
mov [rel .indices + %1], cl
|
||||
|
||||
mov r15, rax
|
||||
ArrangeAndStoreFLAGS %1
|
||||
mov rax, r15
|
||||
%endmacro
|
||||
|
||||
movaps xmm2, [rel .data]
|
||||
movaps xmm3, [rel .data + 32]
|
||||
|
||||
; Range unsigned byte check (lsb, positive polarity)
|
||||
mov rax, 4
|
||||
mov rdx, 16
|
||||
CompareAndStore 0, 0b00000100
|
||||
|
||||
; Range unsigned byte check (msb, positive polarity)
|
||||
CompareAndStore 1, 0b01000100
|
||||
|
||||
; Range unsigned byte check (lsb, negative polarity)
|
||||
CompareAndStore 2, 0b00010100
|
||||
|
||||
; Range unsigned byte check (msb, negative polarity)
|
||||
CompareAndStore 3, 0b01010100
|
||||
|
||||
; Range unsigned byte check (lsb, negative masked)
|
||||
CompareAndStore 4, 0b00110100
|
||||
|
||||
; Range unsigned byte check (msb, negative masked)
|
||||
CompareAndStore 5, 0b01110100
|
||||
|
||||
; --- 16-bit unsigned word tests ---
|
||||
; Intentionally don't reset RDX to 8 here to test upper bounds clamping.
|
||||
movaps xmm2, [rel .data16]
|
||||
movaps xmm3, [rel .data16 + 32]
|
||||
|
||||
; Range unsigned word check (msb, positive polarity)
|
||||
CompareAndStore 6, 0b01000101
|
||||
|
||||
; Range unsigned word check (lsb, negative polarity)
|
||||
CompareAndStore 7, 0b00010101
|
||||
|
||||
; Range unsigned word check (msb, negative polarity)
|
||||
CompareAndStore 8, 0b01010101
|
||||
|
||||
; Range unsigned word check (lsb, negative masked)
|
||||
CompareAndStore 9, 0b00110101
|
||||
|
||||
; Range unsigned word check (msb, negative masked)
|
||||
CompareAndStore 10, 0b01110101
|
||||
|
||||
; Load all our stored indices and flags for result comparing
|
||||
movaps xmm0, [rel .indices]
|
||||
movaps xmm1, [rel .flags]
|
||||
|
||||
hlt
|
||||
|
||||
align 32
|
||||
.data:
|
||||
dq 0x998877665A417A61 ; "azAZ" (followed by junk)
|
||||
dq 0x55AACCBBFF223344
|
||||
dq 0xFFFFFFFFFFFFFFFF
|
||||
dq 0xEEEEEEEEEEEEEEEE
|
||||
|
||||
dq 0x726548206D27493F ; "?I'm Her"
|
||||
dq 0x21216E65704F2065 ; "e Open!!"
|
||||
dq 0xFFFFFFFFFFFFFFFF
|
||||
dq 0xEEEEEEEEEEEEEEEE
|
||||
|
||||
.data16:
|
||||
dq 0x005A0041007A0061 ; "azAZ"
|
||||
dq 0x55AACCBBFF223344
|
||||
dq 0xAAAAAAAAAAAAAAAA
|
||||
dq 0xBBBBBBBBBBBBBBBB
|
||||
|
||||
dq 0x006500200027003F ; "?' e"
|
||||
dq 0x00210065004F0065 ; "eOen!"
|
||||
dq 0x8888888888888888
|
||||
dq 0x9999999999999999
|
||||
|
||||
.indices:
|
||||
dq 0x0000000000000000
|
||||
dq 0x0000000000000000
|
||||
dq 0x0000000000000000
|
||||
dq 0x0000000000000000
|
||||
|
||||
.flags:
|
||||
dq 0x0000000000000000
|
||||
dq 0x0000000000000000
|
||||
dq 0x0000000000000000
|
||||
dq 0x0000000000000000
|
||||
@@ -0,0 +1,154 @@
|
||||
%ifdef CONFIG
|
||||
{
|
||||
"HostFeatures": ["AVX"],
|
||||
"RegData": {
|
||||
"RAX": ["15"],
|
||||
"RDX": ["16"],
|
||||
"XMM0": ["0x04070F000F000E05", "0x0000000000040404", "0x0000000000000000", "0x0000000000000000"],
|
||||
"XMM1": ["0x0121313131311111", "0x0000000000010101", "0x0000000000000000", "0x0000000000000000"],
|
||||
"XMM2": ["0x306F8A9E672C65E5", "0x000030443057697D", "0xAAAAAAAAAAAAAAAA", "0xBBBBBBBBBBBBBBBB"],
|
||||
"XMM3": ["0x306F8A9E672C65E5", "0x00003044305796E3", "0x8888888888888888", "0x9999999999999999"]
|
||||
}
|
||||
}
|
||||
%endif
|
||||
|
||||
; Adjusts the result from LAHF and SETO so that we have a set of flags organized
|
||||
; like [OF, SF, ZF, AF, PF, CF] for storing into the .flags region
|
||||
; of memory.
|
||||
;
|
||||
; The first parameter is the byte offset to store the flag result
|
||||
; at in the .flags region of memory.
|
||||
;
|
||||
%macro ArrangeAndStoreFLAGS 1
|
||||
lahf
|
||||
seto bl
|
||||
movzx bx, bl
|
||||
|
||||
shr ax, 8
|
||||
shl bx, 5
|
||||
|
||||
mov di, ax
|
||||
mov si, ax
|
||||
|
||||
; Mask and shift
|
||||
and di, 0b0000_0000_0000_0100 ; PF
|
||||
and si, 0b0000_0000_0001_0000 ; AF
|
||||
shr di, 1
|
||||
shr si, 2
|
||||
|
||||
; OR all of them together
|
||||
or bx, di
|
||||
or bx, si
|
||||
|
||||
; Reclaim DI for getting ZF/SF and shift into place
|
||||
mov di, ax
|
||||
and di, 0b0000_0000_1100_0000 ; ZF and SF
|
||||
shr di, 3
|
||||
|
||||
; Finally mask and OR all of the bits together
|
||||
and ax, 0b0000_0000_0000_0001 ; CF
|
||||
or bx, ax
|
||||
or bx, di
|
||||
|
||||
; Store result to .flags memory
|
||||
mov [rel .flags + %1], bl
|
||||
%endmacro
|
||||
|
||||
; Performs the string comparison and moves the result from RCX to
|
||||
; a region of memory in the .indices section specified by a byte
|
||||
; offset.
|
||||
;
|
||||
; The first parameter is the byte offset to store the RCX result to.
|
||||
; The second parameter is the control values to pass to vpcmpestri
|
||||
;
|
||||
%macro CompareAndStore 2
|
||||
vpcmpestri xmm2, xmm3, %2
|
||||
mov [rel .indices + %1], cl
|
||||
|
||||
mov r15, rax
|
||||
ArrangeAndStoreFLAGS %1
|
||||
mov rax, r15
|
||||
%endmacro
|
||||
|
||||
vmovaps ymm2, [rel .data]
|
||||
vmovaps ymm3, [rel .data + 32]
|
||||
|
||||
; Unsigned byte character check (lsb, positive polarity)
|
||||
mov rax, 15 ; Exclude 'l'
|
||||
mov rdx, 16
|
||||
CompareAndStore 0, 0b00000000
|
||||
|
||||
; Unsigned byte character check (msb, positive polarity)
|
||||
CompareAndStore 1, 0b01000000
|
||||
|
||||
; Unsigned byte character check (lsb, negative polarity)
|
||||
CompareAndStore 2, 0b00010000
|
||||
|
||||
; Unsigned byte character check (msb, negative polarity)
|
||||
CompareAndStore 3, 0b01010000
|
||||
|
||||
; Unsigned byte character check (lsb, negative masked)
|
||||
CompareAndStore 4, 0b00110000
|
||||
|
||||
; Unsigned byte character check (msb, negative masked)
|
||||
CompareAndStore 5, 0b01110000
|
||||
|
||||
; --- 16-bit unsigned word tests ---
|
||||
vmovaps ymm2, [rel .data16]
|
||||
vmovaps ymm3, [rel .data16 + 32]
|
||||
|
||||
; Unsigned word character check (msb, positive polarity)
|
||||
CompareAndStore 6, 0b01000001
|
||||
|
||||
; Unsigned word character check (lsb, negative polarity)
|
||||
CompareAndStore 7, 0b00010001
|
||||
|
||||
; Unsigned word character check (msb, negative polarity)
|
||||
CompareAndStore 8, 0b01010001
|
||||
|
||||
; Unsigned word character check (lsb, negative masked)
|
||||
CompareAndStore 9, 0b00110001
|
||||
|
||||
; Unsigned word character check (msb, negative masked)
|
||||
CompareAndStore 10, 0b01110001
|
||||
|
||||
; Load all our stored indices and flags for result comparing
|
||||
vmovaps ymm0, [rel .indices]
|
||||
vmovaps ymm1, [rel .flags]
|
||||
|
||||
hlt
|
||||
|
||||
align 32
|
||||
.data:
|
||||
dq 0x6463626144434241 ; "ABCDabcd"
|
||||
dq 0x6C6B6A694C4B4A49 ; "IJKLijkl"
|
||||
dq 0xFFFFFFFFFFFFFFFF
|
||||
dq 0xEEEEEEEEEEEEEEEE
|
||||
|
||||
dq 0x4120492065726548 ; "Here I A"
|
||||
dq 0x6C4C612759202C6D ; "m, Y'aLl"
|
||||
dq 0xDDDDDDDDDDDDDDDD
|
||||
dq 0xCCCCCCCCCCCCCCCC
|
||||
|
||||
.data16:
|
||||
dq 0x306F8A9E672C65E5 ; "日本語は"
|
||||
dq 0x000030443057697D ; "楽しい\0" (Japanese is fun)
|
||||
dq 0xAAAAAAAAAAAAAAAA
|
||||
dq 0xBBBBBBBBBBBBBBBB
|
||||
|
||||
dq 0x306F8A9E672C65E5 ; "日本語は"
|
||||
dq 0x00003044305796E3 ; "難しい\0" (Japanese is hard)
|
||||
dq 0x8888888888888888
|
||||
dq 0x9999999999999999
|
||||
|
||||
.indices:
|
||||
dq 0x0000000000000000
|
||||
dq 0x0000000000000000
|
||||
dq 0x0000000000000000
|
||||
dq 0x0000000000000000
|
||||
|
||||
.flags:
|
||||
dq 0x0000000000000000
|
||||
dq 0x0000000000000000
|
||||
dq 0x0000000000000000
|
||||
dq 0x0000000000000000
|
||||
@@ -0,0 +1,200 @@
|
||||
%ifdef CONFIG
|
||||
{
|
||||
"HostFeatures": ["AVX"],
|
||||
"RegData": {
|
||||
"RAX": ["4"],
|
||||
"RDX": ["3"],
|
||||
"XMM0": ["0x0F000B060B060F00", "0x040407000F060706", "0x0704030307000404", "0x0000000000000000"],
|
||||
"XMM1": ["0x3939010101012121", "0x0101212119191919", "0x1919191939390101", "0x0000000000000000"],
|
||||
"XMM2": ["0x306F8A9E672C65E5", "0x000030443057697D", "0xAAAAAAAAAAAAAAAA", "0xBBBBBBBBBBBBBBBB"],
|
||||
"XMM3": ["0x306F8A9E672C65E5", "0x00003044305796E3", "0x8888888888888888", "0x9999999999999999"]
|
||||
}
|
||||
}
|
||||
%endif
|
||||
|
||||
; Adjusts the result from LAHF and SETO so that we have a set of flags organized
|
||||
; like [OF, SF, ZF, AF, PF, CF] for storing into the .flags region
|
||||
; of memory.
|
||||
;
|
||||
; The first parameter is the byte offset to store the flag result
|
||||
; at in the .flags region of memory.
|
||||
;
|
||||
%macro ArrangeAndStoreFLAGS 1
|
||||
lahf
|
||||
seto bl
|
||||
movzx bx, bl
|
||||
|
||||
shr ax, 8
|
||||
shl bx, 5
|
||||
|
||||
mov di, ax
|
||||
mov si, ax
|
||||
|
||||
; Mask and shift
|
||||
and di, 0b0000_0000_0000_0100 ; PF
|
||||
and si, 0b0000_0000_0001_0000 ; AF
|
||||
shr di, 1
|
||||
shr si, 2
|
||||
|
||||
; OR all of them together
|
||||
or bx, di
|
||||
or bx, si
|
||||
|
||||
; Reclaim DI for getting ZF/SF and shift into place
|
||||
mov di, ax
|
||||
and di, 0b0000_0000_1100_0000 ; ZF and SF
|
||||
shr di, 3
|
||||
|
||||
; Finally mask and OR all of the bits together
|
||||
and ax, 0b0000_0000_0000_0001 ; CF
|
||||
or bx, ax
|
||||
or bx, di
|
||||
|
||||
; Store result to .flags memory
|
||||
mov [rel .flags + %1], bl
|
||||
%endmacro
|
||||
|
||||
; Performs the string comparison and moves the result from RCX to
|
||||
; a region of memory in the .indices section specified by a byte
|
||||
; offset.
|
||||
;
|
||||
; The first parameter is the byte offset to store the RCX result to.
|
||||
; The second parameter is the control values to pass to vpcmpestri
|
||||
;
|
||||
%macro CompareAndStore 2
|
||||
vpcmpestri xmm2, xmm3, %2
|
||||
mov [rel .indices + %1], cl
|
||||
|
||||
mov r15, rax
|
||||
ArrangeAndStoreFLAGS %1
|
||||
mov rax, r15
|
||||
%endmacro
|
||||
|
||||
vmovaps ymm2, [rel .data]
|
||||
vmovaps ymm3, [rel .data + 32]
|
||||
|
||||
; Full length unsigned byte string check (lsb, positive polarity)
|
||||
mov rax, 16
|
||||
mov rdx, 16
|
||||
CompareAndStore 0, 0b00001000
|
||||
|
||||
; Full length unsigned byte string check (msb, positive polarity)
|
||||
CompareAndStore 1, 0b01001000
|
||||
|
||||
; Full length unsigned byte string check (lsb, negative polarity)
|
||||
CompareAndStore 2, 0b00011000
|
||||
|
||||
; Full length unsigned byte string check (msb, negative polarity)
|
||||
CompareAndStore 3, 0b01011000
|
||||
|
||||
; Full length unsigned byte string check (lsb, negative masked)
|
||||
CompareAndStore 4, 0b00111000
|
||||
|
||||
; Full length unsigned byte string check (msb, negative masked)
|
||||
CompareAndStore 5, 0b01111000
|
||||
|
||||
; Non-full length unsigned byte string check (lsb, positive polarity)
|
||||
mov rax, 8
|
||||
mov rdx, 7
|
||||
CompareAndStore 6, 0b00001000
|
||||
|
||||
; Non-full length unsigned byte string check (msb, positive polarity)
|
||||
CompareAndStore 7, 0b01001000
|
||||
|
||||
; Non-full length unsigned byte string check (lsb, negative polarity)
|
||||
CompareAndStore 8, 0b00011000
|
||||
|
||||
; Non-full length unsigned byte string check (msb, negative polarity)
|
||||
CompareAndStore 9, 0b01011000
|
||||
|
||||
; Non-full length unsigned byte string check (lsb, negative masked)
|
||||
CompareAndStore 10, 0b00111000
|
||||
|
||||
; Non-full length unsigned byte string check (msb, negative masked)
|
||||
CompareAndStore 11, 0b01111000
|
||||
|
||||
; --- 16-bit unsigned word tests ---
|
||||
|
||||
vmovaps ymm2, [rel .data16]
|
||||
vmovaps ymm3, [rel .data16 + 32]
|
||||
|
||||
; Full length unsigned word string check (lsb, positive polarity)
|
||||
mov rax, 8
|
||||
mov rdx, 8
|
||||
CompareAndStore 12, 0b00001001
|
||||
|
||||
; Full length unsigned word string check (msb, positive polarity)
|
||||
CompareAndStore 13, 0b01001001
|
||||
|
||||
; Full length unsigned word string check (lsb, negative polarity)
|
||||
CompareAndStore 14, 0b00011001
|
||||
|
||||
; Full length unsigned word string check (msb, negative polarity)
|
||||
CompareAndStore 15, 0b01011001
|
||||
|
||||
; Full length unsigned word string check (lsb, negative masked)
|
||||
CompareAndStore 16, 0b00111001
|
||||
|
||||
; Full length unsigned word string check (msb, negative masked)
|
||||
CompareAndStore 17, 0b01111001
|
||||
|
||||
; Non-full length unsigned word string check (lsb, positive polarity)
|
||||
mov rax, 4
|
||||
mov rdx, 3
|
||||
CompareAndStore 18, 0b00001001
|
||||
|
||||
; Non-full length unsigned word string check (msb, positive polarity)
|
||||
CompareAndStore 19, 0b01001001
|
||||
|
||||
; Non-full length unsigned word string check (lsb, negative polarity)
|
||||
CompareAndStore 20, 0b00011001
|
||||
|
||||
; Non-full length unsigned word string check (msb, negative polarity)
|
||||
CompareAndStore 21, 0b01011001
|
||||
|
||||
; Non-full length unsigned word string check (lsb, negative masked)
|
||||
CompareAndStore 22, 0b00111001
|
||||
|
||||
; Non-full length unsigned word string check (msb, negative masked)
|
||||
CompareAndStore 23, 0b01111001
|
||||
|
||||
; Load all our stored indices and flags for result comparing
|
||||
vmovaps ymm0, [rel .indices]
|
||||
vmovaps ymm1, [rel .flags]
|
||||
|
||||
hlt
|
||||
|
||||
align 32
|
||||
.data:
|
||||
dq 0x6550206F6C6C6548 ; "Hello Pe"
|
||||
dq 0x21212121656C706F ; "ople!!!!"
|
||||
dq 0xFFFFFFFFFFFFFFFF
|
||||
dq 0xEEEEEEEEEEEEEEEE
|
||||
|
||||
dq 0x2759206F6C6C6548 ; "Hello Y'"
|
||||
dq 0x21212121216C6C61 ; "all!!!!!"
|
||||
dq 0xDDDDDDDDDDDDDDDD
|
||||
dq 0xCCCCCCCCCCCCCCCC
|
||||
|
||||
.data16:
|
||||
dq 0x306F8A9E672C65E5 ; "日本語は"
|
||||
dq 0x000030443057697D ; "楽しい\0" (Japanese is fun)
|
||||
dq 0xAAAAAAAAAAAAAAAA
|
||||
dq 0xBBBBBBBBBBBBBBBB
|
||||
|
||||
dq 0x306F8A9E672C65E5 ; "日本語は"
|
||||
dq 0x00003044305796E3 ; "難しい\0" (Japanese is hard)
|
||||
dq 0x8888888888888888
|
||||
dq 0x9999999999999999
|
||||
|
||||
.indices:
|
||||
dq 0x0000000000000000
|
||||
dq 0x0000000000000000
|
||||
dq 0x0000000000000000
|
||||
dq 0x0000000000000000
|
||||
|
||||
.flags:
|
||||
dq 0x0000000000000000
|
||||
dq 0x0000000000000000
|
||||
dq 0x0000000000000000
|
||||
dq 0x0000000000000000
|
||||
@@ -0,0 +1,157 @@
|
||||
%ifdef CONFIG
|
||||
{
|
||||
"HostFeatures": ["AVX"],
|
||||
"RegData": {
|
||||
"RAX": ["2"],
|
||||
"RDX": ["16"],
|
||||
"XMM0": ["0x05050F000F000902", "0x0000000007000700", "0x0000000000000000", "0x0000000000000000"],
|
||||
"XMM1": ["0x1111313131311111", "0x0000000031313131", "0x0000000000000000", "0x0000000000000000"],
|
||||
"XMM2": ["0x306F8A9E30443057", "0x000030443057697D", "0xAAAAAAAAAAAAAAAA", "0xBBBBBBBBBBBBBBBB"],
|
||||
"XMM3": ["0x306F8A9E672C65E5", "0x00003044305796E3", "0x8888888888888888", "0x9999999999999999"]
|
||||
}
|
||||
}
|
||||
%endif
|
||||
|
||||
; Adjusts the result from LAHF and SETO so that we have a set of flags organized
|
||||
; like [OF, SF, ZF, AF, PF, CF] for storing into the .flags region
|
||||
; of memory.
|
||||
;
|
||||
; The first parameter is the byte offset to store the flag result
|
||||
; at in the .flags region of memory.
|
||||
;
|
||||
%macro ArrangeAndStoreFLAGS 1
|
||||
lahf
|
||||
seto bl
|
||||
movzx bx, bl
|
||||
|
||||
shr ax, 8
|
||||
shl bx, 5
|
||||
|
||||
mov di, ax
|
||||
mov si, ax
|
||||
|
||||
; Mask and shift
|
||||
and di, 0b0000_0000_0000_0100 ; PF
|
||||
and si, 0b0000_0000_0001_0000 ; AF
|
||||
shr di, 1
|
||||
shr si, 2
|
||||
|
||||
; OR all of them together
|
||||
or bx, di
|
||||
or bx, si
|
||||
|
||||
; Reclaim DI for getting ZF/SF and shift into place
|
||||
mov di, ax
|
||||
and di, 0b0000_0000_1100_0000 ; ZF and SF
|
||||
shr di, 3
|
||||
|
||||
; Finally mask and OR all of the bits together
|
||||
and ax, 0b0000_0000_0000_0001 ; CF
|
||||
or bx, ax
|
||||
or bx, di
|
||||
|
||||
; Store result to .flags memory
|
||||
mov [rel .flags + %1], bl
|
||||
%endmacro
|
||||
|
||||
; Performs the string comparison and moves the result from RCX to
|
||||
; a region of memory in the .indices section specified by a byte
|
||||
; offset.
|
||||
;
|
||||
; The first parameter is the byte offset to store the RCX result to.
|
||||
; The second parameter is the control values to pass to vpcmpestri
|
||||
;
|
||||
%macro CompareAndStore 2
|
||||
vpcmpestri xmm2, xmm3, %2
|
||||
mov [rel .indices + %1], cl
|
||||
|
||||
mov r15, rax
|
||||
ArrangeAndStoreFLAGS %1
|
||||
mov rax, r15
|
||||
%endmacro
|
||||
|
||||
vmovaps ymm2, [rel .data]
|
||||
vmovaps ymm3, [rel .data + 32]
|
||||
|
||||
; Unsigned byte string check (lsb, positive polarity)
|
||||
mov rax, 2
|
||||
mov rdx, 16
|
||||
CompareAndStore 0, 0b00001100
|
||||
|
||||
; Unsigned byte string check (msb, positive polarity)
|
||||
CompareAndStore 1, 0b01001100
|
||||
|
||||
; Unsigned byte string check (lsb, negative polarity)
|
||||
CompareAndStore 2, 0b00011100
|
||||
|
||||
; Unsigned byte string check (msb, negative polarity)
|
||||
CompareAndStore 3, 0b01011100
|
||||
|
||||
; Unsigned byte string check (lsb, negative masked)
|
||||
CompareAndStore 4, 0b00111100
|
||||
|
||||
; Unsigned byte string check (msb, negative masked)
|
||||
CompareAndStore 5, 0b01111100
|
||||
|
||||
; --- 16-bit unsigned word tests ---
|
||||
; Intentionally don't reset RDX to 8 here to test upper bounds clamping.
|
||||
vmovaps ymm2, [rel .data16]
|
||||
vmovaps ymm3, [rel .data16 + 32]
|
||||
|
||||
CompareAndStore 6, 0b00001101
|
||||
|
||||
; Unsigned word string check (msb, positive polarity)
|
||||
CompareAndStore 7, 0b01001101
|
||||
|
||||
; Unsigned word string check (lsb, negative polarity)
|
||||
CompareAndStore 8, 0b00011101
|
||||
|
||||
; Unsigned word string check (msb, negative polarity)
|
||||
CompareAndStore 9, 0b01011101
|
||||
|
||||
; Unsigned word string check (lsb, negative masked)
|
||||
CompareAndStore 10, 0b00111101
|
||||
|
||||
; Unsigned word string check (msb, negative masked)
|
||||
CompareAndStore 11, 0b01111101
|
||||
|
||||
; Load all our stored indices and flags for result comparing
|
||||
vmovaps ymm0, [rel .indices]
|
||||
vmovaps ymm1, [rel .flags]
|
||||
|
||||
hlt
|
||||
|
||||
align 32
|
||||
.data:
|
||||
dq 0x6550206F6FFF6C6C ; "ll" with junk following it
|
||||
dq 0x21212121656C706F
|
||||
dq 0xFFFFFFFFFFFFFFFF
|
||||
dq 0xEEEEEEEEEEEEEEEE
|
||||
|
||||
dq 0x2759206F6C6C6548 ; "Hello Y'"
|
||||
dq 0x21212121216C6C61 ; "all!!!!!"
|
||||
dq 0xDDDDDDDDDDDDDDDD
|
||||
dq 0xCCCCCCCCCCCCCCCC
|
||||
|
||||
.data16:
|
||||
dq 0x306F8A9E30443057 ; "しい" followed by junk
|
||||
dq 0x000030443057697D
|
||||
dq 0xAAAAAAAAAAAAAAAA
|
||||
dq 0xBBBBBBBBBBBBBBBB
|
||||
|
||||
dq 0x306F8A9E672C65E5 ; "日本語は"
|
||||
dq 0x00003044305796E3 ; "難しい\0" (Japanese is hard)
|
||||
dq 0x8888888888888888
|
||||
dq 0x9999999999999999
|
||||
|
||||
.indices:
|
||||
dq 0x0000000000000000
|
||||
dq 0x0000000000000000
|
||||
dq 0x0000000000000000
|
||||
dq 0x0000000000000000
|
||||
|
||||
.flags:
|
||||
dq 0x0000000000000000
|
||||
dq 0x0000000000000000
|
||||
dq 0x0000000000000000
|
||||
dq 0x0000000000000000
|
||||
@@ -0,0 +1,155 @@
|
||||
%ifdef CONFIG
|
||||
{
|
||||
"HostFeatures": ["AVX"],
|
||||
"RegData": {
|
||||
"RAX": ["4"],
|
||||
"RDX": ["16"],
|
||||
"XMM0": ["0x00060F000F000D01", "0x0000000000070007", "0x0000000000000000", "0x0000000000000000"],
|
||||
"XMM1": ["0x3111313131311111", "0x0000000000313131", "0x0000000000000000", "0x0000000000000000"],
|
||||
"XMM2": ["0x005A0041007A0061", "0x55AACCBBFF223344", "0xAAAAAAAAAAAAAAAA", "0xBBBBBBBBBBBBBBBB"],
|
||||
"XMM3": ["0x006500200027003F", "0x00210065004F0065", "0x8888888888888888", "0x9999999999999999"]
|
||||
}
|
||||
}
|
||||
%endif
|
||||
|
||||
; Adjusts the result from LAHF and SETO so that we have a set of flags organized
|
||||
; like [OF, SF, ZF, AF, PF, CF] for storing into the .flags region
|
||||
; of memory.
|
||||
;
|
||||
; The first parameter is the byte offset to store the flag result
|
||||
; at in the .flags region of memory.
|
||||
;
|
||||
%macro ArrangeAndStoreFLAGS 1
|
||||
lahf
|
||||
seto bl
|
||||
movzx bx, bl
|
||||
|
||||
shr ax, 8
|
||||
shl bx, 5
|
||||
|
||||
mov di, ax
|
||||
mov si, ax
|
||||
|
||||
; Mask and shift
|
||||
and di, 0b0000_0000_0000_0100 ; PF
|
||||
and si, 0b0000_0000_0001_0000 ; AF
|
||||
shr di, 1
|
||||
shr si, 2
|
||||
|
||||
; OR all of them together
|
||||
or bx, di
|
||||
or bx, si
|
||||
|
||||
; Reclaim DI for getting ZF/SF and shift into place
|
||||
mov di, ax
|
||||
and di, 0b0000_0000_1100_0000 ; ZF and SF
|
||||
shr di, 3
|
||||
|
||||
; Finally mask and OR all of the bits together
|
||||
and ax, 0b0000_0000_0000_0001 ; CF
|
||||
or bx, ax
|
||||
or bx, di
|
||||
|
||||
; Store result to .flags memory
|
||||
mov [rel .flags + %1], bl
|
||||
%endmacro
|
||||
|
||||
; Performs the string comparison and moves the result from RCX to
|
||||
; a region of memory in the .indices section specified by a byte
|
||||
; offset.
|
||||
;
|
||||
; The first parameter is the byte offset to store the RCX result to.
|
||||
; The second parameter is the control values to pass to vpcmpestri
|
||||
;
|
||||
%macro CompareAndStore 2
|
||||
vpcmpestri xmm2, xmm3, %2
|
||||
mov [rel .indices + %1], cl
|
||||
|
||||
mov r15, rax
|
||||
ArrangeAndStoreFLAGS %1
|
||||
mov rax, r15
|
||||
%endmacro
|
||||
|
||||
vmovaps ymm2, [rel .data]
|
||||
vmovaps ymm3, [rel .data + 32]
|
||||
|
||||
; Range unsigned byte check (lsb, positive polarity)
|
||||
mov rax, 4
|
||||
mov rdx, 16
|
||||
CompareAndStore 0, 0b00000100
|
||||
|
||||
; Range unsigned byte check (msb, positive polarity)
|
||||
CompareAndStore 1, 0b01000100
|
||||
|
||||
; Range unsigned byte check (lsb, negative polarity)
|
||||
CompareAndStore 2, 0b00010100
|
||||
|
||||
; Range unsigned byte check (msb, negative polarity)
|
||||
CompareAndStore 3, 0b01010100
|
||||
|
||||
; Range unsigned byte check (lsb, negative masked)
|
||||
CompareAndStore 4, 0b00110100
|
||||
|
||||
; Range unsigned byte check (msb, negative masked)
|
||||
CompareAndStore 5, 0b01110100
|
||||
|
||||
; --- 16-bit unsigned word tests ---
|
||||
; Intentionally don't reset RDX to 8 here to test upper bounds clamping.
|
||||
vmovaps ymm2, [rel .data16]
|
||||
vmovaps ymm3, [rel .data16 + 32]
|
||||
|
||||
; Range unsigned word check (msb, positive polarity)
|
||||
CompareAndStore 6, 0b01000101
|
||||
|
||||
; Range unsigned word check (lsb, negative polarity)
|
||||
CompareAndStore 7, 0b00010101
|
||||
|
||||
; Range unsigned word check (msb, negative polarity)
|
||||
CompareAndStore 8, 0b01010101
|
||||
|
||||
; Range unsigned word check (lsb, negative masked)
|
||||
CompareAndStore 9, 0b00110101
|
||||
|
||||
; Range unsigned word check (msb, negative masked)
|
||||
CompareAndStore 10, 0b01110101
|
||||
|
||||
; Load all our stored indices and flags for result comparing
|
||||
vmovaps ymm0, [rel .indices]
|
||||
vmovaps ymm1, [rel .flags]
|
||||
|
||||
hlt
|
||||
|
||||
align 32
|
||||
.data:
|
||||
dq 0x998877665A417A61 ; "azAZ" (followed by junk)
|
||||
dq 0x55AACCBBFF223344
|
||||
dq 0xFFFFFFFFFFFFFFFF
|
||||
dq 0xEEEEEEEEEEEEEEEE
|
||||
|
||||
dq 0x726548206D27493F ; "?I'm Her"
|
||||
dq 0x21216E65704F2065 ; "e Open!!"
|
||||
dq 0xFFFFFFFFFFFFFFFF
|
||||
dq 0xEEEEEEEEEEEEEEEE
|
||||
|
||||
.data16:
|
||||
dq 0x005A0041007A0061 ; "azAZ"
|
||||
dq 0x55AACCBBFF223344
|
||||
dq 0xAAAAAAAAAAAAAAAA
|
||||
dq 0xBBBBBBBBBBBBBBBB
|
||||
|
||||
dq 0x006500200027003F ; "?' e"
|
||||
dq 0x00210065004F0065 ; "eOen!"
|
||||
dq 0x8888888888888888
|
||||
dq 0x9999999999999999
|
||||
|
||||
.indices:
|
||||
dq 0x0000000000000000
|
||||
dq 0x0000000000000000
|
||||
dq 0x0000000000000000
|
||||
dq 0x0000000000000000
|
||||
|
||||
.flags:
|
||||
dq 0x0000000000000000
|
||||
dq 0x0000000000000000
|
||||
dq 0x0000000000000000
|
||||
dq 0x0000000000000000
|
||||
Reference in new issue
Block a user