diff options
| author | Mike Pall <mike> | 2011-05-09 18:09:29 +0200 |
|---|---|---|
| committer | Mike Pall <mike> | 2011-05-09 18:09:29 +0200 |
| commit | 28e87d33e931661e8118a25b293213938a9e0af4 (patch) | |
| tree | 8177a3e7d463ed27bbb0e63f7a12a060d836029b /src | |
| parent | d9c1f771a7575510a9612e0a67be6c61d83de982 (diff) | |
| download | luajit-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.h | 26 | ||||
| -rw-r--r-- | src/lj_opt_fold.c | 9 | ||||
| -rw-r--r-- | src/lj_str.c | 22 |
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 | ||
| 187 | typedef union __attribute__((packed)) Unaligned16 { | ||
| 188 | uint16_t u; | ||
| 189 | uint8_t b[2]; | ||
| 190 | } Unaligned16; | ||
| 191 | |||
| 192 | typedef union __attribute__((packed)) Unaligned32 { | ||
| 193 | uint32_t u; | ||
| 194 | uint8_t b[4]; | ||
| 195 | } Unaligned32; | ||
| 196 | |||
| 197 | /* Unaligned load of uint16_t. */ | ||
| 198 | static LJ_AINLINE uint16_t lj_getu16(const void *p) | ||
| 199 | { | ||
| 200 | return ((const Unaligned16 *)p)->u; | ||
| 201 | } | ||
| 202 | |||
| 203 | /* Unaligned load of uint32_t. */ | ||
| 204 | static 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) | |||
| 1647 | static TRef kfold_xload(jit_State *J, IRIns *ir, const void *p) | 1647 | static 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 | ||
| 46 | typedef union | ||
| 47 | #ifdef __GNUC__ | ||
| 48 | __attribute__((packed)) | ||
| 49 | #endif | ||
| 50 | Unaligned32 { uint32_t u; uint8_t b[4]; } Unaligned32; | ||
| 51 | |||
| 52 | /* Unaligned read of uint32_t. */ | ||
| 53 | static 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! */ |
| 59 | static LJ_AINLINE int str_fastcmp(const char *a, const char *b, MSize len) | 47 | static 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); |
