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];
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) {
** 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);
#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__
|.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]
|.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]