diff options
Diffstat (limited to '')
-rw-r--r-- | src/lib_jit.c | 65 |
1 files changed, 23 insertions, 42 deletions
diff --git a/src/lib_jit.c b/src/lib_jit.c index c97b0d53..acd6c293 100644 --- a/src/lib_jit.c +++ b/src/lib_jit.c | |||
@@ -104,8 +104,8 @@ LJLIB_CF(jit_status) | |||
104 | jit_State *J = L2J(L); | 104 | jit_State *J = L2J(L); |
105 | L->top = L->base; | 105 | L->top = L->base; |
106 | setboolV(L->top++, (J->flags & JIT_F_ON) ? 1 : 0); | 106 | setboolV(L->top++, (J->flags & JIT_F_ON) ? 1 : 0); |
107 | flagbits_to_strings(L, J->flags, JIT_F_CPU_FIRST, JIT_F_CPUSTRING); | 107 | flagbits_to_strings(L, J->flags, JIT_F_CPU, JIT_F_CPUSTRING); |
108 | flagbits_to_strings(L, J->flags, JIT_F_OPT_FIRST, JIT_F_OPTSTRING); | 108 | flagbits_to_strings(L, J->flags, JIT_F_OPT, JIT_F_OPTSTRING); |
109 | return (int)(L->top - L->base); | 109 | return (int)(L->top - L->base); |
110 | #else | 110 | #else |
111 | setboolV(L->top++, 0); | 111 | setboolV(L->top++, 0); |
@@ -471,7 +471,7 @@ static int jitopt_flag(jit_State *J, const char *str) | |||
471 | str += str[2] == '-' ? 3 : 2; | 471 | str += str[2] == '-' ? 3 : 2; |
472 | set = 0; | 472 | set = 0; |
473 | } | 473 | } |
474 | for (opt = JIT_F_OPT_FIRST; ; opt <<= 1) { | 474 | for (opt = JIT_F_OPT; ; opt <<= 1) { |
475 | size_t len = *(const uint8_t *)lst; | 475 | size_t len = *(const uint8_t *)lst; |
476 | if (len == 0) | 476 | if (len == 0) |
477 | break; | 477 | break; |
@@ -640,59 +640,41 @@ JIT_PARAMDEF(JIT_PARAMINIT) | |||
640 | #undef JIT_PARAMINIT | 640 | #undef JIT_PARAMINIT |
641 | 0 | 641 | 0 |
642 | }; | 642 | }; |
643 | #endif | ||
644 | 643 | ||
645 | #if LJ_TARGET_ARM && LJ_TARGET_LINUX | 644 | #if LJ_TARGET_ARM && LJ_TARGET_LINUX |
646 | #include <sys/utsname.h> | 645 | #include <sys/utsname.h> |
647 | #endif | 646 | #endif |
648 | 647 | ||
649 | /* Arch-dependent CPU detection. */ | 648 | /* Arch-dependent CPU feature detection. */ |
650 | static uint32_t jit_cpudetect(lua_State *L) | 649 | static uint32_t jit_cpudetect(void) |
651 | { | 650 | { |
652 | uint32_t flags = 0; | 651 | uint32_t flags = 0; |
653 | #if LJ_TARGET_X86ORX64 | 652 | #if LJ_TARGET_X86ORX64 |
653 | |||
654 | uint32_t vendor[4]; | 654 | uint32_t vendor[4]; |
655 | uint32_t features[4]; | 655 | uint32_t features[4]; |
656 | if (lj_vm_cpuid(0, vendor) && lj_vm_cpuid(1, features)) { | 656 | if (lj_vm_cpuid(0, vendor) && lj_vm_cpuid(1, features)) { |
657 | #if !LJ_HASJIT | ||
658 | #define JIT_F_SSE2 2 | ||
659 | #endif | ||
660 | flags |= ((features[3] >> 26)&1) * JIT_F_SSE2; | ||
661 | #if LJ_HASJIT | ||
662 | flags |= ((features[2] >> 0)&1) * JIT_F_SSE3; | 657 | flags |= ((features[2] >> 0)&1) * JIT_F_SSE3; |
663 | flags |= ((features[2] >> 19)&1) * JIT_F_SSE4_1; | 658 | flags |= ((features[2] >> 19)&1) * JIT_F_SSE4_1; |
664 | if (vendor[2] == 0x6c65746e) { /* Intel. */ | ||
665 | if ((features[0] & 0x0fff0ff0) == 0x000106c0) /* Atom. */ | ||
666 | flags |= JIT_F_LEA_AGU; | ||
667 | } else if (vendor[2] == 0x444d4163) { /* AMD. */ | ||
668 | uint32_t fam = (features[0] & 0x0ff00f00); | ||
669 | if (fam >= 0x00000f00) /* K8, K10. */ | ||
670 | flags |= JIT_F_PREFER_IMUL; | ||
671 | } | ||
672 | if (vendor[0] >= 7) { | 659 | if (vendor[0] >= 7) { |
673 | uint32_t xfeatures[4]; | 660 | uint32_t xfeatures[4]; |
674 | lj_vm_cpuid(7, xfeatures); | 661 | lj_vm_cpuid(7, xfeatures); |
675 | flags |= ((xfeatures[1] >> 8)&1) * JIT_F_BMI2; | 662 | flags |= ((xfeatures[1] >> 8)&1) * JIT_F_BMI2; |
676 | } | 663 | } |
677 | #endif | ||
678 | } | 664 | } |
679 | /* Check for required instruction set support on x86 (unnecessary on x64). */ | 665 | /* Don't bother checking for SSE2 -- the VM will crash before getting here. */ |
680 | #if LJ_TARGET_X86 | 666 | |
681 | if (!(flags & JIT_F_SSE2)) | ||
682 | luaL_error(L, "CPU with SSE2 required"); | ||
683 | #endif | ||
684 | #elif LJ_TARGET_ARM | 667 | #elif LJ_TARGET_ARM |
685 | #if LJ_HASJIT | 668 | |
686 | int ver = LJ_ARCH_VERSION; /* Compile-time ARM CPU detection. */ | 669 | int ver = LJ_ARCH_VERSION; /* Compile-time ARM CPU detection. */ |
687 | #if LJ_TARGET_LINUX | 670 | #if LJ_TARGET_LINUX |
688 | if (ver < 70) { /* Runtime ARM CPU detection. */ | 671 | if (ver < 70) { /* Runtime ARM CPU detection. */ |
689 | struct utsname ut; | 672 | struct utsname ut; |
690 | uname(&ut); | 673 | uname(&ut); |
691 | if (strncmp(ut.machine, "armv", 4) == 0) { | 674 | if (strncmp(ut.machine, "armv", 4) == 0) { |
692 | if (ut.machine[4] >= '7') | 675 | if (ut.machine[4] >= '8') ver = 80; |
693 | ver = 70; | 676 | else if (ut.machine[4] == '7') ver = 70; |
694 | else if (ut.machine[4] == '6') | 677 | else if (ut.machine[4] == '6') ver = 60; |
695 | ver = 60; | ||
696 | } | 678 | } |
697 | } | 679 | } |
698 | #endif | 680 | #endif |
@@ -700,20 +682,22 @@ static uint32_t jit_cpudetect(lua_State *L) | |||
700 | ver >= 61 ? JIT_F_ARMV6T2_ : | 682 | ver >= 61 ? JIT_F_ARMV6T2_ : |
701 | ver >= 60 ? JIT_F_ARMV6_ : 0; | 683 | ver >= 60 ? JIT_F_ARMV6_ : 0; |
702 | flags |= LJ_ARCH_HASFPU == 0 ? 0 : ver >= 70 ? JIT_F_VFPV3 : JIT_F_VFPV2; | 684 | flags |= LJ_ARCH_HASFPU == 0 ? 0 : ver >= 70 ? JIT_F_VFPV3 : JIT_F_VFPV2; |
703 | #endif | 685 | |
704 | #elif LJ_TARGET_ARM64 | 686 | #elif LJ_TARGET_ARM64 |
687 | |||
705 | /* No optional CPU features to detect (for now). */ | 688 | /* No optional CPU features to detect (for now). */ |
689 | |||
706 | #elif LJ_TARGET_PPC | 690 | #elif LJ_TARGET_PPC |
707 | #if LJ_HASJIT | 691 | |
708 | #if LJ_ARCH_SQRT | 692 | #if LJ_ARCH_SQRT |
709 | flags |= JIT_F_SQRT; | 693 | flags |= JIT_F_SQRT; |
710 | #endif | 694 | #endif |
711 | #if LJ_ARCH_ROUND | 695 | #if LJ_ARCH_ROUND |
712 | flags |= JIT_F_ROUND; | 696 | flags |= JIT_F_ROUND; |
713 | #endif | 697 | #endif |
714 | #endif | 698 | |
715 | #elif LJ_TARGET_MIPS | 699 | #elif LJ_TARGET_MIPS |
716 | #if LJ_HASJIT | 700 | |
717 | /* Compile-time MIPS CPU detection. */ | 701 | /* Compile-time MIPS CPU detection. */ |
718 | #if LJ_ARCH_VERSION >= 20 | 702 | #if LJ_ARCH_VERSION >= 20 |
719 | flags |= JIT_F_MIPSXXR2; | 703 | flags |= JIT_F_MIPSXXR2; |
@@ -731,31 +715,28 @@ static uint32_t jit_cpudetect(lua_State *L) | |||
731 | if (x) flags |= JIT_F_MIPSXXR2; /* Either 0x80000000 (R2) or 0 (R1). */ | 715 | if (x) flags |= JIT_F_MIPSXXR2; /* Either 0x80000000 (R2) or 0 (R1). */ |
732 | } | 716 | } |
733 | #endif | 717 | #endif |
734 | #endif | 718 | |
735 | #else | 719 | #else |
736 | #error "Missing CPU detection for this architecture" | 720 | #error "Missing CPU detection for this architecture" |
737 | #endif | 721 | #endif |
738 | UNUSED(L); | ||
739 | return flags; | 722 | return flags; |
740 | } | 723 | } |
741 | 724 | ||
742 | /* Initialize JIT compiler. */ | 725 | /* Initialize JIT compiler. */ |
743 | static void jit_init(lua_State *L) | 726 | static void jit_init(lua_State *L) |
744 | { | 727 | { |
745 | uint32_t flags = jit_cpudetect(L); | ||
746 | #if LJ_HASJIT | ||
747 | jit_State *J = L2J(L); | 728 | jit_State *J = L2J(L); |
748 | J->flags = flags | JIT_F_ON | JIT_F_OPT_DEFAULT; | 729 | J->flags = jit_cpudetect() | JIT_F_ON | JIT_F_OPT_DEFAULT; |
749 | memcpy(J->param, jit_param_default, sizeof(J->param)); | 730 | memcpy(J->param, jit_param_default, sizeof(J->param)); |
750 | lj_dispatch_update(G(L)); | 731 | lj_dispatch_update(G(L)); |
751 | #else | ||
752 | UNUSED(flags); | ||
753 | #endif | ||
754 | } | 732 | } |
733 | #endif | ||
755 | 734 | ||
756 | LUALIB_API int luaopen_jit(lua_State *L) | 735 | LUALIB_API int luaopen_jit(lua_State *L) |
757 | { | 736 | { |
737 | #if LJ_HASJIT | ||
758 | jit_init(L); | 738 | jit_init(L); |
739 | #endif | ||
759 | lua_pushliteral(L, LJ_OS_NAME); | 740 | lua_pushliteral(L, LJ_OS_NAME); |
760 | lua_pushliteral(L, LJ_ARCH_NAME); | 741 | lua_pushliteral(L, LJ_ARCH_NAME); |
761 | lua_pushinteger(L, LUAJIT_VERSION_NUM); | 742 | lua_pushinteger(L, LUAJIT_VERSION_NUM); |