aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMike Pall <mike>2026-07-28 00:44:24 +0200
committerMike Pall <mike>2026-07-28 00:44:24 +0200
commitfaaf663340347a78b22ed94c63c24fe090bd9784 (patch)
tree063c135292ca7cbbe872873eb77173bd59fd394e /src
parenta471ab78c7b670b4f92dae111fc3c96fb824c768 (diff)
downloadluajit-faaf663340347a78b22ed94c63c24fe090bd9784.tar.gz
luajit-faaf663340347a78b22ed94c63c24fe090bd9784.tar.bz2
luajit-faaf663340347a78b22ed94c63c24fe090bd9784.zip
x86: Conditionally use SSE3 for 64 bit conversions.
Reported by Gero Schwäricke. #1496 #1411
Diffstat (limited to 'src')
-rw-r--r--src/lib_jit.c6
-rw-r--r--src/lj_meta.c4
-rw-r--r--src/lj_obj.h21
-rw-r--r--src/lj_vmmath.c5
-rw-r--r--src/vm_x86.dasc46
5 files changed, 79 insertions, 3 deletions
diff --git a/src/lib_jit.c b/src/lib_jit.c
index e6c5271f8..6e01e374f 100644
--- a/src/lib_jit.c
+++ b/src/lib_jit.c
@@ -657,6 +657,12 @@ static uint32_t jit_cpudetect(void)
657 uint32_t features[4]; 657 uint32_t features[4];
658 if (lj_vm_cpuid(0, vendor) && lj_vm_cpuid(1, features)) { 658 if (lj_vm_cpuid(0, vendor) && lj_vm_cpuid(1, features)) {
659 flags |= ((features[2] >> 0)&1) * JIT_F_SSE3; 659 flags |= ((features[2] >> 0)&1) * JIT_F_SSE3;
660#if LJ_TARGET_X86
661 if (flags) {
662 lj_vm_num2i64_ptr = lj_vm_num2i64_sse3;
663 lj_vm_num2u64_ptr = lj_vm_num2u64_sse3;
664 }
665#endif
660 flags |= ((features[2] >> 19)&1) * JIT_F_SSE4_1; 666 flags |= ((features[2] >> 19)&1) * JIT_F_SSE4_1;
661 if (vendor[0] >= 7) { 667 if (vendor[0] >= 7) {
662 uint32_t xfeatures[4]; 668 uint32_t xfeatures[4];
diff --git a/src/lj_meta.c b/src/lj_meta.c
index ddb37a1a3..5a08cf947 100644
--- a/src/lj_meta.c
+++ b/src/lj_meta.c
@@ -248,10 +248,10 @@ void lj_meta_bitop(lua_State *L, TValue *ra, cTValue *rb, cTValue *rc, BCReg op)
248 uint64_t c = lj_carith_checkbit64(L, rc, op >= BC_BSHL ? &id_ignore : &id); 248 uint64_t c = lj_carith_checkbit64(L, rc, op >= BC_BSHL ? &id_ignore : &id);
249 if (id) { 249 if (id) {
250 if (tvisnum(rb)) { 250 if (tvisnum(rb)) {
251 b = id == CTID_UINT64 ? lj_num2u64(numV(rb)) : lj_num2i64(numV(rb)); 251 b = id == CTID_UINT64 ? lj_num2u64(numV(rb)) : (uint64_t)lj_num2i64(numV(rb));
252 } 252 }
253 if (tvisnum(rc)) { 253 if (tvisnum(rc)) {
254 c = id == CTID_UINT64 ? lj_num2u64(numV(rc)) : lj_num2i64(numV(rc)); 254 c = id == CTID_UINT64 ? lj_num2u64(numV(rc)) : (uint64_t)lj_num2i64(numV(rc));
255 } 255 }
256 } 256 }
257 switch (op) { 257 switch (op) {
diff --git a/src/lj_obj.h b/src/lj_obj.h
index 96dc1e0d0..30991a7e9 100644
--- a/src/lj_obj.h
+++ b/src/lj_obj.h
@@ -1035,11 +1035,30 @@ LJ_ASMF LJ_CONSTF int64_t lj_vm_num2int_check(double x);
1035** The uint64_t conversion accepts the union of the unsigned + signed range. 1035** The uint64_t conversion accepts the union of the unsigned + signed range.
1036*/ 1036*/
1037LJ_ASMF LJ_CONSTF int64_t lj_vm_num2i64(double x); 1037LJ_ASMF LJ_CONSTF int64_t lj_vm_num2i64(double x);
1038LJ_ASMF LJ_CONSTF int64_t lj_vm_num2u64(double x); 1038LJ_ASMF LJ_CONSTF uint64_t lj_vm_num2u64(double x);
1039
1040#if LJ_TARGET_X86
1041
1042LJ_ASMF LJ_CONSTF int64_t lj_vm_num2i64_sse3(double x);
1043LJ_ASMF LJ_CONSTF uint64_t lj_vm_num2u64_sse3(double x);
1044LJ_ASMF int64_t (*lj_vm_num2i64_ptr)(double x);
1045LJ_ASMF uint64_t (*lj_vm_num2u64_ptr)(double x);
1046static LJ_AINLINE int64_t lj_num2i64(double x)
1047{
1048 return (*lj_vm_num2i64_ptr)(x);
1049}
1050static LJ_AINLINE uint64_t lj_num2u64(double x)
1051{
1052 return (*lj_vm_num2u64_ptr)(x);
1053}
1054
1055#else
1039 1056
1040#define lj_num2i64(x) (lj_vm_num2i64((x))) 1057#define lj_num2i64(x) (lj_vm_num2i64((x)))
1041#define lj_num2u64(x) (lj_vm_num2u64((x))) 1058#define lj_num2u64(x) (lj_vm_num2u64((x)))
1042 1059
1060#endif
1061
1043/* Lua BitOp conversion semantics use the 2^52 + 2^51 trick. */ 1062/* Lua BitOp conversion semantics use the 2^52 + 2^51 trick. */
1044LJ_ASMF LJ_CONSTF int32_t lj_vm_tobit(double x); 1063LJ_ASMF LJ_CONSTF int32_t lj_vm_tobit(double x);
1045 1064
diff --git a/src/lj_vmmath.c b/src/lj_vmmath.c
index 5aca72071..603b913e6 100644
--- a/src/lj_vmmath.c
+++ b/src/lj_vmmath.c
@@ -13,6 +13,11 @@
13#include "lj_ir.h" 13#include "lj_ir.h"
14#include "lj_vm.h" 14#include "lj_vm.h"
15 15
16#if LJ_TARGET_X86
17int64_t (*lj_vm_num2i64_ptr)(double x) = lj_vm_num2i64;
18uint64_t (*lj_vm_num2u64_ptr)(double x) = lj_vm_num2u64;
19#endif
20
16/* -- Wrapper functions --------------------------------------------------- */ 21/* -- Wrapper functions --------------------------------------------------- */
17 22
18#if LJ_TARGET_X86 && __ELF__ && __PIC__ 23#if LJ_TARGET_X86 && __ELF__ && __PIC__
diff --git a/src/vm_x86.dasc b/src/vm_x86.dasc
index c201c3343..50becd460 100644
--- a/src/vm_x86.dasc
+++ b/src/vm_x86.dasc
@@ -3140,6 +3140,21 @@ static void build_subroutines(BuildCtx *ctx)
3140 |.else 3140 |.else
3141 | sub esp, 12 3141 | sub esp, 12
3142 | fld qword [esp+16] 3142 | fld qword [esp+16]
3143 | fnstcw word [esp+8]
3144 | mov eax, 0x0c00
3145 | or ax, word [esp+8]
3146 | mov word [esp+10], ax
3147 | fldcw word [esp+10]
3148 | fistp qword [esp]
3149 | fldcw word [esp+8]
3150 | mov eax, dword [esp]
3151 | mov edx, dword [esp+4]
3152 | add esp, 12
3153 | ret
3154 |
3155 |->vm_num2i64_sse3:
3156 | sub esp, 12
3157 | fld qword [esp+16]
3143 | fisttp qword [esp] 3158 | fisttp qword [esp]
3144 | mov eax, dword [esp] 3159 | mov eax, dword [esp]
3145 | mov edx, dword [esp+4] 3160 | mov edx, dword [esp+4]
@@ -3164,6 +3179,37 @@ static void build_subroutines(BuildCtx *ctx)
3164 |.else 3179 |.else
3165 | sub esp, 12 3180 | sub esp, 12
3166 | fld qword [esp+16] 3181 | fld qword [esp+16]
3182 | fnstcw word [esp+8]
3183 | mov eax, 0x0c00
3184 | or ax, word [esp+8]
3185 | mov word [esp+10], ax
3186 | fldcw word [esp+10]
3187 | fld st0
3188 | fistp qword [esp]
3189 | mov edx, dword [esp+4]
3190 | mov eax, dword [esp]
3191 | cmp edx, 1
3192 | jo >2
3193 |1:
3194 | fpop
3195 | fldcw word [esp+8]
3196 | add esp, 12
3197 | ret
3198 |2:
3199 | cmp eax, 0
3200 | jne <1
3201 | mov dword [esp], 0xdf800000 // -0x1p64 (float).
3202 | fadd dword [esp]
3203 | fistp qword [esp]
3204 | fldcw word [esp+8]
3205 | mov eax, dword [esp]
3206 | mov edx, dword [esp+4]
3207 | add esp, 12
3208 | ret
3209 |
3210 |->vm_num2u64_sse3:
3211 | sub esp, 12
3212 | fld qword [esp+16]
3167 | fld st0 3213 | fld st0
3168 | fisttp qword [esp] 3214 | fisttp qword [esp]
3169 | mov edx, dword [esp+4] 3215 | mov edx, dword [esp+4]