[Forensics-changes] [yara] 56/415: String comparison implemented using SSE 4.2 intrinsics
Hilko Bengen
bengen at moszumanska.debian.org
Thu Apr 3 05:42:44 UTC 2014
This is an automated email from the git hooks/post-receive script.
bengen pushed a commit to branch debian
in repository yara.
commit aaf57e9ce8f657af6d78026742c87bfa0e57d321
Author: Victor M. Alvarez <plusvic at gmail.com>
Date: Fri Dec 25 13:34:59 2009 +0000
String comparison implemented using SSE 4.2 intrinsics
---
libyara/scan.c | 102 +++++++++++++++++++++++++++++++++++++++++----------------
1 file changed, 73 insertions(+), 29 deletions(-)
diff --git a/libyara/scan.c b/libyara/scan.c
index 92906a3..64edf0b 100644
--- a/libyara/scan.c
+++ b/libyara/scan.c
@@ -44,39 +44,81 @@ static char isalphanum[256];
/* Function implementations */
-#if defined(WIN32) && defined(SSE42)
+#ifdef SSE42
-int compare(char* str1, char* str2, int len)
+#include <nmmintrin.h>
+
+static char sdeltas[16] = {0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20};
+static char szeroes[16] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
+static char sranges[2] = {0x61, 0x7a};
+
+int inline compare(char* str1, char* str2, int len)
+{
+ __m128i s1, s2;
+
+ int c, result = 0;
+
+ do {
+
+ s1 = _mm_lddqu_si128((const __m128i*) str1);
+ s2 = _mm_lddqu_si128((const __m128i*) str2);
+
+ c = _mm_cmpestri(s1, len - result, s2, 16, _SIDD_CMP_EQUAL_EACH | _SIDD_MASKED_NEGATIVE_POLARITY);
+
+ str1 += 16;
+ str2 += 16;
+
+ result += c;
+
+ } while(c == 16);
+
+ return ((result==len) ? result : 0);
+}
+
+int inline icompare(char* str1, char* str2, int len)
{
- int result;
+ __m128i s1, s2, ranges, zeroes, deltas, mask;
- __asm
- {
- mov esi, str1
- mov edi, str2
- mov eax, len
-
- xor edx, edx
- xor ebx, ebx
-
- mov edx, 16
-
- _loop:
- MovDqU xmm0, [esi + ebx]
- PcmpEstrI xmm0, [edi + ebx], 111000b
- add ebx, ecx
- cmp ecx, 16
- jb _exit_loop
- sub eax, 16
- jmp _loop
-
- _exit_loop:
- mov result, ebx
- }
+ int c, result = 0;
- return result;
+ ranges = _mm_loadu_si128((const __m128i*) sranges);
+ deltas = _mm_loadu_si128((const __m128i*) sdeltas);
+ zeroes = _mm_loadu_si128((const __m128i*) szeroes);
+
+ do {
+
+ s1 = _mm_lddqu_si128((const __m128i*) str1);
+ s2 = _mm_lddqu_si128((const __m128i*) str2);
+
+ // producing mask, 0xFF for lowercases, 0x00 for the rest
+ mask = _mm_cmpestrm(ranges, 2, s1, len - result, _SIDD_CMP_RANGES | _SIDD_UNIT_MASK);
+
+ // producing mask, 0x20 for lowercases, 0x00 for the rest
+ mask = _mm_blendv_epi8(zeroes, deltas, mask);
+
+ s1 = _mm_sub_epi8(s1, mask);
+
+ // producing mask, 0xFF for lowercases, 0x00 for the rest
+ mask = _mm_cmpestrm(ranges, 2, s2, 16, _SIDD_CMP_RANGES | _SIDD_UNIT_MASK);
+
+ // producing mask, 0x20 for lowercases, 0x00 for the rest
+ mask = _mm_blendv_epi8(zeroes, deltas, mask);
+
+ s2 = _mm_sub_epi8(s2, mask);
+
+ c = _mm_cmpestri(s1, len - result, s2, 16, _SIDD_CMP_EQUAL_EACH | _SIDD_MASKED_NEGATIVE_POLARITY);
+
+ str1 += 16;
+ str2 += 16;
+
+ result += c;
+
+ } while(c == 16);
+
+ return ((result==len) ? result : 0);
}
+
#else
inline int compare(char* str1, char* str2, int len)
@@ -93,8 +135,6 @@ inline int compare(char* str1, char* str2, int len)
return ((i==len) ? i : 0);
}
-#endif
-
inline int icompare(char* str1, char* str2, int len)
{
char* s1 = str1;
@@ -109,6 +149,10 @@ inline int icompare(char* str1, char* str2, int len)
return ((i==len) ? i : 0);
}
+#endif
+
+
+
inline int wcompare(char* str1, char* str2, int len)
{
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/forensics/yara.git
More information about the forensics-changes
mailing list