pull/11725/merge
AGSaidi 12 hours ago committed by GitHub
commit a97090c0aa
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -901,6 +901,12 @@ static void PrintBuildInfo(void)
#endif
#if defined(__SSE2__)
strlcat(features, "SSE_2 ", sizeof(features));
#endif
#if defined(__ARM_FEATURE_SVE)
strlcat(features, "SVE ", sizeof(features));
#endif
#if defined(__ARM_NEON)
strlcat(features, "NEON ", sizeof(features));
#endif
if (strlen(features) == 0) {
strlcat(features, "none", sizeof(features));

@ -34,102 +34,134 @@
static int MemcmpTest01 (void)
{
uint8_t a[] = "abcd";
uint8_t b[] = "abcd";
uint8_t a[] = "abcd abcd";
uint8_t b[] = "abcd abcd";
for (size_t x = 1; x < sizeof(a); x++) {
FAIL_IF(SCMemcmp(a, b, sizeof(a) - 1) != 0);
}
FAIL_IF(SCMemcmp(a, b, sizeof(a) - 1) != 0);
PASS;
}
static int MemcmpTest02 (void)
{
uint8_t a[] = "abcdabcdabcdabcd";
uint8_t b[] = "abcdabcdabcdabcd";
uint8_t a[] = "abcdabcdabcdabcd ";
uint8_t b[] = "abcdabcdabcdabcd ";
for (size_t x = 1; x < sizeof(a); x++) {
FAIL_IF(SCMemcmp(a, b, sizeof(a) - 1) != 0);
}
FAIL_IF(SCMemcmp(a, b, sizeof(a) - 1) != 0);
PASS;
}
static int MemcmpTest03 (void)
{
uint8_t a[] = "abcdabcd";
uint8_t b[] = "abcdabcd";
uint8_t a[] = "abcdabcd ";
uint8_t b[] = "abcdabcd ";
for (size_t x = 1; x < sizeof(a); x++) {
FAIL_IF(SCMemcmp(a, b, sizeof(a) - 1) != 0);
}
FAIL_IF(SCMemcmp(a, b, sizeof(a) - 1) != 0);
PASS;
}
static int MemcmpTest04 (void)
{
uint8_t a[] = "abcd";
uint8_t b[] = "abcD";
uint8_t a[] = "abcd ";
uint8_t b[] = "abcD ";
int r = SCMemcmp(a, b, sizeof(a)-1);
FAIL_IF(r != 1);
for (size_t x = 4; x < sizeof(a); x++) {
int r = SCMemcmp(a, b, x);
FAIL_IF(r != 1);
}
PASS;
}
static int MemcmpTest05 (void)
{
uint8_t a[] = "abcdabcdabcdabcd";
uint8_t b[] = "abcDabcdabcdabcd";
uint8_t a[] = "abcdabcdabcdabcd ";
uint8_t b[] = "abcDabcdabcdabcd ";
for (size_t x = 4; x < sizeof(a); x++) {
FAIL_IF(SCMemcmp(a, b, sizeof(a) - 1) != 1);
}
FAIL_IF(SCMemcmp(a, b, sizeof(a) - 1) != 1);
PASS;
}
static int MemcmpTest06 (void)
{
uint8_t a[] = "abcdabcd";
uint8_t b[] = "abcDabcd";
uint8_t a[] = "abcdabcd ";
uint8_t b[] = "abcDabcd ";
for (size_t x = 4; x < sizeof(a); x++) {
FAIL_IF(SCMemcmp(a, b, sizeof(a) - 1) != 1);
}
FAIL_IF(SCMemcmp(a, b, sizeof(a) - 1) != 1);
PASS;
}
static int MemcmpTest07 (void)
{
uint8_t a[] = "abcd";
uint8_t b[] = "abcde";
uint8_t a[] = " abcd";
uint8_t b[] = " abcde";
for (size_t x = 1; x < sizeof(a); x++) {
FAIL_IF(SCMemcmp(a, b, sizeof(a) - 1) != 0);
}
FAIL_IF(SCMemcmp(a, b, sizeof(a) - 1) != 0);
PASS;
}
static int MemcmpTest08 (void)
{
uint8_t a[] = "abcdabcdabcdabcd";
uint8_t b[] = "abcdabcdabcdabcde";
uint8_t a[] = " zyxvabcdabcdabcdabcd";
uint8_t b[] = " zyxvabcdabcdabcdabcde";
for (size_t x = 1; x < sizeof(a); x++) {
FAIL_IF(SCMemcmp(a, b, sizeof(a) - 1) != 0);
}
FAIL_IF(SCMemcmp(a, b, sizeof(a) - 1) != 0);
PASS;
}
static int MemcmpTest09 (void)
{
uint8_t a[] = "abcdabcd";
uint8_t b[] = "abcdabcde";
uint8_t a[] = " abcdabcd";
uint8_t b[] = " abcdabcde";
for (size_t x = 1; x < sizeof(a); x++) {
FAIL_IF(SCMemcmp(a, b, sizeof(a) - 1) != 0);
}
FAIL_IF(SCMemcmp(a, b, sizeof(a) - 1) != 0);
PASS;
}
static int MemcmpTest10 (void)
{
uint8_t a[] = "abcd";
uint8_t b[] = "Zbcde";
uint8_t a[] = "abcd ";
uint8_t b[] = "Zbcde ";
for (size_t x = 1; x < sizeof(a); x++) {
FAIL_IF(SCMemcmp(a, b, sizeof(a) - 1) != 1);
}
FAIL_IF(SCMemcmp(a, b, sizeof(a) - 1) != 1);
PASS;
}
static int MemcmpTest11 (void)
{
uint8_t a[] = "abcdabcdabcdabcd";
uint8_t b[] = "Zbcdabcdabcdabcde";
uint8_t a[] = "abcdabcdabcdabcd ";
uint8_t b[] = "Zbcdabcdabcdabcde ";
for (size_t x = 1; x < sizeof(a); x++) {
FAIL_IF(SCMemcmp(a, b, sizeof(a) - 1) != 1);
}
FAIL_IF(SCMemcmp(a, b, sizeof(a) - 1) != 1);
PASS;
}
@ -144,10 +176,13 @@ static int MemcmpTest12 (void)
static int MemcmpTest13 (void)
{
uint8_t a[] = "abcdefgh";
uint8_t b[] = "AbCdEfGhIjK";
uint8_t a[] = " abcdefgh";
uint8_t b[] = " AbCdEfGhIjK";
for (size_t x = 1; x < sizeof(a); x++) {
FAIL_IF(SCMemcmpLowercase(a, b, sizeof(a) - 1) != 0);
}
FAIL_IF(SCMemcmpLowercase(a, b, sizeof(a) - 1) != 0);
PASS;
}
@ -311,25 +346,142 @@ struct MemcmpTest18Tests {
const char *b;
int result;
} memcmp_tests18_tests[] = {
{ "abcdefgh", "!bcdefgh", 1, },
{ "?bcdefgh", "!bcdefgh", 1, },
{ "!bcdefgh", "abcdefgh", 1, },
{ "!bcdefgh", "?bcdefgh", 1, },
{ "zbcdefgh", "bbcdefgh", 1, },
{ "abcdefgh12345678", "!bcdefgh12345678", 1, },
{ "?bcdefgh12345678", "!bcdefgh12345678", 1, },
{ "!bcdefgh12345678", "abcdefgh12345678", 1, },
{ "!bcdefgh12345678", "?bcdefgh12345678", 1, },
{ "bbcdefgh12345678", "zbcdefgh12345678", 1, },
{ "abcdefgh", "abcdefgh", 0, },
{ "abcdefgh", "Abcdefgh", 0, },
{ "abcdefgh12345678", "Abcdefgh12345678", 0, },
{ NULL, NULL, 0 },
};
{
"abcdefgh",
"!bcdefgh",
1,
},
{
"?bcdefgh",
"!bcdefgh",
1,
},
{
"!bcdefgh",
"abcdefgh",
1,
},
{
"!bcdefgh",
"?bcdefgh",
1,
},
{
"zbcdefgh",
"bbcdefgh",
1,
},
{
"abcdefgh ",
"!bcdefgh ",
1,
},
{
"?bcdefgh ",
"!bcdefgh ",
1,
},
{
"!bcdefgh ",
"abcdefgh ",
1,
},
{
"!bcdefgh ",
"?bcdefgh ",
1,
},
{
"zbcdefgh ",
"bbcdefgh ",
1,
},
{
"abcdefgh12345678",
"!bcdefgh12345678",
1,
},
{
"?bcdefgh12345678",
"!bcdefgh12345678",
1,
},
{
"!bcdefgh12345678",
"abcdefgh12345678",
1,
},
{
"!bcdefgh12345678",
"?bcdefgh12345678",
1,
},
{
"bbcdefgh12345678",
"zbcdefgh12345678",
1,
},
{
"abcdefgh",
"abcdefgh",
0,
},
{
"abcdefgh",
"Abcdefgh",
0,
},
{
"abcdefgh ",
"abcdefgh ",
0,
},
{
"abcdefgh ",
"Abcdefgh ",
0,
},
{
"abcdefgh12345678",
"Abcdefgh12345678",
0,
},
{
"abcdefgz12345678",
"AbcdefgZ12345678",
0,
},
{
"abcdefgz[@@45678aa",
"AbcdefgZ[@@45678AA",
0,
},
{
"abcdefgz12345678",
"abcdefgz12345678",
0,
},
{
"abcdefgz12345678",
"Xbcdefgz12345678",
1,
},
{
"abcdefgz12345678",
"abcdefgzX2345678",
1,
},
{
"abcdefgz12345678",
"abcdXfgz1234X678",
1,
},
{ NULL, NULL, 0 },
};
static int MemcmpTest18 (void)
{

@ -281,6 +281,94 @@ static inline int SCMemcmpLowercase(const void *s1, const void *s2, size_t len)
return 0;
}
#elif defined(__aarch64__)
#include <arm_neon.h>
#if defined(__ARM_FEATURE_SVE)
#include <arm_sve.h>
static inline int SCMemcmp(const void *s1, const void *s2, size_t len)
{
uint64_t i = 0;
int vec_size = svcntb();
svbool_t pg = svwhilelt_b8(i, len);
do {
svuint8_t b1 = svld1(pg, (uint8_t *)s1 + i);
svuint8_t b2 = svld1(pg, (uint8_t *)s2 + i);
svbool_t match = svcmpne(pg, b1, b2);
if (svptest_any(pg, match))
return 1;
i += vec_size;
pg = svwhilelt_b8(i, len);
} while (svptest_any(svptrue_b64(), pg));
return 0;
}
#else
/* wrapper around memcmp to match the retvals of the SIMD implementations */
#define SCMemcmp(a, b, c) ({ memcmp((a), (b), (c)) ? 1 : 0; })
#endif
#define SCMEMCMP_BYTES 16
#define UPPER_LOW 0x41 /* "A" */
#define UPPER_HIGH 0x5A /* "Z" */
#define UPPER_DELTA 0x20
static inline int SCMemcmpLowercase(const void *s1, const void *s2, size_t len)
{
size_t offset = 0;
uint8x16_t b1, mask1, mask2, delta, b3, equiv;
uint8x16_t b2, upper1, upper2;
uint64_t eqt, eqb;
/* setup registers for upper to lower conversion */
upper1 = vdupq_n_u8(UPPER_LOW);
upper2 = vdupq_n_u8(UPPER_HIGH);
delta = vdupq_n_u8(UPPER_DELTA);
do {
if (likely(len - offset < SCMEMCMP_BYTES)) {
return MemcmpLowercase(s1, s2, len - offset);
}
/* unaligned loading of the bytes to compare */
b1 = vld1q_u8(s1);
b2 = vld1q_u8(s2);
/* mark all chars bigger than upper1 */
mask1 = vcgeq_u8(b2, upper1);
/* mark all chars lower than upper2 */
mask2 = vcleq_u8(b2, upper2);
/* merge the two, leaving only those that are true in both */
mask1 = vandq_u8(mask1, mask2);
/* Generate only 0x20 which is the delta from a upper-case to lower-case */
mask1 = vandq_u8(mask1, delta);
/* add 0x20 to each upper case value */
b3 = vaddq_u8(b2, mask1);
/* do the actual compare */
equiv = vceqq_u8(b1, b3);
/* move the values to a GP */
eqb = vgetq_lane_u64(vreinterpretq_u64_u8(equiv), 0);
eqt = vgetq_lane_u64(vreinterpretq_u64_u8(equiv), 1);
if (!(~eqb == 0 && ~eqt == 0)) {
return 1;
}
offset += SCMEMCMP_BYTES;
s1 += SCMEMCMP_BYTES;
s2 += SCMEMCMP_BYTES;
} while (len > offset);
return 0;
}
#else
/* No SIMD support, fall back to plain memcmp and a home grown lowercase one */

Loading…
Cancel
Save