📄 ljit_x86.h
字号:
/* Copy args. */ co->top = (StkId)(((char *)co->top) + ndelta); { StkId t = co->top, f = L->top; while (f > base) setobj2s(co, --t, --f); } L->top = base; status = luaCOCO_resume(co, nargs); /* Resume Coco thread. */ if (status == 0 || status == LUA_YIELD) { /* Ok. */ StkId f; if (nresults == 0) return NULL; if (nresults == -1) { luaD_checkstack(L, co->top - co->base); /* Grow own stack. */ } base = L->top - 2; setbvalue(base++, 1); /* true */ /* Copy results. Fill unused result slots with nil. */ f = co->base; while (--nresults != 0 && f < co->top) setobj2s(L, base++, f++); while (nresults-- > 0) setnilvalue(base++); co->top = co->base; return base; } else { /* Error. */ base = L->top; setobj2s(L, base-1, co->top-1); /* Copy error object. */err: setbvalue(base-2, 0); /* false */ nresults -= 2; while (--nresults >= 0) setnilvalue(base+nresults); /* Fill results. */ return base; } }}static void jit_inline_coroutine(jit_State *J, jit_InlineInfo *ii){ int arg = ii->func+1; int res = ii->res; int i; switch (JIT_IH_IDX(ii->hidx)) { case JIT_IH_COROUTINE_YIELD: dasm_put(Dst, 775, ((int)&LHASCOCO((lua_State *)0)), Dt1(->savedpc), (ptrdiff_t)(J->nextins), arg*sizeof(TValue)); if (ii->nargs >= 0) { /* Previous op was not open and did not set TOP. */ dasm_put(Dst, 791, Dt2([ii->nargs])); } dasm_put(Dst, 795, Dt1(->base), Dt1(->top), (ptrdiff_t)(luaCOCO_yield), Dt1(->base), Dt1(->top)); jit_assert(ii->nresults >= 0 && ii->nresults <= EXTRA_STACK); for (i = 0; i < ii->nresults; i++) { dasm_put(Dst, 813, Dt3([i].tt)); if (J->flags & JIT_F_CPU_SSE2) { dasm_put(Dst, 821, Dt2([arg+i].tt), Dt2([arg+i].value), Dt2([res+i].tt), Dt2([res+i].value)); } else { dasm_put(Dst, 839, Dt2([arg+i].value), Dt2([arg+i].value.na[1]), Dt2([arg+i].tt), Dt2([res+i].value), Dt2([res+i].value.na[1]), Dt2([res+i].tt)); } } ii->nargs = -1; /* Force restore of L->top. */ break; case JIT_IH_COROUTINE_RESUME: jit_assert(ii->nargs != 0 && ii->res == ii->func); dasm_put(Dst, 787, (arg+1)*sizeof(TValue)); if (ii->nargs >= 0) { /* Previous op was not open and did not set TOP. */ dasm_put(Dst, 791, Dt2([ii->nargs-1])); } else { dasm_put(Dst, 858); } dasm_put(Dst, 865, Dt2([-1].tt), Dt2([-1].value), ((int)&LHASCOCO((lua_State *)0)), Dt1(->savedpc), (ptrdiff_t)(J->nextins), Dt1(->top), ii->nresults, (ptrdiff_t)(jit_coroutine_resume), Dt1(->base)); if (ii->nresults == -1) { dasm_put(Dst, 909); } ii->nargs = -1; /* Force restore of L->top. */ break; default: jit_assert(0); break; }}#endif /* COCO_DISABLE *//* ------------------------------------------------------------------------ */static void jit_inline_string(jit_State *J, jit_InlineInfo *ii){ int arg = ii->func+1; int res = ii->res; switch (JIT_IH_IDX(ii->hidx)) { case JIT_IH_STRING_LEN: dasm_put(Dst, 912, Dt2([arg].tt), Dt2([arg].value), DtB(->tsv.len), Dt2([res].tt), Dt2([res].value)); break; case JIT_IH_STRING_SUB: /* TODO: inline numeric constants with help from the optimizer. */ /* But this would save only another 15-20% in a trivial loop. */ jit_assert(ii->nargs >= 2); /* Open op caveat is ok, too. */ if (ii->nargs > 2) { dasm_put(Dst, 937, Dt2([arg]), Dt2([res].value), Dt2([res].tt)); } else { dasm_put(Dst, 954, Dt2([arg]), Dt2([res].value), Dt2([res].tt)); } break; case JIT_IH_STRING_CHAR: dasm_put(Dst, 971, Dt2([arg].tt), Dt1(->env), Dt2([arg].value), (ptrdiff_t)(luaS_newlstr), Dt2([res].value), Dt2([res].tt)); break; default: jit_assert(0); break; }}/* ------------------------------------------------------------------------ *//* Helper functions for inlined calls to table.*. */static void jit_table_insert(lua_State *L, TValue *arg){ setobj2t(L, luaH_setnum(L, hvalue(arg), luaH_getn(hvalue(arg))+1), arg+1); luaC_barriert(L, hvalue(arg), arg+1);}static TValue *jit_table_remove(lua_State *L, TValue *arg, TValue *res){ int n = luaH_getn(hvalue(arg)); if (n == 0) { setnilvalue(res); /* For the nresults == 1 case. Harmless otherwise. */ return res; /* For the nresults == -1 case. */ } else { TValue *val = luaH_setnum(L, hvalue(arg), n); setobj2s(L, res, val); setnilvalue(val); return res+1; /* For the nresults == -1 case. */ }}static void jit_inline_table(jit_State *J, jit_InlineInfo *ii){ int arg = ii->func+1; int res = ii->res; dasm_put(Dst, 1250, Dt2([arg].tt)); switch (JIT_IH_IDX(ii->hidx)) { case JIT_IH_TABLE_INSERT: jit_assert(ii->nargs == 2); dasm_put(Dst, 1259, Dt2([arg]), (ptrdiff_t)(jit_table_insert)); break; case JIT_IH_TABLE_REMOVE: jit_assert(ii->nargs == 1); dasm_put(Dst, 1272, Dt2([arg]), Dt2([res]), (ptrdiff_t)(jit_table_remove)); if (ii->nresults == -1) { ii->xnresults = -1; dasm_put(Dst, 909); } break; case JIT_IH_TABLE_GETN: dasm_put(Dst, 1292, Dt2([arg].value), (ptrdiff_t)(luaH_getn), Dt2([res].value), Dt2([res].tt)); break; default: jit_assert(0); break; }}/* ------------------------------------------------------------------------ *//* This typedef must match the libm function signature. *//* Serves as a check against wrong lua_Number or wrong calling conventions. */typedef lua_Number (*mathfunc_11)(lua_Number);/* Partially inlined math functions. *//* CHECK: must match with jit_hints.h and jit.opt_lib. */static const mathfunc_11 jit_mathfuncs_11[JIT_IH_MATH_SIN] = { log, log10, exp, sinh, cosh, tanh, asin, acos, atan};/* FPU control words for ceil and floor (exceptions masked, full precision). */static const unsigned short jit_fpucw[2] = { 0x0b7f, 0x077f };static void jit_inline_math(jit_State *J, jit_InlineInfo *ii){ int arg = ii->func+1; int res = ii->res; int idx = JIT_IH_IDX(ii->hidx); if (idx < JIT_IH_MATH__21) { dasm_put(Dst, 1317, Dt2([arg].tt), Dt2([arg].value)); } else { jit_assert(idx < JIT_IH_MATH__LAST); dasm_put(Dst, 1329, Dt2([arg].tt), Dt2([arg+1].tt)); } switch (idx) { /* We ignore sin/cos/tan range overflows (2^63 rad) just like -ffast-math. */ case JIT_IH_MATH_SIN: dasm_put(Dst, 1347); break; case JIT_IH_MATH_COS: dasm_put(Dst, 1351); break; case JIT_IH_MATH_TAN: dasm_put(Dst, 1355); break; case JIT_IH_MATH_CEIL: case JIT_IH_MATH_FLOOR: dasm_put(Dst, 1361, (ptrdiff_t)&jit_fpucw[idx-JIT_IH_MATH_CEIL]); break; case JIT_IH_MATH_ABS: dasm_put(Dst, 1374); break; case JIT_IH_MATH_SQRT: dasm_put(Dst, 1377); break; case JIT_IH_MATH_FMOD: dasm_put(Dst, 1381, Dt2([arg+1].value), Dt2([arg].value)); break; case JIT_IH_MATH_ATAN2: dasm_put(Dst, 1402, Dt2([arg].value), Dt2([arg+1].value)); break; default: dasm_put(Dst, 1412, (ptrdiff_t)(jit_mathfuncs_11[idx])); break; } dasm_put(Dst, 926, Dt2([res].tt), Dt2([res].value));}/* ------------------------------------------------------------------------ *//* Try to inline a CALL or TAILCALL instruction. */static int jit_inline_call(jit_State *J, int func, int nargs, int nresults){ const TValue *callable = hint_get(J, TYPE); /* TYPE hint = callable. */ int cltype = ttype(callable); const TValue *oidx; jit_InlineInfo ii; int idx; if (cltype != LUA_TFUNCTION) goto fail; if (J->flags & JIT_F_DEBUG) goto fail; /* DWIM. */ oidx = hint_get(J, INLINE); /* INLINE hint = library/function index. */ if (!ttisnumber(oidx)) goto fail; ii.hidx = (int)nvalue(oidx); idx = JIT_IH_IDX(ii.hidx); if (nresults == -2) { /* Tailcall. */ /* Tailcalls from vararg functions don't work with BASE[-1]. */ if (J->pt->is_vararg) goto fail; /* So forget about this rare case. */ ii.res = -1; /* Careful: 2nd result overlaps 1st stack slot. */ ii.nresults = -1; } else { ii.res = func; ii.nresults = nresults; } ii.func = func; ii.nargs = nargs; ii.xnargs = ii.xnresults = 1; /* Default: 1 arg, 1 result. */ /* Check for the currently supported cases. */ switch (JIT_IH_LIB(ii.hidx)) { case JIT_IHLIB_BASE: switch (idx) { case JIT_IH_BASE_PAIRS: case JIT_IH_BASE_IPAIRS: if (nresults == -2) goto fail; /* Not useful for tailcalls. */ ii.xnresults = 3; goto check; } break;#ifndef COCO_DISABLE case JIT_IHLIB_COROUTINE: switch (idx) { case JIT_IH_COROUTINE_YIELD: /* Only support common cases: no tailcalls, low number of results. */ if (nresults < 0 || nresults > EXTRA_STACK) goto fail; ii.xnargs = ii.xnresults = -1; goto ok; /* Anything else is ok. */ case JIT_IH_COROUTINE_RESUME: /* Only support common cases: no tailcalls, not with 0 args (error). */ if (nresults == -2 || nargs == 0) goto fail; ii.xnargs = ii.xnresults = -1; goto ok; /* Anything else is ok. */ } break;#endif case JIT_IHLIB_STRING: switch (idx) { case JIT_IH_STRING_LEN: goto check; case JIT_IH_STRING_SUB: if (nargs < 2) goto fail; /* No support for open calls, too. */ goto ok; /* 2 or more args are ok. */ case JIT_IH_STRING_CHAR: goto check; /* Only single arg supported. */ } break; case JIT_IHLIB_TABLE: switch (idx) { case JIT_IH_TABLE_INSERT: ii.xnargs = 2; goto check; /* Only push (append) supported. */ case JIT_IH_TABLE_REMOVE: goto check; /* Only pop supported. */ case JIT_IH_TABLE_GETN: goto check; } break; case JIT_IHLIB_MATH: if (idx >= JIT_IH_MATH__LAST) goto fail; if (idx >= JIT_IH_MATH__21) ii.xnargs = 2; goto check; }fail: return cltype; /* Call could not be inlined. Return type of callable. */check: if (nargs != ii.xnargs && nargs != -1) goto fail; /* The optimizer already checks the number of results (avoid setnil). */ok: /* Whew, all checks done. Go for it! */ /* Start with the common leadin for inlined calls. */ jit_deopt_target(J, nargs); dasm_put(Dst, 1418, Dt2([func].tt), Dt2([func].value), (ptrdiff_t)(clvalue(callable)));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -