root/lib_jit.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. setjitmode
  2. LJLIB_CF
  3. LJLIB_CF
  4. LJLIB_CF
  5. flagbits_to_strings
  6. LJLIB_CF
  7. LJLIB_CF
  8. LJLIB_PUSH
  9. setintfield
  10. LJLIB_CF
  11. LJLIB_CF
  12. LJLIB_CF
  13. LJLIB_CF
  14. jit_checktrace
  15. LJLIB_CF
  16. LJLIB_CF
  17. LJLIB_CF
  18. LJLIB_CF
  19. LJLIB_CF
  20. LJLIB_CF
  21. LJLIB_CF
  22. jitopt_level
  23. jitopt_flag
  24. jitopt_param
  25. LJLIB_CF
  26. jit_cpudetect
  27. jit_init
  28. luaopen_jit

   1 /*
   2 ** JIT library.
   3 ** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h
   4 */
   5 
   6 #define lib_jit_c
   7 #define LUA_LIB
   8 
   9 #include "lua.h"
  10 #include "lauxlib.h"
  11 #include "lualib.h"
  12 
  13 #include "lj_arch.h"
  14 #include "lj_obj.h"
  15 #include "lj_err.h"
  16 #include "lj_debug.h"
  17 #include "lj_str.h"
  18 #include "lj_tab.h"
  19 #include "lj_bc.h"
  20 #if LJ_HASJIT
  21 #include "lj_ir.h"
  22 #include "lj_jit.h"
  23 #include "lj_ircall.h"
  24 #include "lj_iropt.h"
  25 #include "lj_target.h"
  26 #endif
  27 #include "lj_dispatch.h"
  28 #include "lj_vm.h"
  29 #include "lj_vmevent.h"
  30 #include "lj_lib.h"
  31 
  32 #include "luajit.h"
  33 
  34 /* -- jit.* functions ----------------------------------------------------- */
  35 
  36 #define LJLIB_MODULE_jit
  37 
  38 static int setjitmode(lua_State *L, int mode)
  39 {
  40   int idx = 0;
  41   if (L->base == L->top || tvisnil(L->base)) {  /* jit.on/off/flush([nil]) */
  42     mode |= LUAJIT_MODE_ENGINE;
  43   } else {
  44     /* jit.on/off/flush(func|proto, nil|true|false) */
  45     if (tvisfunc(L->base) || tvisproto(L->base))
  46       idx = 1;
  47     else if (!tvistrue(L->base))  /* jit.on/off/flush(true, nil|true|false) */
  48       goto err;
  49     if (L->base+1 < L->top && tvisbool(L->base+1))
  50       mode |= boolV(L->base+1) ? LUAJIT_MODE_ALLFUNC : LUAJIT_MODE_ALLSUBFUNC;
  51     else
  52       mode |= LUAJIT_MODE_FUNC;
  53   }
  54   if (luaJIT_setmode(L, idx, mode) != 1) {
  55     if ((mode & LUAJIT_MODE_MASK) == LUAJIT_MODE_ENGINE)
  56       lj_err_caller(L, LJ_ERR_NOJIT);
  57   err:
  58     lj_err_argt(L, 1, LUA_TFUNCTION);
  59   }
  60   return 0;
  61 }
  62 
  63 LJLIB_CF(jit_on)
  64 {
  65   return setjitmode(L, LUAJIT_MODE_ON);
  66 }
  67 
  68 LJLIB_CF(jit_off)
  69 {
  70   return setjitmode(L, LUAJIT_MODE_OFF);
  71 }
  72 
  73 LJLIB_CF(jit_flush)
  74 {
  75 #if LJ_HASJIT
  76   if (L->base < L->top && tvisnumber(L->base)) {
  77     int traceno = lj_lib_checkint(L, 1);
  78     luaJIT_setmode(L, traceno, LUAJIT_MODE_FLUSH|LUAJIT_MODE_TRACE);
  79     return 0;
  80   }
  81 #endif
  82   return setjitmode(L, LUAJIT_MODE_FLUSH);
  83 }
  84 
  85 #if LJ_HASJIT
  86 /* Push a string for every flag bit that is set. */
  87 static void flagbits_to_strings(lua_State *L, uint32_t flags, uint32_t base,
  88                                 const char *str)
  89 {
  90   for (; *str; base <<= 1, str += 1+*str)
  91     if (flags & base)
  92       setstrV(L, L->top++, lj_str_new(L, str+1, *(uint8_t *)str));
  93 }
  94 #endif
  95 
  96 LJLIB_CF(jit_status)
  97 {
  98 #if LJ_HASJIT
  99   jit_State *J = L2J(L);
 100   L->top = L->base;
 101   setboolV(L->top++, (J->flags & JIT_F_ON) ? 1 : 0);
 102   flagbits_to_strings(L, J->flags, JIT_F_CPU_FIRST, JIT_F_CPUSTRING);
 103   flagbits_to_strings(L, J->flags, JIT_F_OPT_FIRST, JIT_F_OPTSTRING);
 104   return (int)(L->top - L->base);
 105 #else
 106   setboolV(L->top++, 0);
 107   return 1;
 108 #endif
 109 }
 110 
 111 LJLIB_CF(jit_attach)
 112 {
 113 #ifdef LUAJIT_DISABLE_VMEVENT
 114   luaL_error(L, "vmevent API disabled");
 115 #else
 116   GCfunc *fn = lj_lib_checkfunc(L, 1);
 117   GCstr *s = lj_lib_optstr(L, 2);
 118   luaL_findtable(L, LUA_REGISTRYINDEX, LJ_VMEVENTS_REGKEY, LJ_VMEVENTS_HSIZE);
 119   if (s) {  /* Attach to given event. */
 120     const uint8_t *p = (const uint8_t *)strdata(s);
 121     uint32_t h = s->len;
 122     while (*p) h = h ^ (lj_rol(h, 6) + *p++);
 123     lua_pushvalue(L, 1);
 124     lua_rawseti(L, -2, VMEVENT_HASHIDX(h));
 125     G(L)->vmevmask = VMEVENT_NOCACHE;  /* Invalidate cache. */
 126   } else {  /* Detach if no event given. */
 127     setnilV(L->top++);
 128     while (lua_next(L, -2)) {
 129       L->top--;
 130       if (tvisfunc(L->top) && funcV(L->top) == fn) {
 131         setnilV(lj_tab_set(L, tabV(L->top-2), L->top-1));
 132       }
 133     }
 134   }
 135 #endif
 136   return 0;
 137 }
 138 
 139 LJLIB_PUSH(top-5) LJLIB_SET(os)
 140 LJLIB_PUSH(top-4) LJLIB_SET(arch)
 141 LJLIB_PUSH(top-3) LJLIB_SET(version_num)
 142 LJLIB_PUSH(top-2) LJLIB_SET(version)
 143 
 144 #include "lj_libdef.h"
 145 
 146 /* -- jit.util.* functions ------------------------------------------------ */
 147 
 148 #define LJLIB_MODULE_jit_util
 149 
 150 /* -- Reflection API for Lua functions ------------------------------------ */
 151 
 152 /* Return prototype of first argument (Lua function or prototype object) */
 153 static GCproto *check_Lproto(lua_State *L, int nolua)
 154 {
 155   TValue *o = L->base;
 156   if (L->top > o) {
 157     if (tvisproto(o)) {
 158       return protoV(o);
 159     } else if (tvisfunc(o)) {
 160       if (isluafunc(funcV(o)))
 161         return funcproto(funcV(o));
 162       else if (nolua)
 163         return NULL;
 164     }
 165   }
 166   lj_err_argt(L, 1, LUA_TFUNCTION);
 167   return NULL;  /* unreachable */
 168 }
 169 
 170 static void setintfield(lua_State *L, GCtab *t, const char *name, int32_t val)
 171 {
 172   setintV(lj_tab_setstr(L, t, lj_str_newz(L, name)), val);
 173 }
 174 
 175 /* local info = jit.util.funcinfo(func [,pc]) */
 176 LJLIB_CF(jit_util_funcinfo)
 177 {
 178   GCproto *pt = check_Lproto(L, 1);
 179   if (pt) {
 180     BCPos pc = (BCPos)lj_lib_optint(L, 2, 0);
 181     GCtab *t;
 182     lua_createtable(L, 0, 16);  /* Increment hash size if fields are added. */
 183     t = tabV(L->top-1);
 184     setintfield(L, t, "linedefined", pt->firstline);
 185     setintfield(L, t, "lastlinedefined", pt->firstline + pt->numline);
 186     setintfield(L, t, "stackslots", pt->framesize);
 187     setintfield(L, t, "params", pt->numparams);
 188     setintfield(L, t, "bytecodes", (int32_t)pt->sizebc);
 189     setintfield(L, t, "gcconsts", (int32_t)pt->sizekgc);
 190     setintfield(L, t, "nconsts", (int32_t)pt->sizekn);
 191     setintfield(L, t, "upvalues", (int32_t)pt->sizeuv);
 192     if (pc < pt->sizebc)
 193       setintfield(L, t, "currentline", lj_debug_line(pt, pc));
 194     lua_pushboolean(L, (pt->flags & PROTO_VARARG));
 195     lua_setfield(L, -2, "isvararg");
 196     lua_pushboolean(L, (pt->flags & PROTO_CHILD));
 197     lua_setfield(L, -2, "children");
 198     setstrV(L, L->top++, proto_chunkname(pt));
 199     lua_setfield(L, -2, "source");
 200     lj_debug_pushloc(L, pt, pc);
 201     lua_setfield(L, -2, "loc");
 202     setprotoV(L, lj_tab_setstr(L, t, lj_str_newlit(L, "proto")), pt);
 203   } else {
 204     GCfunc *fn = funcV(L->base);
 205     GCtab *t;
 206     lua_createtable(L, 0, 4);  /* Increment hash size if fields are added. */
 207     t = tabV(L->top-1);
 208     if (!iscfunc(fn))
 209       setintfield(L, t, "ffid", fn->c.ffid);
 210     setintptrV(lj_tab_setstr(L, t, lj_str_newlit(L, "addr")),
 211                (intptr_t)(void *)fn->c.f);
 212     setintfield(L, t, "upvalues", fn->c.nupvalues);
 213   }
 214   return 1;
 215 }
 216 
 217 /* local ins, m = jit.util.funcbc(func, pc) */
 218 LJLIB_CF(jit_util_funcbc)
 219 {
 220   GCproto *pt = check_Lproto(L, 0);
 221   BCPos pc = (BCPos)lj_lib_checkint(L, 2);
 222   if (pc < pt->sizebc) {
 223     BCIns ins = proto_bc(pt)[pc];
 224     BCOp op = bc_op(ins);
 225     lua_assert(op < BC__MAX);
 226     setintV(L->top, ins);
 227     setintV(L->top+1, lj_bc_mode[op]);
 228     L->top += 2;
 229     return 2;
 230   }
 231   return 0;
 232 }
 233 
 234 /* local k = jit.util.funck(func, idx) */
 235 LJLIB_CF(jit_util_funck)
 236 {
 237   GCproto *pt = check_Lproto(L, 0);
 238   ptrdiff_t idx = (ptrdiff_t)lj_lib_checkint(L, 2);
 239   if (idx >= 0) {
 240     if (idx < (ptrdiff_t)pt->sizekn) {
 241       copyTV(L, L->top-1, proto_knumtv(pt, idx));
 242       return 1;
 243     }
 244   } else {
 245     if (~idx < (ptrdiff_t)pt->sizekgc) {
 246       GCobj *gc = proto_kgc(pt, idx);
 247       setgcV(L, L->top-1, gc, ~gc->gch.gct);
 248       return 1;
 249     }
 250   }
 251   return 0;
 252 }
 253 
 254 /* local name = jit.util.funcuvname(func, idx) */
 255 LJLIB_CF(jit_util_funcuvname)
 256 {
 257   GCproto *pt = check_Lproto(L, 0);
 258   uint32_t idx = (uint32_t)lj_lib_checkint(L, 2);
 259   if (idx < pt->sizeuv) {
 260     setstrV(L, L->top-1, lj_str_newz(L, lj_debug_uvname(pt, idx)));
 261     return 1;
 262   }
 263   return 0;
 264 }
 265 
 266 /* -- Reflection API for traces ------------------------------------------- */
 267 
 268 #if LJ_HASJIT
 269 
 270 /* Check trace argument. Must not throw for non-existent trace numbers. */
 271 static GCtrace *jit_checktrace(lua_State *L)
 272 {
 273   TraceNo tr = (TraceNo)lj_lib_checkint(L, 1);
 274   jit_State *J = L2J(L);
 275   if (tr > 0 && tr < J->sizetrace)
 276     return traceref(J, tr);
 277   return NULL;
 278 }
 279 
 280 /* Names of link types. ORDER LJ_TRLINK */
 281 static const char *const jit_trlinkname[] = {
 282   "none", "root", "loop", "tail-recursion", "up-recursion", "down-recursion",
 283   "interpreter", "return"
 284 };
 285 
 286 /* local info = jit.util.traceinfo(tr) */
 287 LJLIB_CF(jit_util_traceinfo)
 288 {
 289   GCtrace *T = jit_checktrace(L);
 290   if (T) {
 291     GCtab *t;
 292     lua_createtable(L, 0, 8);  /* Increment hash size if fields are added. */
 293     t = tabV(L->top-1);
 294     setintfield(L, t, "nins", (int32_t)T->nins - REF_BIAS - 1);
 295     setintfield(L, t, "nk", REF_BIAS - (int32_t)T->nk);
 296     setintfield(L, t, "link", T->link);
 297     setintfield(L, t, "nexit", T->nsnap);
 298     setstrV(L, L->top++, lj_str_newz(L, jit_trlinkname[T->linktype]));
 299     lua_setfield(L, -2, "linktype");
 300     /* There are many more fields. Add them only when needed. */
 301     return 1;
 302   }
 303   return 0;
 304 }
 305 
 306 /* local m, ot, op1, op2, prev = jit.util.traceir(tr, idx) */
 307 LJLIB_CF(jit_util_traceir)
 308 {
 309   GCtrace *T = jit_checktrace(L);
 310   IRRef ref = (IRRef)lj_lib_checkint(L, 2) + REF_BIAS;
 311   if (T && ref >= REF_BIAS && ref < T->nins) {
 312     IRIns *ir = &T->ir[ref];
 313     int32_t m = lj_ir_mode[ir->o];
 314     setintV(L->top-2, m);
 315     setintV(L->top-1, ir->ot);
 316     setintV(L->top++, (int32_t)ir->op1 - (irm_op1(m)==IRMref ? REF_BIAS : 0));
 317     setintV(L->top++, (int32_t)ir->op2 - (irm_op2(m)==IRMref ? REF_BIAS : 0));
 318     setintV(L->top++, ir->prev);
 319     return 5;
 320   }
 321   return 0;
 322 }
 323 
 324 /* local k, t [, slot] = jit.util.tracek(tr, idx) */
 325 LJLIB_CF(jit_util_tracek)
 326 {
 327   GCtrace *T = jit_checktrace(L);
 328   IRRef ref = (IRRef)lj_lib_checkint(L, 2) + REF_BIAS;
 329   if (T && ref >= T->nk && ref < REF_BIAS) {
 330     IRIns *ir = &T->ir[ref];
 331     int32_t slot = -1;
 332     if (ir->o == IR_KSLOT) {
 333       slot = ir->op2;
 334       ir = &T->ir[ir->op1];
 335     }
 336     lj_ir_kvalue(L, L->top-2, ir);
 337     setintV(L->top-1, (int32_t)irt_type(ir->t));
 338     if (slot == -1)
 339       return 2;
 340     setintV(L->top++, slot);
 341     return 3;
 342   }
 343   return 0;
 344 }
 345 
 346 /* local snap = jit.util.tracesnap(tr, sn) */
 347 LJLIB_CF(jit_util_tracesnap)
 348 {
 349   GCtrace *T = jit_checktrace(L);
 350   SnapNo sn = (SnapNo)lj_lib_checkint(L, 2);
 351   if (T && sn < T->nsnap) {
 352     SnapShot *snap = &T->snap[sn];
 353     SnapEntry *map = &T->snapmap[snap->mapofs];
 354     MSize n, nent = snap->nent;
 355     GCtab *t;
 356     lua_createtable(L, nent+2, 0);
 357     t = tabV(L->top-1);
 358     setintV(lj_tab_setint(L, t, 0), (int32_t)snap->ref - REF_BIAS);
 359     setintV(lj_tab_setint(L, t, 1), (int32_t)snap->nslots);
 360     for (n = 0; n < nent; n++)
 361       setintV(lj_tab_setint(L, t, (int32_t)(n+2)), (int32_t)map[n]);
 362     setintV(lj_tab_setint(L, t, (int32_t)(nent+2)), (int32_t)SNAP(255, 0, 0));
 363     return 1;
 364   }
 365   return 0;
 366 }
 367 
 368 /* local mcode, addr, loop = jit.util.tracemc(tr) */
 369 LJLIB_CF(jit_util_tracemc)
 370 {
 371   GCtrace *T = jit_checktrace(L);
 372   if (T && T->mcode != NULL) {
 373     setstrV(L, L->top-1, lj_str_new(L, (const char *)T->mcode, T->szmcode));
 374     setintptrV(L->top++, (intptr_t)(void *)T->mcode);
 375     setintV(L->top++, T->mcloop);
 376     return 3;
 377   }
 378   return 0;
 379 }
 380 
 381 /* local addr = jit.util.traceexitstub([tr,] exitno) */
 382 LJLIB_CF(jit_util_traceexitstub)
 383 {
 384 #ifdef EXITSTUBS_PER_GROUP
 385   ExitNo exitno = (ExitNo)lj_lib_checkint(L, 1);
 386   jit_State *J = L2J(L);
 387   if (exitno < EXITSTUBS_PER_GROUP*LJ_MAX_EXITSTUBGR) {
 388     setintptrV(L->top-1, (intptr_t)(void *)exitstub_addr(J, exitno));
 389     return 1;
 390   }
 391 #else
 392   if (L->top > L->base+1) {  /* Don't throw for one-argument variant. */
 393     GCtrace *T = jit_checktrace(L);
 394     ExitNo exitno = (ExitNo)lj_lib_checkint(L, 2);
 395     ExitNo maxexit = T->root ? T->nsnap+1 : T->nsnap;
 396     if (T && T->mcode != NULL && exitno < maxexit) {
 397       setintptrV(L->top-1, (intptr_t)(void *)exitstub_trace_addr(T, exitno));
 398       return 1;
 399     }
 400   }
 401 #endif
 402   return 0;
 403 }
 404 
 405 /* local addr = jit.util.ircalladdr(idx) */
 406 LJLIB_CF(jit_util_ircalladdr)
 407 {
 408   uint32_t idx = (uint32_t)lj_lib_checkint(L, 1);
 409   if (idx < IRCALL__MAX) {
 410     setintptrV(L->top-1, (intptr_t)(void *)lj_ir_callinfo[idx].func);
 411     return 1;
 412   }
 413   return 0;
 414 }
 415 
 416 #endif
 417 
 418 #include "lj_libdef.h"
 419 
 420 /* -- jit.opt module ------------------------------------------------------ */
 421 
 422 #if LJ_HASJIT
 423 
 424 #define LJLIB_MODULE_jit_opt
 425 
 426 /* Parse optimization level. */
 427 static int jitopt_level(jit_State *J, const char *str)
 428 {
 429   if (str[0] >= '0' && str[0] <= '9' && str[1] == '\0') {
 430     uint32_t flags;
 431     if (str[0] == '0') flags = JIT_F_OPT_0;
 432     else if (str[0] == '1') flags = JIT_F_OPT_1;
 433     else if (str[0] == '2') flags = JIT_F_OPT_2;
 434     else flags = JIT_F_OPT_3;
 435     J->flags = (J->flags & ~JIT_F_OPT_MASK) | flags;
 436     return 1;  /* Ok. */
 437   }
 438   return 0;  /* No match. */
 439 }
 440 
 441 /* Parse optimization flag. */
 442 static int jitopt_flag(jit_State *J, const char *str)
 443 {
 444   const char *lst = JIT_F_OPTSTRING;
 445   uint32_t opt;
 446   int set = 1;
 447   if (str[0] == '+') {
 448     str++;
 449   } else if (str[0] == '-') {
 450     str++;
 451     set = 0;
 452   } else if (str[0] == 'n' && str[1] == 'o') {
 453     str += str[2] == '-' ? 3 : 2;
 454     set = 0;
 455   }
 456   for (opt = JIT_F_OPT_FIRST; ; opt <<= 1) {
 457     size_t len = *(const uint8_t *)lst;
 458     if (len == 0)
 459       break;
 460     if (strncmp(str, lst+1, len) == 0 && str[len] == '\0') {
 461       if (set) J->flags |= opt; else J->flags &= ~opt;
 462       return 1;  /* Ok. */
 463     }
 464     lst += 1+len;
 465   }
 466   return 0;  /* No match. */
 467 }
 468 
 469 /* Parse optimization parameter. */
 470 static int jitopt_param(jit_State *J, const char *str)
 471 {
 472   const char *lst = JIT_P_STRING;
 473   int i;
 474   for (i = 0; i < JIT_P__MAX; i++) {
 475     size_t len = *(const uint8_t *)lst;
 476     lua_assert(len != 0);
 477     if (strncmp(str, lst+1, len) == 0 && str[len] == '=') {
 478       int32_t n = 0;
 479       const char *p = &str[len+1];
 480       while (*p >= '0' && *p <= '9')
 481         n = n*10 + (*p++ - '0');
 482       if (*p) return 0;  /* Malformed number. */
 483       J->param[i] = n;
 484       if (i == JIT_P_hotloop)
 485         lj_dispatch_init_hotcount(J2G(J));
 486       return 1;  /* Ok. */
 487     }
 488     lst += 1+len;
 489   }
 490   return 0;  /* No match. */
 491 }
 492 
 493 /* jit.opt.start(flags...) */
 494 LJLIB_CF(jit_opt_start)
 495 {
 496   jit_State *J = L2J(L);
 497   int nargs = (int)(L->top - L->base);
 498   if (nargs == 0) {
 499     J->flags = (J->flags & ~JIT_F_OPT_MASK) | JIT_F_OPT_DEFAULT;
 500   } else {
 501     int i;
 502     for (i = 1; i <= nargs; i++) {
 503       const char *str = strdata(lj_lib_checkstr(L, i));
 504       if (!jitopt_level(J, str) &&
 505           !jitopt_flag(J, str) &&
 506           !jitopt_param(J, str))
 507         lj_err_callerv(L, LJ_ERR_JITOPT, str);
 508     }
 509   }
 510   return 0;
 511 }
 512 
 513 #include "lj_libdef.h"
 514 
 515 #endif
 516 
 517 /* -- JIT compiler initialization ----------------------------------------- */
 518 
 519 #if LJ_HASJIT
 520 /* Default values for JIT parameters. */
 521 static const int32_t jit_param_default[JIT_P__MAX+1] = {
 522 #define JIT_PARAMINIT(len, name, value) (value),
 523 JIT_PARAMDEF(JIT_PARAMINIT)
 524 #undef JIT_PARAMINIT
 525   0
 526 };
 527 #endif
 528 
 529 #if LJ_TARGET_ARM && LJ_TARGET_LINUX
 530 #include <sys/utsname.h>
 531 #endif
 532 
 533 /* Arch-dependent CPU detection. */
 534 static uint32_t jit_cpudetect(lua_State *L)
 535 {
 536   uint32_t flags = 0;
 537 #if LJ_TARGET_X86ORX64
 538   uint32_t vendor[4];
 539   uint32_t features[4];
 540   if (lj_vm_cpuid(0, vendor) && lj_vm_cpuid(1, features)) {
 541 #if !LJ_HASJIT
 542 #define JIT_F_CMOV      1
 543 #define JIT_F_SSE2      2
 544 #endif
 545     flags |= ((features[3] >> 15)&1) * JIT_F_CMOV;
 546     flags |= ((features[3] >> 26)&1) * JIT_F_SSE2;
 547 #if LJ_HASJIT
 548     flags |= ((features[2] >> 0)&1) * JIT_F_SSE3;
 549     flags |= ((features[2] >> 19)&1) * JIT_F_SSE4_1;
 550     if (vendor[2] == 0x6c65746e) {  /* Intel. */
 551       if ((features[0] & 0x0ff00f00) == 0x00000f00)  /* P4. */
 552         flags |= JIT_F_P4;  /* Currently unused. */
 553       else if ((features[0] & 0x0fff0ff0) == 0x000106c0)  /* Atom. */
 554         flags |= JIT_F_LEA_AGU;
 555     } else if (vendor[2] == 0x444d4163) {  /* AMD. */
 556       uint32_t fam = (features[0] & 0x0ff00f00);
 557       if (fam == 0x00000f00)  /* K8. */
 558         flags |= JIT_F_SPLIT_XMM;
 559       if (fam >= 0x00000f00)  /* K8, K10. */
 560         flags |= JIT_F_PREFER_IMUL;
 561     }
 562 #endif
 563   }
 564   /* Check for required instruction set support on x86 (unnecessary on x64). */
 565 #if LJ_TARGET_X86
 566 #if !defined(LUAJIT_CPU_NOCMOV)
 567   if (!(flags & JIT_F_CMOV))
 568     luaL_error(L, "CPU not supported");
 569 #endif
 570 #if defined(LUAJIT_CPU_SSE2)
 571   if (!(flags & JIT_F_SSE2))
 572     luaL_error(L, "CPU does not support SSE2 (recompile without -DLUAJIT_CPU_SSE2)");
 573 #endif
 574 #endif
 575 #elif LJ_TARGET_ARM
 576 #if LJ_HASJIT
 577   int ver = LJ_ARCH_VERSION;  /* Compile-time ARM CPU detection. */
 578 #if LJ_TARGET_LINUX
 579   if (ver < 70) {  /* Runtime ARM CPU detection. */
 580     struct utsname ut;
 581     uname(&ut);
 582     if (strncmp(ut.machine, "armv", 4) == 0) {
 583       if (ut.machine[4] >= '7')
 584         ver = 70;
 585       else if (ut.machine[4] == '6')
 586         ver = 60;
 587     }
 588   }
 589 #endif
 590   flags |= ver >= 70 ? JIT_F_ARMV7 :
 591            ver >= 61 ? JIT_F_ARMV6T2_ :
 592            ver >= 60 ? JIT_F_ARMV6_ : 0;
 593   flags |= LJ_ARCH_HASFPU == 0 ? 0 : ver >= 70 ? JIT_F_VFPV3 : JIT_F_VFPV2;
 594 #endif
 595 #elif LJ_TARGET_PPC
 596 #if LJ_HASJIT
 597 #if LJ_ARCH_SQRT
 598   flags |= JIT_F_SQRT;
 599 #endif
 600 #if LJ_ARCH_ROUND
 601   flags |= JIT_F_ROUND;
 602 #endif
 603 #endif
 604 #elif LJ_TARGET_PPCSPE
 605   /* Nothing to do. */
 606 #elif LJ_TARGET_MIPS
 607 #if LJ_HASJIT
 608   /* Compile-time MIPS CPU detection. */
 609 #if LJ_ARCH_VERSION >= 20
 610   flags |= JIT_F_MIPS32R2;
 611 #endif
 612   /* Runtime MIPS CPU detection. */
 613 #if defined(__GNUC__)
 614   if (!(flags & JIT_F_MIPS32R2)) {
 615     int x;
 616     /* On MIPS32R1 rotr is treated as srl. rotr r2,r2,1 -> srl r2,r2,1. */
 617     __asm__("li $2, 1\n\t.long 0x00221042\n\tmove %0, $2" : "=r"(x) : : "$2");
 618     if (x) flags |= JIT_F_MIPS32R2;  /* Either 0x80000000 (R2) or 0 (R1). */
 619   }
 620 #endif
 621 #endif
 622 #else
 623 #error "Missing CPU detection for this architecture"
 624 #endif
 625   UNUSED(L);
 626   return flags;
 627 }
 628 
 629 /* Initialize JIT compiler. */
 630 static void jit_init(lua_State *L)
 631 {
 632   uint32_t flags = jit_cpudetect(L);
 633 #if LJ_HASJIT
 634   jit_State *J = L2J(L);
 635 #if LJ_TARGET_X86
 636   /* Silently turn off the JIT compiler on CPUs without SSE2. */
 637   if ((flags & JIT_F_SSE2))
 638 #endif
 639     J->flags = flags | JIT_F_ON | JIT_F_OPT_DEFAULT;
 640   memcpy(J->param, jit_param_default, sizeof(J->param));
 641   lj_dispatch_update(G(L));
 642 #else
 643   UNUSED(flags);
 644 #endif
 645 }
 646 
 647 LUALIB_API int luaopen_jit(lua_State *L)
 648 {
 649   lua_pushliteral(L, LJ_OS_NAME);
 650   lua_pushliteral(L, LJ_ARCH_NAME);
 651   lua_pushinteger(L, LUAJIT_VERSION_NUM);
 652   lua_pushliteral(L, LUAJIT_VERSION);
 653   LJ_LIB_REG(L, LUA_JITLIBNAME, jit);
 654 #ifndef LUAJIT_DISABLE_JITUTIL
 655   LJ_LIB_REG(L, "jit.util", jit_util);
 656 #endif
 657 #if LJ_HASJIT
 658   LJ_LIB_REG(L, "jit.opt", jit_opt);
 659 #endif
 660   L->top -= 2;
 661   jit_init(L);
 662   return 1;
 663 }
 664 

/* [<][>][^][v][top][bottom][index][help] */