mirror of
https://github.com/love2d/megasource.git
synced 2026-08-17 03:02:49 +02:00
Update LuaJIT to commit 72efc42
This commit is contained in:
@@ -92,7 +92,9 @@ FILES_INC= lua.h lualib.h lauxlib.h luaconf.h lua.hpp luajit.h
|
|||||||
FILES_JITLIB= bc.lua bcsave.lua dump.lua p.lua v.lua zone.lua \
|
FILES_JITLIB= bc.lua bcsave.lua dump.lua p.lua v.lua zone.lua \
|
||||||
dis_x86.lua dis_x64.lua dis_arm.lua dis_arm64.lua \
|
dis_x86.lua dis_x64.lua dis_arm.lua dis_arm64.lua \
|
||||||
dis_arm64be.lua dis_ppc.lua dis_mips.lua dis_mipsel.lua \
|
dis_arm64be.lua dis_ppc.lua dis_mips.lua dis_mipsel.lua \
|
||||||
dis_mips64.lua dis_mips64el.lua vmdef.lua
|
dis_mips64.lua dis_mips64el.lua \
|
||||||
|
dis_mips64r6.lua dis_mips64r6el.lua \
|
||||||
|
vmdef.lua
|
||||||
|
|
||||||
ifeq (,$(findstring Windows,$(OS)))
|
ifeq (,$(findstring Windows,$(OS)))
|
||||||
HOST_SYS:= $(shell uname -s)
|
HOST_SYS:= $(shell uname -s)
|
||||||
|
|||||||
@@ -84,6 +84,13 @@ xD("fyZKB8xv\"FJytmz8.KAB0u52D")
|
|||||||
</p>
|
</p>
|
||||||
</noscript>
|
</noscript>
|
||||||
|
|
||||||
|
<p><i>
|
||||||
|
Note: I cannot reply to GMail, Google Workplace, Outlook or Office365
|
||||||
|
mail addresses, since they prefer to mindlessly filter out mails sent
|
||||||
|
from small domains using independent mail servers, such as mine. If you
|
||||||
|
don't like that, please complain to Google or Microsoft, not me.
|
||||||
|
</i></p>
|
||||||
|
|
||||||
<h2>Copyright</h2>
|
<h2>Copyright</h2>
|
||||||
<p>
|
<p>
|
||||||
All documentation is
|
All documentation is
|
||||||
|
|||||||
@@ -463,8 +463,10 @@ otherwise. The following parameters are currently defined:
|
|||||||
<tr class="odd">
|
<tr class="odd">
|
||||||
<td class="abiparam">win</td><td class="abidesc">Windows variant of the standard ABI</td></tr>
|
<td class="abiparam">win</td><td class="abidesc">Windows variant of the standard ABI</td></tr>
|
||||||
<tr class="even">
|
<tr class="even">
|
||||||
<td class="abiparam">uwp</td><td class="abidesc">Universal Windows Platform</td></tr>
|
<td class="abiparam">pauth</td><td class="abidesc">Pointer authentication ABI</td></tr>
|
||||||
<tr class="odd">
|
<tr class="odd">
|
||||||
|
<td class="abiparam">uwp</td><td class="abidesc">Universal Windows Platform</td></tr>
|
||||||
|
<tr class="even">
|
||||||
<td class="abiparam">gc64</td><td class="abidesc">64 bit GC references</td></tr>
|
<td class="abiparam">gc64</td><td class="abidesc">64 bit GC references</td></tr>
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
|
|||||||
@@ -220,6 +220,12 @@ mix the three forms, but note that setting an optimization level
|
|||||||
overrides all earlier flags.
|
overrides all earlier flags.
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
|
Note that <tt>-Ofma</tt> is not enabled by default at any level,
|
||||||
|
because it affects floating-point result accuracy. Only enable this,
|
||||||
|
if you fully understand the trade-offs of FMA for performance (higher),
|
||||||
|
determinism (lower) and numerical accuracy (higher).
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
Here are the available flags and at what optimization levels they
|
Here are the available flags and at what optimization levels they
|
||||||
are enabled:
|
are enabled:
|
||||||
</p>
|
</p>
|
||||||
@@ -251,6 +257,8 @@ are enabled:
|
|||||||
<td class="flag_name">sink</td><td class="flag_level"> </td><td class="flag_level"> </td><td class="flag_level">•</td><td class="flag_desc">Allocation/Store Sinking</td></tr>
|
<td class="flag_name">sink</td><td class="flag_level"> </td><td class="flag_level"> </td><td class="flag_level">•</td><td class="flag_desc">Allocation/Store Sinking</td></tr>
|
||||||
<tr class="even">
|
<tr class="even">
|
||||||
<td class="flag_name">fuse</td><td class="flag_level"> </td><td class="flag_level"> </td><td class="flag_level">•</td><td class="flag_desc">Fusion of operands into instructions</td></tr>
|
<td class="flag_name">fuse</td><td class="flag_level"> </td><td class="flag_level"> </td><td class="flag_level">•</td><td class="flag_desc">Fusion of operands into instructions</td></tr>
|
||||||
|
<tr class="odd">
|
||||||
|
<td class="flag_name">fma </td><td class="flag_level"> </td><td class="flag_level"> </td><td class="flag_level"> </td><td class="flag_desc">Fused multiply-add</td></tr>
|
||||||
</table>
|
</table>
|
||||||
<p>
|
<p>
|
||||||
Here are the parameters and their default settings:
|
Here are the parameters and their default settings:
|
||||||
|
|||||||
@@ -70,7 +70,7 @@ struct dasm_State {
|
|||||||
size_t lgsize;
|
size_t lgsize;
|
||||||
int *pclabels; /* PC label chains/pos ptrs. */
|
int *pclabels; /* PC label chains/pos ptrs. */
|
||||||
size_t pcsize;
|
size_t pcsize;
|
||||||
void **globals; /* Array of globals (bias -10). */
|
void **globals; /* Array of globals. */
|
||||||
dasm_Section *section; /* Pointer to active section. */
|
dasm_Section *section; /* Pointer to active section. */
|
||||||
size_t codesize; /* Total size of all code sections. */
|
size_t codesize; /* Total size of all code sections. */
|
||||||
int maxsection; /* 0 <= sectionidx < maxsection. */
|
int maxsection; /* 0 <= sectionidx < maxsection. */
|
||||||
@@ -87,7 +87,6 @@ void dasm_init(Dst_DECL, int maxsection)
|
|||||||
{
|
{
|
||||||
dasm_State *D;
|
dasm_State *D;
|
||||||
size_t psz = 0;
|
size_t psz = 0;
|
||||||
int i;
|
|
||||||
Dst_REF = NULL;
|
Dst_REF = NULL;
|
||||||
DASM_M_GROW(Dst, struct dasm_State, Dst_REF, psz, DASM_PSZ(maxsection));
|
DASM_M_GROW(Dst, struct dasm_State, Dst_REF, psz, DASM_PSZ(maxsection));
|
||||||
D = Dst_REF;
|
D = Dst_REF;
|
||||||
@@ -98,12 +97,7 @@ void dasm_init(Dst_DECL, int maxsection)
|
|||||||
D->pcsize = 0;
|
D->pcsize = 0;
|
||||||
D->globals = NULL;
|
D->globals = NULL;
|
||||||
D->maxsection = maxsection;
|
D->maxsection = maxsection;
|
||||||
for (i = 0; i < maxsection; i++) {
|
memset((void *)D->sections, 0, maxsection * sizeof(dasm_Section));
|
||||||
D->sections[i].buf = NULL; /* Need this for pass3. */
|
|
||||||
D->sections[i].rbuf = D->sections[i].buf - DASM_SEC2POS(i);
|
|
||||||
D->sections[i].bsize = 0;
|
|
||||||
D->sections[i].epos = 0; /* Wrong, but is recalculated after resize. */
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Free DynASM state. */
|
/* Free DynASM state. */
|
||||||
@@ -123,7 +117,7 @@ void dasm_free(Dst_DECL)
|
|||||||
void dasm_setupglobal(Dst_DECL, void **gl, unsigned int maxgl)
|
void dasm_setupglobal(Dst_DECL, void **gl, unsigned int maxgl)
|
||||||
{
|
{
|
||||||
dasm_State *D = Dst_REF;
|
dasm_State *D = Dst_REF;
|
||||||
D->globals = gl - 10; /* Negative bias to compensate for locals. */
|
D->globals = gl;
|
||||||
DASM_M_GROW(Dst, int, D->lglabels, D->lgsize, (10+maxgl)*sizeof(int));
|
DASM_M_GROW(Dst, int, D->lglabels, D->lgsize, (10+maxgl)*sizeof(int));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -148,6 +142,7 @@ void dasm_setup(Dst_DECL, const void *actionlist)
|
|||||||
if (D->pclabels) memset((void *)D->pclabels, 0, D->pcsize);
|
if (D->pclabels) memset((void *)D->pclabels, 0, D->pcsize);
|
||||||
for (i = 0; i < D->maxsection; i++) {
|
for (i = 0; i < D->maxsection; i++) {
|
||||||
D->sections[i].pos = DASM_SEC2POS(i);
|
D->sections[i].pos = DASM_SEC2POS(i);
|
||||||
|
D->sections[i].rbuf = D->sections[i].buf - D->sections[i].pos;
|
||||||
D->sections[i].ofs = 0;
|
D->sections[i].ofs = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -372,7 +367,7 @@ int dasm_encode(Dst_DECL, void *buffer)
|
|||||||
break;
|
break;
|
||||||
case DASM_REL_LG:
|
case DASM_REL_LG:
|
||||||
if (n < 0) {
|
if (n < 0) {
|
||||||
n = (int)((ptrdiff_t)D->globals[-n] - (ptrdiff_t)cp - 4);
|
n = (int)((ptrdiff_t)D->globals[-n-10] - (ptrdiff_t)cp - 4);
|
||||||
goto patchrel;
|
goto patchrel;
|
||||||
}
|
}
|
||||||
/* fallthrough */
|
/* fallthrough */
|
||||||
@@ -396,7 +391,7 @@ int dasm_encode(Dst_DECL, void *buffer)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case DASM_LABEL_LG:
|
case DASM_LABEL_LG:
|
||||||
ins &= 2047; if (ins >= 20) D->globals[ins-10] = (void *)(base + n);
|
ins &= 2047; if (ins >= 20) D->globals[ins-20] = (void *)(base + n);
|
||||||
break;
|
break;
|
||||||
case DASM_LABEL_PC: break;
|
case DASM_LABEL_PC: break;
|
||||||
case DASM_IMM:
|
case DASM_IMM:
|
||||||
|
|||||||
@@ -72,7 +72,7 @@ struct dasm_State {
|
|||||||
size_t lgsize;
|
size_t lgsize;
|
||||||
int *pclabels; /* PC label chains/pos ptrs. */
|
int *pclabels; /* PC label chains/pos ptrs. */
|
||||||
size_t pcsize;
|
size_t pcsize;
|
||||||
void **globals; /* Array of globals (bias -10). */
|
void **globals; /* Array of globals. */
|
||||||
dasm_Section *section; /* Pointer to active section. */
|
dasm_Section *section; /* Pointer to active section. */
|
||||||
size_t codesize; /* Total size of all code sections. */
|
size_t codesize; /* Total size of all code sections. */
|
||||||
int maxsection; /* 0 <= sectionidx < maxsection. */
|
int maxsection; /* 0 <= sectionidx < maxsection. */
|
||||||
@@ -89,7 +89,6 @@ void dasm_init(Dst_DECL, int maxsection)
|
|||||||
{
|
{
|
||||||
dasm_State *D;
|
dasm_State *D;
|
||||||
size_t psz = 0;
|
size_t psz = 0;
|
||||||
int i;
|
|
||||||
Dst_REF = NULL;
|
Dst_REF = NULL;
|
||||||
DASM_M_GROW(Dst, struct dasm_State, Dst_REF, psz, DASM_PSZ(maxsection));
|
DASM_M_GROW(Dst, struct dasm_State, Dst_REF, psz, DASM_PSZ(maxsection));
|
||||||
D = Dst_REF;
|
D = Dst_REF;
|
||||||
@@ -100,12 +99,7 @@ void dasm_init(Dst_DECL, int maxsection)
|
|||||||
D->pcsize = 0;
|
D->pcsize = 0;
|
||||||
D->globals = NULL;
|
D->globals = NULL;
|
||||||
D->maxsection = maxsection;
|
D->maxsection = maxsection;
|
||||||
for (i = 0; i < maxsection; i++) {
|
memset((void *)D->sections, 0, maxsection * sizeof(dasm_Section));
|
||||||
D->sections[i].buf = NULL; /* Need this for pass3. */
|
|
||||||
D->sections[i].rbuf = D->sections[i].buf - DASM_SEC2POS(i);
|
|
||||||
D->sections[i].bsize = 0;
|
|
||||||
D->sections[i].epos = 0; /* Wrong, but is recalculated after resize. */
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Free DynASM state. */
|
/* Free DynASM state. */
|
||||||
@@ -125,7 +119,7 @@ void dasm_free(Dst_DECL)
|
|||||||
void dasm_setupglobal(Dst_DECL, void **gl, unsigned int maxgl)
|
void dasm_setupglobal(Dst_DECL, void **gl, unsigned int maxgl)
|
||||||
{
|
{
|
||||||
dasm_State *D = Dst_REF;
|
dasm_State *D = Dst_REF;
|
||||||
D->globals = gl - 10; /* Negative bias to compensate for locals. */
|
D->globals = gl;
|
||||||
DASM_M_GROW(Dst, int, D->lglabels, D->lgsize, (10+maxgl)*sizeof(int));
|
DASM_M_GROW(Dst, int, D->lglabels, D->lgsize, (10+maxgl)*sizeof(int));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -150,6 +144,7 @@ void dasm_setup(Dst_DECL, const void *actionlist)
|
|||||||
if (D->pclabels) memset((void *)D->pclabels, 0, D->pcsize);
|
if (D->pclabels) memset((void *)D->pclabels, 0, D->pcsize);
|
||||||
for (i = 0; i < D->maxsection; i++) {
|
for (i = 0; i < D->maxsection; i++) {
|
||||||
D->sections[i].pos = DASM_SEC2POS(i);
|
D->sections[i].pos = DASM_SEC2POS(i);
|
||||||
|
D->sections[i].rbuf = D->sections[i].buf - D->sections[i].pos;
|
||||||
D->sections[i].ofs = 0;
|
D->sections[i].ofs = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -444,7 +439,7 @@ int dasm_encode(Dst_DECL, void *buffer)
|
|||||||
break;
|
break;
|
||||||
case DASM_REL_LG:
|
case DASM_REL_LG:
|
||||||
if (n < 0) {
|
if (n < 0) {
|
||||||
ptrdiff_t na = (ptrdiff_t)D->globals[-n] - (ptrdiff_t)cp + 4;
|
ptrdiff_t na = (ptrdiff_t)D->globals[-n-10] - (ptrdiff_t)cp + 4;
|
||||||
n = (int)na;
|
n = (int)na;
|
||||||
CK((ptrdiff_t)n == na, RANGE_REL);
|
CK((ptrdiff_t)n == na, RANGE_REL);
|
||||||
goto patchrel;
|
goto patchrel;
|
||||||
@@ -487,7 +482,7 @@ int dasm_encode(Dst_DECL, void *buffer)
|
|||||||
goto patchrel;
|
goto patchrel;
|
||||||
}
|
}
|
||||||
case DASM_LABEL_LG:
|
case DASM_LABEL_LG:
|
||||||
ins &= 2047; if (ins >= 20) D->globals[ins-10] = (void *)(base + n);
|
ins &= 2047; if (ins >= 20) D->globals[ins-20] = (void *)(base + n);
|
||||||
break;
|
break;
|
||||||
case DASM_LABEL_PC: break;
|
case DASM_LABEL_PC: break;
|
||||||
case DASM_IMM:
|
case DASM_IMM:
|
||||||
|
|||||||
@@ -823,6 +823,13 @@ map_op = {
|
|||||||
tbz_3 = "36000000DTBw|36000000DTBx",
|
tbz_3 = "36000000DTBw|36000000DTBx",
|
||||||
tbnz_3 = "37000000DTBw|37000000DTBx",
|
tbnz_3 = "37000000DTBw|37000000DTBx",
|
||||||
|
|
||||||
|
-- ARM64e: Pointer authentication codes (PAC).
|
||||||
|
blraaz_1 = "d63f081fNx",
|
||||||
|
braa_2 = "d71f0800NDx",
|
||||||
|
braaz_1 = "d61f081fNx",
|
||||||
|
pacibsp_0 = "d503237f",
|
||||||
|
retab_0 = "d65f0fff",
|
||||||
|
|
||||||
-- Miscellaneous instructions.
|
-- Miscellaneous instructions.
|
||||||
-- TODO: hlt, hvc, smc, svc, eret, dcps[123], drps, mrs, msr
|
-- TODO: hlt, hvc, smc, svc, eret, dcps[123], drps, mrs, msr
|
||||||
-- TODO: sys, sysl, ic, dc, at, tlbi
|
-- TODO: sys, sysl, ic, dc, at, tlbi
|
||||||
|
|||||||
@@ -69,7 +69,7 @@ struct dasm_State {
|
|||||||
size_t lgsize;
|
size_t lgsize;
|
||||||
int *pclabels; /* PC label chains/pos ptrs. */
|
int *pclabels; /* PC label chains/pos ptrs. */
|
||||||
size_t pcsize;
|
size_t pcsize;
|
||||||
void **globals; /* Array of globals (bias -10). */
|
void **globals; /* Array of globals. */
|
||||||
dasm_Section *section; /* Pointer to active section. */
|
dasm_Section *section; /* Pointer to active section. */
|
||||||
size_t codesize; /* Total size of all code sections. */
|
size_t codesize; /* Total size of all code sections. */
|
||||||
int maxsection; /* 0 <= sectionidx < maxsection. */
|
int maxsection; /* 0 <= sectionidx < maxsection. */
|
||||||
@@ -86,7 +86,6 @@ void dasm_init(Dst_DECL, int maxsection)
|
|||||||
{
|
{
|
||||||
dasm_State *D;
|
dasm_State *D;
|
||||||
size_t psz = 0;
|
size_t psz = 0;
|
||||||
int i;
|
|
||||||
Dst_REF = NULL;
|
Dst_REF = NULL;
|
||||||
DASM_M_GROW(Dst, struct dasm_State, Dst_REF, psz, DASM_PSZ(maxsection));
|
DASM_M_GROW(Dst, struct dasm_State, Dst_REF, psz, DASM_PSZ(maxsection));
|
||||||
D = Dst_REF;
|
D = Dst_REF;
|
||||||
@@ -97,12 +96,7 @@ void dasm_init(Dst_DECL, int maxsection)
|
|||||||
D->pcsize = 0;
|
D->pcsize = 0;
|
||||||
D->globals = NULL;
|
D->globals = NULL;
|
||||||
D->maxsection = maxsection;
|
D->maxsection = maxsection;
|
||||||
for (i = 0; i < maxsection; i++) {
|
memset((void *)D->sections, 0, maxsection * sizeof(dasm_Section));
|
||||||
D->sections[i].buf = NULL; /* Need this for pass3. */
|
|
||||||
D->sections[i].rbuf = D->sections[i].buf - DASM_SEC2POS(i);
|
|
||||||
D->sections[i].bsize = 0;
|
|
||||||
D->sections[i].epos = 0; /* Wrong, but is recalculated after resize. */
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Free DynASM state. */
|
/* Free DynASM state. */
|
||||||
@@ -122,7 +116,7 @@ void dasm_free(Dst_DECL)
|
|||||||
void dasm_setupglobal(Dst_DECL, void **gl, unsigned int maxgl)
|
void dasm_setupglobal(Dst_DECL, void **gl, unsigned int maxgl)
|
||||||
{
|
{
|
||||||
dasm_State *D = Dst_REF;
|
dasm_State *D = Dst_REF;
|
||||||
D->globals = gl - 10; /* Negative bias to compensate for locals. */
|
D->globals = gl;
|
||||||
DASM_M_GROW(Dst, int, D->lglabels, D->lgsize, (10+maxgl)*sizeof(int));
|
DASM_M_GROW(Dst, int, D->lglabels, D->lgsize, (10+maxgl)*sizeof(int));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -147,6 +141,7 @@ void dasm_setup(Dst_DECL, const void *actionlist)
|
|||||||
if (D->pclabels) memset((void *)D->pclabels, 0, D->pcsize);
|
if (D->pclabels) memset((void *)D->pclabels, 0, D->pcsize);
|
||||||
for (i = 0; i < D->maxsection; i++) {
|
for (i = 0; i < D->maxsection; i++) {
|
||||||
D->sections[i].pos = DASM_SEC2POS(i);
|
D->sections[i].pos = DASM_SEC2POS(i);
|
||||||
|
D->sections[i].rbuf = D->sections[i].buf - D->sections[i].pos;
|
||||||
D->sections[i].ofs = 0;
|
D->sections[i].ofs = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -350,7 +345,7 @@ int dasm_encode(Dst_DECL, void *buffer)
|
|||||||
break;
|
break;
|
||||||
case DASM_REL_LG:
|
case DASM_REL_LG:
|
||||||
if (n < 0) {
|
if (n < 0) {
|
||||||
n = (int)((ptrdiff_t)D->globals[-n] - (ptrdiff_t)cp);
|
n = (int)((ptrdiff_t)D->globals[-n-10] - (ptrdiff_t)cp);
|
||||||
goto patchrel;
|
goto patchrel;
|
||||||
}
|
}
|
||||||
/* fallthrough */
|
/* fallthrough */
|
||||||
@@ -369,7 +364,7 @@ int dasm_encode(Dst_DECL, void *buffer)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case DASM_LABEL_LG:
|
case DASM_LABEL_LG:
|
||||||
ins &= 2047; if (ins >= 20) D->globals[ins-10] = (void *)(base + n);
|
ins &= 2047; if (ins >= 20) D->globals[ins-20] = (void *)(base + n);
|
||||||
break;
|
break;
|
||||||
case DASM_LABEL_PC: break;
|
case DASM_LABEL_PC: break;
|
||||||
case DASM_IMMS:
|
case DASM_IMMS:
|
||||||
|
|||||||
@@ -69,7 +69,7 @@ struct dasm_State {
|
|||||||
size_t lgsize;
|
size_t lgsize;
|
||||||
int *pclabels; /* PC label chains/pos ptrs. */
|
int *pclabels; /* PC label chains/pos ptrs. */
|
||||||
size_t pcsize;
|
size_t pcsize;
|
||||||
void **globals; /* Array of globals (bias -10). */
|
void **globals; /* Array of globals. */
|
||||||
dasm_Section *section; /* Pointer to active section. */
|
dasm_Section *section; /* Pointer to active section. */
|
||||||
size_t codesize; /* Total size of all code sections. */
|
size_t codesize; /* Total size of all code sections. */
|
||||||
int maxsection; /* 0 <= sectionidx < maxsection. */
|
int maxsection; /* 0 <= sectionidx < maxsection. */
|
||||||
@@ -86,7 +86,6 @@ void dasm_init(Dst_DECL, int maxsection)
|
|||||||
{
|
{
|
||||||
dasm_State *D;
|
dasm_State *D;
|
||||||
size_t psz = 0;
|
size_t psz = 0;
|
||||||
int i;
|
|
||||||
Dst_REF = NULL;
|
Dst_REF = NULL;
|
||||||
DASM_M_GROW(Dst, struct dasm_State, Dst_REF, psz, DASM_PSZ(maxsection));
|
DASM_M_GROW(Dst, struct dasm_State, Dst_REF, psz, DASM_PSZ(maxsection));
|
||||||
D = Dst_REF;
|
D = Dst_REF;
|
||||||
@@ -97,12 +96,7 @@ void dasm_init(Dst_DECL, int maxsection)
|
|||||||
D->pcsize = 0;
|
D->pcsize = 0;
|
||||||
D->globals = NULL;
|
D->globals = NULL;
|
||||||
D->maxsection = maxsection;
|
D->maxsection = maxsection;
|
||||||
for (i = 0; i < maxsection; i++) {
|
memset((void *)D->sections, 0, maxsection * sizeof(dasm_Section));
|
||||||
D->sections[i].buf = NULL; /* Need this for pass3. */
|
|
||||||
D->sections[i].rbuf = D->sections[i].buf - DASM_SEC2POS(i);
|
|
||||||
D->sections[i].bsize = 0;
|
|
||||||
D->sections[i].epos = 0; /* Wrong, but is recalculated after resize. */
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Free DynASM state. */
|
/* Free DynASM state. */
|
||||||
@@ -122,7 +116,7 @@ void dasm_free(Dst_DECL)
|
|||||||
void dasm_setupglobal(Dst_DECL, void **gl, unsigned int maxgl)
|
void dasm_setupglobal(Dst_DECL, void **gl, unsigned int maxgl)
|
||||||
{
|
{
|
||||||
dasm_State *D = Dst_REF;
|
dasm_State *D = Dst_REF;
|
||||||
D->globals = gl - 10; /* Negative bias to compensate for locals. */
|
D->globals = gl;
|
||||||
DASM_M_GROW(Dst, int, D->lglabels, D->lgsize, (10+maxgl)*sizeof(int));
|
DASM_M_GROW(Dst, int, D->lglabels, D->lgsize, (10+maxgl)*sizeof(int));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -147,6 +141,7 @@ void dasm_setup(Dst_DECL, const void *actionlist)
|
|||||||
if (D->pclabels) memset((void *)D->pclabels, 0, D->pcsize);
|
if (D->pclabels) memset((void *)D->pclabels, 0, D->pcsize);
|
||||||
for (i = 0; i < D->maxsection; i++) {
|
for (i = 0; i < D->maxsection; i++) {
|
||||||
D->sections[i].pos = DASM_SEC2POS(i);
|
D->sections[i].pos = DASM_SEC2POS(i);
|
||||||
|
D->sections[i].rbuf = D->sections[i].buf - D->sections[i].pos;
|
||||||
D->sections[i].ofs = 0;
|
D->sections[i].ofs = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -354,7 +349,7 @@ int dasm_encode(Dst_DECL, void *buffer)
|
|||||||
break;
|
break;
|
||||||
case DASM_REL_LG:
|
case DASM_REL_LG:
|
||||||
if (n < 0) {
|
if (n < 0) {
|
||||||
n = (int)((ptrdiff_t)D->globals[-n] - (ptrdiff_t)cp);
|
n = (int)((ptrdiff_t)D->globals[-n-10] - (ptrdiff_t)cp);
|
||||||
goto patchrel;
|
goto patchrel;
|
||||||
}
|
}
|
||||||
/* fallthrough */
|
/* fallthrough */
|
||||||
@@ -368,7 +363,7 @@ int dasm_encode(Dst_DECL, void *buffer)
|
|||||||
cp[-1] |= ((n+4) & ((ins & 2048) ? 0x0000fffc: 0x03fffffc));
|
cp[-1] |= ((n+4) & ((ins & 2048) ? 0x0000fffc: 0x03fffffc));
|
||||||
break;
|
break;
|
||||||
case DASM_LABEL_LG:
|
case DASM_LABEL_LG:
|
||||||
ins &= 2047; if (ins >= 20) D->globals[ins-10] = (void *)(base + n);
|
ins &= 2047; if (ins >= 20) D->globals[ins-20] = (void *)(base + n);
|
||||||
break;
|
break;
|
||||||
case DASM_LABEL_PC: break;
|
case DASM_LABEL_PC: break;
|
||||||
case DASM_IMM:
|
case DASM_IMM:
|
||||||
|
|||||||
@@ -68,7 +68,7 @@ struct dasm_State {
|
|||||||
size_t lgsize;
|
size_t lgsize;
|
||||||
int *pclabels; /* PC label chains/pos ptrs. */
|
int *pclabels; /* PC label chains/pos ptrs. */
|
||||||
size_t pcsize;
|
size_t pcsize;
|
||||||
void **globals; /* Array of globals (bias -10). */
|
void **globals; /* Array of globals. */
|
||||||
dasm_Section *section; /* Pointer to active section. */
|
dasm_Section *section; /* Pointer to active section. */
|
||||||
size_t codesize; /* Total size of all code sections. */
|
size_t codesize; /* Total size of all code sections. */
|
||||||
int maxsection; /* 0 <= sectionidx < maxsection. */
|
int maxsection; /* 0 <= sectionidx < maxsection. */
|
||||||
@@ -85,7 +85,6 @@ void dasm_init(Dst_DECL, int maxsection)
|
|||||||
{
|
{
|
||||||
dasm_State *D;
|
dasm_State *D;
|
||||||
size_t psz = 0;
|
size_t psz = 0;
|
||||||
int i;
|
|
||||||
Dst_REF = NULL;
|
Dst_REF = NULL;
|
||||||
DASM_M_GROW(Dst, struct dasm_State, Dst_REF, psz, DASM_PSZ(maxsection));
|
DASM_M_GROW(Dst, struct dasm_State, Dst_REF, psz, DASM_PSZ(maxsection));
|
||||||
D = Dst_REF;
|
D = Dst_REF;
|
||||||
@@ -96,12 +95,7 @@ void dasm_init(Dst_DECL, int maxsection)
|
|||||||
D->pcsize = 0;
|
D->pcsize = 0;
|
||||||
D->globals = NULL;
|
D->globals = NULL;
|
||||||
D->maxsection = maxsection;
|
D->maxsection = maxsection;
|
||||||
for (i = 0; i < maxsection; i++) {
|
memset((void *)D->sections, 0, maxsection * sizeof(dasm_Section));
|
||||||
D->sections[i].buf = NULL; /* Need this for pass3. */
|
|
||||||
D->sections[i].rbuf = D->sections[i].buf - DASM_SEC2POS(i);
|
|
||||||
D->sections[i].bsize = 0;
|
|
||||||
D->sections[i].epos = 0; /* Wrong, but is recalculated after resize. */
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Free DynASM state. */
|
/* Free DynASM state. */
|
||||||
@@ -121,7 +115,7 @@ void dasm_free(Dst_DECL)
|
|||||||
void dasm_setupglobal(Dst_DECL, void **gl, unsigned int maxgl)
|
void dasm_setupglobal(Dst_DECL, void **gl, unsigned int maxgl)
|
||||||
{
|
{
|
||||||
dasm_State *D = Dst_REF;
|
dasm_State *D = Dst_REF;
|
||||||
D->globals = gl - 10; /* Negative bias to compensate for locals. */
|
D->globals = gl;
|
||||||
DASM_M_GROW(Dst, int, D->lglabels, D->lgsize, (10+maxgl)*sizeof(int));
|
DASM_M_GROW(Dst, int, D->lglabels, D->lgsize, (10+maxgl)*sizeof(int));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -146,6 +140,7 @@ void dasm_setup(Dst_DECL, const void *actionlist)
|
|||||||
if (D->pclabels) memset((void *)D->pclabels, 0, D->pcsize);
|
if (D->pclabels) memset((void *)D->pclabels, 0, D->pcsize);
|
||||||
for (i = 0; i < D->maxsection; i++) {
|
for (i = 0; i < D->maxsection; i++) {
|
||||||
D->sections[i].pos = DASM_SEC2POS(i);
|
D->sections[i].pos = DASM_SEC2POS(i);
|
||||||
|
D->sections[i].rbuf = D->sections[i].buf - D->sections[i].pos;
|
||||||
D->sections[i].ofs = 0;
|
D->sections[i].ofs = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -445,7 +440,7 @@ int dasm_encode(Dst_DECL, void *buffer)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case DASM_REL_LG: p++; if (n >= 0) goto rel_pc;
|
case DASM_REL_LG: p++; if (n >= 0) goto rel_pc;
|
||||||
b++; n = (int)(ptrdiff_t)D->globals[-n];
|
b++; n = (int)(ptrdiff_t)D->globals[-n-10];
|
||||||
/* fallthrough */
|
/* fallthrough */
|
||||||
case DASM_REL_A: rel_a:
|
case DASM_REL_A: rel_a:
|
||||||
n -= (unsigned int)(ptrdiff_t)(cp+4); goto wd; /* !x64 */
|
n -= (unsigned int)(ptrdiff_t)(cp+4); goto wd; /* !x64 */
|
||||||
@@ -459,7 +454,7 @@ int dasm_encode(Dst_DECL, void *buffer)
|
|||||||
}
|
}
|
||||||
case DASM_IMM_LG:
|
case DASM_IMM_LG:
|
||||||
p++;
|
p++;
|
||||||
if (n < 0) { dasma((ptrdiff_t)D->globals[-n]); break; }
|
if (n < 0) { dasma((ptrdiff_t)D->globals[-n-10]); break; }
|
||||||
/* fallthrough */
|
/* fallthrough */
|
||||||
case DASM_IMM_PC: {
|
case DASM_IMM_PC: {
|
||||||
int *pb = DASM_POS2PTR(D, n);
|
int *pb = DASM_POS2PTR(D, n);
|
||||||
@@ -469,7 +464,7 @@ int dasm_encode(Dst_DECL, void *buffer)
|
|||||||
case DASM_LABEL_LG: {
|
case DASM_LABEL_LG: {
|
||||||
int idx = *p++;
|
int idx = *p++;
|
||||||
if (idx >= 10)
|
if (idx >= 10)
|
||||||
D->globals[idx] = (void *)(base + (*p == DASM_SETLABEL ? *b : n));
|
D->globals[idx-10] = (void *)(base + (*p == DASM_SETLABEL ? *b : n));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case DASM_LABEL_PC: case DASM_SETLABEL: break;
|
case DASM_LABEL_PC: case DASM_SETLABEL: break;
|
||||||
|
|||||||
@@ -433,6 +433,10 @@ ifneq (,$(findstring LJ_NO_UNWIND 1,$(TARGET_TESTARCH)))
|
|||||||
DASM_AFLAGS+= -D NO_UNWIND
|
DASM_AFLAGS+= -D NO_UNWIND
|
||||||
TARGET_ARCH+= -DLUAJIT_NO_UNWIND
|
TARGET_ARCH+= -DLUAJIT_NO_UNWIND
|
||||||
endif
|
endif
|
||||||
|
ifneq (,$(findstring LJ_ABI_PAUTH 1,$(TARGET_TESTARCH)))
|
||||||
|
DASM_AFLAGS+= -D PAUTH
|
||||||
|
TARGET_ARCH+= -DLJ_ABI_PAUTH=1
|
||||||
|
endif
|
||||||
DASM_AFLAGS+= -D VER=$(subst LJ_ARCH_VERSION_,,$(filter LJ_ARCH_VERSION_%,$(subst LJ_ARCH_VERSION ,LJ_ARCH_VERSION_,$(TARGET_TESTARCH))))
|
DASM_AFLAGS+= -D VER=$(subst LJ_ARCH_VERSION_,,$(filter LJ_ARCH_VERSION_%,$(subst LJ_ARCH_VERSION ,LJ_ARCH_VERSION_,$(TARGET_TESTARCH))))
|
||||||
ifeq (Windows,$(TARGET_SYS))
|
ifeq (Windows,$(TARGET_SYS))
|
||||||
DASM_AFLAGS+= -D WIN
|
DASM_AFLAGS+= -D WIN
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
lib_aux.o: lib_aux.c lua.h luaconf.h lauxlib.h lj_obj.h lj_def.h \
|
lib_aux.o: lib_aux.c lua.h luaconf.h lauxlib.h lj_obj.h lj_def.h \
|
||||||
lj_arch.h lj_err.h lj_errmsg.h lj_state.h lj_trace.h lj_jit.h lj_ir.h \
|
lj_arch.h lj_err.h lj_errmsg.h lj_state.h lj_trace.h lj_jit.h lj_ir.h \
|
||||||
lj_dispatch.h lj_bc.h lj_traceerr.h lj_lib.h
|
lj_dispatch.h lj_bc.h lj_traceerr.h lj_lib.h lj_vmevent.h
|
||||||
lib_base.o: lib_base.c lua.h luaconf.h lauxlib.h lualib.h lj_obj.h \
|
lib_base.o: lib_base.c lua.h luaconf.h lauxlib.h lualib.h lj_obj.h \
|
||||||
lj_def.h lj_arch.h lj_gc.h lj_err.h lj_errmsg.h lj_debug.h lj_buf.h \
|
lj_def.h lj_arch.h lj_gc.h lj_err.h lj_errmsg.h lj_debug.h lj_buf.h \
|
||||||
lj_str.h lj_tab.h lj_meta.h lj_state.h lj_frame.h lj_bc.h lj_ctype.h \
|
lj_str.h lj_tab.h lj_meta.h lj_state.h lj_frame.h lj_bc.h lj_ctype.h \
|
||||||
@@ -124,7 +124,7 @@ lj_func.o: lj_func.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h lj_gc.h \
|
|||||||
lj_gc.o: lj_gc.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h lj_gc.h \
|
lj_gc.o: lj_gc.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h lj_gc.h \
|
||||||
lj_err.h lj_errmsg.h lj_buf.h lj_str.h lj_tab.h lj_func.h lj_udata.h \
|
lj_err.h lj_errmsg.h lj_buf.h lj_str.h lj_tab.h lj_func.h lj_udata.h \
|
||||||
lj_meta.h lj_state.h lj_frame.h lj_bc.h lj_ctype.h lj_cdata.h lj_trace.h \
|
lj_meta.h lj_state.h lj_frame.h lj_bc.h lj_ctype.h lj_cdata.h lj_trace.h \
|
||||||
lj_jit.h lj_ir.h lj_dispatch.h lj_traceerr.h lj_vm.h
|
lj_jit.h lj_ir.h lj_dispatch.h lj_traceerr.h lj_vm.h lj_vmevent.h
|
||||||
lj_gdbjit.o: lj_gdbjit.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
|
lj_gdbjit.o: lj_gdbjit.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
|
||||||
lj_gc.h lj_err.h lj_errmsg.h lj_debug.h lj_frame.h lj_bc.h lj_buf.h \
|
lj_gc.h lj_err.h lj_errmsg.h lj_debug.h lj_frame.h lj_bc.h lj_buf.h \
|
||||||
lj_str.h lj_strfmt.h lj_jit.h lj_ir.h lj_dispatch.h
|
lj_str.h lj_strfmt.h lj_jit.h lj_ir.h lj_dispatch.h
|
||||||
@@ -222,25 +222,25 @@ ljamalg.o: ljamalg.c lua.h luaconf.h lauxlib.h lj_assert.c lj_obj.h \
|
|||||||
lj_def.h lj_arch.h lj_gc.c lj_gc.h lj_err.h lj_errmsg.h lj_buf.h \
|
lj_def.h lj_arch.h lj_gc.c lj_gc.h lj_err.h lj_errmsg.h lj_buf.h \
|
||||||
lj_str.h lj_tab.h lj_func.h lj_udata.h lj_meta.h lj_state.h lj_frame.h \
|
lj_str.h lj_tab.h lj_func.h lj_udata.h lj_meta.h lj_state.h lj_frame.h \
|
||||||
lj_bc.h lj_ctype.h lj_cdata.h lj_trace.h lj_jit.h lj_ir.h lj_dispatch.h \
|
lj_bc.h lj_ctype.h lj_cdata.h lj_trace.h lj_jit.h lj_ir.h lj_dispatch.h \
|
||||||
lj_traceerr.h lj_vm.h lj_err.c lj_debug.h lj_ff.h lj_ffdef.h lj_strfmt.h \
|
lj_traceerr.h lj_vm.h lj_vmevent.h lj_err.c lj_debug.h lj_ff.h \
|
||||||
lj_char.c lj_char.h lj_bc.c lj_bcdef.h lj_obj.c lj_buf.c lj_str.c \
|
lj_ffdef.h lj_strfmt.h lj_char.c lj_char.h lj_bc.c lj_bcdef.h lj_obj.c \
|
||||||
lj_prng.h lj_tab.c lj_func.c lj_udata.c lj_meta.c lj_strscan.h lj_lib.h \
|
lj_buf.c lj_str.c lj_prng.h lj_tab.c lj_func.c lj_udata.c lj_meta.c \
|
||||||
lj_debug.c lj_prng.c lj_state.c lj_lex.h lj_alloc.h luajit.h \
|
lj_strscan.h lj_lib.h lj_debug.c lj_prng.c lj_state.c lj_lex.h \
|
||||||
lj_dispatch.c lj_ccallback.h lj_profile.h lj_vmevent.c lj_vmevent.h \
|
lj_alloc.h luajit.h lj_dispatch.c lj_ccallback.h lj_profile.h \
|
||||||
lj_vmmath.c lj_strscan.c lj_strfmt.c lj_strfmt_num.c lj_serialize.c \
|
lj_vmevent.c lj_vmmath.c lj_strscan.c lj_strfmt.c lj_strfmt_num.c \
|
||||||
lj_serialize.h lj_api.c lj_profile.c lj_lex.c lualib.h lj_parse.h \
|
lj_serialize.c lj_serialize.h lj_api.c lj_profile.c lj_lex.c lualib.h \
|
||||||
lj_parse.c lj_bcread.c lj_bcdump.h lj_bcwrite.c lj_load.c lj_ctype.c \
|
lj_parse.h lj_parse.c lj_bcread.c lj_bcdump.h lj_bcwrite.c lj_load.c \
|
||||||
lj_cdata.c lj_cconv.h lj_cconv.c lj_ccall.c lj_ccall.h lj_ccallback.c \
|
lj_ctype.c lj_cdata.c lj_cconv.h lj_cconv.c lj_ccall.c lj_ccall.h \
|
||||||
lj_target.h lj_target_*.h lj_mcode.h lj_carith.c lj_carith.h lj_clib.c \
|
lj_ccallback.c lj_target.h lj_target_*.h lj_mcode.h lj_carith.c \
|
||||||
lj_clib.h lj_cparse.c lj_cparse.h lj_lib.c lj_ir.c lj_ircall.h \
|
lj_carith.h lj_clib.c lj_clib.h lj_cparse.c lj_cparse.h lj_lib.c lj_ir.c \
|
||||||
lj_iropt.h lj_opt_mem.c lj_opt_fold.c lj_folddef.h lj_opt_narrow.c \
|
lj_ircall.h lj_iropt.h lj_opt_mem.c lj_opt_fold.c lj_folddef.h \
|
||||||
lj_opt_dce.c lj_opt_loop.c lj_snap.h lj_opt_split.c lj_opt_sink.c \
|
lj_opt_narrow.c lj_opt_dce.c lj_opt_loop.c lj_snap.h lj_opt_split.c \
|
||||||
lj_mcode.c lj_snap.c lj_record.c lj_record.h lj_ffrecord.h lj_crecord.c \
|
lj_opt_sink.c lj_mcode.c lj_snap.c lj_record.c lj_record.h lj_ffrecord.h \
|
||||||
lj_crecord.h lj_ffrecord.c lj_recdef.h lj_asm.c lj_asm.h lj_emit_*.h \
|
lj_crecord.c lj_crecord.h lj_ffrecord.c lj_recdef.h lj_asm.c lj_asm.h \
|
||||||
lj_asm_*.h lj_trace.c lj_gdbjit.h lj_gdbjit.c lj_alloc.c lib_aux.c \
|
lj_emit_*.h lj_asm_*.h lj_trace.c lj_gdbjit.h lj_gdbjit.c lj_alloc.c \
|
||||||
lib_base.c lj_libdef.h lib_math.c lib_string.c lib_table.c lib_io.c \
|
lib_aux.c lib_base.c lj_libdef.h lib_math.c lib_string.c lib_table.c \
|
||||||
lib_os.c lib_package.c lib_debug.c lib_bit.c lib_jit.c lib_ffi.c \
|
lib_io.c lib_os.c lib_package.c lib_debug.c lib_bit.c lib_jit.c \
|
||||||
lib_buffer.c lib_init.c
|
lib_ffi.c lib_buffer.c lib_init.c
|
||||||
luajit.o: luajit.c lua.h luaconf.h lauxlib.h lualib.h luajit.h lj_arch.h
|
luajit.o: luajit.c lua.h luaconf.h lauxlib.h lualib.h luajit.h lj_arch.h
|
||||||
host/buildvm.o: host/buildvm.c host/buildvm.h lj_def.h lua.h luaconf.h \
|
host/buildvm.o: host/buildvm.c host/buildvm.h lj_def.h lua.h luaconf.h \
|
||||||
lj_arch.h lj_obj.h lj_def.h lj_arch.h lj_gc.h lj_obj.h lj_bc.h lj_ir.h \
|
lj_arch.h lj_obj.h lj_def.h lj_arch.h lj_gc.h lj_obj.h lj_bc.h lj_ir.h \
|
||||||
|
|||||||
@@ -243,6 +243,12 @@ void emit_asm(BuildCtx *ctx)
|
|||||||
|
|
||||||
fprintf(ctx->fp, "\t.file \"buildvm_%s.dasc\"\n", ctx->dasm_arch);
|
fprintf(ctx->fp, "\t.file \"buildvm_%s.dasc\"\n", ctx->dasm_arch);
|
||||||
fprintf(ctx->fp, "\t.text\n");
|
fprintf(ctx->fp, "\t.text\n");
|
||||||
|
#if LJ_TARGET_MIPS32 && !LJ_ABI_SOFTFP
|
||||||
|
fprintf(ctx->fp, "\t.module fp=32\n");
|
||||||
|
#endif
|
||||||
|
#if LJ_TARGET_MIPS
|
||||||
|
fprintf(ctx->fp, "\t.set nomips16\n\t.abicalls\n\t.set noreorder\n\t.set nomacro\n");
|
||||||
|
#endif
|
||||||
emit_asm_align(ctx, 4);
|
emit_asm_align(ctx, 4);
|
||||||
|
|
||||||
#if LJ_TARGET_PS3
|
#if LJ_TARGET_PS3
|
||||||
@@ -268,9 +274,6 @@ void emit_asm(BuildCtx *ctx)
|
|||||||
".save {r4, r5, r6, r7, r8, r9, r10, r11, lr}\n"
|
".save {r4, r5, r6, r7, r8, r9, r10, r11, lr}\n"
|
||||||
".pad #28\n");
|
".pad #28\n");
|
||||||
#endif
|
#endif
|
||||||
#endif
|
|
||||||
#if LJ_TARGET_MIPS
|
|
||||||
fprintf(ctx->fp, ".set nomips16\n.abicalls\n.set noreorder\n.set nomacro\n");
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
for (i = rel = 0; i < ctx->nsym; i++) {
|
for (i = rel = 0; i < ctx->nsym; i++) {
|
||||||
|
|||||||
@@ -379,13 +379,20 @@ void emit_lib(BuildCtx *ctx)
|
|||||||
/* Simplistic pre-processor. Only handles top-level #if/#endif. */
|
/* Simplistic pre-processor. Only handles top-level #if/#endif. */
|
||||||
if (buf[0] == '#' && buf[1] == 'i' && buf[2] == 'f') {
|
if (buf[0] == '#' && buf[1] == 'i' && buf[2] == 'f') {
|
||||||
int ok = 1;
|
int ok = 1;
|
||||||
if (!strcmp(buf, "#if LJ_52\n"))
|
size_t len = strlen(buf);
|
||||||
|
if (buf[len-1] == '\n') {
|
||||||
|
buf[len-1] = 0;
|
||||||
|
if (buf[len-2] == '\r') {
|
||||||
|
buf[len-2] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!strcmp(buf, "#if LJ_52"))
|
||||||
ok = LJ_52;
|
ok = LJ_52;
|
||||||
else if (!strcmp(buf, "#if LJ_HASJIT\n"))
|
else if (!strcmp(buf, "#if LJ_HASJIT"))
|
||||||
ok = LJ_HASJIT;
|
ok = LJ_HASJIT;
|
||||||
else if (!strcmp(buf, "#if LJ_HASFFI\n"))
|
else if (!strcmp(buf, "#if LJ_HASFFI"))
|
||||||
ok = LJ_HASFFI;
|
ok = LJ_HASFFI;
|
||||||
else if (!strcmp(buf, "#if LJ_HASBUFFER\n"))
|
else if (!strcmp(buf, "#if LJ_HASBUFFER"))
|
||||||
ok = LJ_HASBUFFER;
|
ok = LJ_HASBUFFER;
|
||||||
if (!ok) {
|
if (!ok) {
|
||||||
int lvl = 1;
|
int lvl = 1;
|
||||||
|
|||||||
@@ -21,6 +21,7 @@
|
|||||||
#include "lj_state.h"
|
#include "lj_state.h"
|
||||||
#include "lj_trace.h"
|
#include "lj_trace.h"
|
||||||
#include "lj_lib.h"
|
#include "lj_lib.h"
|
||||||
|
#include "lj_vmevent.h"
|
||||||
|
|
||||||
#if LJ_TARGET_POSIX
|
#if LJ_TARGET_POSIX
|
||||||
#include <sys/wait.h>
|
#include <sys/wait.h>
|
||||||
@@ -318,6 +319,18 @@ static int panic(lua_State *L)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef LUAJIT_DISABLE_VMEVENT
|
||||||
|
static int error_finalizer(lua_State *L)
|
||||||
|
{
|
||||||
|
const char *s = lua_tostring(L, -1);
|
||||||
|
fputs("ERROR in finalizer: ", stderr);
|
||||||
|
fputs(s ? s : "?", stderr);
|
||||||
|
fputc('\n', stderr);
|
||||||
|
fflush(stderr);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef LUAJIT_USE_SYSMALLOC
|
#ifdef LUAJIT_USE_SYSMALLOC
|
||||||
|
|
||||||
#if LJ_64 && !LJ_GC64 && !defined(LUAJIT_USE_VALGRIND)
|
#if LJ_64 && !LJ_GC64 && !defined(LUAJIT_USE_VALGRIND)
|
||||||
@@ -339,7 +352,16 @@ static void *mem_alloc(void *ud, void *ptr, size_t osize, size_t nsize)
|
|||||||
LUALIB_API lua_State *luaL_newstate(void)
|
LUALIB_API lua_State *luaL_newstate(void)
|
||||||
{
|
{
|
||||||
lua_State *L = lua_newstate(mem_alloc, NULL);
|
lua_State *L = lua_newstate(mem_alloc, NULL);
|
||||||
if (L) G(L)->panic = panic;
|
if (L) {
|
||||||
|
G(L)->panic = panic;
|
||||||
|
#ifndef LUAJIT_DISABLE_VMEVENT
|
||||||
|
luaL_findtable(L, LUA_REGISTRYINDEX, LJ_VMEVENTS_REGKEY, LJ_VMEVENTS_HSIZE);
|
||||||
|
lua_pushcfunction(L, error_finalizer);
|
||||||
|
lua_rawseti(L, -2, VMEVENT_HASH(LJ_VMEVENT_ERRFIN));
|
||||||
|
G(L)->vmevmask = VMEVENT_MASK(LJ_VMEVENT_ERRFIN);
|
||||||
|
L->top--;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
return L;
|
return L;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -353,7 +375,16 @@ LUALIB_API lua_State *luaL_newstate(void)
|
|||||||
#else
|
#else
|
||||||
L = lua_newstate(LJ_ALLOCF_INTERNAL, NULL);
|
L = lua_newstate(LJ_ALLOCF_INTERNAL, NULL);
|
||||||
#endif
|
#endif
|
||||||
if (L) G(L)->panic = panic;
|
if (L) {
|
||||||
|
G(L)->panic = panic;
|
||||||
|
#ifndef LUAJIT_DISABLE_VMEVENT
|
||||||
|
luaL_findtable(L, LUA_REGISTRYINDEX, LJ_VMEVENTS_REGKEY, LJ_VMEVENTS_HSIZE);
|
||||||
|
lua_pushcfunction(L, error_finalizer);
|
||||||
|
lua_rawseti(L, -2, VMEVENT_HASH(LJ_VMEVENT_ERRFIN));
|
||||||
|
G(L)->vmevmask = VMEVENT_MASK(LJ_VMEVENT_ERRFIN);
|
||||||
|
L->top--;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
return L;
|
return L;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -303,7 +303,7 @@ LJLIB_ASM(tonumber) LJLIB_REC(.)
|
|||||||
while (lj_char_isspace((unsigned char)(*ep))) ep++;
|
while (lj_char_isspace((unsigned char)(*ep))) ep++;
|
||||||
if (*ep == '\0') {
|
if (*ep == '\0') {
|
||||||
if (LJ_DUALNUM && LJ_LIKELY(ul < 0x80000000u+neg)) {
|
if (LJ_DUALNUM && LJ_LIKELY(ul < 0x80000000u+neg)) {
|
||||||
if (neg) ul = (unsigned long)-(long)ul;
|
if (neg) ul = ~ul+1u;
|
||||||
setintV(L->base-1-LJ_FR2, (int32_t)ul);
|
setintV(L->base-1-LJ_FR2, (int32_t)ul);
|
||||||
} else {
|
} else {
|
||||||
lua_Number n = (lua_Number)ul;
|
lua_Number n = (lua_Number)ul;
|
||||||
|
|||||||
@@ -155,7 +155,8 @@ LJLIB_CF(bit_tohex) LJLIB_REC(.)
|
|||||||
#endif
|
#endif
|
||||||
SBuf *sb = lj_buf_tmp_(L);
|
SBuf *sb = lj_buf_tmp_(L);
|
||||||
SFormat sf = (STRFMT_UINT|STRFMT_T_HEX);
|
SFormat sf = (STRFMT_UINT|STRFMT_T_HEX);
|
||||||
if (n < 0) { n = -n; sf |= STRFMT_F_UPPER; }
|
if (n < 0) { n = (int32_t)(~(uint32_t)n+1u); sf |= STRFMT_F_UPPER; }
|
||||||
|
if ((uint32_t)n > 254) n = 254;
|
||||||
sf |= ((SFormat)((n+1)&255) << STRFMT_SH_PREC);
|
sf |= ((SFormat)((n+1)&255) << STRFMT_SH_PREC);
|
||||||
#if LJ_HASFFI
|
#if LJ_HASFFI
|
||||||
if (n < 16) b &= ((uint64_t)1 << 4*n)-1;
|
if (n < 16) b &= ((uint64_t)1 << 4*n)-1;
|
||||||
|
|||||||
@@ -745,6 +745,9 @@ LJLIB_CF(ffi_abi) LJLIB_REC(.)
|
|||||||
#if LJ_ABI_WIN
|
#if LJ_ABI_WIN
|
||||||
"\003win"
|
"\003win"
|
||||||
#endif
|
#endif
|
||||||
|
#if LJ_ABI_PAUTH
|
||||||
|
"\007pauth"
|
||||||
|
#endif
|
||||||
#if LJ_TARGET_UWP
|
#if LJ_TARGET_UWP
|
||||||
"\003uwp"
|
"\003uwp"
|
||||||
#endif
|
#endif
|
||||||
@@ -776,7 +779,7 @@ LJLIB_CF(ffi_metatype)
|
|||||||
if (!(ctype_isstruct(ct->info) || ctype_iscomplex(ct->info) ||
|
if (!(ctype_isstruct(ct->info) || ctype_iscomplex(ct->info) ||
|
||||||
ctype_isvector(ct->info)))
|
ctype_isvector(ct->info)))
|
||||||
lj_err_arg(L, 1, LJ_ERR_FFI_INVTYPE);
|
lj_err_arg(L, 1, LJ_ERR_FFI_INVTYPE);
|
||||||
tv = lj_tab_setinth(L, t, -(int32_t)id);
|
tv = lj_tab_setinth(L, t, -(int32_t)ctype_typeid(cts, ct));
|
||||||
if (!tvisnil(tv))
|
if (!tvisnil(tv))
|
||||||
lj_err_caller(L, LJ_ERR_PROTMT);
|
lj_err_caller(L, LJ_ERR_PROTMT);
|
||||||
settabV(L, tv, mt);
|
settabV(L, tv, mt);
|
||||||
|
|||||||
@@ -422,7 +422,8 @@ LJLIB_CF(jit_util_ircalladdr)
|
|||||||
{
|
{
|
||||||
uint32_t idx = (uint32_t)lj_lib_checkint(L, 1);
|
uint32_t idx = (uint32_t)lj_lib_checkint(L, 1);
|
||||||
if (idx < IRCALL__MAX) {
|
if (idx < IRCALL__MAX) {
|
||||||
setintptrV(L->top-1, (intptr_t)(void *)lj_ir_callinfo[idx].func);
|
ASMFunction func = lj_ir_callinfo[idx].func;
|
||||||
|
setintptrV(L->top-1, (intptr_t)(void *)lj_ptr_strip(func));
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
@@ -259,6 +259,9 @@
|
|||||||
#define LJ_ARCH_NAME "arm64"
|
#define LJ_ARCH_NAME "arm64"
|
||||||
#define LJ_ARCH_ENDIAN LUAJIT_LE
|
#define LJ_ARCH_ENDIAN LUAJIT_LE
|
||||||
#endif
|
#endif
|
||||||
|
#if !defined(LJ_ABI_PAUTH) && defined(__arm64e__)
|
||||||
|
#define LJ_ABI_PAUTH 1
|
||||||
|
#endif
|
||||||
#define LJ_TARGET_ARM64 1
|
#define LJ_TARGET_ARM64 1
|
||||||
#define LJ_TARGET_EHRETREG 0
|
#define LJ_TARGET_EHRETREG 0
|
||||||
#define LJ_TARGET_EHRAREG 30
|
#define LJ_TARGET_EHRAREG 30
|
||||||
@@ -466,11 +469,17 @@
|
|||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
#elif !LJ_TARGET_PS3
|
#elif !LJ_TARGET_PS3
|
||||||
|
#if __clang__
|
||||||
|
#if ((__clang_major__ < 3) || ((__clang_major__ == 3) && __clang_minor__ < 5))
|
||||||
|
#error "Need at least Clang 3.5 or newer"
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
#if (__GNUC__ < 4) || ((__GNUC__ == 4) && __GNUC_MINOR__ < 3)
|
#if (__GNUC__ < 4) || ((__GNUC__ == 4) && __GNUC_MINOR__ < 3)
|
||||||
#error "Need at least GCC 4.3 or newer"
|
#error "Need at least GCC 4.3 or newer"
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Check target-specific constraints. */
|
/* Check target-specific constraints. */
|
||||||
#ifndef _BUILDVM_H
|
#ifndef _BUILDVM_H
|
||||||
@@ -597,6 +606,10 @@
|
|||||||
#define LJ_SOFTFP (!LJ_ARCH_HASFPU)
|
#define LJ_SOFTFP (!LJ_ARCH_HASFPU)
|
||||||
#define LJ_SOFTFP32 (LJ_SOFTFP && LJ_32)
|
#define LJ_SOFTFP32 (LJ_SOFTFP && LJ_32)
|
||||||
|
|
||||||
|
#ifndef LJ_ABI_PAUTH
|
||||||
|
#define LJ_ABI_PAUTH 0
|
||||||
|
#endif
|
||||||
|
|
||||||
#if LJ_ARCH_ENDIAN == LUAJIT_BE
|
#if LJ_ARCH_ENDIAN == LUAJIT_BE
|
||||||
#define LJ_LE 0
|
#define LJ_LE 0
|
||||||
#define LJ_BE 1
|
#define LJ_BE 1
|
||||||
|
|||||||
@@ -1888,6 +1888,8 @@ static void asm_head_side(ASMState *as)
|
|||||||
IRRef1 sloadins[RID_MAX];
|
IRRef1 sloadins[RID_MAX];
|
||||||
RegSet allow = RSET_ALL; /* Inverse of all coalesced registers. */
|
RegSet allow = RSET_ALL; /* Inverse of all coalesced registers. */
|
||||||
RegSet live = RSET_EMPTY; /* Live parent registers. */
|
RegSet live = RSET_EMPTY; /* Live parent registers. */
|
||||||
|
RegSet pallow = RSET_GPR; /* Registers needed by the parent stack check. */
|
||||||
|
Reg pbase;
|
||||||
IRIns *irp = &as->parent->ir[REF_BASE]; /* Parent base. */
|
IRIns *irp = &as->parent->ir[REF_BASE]; /* Parent base. */
|
||||||
int32_t spadj, spdelta;
|
int32_t spadj, spdelta;
|
||||||
int pass2 = 0;
|
int pass2 = 0;
|
||||||
@@ -1898,7 +1900,11 @@ static void asm_head_side(ASMState *as)
|
|||||||
/* Force snap #0 alloc to prevent register overwrite in stack check. */
|
/* Force snap #0 alloc to prevent register overwrite in stack check. */
|
||||||
asm_snap_alloc(as, 0);
|
asm_snap_alloc(as, 0);
|
||||||
}
|
}
|
||||||
allow = asm_head_side_base(as, irp, allow);
|
pbase = asm_head_side_base(as, irp);
|
||||||
|
if (pbase != RID_NONE) {
|
||||||
|
rset_clear(allow, pbase);
|
||||||
|
rset_clear(pallow, pbase);
|
||||||
|
}
|
||||||
|
|
||||||
/* Scan all parent SLOADs and collect register dependencies. */
|
/* Scan all parent SLOADs and collect register dependencies. */
|
||||||
for (i = as->stopins; i > REF_BASE; i--) {
|
for (i = as->stopins; i > REF_BASE; i--) {
|
||||||
@@ -1928,6 +1934,7 @@ static void asm_head_side(ASMState *as)
|
|||||||
sloadins[rs] = (IRRef1)i;
|
sloadins[rs] = (IRRef1)i;
|
||||||
rset_set(live, rs); /* Block live parent register. */
|
rset_set(live, rs); /* Block live parent register. */
|
||||||
}
|
}
|
||||||
|
if (!ra_hasspill(regsp_spill(rs))) rset_clear(pallow, regsp_reg(rs));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Calculate stack frame adjustment. */
|
/* Calculate stack frame adjustment. */
|
||||||
@@ -2044,7 +2051,7 @@ static void asm_head_side(ASMState *as)
|
|||||||
ExitNo exitno = as->J->exitno;
|
ExitNo exitno = as->J->exitno;
|
||||||
#endif
|
#endif
|
||||||
as->T->topslot = (uint8_t)as->topslot; /* Remember for child traces. */
|
as->T->topslot = (uint8_t)as->topslot; /* Remember for child traces. */
|
||||||
asm_stack_check(as, as->topslot, irp, allow & RSET_GPR, exitno);
|
asm_stack_check(as, as->topslot, irp, pallow, exitno);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -313,7 +313,11 @@ static void asm_fusexref(ASMState *as, ARMIns ai, Reg rd, IRRef ref,
|
|||||||
}
|
}
|
||||||
|
|
||||||
#if !LJ_SOFTFP
|
#if !LJ_SOFTFP
|
||||||
/* Fuse to multiply-add/sub instruction. */
|
/*
|
||||||
|
** Fuse to multiply-add/sub instruction.
|
||||||
|
** VMLA rounds twice (UMA, not FMA) -- no need to check for JIT_F_OPT_FMA.
|
||||||
|
** VFMA needs VFPv4, which is uncommon on the remaining ARM32 targets.
|
||||||
|
*/
|
||||||
static int asm_fusemadd(ASMState *as, IRIns *ir, ARMIns ai, ARMIns air)
|
static int asm_fusemadd(ASMState *as, IRIns *ir, ARMIns ai, ARMIns air)
|
||||||
{
|
{
|
||||||
IRRef lref = ir->op1, rref = ir->op2;
|
IRRef lref = ir->op1, rref = ir->op2;
|
||||||
@@ -2163,7 +2167,7 @@ static void asm_head_root_base(ASMState *as)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Coalesce BASE register for a side trace. */
|
/* Coalesce BASE register for a side trace. */
|
||||||
static RegSet asm_head_side_base(ASMState *as, IRIns *irp, RegSet allow)
|
static Reg asm_head_side_base(ASMState *as, IRIns *irp)
|
||||||
{
|
{
|
||||||
IRIns *ir;
|
IRIns *ir;
|
||||||
asm_head_lreg(as);
|
asm_head_lreg(as);
|
||||||
@@ -2171,16 +2175,15 @@ static RegSet asm_head_side_base(ASMState *as, IRIns *irp, RegSet allow)
|
|||||||
if (ra_hasreg(ir->r) && (rset_test(as->modset, ir->r) || irt_ismarked(ir->t)))
|
if (ra_hasreg(ir->r) && (rset_test(as->modset, ir->r) || irt_ismarked(ir->t)))
|
||||||
ra_spill(as, ir);
|
ra_spill(as, ir);
|
||||||
if (ra_hasspill(irp->s)) {
|
if (ra_hasspill(irp->s)) {
|
||||||
rset_clear(allow, ra_dest(as, ir, allow));
|
return ra_dest(as, ir, RSET_GPR);
|
||||||
} else {
|
} else {
|
||||||
Reg r = irp->r;
|
Reg r = irp->r;
|
||||||
lj_assertA(ra_hasreg(r), "base reg lost");
|
lj_assertA(ra_hasreg(r), "base reg lost");
|
||||||
rset_clear(allow, r);
|
|
||||||
if (r != ir->r && !rset_test(as->freeset, r))
|
if (r != ir->r && !rset_test(as->freeset, r))
|
||||||
ra_restore(as, regcost_ref(as->cost[r]));
|
ra_restore(as, regcost_ref(as->cost[r]));
|
||||||
ra_destreg(as, ir, r);
|
ra_destreg(as, ir, r);
|
||||||
|
return r;
|
||||||
}
|
}
|
||||||
return allow;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -- Tail of trace ------------------------------------------------------- */
|
/* -- Tail of trace ------------------------------------------------------- */
|
||||||
|
|||||||
@@ -337,7 +337,8 @@ static int asm_fusemadd(ASMState *as, IRIns *ir, A64Ins ai, A64Ins air)
|
|||||||
{
|
{
|
||||||
IRRef lref = ir->op1, rref = ir->op2;
|
IRRef lref = ir->op1, rref = ir->op2;
|
||||||
IRIns *irm;
|
IRIns *irm;
|
||||||
if (lref != rref &&
|
if ((as->flags & JIT_F_OPT_FMA) &&
|
||||||
|
lref != rref &&
|
||||||
((mayfuse(as, lref) && (irm = IR(lref), irm->o == IR_MUL) &&
|
((mayfuse(as, lref) && (irm = IR(lref), irm->o == IR_MUL) &&
|
||||||
ra_noreg(irm->r)) ||
|
ra_noreg(irm->r)) ||
|
||||||
(mayfuse(as, rref) && (irm = IR(rref), irm->o == IR_MUL) &&
|
(mayfuse(as, rref) && (irm = IR(rref), irm->o == IR_MUL) &&
|
||||||
@@ -420,8 +421,8 @@ static void asm_gencall(ASMState *as, const CCallInfo *ci, IRRef *args)
|
|||||||
uint32_t n, nargs = CCI_XNARGS(ci);
|
uint32_t n, nargs = CCI_XNARGS(ci);
|
||||||
int32_t ofs = 0;
|
int32_t ofs = 0;
|
||||||
Reg gpr, fpr = REGARG_FIRSTFPR;
|
Reg gpr, fpr = REGARG_FIRSTFPR;
|
||||||
if ((void *)ci->func)
|
if (ci->func)
|
||||||
emit_call(as, (void *)ci->func);
|
emit_call(as, ci->func);
|
||||||
for (gpr = REGARG_FIRSTGPR; gpr <= REGARG_LASTGPR; gpr++)
|
for (gpr = REGARG_FIRSTGPR; gpr <= REGARG_LASTGPR; gpr++)
|
||||||
as->cost[gpr] = REGCOST(~0u, ASMREF_L);
|
as->cost[gpr] = REGCOST(~0u, ASMREF_L);
|
||||||
gpr = REGARG_FIRSTGPR;
|
gpr = REGARG_FIRSTGPR;
|
||||||
@@ -500,7 +501,7 @@ static void asm_callx(ASMState *as, IRIns *ir)
|
|||||||
ci.func = (ASMFunction)(ir_k64(irf)->u64);
|
ci.func = (ASMFunction)(ir_k64(irf)->u64);
|
||||||
} else { /* Need a non-argument register for indirect calls. */
|
} else { /* Need a non-argument register for indirect calls. */
|
||||||
Reg freg = ra_alloc1(as, func, RSET_RANGE(RID_X8, RID_MAX_GPR)-RSET_FIXED);
|
Reg freg = ra_alloc1(as, func, RSET_RANGE(RID_X8, RID_MAX_GPR)-RSET_FIXED);
|
||||||
emit_n(as, A64I_BLR, freg);
|
emit_n(as, A64I_BLR_AUTH, freg);
|
||||||
ci.func = (ASMFunction)(void *)0;
|
ci.func = (ASMFunction)(void *)0;
|
||||||
}
|
}
|
||||||
asm_gencall(as, &ci, args);
|
asm_gencall(as, &ci, args);
|
||||||
@@ -908,7 +909,7 @@ static void asm_hrefk(ASMState *as, IRIns *ir)
|
|||||||
IRIns *irkey = IR(kslot->op1);
|
IRIns *irkey = IR(kslot->op1);
|
||||||
int32_t ofs = (int32_t)(kslot->op2 * sizeof(Node));
|
int32_t ofs = (int32_t)(kslot->op2 * sizeof(Node));
|
||||||
int32_t kofs = ofs + (int32_t)offsetof(Node, key);
|
int32_t kofs = ofs + (int32_t)offsetof(Node, key);
|
||||||
int bigofs = !emit_checkofs(A64I_LDRx, ofs);
|
int bigofs = !emit_checkofs(A64I_LDRx, kofs);
|
||||||
Reg dest = (ra_used(ir) || bigofs) ? ra_dest(as, ir, RSET_GPR) : RID_NONE;
|
Reg dest = (ra_used(ir) || bigofs) ? ra_dest(as, ir, RSET_GPR) : RID_NONE;
|
||||||
Reg node = ra_alloc1(as, ir->op1, RSET_GPR);
|
Reg node = ra_alloc1(as, ir->op1, RSET_GPR);
|
||||||
Reg key, idx = node;
|
Reg key, idx = node;
|
||||||
@@ -934,7 +935,7 @@ static void asm_hrefk(ASMState *as, IRIns *ir)
|
|||||||
emit_nm(as, A64I_CMPx, key, ra_allock(as, k, rset_exclude(allow, key)));
|
emit_nm(as, A64I_CMPx, key, ra_allock(as, k, rset_exclude(allow, key)));
|
||||||
emit_lso(as, A64I_LDRx, key, idx, kofs);
|
emit_lso(as, A64I_LDRx, key, idx, kofs);
|
||||||
if (bigofs)
|
if (bigofs)
|
||||||
emit_opk(as, A64I_ADDx, dest, node, ofs, RSET_GPR);
|
emit_opk(as, A64I_ADDx, dest, node, ofs, rset_exclude(RSET_GPR, node));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void asm_uref(ASMState *as, IRIns *ir)
|
static void asm_uref(ASMState *as, IRIns *ir)
|
||||||
@@ -1201,7 +1202,7 @@ dotypecheck:
|
|||||||
tmp = ra_scratch(as, allow);
|
tmp = ra_scratch(as, allow);
|
||||||
rset_clear(allow, tmp);
|
rset_clear(allow, tmp);
|
||||||
}
|
}
|
||||||
if (ra_hasreg(dest) && irt_isnum(t) && !(ir->op2 & IRSLOAD_CONVERT))
|
if (ra_hasreg(dest) && tmp != dest)
|
||||||
emit_dn(as, A64I_FMOV_D_R, (dest & 31), tmp);
|
emit_dn(as, A64I_FMOV_D_R, (dest & 31), tmp);
|
||||||
/* Need type check, even if the load result is unused. */
|
/* Need type check, even if the load result is unused. */
|
||||||
asm_guardcc(as, irt_isnum(t) ? CC_LS : CC_NE);
|
asm_guardcc(as, irt_isnum(t) ? CC_LS : CC_NE);
|
||||||
@@ -1914,7 +1915,7 @@ static void asm_head_root_base(ASMState *as)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Coalesce BASE register for a side trace. */
|
/* Coalesce BASE register for a side trace. */
|
||||||
static RegSet asm_head_side_base(ASMState *as, IRIns *irp, RegSet allow)
|
static Reg asm_head_side_base(ASMState *as, IRIns *irp)
|
||||||
{
|
{
|
||||||
IRIns *ir;
|
IRIns *ir;
|
||||||
asm_head_lreg(as);
|
asm_head_lreg(as);
|
||||||
@@ -1922,16 +1923,15 @@ static RegSet asm_head_side_base(ASMState *as, IRIns *irp, RegSet allow)
|
|||||||
if (ra_hasreg(ir->r) && (rset_test(as->modset, ir->r) || irt_ismarked(ir->t)))
|
if (ra_hasreg(ir->r) && (rset_test(as->modset, ir->r) || irt_ismarked(ir->t)))
|
||||||
ra_spill(as, ir);
|
ra_spill(as, ir);
|
||||||
if (ra_hasspill(irp->s)) {
|
if (ra_hasspill(irp->s)) {
|
||||||
rset_clear(allow, ra_dest(as, ir, allow));
|
return ra_dest(as, ir, RSET_GPR);
|
||||||
} else {
|
} else {
|
||||||
Reg r = irp->r;
|
Reg r = irp->r;
|
||||||
lj_assertA(ra_hasreg(r), "base reg lost");
|
lj_assertA(ra_hasreg(r), "base reg lost");
|
||||||
rset_clear(allow, r);
|
|
||||||
if (r != ir->r && !rset_test(as->freeset, r))
|
if (r != ir->r && !rset_test(as->freeset, r))
|
||||||
ra_restore(as, regcost_ref(as->cost[r]));
|
ra_restore(as, regcost_ref(as->cost[r]));
|
||||||
ra_destreg(as, ir, r);
|
ra_destreg(as, ir, r);
|
||||||
|
return r;
|
||||||
}
|
}
|
||||||
return allow;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -- Tail of trace ------------------------------------------------------- */
|
/* -- Tail of trace ------------------------------------------------------- */
|
||||||
|
|||||||
@@ -1337,8 +1337,8 @@ static void asm_fload(ASMState *as, IRIns *ir)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
ofs = field_ofs[ir->op2];
|
ofs = field_ofs[ir->op2];
|
||||||
|
lj_assertA(!irt_isfp(ir->t), "bad FP FLOAD");
|
||||||
}
|
}
|
||||||
lj_assertA(!irt_isfp(ir->t), "bad FP FLOAD");
|
|
||||||
emit_tsi(as, mi, dest, idx, ofs);
|
emit_tsi(as, mi, dest, idx, ofs);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1894,7 +1894,7 @@ static void asm_arithov(ASMState *as, IRIns *ir)
|
|||||||
lj_assertA(!irt_is64(ir->t), "bad usage");
|
lj_assertA(!irt_is64(ir->t), "bad usage");
|
||||||
if (irref_isk(ir->op2)) {
|
if (irref_isk(ir->op2)) {
|
||||||
int k = IR(ir->op2)->i;
|
int k = IR(ir->op2)->i;
|
||||||
if (ir->o == IR_SUBOV) k = -k;
|
if (ir->o == IR_SUBOV) k = (int)(~(unsigned int)k+1u);
|
||||||
if (checki16(k)) { /* (dest < left) == (k >= 0 ? 1 : 0) */
|
if (checki16(k)) { /* (dest < left) == (k >= 0 ? 1 : 0) */
|
||||||
left = ra_alloc1(as, ir->op1, RSET_GPR);
|
left = ra_alloc1(as, ir->op1, RSET_GPR);
|
||||||
asm_guard(as, k >= 0 ? MIPSI_BNE : MIPSI_BEQ, RID_TMP, RID_ZERO);
|
asm_guard(as, k >= 0 ? MIPSI_BNE : MIPSI_BEQ, RID_TMP, RID_ZERO);
|
||||||
@@ -2667,7 +2667,7 @@ static void asm_head_root_base(ASMState *as)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Coalesce BASE register for a side trace. */
|
/* Coalesce BASE register for a side trace. */
|
||||||
static RegSet asm_head_side_base(ASMState *as, IRIns *irp, RegSet allow)
|
static Reg asm_head_side_base(ASMState *as, IRIns *irp)
|
||||||
{
|
{
|
||||||
IRIns *ir = IR(REF_BASE);
|
IRIns *ir = IR(REF_BASE);
|
||||||
Reg r = ir->r;
|
Reg r = ir->r;
|
||||||
@@ -2676,15 +2676,15 @@ static RegSet asm_head_side_base(ASMState *as, IRIns *irp, RegSet allow)
|
|||||||
if (rset_test(as->modset, r) || irt_ismarked(ir->t))
|
if (rset_test(as->modset, r) || irt_ismarked(ir->t))
|
||||||
ir->r = RID_INIT; /* No inheritance for modified BASE register. */
|
ir->r = RID_INIT; /* No inheritance for modified BASE register. */
|
||||||
if (irp->r == r) {
|
if (irp->r == r) {
|
||||||
rset_clear(allow, r); /* Mark same BASE register as coalesced. */
|
return r; /* Same BASE register already coalesced. */
|
||||||
} else if (ra_hasreg(irp->r) && rset_test(as->freeset, irp->r)) {
|
} else if (ra_hasreg(irp->r) && rset_test(as->freeset, irp->r)) {
|
||||||
rset_clear(allow, irp->r);
|
|
||||||
emit_move(as, r, irp->r); /* Move from coalesced parent reg. */
|
emit_move(as, r, irp->r); /* Move from coalesced parent reg. */
|
||||||
|
return irp->r;
|
||||||
} else {
|
} else {
|
||||||
emit_getgl(as, r, jit_base); /* Otherwise reload BASE. */
|
emit_getgl(as, r, jit_base); /* Otherwise reload BASE. */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return allow;
|
return RID_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -- Tail of trace ------------------------------------------------------- */
|
/* -- Tail of trace ------------------------------------------------------- */
|
||||||
|
|||||||
@@ -235,7 +235,8 @@ static int asm_fusemadd(ASMState *as, IRIns *ir, PPCIns pi, PPCIns pir)
|
|||||||
{
|
{
|
||||||
IRRef lref = ir->op1, rref = ir->op2;
|
IRRef lref = ir->op1, rref = ir->op2;
|
||||||
IRIns *irm;
|
IRIns *irm;
|
||||||
if (lref != rref &&
|
if ((as->flags & JIT_F_OPT_FMA) &&
|
||||||
|
lref != rref &&
|
||||||
((mayfuse(as, lref) && (irm = IR(lref), irm->o == IR_MUL) &&
|
((mayfuse(as, lref) && (irm = IR(lref), irm->o == IR_MUL) &&
|
||||||
ra_noreg(irm->r)) ||
|
ra_noreg(irm->r)) ||
|
||||||
(mayfuse(as, rref) && (irm = IR(rref), irm->o == IR_MUL) &&
|
(mayfuse(as, rref) && (irm = IR(rref), irm->o == IR_MUL) &&
|
||||||
@@ -2185,7 +2186,7 @@ static void asm_head_root_base(ASMState *as)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Coalesce BASE register for a side trace. */
|
/* Coalesce BASE register for a side trace. */
|
||||||
static RegSet asm_head_side_base(ASMState *as, IRIns *irp, RegSet allow)
|
static Reg asm_head_side_base(ASMState *as, IRIns *irp)
|
||||||
{
|
{
|
||||||
IRIns *ir = IR(REF_BASE);
|
IRIns *ir = IR(REF_BASE);
|
||||||
Reg r = ir->r;
|
Reg r = ir->r;
|
||||||
@@ -2194,15 +2195,15 @@ static RegSet asm_head_side_base(ASMState *as, IRIns *irp, RegSet allow)
|
|||||||
if (rset_test(as->modset, r) || irt_ismarked(ir->t))
|
if (rset_test(as->modset, r) || irt_ismarked(ir->t))
|
||||||
ir->r = RID_INIT; /* No inheritance for modified BASE register. */
|
ir->r = RID_INIT; /* No inheritance for modified BASE register. */
|
||||||
if (irp->r == r) {
|
if (irp->r == r) {
|
||||||
rset_clear(allow, r); /* Mark same BASE register as coalesced. */
|
return r; /* Same BASE register already coalesced. */
|
||||||
} else if (ra_hasreg(irp->r) && rset_test(as->freeset, irp->r)) {
|
} else if (ra_hasreg(irp->r) && rset_test(as->freeset, irp->r)) {
|
||||||
rset_clear(allow, irp->r);
|
|
||||||
emit_mr(as, r, irp->r); /* Move from coalesced parent reg. */
|
emit_mr(as, r, irp->r); /* Move from coalesced parent reg. */
|
||||||
|
return irp->r;
|
||||||
} else {
|
} else {
|
||||||
emit_getgl(as, r, jit_base); /* Otherwise reload BASE. */
|
emit_getgl(as, r, jit_base); /* Otherwise reload BASE. */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return allow;
|
return RID_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -- Tail of trace ------------------------------------------------------- */
|
/* -- Tail of trace ------------------------------------------------------- */
|
||||||
|
|||||||
@@ -2877,7 +2877,7 @@ static void asm_head_root_base(ASMState *as)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Coalesce or reload BASE register for a side trace. */
|
/* Coalesce or reload BASE register for a side trace. */
|
||||||
static RegSet asm_head_side_base(ASMState *as, IRIns *irp, RegSet allow)
|
static Reg asm_head_side_base(ASMState *as, IRIns *irp)
|
||||||
{
|
{
|
||||||
IRIns *ir = IR(REF_BASE);
|
IRIns *ir = IR(REF_BASE);
|
||||||
Reg r = ir->r;
|
Reg r = ir->r;
|
||||||
@@ -2886,16 +2886,16 @@ static RegSet asm_head_side_base(ASMState *as, IRIns *irp, RegSet allow)
|
|||||||
if (rset_test(as->modset, r) || irt_ismarked(ir->t))
|
if (rset_test(as->modset, r) || irt_ismarked(ir->t))
|
||||||
ir->r = RID_INIT; /* No inheritance for modified BASE register. */
|
ir->r = RID_INIT; /* No inheritance for modified BASE register. */
|
||||||
if (irp->r == r) {
|
if (irp->r == r) {
|
||||||
rset_clear(allow, r); /* Mark same BASE register as coalesced. */
|
return r; /* Same BASE register already coalesced. */
|
||||||
} else if (ra_hasreg(irp->r) && rset_test(as->freeset, irp->r)) {
|
} else if (ra_hasreg(irp->r) && rset_test(as->freeset, irp->r)) {
|
||||||
/* Move from coalesced parent reg. */
|
/* Move from coalesced parent reg. */
|
||||||
rset_clear(allow, irp->r);
|
|
||||||
emit_rr(as, XO_MOV, r|REX_GC64, irp->r);
|
emit_rr(as, XO_MOV, r|REX_GC64, irp->r);
|
||||||
|
return irp->r;
|
||||||
} else {
|
} else {
|
||||||
emit_getgl(as, r, jit_base); /* Otherwise reload BASE. */
|
emit_getgl(as, r, jit_base); /* Otherwise reload BASE. */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return allow;
|
return RID_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -- Tail of trace ------------------------------------------------------- */
|
/* -- Tail of trace ------------------------------------------------------- */
|
||||||
|
|||||||
@@ -189,7 +189,8 @@ static void bcwrite_knum(BCWriteCtx *ctx, GCproto *pt)
|
|||||||
goto save_int;
|
goto save_int;
|
||||||
} else {
|
} else {
|
||||||
/* Write a 33 bit ULEB128 for the int (lsb=0) or loword (lsb=1). */
|
/* Write a 33 bit ULEB128 for the int (lsb=0) or loword (lsb=1). */
|
||||||
if (!LJ_DUALNUM) { /* Narrow number constants to integers. */
|
if (!LJ_DUALNUM && o->u32.hi != LJ_KEYINDEX) {
|
||||||
|
/* Narrow number constants to integers. */
|
||||||
lua_Number num = numV(o);
|
lua_Number num = numV(o);
|
||||||
k = lj_num2int(num);
|
k = lj_num2int(num);
|
||||||
if (num == (lua_Number)k) { /* -0 is never a constant. */
|
if (num == (lua_Number)k) { /* -0 is never a constant. */
|
||||||
|
|||||||
@@ -207,7 +207,7 @@ static int carith_int64(lua_State *L, CTState *cts, CDArith *ca, MMS mm)
|
|||||||
else
|
else
|
||||||
*up = lj_carith_powu64(u0, u1);
|
*up = lj_carith_powu64(u0, u1);
|
||||||
break;
|
break;
|
||||||
case MM_unm: *up = (uint64_t)-(int64_t)u0; break;
|
case MM_unm: *up = ~u0+1u; break;
|
||||||
default:
|
default:
|
||||||
lj_assertL(0, "bad metamethod %d", mm);
|
lj_assertL(0, "bad metamethod %d", mm);
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -171,13 +171,13 @@ static void *callback_mcode_init(global_State *g, uint32_t *page)
|
|||||||
static void *callback_mcode_init(global_State *g, uint32_t *page)
|
static void *callback_mcode_init(global_State *g, uint32_t *page)
|
||||||
{
|
{
|
||||||
uint32_t *p = page;
|
uint32_t *p = page;
|
||||||
void *target = (void *)lj_vm_ffi_callback;
|
ASMFunction target = lj_vm_ffi_callback;
|
||||||
MSize slot;
|
MSize slot;
|
||||||
*p++ = A64I_LE(A64I_LDRLx | A64F_D(RID_X11) | A64F_S19(4));
|
*p++ = A64I_LE(A64I_LDRLx | A64F_D(RID_X11) | A64F_S19(4));
|
||||||
*p++ = A64I_LE(A64I_LDRLx | A64F_D(RID_X10) | A64F_S19(5));
|
*p++ = A64I_LE(A64I_LDRLx | A64F_D(RID_X10) | A64F_S19(5));
|
||||||
*p++ = A64I_LE(A64I_BR | A64F_N(RID_X11));
|
*p++ = A64I_LE(A64I_BR_AUTH | A64F_N(RID_X11));
|
||||||
*p++ = A64I_LE(A64I_NOP);
|
*p++ = A64I_LE(A64I_NOP);
|
||||||
((void **)p)[0] = target;
|
((ASMFunction *)p)[0] = target;
|
||||||
((void **)p)[1] = g;
|
((void **)p)[1] = g;
|
||||||
p += 4;
|
p += 4;
|
||||||
for (slot = 0; slot < CALLBACK_MAX_SLOT; slot++) {
|
for (slot = 0; slot < CALLBACK_MAX_SLOT; slot++) {
|
||||||
|
|||||||
@@ -488,7 +488,7 @@ static void cp_expr_prefix(CPState *cp, CPValue *k)
|
|||||||
} else if (cp_opt(cp, '+')) {
|
} else if (cp_opt(cp, '+')) {
|
||||||
cp_expr_unary(cp, k); /* Nothing to do (well, integer promotion). */
|
cp_expr_unary(cp, k); /* Nothing to do (well, integer promotion). */
|
||||||
} else if (cp_opt(cp, '-')) {
|
} else if (cp_opt(cp, '-')) {
|
||||||
cp_expr_unary(cp, k); k->i32 = -k->i32;
|
cp_expr_unary(cp, k); k->i32 = (int32_t)(~(uint32_t)k->i32+1);
|
||||||
} else if (cp_opt(cp, '~')) {
|
} else if (cp_opt(cp, '~')) {
|
||||||
cp_expr_unary(cp, k); k->i32 = ~k->i32;
|
cp_expr_unary(cp, k); k->i32 = ~k->i32;
|
||||||
} else if (cp_opt(cp, '!')) {
|
} else if (cp_opt(cp, '!')) {
|
||||||
|
|||||||
@@ -1504,9 +1504,13 @@ void LJ_FASTCALL recff_cdata_arith(jit_State *J, RecordFFData *rd)
|
|||||||
if (ctype_isenum(ct->info)) ct = ctype_child(cts, ct);
|
if (ctype_isenum(ct->info)) ct = ctype_child(cts, ct);
|
||||||
goto ok;
|
goto ok;
|
||||||
} else if (ctype_isfunc(ct->info)) {
|
} else if (ctype_isfunc(ct->info)) {
|
||||||
|
CTypeID id0 = i ? ctype_typeid(cts, s[0]) : 0;
|
||||||
tr = emitir(IRT(IR_FLOAD, IRT_PTR), tr, IRFL_CDATA_PTR);
|
tr = emitir(IRT(IR_FLOAD, IRT_PTR), tr, IRFL_CDATA_PTR);
|
||||||
ct = ctype_get(cts,
|
ct = ctype_get(cts,
|
||||||
lj_ctype_intern(cts, CTINFO(CT_PTR, CTALIGN_PTR|id), CTSIZE_PTR));
|
lj_ctype_intern(cts, CTINFO(CT_PTR, CTALIGN_PTR|id), CTSIZE_PTR));
|
||||||
|
if (i) {
|
||||||
|
s[0] = ctype_get(cts, id0); /* cts->tab may have been reallocated. */
|
||||||
|
}
|
||||||
goto ok;
|
goto ok;
|
||||||
} else {
|
} else {
|
||||||
tr = emitir(IRT(IR_ADD, IRT_PTR), tr, lj_ir_kintp(J, sizeof(GCcdata)));
|
tr = emitir(IRT(IR_ADD, IRT_PTR), tr, lj_ir_kintp(J, sizeof(GCcdata)));
|
||||||
@@ -1875,7 +1879,8 @@ TRef recff_bit64_tohex(jit_State *J, RecordFFData *rd, TRef hdr)
|
|||||||
} else {
|
} else {
|
||||||
n = id ? 16 : 8;
|
n = id ? 16 : 8;
|
||||||
}
|
}
|
||||||
if (n < 0) { n = -n; sf |= STRFMT_F_UPPER; }
|
if (n < 0) { n = (int32_t)(~n+1u); sf |= STRFMT_F_UPPER; }
|
||||||
|
if ((uint32_t)n > 254) n = 254;
|
||||||
sf |= ((SFormat)((n+1)&255) << STRFMT_SH_PREC);
|
sf |= ((SFormat)((n+1)&255) << STRFMT_SH_PREC);
|
||||||
if (id) {
|
if (id) {
|
||||||
tr = crec_ct_tv(J, ctype_get(cts, id), 0, J->base[0], &rd->argv[0]);
|
tr = crec_ct_tv(J, ctype_get(cts, id), 0, J->base[0], &rd->argv[0]);
|
||||||
|
|||||||
@@ -191,8 +191,20 @@ CTypeID lj_ctype_intern(CTState *cts, CTInfo info, CTSize size)
|
|||||||
}
|
}
|
||||||
id = cts->top;
|
id = cts->top;
|
||||||
if (LJ_UNLIKELY(id >= cts->sizetab)) {
|
if (LJ_UNLIKELY(id >= cts->sizetab)) {
|
||||||
|
#ifdef LUAJIT_CTYPE_CHECK_ANCHOR
|
||||||
|
CType *ct;
|
||||||
|
#endif
|
||||||
if (id >= CTID_MAX) lj_err_msg(cts->L, LJ_ERR_TABOV);
|
if (id >= CTID_MAX) lj_err_msg(cts->L, LJ_ERR_TABOV);
|
||||||
|
#ifdef LUAJIT_CTYPE_CHECK_ANCHOR
|
||||||
|
ct = lj_mem_newvec(cts->L, id+1, CType);
|
||||||
|
memcpy(ct, cts->tab, id*sizeof(CType));
|
||||||
|
memset(cts->tab, 0, id*sizeof(CType));
|
||||||
|
lj_mem_freevec(cts->g, cts->tab, cts->sizetab, CType);
|
||||||
|
cts->tab = ct;
|
||||||
|
cts->sizetab = id+1;
|
||||||
|
#else
|
||||||
lj_mem_growvec(cts->L, cts->tab, cts->sizetab, CTID_MAX, CType);
|
lj_mem_growvec(cts->L, cts->tab, cts->sizetab, CTID_MAX, CType);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
cts->top = id+1;
|
cts->top = id+1;
|
||||||
cts->tab[id].info = info;
|
cts->tab[id].info = info;
|
||||||
@@ -570,7 +582,7 @@ GCstr *lj_ctype_repr_int64(lua_State *L, uint64_t n, int isunsigned)
|
|||||||
if (isunsigned) {
|
if (isunsigned) {
|
||||||
*--p = 'U';
|
*--p = 'U';
|
||||||
} else if ((int64_t)n < 0) {
|
} else if ((int64_t)n < 0) {
|
||||||
n = (uint64_t)-(int64_t)n;
|
n = ~n+1u;
|
||||||
sign = 1;
|
sign = 1;
|
||||||
}
|
}
|
||||||
do { *--p = (char)('0' + n % 10); } while (n /= 10);
|
do { *--p = (char)('0' + n % 10); } while (n /= 10);
|
||||||
|
|||||||
@@ -101,9 +101,12 @@ static BCPos debug_framepc(lua_State *L, GCfunc *fn, cTValue *nextframe)
|
|||||||
pos = proto_bcpos(pt, ins) - 1;
|
pos = proto_bcpos(pt, ins) - 1;
|
||||||
#if LJ_HASJIT
|
#if LJ_HASJIT
|
||||||
if (pos > pt->sizebc) { /* Undo the effects of lj_trace_exit for JLOOP. */
|
if (pos > pt->sizebc) { /* Undo the effects of lj_trace_exit for JLOOP. */
|
||||||
GCtrace *T = (GCtrace *)((char *)(ins-1) - offsetof(GCtrace, startins));
|
if (bc_isret(bc_op(ins[-1]))) {
|
||||||
lj_assertL(bc_isret(bc_op(ins[-1])), "return bytecode expected");
|
GCtrace *T = (GCtrace *)((char *)(ins-1) - offsetof(GCtrace, startins));
|
||||||
pos = proto_bcpos(pt, mref(T->startpc, const BCIns));
|
pos = proto_bcpos(pt, mref(T->startpc, const BCIns));
|
||||||
|
} else {
|
||||||
|
pos = NO_BCPOS; /* Punt in case of stack overflow for stitched trace. */
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
return pos;
|
return pos;
|
||||||
|
|||||||
@@ -157,7 +157,7 @@ static int emit_kdelta2(ASMState *as, Reg rd, int32_t i)
|
|||||||
if (other) {
|
if (other) {
|
||||||
int32_t delta = i - other;
|
int32_t delta = i - other;
|
||||||
uint32_t sh, inv = 0, k2, k;
|
uint32_t sh, inv = 0, k2, k;
|
||||||
if (delta < 0) { delta = -delta; inv = ARMI_ADD^ARMI_SUB; }
|
if (delta < 0) { delta = (int32_t)(~(uint32_t)delta+1u); inv = ARMI_ADD^ARMI_SUB; }
|
||||||
sh = lj_ffs(delta) & ~1;
|
sh = lj_ffs(delta) & ~1;
|
||||||
k2 = emit_isk12(0, delta & (255 << sh));
|
k2 = emit_isk12(0, delta & (255 << sh));
|
||||||
k = emit_isk12(0, delta & ~(255 << sh));
|
k = emit_isk12(0, delta & ~(255 << sh));
|
||||||
|
|||||||
@@ -27,8 +27,8 @@ static uint64_t get_k64val(ASMState *as, IRRef ref)
|
|||||||
/* Encode constant in K12 format for data processing instructions. */
|
/* Encode constant in K12 format for data processing instructions. */
|
||||||
static uint32_t emit_isk12(int64_t n)
|
static uint32_t emit_isk12(int64_t n)
|
||||||
{
|
{
|
||||||
uint64_t k = (n < 0) ? -n : n;
|
uint64_t k = n < 0 ? ~(uint64_t)n+1u : (uint64_t)n;
|
||||||
uint32_t m = (n < 0) ? 0x40000000 : 0;
|
uint32_t m = n < 0 ? 0x40000000 : 0;
|
||||||
if (k < 0x1000) {
|
if (k < 0x1000) {
|
||||||
return A64I_K12|m|A64F_U12(k);
|
return A64I_K12|m|A64F_U12(k);
|
||||||
} else if ((k & 0xfff000) == k) {
|
} else if ((k & 0xfff000) == k) {
|
||||||
@@ -143,7 +143,7 @@ static void emit_lso(ASMState *as, A64Ins ai, Reg rd, Reg rn, int64_t ofs)
|
|||||||
goto nopair;
|
goto nopair;
|
||||||
}
|
}
|
||||||
if (ofsm >= (int)((unsigned int)-64<<sc) && ofsm <= (63<<sc)) {
|
if (ofsm >= (int)((unsigned int)-64<<sc) && ofsm <= (63<<sc)) {
|
||||||
*as->mcp = aip | A64F_N(rn) | ((ofsm >> sc) << 15) |
|
*as->mcp = aip | A64F_N(rn) | (((ofsm >> sc) & 0x7f) << 15) |
|
||||||
(ai ^ ((ai == A64I_LDRx || ai == A64I_STRx) ? 0x50000000 : 0x90000000));
|
(ai ^ ((ai == A64I_LDRx || ai == A64I_STRx) ? 0x50000000 : 0x90000000));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -177,7 +177,7 @@ static int emit_kdelta(ASMState *as, Reg rd, uint64_t k, int lim)
|
|||||||
emit_dm(as, A64I_MOVx, rd, r);
|
emit_dm(as, A64I_MOVx, rd, r);
|
||||||
return 1;
|
return 1;
|
||||||
} else {
|
} else {
|
||||||
uint32_t k12 = emit_isk12(delta < 0 ? -delta : delta);
|
uint32_t k12 = emit_isk12(delta < 0 ? (int64_t)(~(uint64_t)delta+1u) : delta);
|
||||||
if (k12) {
|
if (k12) {
|
||||||
emit_dn(as, (delta < 0 ? A64I_SUBx : A64I_ADDx)^k12, rd, r);
|
emit_dn(as, (delta < 0 ? A64I_SUBx : A64I_ADDx)^k12, rd, r);
|
||||||
return 1;
|
return 1;
|
||||||
@@ -348,16 +348,22 @@ static void emit_cnb(ASMState *as, A64Ins ai, Reg r, MCode *target)
|
|||||||
|
|
||||||
#define emit_jmp(as, target) emit_branch(as, A64I_B, (target))
|
#define emit_jmp(as, target) emit_branch(as, A64I_B, (target))
|
||||||
|
|
||||||
static void emit_call(ASMState *as, void *target)
|
static void emit_call(ASMState *as, ASMFunction target)
|
||||||
{
|
{
|
||||||
MCode *p = --as->mcp;
|
MCode *p = --as->mcp;
|
||||||
ptrdiff_t delta = (char *)target - (char *)p;
|
#if LJ_ABI_PAUTH
|
||||||
|
char *targetp = ptrauth_auth_data((char *)target,
|
||||||
|
ptrauth_key_function_pointer, 0);
|
||||||
|
#else
|
||||||
|
char *targetp = (char *)target;
|
||||||
|
#endif
|
||||||
|
ptrdiff_t delta = targetp - (char *)p;
|
||||||
if (A64F_S_OK(delta>>2, 26)) {
|
if (A64F_S_OK(delta>>2, 26)) {
|
||||||
*p = A64I_BL | A64F_S26(delta>>2);
|
*p = A64I_BL | A64F_S26(delta>>2);
|
||||||
} else { /* Target out of range: need indirect call. But don't use R0-R7. */
|
} else { /* Target out of range: need indirect call. But don't use R0-R7. */
|
||||||
Reg r = ra_allock(as, i64ptr(target),
|
Reg r = ra_allock(as, i64ptr(target),
|
||||||
RSET_RANGE(RID_X8, RID_MAX_GPR)-RSET_FIXED);
|
RSET_RANGE(RID_X8, RID_MAX_GPR)-RSET_FIXED);
|
||||||
*p = A64I_BLR | A64F_N(r);
|
*p = A64I_BLR_AUTH | A64F_N(r);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -417,7 +423,8 @@ static void emit_addptr(ASMState *as, Reg r, int32_t ofs)
|
|||||||
{
|
{
|
||||||
if (ofs)
|
if (ofs)
|
||||||
emit_opk(as, ofs < 0 ? A64I_SUBx : A64I_ADDx, r, r,
|
emit_opk(as, ofs < 0 ? A64I_SUBx : A64I_ADDx, r, r,
|
||||||
ofs < 0 ? -ofs : ofs, rset_exclude(RSET_GPR, r));
|
ofs < 0 ? (int32_t)(~(uint32_t)ofs+1u) : ofs,
|
||||||
|
rset_exclude(RSET_GPR, r));
|
||||||
}
|
}
|
||||||
|
|
||||||
#define emit_spsub(as, ofs) emit_addptr(as, RID_SP, -(ofs))
|
#define emit_spsub(as, ofs) emit_addptr(as, RID_SP, -(ofs))
|
||||||
|
|||||||
@@ -329,12 +329,12 @@ static void err_unwind_win_jit(global_State *g, int errcode)
|
|||||||
memset(&hist, 0, sizeof(hist));
|
memset(&hist, 0, sizeof(hist));
|
||||||
RtlCaptureContext(&ctx);
|
RtlCaptureContext(&ctx);
|
||||||
while (1) {
|
while (1) {
|
||||||
uintptr_t frame, base, addr = ctx.CONTEXT_REG_PC;
|
DWORD64 frame, base, addr = ctx.CONTEXT_REG_PC;
|
||||||
void *hdata;
|
void *hdata;
|
||||||
PRUNTIME_FUNCTION func = RtlLookupFunctionEntry(addr, &base, &hist);
|
PRUNTIME_FUNCTION func = RtlLookupFunctionEntry(addr, &base, &hist);
|
||||||
if (!func) { /* Found frame without .pdata: must be JIT-compiled code. */
|
if (!func) { /* Found frame without .pdata: must be JIT-compiled code. */
|
||||||
ExitNo exitno;
|
ExitNo exitno;
|
||||||
uintptr_t stub = lj_trace_unwind(G2J(g), addr - sizeof(MCode), &exitno);
|
uintptr_t stub = lj_trace_unwind(G2J(g), (uintptr_t)(addr - sizeof(MCode)), &exitno);
|
||||||
if (stub) { /* Jump to side exit to unwind the trace. */
|
if (stub) { /* Jump to side exit to unwind the trace. */
|
||||||
ctx.CONTEXT_REG_PC = stub;
|
ctx.CONTEXT_REG_PC = stub;
|
||||||
G2J(g)->exitcode = errcode;
|
G2J(g)->exitcode = errcode;
|
||||||
@@ -444,10 +444,10 @@ LJ_FUNCA int lj_err_unwind_dwarf(int version, int actions,
|
|||||||
if ((actions & _UA_FORCE_UNWIND)) {
|
if ((actions & _UA_FORCE_UNWIND)) {
|
||||||
return _URC_CONTINUE_UNWIND;
|
return _URC_CONTINUE_UNWIND;
|
||||||
} else if (cf) {
|
} else if (cf) {
|
||||||
|
ASMFunction ip;
|
||||||
_Unwind_SetGR(ctx, LJ_TARGET_EHRETREG, errcode);
|
_Unwind_SetGR(ctx, LJ_TARGET_EHRETREG, errcode);
|
||||||
_Unwind_SetIP(ctx, (uintptr_t)(cframe_unwind_ff(cf) ?
|
ip = cframe_unwind_ff(cf) ? lj_vm_unwind_ff_eh : lj_vm_unwind_c_eh;
|
||||||
lj_vm_unwind_ff_eh :
|
_Unwind_SetIP(ctx, (uintptr_t)lj_ptr_strip(ip));
|
||||||
lj_vm_unwind_c_eh));
|
|
||||||
return _URC_INSTALL_CONTEXT;
|
return _URC_INSTALL_CONTEXT;
|
||||||
}
|
}
|
||||||
#if LJ_TARGET_X86ORX64
|
#if LJ_TARGET_X86ORX64
|
||||||
@@ -580,9 +580,17 @@ extern void __deregister_frame(const void *);
|
|||||||
|
|
||||||
uint8_t *lj_err_register_mcode(void *base, size_t sz, uint8_t *info)
|
uint8_t *lj_err_register_mcode(void *base, size_t sz, uint8_t *info)
|
||||||
{
|
{
|
||||||
void **handler;
|
ASMFunction handler = (ASMFunction)err_unwind_jit;
|
||||||
memcpy(info, err_frame_jit_template, sizeof(err_frame_jit_template));
|
memcpy(info, err_frame_jit_template, sizeof(err_frame_jit_template));
|
||||||
handler = (void *)err_unwind_jit;
|
#if LJ_ABI_PAUTH
|
||||||
|
#if LJ_TARGET_ARM64
|
||||||
|
handler = ptrauth_auth_and_resign(handler,
|
||||||
|
ptrauth_key_function_pointer, 0,
|
||||||
|
ptrauth_key_process_independent_code, info + ERR_FRAME_JIT_OFS_HANDLER);
|
||||||
|
#else
|
||||||
|
#error "missing pointer authentication support for this architecture"
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
memcpy(info + ERR_FRAME_JIT_OFS_HANDLER, &handler, sizeof(handler));
|
memcpy(info + ERR_FRAME_JIT_OFS_HANDLER, &handler, sizeof(handler));
|
||||||
*(uint32_t *)(info + ERR_FRAME_JIT_OFS_CODE_SIZE) =
|
*(uint32_t *)(info + ERR_FRAME_JIT_OFS_CODE_SIZE) =
|
||||||
(uint32_t)(sz - sizeof(err_frame_jit_template) - (info - (uint8_t *)base));
|
(uint32_t)(sz - sizeof(err_frame_jit_template) - (info - (uint8_t *)base));
|
||||||
@@ -777,6 +785,10 @@ LJ_NOINLINE void lj_err_mem(lua_State *L)
|
|||||||
{
|
{
|
||||||
if (L->status == LUA_ERRERR+1) /* Don't touch the stack during lua_open. */
|
if (L->status == LUA_ERRERR+1) /* Don't touch the stack during lua_open. */
|
||||||
lj_vm_unwind_c(L->cframe, LUA_ERRMEM);
|
lj_vm_unwind_c(L->cframe, LUA_ERRMEM);
|
||||||
|
if (LJ_HASJIT) {
|
||||||
|
TValue *base = tvref(G(L)->jit_base);
|
||||||
|
if (base) L->base = base;
|
||||||
|
}
|
||||||
if (curr_funcisL(L)) L->top = curr_topL(L);
|
if (curr_funcisL(L)) L->top = curr_topL(L);
|
||||||
setstrV(L, L->top++, lj_err_str(L, LJ_ERR_ERRMEM));
|
setstrV(L, L->top++, lj_err_str(L, LJ_ERR_ERRMEM));
|
||||||
lj_err_throw(L, LUA_ERRMEM);
|
lj_err_throw(L, LUA_ERRMEM);
|
||||||
@@ -871,6 +883,10 @@ LJ_NORET LJ_NOINLINE static void err_msgv(lua_State *L, ErrMsg em, ...)
|
|||||||
const char *msg;
|
const char *msg;
|
||||||
va_list argp;
|
va_list argp;
|
||||||
va_start(argp, em);
|
va_start(argp, em);
|
||||||
|
if (LJ_HASJIT) {
|
||||||
|
TValue *base = tvref(G(L)->jit_base);
|
||||||
|
if (base) L->base = base;
|
||||||
|
}
|
||||||
if (curr_funcisL(L)) L->top = curr_topL(L);
|
if (curr_funcisL(L)) L->top = curr_topL(L);
|
||||||
msg = lj_strfmt_pushvf(L, err2msg(em), argp);
|
msg = lj_strfmt_pushvf(L, err2msg(em), argp);
|
||||||
va_end(argp);
|
va_end(argp);
|
||||||
|
|||||||
@@ -27,6 +27,7 @@
|
|||||||
#include "lj_trace.h"
|
#include "lj_trace.h"
|
||||||
#include "lj_dispatch.h"
|
#include "lj_dispatch.h"
|
||||||
#include "lj_vm.h"
|
#include "lj_vm.h"
|
||||||
|
#include "lj_vmevent.h"
|
||||||
|
|
||||||
#define GCSTEPSIZE 1024u
|
#define GCSTEPSIZE 1024u
|
||||||
#define GCSWEEPMAX 40
|
#define GCSWEEPMAX 40
|
||||||
@@ -521,8 +522,13 @@ static void gc_call_finalizer(global_State *g, lua_State *L,
|
|||||||
hook_restore(g, oldh);
|
hook_restore(g, oldh);
|
||||||
if (LJ_HASPROFILE && (oldh & HOOK_PROFILE)) lj_dispatch_update(g);
|
if (LJ_HASPROFILE && (oldh & HOOK_PROFILE)) lj_dispatch_update(g);
|
||||||
g->gc.threshold = oldt; /* Restore GC threshold. */
|
g->gc.threshold = oldt; /* Restore GC threshold. */
|
||||||
if (errcode)
|
if (errcode) {
|
||||||
lj_err_throw(L, errcode); /* Propagate errors. */
|
ptrdiff_t errobj = savestack(L, L->top-1); /* Stack may be resized. */
|
||||||
|
lj_vmevent_send(L, ERRFIN,
|
||||||
|
copyTV(L, L->top++, restorestack(L, errobj));
|
||||||
|
);
|
||||||
|
L->top--;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Finalize one userdata or cdata object from the mmudata list. */
|
/* Finalize one userdata or cdata object from the mmudata list. */
|
||||||
|
|||||||
@@ -87,10 +87,11 @@
|
|||||||
#define JIT_F_OPT_ABC (JIT_F_OPT << 7)
|
#define JIT_F_OPT_ABC (JIT_F_OPT << 7)
|
||||||
#define JIT_F_OPT_SINK (JIT_F_OPT << 8)
|
#define JIT_F_OPT_SINK (JIT_F_OPT << 8)
|
||||||
#define JIT_F_OPT_FUSE (JIT_F_OPT << 9)
|
#define JIT_F_OPT_FUSE (JIT_F_OPT << 9)
|
||||||
|
#define JIT_F_OPT_FMA (JIT_F_OPT << 10)
|
||||||
|
|
||||||
/* Optimizations names for -O. Must match the order above. */
|
/* Optimizations names for -O. Must match the order above. */
|
||||||
#define JIT_F_OPTSTRING \
|
#define JIT_F_OPTSTRING \
|
||||||
"\4fold\3cse\3dce\3fwd\3dse\6narrow\4loop\3abc\4sink\4fuse"
|
"\4fold\3cse\3dce\3fwd\3dse\6narrow\4loop\3abc\4sink\4fuse\3fma"
|
||||||
|
|
||||||
/* Optimization levels set a fixed combination of flags. */
|
/* Optimization levels set a fixed combination of flags. */
|
||||||
#define JIT_F_OPT_0 0
|
#define JIT_F_OPT_0 0
|
||||||
@@ -99,6 +100,7 @@
|
|||||||
#define JIT_F_OPT_3 (JIT_F_OPT_2|\
|
#define JIT_F_OPT_3 (JIT_F_OPT_2|\
|
||||||
JIT_F_OPT_FWD|JIT_F_OPT_DSE|JIT_F_OPT_ABC|JIT_F_OPT_SINK|JIT_F_OPT_FUSE)
|
JIT_F_OPT_FWD|JIT_F_OPT_DSE|JIT_F_OPT_ABC|JIT_F_OPT_SINK|JIT_F_OPT_FUSE)
|
||||||
#define JIT_F_OPT_DEFAULT JIT_F_OPT_3
|
#define JIT_F_OPT_DEFAULT JIT_F_OPT_3
|
||||||
|
/* Note: FMA is not set by default. */
|
||||||
|
|
||||||
/* -- JIT engine parameters ----------------------------------------------- */
|
/* -- JIT engine parameters ----------------------------------------------- */
|
||||||
|
|
||||||
@@ -271,6 +273,9 @@ typedef struct GCtrace {
|
|||||||
BCIns startins; /* Original bytecode of starting instruction. */
|
BCIns startins; /* Original bytecode of starting instruction. */
|
||||||
MSize szmcode; /* Size of machine code. */
|
MSize szmcode; /* Size of machine code. */
|
||||||
MCode *mcode; /* Start of machine code. */
|
MCode *mcode; /* Start of machine code. */
|
||||||
|
#if LJ_ABI_PAUTH
|
||||||
|
ASMFunction mcauth; /* Start of machine code, with ptr auth applied. */
|
||||||
|
#endif
|
||||||
MSize mcloop; /* Offset of loop start in machine code. */
|
MSize mcloop; /* Offset of loop start in machine code. */
|
||||||
uint16_t nchild; /* Number of child traces (root trace only). */
|
uint16_t nchild; /* Number of child traces (root trace only). */
|
||||||
uint16_t spadjust; /* Stack pointer adjustment (offset in bytes). */
|
uint16_t spadjust; /* Stack pointer adjustment (offset in bytes). */
|
||||||
|
|||||||
@@ -413,7 +413,7 @@ typedef struct GCproto {
|
|||||||
#define PROTO_UV_IMMUTABLE 0x4000 /* Immutable upvalue. */
|
#define PROTO_UV_IMMUTABLE 0x4000 /* Immutable upvalue. */
|
||||||
|
|
||||||
#define proto_kgc(pt, idx) \
|
#define proto_kgc(pt, idx) \
|
||||||
check_exp((uintptr_t)(intptr_t)(idx) >= (uintptr_t)-(intptr_t)(pt)->sizekgc, \
|
check_exp((uintptr_t)(intptr_t)(idx) >= ~(uintptr_t)(pt)->sizekgc+1u, \
|
||||||
gcref(mref((pt)->k, GCRef)[(idx)]))
|
gcref(mref((pt)->k, GCRef)[(idx)]))
|
||||||
#define proto_knumtv(pt, idx) \
|
#define proto_knumtv(pt, idx) \
|
||||||
check_exp((uintptr_t)(idx) < (pt)->sizekn, &mref((pt)->k, TValue)[(idx)])
|
check_exp((uintptr_t)(idx) < (pt)->sizekn, &mref((pt)->k, TValue)[(idx)])
|
||||||
@@ -1042,4 +1042,18 @@ LJ_DATA const char *const lj_obj_itypename[~LJ_TNUMX+1];
|
|||||||
LJ_FUNC int LJ_FASTCALL lj_obj_equal(cTValue *o1, cTValue *o2);
|
LJ_FUNC int LJ_FASTCALL lj_obj_equal(cTValue *o1, cTValue *o2);
|
||||||
LJ_FUNC const void * LJ_FASTCALL lj_obj_ptr(global_State *g, cTValue *o);
|
LJ_FUNC const void * LJ_FASTCALL lj_obj_ptr(global_State *g, cTValue *o);
|
||||||
|
|
||||||
|
#if LJ_ABI_PAUTH
|
||||||
|
#if LJ_TARGET_ARM64
|
||||||
|
#include <ptrauth.h>
|
||||||
|
#define lj_ptr_sign(ptr, ctx) \
|
||||||
|
ptrauth_sign_unauthenticated((ptr), ptrauth_key_function_pointer, (ctx))
|
||||||
|
#define lj_ptr_strip(ptr) ptrauth_strip((ptr), ptrauth_key_function_pointer)
|
||||||
|
#else
|
||||||
|
#error "No support for pointer authentication for this architecture"
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
#define lj_ptr_sign(ptr, ctx) (ptr)
|
||||||
|
#define lj_ptr_strip(ptr) (ptr)
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -267,7 +267,7 @@ static int32_t kfold_intop(int32_t k1, int32_t k2, IROp op)
|
|||||||
case IR_SUB: k1 -= k2; break;
|
case IR_SUB: k1 -= k2; break;
|
||||||
case IR_MUL: k1 *= k2; break;
|
case IR_MUL: k1 *= k2; break;
|
||||||
case IR_MOD: k1 = lj_vm_modi(k1, k2); break;
|
case IR_MOD: k1 = lj_vm_modi(k1, k2); break;
|
||||||
case IR_NEG: k1 = -k1; break;
|
case IR_NEG: k1 = (int32_t)(~(uint32_t)k1+1u); break;
|
||||||
case IR_BAND: k1 &= k2; break;
|
case IR_BAND: k1 &= k2; break;
|
||||||
case IR_BOR: k1 |= k2; break;
|
case IR_BOR: k1 |= k2; break;
|
||||||
case IR_BXOR: k1 ^= k2; break;
|
case IR_BXOR: k1 ^= k2; break;
|
||||||
@@ -1366,7 +1366,7 @@ LJFOLDF(simplify_intsub_k)
|
|||||||
if (fright->i == 0) /* i - 0 ==> i */
|
if (fright->i == 0) /* i - 0 ==> i */
|
||||||
return LEFTFOLD;
|
return LEFTFOLD;
|
||||||
fins->o = IR_ADD; /* i - k ==> i + (-k) */
|
fins->o = IR_ADD; /* i - k ==> i + (-k) */
|
||||||
fins->op2 = (IRRef1)lj_ir_kint(J, -fright->i); /* Overflow for -2^31 ok. */
|
fins->op2 = (IRRef1)lj_ir_kint(J, (int32_t)(~(uint32_t)fright->i+1u)); /* Overflow for -2^31 ok. */
|
||||||
return RETRYFOLD;
|
return RETRYFOLD;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1397,7 +1397,7 @@ LJFOLDF(simplify_intsub_k64)
|
|||||||
if (k == 0) /* i - 0 ==> i */
|
if (k == 0) /* i - 0 ==> i */
|
||||||
return LEFTFOLD;
|
return LEFTFOLD;
|
||||||
fins->o = IR_ADD; /* i - k ==> i + (-k) */
|
fins->o = IR_ADD; /* i - k ==> i + (-k) */
|
||||||
fins->op2 = (IRRef1)lj_ir_kint64(J, (uint64_t)-(int64_t)k);
|
fins->op2 = (IRRef1)lj_ir_kint64(J, ~k+1u);
|
||||||
return RETRYFOLD;
|
return RETRYFOLD;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -186,6 +186,7 @@ static TRef fwd_ahload(jit_State *J, IRRef xref)
|
|||||||
fwd_aa_tab_clear(J, tab, tab)) {
|
fwd_aa_tab_clear(J, tab, tab)) {
|
||||||
/* A NEWREF with a number key may end up pointing to the array part.
|
/* A NEWREF with a number key may end up pointing to the array part.
|
||||||
** But it's referenced from HSTORE and not found in the ASTORE chain.
|
** But it's referenced from HSTORE and not found in the ASTORE chain.
|
||||||
|
** Or a NEWREF may rehash the table and move unrelated number keys.
|
||||||
** For now simply consider this a conflict without forwarding anything.
|
** For now simply consider this a conflict without forwarding anything.
|
||||||
*/
|
*/
|
||||||
if (xr->o == IR_AREF) {
|
if (xr->o == IR_AREF) {
|
||||||
@@ -196,6 +197,11 @@ static TRef fwd_ahload(jit_State *J, IRRef xref)
|
|||||||
goto cselim;
|
goto cselim;
|
||||||
ref2 = newref->prev;
|
ref2 = newref->prev;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
IRIns *key = IR(xr->op2);
|
||||||
|
if (key->o == IR_KSLOT) key = IR(key->op1);
|
||||||
|
if (irt_isnum(key->t) && J->chain[IR_NEWREF] > tab)
|
||||||
|
goto cselim;
|
||||||
}
|
}
|
||||||
/* NEWREF inhibits CSE for HREF, and dependent FLOADs from HREFK/AREF.
|
/* NEWREF inhibits CSE for HREF, and dependent FLOADs from HREFK/AREF.
|
||||||
** But the above search for conflicting stores was limited by xref.
|
** But the above search for conflicting stores was limited by xref.
|
||||||
@@ -223,8 +229,8 @@ static TRef fwd_ahload(jit_State *J, IRRef xref)
|
|||||||
if (key->o == IR_KSLOT) key = IR(key->op1);
|
if (key->o == IR_KSLOT) key = IR(key->op1);
|
||||||
lj_ir_kvalue(J->L, &keyv, key);
|
lj_ir_kvalue(J->L, &keyv, key);
|
||||||
tv = lj_tab_get(J->L, ir_ktab(IR(ir->op1)), &keyv);
|
tv = lj_tab_get(J->L, ir_ktab(IR(ir->op1)), &keyv);
|
||||||
lj_assertJ(itype2irt(tv) == irt_type(fins->t),
|
if (itype2irt(tv) != irt_type(fins->t))
|
||||||
"mismatched type in constant table");
|
return 0; /* Type instability in loop-carried dependency. */
|
||||||
if (irt_isnum(fins->t))
|
if (irt_isnum(fins->t))
|
||||||
return lj_ir_knum_u64(J, tv->u64);
|
return lj_ir_knum_u64(J, tv->u64);
|
||||||
else if (LJ_DUALNUM && irt_isint(fins->t))
|
else if (LJ_DUALNUM && irt_isint(fins->t))
|
||||||
|
|||||||
@@ -964,22 +964,22 @@ static void bcemit_unop(FuncState *fs, BCOp op, ExpDesc *e)
|
|||||||
#if LJ_HASFFI
|
#if LJ_HASFFI
|
||||||
if (e->k == VKCDATA) { /* Fold in-place since cdata is not interned. */
|
if (e->k == VKCDATA) { /* Fold in-place since cdata is not interned. */
|
||||||
GCcdata *cd = cdataV(&e->u.nval);
|
GCcdata *cd = cdataV(&e->u.nval);
|
||||||
int64_t *p = (int64_t *)cdataptr(cd);
|
uint64_t *p = (uint64_t *)cdataptr(cd);
|
||||||
if (cd->ctypeid == CTID_COMPLEX_DOUBLE)
|
if (cd->ctypeid == CTID_COMPLEX_DOUBLE)
|
||||||
p[1] ^= (int64_t)U64x(80000000,00000000);
|
p[1] ^= U64x(80000000,00000000);
|
||||||
else
|
else
|
||||||
*p = -*p;
|
*p = ~*p+1u;
|
||||||
return;
|
return;
|
||||||
} else
|
} else
|
||||||
#endif
|
#endif
|
||||||
if (expr_isnumk(e) && !expr_numiszero(e)) { /* Avoid folding to -0. */
|
if (expr_isnumk(e) && !expr_numiszero(e)) { /* Avoid folding to -0. */
|
||||||
TValue *o = expr_numtv(e);
|
TValue *o = expr_numtv(e);
|
||||||
if (tvisint(o)) {
|
if (tvisint(o)) {
|
||||||
int32_t k = intV(o);
|
int32_t k = intV(o), negk = (int32_t)(~(uint32_t)k+1u);
|
||||||
if (k == -k)
|
if (k == negk)
|
||||||
setnumV(o, -(lua_Number)k);
|
setnumV(o, -(lua_Number)k);
|
||||||
else
|
else
|
||||||
setintV(o, -k);
|
setintV(o, negk);
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
o->u64 ^= U64x(80000000,00000000);
|
o->u64 ^= U64x(80000000,00000000);
|
||||||
@@ -2518,6 +2518,7 @@ static int predict_next(LexState *ls, FuncState *fs, BCPos pc)
|
|||||||
cTValue *o;
|
cTValue *o;
|
||||||
switch (bc_op(ins)) {
|
switch (bc_op(ins)) {
|
||||||
case BC_MOV:
|
case BC_MOV:
|
||||||
|
if (bc_d(ins) >= fs->nactvar) return 0;
|
||||||
name = gco2str(gcref(var_get(ls, fs, bc_d(ins)).name));
|
name = gco2str(gcref(var_get(ls, fs, bc_d(ins)).name));
|
||||||
break;
|
break;
|
||||||
case BC_UGET:
|
case BC_UGET:
|
||||||
|
|||||||
@@ -116,6 +116,7 @@ static void rec_check_slots(jit_State *J)
|
|||||||
cTValue *tv = &base[s];
|
cTValue *tv = &base[s];
|
||||||
IRRef ref = tref_ref(tr);
|
IRRef ref = tref_ref(tr);
|
||||||
IRIns *ir = NULL; /* Silence compiler. */
|
IRIns *ir = NULL; /* Silence compiler. */
|
||||||
|
lj_assertJ(tv < J->L->top, "slot %d above top of Lua stack", s);
|
||||||
if (!LJ_FR2 || ref || !(tr & (TREF_FRAME | TREF_CONT))) {
|
if (!LJ_FR2 || ref || !(tr & (TREF_FRAME | TREF_CONT))) {
|
||||||
lj_assertJ(ref >= J->cur.nk && ref < J->cur.nins,
|
lj_assertJ(ref >= J->cur.nk && ref < J->cur.nins,
|
||||||
"slot %d ref %04d out of range", s, ref - REF_BIAS);
|
"slot %d ref %04d out of range", s, ref - REF_BIAS);
|
||||||
@@ -1600,6 +1601,8 @@ TRef lj_record_idx(jit_State *J, RecordIndex *ix)
|
|||||||
TRef key = ix->key;
|
TRef key = ix->key;
|
||||||
if (tref_isinteger(key)) /* NEWREF needs a TValue as a key. */
|
if (tref_isinteger(key)) /* NEWREF needs a TValue as a key. */
|
||||||
key = emitir(IRTN(IR_CONV), key, IRCONV_NUM_INT);
|
key = emitir(IRTN(IR_CONV), key, IRCONV_NUM_INT);
|
||||||
|
else if (tref_isnumber(key) && tref_isk(key) && tvismzero(&ix->keyv))
|
||||||
|
key = lj_ir_knum_zero(J); /* Canonicalize -0.0 to +0.0. */
|
||||||
xref = emitir(IRT(IR_NEWREF, IRT_PGC), ix->tab, key);
|
xref = emitir(IRT(IR_NEWREF, IRT_PGC), ix->tab, key);
|
||||||
keybarrier = 0; /* NEWREF already takes care of the key barrier. */
|
keybarrier = 0; /* NEWREF already takes care of the key barrier. */
|
||||||
#ifdef LUAJIT_ENABLE_TABLE_BUMP
|
#ifdef LUAJIT_ENABLE_TABLE_BUMP
|
||||||
@@ -1939,12 +1942,14 @@ static void rec_varg(jit_State *J, BCReg dst, ptrdiff_t nresults)
|
|||||||
if (J->framedepth > 0) { /* Simple case: varargs defined on-trace. */
|
if (J->framedepth > 0) { /* Simple case: varargs defined on-trace. */
|
||||||
ptrdiff_t i;
|
ptrdiff_t i;
|
||||||
if (nvararg < 0) nvararg = 0;
|
if (nvararg < 0) nvararg = 0;
|
||||||
if (nresults == -1) {
|
if (nresults != 1) {
|
||||||
nresults = nvararg;
|
if (nresults == -1) nresults = nvararg;
|
||||||
J->maxslot = dst + (BCReg)nvararg;
|
|
||||||
} else if (dst + nresults > J->maxslot) {
|
|
||||||
J->maxslot = dst + (BCReg)nresults;
|
J->maxslot = dst + (BCReg)nresults;
|
||||||
|
} else if (dst >= J->maxslot) {
|
||||||
|
J->maxslot = dst + 1;
|
||||||
}
|
}
|
||||||
|
if (J->baseslot + J->maxslot >= LJ_MAX_JSLOTS)
|
||||||
|
lj_trace_err(J, LJ_TRERR_STACKOV);
|
||||||
for (i = 0; i < nresults; i++)
|
for (i = 0; i < nresults; i++)
|
||||||
J->base[dst+i] = i < nvararg ? getslot(J, i - nvararg - 1 - LJ_FR2) : TREF_NIL;
|
J->base[dst+i] = i < nvararg ? getslot(J, i - nvararg - 1 - LJ_FR2) : TREF_NIL;
|
||||||
} else { /* Unknown number of varargs passed to trace. */
|
} else { /* Unknown number of varargs passed to trace. */
|
||||||
@@ -1972,8 +1977,9 @@ static void rec_varg(jit_State *J, BCReg dst, ptrdiff_t nresults)
|
|||||||
}
|
}
|
||||||
for (i = nvararg; i < nresults; i++)
|
for (i = nvararg; i < nresults; i++)
|
||||||
J->base[dst+i] = TREF_NIL;
|
J->base[dst+i] = TREF_NIL;
|
||||||
if (dst + (BCReg)nresults > J->maxslot)
|
if (nresults != 1 || dst >= J->maxslot) {
|
||||||
J->maxslot = dst + (BCReg)nresults;
|
J->maxslot = dst + (BCReg)nresults;
|
||||||
|
}
|
||||||
} else if (select_detect(J)) { /* y = select(x, ...) */
|
} else if (select_detect(J)) { /* y = select(x, ...) */
|
||||||
TRef tridx = J->base[dst-1];
|
TRef tridx = J->base[dst-1];
|
||||||
TRef tr = TREF_NIL;
|
TRef tr = TREF_NIL;
|
||||||
@@ -2022,8 +2028,6 @@ static void rec_varg(jit_State *J, BCReg dst, ptrdiff_t nresults)
|
|||||||
lj_trace_err_info(J, LJ_TRERR_NYIBC);
|
lj_trace_err_info(J, LJ_TRERR_NYIBC);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (J->baseslot + J->maxslot >= LJ_MAX_JSLOTS)
|
|
||||||
lj_trace_err(J, LJ_TRERR_STACKOV);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -- Record allocations -------------------------------------------------- */
|
/* -- Record allocations -------------------------------------------------- */
|
||||||
@@ -2475,6 +2479,7 @@ void lj_record_ins(jit_State *J)
|
|||||||
|
|
||||||
case BC_TSETM:
|
case BC_TSETM:
|
||||||
rec_tsetm(J, ra, (BCReg)(J->L->top - J->L->base), (int32_t)rcv->u32.lo);
|
rec_tsetm(J, ra, (BCReg)(J->L->top - J->L->base), (int32_t)rcv->u32.lo);
|
||||||
|
J->maxslot = ra; /* The table slot at ra-1 is the highest used slot. */
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case BC_TNEW:
|
case BC_TNEW:
|
||||||
|
|||||||
@@ -114,7 +114,7 @@ void LJ_FASTCALL lj_state_growstack(lua_State *L, MSize need)
|
|||||||
n = LJ_STACK_MAX;
|
n = LJ_STACK_MAX;
|
||||||
}
|
}
|
||||||
resizestack(L, n);
|
resizestack(L, n);
|
||||||
if (L->stacksize > LJ_STACK_MAXEX)
|
if (L->stacksize >= LJ_STACK_MAXEX)
|
||||||
lj_err_msg(L, LJ_ERR_STKOV);
|
lj_err_msg(L, LJ_ERR_STKOV);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -102,7 +102,7 @@ retlit:
|
|||||||
char * LJ_FASTCALL lj_strfmt_wint(char *p, int32_t k)
|
char * LJ_FASTCALL lj_strfmt_wint(char *p, int32_t k)
|
||||||
{
|
{
|
||||||
uint32_t u = (uint32_t)k;
|
uint32_t u = (uint32_t)k;
|
||||||
if (k < 0) { u = (uint32_t)-k; *p++ = '-'; }
|
if (k < 0) { u = ~u+1u; *p++ = '-'; }
|
||||||
if (u < 10000) {
|
if (u < 10000) {
|
||||||
if (u < 10) goto dig1;
|
if (u < 10) goto dig1;
|
||||||
if (u < 100) goto dig2;
|
if (u < 100) goto dig2;
|
||||||
@@ -287,7 +287,7 @@ SBuf *lj_strfmt_putfxint(SBuf *sb, SFormat sf, uint64_t k)
|
|||||||
/* Figure out signed prefixes. */
|
/* Figure out signed prefixes. */
|
||||||
if (STRFMT_TYPE(sf) == STRFMT_INT) {
|
if (STRFMT_TYPE(sf) == STRFMT_INT) {
|
||||||
if ((int64_t)k < 0) {
|
if ((int64_t)k < 0) {
|
||||||
k = (uint64_t)-(int64_t)k;
|
k = ~k+1u;
|
||||||
prefix = 256 + '-';
|
prefix = 256 + '-';
|
||||||
} else if ((sf & STRFMT_F_PLUS)) {
|
} else if ((sf & STRFMT_F_PLUS)) {
|
||||||
prefix = 256 + '+';
|
prefix = 256 + '+';
|
||||||
|
|||||||
@@ -124,19 +124,19 @@ static StrScanFmt strscan_hex(const uint8_t *p, TValue *o,
|
|||||||
case STRSCAN_INT:
|
case STRSCAN_INT:
|
||||||
if (!(opt & STRSCAN_OPT_TONUM) && x < 0x80000000u+neg &&
|
if (!(opt & STRSCAN_OPT_TONUM) && x < 0x80000000u+neg &&
|
||||||
!(x == 0 && neg)) {
|
!(x == 0 && neg)) {
|
||||||
o->i = neg ? -(int32_t)x : (int32_t)x;
|
o->i = neg ? (int32_t)(~x+1u) : (int32_t)x;
|
||||||
return STRSCAN_INT; /* Fast path for 32 bit integers. */
|
return STRSCAN_INT; /* Fast path for 32 bit integers. */
|
||||||
}
|
}
|
||||||
if (!(opt & STRSCAN_OPT_C)) { fmt = STRSCAN_NUM; break; }
|
if (!(opt & STRSCAN_OPT_C)) { fmt = STRSCAN_NUM; break; }
|
||||||
/* fallthrough */
|
/* fallthrough */
|
||||||
case STRSCAN_U32:
|
case STRSCAN_U32:
|
||||||
if (dig > 8) return STRSCAN_ERROR;
|
if (dig > 8) return STRSCAN_ERROR;
|
||||||
o->i = neg ? -(int32_t)x : (int32_t)x;
|
o->i = neg ? (int32_t)(~x+1u) : (int32_t)x;
|
||||||
return STRSCAN_U32;
|
return STRSCAN_U32;
|
||||||
case STRSCAN_I64:
|
case STRSCAN_I64:
|
||||||
case STRSCAN_U64:
|
case STRSCAN_U64:
|
||||||
if (dig > 16) return STRSCAN_ERROR;
|
if (dig > 16) return STRSCAN_ERROR;
|
||||||
o->u64 = neg ? (uint64_t)-(int64_t)x : x;
|
o->u64 = neg ? ~x+1u : x;
|
||||||
return fmt;
|
return fmt;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
@@ -168,12 +168,12 @@ static StrScanFmt strscan_oct(const uint8_t *p, TValue *o,
|
|||||||
/* fallthrough */
|
/* fallthrough */
|
||||||
case STRSCAN_U32:
|
case STRSCAN_U32:
|
||||||
if ((x >> 32)) return STRSCAN_ERROR;
|
if ((x >> 32)) return STRSCAN_ERROR;
|
||||||
o->i = neg ? -(int32_t)x : (int32_t)x;
|
o->i = neg ? (int32_t)(~(uint32_t)x+1u) : (int32_t)x;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
case STRSCAN_I64:
|
case STRSCAN_I64:
|
||||||
case STRSCAN_U64:
|
case STRSCAN_U64:
|
||||||
o->u64 = neg ? (uint64_t)-(int64_t)x : x;
|
o->u64 = neg ? ~x+1u : x;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return fmt;
|
return fmt;
|
||||||
@@ -229,18 +229,18 @@ static StrScanFmt strscan_dec(const uint8_t *p, TValue *o,
|
|||||||
switch (fmt) {
|
switch (fmt) {
|
||||||
case STRSCAN_INT:
|
case STRSCAN_INT:
|
||||||
if (!(opt & STRSCAN_OPT_TONUM) && x < 0x80000000u+neg) {
|
if (!(opt & STRSCAN_OPT_TONUM) && x < 0x80000000u+neg) {
|
||||||
o->i = neg ? -(int32_t)x : (int32_t)x;
|
o->i = neg ? (int32_t)(~x+1u) : (int32_t)x;
|
||||||
return STRSCAN_INT; /* Fast path for 32 bit integers. */
|
return STRSCAN_INT; /* Fast path for 32 bit integers. */
|
||||||
}
|
}
|
||||||
if (!(opt & STRSCAN_OPT_C)) { fmt = STRSCAN_NUM; goto plainnumber; }
|
if (!(opt & STRSCAN_OPT_C)) { fmt = STRSCAN_NUM; goto plainnumber; }
|
||||||
/* fallthrough */
|
/* fallthrough */
|
||||||
case STRSCAN_U32:
|
case STRSCAN_U32:
|
||||||
if ((x >> 32) != 0) return STRSCAN_ERROR;
|
if ((x >> 32) != 0) return STRSCAN_ERROR;
|
||||||
o->i = neg ? -(int32_t)x : (int32_t)x;
|
o->i = neg ? (int32_t)(~x+1u) : (int32_t)x;
|
||||||
return STRSCAN_U32;
|
return STRSCAN_U32;
|
||||||
case STRSCAN_I64:
|
case STRSCAN_I64:
|
||||||
case STRSCAN_U64:
|
case STRSCAN_U64:
|
||||||
o->u64 = neg ? (uint64_t)-(int64_t)x : x;
|
o->u64 = neg ? ~x+1u : x;
|
||||||
return fmt;
|
return fmt;
|
||||||
default:
|
default:
|
||||||
plainnumber: /* Fast path for plain numbers < 2^63. */
|
plainnumber: /* Fast path for plain numbers < 2^63. */
|
||||||
@@ -348,18 +348,18 @@ static StrScanFmt strscan_bin(const uint8_t *p, TValue *o,
|
|||||||
switch (fmt) {
|
switch (fmt) {
|
||||||
case STRSCAN_INT:
|
case STRSCAN_INT:
|
||||||
if (!(opt & STRSCAN_OPT_TONUM) && x < 0x80000000u+neg) {
|
if (!(opt & STRSCAN_OPT_TONUM) && x < 0x80000000u+neg) {
|
||||||
o->i = neg ? -(int32_t)x : (int32_t)x;
|
o->i = neg ? (int32_t)(~x+1u) : (int32_t)x;
|
||||||
return STRSCAN_INT; /* Fast path for 32 bit integers. */
|
return STRSCAN_INT; /* Fast path for 32 bit integers. */
|
||||||
}
|
}
|
||||||
if (!(opt & STRSCAN_OPT_C)) { fmt = STRSCAN_NUM; break; }
|
if (!(opt & STRSCAN_OPT_C)) { fmt = STRSCAN_NUM; break; }
|
||||||
/* fallthrough */
|
/* fallthrough */
|
||||||
case STRSCAN_U32:
|
case STRSCAN_U32:
|
||||||
if (dig > 32) return STRSCAN_ERROR;
|
if (dig > 32) return STRSCAN_ERROR;
|
||||||
o->i = neg ? -(int32_t)x : (int32_t)x;
|
o->i = neg ? (int32_t)(~x+1u) : (int32_t)x;
|
||||||
return STRSCAN_U32;
|
return STRSCAN_U32;
|
||||||
case STRSCAN_I64:
|
case STRSCAN_I64:
|
||||||
case STRSCAN_U64:
|
case STRSCAN_U64:
|
||||||
o->u64 = neg ? (uint64_t)-(int64_t)x : x;
|
o->u64 = neg ? ~x+1u : x;
|
||||||
return fmt;
|
return fmt;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
@@ -468,7 +468,7 @@ StrScanFmt lj_strscan_scan(const uint8_t *p, MSize len, TValue *o,
|
|||||||
if (xx >= STRSCAN_MAXEXP) return STRSCAN_ERROR;
|
if (xx >= STRSCAN_MAXEXP) return STRSCAN_ERROR;
|
||||||
p++;
|
p++;
|
||||||
}
|
}
|
||||||
ex += negx ? -(int32_t)xx : (int32_t)xx;
|
ex += negx ? (int32_t)(~xx+1u) : (int32_t)xx;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Parse suffix. */
|
/* Parse suffix. */
|
||||||
@@ -507,7 +507,7 @@ StrScanFmt lj_strscan_scan(const uint8_t *p, MSize len, TValue *o,
|
|||||||
o->n = -0.0;
|
o->n = -0.0;
|
||||||
return STRSCAN_NUM;
|
return STRSCAN_NUM;
|
||||||
} else {
|
} else {
|
||||||
o->i = neg ? -(int32_t)x : (int32_t)x;
|
o->i = neg ? (int32_t)(~x+1u) : (int32_t)x;
|
||||||
return STRSCAN_INT;
|
return STRSCAN_INT;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -260,6 +260,9 @@ typedef enum A64Ins {
|
|||||||
A64I_CBZ = 0x34000000,
|
A64I_CBZ = 0x34000000,
|
||||||
A64I_CBNZ = 0x35000000,
|
A64I_CBNZ = 0x35000000,
|
||||||
|
|
||||||
|
A64I_BRAAZ = 0xd61f081f,
|
||||||
|
A64I_BLRAAZ = 0xd63f081f,
|
||||||
|
|
||||||
A64I_NOP = 0xd503201f,
|
A64I_NOP = 0xd503201f,
|
||||||
|
|
||||||
/* FP */
|
/* FP */
|
||||||
@@ -317,6 +320,9 @@ typedef enum A64Ins {
|
|||||||
A64I_FMOV_DI = 0x1e601000,
|
A64I_FMOV_DI = 0x1e601000,
|
||||||
} A64Ins;
|
} A64Ins;
|
||||||
|
|
||||||
|
#define A64I_BR_AUTH (LJ_ABI_PAUTH ? A64I_BRAAZ : A64I_BR)
|
||||||
|
#define A64I_BLR_AUTH (LJ_ABI_PAUTH ? A64I_BLRAAZ : A64I_BLR)
|
||||||
|
|
||||||
typedef enum A64Shift {
|
typedef enum A64Shift {
|
||||||
A64SH_LSL, A64SH_LSR, A64SH_ASR, A64SH_ROR
|
A64SH_LSL, A64SH_LSR, A64SH_ASR, A64SH_ROR
|
||||||
} A64Shift;
|
} A64Shift;
|
||||||
|
|||||||
+23
-17
@@ -153,6 +153,9 @@ static void trace_save(jit_State *J, GCtrace *T)
|
|||||||
newwhite(J2G(J), T);
|
newwhite(J2G(J), T);
|
||||||
T->gct = ~LJ_TTRACE;
|
T->gct = ~LJ_TTRACE;
|
||||||
T->ir = (IRIns *)p - J->cur.nk; /* The IR has already been copied above. */
|
T->ir = (IRIns *)p - J->cur.nk; /* The IR has already been copied above. */
|
||||||
|
#if LJ_ABI_PAUTH
|
||||||
|
T->mcauth = lj_ptr_sign((ASMFunction)T->mcode, T);
|
||||||
|
#endif
|
||||||
p += szins;
|
p += szins;
|
||||||
TRACE_APPENDVEC(snap, nsnap, SnapShot)
|
TRACE_APPENDVEC(snap, nsnap, SnapShot)
|
||||||
TRACE_APPENDVEC(snapmap, nsnapmap, SnapEntry)
|
TRACE_APPENDVEC(snapmap, nsnapmap, SnapEntry)
|
||||||
@@ -428,6 +431,12 @@ static void trace_start(jit_State *J)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Ensuring forward progress for BC_ITERN can trigger hotcount again. */
|
||||||
|
if (!J->parent && bc_op(*J->pc) == BC_JLOOP) { /* Already compiled. */
|
||||||
|
J->state = LJ_TRACE_IDLE; /* Silently ignored. */
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
/* Get a new trace number. */
|
/* Get a new trace number. */
|
||||||
traceno = trace_findfree(J);
|
traceno = trace_findfree(J);
|
||||||
if (LJ_UNLIKELY(traceno == 0)) { /* No free trace? */
|
if (LJ_UNLIKELY(traceno == 0)) { /* No free trace? */
|
||||||
@@ -864,7 +873,7 @@ int LJ_FASTCALL lj_trace_exit(jit_State *J, void *exptr)
|
|||||||
ExitDataCP exd;
|
ExitDataCP exd;
|
||||||
int errcode, exitcode = J->exitcode;
|
int errcode, exitcode = J->exitcode;
|
||||||
TValue exiterr;
|
TValue exiterr;
|
||||||
const BCIns *pc;
|
const BCIns *pc, *retpc;
|
||||||
void *cf;
|
void *cf;
|
||||||
GCtrace *T;
|
GCtrace *T;
|
||||||
|
|
||||||
@@ -916,22 +925,7 @@ int LJ_FASTCALL lj_trace_exit(jit_State *J, void *exptr)
|
|||||||
} else {
|
} else {
|
||||||
trace_hotside(J, pc);
|
trace_hotside(J, pc);
|
||||||
}
|
}
|
||||||
if (bc_op(*pc) == BC_JLOOP) {
|
/* Return MULTRES or 0 or -17. */
|
||||||
BCIns *retpc = &traceref(J, bc_d(*pc))->startins;
|
|
||||||
int isret = bc_isret(bc_op(*retpc));
|
|
||||||
if (isret || bc_op(*retpc) == BC_ITERN) {
|
|
||||||
if (J->state == LJ_TRACE_RECORD) {
|
|
||||||
J->patchins = *pc;
|
|
||||||
J->patchpc = (BCIns *)pc;
|
|
||||||
*J->patchpc = *retpc;
|
|
||||||
J->bcskip = 1;
|
|
||||||
} else if (isret) {
|
|
||||||
pc = retpc;
|
|
||||||
setcframe_pc(cf, pc);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/* Return MULTRES or 0. */
|
|
||||||
ERRNO_RESTORE
|
ERRNO_RESTORE
|
||||||
switch (bc_op(*pc)) {
|
switch (bc_op(*pc)) {
|
||||||
case BC_CALLM: case BC_CALLMT:
|
case BC_CALLM: case BC_CALLMT:
|
||||||
@@ -940,6 +934,18 @@ int LJ_FASTCALL lj_trace_exit(jit_State *J, void *exptr)
|
|||||||
return (int)((BCReg)(L->top - L->base) + 1 - bc_a(*pc) - bc_d(*pc));
|
return (int)((BCReg)(L->top - L->base) + 1 - bc_a(*pc) - bc_d(*pc));
|
||||||
case BC_TSETM:
|
case BC_TSETM:
|
||||||
return (int)((BCReg)(L->top - L->base) + 1 - bc_a(*pc));
|
return (int)((BCReg)(L->top - L->base) + 1 - bc_a(*pc));
|
||||||
|
case BC_JLOOP:
|
||||||
|
retpc = &traceref(J, bc_d(*pc))->startins;
|
||||||
|
if (bc_isret(bc_op(*retpc)) || bc_op(*retpc) == BC_ITERN) {
|
||||||
|
/* Dispatch to original ins to ensure forward progress. */
|
||||||
|
if (J->state != LJ_TRACE_RECORD) return -17;
|
||||||
|
/* Unpatch bytecode when recording. */
|
||||||
|
J->patchins = *pc;
|
||||||
|
J->patchpc = (BCIns *)pc;
|
||||||
|
*J->patchpc = *retpc;
|
||||||
|
J->bcskip = 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
default:
|
default:
|
||||||
if (bc_op(*pc) >= BC_FUNCF)
|
if (bc_op(*pc) >= BC_FUNCF)
|
||||||
return (int)((BCReg)(L->top - L->base) + 1);
|
return (int)((BCReg)(L->top - L->base) + 1);
|
||||||
|
|||||||
@@ -54,8 +54,8 @@ LJ_ASMF void lj_vm_profhook(void);
|
|||||||
LJ_ASMF void lj_vm_IITERN(void);
|
LJ_ASMF void lj_vm_IITERN(void);
|
||||||
|
|
||||||
/* Trace exit handling. */
|
/* Trace exit handling. */
|
||||||
LJ_ASMF void lj_vm_exit_handler(void);
|
LJ_ASMF char lj_vm_exit_handler[];
|
||||||
LJ_ASMF void lj_vm_exit_interp(void);
|
LJ_ASMF char lj_vm_exit_interp[];
|
||||||
|
|
||||||
/* Internal math helper functions. */
|
/* Internal math helper functions. */
|
||||||
#if LJ_TARGET_PPC || LJ_TARGET_ARM64 || (LJ_TARGET_MIPS && LJ_ABI_SOFTFP)
|
#if LJ_TARGET_PPC || LJ_TARGET_ARM64 || (LJ_TARGET_MIPS && LJ_ABI_SOFTFP)
|
||||||
@@ -111,6 +111,6 @@ LJ_ASMF void lj_cont_stitch(void); /* Trace stitching. */
|
|||||||
LJ_ASMF char lj_vm_asm_begin[];
|
LJ_ASMF char lj_vm_asm_begin[];
|
||||||
|
|
||||||
/* Bytecode offsets are relative to lj_vm_asm_begin. */
|
/* Bytecode offsets are relative to lj_vm_asm_begin. */
|
||||||
#define makeasmfunc(ofs) ((ASMFunction)(lj_vm_asm_begin + (ofs)))
|
#define makeasmfunc(ofs) lj_ptr_sign((ASMFunction)(lj_vm_asm_begin + (ofs)), 0)
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -24,9 +24,10 @@
|
|||||||
/* VM event IDs. */
|
/* VM event IDs. */
|
||||||
typedef enum {
|
typedef enum {
|
||||||
VMEVENT_DEF(BC, 0x00003883),
|
VMEVENT_DEF(BC, 0x00003883),
|
||||||
VMEVENT_DEF(TRACE, 0xb2d91467),
|
VMEVENT_DEF(TRACE, 0x12d91467),
|
||||||
VMEVENT_DEF(RECORD, 0x9284bf4f),
|
VMEVENT_DEF(RECORD, 0x1284bf4f),
|
||||||
VMEVENT_DEF(TEXIT, 0xb29df2b0),
|
VMEVENT_DEF(TEXIT, 0x129df2b0),
|
||||||
|
VMEVENT_DEF(ERRFIN, 0x12d93888),
|
||||||
LJ_VMEVENT__MAX
|
LJ_VMEVENT__MAX
|
||||||
} VMEvent;
|
} VMEvent;
|
||||||
|
|
||||||
|
|||||||
@@ -36,6 +36,17 @@ LJ_FUNCA double lj_wrap_fmod(double x, double y) { return fmod(x, y); }
|
|||||||
|
|
||||||
/* -- Helper functions ---------------------------------------------------- */
|
/* -- Helper functions ---------------------------------------------------- */
|
||||||
|
|
||||||
|
/* Required to prevent the C compiler from applying FMA optimizations.
|
||||||
|
**
|
||||||
|
** Yes, there's -ffp-contract and the FP_CONTRACT pragma ... in theory.
|
||||||
|
** But the current state of C compilers is a mess in this regard.
|
||||||
|
** Also, this function is not performance sensitive at all.
|
||||||
|
*/
|
||||||
|
LJ_NOINLINE static double lj_vm_floormul(double x, double y)
|
||||||
|
{
|
||||||
|
return lj_vm_floor(x / y) * y;
|
||||||
|
}
|
||||||
|
|
||||||
double lj_vm_foldarith(double x, double y, int op)
|
double lj_vm_foldarith(double x, double y, int op)
|
||||||
{
|
{
|
||||||
switch (op) {
|
switch (op) {
|
||||||
@@ -43,7 +54,7 @@ double lj_vm_foldarith(double x, double y, int op)
|
|||||||
case IR_SUB - IR_ADD: return x-y; break;
|
case IR_SUB - IR_ADD: return x-y; break;
|
||||||
case IR_MUL - IR_ADD: return x*y; break;
|
case IR_MUL - IR_ADD: return x*y; break;
|
||||||
case IR_DIV - IR_ADD: return x/y; break;
|
case IR_DIV - IR_ADD: return x/y; break;
|
||||||
case IR_MOD - IR_ADD: return x-lj_vm_floor(x/y)*y; break;
|
case IR_MOD - IR_ADD: return x-lj_vm_floormul(x, y); break;
|
||||||
case IR_POW - IR_ADD: return pow(x, y); break;
|
case IR_POW - IR_ADD: return pow(x, y); break;
|
||||||
case IR_NEG - IR_ADD: return -x; break;
|
case IR_NEG - IR_ADD: return -x; break;
|
||||||
case IR_ABS - IR_ADD: return fabs(x); break;
|
case IR_ABS - IR_ADD: return fabs(x); break;
|
||||||
@@ -64,11 +75,11 @@ int32_t LJ_FASTCALL lj_vm_modi(int32_t a, int32_t b)
|
|||||||
uint32_t y, ua, ub;
|
uint32_t y, ua, ub;
|
||||||
/* This must be checked before using this function. */
|
/* This must be checked before using this function. */
|
||||||
lj_assertX(b != 0, "modulo with zero divisor");
|
lj_assertX(b != 0, "modulo with zero divisor");
|
||||||
ua = a < 0 ? (uint32_t)-a : (uint32_t)a;
|
ua = a < 0 ? ~(uint32_t)a+1u : (uint32_t)a;
|
||||||
ub = b < 0 ? (uint32_t)-b : (uint32_t)b;
|
ub = b < 0 ? ~(uint32_t)b+1u : (uint32_t)b;
|
||||||
y = ua % ub;
|
y = ua % ub;
|
||||||
if (y != 0 && (a^b) < 0) y = y - ub;
|
if (y != 0 && (a^b) < 0) y = y - ub;
|
||||||
if (((int32_t)y^b) < 0) y = (uint32_t)-(int32_t)y;
|
if (((int32_t)y^b) < 0) y = ~y+1u;
|
||||||
return (int32_t)y;
|
return (int32_t)y;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -121,6 +121,7 @@ goto :BUILD
|
|||||||
@set TARGETLIB=libluajit_%TARGETLIB_SUFFIX%.a
|
@set TARGETLIB=libluajit_%TARGETLIB_SUFFIX%.a
|
||||||
:BUILD
|
:BUILD
|
||||||
del %TARGETLIB%
|
del %TARGETLIB%
|
||||||
|
@set LJCOMPILE=%LJCOMPILE% -fPIC
|
||||||
@if "%1" neq "noamalg" goto :AMALG
|
@if "%1" neq "noamalg" goto :AMALG
|
||||||
for %%f in (lj_*.c lib_*.c) do (
|
for %%f in (lj_*.c lib_*.c) do (
|
||||||
%LJCOMPILE% %%f
|
%LJCOMPILE% %%f
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ if exist minilua.exe.manifest^
|
|||||||
minilua %DASM% -LN %DASMFLAGS% -o host\buildvm_arch.h %DASC%
|
minilua %DASM% -LN %DASMFLAGS% -o host\buildvm_arch.h %DASC%
|
||||||
@if errorlevel 1 goto :BAD
|
@if errorlevel 1 goto :BAD
|
||||||
|
|
||||||
%LJCOMPILE% /I "." /I %DASMDIR% %GC64% -DLUAJIT_TARGET=LUAJIT_ARCH_X64 -DLUAJIT_OS=LUAJIT_OS_OTHER -DLUAJIT_DISABLE_JIT -DLUAJIT_DISABLE_FFI -DLUAJIT_NO_UNWIND host\buildvm*.c
|
%LJCOMPILE% /I "." /I %DASMDIR% %GC64% -DLUAJIT_TARGET=LUAJIT_ARCH_X64 -DLUAJIT_OS=LUAJIT_OS_OTHER -DLUAJIT_DISABLE_JIT -DLUAJIT_DISABLE_FFI -DLUAJIT_USE_SYSMALLOC -DLUAJIT_NO_UNWIND host\buildvm*.c
|
||||||
@if errorlevel 1 goto :BAD
|
@if errorlevel 1 goto :BAD
|
||||||
%LJLINK% /out:buildvm.exe buildvm*.obj
|
%LJLINK% /out:buildvm.exe buildvm*.obj
|
||||||
@if errorlevel 1 goto :BAD
|
@if errorlevel 1 goto :BAD
|
||||||
@@ -78,7 +78,7 @@ buildvm -m folddef -o lj_folddef.h lj_opt_fold.c
|
|||||||
@set LJLIB="%SCE_ORBIS_SDK_DIR%\host_tools\bin\orbis-ar" rcus
|
@set LJLIB="%SCE_ORBIS_SDK_DIR%\host_tools\bin\orbis-ar" rcus
|
||||||
@set INCLUDE=""
|
@set INCLUDE=""
|
||||||
|
|
||||||
orbis-as -o lj_vm.o lj_vm.s
|
"%SCE_ORBIS_SDK_DIR%\host_tools\bin\orbis-as" -o lj_vm.o lj_vm.s
|
||||||
|
|
||||||
@if "%1" neq "debug" goto :NODEBUG
|
@if "%1" neq "debug" goto :NODEBUG
|
||||||
@shift
|
@shift
|
||||||
|
|||||||
@@ -74,11 +74,11 @@ buildvm -m folddef -o lj_folddef.h lj_opt_fold.c
|
|||||||
@if errorlevel 1 goto :BAD
|
@if errorlevel 1 goto :BAD
|
||||||
|
|
||||||
@rem ---- Cross compiler ----
|
@rem ---- Cross compiler ----
|
||||||
@set LJCOMPILE="%SCE_PROSPERO_SDK_DIR%\host_tools\bin\prospero-clang" -c -Wall -DLUAJIT_DISABLE_FFI %GC64%
|
@set LJCOMPILE="%SCE_PROSPERO_SDK_DIR%\host_tools\bin\prospero-clang" -c -Wall -DLUAJIT_DISABLE_FFI -DLUAJIT_USE_SYSMALLOC %GC64%
|
||||||
@set LJLIB="%SCE_PROSPERO_SDK_DIR%\host_tools\bin\prospero-llvm-ar" rcus
|
@set LJLIB="%SCE_PROSPERO_SDK_DIR%\host_tools\bin\prospero-llvm-ar" rcus
|
||||||
@set INCLUDE=""
|
@set INCLUDE=""
|
||||||
|
|
||||||
%SCE_PROSPERO_SDK_DIR%\host_tools\bin\prospero-llvm-as -o lj_vm.o lj_vm.s
|
"%SCE_PROSPERO_SDK_DIR%\host_tools\bin\prospero-clang" -c -o lj_vm.o lj_vm.s
|
||||||
|
|
||||||
@if "%1" neq "debug" goto :NODEBUG
|
@if "%1" neq "debug" goto :NODEBUG
|
||||||
@shift
|
@shift
|
||||||
|
|||||||
@@ -2196,8 +2196,8 @@ static void build_subroutines(BuildCtx *ctx)
|
|||||||
|.if JIT
|
|.if JIT
|
||||||
| ldr L, SAVE_L
|
| ldr L, SAVE_L
|
||||||
|1:
|
|1:
|
||||||
| cmp CARG1, #0
|
| cmn CARG1, #LUA_ERRERR
|
||||||
| blt >9 // Check for error from exit.
|
| bhs >9 // Check for error from exit.
|
||||||
| lsl RC, CARG1, #3
|
| lsl RC, CARG1, #3
|
||||||
| ldr LFUNC:CARG2, [BASE, FRAME_FUNC]
|
| ldr LFUNC:CARG2, [BASE, FRAME_FUNC]
|
||||||
| str RC, SAVE_MULTRES
|
| str RC, SAVE_MULTRES
|
||||||
@@ -2213,6 +2213,8 @@ static void build_subroutines(BuildCtx *ctx)
|
|||||||
| ldr INS, [PC], #4
|
| ldr INS, [PC], #4
|
||||||
| lsl MASKR8, MASKR8, #3 // MASKR8 = 255*8.
|
| lsl MASKR8, MASKR8, #3 // MASKR8 = 255*8.
|
||||||
| st_vmstate CARG4
|
| st_vmstate CARG4
|
||||||
|
| cmn CARG1, #17 // Static dispatch?
|
||||||
|
| beq >5
|
||||||
| cmp OP, #BC_FUNCC+2 // Fast function?
|
| cmp OP, #BC_FUNCC+2 // Fast function?
|
||||||
| bhs >4
|
| bhs >4
|
||||||
|2:
|
|2:
|
||||||
@@ -2238,6 +2240,17 @@ static void build_subroutines(BuildCtx *ctx)
|
|||||||
| ldr KBASE, [CARG3, #PC2PROTO(k)]
|
| ldr KBASE, [CARG3, #PC2PROTO(k)]
|
||||||
| b <2
|
| b <2
|
||||||
|
|
|
|
||||||
|
|5: // Dispatch to static entry of original ins replaced by BC_JLOOP.
|
||||||
|
| ldr CARG1, [DISPATCH, #DISPATCH_J(trace)]
|
||||||
|
| decode_RD RC, INS
|
||||||
|
| ldr TRACE:CARG1, [CARG1, RC, lsl #2]
|
||||||
|
| ldr INS, TRACE:CARG1->startins
|
||||||
|
| decode_OP OP, INS
|
||||||
|
| decode_RA8 RA, INS
|
||||||
|
| add OP, DISPATCH, OP, lsl #2
|
||||||
|
| decode_RD RC, INS
|
||||||
|
| ldr pc, [OP, #GG_DISP2STATIC]
|
||||||
|
|
|
||||||
|9: // Rethrow error from the right C frame.
|
|9: // Rethrow error from the right C frame.
|
||||||
| rsb CARG2, CARG1, #0
|
| rsb CARG2, CARG1, #0
|
||||||
| mov CARG1, L
|
| mov CARG1, L
|
||||||
|
|||||||
@@ -77,6 +77,23 @@
|
|||||||
|.define CRET1, x0
|
|.define CRET1, x0
|
||||||
|.define CRET1w, w0
|
|.define CRET1w, w0
|
||||||
|
|
|
|
||||||
|
|//-----------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
|// ARM64e pointer authentication codes (PAC).
|
||||||
|
|.if PAUTH
|
||||||
|
|.macro sp_auth; pacibsp; .endmacro
|
||||||
|
|.macro br_auth, reg; braaz reg; .endmacro
|
||||||
|
|.macro blr_auth, reg; blraaz reg; .endmacro
|
||||||
|
|.macro ret_auth; retab; .endmacro
|
||||||
|
|.else
|
||||||
|
|.macro sp_auth; .endmacro
|
||||||
|
|.macro br_auth, reg; br reg; .endmacro
|
||||||
|
|.macro blr_auth, reg; blr reg; .endmacro
|
||||||
|
|.macro ret_auth; ret; .endmacro
|
||||||
|
|.endif
|
||||||
|
|
|
||||||
|
|//-----------------------------------------------------------------------
|
||||||
|
|
|
||||||
|// Stack layout while in interpreter. Must match with lj_frame.h.
|
|// Stack layout while in interpreter. Must match with lj_frame.h.
|
||||||
|
|
|
|
||||||
|.define CFRAME_SPACE, 208
|
|.define CFRAME_SPACE, 208
|
||||||
@@ -106,6 +123,7 @@
|
|||||||
|.endmacro
|
|.endmacro
|
||||||
|
|
|
|
||||||
|.macro saveregs
|
|.macro saveregs
|
||||||
|
| sp_auth
|
||||||
| sub sp, sp, # CFRAME_SPACE
|
| sub sp, sp, # CFRAME_SPACE
|
||||||
| stp fp, lr, [sp, # SAVE_FP_LR_]
|
| stp fp, lr, [sp, # SAVE_FP_LR_]
|
||||||
| add fp, sp, # SAVE_FP_LR_
|
| add fp, sp, # SAVE_FP_LR_
|
||||||
@@ -180,7 +198,7 @@
|
|||||||
| decode_RA RA, INS
|
| decode_RA RA, INS
|
||||||
| ldr TMP0, [TMP1, #GG_G2DISP]
|
| ldr TMP0, [TMP1, #GG_G2DISP]
|
||||||
| decode_RD RC, INS
|
| decode_RD RC, INS
|
||||||
| br TMP0
|
| br_auth TMP0
|
||||||
|.endmacro
|
|.endmacro
|
||||||
|
|
|
|
||||||
|// Instruction footer.
|
|// Instruction footer.
|
||||||
@@ -209,7 +227,7 @@
|
|||||||
| decode_RA RA, INS
|
| decode_RA RA, INS
|
||||||
| ldr TMP0, [TMP1, #GG_G2DISP]
|
| ldr TMP0, [TMP1, #GG_G2DISP]
|
||||||
| add RA, BASE, RA, lsl #3
|
| add RA, BASE, RA, lsl #3
|
||||||
| br TMP0
|
| br_auth TMP0
|
||||||
|.endmacro
|
|.endmacro
|
||||||
|
|
|
|
||||||
|.macro ins_call
|
|.macro ins_call
|
||||||
@@ -356,7 +374,7 @@ static void build_subroutines(BuildCtx *ctx)
|
|||||||
|
|
|
|
||||||
|->vm_leave_unw:
|
|->vm_leave_unw:
|
||||||
| restoreregs
|
| restoreregs
|
||||||
| ret
|
| ret_auth
|
||||||
|
|
|
|
||||||
|6:
|
|6:
|
||||||
| bgt >7 // Less results wanted?
|
| bgt >7 // Less results wanted?
|
||||||
@@ -542,7 +560,7 @@ static void build_subroutines(BuildCtx *ctx)
|
|||||||
| str RC, SAVE_CFRAME
|
| str RC, SAVE_CFRAME
|
||||||
| str TMP0, L->cframe // Add our C frame to cframe chain.
|
| str TMP0, L->cframe // Add our C frame to cframe chain.
|
||||||
| str L, GL->cur_L
|
| str L, GL->cur_L
|
||||||
| blr CARG4 // (lua_State *L, lua_CFunction func, void *ud)
|
| blr_auth CARG4 // (lua_State *L, lua_CFunction func, void *ud)
|
||||||
| mov BASE, CRET1
|
| mov BASE, CRET1
|
||||||
| mov PC, #FRAME_CP
|
| mov PC, #FRAME_CP
|
||||||
| cbnz BASE, <3 // Else continue with the call.
|
| cbnz BASE, <3 // Else continue with the call.
|
||||||
@@ -573,7 +591,7 @@ static void build_subroutines(BuildCtx *ctx)
|
|||||||
| ldr CARG3, LFUNC:CARG3->pc
|
| ldr CARG3, LFUNC:CARG3->pc
|
||||||
| ldr KBASE, [CARG3, #PC2PROTO(k)]
|
| ldr KBASE, [CARG3, #PC2PROTO(k)]
|
||||||
| // BASE = base, RA = resultptr, CARG4 = meta base
|
| // BASE = base, RA = resultptr, CARG4 = meta base
|
||||||
| br CARG1
|
| br_auth CARG1
|
||||||
|
|
|
|
||||||
|.if FFI
|
|.if FFI
|
||||||
|1:
|
|1:
|
||||||
@@ -1707,7 +1725,7 @@ static void build_subroutines(BuildCtx *ctx)
|
|||||||
| cmp TMP1, TMP2
|
| cmp TMP1, TMP2
|
||||||
| mov CARG1, L
|
| mov CARG1, L
|
||||||
| bhi >5 // Need to grow stack.
|
| bhi >5 // Need to grow stack.
|
||||||
| blr CARG3 // (lua_State *L)
|
| blr_auth CARG3 // (lua_State *L)
|
||||||
| // Either throws an error, or recovers and returns -1, 0 or nresults+1.
|
| // Either throws an error, or recovers and returns -1, 0 or nresults+1.
|
||||||
| ldr BASE, L->base
|
| ldr BASE, L->base
|
||||||
| cmp CRET1w, #0
|
| cmp CRET1w, #0
|
||||||
@@ -1743,6 +1761,7 @@ static void build_subroutines(BuildCtx *ctx)
|
|||||||
|
|
|
|
||||||
|->fff_gcstep: // Call GC step function.
|
|->fff_gcstep: // Call GC step function.
|
||||||
| // BASE = new base, RC = nargs*8
|
| // BASE = new base, RC = nargs*8
|
||||||
|
| sp_auth
|
||||||
| add CARG2, BASE, NARGS8:RC // Calculate L->top.
|
| add CARG2, BASE, NARGS8:RC // Calculate L->top.
|
||||||
| mov RA, lr
|
| mov RA, lr
|
||||||
| stp BASE, CARG2, L->base
|
| stp BASE, CARG2, L->base
|
||||||
@@ -1754,7 +1773,7 @@ static void build_subroutines(BuildCtx *ctx)
|
|||||||
| mov lr, RA // Help return address predictor.
|
| mov lr, RA // Help return address predictor.
|
||||||
| sub NARGS8:RC, CARG2, BASE // Calculate nargs*8.
|
| sub NARGS8:RC, CARG2, BASE // Calculate nargs*8.
|
||||||
| and CFUNC:CARG3, CARG3, #LJ_GCVMASK
|
| and CFUNC:CARG3, CARG3, #LJ_GCVMASK
|
||||||
| ret
|
| ret_auth
|
||||||
|
|
|
|
||||||
|//-----------------------------------------------------------------------
|
|//-----------------------------------------------------------------------
|
||||||
|//-- Special dispatch targets -------------------------------------------
|
|//-- Special dispatch targets -------------------------------------------
|
||||||
@@ -1781,7 +1800,7 @@ static void build_subroutines(BuildCtx *ctx)
|
|||||||
| tbz TMP2w, #HOOK_ACTIVE_SHIFT, >1 // Hook already active?
|
| tbz TMP2w, #HOOK_ACTIVE_SHIFT, >1 // Hook already active?
|
||||||
|5: // Re-dispatch to static ins.
|
|5: // Re-dispatch to static ins.
|
||||||
| ldr TMP0, [TMP1, #GG_G2DISP+GG_DISP2STATIC]
|
| ldr TMP0, [TMP1, #GG_G2DISP+GG_DISP2STATIC]
|
||||||
| br TMP0
|
| br_auth TMP0
|
||||||
|
|
|
|
||||||
|->vm_inshook: // Dispatch target for instr/line hooks.
|
|->vm_inshook: // Dispatch target for instr/line hooks.
|
||||||
| ldrb TMP2w, GL->hookmask
|
| ldrb TMP2w, GL->hookmask
|
||||||
@@ -1807,7 +1826,7 @@ static void build_subroutines(BuildCtx *ctx)
|
|||||||
| decode_RA RA, INS
|
| decode_RA RA, INS
|
||||||
| ldr TMP0, [TMP1, #GG_G2DISP+GG_DISP2STATIC]
|
| ldr TMP0, [TMP1, #GG_G2DISP+GG_DISP2STATIC]
|
||||||
| decode_RD RC, INS
|
| decode_RD RC, INS
|
||||||
| br TMP0
|
| br_auth TMP0
|
||||||
|
|
|
|
||||||
|->cont_hook: // Continue from hook yield.
|
|->cont_hook: // Continue from hook yield.
|
||||||
| ldr CARG1, [CARG4, #-40]
|
| ldr CARG1, [CARG4, #-40]
|
||||||
@@ -1857,7 +1876,7 @@ static void build_subroutines(BuildCtx *ctx)
|
|||||||
| sub NARGS8:RC, TMP1, BASE
|
| sub NARGS8:RC, TMP1, BASE
|
||||||
| ldr INSw, [PC, #-4]
|
| ldr INSw, [PC, #-4]
|
||||||
| and LFUNC:CARG3, CARG3, #LJ_GCVMASK
|
| and LFUNC:CARG3, CARG3, #LJ_GCVMASK
|
||||||
| br CRET1
|
| br_auth CRET1
|
||||||
|
|
|
|
||||||
|->cont_stitch: // Trace stitching.
|
|->cont_stitch: // Trace stitching.
|
||||||
|.if JIT
|
|.if JIT
|
||||||
@@ -1986,8 +2005,8 @@ static void build_subroutines(BuildCtx *ctx)
|
|||||||
|.if JIT
|
|.if JIT
|
||||||
| ldr L, SAVE_L
|
| ldr L, SAVE_L
|
||||||
|1:
|
|1:
|
||||||
| cmp CARG1w, #0
|
| cmn CARG1w, #LUA_ERRERR
|
||||||
| blt >9 // Check for error from exit.
|
| bhs >9 // Check for error from exit.
|
||||||
| lsl RC, CARG1, #3
|
| lsl RC, CARG1, #3
|
||||||
| ldr LFUNC:CARG2, [BASE, FRAME_FUNC]
|
| ldr LFUNC:CARG2, [BASE, FRAME_FUNC]
|
||||||
| movz TISNUM, #(LJ_TISNUM>>1)&0xffff, lsl #48
|
| movz TISNUM, #(LJ_TISNUM>>1)&0xffff, lsl #48
|
||||||
@@ -2004,6 +2023,8 @@ static void build_subroutines(BuildCtx *ctx)
|
|||||||
| ldrb RBw, [PC, # OFS_OP]
|
| ldrb RBw, [PC, # OFS_OP]
|
||||||
| ldr INSw, [PC], #4
|
| ldr INSw, [PC], #4
|
||||||
| st_vmstate CARG4w
|
| st_vmstate CARG4w
|
||||||
|
| cmn CARG1w, #17 // Static dispatch?
|
||||||
|
| beq >5
|
||||||
| cmp RBw, #BC_FUNCC+2 // Fast function?
|
| cmp RBw, #BC_FUNCC+2 // Fast function?
|
||||||
| add TMP1, GL, INS, uxtb #3
|
| add TMP1, GL, INS, uxtb #3
|
||||||
| bhs >4
|
| bhs >4
|
||||||
@@ -2014,13 +2035,13 @@ static void build_subroutines(BuildCtx *ctx)
|
|||||||
| decode_RA RA, INS
|
| decode_RA RA, INS
|
||||||
| lsr TMP0, INS, #16
|
| lsr TMP0, INS, #16
|
||||||
| csel RC, TMP0, RC, lo
|
| csel RC, TMP0, RC, lo
|
||||||
| blo >5
|
| blo >3
|
||||||
| ldr CARG3, [BASE, FRAME_FUNC]
|
| ldr CARG3, [BASE, FRAME_FUNC]
|
||||||
| sub RC, RC, #8
|
| sub RC, RC, #8
|
||||||
| add RA, BASE, RA, lsl #3 // Yes: RA = BASE+framesize*8, RC = nargs*8
|
| add RA, BASE, RA, lsl #3 // Yes: RA = BASE+framesize*8, RC = nargs*8
|
||||||
| and LFUNC:CARG3, CARG3, #LJ_GCVMASK
|
| and LFUNC:CARG3, CARG3, #LJ_GCVMASK
|
||||||
|5:
|
|3:
|
||||||
| br RB
|
| br_auth RB
|
||||||
|
|
|
|
||||||
|4: // Check frame below fast function.
|
|4: // Check frame below fast function.
|
||||||
| ldr CARG1, [BASE, FRAME_PC]
|
| ldr CARG1, [BASE, FRAME_PC]
|
||||||
@@ -2036,6 +2057,17 @@ static void build_subroutines(BuildCtx *ctx)
|
|||||||
| ldr KBASE, [CARG3, #PC2PROTO(k)]
|
| ldr KBASE, [CARG3, #PC2PROTO(k)]
|
||||||
| b <2
|
| b <2
|
||||||
|
|
|
|
||||||
|
|5: // Dispatch to static entry of original ins replaced by BC_JLOOP.
|
||||||
|
| ldr RA, [GL, #GL_J(trace)]
|
||||||
|
| decode_RD RC, INS
|
||||||
|
| ldr TRACE:RA, [RA, RC, lsl #3]
|
||||||
|
| ldr INSw, TRACE:RA->startins
|
||||||
|
| add TMP0, GL, INS, uxtb #3
|
||||||
|
| decode_RA RA, INS
|
||||||
|
| ldr RB, [TMP0, #GG_G2DISP+GG_DISP2STATIC]
|
||||||
|
| decode_RD RC, INS
|
||||||
|
| br_auth RB
|
||||||
|
|
|
||||||
|9: // Rethrow error from the right C frame.
|
|9: // Rethrow error from the right C frame.
|
||||||
| neg CARG2w, CARG1w
|
| neg CARG2w, CARG1w
|
||||||
| mov CARG1, L
|
| mov CARG1, L
|
||||||
@@ -2182,6 +2214,7 @@ static void build_subroutines(BuildCtx *ctx)
|
|||||||
| // Caveat: needs special frame unwinding, see below.
|
| // Caveat: needs special frame unwinding, see below.
|
||||||
|.if FFI
|
|.if FFI
|
||||||
| .type CCSTATE, CCallState, x19
|
| .type CCSTATE, CCallState, x19
|
||||||
|
| sp_auth
|
||||||
| stp x20, CCSTATE, [sp, #-32]!
|
| stp x20, CCSTATE, [sp, #-32]!
|
||||||
| stp fp, lr, [sp, #16]
|
| stp fp, lr, [sp, #16]
|
||||||
| add fp, sp, #16
|
| add fp, sp, #16
|
||||||
@@ -2208,14 +2241,14 @@ static void build_subroutines(BuildCtx *ctx)
|
|||||||
| ldp x6, x7, CCSTATE->gpr[6]
|
| ldp x6, x7, CCSTATE->gpr[6]
|
||||||
| ldp d6, d7, CCSTATE->fpr[6]
|
| ldp d6, d7, CCSTATE->fpr[6]
|
||||||
| ldr x8, CCSTATE->retp
|
| ldr x8, CCSTATE->retp
|
||||||
| blr TMP3
|
| blr_auth TMP3
|
||||||
| sub sp, fp, #16
|
| sub sp, fp, #16
|
||||||
| stp x0, x1, CCSTATE->gpr[0]
|
| stp x0, x1, CCSTATE->gpr[0]
|
||||||
| stp d0, d1, CCSTATE->fpr[0]
|
| stp d0, d1, CCSTATE->fpr[0]
|
||||||
| stp d2, d3, CCSTATE->fpr[2]
|
| stp d2, d3, CCSTATE->fpr[2]
|
||||||
| ldp fp, lr, [sp, #16]
|
| ldp fp, lr, [sp, #16]
|
||||||
| ldp x20, CCSTATE, [sp], #32
|
| ldp x20, CCSTATE, [sp], #32
|
||||||
| ret
|
| ret_auth
|
||||||
|.endif
|
|.endif
|
||||||
|// Note: vm_ffi_call must be the last function in this object file!
|
|// Note: vm_ffi_call must be the last function in this object file!
|
||||||
|
|
|
|
||||||
@@ -2636,7 +2669,9 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop)
|
|||||||
|.macro ins_arithmod, res, reg1, reg2
|
|.macro ins_arithmod, res, reg1, reg2
|
||||||
| fdiv d2, reg1, reg2
|
| fdiv d2, reg1, reg2
|
||||||
| frintm d2, d2
|
| frintm d2, d2
|
||||||
| fmsub res, d2, reg2, reg1
|
| // Cannot use fmsub, because FMA is not enabled by default.
|
||||||
|
| fmul d2, d2, reg2
|
||||||
|
| fsub res, reg1, d2
|
||||||
|.endmacro
|
|.endmacro
|
||||||
|
|
|
|
||||||
|.macro ins_arithdn, intins, fpins
|
|.macro ins_arithdn, intins, fpins
|
||||||
@@ -3784,12 +3819,20 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop)
|
|||||||
| mov CARG2w, #0 // Traces on ARM64 don't store the trace #, so use 0.
|
| mov CARG2w, #0 // Traces on ARM64 don't store the trace #, so use 0.
|
||||||
| ldr TRACE:RC, [CARG1, RC, lsl #3]
|
| ldr TRACE:RC, [CARG1, RC, lsl #3]
|
||||||
| st_vmstate CARG2w
|
| st_vmstate CARG2w
|
||||||
|
|.if PAUTH
|
||||||
|
| ldr RA, TRACE:RC->mcauth
|
||||||
|
|.else
|
||||||
| ldr RA, TRACE:RC->mcode
|
| ldr RA, TRACE:RC->mcode
|
||||||
|
|.endif
|
||||||
| str BASE, GL->jit_base
|
| str BASE, GL->jit_base
|
||||||
| str L, GL->tmpbuf.L
|
| str L, GL->tmpbuf.L
|
||||||
| sub sp, sp, #16 // See SPS_FIXED. Avoids sp adjust in every root trace.
|
| sub sp, sp, #16 // See SPS_FIXED. Avoids sp adjust in every root trace.
|
||||||
|
|.if PAUTH
|
||||||
|
| braa RA, RC
|
||||||
|
|.else
|
||||||
| br RA
|
| br RA
|
||||||
|.endif
|
|.endif
|
||||||
|
|.endif
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case BC_JMP:
|
case BC_JMP:
|
||||||
@@ -3899,7 +3942,7 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop)
|
|||||||
| mov CARG1, L
|
| mov CARG1, L
|
||||||
| bhi ->vm_growstack_c // Need to grow stack.
|
| bhi ->vm_growstack_c // Need to grow stack.
|
||||||
| st_vmstate TMP0w
|
| st_vmstate TMP0w
|
||||||
| blr CARG4 // (lua_State *L [, lua_CFunction f])
|
| blr_auth CARG4 // (lua_State *L [, lua_CFunction f])
|
||||||
| // Returns nresults.
|
| // Returns nresults.
|
||||||
| ldp BASE, TMP1, L->base
|
| ldp BASE, TMP1, L->base
|
||||||
| str L, GL->cur_L
|
| str L, GL->cur_L
|
||||||
|
|||||||
@@ -2466,7 +2466,8 @@ static void build_subroutines(BuildCtx *ctx)
|
|||||||
| addiu DISPATCH, JGL, -GG_DISP2G-32768
|
| addiu DISPATCH, JGL, -GG_DISP2G-32768
|
||||||
| sw BASE, L->base
|
| sw BASE, L->base
|
||||||
|1:
|
|1:
|
||||||
| bltz CRET1, >9 // Check for error from exit.
|
| sltiu TMP0, CRET1, -LUA_ERRERR // Check for error from exit.
|
||||||
|
| beqz TMP0, >9
|
||||||
|. lw LFUNC:RB, FRAME_FUNC(BASE)
|
|. lw LFUNC:RB, FRAME_FUNC(BASE)
|
||||||
| .FPU lui TMP3, 0x59c0 // TOBIT = 2^52 + 2^51 (float).
|
| .FPU lui TMP3, 0x59c0 // TOBIT = 2^52 + 2^51 (float).
|
||||||
| sll MULTRES, CRET1, 3
|
| sll MULTRES, CRET1, 3
|
||||||
@@ -2480,14 +2481,16 @@ static void build_subroutines(BuildCtx *ctx)
|
|||||||
| .FPU cvt.d.s TOBIT, TOBIT
|
| .FPU cvt.d.s TOBIT, TOBIT
|
||||||
| // Modified copy of ins_next which handles function header dispatch, too.
|
| // Modified copy of ins_next which handles function header dispatch, too.
|
||||||
| lw INS, 0(PC)
|
| lw INS, 0(PC)
|
||||||
| addiu PC, PC, 4
|
| addiu CRET1, CRET1, 17 // Static dispatch?
|
||||||
| // Assumes TISNIL == ~LJ_VMST_INTERP == -1
|
| // Assumes TISNIL == ~LJ_VMST_INTERP == -1
|
||||||
| sw TISNIL, DISPATCH_GL(vmstate)(DISPATCH)
|
| sw TISNIL, DISPATCH_GL(vmstate)(DISPATCH)
|
||||||
|
| decode_RD8a RD, INS
|
||||||
|
| beqz CRET1, >5
|
||||||
|
|. addiu PC, PC, 4
|
||||||
| decode_OP4a TMP1, INS
|
| decode_OP4a TMP1, INS
|
||||||
| decode_OP4b TMP1
|
| decode_OP4b TMP1
|
||||||
| sltiu TMP2, TMP1, BC_FUNCF*4
|
|
||||||
| addu TMP0, DISPATCH, TMP1
|
| addu TMP0, DISPATCH, TMP1
|
||||||
| decode_RD8a RD, INS
|
| sltiu TMP2, TMP1, BC_FUNCF*4
|
||||||
| lw AT, 0(TMP0)
|
| lw AT, 0(TMP0)
|
||||||
| decode_RA8a RA, INS
|
| decode_RA8a RA, INS
|
||||||
| beqz TMP2, >2
|
| beqz TMP2, >2
|
||||||
@@ -2515,6 +2518,22 @@ static void build_subroutines(BuildCtx *ctx)
|
|||||||
| jr AT
|
| jr AT
|
||||||
|. addu RA, RA, BASE
|
|. addu RA, RA, BASE
|
||||||
|
|
|
|
||||||
|
|5: // Dispatch to static entry of original ins replaced by BC_JLOOP.
|
||||||
|
| lw TMP0, DISPATCH_J(trace)(DISPATCH)
|
||||||
|
| decode_RD4b RD
|
||||||
|
| addu TMP0, TMP0, RD
|
||||||
|
| lw TRACE:TMP2, 0(TMP0)
|
||||||
|
| lw INS, TRACE:TMP2->startins
|
||||||
|
| decode_OP4a TMP1, INS
|
||||||
|
| decode_OP4b TMP1
|
||||||
|
| addu TMP0, DISPATCH, TMP1
|
||||||
|
| decode_RD8a RD, INS
|
||||||
|
| lw AT, GG_DISP2STATIC(TMP0)
|
||||||
|
| decode_RA8a RA, INS
|
||||||
|
| decode_RD8b RD
|
||||||
|
| jr AT
|
||||||
|
|. decode_RA8b RA
|
||||||
|
|
|
||||||
|9: // Rethrow error from the right C frame.
|
|9: // Rethrow error from the right C frame.
|
||||||
| load_got lj_err_trace
|
| load_got lj_err_trace
|
||||||
| sub CARG2, r0, CRET1
|
| sub CARG2, r0, CRET1
|
||||||
|
|||||||
@@ -2571,7 +2571,8 @@ static void build_subroutines(BuildCtx *ctx)
|
|||||||
| daddiu DISPATCH, JGL, -GG_DISP2G-32768
|
| daddiu DISPATCH, JGL, -GG_DISP2G-32768
|
||||||
| sd BASE, L->base
|
| sd BASE, L->base
|
||||||
|1:
|
|1:
|
||||||
| bltz CRET1, >9 // Check for error from exit.
|
| sltiu TMP0, CRET1, -LUA_ERRERR // Check for error from exit.
|
||||||
|
| beqz TMP0, >9
|
||||||
|. ld LFUNC:RB, FRAME_FUNC(BASE)
|
|. ld LFUNC:RB, FRAME_FUNC(BASE)
|
||||||
| .FPU lui TMP3, 0x59c0 // TOBIT = 2^52 + 2^51 (float).
|
| .FPU lui TMP3, 0x59c0 // TOBIT = 2^52 + 2^51 (float).
|
||||||
| dsll MULTRES, CRET1, 3
|
| dsll MULTRES, CRET1, 3
|
||||||
@@ -2586,14 +2587,16 @@ static void build_subroutines(BuildCtx *ctx)
|
|||||||
| .FPU cvt.d.s TOBIT, TOBIT
|
| .FPU cvt.d.s TOBIT, TOBIT
|
||||||
| // Modified copy of ins_next which handles function header dispatch, too.
|
| // Modified copy of ins_next which handles function header dispatch, too.
|
||||||
| lw INS, 0(PC)
|
| lw INS, 0(PC)
|
||||||
| daddiu PC, PC, 4
|
| addiu CRET1, CRET1, 17 // Static dispatch?
|
||||||
| // Assumes TISNIL == ~LJ_VMST_INTERP == -1
|
| // Assumes TISNIL == ~LJ_VMST_INTERP == -1
|
||||||
| sw TISNIL, DISPATCH_GL(vmstate)(DISPATCH)
|
| sw TISNIL, DISPATCH_GL(vmstate)(DISPATCH)
|
||||||
|
| decode_RD8a RD, INS
|
||||||
|
| beqz CRET1, >5
|
||||||
|
|. daddiu PC, PC, 4
|
||||||
| decode_OP8a TMP1, INS
|
| decode_OP8a TMP1, INS
|
||||||
| decode_OP8b TMP1
|
| decode_OP8b TMP1
|
||||||
| sltiu TMP2, TMP1, BC_FUNCF*8
|
|
||||||
| daddu TMP0, DISPATCH, TMP1
|
| daddu TMP0, DISPATCH, TMP1
|
||||||
| decode_RD8a RD, INS
|
| sltiu TMP2, TMP1, BC_FUNCF*8
|
||||||
| ld AT, 0(TMP0)
|
| ld AT, 0(TMP0)
|
||||||
| decode_RA8a RA, INS
|
| decode_RA8a RA, INS
|
||||||
| beqz TMP2, >2
|
| beqz TMP2, >2
|
||||||
@@ -2622,6 +2625,22 @@ static void build_subroutines(BuildCtx *ctx)
|
|||||||
| jr AT
|
| jr AT
|
||||||
|. daddu RA, RA, BASE
|
|. daddu RA, RA, BASE
|
||||||
|
|
|
|
||||||
|
|5: // Dispatch to static entry of original ins replaced by BC_JLOOP.
|
||||||
|
| ld TMP0, DISPATCH_J(trace)(DISPATCH)
|
||||||
|
| decode_RD8b RD
|
||||||
|
| daddu TMP0, TMP0, RD
|
||||||
|
| ld TRACE:TMP2, 0(TMP0)
|
||||||
|
| lw INS, TRACE:TMP2->startins
|
||||||
|
| decode_OP8a TMP1, INS
|
||||||
|
| decode_OP8b TMP1
|
||||||
|
| daddu TMP0, DISPATCH, TMP1
|
||||||
|
| decode_RD8a RD, INS
|
||||||
|
| ld AT, GG_DISP2STATIC(TMP0)
|
||||||
|
| decode_RA8a RA, INS
|
||||||
|
| decode_RD8b RD
|
||||||
|
| jr AT
|
||||||
|
|. decode_RA8b RA
|
||||||
|
|
|
||||||
|9: // Rethrow error from the right C frame.
|
|9: // Rethrow error from the right C frame.
|
||||||
| load_got lj_err_trace
|
| load_got lj_err_trace
|
||||||
| sub CARG2, r0, CRET1
|
| sub CARG2, r0, CRET1
|
||||||
|
|||||||
@@ -3015,8 +3015,9 @@ static void build_subroutines(BuildCtx *ctx)
|
|||||||
| addi DISPATCH, JGL, -GG_DISP2G-32768
|
| addi DISPATCH, JGL, -GG_DISP2G-32768
|
||||||
| stp BASE, L->base
|
| stp BASE, L->base
|
||||||
|1:
|
|1:
|
||||||
| cmpwi CARG1, 0
|
| li TMP2, -LUA_ERRERR
|
||||||
| blt >9 // Check for error from exit.
|
| cmplw CARG1, TMP2
|
||||||
|
| bge >9 // Check for error from exit.
|
||||||
| lwz LFUNC:RB, FRAME_FUNC(BASE)
|
| lwz LFUNC:RB, FRAME_FUNC(BASE)
|
||||||
| slwi MULTRES, CARG1, 3
|
| slwi MULTRES, CARG1, 3
|
||||||
| li TMP2, 0
|
| li TMP2, 0
|
||||||
@@ -3041,6 +3042,8 @@ static void build_subroutines(BuildCtx *ctx)
|
|||||||
| addi PC, PC, 4
|
| addi PC, PC, 4
|
||||||
| // Assumes TISNIL == ~LJ_VMST_INTERP == -1.
|
| // Assumes TISNIL == ~LJ_VMST_INTERP == -1.
|
||||||
| stw TISNIL, DISPATCH_GL(vmstate)(DISPATCH)
|
| stw TISNIL, DISPATCH_GL(vmstate)(DISPATCH)
|
||||||
|
| cmpwi CARG1, -17 // Static dispatch?
|
||||||
|
| beq >5
|
||||||
| decode_OPP TMP1, INS
|
| decode_OPP TMP1, INS
|
||||||
| decode_RA8 RA, INS
|
| decode_RA8 RA, INS
|
||||||
| lpx TMP0, DISPATCH, TMP1
|
| lpx TMP0, DISPATCH, TMP1
|
||||||
@@ -3070,6 +3073,21 @@ static void build_subroutines(BuildCtx *ctx)
|
|||||||
| add RA, RA, BASE
|
| add RA, RA, BASE
|
||||||
| bctr
|
| bctr
|
||||||
|
|
|
|
||||||
|
|5: // Dispatch to static entry of original ins replaced by BC_JLOOP.
|
||||||
|
| lwz TMP1, DISPATCH_J(trace)(DISPATCH)
|
||||||
|
| decode_RD4 RD, INS
|
||||||
|
| lwzx TRACE:TMP1, TMP1, RD
|
||||||
|
| lwz INS, TRACE:TMP1->startins
|
||||||
|
| decode_OPP TMP1, INS
|
||||||
|
| addi TMP1, TMP1, GG_DISP2STATIC
|
||||||
|
| lpx TMP0, DISPATCH, TMP1
|
||||||
|
| mtctr TMP0
|
||||||
|
| decode_RB8 RB, INS
|
||||||
|
| decode_RD8 RD, INS
|
||||||
|
| decode_RA8 RA, INS
|
||||||
|
| decode_RC8 RC, INS
|
||||||
|
| bctr
|
||||||
|
|
|
||||||
|9: // Rethrow error from the right C frame.
|
|9: // Rethrow error from the right C frame.
|
||||||
| neg CARG2, CARG1
|
| neg CARG2, CARG1
|
||||||
| mr CARG1, L
|
| mr CARG1, L
|
||||||
|
|||||||
@@ -2453,7 +2453,7 @@ static void build_subroutines(BuildCtx *ctx)
|
|||||||
| mov r12, [RA]
|
| mov r12, [RA]
|
||||||
| mov rsp, RA // Reposition stack to C frame.
|
| mov rsp, RA // Reposition stack to C frame.
|
||||||
|.endif
|
|.endif
|
||||||
| test RDd, RDd; js >9 // Check for error from exit.
|
| cmp RDd, -LUA_ERRERR; jae >9 // Check for error from exit.
|
||||||
| mov L:RB, SAVE_L
|
| mov L:RB, SAVE_L
|
||||||
| mov MULTRES, RDd
|
| mov MULTRES, RDd
|
||||||
| mov LFUNC:KBASE, [BASE-16]
|
| mov LFUNC:KBASE, [BASE-16]
|
||||||
@@ -2469,6 +2469,8 @@ static void build_subroutines(BuildCtx *ctx)
|
|||||||
| movzx OP, RCL
|
| movzx OP, RCL
|
||||||
| add PC, 4
|
| add PC, 4
|
||||||
| shr RCd, 16
|
| shr RCd, 16
|
||||||
|
| cmp MULTRES, -17 // Static dispatch?
|
||||||
|
| je >5
|
||||||
| cmp OP, BC_FUNCF // Function header?
|
| cmp OP, BC_FUNCF // Function header?
|
||||||
| jb >3
|
| jb >3
|
||||||
| cmp OP, BC_FUNCC+2 // Fast function?
|
| cmp OP, BC_FUNCC+2 // Fast function?
|
||||||
@@ -2491,6 +2493,15 @@ static void build_subroutines(BuildCtx *ctx)
|
|||||||
| mov KBASE, [KBASE+PC2PROTO(k)]
|
| mov KBASE, [KBASE+PC2PROTO(k)]
|
||||||
| jmp <2
|
| jmp <2
|
||||||
|
|
|
|
||||||
|
|5: // Dispatch to static entry of original ins replaced by BC_JLOOP.
|
||||||
|
| mov RA, [DISPATCH+DISPATCH_J(trace)]
|
||||||
|
| mov TRACE:RA, [RA+RD*8]
|
||||||
|
| mov RCd, TRACE:RA->startins
|
||||||
|
| movzx RAd, RCH
|
||||||
|
| movzx OP, RCL
|
||||||
|
| shr RCd, 16
|
||||||
|
| jmp aword [DISPATCH+OP*8+GG_DISP2STATIC]
|
||||||
|
|
|
||||||
|9: // Rethrow error from the right C frame.
|
|9: // Rethrow error from the right C frame.
|
||||||
| mov CARG2d, RDd
|
| mov CARG2d, RDd
|
||||||
| mov CARG1, L:RB
|
| mov CARG1, L:RB
|
||||||
|
|||||||
@@ -2902,7 +2902,7 @@ static void build_subroutines(BuildCtx *ctx)
|
|||||||
| mov r13, TMPa
|
| mov r13, TMPa
|
||||||
| mov r12, TMPQ
|
| mov r12, TMPQ
|
||||||
|.endif
|
|.endif
|
||||||
| test RD, RD; js >9 // Check for error from exit.
|
| cmp RD, -LUA_ERRERR; jae >9 // Check for error from exit.
|
||||||
| mov L:RB, SAVE_L
|
| mov L:RB, SAVE_L
|
||||||
| mov MULTRES, RD
|
| mov MULTRES, RD
|
||||||
| mov LFUNC:KBASE, [BASE-8]
|
| mov LFUNC:KBASE, [BASE-8]
|
||||||
@@ -2917,6 +2917,8 @@ static void build_subroutines(BuildCtx *ctx)
|
|||||||
| movzx OP, RCL
|
| movzx OP, RCL
|
||||||
| add PC, 4
|
| add PC, 4
|
||||||
| shr RC, 16
|
| shr RC, 16
|
||||||
|
| cmp MULTRES, -17 // Static dispatch?
|
||||||
|
| je >5
|
||||||
| cmp OP, BC_FUNCF // Function header?
|
| cmp OP, BC_FUNCF // Function header?
|
||||||
| jb >3
|
| jb >3
|
||||||
| cmp OP, BC_FUNCC+2 // Fast function?
|
| cmp OP, BC_FUNCC+2 // Fast function?
|
||||||
@@ -2942,6 +2944,19 @@ static void build_subroutines(BuildCtx *ctx)
|
|||||||
| mov KBASE, [KBASE+PC2PROTO(k)]
|
| mov KBASE, [KBASE+PC2PROTO(k)]
|
||||||
| jmp <2
|
| jmp <2
|
||||||
|
|
|
|
||||||
|
|5: // Dispatch to static entry of original ins replaced by BC_JLOOP.
|
||||||
|
| mov RA, [DISPATCH+DISPATCH_J(trace)]
|
||||||
|
| mov TRACE:RA, [RA+RD*4]
|
||||||
|
| mov RC, TRACE:RA->startins
|
||||||
|
| movzx RA, RCH
|
||||||
|
| movzx OP, RCL
|
||||||
|
| shr RC, 16
|
||||||
|
|.if X64
|
||||||
|
| jmp aword [DISPATCH+OP*8+GG_DISP2STATIC]
|
||||||
|
|.else
|
||||||
|
| jmp aword [DISPATCH+OP*4+GG_DISP2STATIC]
|
||||||
|
|.endif
|
||||||
|
|
|
||||||
|9: // Rethrow error from the right C frame.
|
|9: // Rethrow error from the right C frame.
|
||||||
| mov FCARG2, RD
|
| mov FCARG2, RD
|
||||||
| mov FCARG1, L:RB
|
| mov FCARG1, L:RB
|
||||||
|
|||||||
Reference in New Issue
Block a user