Last active
September 2, 2023 09:21
-
-
Save RealNeGate/f15253c9da8f0661a00b84e8be83c57e to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdlib.h> | |
#include <stdio.h> | |
#include <stdint.h> | |
#include <string.h> | |
#include <x86intrin.h> | |
const char keywords[][16] = { | |
"alignof", | |
"auto", | |
"break", | |
"case", | |
"char", | |
"const", | |
"continue", | |
"default", | |
"do", | |
"double", | |
"else", | |
"enum", | |
"extern", | |
"float", | |
"for", | |
"goto", | |
"if", | |
"inline", | |
"int", | |
"long", | |
"register", | |
"restrict", | |
"return", | |
"short", | |
"signed", | |
"sizeof", | |
"static", | |
"struct", | |
"switch", | |
"typedef", | |
"union", | |
"unsigned", | |
"void", | |
"volatile", | |
"while", | |
"_Alignas", | |
"_Atomic", | |
"_Bool", | |
"_Complex", | |
"_Generic", | |
"_Imaginary", | |
"_Noreturn", | |
"_Static_assert", | |
"_Thread_local" | |
}; | |
typedef enum Keyword { | |
KW_alignof, | |
KW_auto, | |
KW_break, | |
KW_case, | |
KW_char, | |
KW_const, | |
KW_continue, | |
KW_default, | |
KW_do, | |
KW_double, | |
KW_else, | |
KW_enum, | |
KW_extern, | |
KW_float, | |
KW_for, | |
KW_goto, | |
KW_if, | |
KW_inline, | |
KW_int, | |
KW_long, | |
KW_register, | |
KW_restrict, | |
KW_return, | |
KW_short, | |
KW_signed, | |
KW_sizeof, | |
KW_static, | |
KW_struct, | |
KW_switch, | |
KW_typedef, | |
KW_union, | |
KW_unsigned, | |
KW_void, | |
KW_volatile, | |
KW_while, | |
KW_Alignas, | |
KW_Atomic, | |
KW_Bool, | |
KW_Complex, | |
KW_Generic, | |
KW_Imaginary, | |
KW_Noreturn, | |
KW_Static_assert, | |
KW_Thread_local, | |
KW_NONE | |
} Keyword; | |
static uint32_t fnv1a_len(const void* data, size_t len) { | |
const unsigned char* ptr = (const unsigned char*)data; | |
uint32_t hash = 0x811C9DC5; | |
size_t i = len; | |
while (i--) { | |
hash = ((*ptr++) ^ hash) * 0x01000193; | |
} | |
return hash; | |
} | |
Keyword get_token_as_keyword(const char* restrict str, size_t len) { | |
// BINARY SEARCH ARRAYS | |
const static uint32_t keys[64] = { | |
0x0C547726,0x0DC628CE,0x10D4792F,0x18338D5E,0x1D0E8DBE,0x221EDE24,0x2D6871C0,0x39386E06, | |
0x3974EFA7,0x48B5725F,0x505E61EF,0x621CD814,0x664FD1D4,0x6AA4A81B,0x6EE13AFD,0x816CB000, | |
0x85EE37BF,0x9087DDB7,0x923FA396,0x92C2BE20,0x933B5BDE,0x93E05F71,0x94E1036D,0x95E97E5E, | |
0x9B2538B1,0xA0EB0F08,0xA6C45D85,0xA84C031D,0xACF38390,0xAE76E4A2,0xB1727E44,0xB5712015, | |
0xBA226BD5,0xBDBF5BF0,0xC2CB5034,0xC2ECDF53,0xC919731F,0xC9648178,0xD290C23B,0xDBDED6F4, | |
0xE3F06707,0xF5A30FE6,0xFDD57AE5,0xFF2BDAB7,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF, | |
0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF, | |
0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF, | |
}; | |
const static uint8_t values[64] = { | |
31,34,39,38,43,29,20,16,41,32,42,8,5,35,25,11,22,12,1,27,7,28,33,18,3,9,13,4,14,37,6,24,23,10,17,19,0,2,26,30,40,15,21,36, | |
}; | |
// HASH STRING | |
uint32_t n = fnv1a_len(str, len); | |
// BRANCHLESS BINARY SEARCH | |
size_t i = 0; | |
i += (keys[i + 32] <= n) * 32; | |
i += (keys[i + 16] <= n) * 16; | |
i += (keys[i + 8] <= n) * 8; | |
i += (keys[i + 4] <= n) * 4; | |
i += (keys[i + 2] <= n) * 2; | |
i += (keys[i + 1] <= n) * 1; | |
size_t v = values[i]; | |
// VERIFY | |
__m128i kw128 = _mm_loadu_si128((__m128i*) &keywords[v]); | |
__m128i str128 = _mm_loadu_si128((__m128i*) str); | |
// NOTE(NeGate): Fancy x86 strcmp crap :) | |
int result = _mm_cmpestri(kw128, len, | |
str128, len, | |
_SIDD_UBYTE_OPS | | |
_SIDD_CMP_EQUAL_ANY | | |
_SIDD_NEGATIVE_POLARITY | | |
_SIDD_BIT_MASK); | |
return result ? KW_NONE : v; | |
} | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
get_token_as_keyword: # @get_token_as_keyword | |
mov rax, rsi | |
test rsi, rsi | |
je .LBB0_1 | |
lea rcx, [rax - 1] | |
mov r8d, eax | |
and r8d, 3 | |
cmp rcx, 3 | |
jae .LBB0_4 | |
mov r9d, -2128831035 | |
mov rsi, rdi | |
jmp .LBB0_6 | |
.LBB0_1: | |
mov r9d, -2128831035 | |
xor edx, edx | |
jmp .LBB0_10 | |
.LBB0_4: | |
mov rdx, rax | |
and rdx, -4 | |
mov r9d, -2128831035 | |
mov rsi, rdi | |
.LBB0_5: # =>This Inner Loop Header: Depth=1 | |
movzx ecx, byte ptr [rsi] | |
xor ecx, r9d | |
imul r9d, ecx, 16777619 | |
movzx ecx, byte ptr [rsi + 1] | |
xor ecx, r9d | |
imul r9d, ecx, 16777619 | |
movzx ecx, byte ptr [rsi + 2] | |
xor ecx, r9d | |
imul r9d, ecx, 16777619 | |
movzx ecx, byte ptr [rsi + 3] | |
add rsi, 4 | |
xor ecx, r9d | |
imul r9d, ecx, 16777619 | |
add rdx, -4 | |
jne .LBB0_5 | |
.LBB0_6: | |
test r8, r8 | |
je .LBB0_9 | |
xor edx, edx | |
.LBB0_8: # =>This Inner Loop Header: Depth=1 | |
movzx ecx, byte ptr [rsi + rdx] | |
xor ecx, r9d | |
imul r9d, ecx, 16777619 | |
inc rdx | |
cmp r8, rdx | |
jne .LBB0_8 | |
.LBB0_9: | |
xor edx, edx | |
cmp r9d, -1172149291 | |
setae dl | |
shl rdx, 5 | |
.LBB0_10: | |
lea rcx, [4*rdx] | |
or rcx, 64 | |
xor esi, esi | |
cmp dword ptr [rcx + get_token_as_keyword.keys], r9d | |
setbe sil | |
shl rsi, 4 | |
or rsi, rdx | |
lea rcx, [4*rsi] | |
or rcx, 32 | |
xor edx, edx | |
cmp dword ptr [rcx + get_token_as_keyword.keys], r9d | |
setbe dl | |
shl rdx, 3 | |
or rdx, rsi | |
lea rcx, [4*rdx] | |
or rcx, 16 | |
xor esi, esi | |
cmp dword ptr [rcx + get_token_as_keyword.keys], r9d | |
setbe sil | |
shl rsi, 2 | |
or rsi, rdx | |
lea rcx, [4*rsi] | |
or rcx, 8 | |
xor edx, edx | |
cmp dword ptr [rcx + get_token_as_keyword.keys], r9d | |
setbe dl | |
add rdx, rdx | |
or rdx, rsi | |
lea rcx, [4*rdx] | |
or rcx, 4 | |
xor esi, esi | |
cmp dword ptr [rcx + get_token_as_keyword.keys], r9d | |
setbe sil | |
or rsi, rdx | |
movzx esi, byte ptr [rsi + get_token_as_keyword.values] | |
mov rcx, rsi | |
shl rcx, 4 | |
movdqa xmm0, xmmword ptr [rcx + keywords] | |
mov edx, eax | |
pcmpestri xmm0, xmmword ptr [rdi], 16 | |
test ecx, ecx | |
mov eax, 44 | |
cmove eax, esi | |
ret |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment