diff options
| author | Mike Pall <mike> | 2020-05-20 20:42:04 +0200 |
|---|---|---|
| committer | Mike Pall <mike> | 2020-05-20 20:42:04 +0200 |
| commit | 0eddcbead2d67c16dcd4039a6765b9d2fc8ea631 (patch) | |
| tree | 614b63b87bb6ba476b616b10b95e278d4af0c452 /src/lib_jit.c | |
| parent | 5bf0da3d7c02f9959fa3a9fb721e0565137b70c8 (diff) | |
| download | luajit-0eddcbead2d67c16dcd4039a6765b9d2fc8ea631.tar.gz luajit-0eddcbead2d67c16dcd4039a6765b9d2fc8ea631.tar.bz2 luajit-0eddcbead2d67c16dcd4039a6765b9d2fc8ea631.zip | |
Cleanup CPU detection and tuning for old CPUs.
Diffstat (limited to 'src/lib_jit.c')
| -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 c97b0d531..acd6c293b 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); |
