]> git.ipfire.org Git - thirdparty/LuaJIT.git/commitdiff
x86: Conditionally use SSE3 for 64 bit conversions. v2.1
authorMike Pall <mike>
Mon, 27 Jul 2026 22:44:24 +0000 (00:44 +0200)
committerMike Pall <mike>
Mon, 27 Jul 2026 22:44:24 +0000 (00:44 +0200)
Reported by Gero Schwäricke. #1496 #1411

src/lib_jit.c
src/lj_meta.c
src/lj_obj.h
src/lj_vmmath.c
src/vm_x86.dasc

index e6c5271f8e5eb51bd6e3d792f7b7be0d0ebec086..6e01e374fe170231163926e10c02207fae6b5d7f 100644 (file)
@@ -657,6 +657,12 @@ static uint32_t jit_cpudetect(void)
   uint32_t features[4];
   if (lj_vm_cpuid(0, vendor) && lj_vm_cpuid(1, features)) {
     flags |= ((features[2] >> 0)&1) * JIT_F_SSE3;
+#if LJ_TARGET_X86
+    if (flags) {
+      lj_vm_num2i64_ptr = lj_vm_num2i64_sse3;
+      lj_vm_num2u64_ptr = lj_vm_num2u64_sse3;
+    }
+#endif
     flags |= ((features[2] >> 19)&1) * JIT_F_SSE4_1;
     if (vendor[0] >= 7) {
       uint32_t xfeatures[4];
index ddb37a1a3ee76499977a6dca24a4abf65121f1ca..5a08cf94712bf9b113f052a2215256feb181c3d7 100644 (file)
@@ -248,10 +248,10 @@ void lj_meta_bitop(lua_State *L, TValue *ra, cTValue *rb, cTValue *rc, BCReg op)
   uint64_t c = lj_carith_checkbit64(L, rc, op >= BC_BSHL ? &id_ignore : &id);
   if (id) {
     if (tvisnum(rb)) {
-      b = id == CTID_UINT64 ? lj_num2u64(numV(rb)) : lj_num2i64(numV(rb));
+      b = id == CTID_UINT64 ? lj_num2u64(numV(rb)) : (uint64_t)lj_num2i64(numV(rb));
     }
     if (tvisnum(rc)) {
-      c = id == CTID_UINT64 ? lj_num2u64(numV(rc)) : lj_num2i64(numV(rc));
+      c = id == CTID_UINT64 ? lj_num2u64(numV(rc)) : (uint64_t)lj_num2i64(numV(rc));
     }
   }
   switch (op) {
index 96dc1e0d07f957b5d2ef0003cc82cebc4acd473d..30991a7e9bf796e9706130162b0ec0ffbaf9e01a 100644 (file)
@@ -1035,11 +1035,30 @@ LJ_ASMF LJ_CONSTF int64_t lj_vm_num2int_check(double x);
 ** The uint64_t conversion accepts the union of the unsigned + signed range.
 */
 LJ_ASMF LJ_CONSTF int64_t lj_vm_num2i64(double x);
-LJ_ASMF LJ_CONSTF int64_t lj_vm_num2u64(double x);
+LJ_ASMF LJ_CONSTF uint64_t lj_vm_num2u64(double x);
+
+#if LJ_TARGET_X86
+
+LJ_ASMF LJ_CONSTF int64_t lj_vm_num2i64_sse3(double x);
+LJ_ASMF LJ_CONSTF uint64_t lj_vm_num2u64_sse3(double x);
+LJ_ASMF int64_t (*lj_vm_num2i64_ptr)(double x);
+LJ_ASMF uint64_t (*lj_vm_num2u64_ptr)(double x);
+static LJ_AINLINE int64_t lj_num2i64(double x)
+{
+  return (*lj_vm_num2i64_ptr)(x);
+}
+static LJ_AINLINE uint64_t lj_num2u64(double x)
+{
+  return (*lj_vm_num2u64_ptr)(x);
+}
+
+#else
 
 #define lj_num2i64(x)          (lj_vm_num2i64((x)))
 #define lj_num2u64(x)          (lj_vm_num2u64((x)))
 
+#endif
+
 /* Lua BitOp conversion semantics use the 2^52 + 2^51 trick. */
 LJ_ASMF LJ_CONSTF int32_t lj_vm_tobit(double x);
 
index 5aca720713ce103fde97d0a8ad28b11870440cc3..603b913e67f478560ed62ef3bc2fcddbeee2afb2 100644 (file)
 #include "lj_ir.h"
 #include "lj_vm.h"
 
+#if LJ_TARGET_X86
+int64_t (*lj_vm_num2i64_ptr)(double x) = lj_vm_num2i64;
+uint64_t (*lj_vm_num2u64_ptr)(double x) = lj_vm_num2u64;
+#endif
+
 /* -- Wrapper functions --------------------------------------------------- */
 
 #if LJ_TARGET_X86 && __ELF__ && __PIC__
index c201c3343b61af80e0f188b437348c41eabe3c4a..50becd4609c9320f0f863c10ba05383046bc71fd 100644 (file)
@@ -3140,6 +3140,21 @@ static void build_subroutines(BuildCtx *ctx)
   |.else
   |  sub esp, 12
   |  fld qword [esp+16]
+  |   fnstcw word [esp+8]
+  |   mov eax, 0x0c00
+  |   or ax, word [esp+8]
+  |   mov word [esp+10], ax
+  |   fldcw word [esp+10]
+  |  fistp qword [esp]
+  |   fldcw word [esp+8]
+  |  mov eax, dword [esp]
+  |  mov edx, dword [esp+4]
+  |  add esp, 12
+  |  ret
+  |
+  |->vm_num2i64_sse3:
+  |  sub esp, 12
+  |  fld qword [esp+16]
   |  fisttp qword [esp]
   |  mov eax, dword [esp]
   |  mov edx, dword [esp+4]
@@ -3164,6 +3179,37 @@ static void build_subroutines(BuildCtx *ctx)
   |.else
   |  sub esp, 12
   |  fld qword [esp+16]
+  |   fnstcw word [esp+8]
+  |   mov eax, 0x0c00
+  |   or ax, word [esp+8]
+  |   mov word [esp+10], ax
+  |   fldcw word [esp+10]
+  |  fld st0
+  |  fistp qword [esp]
+  |  mov edx, dword [esp+4]
+  |  mov eax, dword [esp]
+  |  cmp edx, 1
+  |  jo >2
+  |1:
+  |  fpop
+  |   fldcw word [esp+8]
+  |  add esp, 12
+  |  ret
+  |2:
+  |  cmp eax, 0
+  |  jne <1
+  |  mov dword [esp], 0xdf800000       // -0x1p64 (float).
+  |  fadd dword [esp]
+  |  fistp qword [esp]
+  |   fldcw word [esp+8]
+  |  mov eax, dword [esp]
+  |  mov edx, dword [esp+4]
+  |  add esp, 12
+  |  ret
+  |
+  |->vm_num2u64_sse3:
+  |  sub esp, 12
+  |  fld qword [esp+16]
   |  fld st0
   |  fisttp qword [esp]
   |  mov edx, dword [esp+4]