lib_jit.c 18 KB

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