Cleanup CPU detection and tuning for old CPUs.

This commit is contained in:
Mike Pall
2020-05-20 20:42:04 +02:00
parent 5bf0da3d7c
commit 0eddcbead2
9 changed files with 86 additions and 137 deletions

View File

@@ -104,8 +104,8 @@ LJLIB_CF(jit_status)
jit_State *J = L2J(L);
L->top = L->base;
setboolV(L->top++, (J->flags & JIT_F_ON) ? 1 : 0);
flagbits_to_strings(L, J->flags, JIT_F_CPU_FIRST, JIT_F_CPUSTRING);
flagbits_to_strings(L, J->flags, JIT_F_OPT_FIRST, JIT_F_OPTSTRING);
flagbits_to_strings(L, J->flags, JIT_F_CPU, JIT_F_CPUSTRING);
flagbits_to_strings(L, J->flags, JIT_F_OPT, JIT_F_OPTSTRING);
return (int)(L->top - L->base);
#else
setboolV(L->top++, 0);
@@ -471,7 +471,7 @@ static int jitopt_flag(jit_State *J, const char *str)
str += str[2] == '-' ? 3 : 2;
set = 0;
}
for (opt = JIT_F_OPT_FIRST; ; opt <<= 1) {
for (opt = JIT_F_OPT; ; opt <<= 1) {
size_t len = *(const uint8_t *)lst;
if (len == 0)
break;
@@ -640,59 +640,41 @@ JIT_PARAMDEF(JIT_PARAMINIT)
#undef JIT_PARAMINIT
0
};
#endif
#if LJ_TARGET_ARM && LJ_TARGET_LINUX
#include <sys/utsname.h>
#endif
/* Arch-dependent CPU detection. */
static uint32_t jit_cpudetect(lua_State *L)
/* Arch-dependent CPU feature detection. */
static uint32_t jit_cpudetect(void)
{
uint32_t flags = 0;
#if LJ_TARGET_X86ORX64
uint32_t vendor[4];
uint32_t features[4];
if (lj_vm_cpuid(0, vendor) && lj_vm_cpuid(1, features)) {
#if !LJ_HASJIT
#define JIT_F_SSE2 2
#endif
flags |= ((features[3] >> 26)&1) * JIT_F_SSE2;
#if LJ_HASJIT
flags |= ((features[2] >> 0)&1) * JIT_F_SSE3;
flags |= ((features[2] >> 19)&1) * JIT_F_SSE4_1;
if (vendor[2] == 0x6c65746e) { /* Intel. */
if ((features[0] & 0x0fff0ff0) == 0x000106c0) /* Atom. */
flags |= JIT_F_LEA_AGU;
} else if (vendor[2] == 0x444d4163) { /* AMD. */
uint32_t fam = (features[0] & 0x0ff00f00);
if (fam >= 0x00000f00) /* K8, K10. */
flags |= JIT_F_PREFER_IMUL;
}
if (vendor[0] >= 7) {
uint32_t xfeatures[4];
lj_vm_cpuid(7, xfeatures);
flags |= ((xfeatures[1] >> 8)&1) * JIT_F_BMI2;
}
#endif
}
/* Check for required instruction set support on x86 (unnecessary on x64). */
#if LJ_TARGET_X86
if (!(flags & JIT_F_SSE2))
luaL_error(L, "CPU with SSE2 required");
#endif
/* Don't bother checking for SSE2 -- the VM will crash before getting here. */
#elif LJ_TARGET_ARM
#if LJ_HASJIT
int ver = LJ_ARCH_VERSION; /* Compile-time ARM CPU detection. */
#if LJ_TARGET_LINUX
if (ver < 70) { /* Runtime ARM CPU detection. */
struct utsname ut;
uname(&ut);
if (strncmp(ut.machine, "armv", 4) == 0) {
if (ut.machine[4] >= '7')
ver = 70;
else if (ut.machine[4] == '6')
ver = 60;
if (ut.machine[4] >= '8') ver = 80;
else if (ut.machine[4] == '7') ver = 70;
else if (ut.machine[4] == '6') ver = 60;
}
}
#endif
@@ -700,20 +682,22 @@ static uint32_t jit_cpudetect(lua_State *L)
ver >= 61 ? JIT_F_ARMV6T2_ :
ver >= 60 ? JIT_F_ARMV6_ : 0;
flags |= LJ_ARCH_HASFPU == 0 ? 0 : ver >= 70 ? JIT_F_VFPV3 : JIT_F_VFPV2;
#endif
#elif LJ_TARGET_ARM64
/* No optional CPU features to detect (for now). */
#elif LJ_TARGET_PPC
#if LJ_HASJIT
#if LJ_ARCH_SQRT
flags |= JIT_F_SQRT;
#endif
#if LJ_ARCH_ROUND
flags |= JIT_F_ROUND;
#endif
#endif
#elif LJ_TARGET_MIPS
#if LJ_HASJIT
/* Compile-time MIPS CPU detection. */
#if LJ_ARCH_VERSION >= 20
flags |= JIT_F_MIPSXXR2;
@@ -731,31 +715,28 @@ static uint32_t jit_cpudetect(lua_State *L)
if (x) flags |= JIT_F_MIPSXXR2; /* Either 0x80000000 (R2) or 0 (R1). */
}
#endif
#endif
#else
#error "Missing CPU detection for this architecture"
#endif
UNUSED(L);
return flags;
}
/* Initialize JIT compiler. */
static void jit_init(lua_State *L)
{
uint32_t flags = jit_cpudetect(L);
#if LJ_HASJIT
jit_State *J = L2J(L);
J->flags = flags | JIT_F_ON | JIT_F_OPT_DEFAULT;
J->flags = jit_cpudetect() | JIT_F_ON | JIT_F_OPT_DEFAULT;
memcpy(J->param, jit_param_default, sizeof(J->param));
lj_dispatch_update(G(L));
#else
UNUSED(flags);
#endif
}
#endif
LUALIB_API int luaopen_jit(lua_State *L)
{
#if LJ_HASJIT
jit_init(L);
#endif
lua_pushliteral(L, LJ_OS_NAME);
lua_pushliteral(L, LJ_ARCH_NAME);
lua_pushinteger(L, LUAJIT_VERSION_NUM);