forked from bellard/quickjs
-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathquickjs-aeshash.h
More file actions
122 lines (106 loc) · 3.96 KB
/
Copy pathquickjs-aeshash.h
File metadata and controls
122 lines (106 loc) · 3.96 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
#ifndef QUICKJS_AESHASH_H
#define QUICKJS_AESHASH_H
#include <immintrin.h>
#include <stdint.h>
static inline uint32_t
aeshash8(const uint8_t* s, size_t len, uint32_t h) {
__m128i H, S;
H = _mm_set_epi32(0, 0, 0, h);
/* aligned on 8-byte boundary */
if(((size_t)s & 0x07) == 0) {
while(len >= 8) {
/* load 8 bytes into lower half of vector register */
S = _mm_loadl_epi64((const __m128i*)s);
/* zero extend unsigned 8-bit integers to packed 16-bit integers */
S = _mm_cvtepu8_epi16(S);
H = _mm_aesenc_si128(S, H);
s += 8;
len -= 8;
}
} else {
while(len >= 8) {
/* unaligned load 8 bytes into lower half of vector register */
S = _mm_loadu_si64((const __m128i*)s);
/* zero extend unsigned 8-bit integers to packed 16-bit integers */
S = _mm_cvtepu8_epi16(S);
H = _mm_aesenc_si128(S, H);
s += 8;
len -= 8;
}
}
if(len > 0) {
switch(len) {
case 1: { S = _mm_set_epi16(0, 0, 0, 0, 0, 0, 0, s[0]); break; }
case 2: { S = _mm_set_epi16(0, 0, 0, 0, 0, 0, s[1], s[0]); break; }
case 3: { S = _mm_set_epi16(0, 0, 0, 0, 0, s[2], s[1], s[0]); break; }
case 4: { S = _mm_set_epi16(0, 0, 0, 0, s[3], s[2], s[1], s[0]); break; }
case 5: { S = _mm_set_epi16(0, 0, 0, s[4], s[3], s[2], s[1], s[0]); break; }
case 6: { S = _mm_set_epi16(0, 0, s[5], s[4], s[3], s[2], s[1], s[0]); break; }
case 7: { S = _mm_set_epi16(0, s[6], s[5], s[4], s[3], s[2], s[1], s[0]); break; }
}
H = _mm_aesenclast_si128(S, H);
}
// horizontally xor the 4 32-bit parts of the 128-bit register
return _mm_extract_epi32(H, 0) ^ _mm_extract_epi32(H, 1) ^ _mm_extract_epi32(H, 2) ^ _mm_extract_epi32(H, 3);
}
/*static inline uint32_t
aeshash8_alt(const uint8_t* s, size_t len, uint32_t h) {
__m128i H = _mm_set_epi32(0, 0, 0, h);
while(len >= 8) {
H = _mm_aesenc_si128(_mm_set_epi16(s[7], s[6], s[5], s[4], s[3], s[2], s[1], s[0]), H);
s += 8;
len -= 8;
}
if(len > 0) {
switch(len) {
case 1: { S = _mm_set_epi16(0, 0, 0, 0, 0, 0, 0, s[0]); break; }
case 2: { S = _mm_set_epi16(0, 0, 0, 0, 0, 0, s[1], s[0]); break; }
case 3: { S = _mm_set_epi16(0, 0, 0, 0, 0, s[2], s[1], s[0]); break; }
case 4: { S = _mm_set_epi16(0, 0, 0, 0, s[3], s[2], s[1], s[0]); break; }
case 5: { S = _mm_set_epi16(0, 0, 0, s[4], s[3], s[2], s[1], s[0]); break; }
case 6: { S = _mm_set_epi16(0, 0, s[5], s[4], s[3], s[2], s[1], s[0]); break; }
case 7: { S = _mm_set_epi16(0, s[6], s[5], s[4], s[3], s[2], s[1], s[0]); break; }
}
H = _mm_aesenclast_si128(S, H);
}
// horizontally xor the 4 32-bit parts of the 128-bit register
return _mm_extract_epi32(H, 0) ^ _mm_extract_epi32(H, 1) ^ _mm_extract_epi32(H, 2) ^ _mm_extract_epi32(H, 3);
}*/
static inline uint32_t
aeshash16(const uint16_t* s, size_t len, uint32_t h) {
__m128i H, S;
H = _mm_set_epi32(0, 0, 0, h);
/* aligned on 16-byte boundary */
if(((size_t)s & 0x0f) == 0) {
while(len >= 8) {
/* load 8 shorts into vector register */
S = _mm_load_si128((const __m128i*)s);
H = _mm_aesenc_si128(S, H);
s += 8;
len -= 8;
}
} else {
while(len >= 8) {
/* load 8 unaligned shorts into vector register */
S = _mm_lddqu_si128((const __m128i*)s);
H = _mm_aesenc_si128(S, H);
s += 8;
len -= 8;
}
}
if(len > 0) {
switch(len) {
case 1: { S = _mm_set_epi16(0, 0, 0, 0, 0, 0, 0, s[0]); break; }
case 2: { S = _mm_set_epi16(0, 0, 0, 0, 0, 0, s[1], s[0]); break; }
case 3: { S = _mm_set_epi16(0, 0, 0, 0, 0, s[2], s[1], s[0]); break; }
case 4: { S = _mm_set_epi16(0, 0, 0, 0, s[3], s[2], s[1], s[0]); break; }
case 5: { S = _mm_set_epi16(0, 0, 0, s[4], s[3], s[2], s[1], s[0]); break; }
case 6: { S = _mm_set_epi16(0, 0, s[5], s[4], s[3], s[2], s[1], s[0]); break; }
case 7: { S = _mm_set_epi16(0, s[6], s[5], s[4], s[3], s[2], s[1], s[0]); break; }
}
H = _mm_aesenclast_si128(S, H);
}
// horizontally xor the 4 32-bit parts of the 128-bit register
return _mm_extract_epi32(H, 0) ^ _mm_extract_epi32(H, 1) ^ _mm_extract_epi32(H, 2) ^ _mm_extract_epi32(H, 3);
}
#endif