aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMike Pall <mike>2011-05-09 18:09:29 +0200
committerMike Pall <mike>2011-05-09 18:09:29 +0200
commit28e87d33e931661e8118a25b293213938a9e0af4 (patch)
tree8177a3e7d463ed27bbb0e63f7a12a060d836029b /src
parentd9c1f771a7575510a9612e0a67be6c61d83de982 (diff)
downloadluajit-28e87d33e931661e8118a25b293213938a9e0af4.tar.gz
luajit-28e87d33e931661e8118a25b293213938a9e0af4.tar.bz2
luajit-28e87d33e931661e8118a25b293213938a9e0af4.zip
Use common helper functions for unaligned loads.
Diffstat (limited to 'src')
-rw-r--r--src/lj_def.h26
-rw-r--r--src/lj_opt_fold.c9
-rw-r--r--src/lj_str.c22
3 files changed, 34 insertions, 23 deletions
diff --git a/src/lj_def.h b/src/lj_def.h
index c60bc118..86f041a4 100644
--- a/src/lj_def.h
+++ b/src/lj_def.h
@@ -184,6 +184,28 @@ static LJ_AINLINE uint64_t lj_bswap64(uint64_t x)
184#error "missing define for lj_bswap()" 184#error "missing define for lj_bswap()"
185#endif 185#endif
186 186
187typedef union __attribute__((packed)) Unaligned16 {
188 uint16_t u;
189 uint8_t b[2];
190} Unaligned16;
191
192typedef union __attribute__((packed)) Unaligned32 {
193 uint32_t u;
194 uint8_t b[4];
195} Unaligned32;
196
197/* Unaligned load of uint16_t. */
198static LJ_AINLINE uint16_t lj_getu16(const void *p)
199{
200 return ((const Unaligned16 *)p)->u;
201}
202
203/* Unaligned load of uint32_t. */
204static LJ_AINLINE uint32_t lj_getu32(const void *p)
205{
206 return ((const Unaligned32 *)p)->u;
207}
208
187#elif defined(_MSC_VER) 209#elif defined(_MSC_VER)
188 210
189#define LJ_NORET __declspec(noreturn) 211#define LJ_NORET __declspec(noreturn)
@@ -208,6 +230,10 @@ static LJ_AINLINE uint32_t lj_fls(uint32_t x)
208#define lj_bswap(x) (_byteswap_ulong((x))) 230#define lj_bswap(x) (_byteswap_ulong((x)))
209#define lj_bswap64(x) (_byteswap_uint64((x))) 231#define lj_bswap64(x) (_byteswap_uint64((x)))
210 232
233/* MSVC is only supported on x86/x64, where unaligned loads are always ok. */
234#define lj_getu16(p) (*(uint16_t *)(p))
235#define lj_getu32(p) (*(uint32_t *)(p))
236
211#else 237#else
212#error "missing defines for your compiler" 238#error "missing defines for your compiler"
213#endif 239#endif
diff --git a/src/lj_opt_fold.c b/src/lj_opt_fold.c
index 48f2c40d..c8b4edfe 100644
--- a/src/lj_opt_fold.c
+++ b/src/lj_opt_fold.c
@@ -1647,16 +1647,13 @@ LJFOLDF(comm_bxor)
1647static TRef kfold_xload(jit_State *J, IRIns *ir, const void *p) 1647static TRef kfold_xload(jit_State *J, IRIns *ir, const void *p)
1648{ 1648{
1649 int32_t k; 1649 int32_t k;
1650#if !LJ_TARGET_X86ORX64
1651#error "Missing support for unaligned loads"
1652#endif
1653 switch (irt_type(ir->t)) { 1650 switch (irt_type(ir->t)) {
1654 case IRT_NUM: return lj_ir_knum_u64(J, *(uint64_t *)p); 1651 case IRT_NUM: return lj_ir_knum_u64(J, *(uint64_t *)p);
1655 case IRT_I8: k = (int32_t)*(int8_t *)p; break; 1652 case IRT_I8: k = (int32_t)*(int8_t *)p; break;
1656 case IRT_U8: k = (int32_t)*(uint8_t *)p; break; 1653 case IRT_U8: k = (int32_t)*(uint8_t *)p; break;
1657 case IRT_I16: k = (int32_t)*(int16_t *)p; break; 1654 case IRT_I16: k = (int32_t)(int16_t)lj_getu16(p); break;
1658 case IRT_U16: k = (int32_t)*(uint16_t *)p; break; 1655 case IRT_U16: k = (int32_t)(uint16_t)lj_getu16(p); break;
1659 case IRT_INT: case IRT_U32: k = *(int32_t *)p; break; 1656 case IRT_INT: case IRT_U32: k = (int32_t)lj_getu32(p); break;
1660 case IRT_I64: case IRT_U64: return lj_ir_kint64(J, *(uint64_t *)p); 1657 case IRT_I64: case IRT_U64: return lj_ir_kint64(J, *(uint64_t *)p);
1661 default: return 0; 1658 default: return 0;
1662 } 1659 }
diff --git a/src/lj_str.c b/src/lj_str.c
index 2b94d977..516acefe 100644
--- a/src/lj_str.c
+++ b/src/lj_str.c
@@ -43,18 +43,6 @@ int32_t LJ_FASTCALL lj_str_cmp(GCstr *a, GCstr *b)
43 return (int32_t)(a->len - b->len); 43 return (int32_t)(a->len - b->len);
44} 44}
45 45
46typedef union
47#ifdef __GNUC__
48__attribute__((packed))
49#endif
50Unaligned32 { uint32_t u; uint8_t b[4]; } Unaligned32;
51
52/* Unaligned read of uint32_t. */
53static LJ_AINLINE uint32_t str_getu32(const void *p)
54{
55 return ((const Unaligned32 *)p)->u;
56}
57
58/* Fast string data comparison. Caveat: unaligned access to 1st string! */ 46/* Fast string data comparison. Caveat: unaligned access to 1st string! */
59static LJ_AINLINE int str_fastcmp(const char *a, const char *b, MSize len) 47static LJ_AINLINE int str_fastcmp(const char *a, const char *b, MSize len)
60{ 48{
@@ -62,7 +50,7 @@ static LJ_AINLINE int str_fastcmp(const char *a, const char *b, MSize len)
62 lua_assert(len > 0); 50 lua_assert(len > 0);
63 lua_assert((((uintptr_t)a + len) & (LJ_PAGESIZE-1)) <= LJ_PAGESIZE-4); 51 lua_assert((((uintptr_t)a + len) & (LJ_PAGESIZE-1)) <= LJ_PAGESIZE-4);
64 do { /* Note: innocuous access up to end of string + 3. */ 52 do { /* Note: innocuous access up to end of string + 3. */
65 uint32_t v = str_getu32(a+i) ^ *(const uint32_t *)(b+i); 53 uint32_t v = lj_getu32(a+i) ^ *(const uint32_t *)(b+i);
66 if (v) { 54 if (v) {
67 i -= len; 55 i -= len;
68#if LJ_LE 56#if LJ_LE
@@ -115,11 +103,11 @@ GCstr *lj_str_new(lua_State *L, const char *str, size_t lenx)
115 g = G(L); 103 g = G(L);
116 /* Compute string hash. Constants taken from lookup3 hash by Bob Jenkins. */ 104 /* Compute string hash. Constants taken from lookup3 hash by Bob Jenkins. */
117 if (len >= 4) { /* Caveat: unaligned access! */ 105 if (len >= 4) { /* Caveat: unaligned access! */
118 a = str_getu32(str); 106 a = lj_getu32(str);
119 h ^= str_getu32(str+len-4); 107 h ^= lj_getu32(str+len-4);
120 b = str_getu32(str+(len>>1)-2); 108 b = lj_getu32(str+(len>>1)-2);
121 h ^= b; h -= lj_rol(b, 14); 109 h ^= b; h -= lj_rol(b, 14);
122 b += str_getu32(str+(len>>2)-1); 110 b += lj_getu32(str+(len>>2)-1);
123 } else if (len > 0) { 111 } else if (len > 0) {
124 a = *(const uint8_t *)str; 112 a = *(const uint8_t *)str;
125 h ^= *(const uint8_t *)(str+len-1); 113 h ^= *(const uint8_t *)(str+len-1);