mirror of
https://github.com/php/php-src.git
synced 2026-03-24 00:02:20 +01:00
Update IR
IR commit: 76dea0e897bff7e67f560f9768672519bd9783d4
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
** DynASM ARM encoding engine.
|
||||
** Copyright (C) 2005-2021 Mike Pall. All rights reserved.
|
||||
** Copyright (C) 2005-2023 Mike Pall. All rights reserved.
|
||||
** Released under the MIT license. See dynasm.lua for full copyright notice.
|
||||
*/
|
||||
|
||||
@@ -70,7 +70,7 @@ struct dasm_State {
|
||||
size_t lgsize;
|
||||
int *pclabels; /* PC label chains/pos ptrs. */
|
||||
size_t pcsize;
|
||||
void **globals; /* Array of globals (bias -10). */
|
||||
void **globals; /* Array of globals. */
|
||||
dasm_Section *section; /* Pointer to active section. */
|
||||
size_t codesize; /* Total size of all code sections. */
|
||||
int maxsection; /* 0 <= sectionidx < maxsection. */
|
||||
@@ -87,7 +87,6 @@ void dasm_init(Dst_DECL, int maxsection)
|
||||
{
|
||||
dasm_State *D;
|
||||
size_t psz = 0;
|
||||
int i;
|
||||
Dst_REF = NULL;
|
||||
DASM_M_GROW(Dst, struct dasm_State, Dst_REF, psz, DASM_PSZ(maxsection));
|
||||
D = Dst_REF;
|
||||
@@ -98,12 +97,7 @@ void dasm_init(Dst_DECL, int maxsection)
|
||||
D->pcsize = 0;
|
||||
D->globals = NULL;
|
||||
D->maxsection = maxsection;
|
||||
for (i = 0; i < maxsection; i++) {
|
||||
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. */
|
||||
}
|
||||
memset((void *)D->sections, 0, maxsection * sizeof(dasm_Section));
|
||||
}
|
||||
|
||||
/* Free DynASM state. */
|
||||
@@ -123,7 +117,7 @@ void dasm_free(Dst_DECL)
|
||||
void dasm_setupglobal(Dst_DECL, void **gl, unsigned int maxgl)
|
||||
{
|
||||
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));
|
||||
}
|
||||
|
||||
@@ -148,6 +142,7 @@ void dasm_setup(Dst_DECL, const void *actionlist)
|
||||
if (D->pclabels) memset((void *)D->pclabels, 0, D->pcsize);
|
||||
for (i = 0; i < D->maxsection; 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;
|
||||
}
|
||||
}
|
||||
@@ -372,7 +367,7 @@ int dasm_encode(Dst_DECL, void *buffer)
|
||||
break;
|
||||
case DASM_REL_LG:
|
||||
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;
|
||||
}
|
||||
/* fallthrough */
|
||||
@@ -396,7 +391,7 @@ int dasm_encode(Dst_DECL, void *buffer)
|
||||
}
|
||||
break;
|
||||
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;
|
||||
case DASM_LABEL_PC: break;
|
||||
case DASM_IMM:
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
------------------------------------------------------------------------------
|
||||
-- DynASM ARM module.
|
||||
--
|
||||
-- Copyright (C) 2005-2021 Mike Pall. All rights reserved.
|
||||
-- Copyright (C) 2005-2023 Mike Pall. All rights reserved.
|
||||
-- See dynasm.lua for full copyright notice.
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
** DynASM ARM64 encoding engine.
|
||||
** Copyright (C) 2005-2021 Mike Pall. All rights reserved.
|
||||
** Copyright (C) 2005-2023 Mike Pall. All rights reserved.
|
||||
** Released under the MIT license. See dynasm.lua for full copyright notice.
|
||||
*/
|
||||
|
||||
@@ -72,7 +72,7 @@ struct dasm_State {
|
||||
size_t lgsize;
|
||||
int *pclabels; /* PC label chains/pos ptrs. */
|
||||
size_t pcsize;
|
||||
void **globals; /* Array of globals (bias -10). */
|
||||
void **globals; /* Array of globals. */
|
||||
dasm_Section *section; /* Pointer to active section. */
|
||||
size_t codesize; /* Total size of all code sections. */
|
||||
int maxsection; /* 0 <= sectionidx < maxsection. */
|
||||
@@ -89,7 +89,6 @@ void dasm_init(Dst_DECL, int maxsection)
|
||||
{
|
||||
dasm_State *D;
|
||||
size_t psz = 0;
|
||||
int i;
|
||||
Dst_REF = NULL;
|
||||
DASM_M_GROW(Dst, struct dasm_State, Dst_REF, psz, DASM_PSZ(maxsection));
|
||||
D = Dst_REF;
|
||||
@@ -100,12 +99,7 @@ void dasm_init(Dst_DECL, int maxsection)
|
||||
D->pcsize = 0;
|
||||
D->globals = NULL;
|
||||
D->maxsection = maxsection;
|
||||
for (i = 0; i < maxsection; i++) {
|
||||
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. */
|
||||
}
|
||||
memset((void *)D->sections, 0, maxsection * sizeof(dasm_Section));
|
||||
}
|
||||
|
||||
/* Free DynASM state. */
|
||||
@@ -125,7 +119,7 @@ void dasm_free(Dst_DECL)
|
||||
void dasm_setupglobal(Dst_DECL, void **gl, unsigned int maxgl)
|
||||
{
|
||||
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));
|
||||
}
|
||||
|
||||
@@ -150,6 +144,7 @@ void dasm_setup(Dst_DECL, const void *actionlist)
|
||||
if (D->pclabels) memset((void *)D->pclabels, 0, D->pcsize);
|
||||
for (i = 0; i < D->maxsection; 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;
|
||||
}
|
||||
}
|
||||
@@ -158,10 +153,10 @@ void dasm_setup(Dst_DECL, const void *actionlist)
|
||||
#ifdef DASM_CHECKS
|
||||
#define CK(x, st) \
|
||||
do { if (!(x)) { \
|
||||
D->status = DASM_S_##st|(p-D->actionlist-1); return; } } while (0)
|
||||
D->status = DASM_S_##st|(int)(p-D->actionlist-1); return; } } while (0)
|
||||
#define CKPL(kind, st) \
|
||||
do { if ((size_t)((char *)pl-(char *)D->kind##labels) >= D->kind##size) { \
|
||||
D->status = DASM_S_RANGE_##st|(p-D->actionlist-1); return; } } while (0)
|
||||
D->status = DASM_S_RANGE_##st|(int)(p-D->actionlist-1); return; } } while (0)
|
||||
#else
|
||||
#define CK(x, st) ((void)0)
|
||||
#define CKPL(kind, st) ((void)0)
|
||||
@@ -190,7 +185,9 @@ static int dasm_imm13(int lo, int hi)
|
||||
unsigned long long n = (((unsigned long long)hi) << 32) | (unsigned int)lo;
|
||||
unsigned long long m = 1ULL, a, b, c;
|
||||
if (n & 1) { n = ~n; inv = 1; }
|
||||
a = n & -n; b = (n+a)&-(n+a); c = (n+a-b)&-(n+a-b);
|
||||
a = n & (unsigned long long)-(long long)n;
|
||||
b = (n+a)&(unsigned long long)-(long long)(n+a);
|
||||
c = (n+a-b)&(unsigned long long)-(long long)(n+a-b);
|
||||
xa = dasm_ffs(a); xb = dasm_ffs(b);
|
||||
if (c) {
|
||||
w = dasm_ffs(c) - xa;
|
||||
@@ -415,7 +412,7 @@ int dasm_link(Dst_DECL, size_t *szp)
|
||||
|
||||
#ifdef DASM_CHECKS
|
||||
#define CK(x, st) \
|
||||
do { if (!(x)) return DASM_S_##st|(p-D->actionlist-1); } while (0)
|
||||
do { if (!(x)) return DASM_S_##st|(int)(p-D->actionlist-1); } while (0)
|
||||
#else
|
||||
#define CK(x, st) ((void)0)
|
||||
#endif
|
||||
@@ -451,7 +448,7 @@ int dasm_encode(Dst_DECL, void *buffer)
|
||||
break;
|
||||
case DASM_REL_LG:
|
||||
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;
|
||||
CK_REL((ptrdiff_t)n == na, na);
|
||||
goto patchrel;
|
||||
@@ -494,7 +491,7 @@ int dasm_encode(Dst_DECL, void *buffer)
|
||||
goto patchrel;
|
||||
}
|
||||
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;
|
||||
case DASM_LABEL_PC: break;
|
||||
case DASM_IMM:
|
||||
@@ -563,7 +560,7 @@ int dasm_checkstep(Dst_DECL, int secmatch)
|
||||
}
|
||||
if (D->status == DASM_S_OK && secmatch >= 0 &&
|
||||
D->section != &D->sections[secmatch])
|
||||
D->status = DASM_S_MATCH_SEC|(D->section-D->sections);
|
||||
D->status = DASM_S_MATCH_SEC|(int)(D->section-D->sections);
|
||||
return D->status;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
------------------------------------------------------------------------------
|
||||
-- DynASM ARM64 module.
|
||||
--
|
||||
-- Copyright (C) 2005-2021 Mike Pall. All rights reserved.
|
||||
-- Copyright (C) 2005-2023 Mike Pall. All rights reserved.
|
||||
-- See dynasm.lua for full copyright notice.
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
@@ -549,7 +549,7 @@ end
|
||||
local function parse_load_pair(params, nparams, n, op)
|
||||
if params[n+2] then werror("too many operands") end
|
||||
local pn, p2 = params[n], params[n+1]
|
||||
local scale = shr(op, 30) == 0 and 2 or 3
|
||||
local scale = 2 + shr(op, 31 - band(shr(op, 26), 1))
|
||||
local p1, wb = match(pn, "^%[%s*(.-)%s*%](!?)$")
|
||||
if not p1 then
|
||||
if not p2 then
|
||||
@@ -806,8 +806,8 @@ map_op = {
|
||||
["ldrsw_*"] = "98000000DxB|b8800000DxL",
|
||||
-- NOTE: ldur etc. are handled by ldr et al.
|
||||
|
||||
["stp_*"] = "28000000DAwP|a8000000DAxP|2c000000DAsP|6c000000DAdP",
|
||||
["ldp_*"] = "28400000DAwP|a8400000DAxP|2c400000DAsP|6c400000DAdP",
|
||||
["stp_*"] = "28000000DAwP|a8000000DAxP|2c000000DAsP|6c000000DAdP|ac000000DAqP",
|
||||
["ldp_*"] = "28400000DAwP|a8400000DAxP|2c400000DAsP|6c400000DAdP|ac400000DAqP",
|
||||
["ldpsw_*"] = "68400000DAxP",
|
||||
|
||||
-- Branches.
|
||||
@@ -823,6 +823,13 @@ map_op = {
|
||||
tbz_3 = "36000000DTBw|36000000DTBx",
|
||||
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.
|
||||
-- TODO: hlt, hvc, smc, svc, eret, dcps[123], drps, mrs, msr
|
||||
-- TODO: sys, sysl, ic, dc, at, tlbi
|
||||
@@ -935,7 +942,7 @@ local function parse_template(params, template, nparams, pos)
|
||||
werror("bad register type")
|
||||
end
|
||||
parse_reg_type = false
|
||||
elseif p == "x" or p == "w" or p == "d" or p == "s" then
|
||||
elseif p == "x" or p == "w" or p == "d" or p == "s" or p == "q" then
|
||||
if parse_reg_type ~= p then
|
||||
werror("register size mismatch")
|
||||
end
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
** DynASM MIPS encoding engine.
|
||||
** Copyright (C) 2005-2021 Mike Pall. All rights reserved.
|
||||
** Copyright (C) 2005-2023 Mike Pall. All rights reserved.
|
||||
** Released under the MIT license. See dynasm.lua for full copyright notice.
|
||||
*/
|
||||
|
||||
@@ -69,7 +69,7 @@ struct dasm_State {
|
||||
size_t lgsize;
|
||||
int *pclabels; /* PC label chains/pos ptrs. */
|
||||
size_t pcsize;
|
||||
void **globals; /* Array of globals (bias -10). */
|
||||
void **globals; /* Array of globals. */
|
||||
dasm_Section *section; /* Pointer to active section. */
|
||||
size_t codesize; /* Total size of all code sections. */
|
||||
int maxsection; /* 0 <= sectionidx < maxsection. */
|
||||
@@ -86,7 +86,6 @@ void dasm_init(Dst_DECL, int maxsection)
|
||||
{
|
||||
dasm_State *D;
|
||||
size_t psz = 0;
|
||||
int i;
|
||||
Dst_REF = NULL;
|
||||
DASM_M_GROW(Dst, struct dasm_State, Dst_REF, psz, DASM_PSZ(maxsection));
|
||||
D = Dst_REF;
|
||||
@@ -97,12 +96,7 @@ void dasm_init(Dst_DECL, int maxsection)
|
||||
D->pcsize = 0;
|
||||
D->globals = NULL;
|
||||
D->maxsection = maxsection;
|
||||
for (i = 0; i < maxsection; i++) {
|
||||
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. */
|
||||
}
|
||||
memset((void *)D->sections, 0, maxsection * sizeof(dasm_Section));
|
||||
}
|
||||
|
||||
/* Free DynASM state. */
|
||||
@@ -122,7 +116,7 @@ void dasm_free(Dst_DECL)
|
||||
void dasm_setupglobal(Dst_DECL, void **gl, unsigned int maxgl)
|
||||
{
|
||||
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));
|
||||
}
|
||||
|
||||
@@ -147,6 +141,7 @@ void dasm_setup(Dst_DECL, const void *actionlist)
|
||||
if (D->pclabels) memset((void *)D->pclabels, 0, D->pcsize);
|
||||
for (i = 0; i < D->maxsection; 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;
|
||||
}
|
||||
}
|
||||
@@ -155,10 +150,10 @@ void dasm_setup(Dst_DECL, const void *actionlist)
|
||||
#ifdef DASM_CHECKS
|
||||
#define CK(x, st) \
|
||||
do { if (!(x)) { \
|
||||
D->status = DASM_S_##st|(p-D->actionlist-1); return; } } while (0)
|
||||
D->status = DASM_S_##st|(int)(p-D->actionlist-1); return; } } while (0)
|
||||
#define CKPL(kind, st) \
|
||||
do { if ((size_t)((char *)pl-(char *)D->kind##labels) >= D->kind##size) { \
|
||||
D->status = DASM_S_RANGE_##st|(p-D->actionlist-1); return; } } while (0)
|
||||
D->status = DASM_S_RANGE_##st|(int)(p-D->actionlist-1); return; } } while (0)
|
||||
#else
|
||||
#define CK(x, st) ((void)0)
|
||||
#define CKPL(kind, st) ((void)0)
|
||||
@@ -314,7 +309,7 @@ int dasm_link(Dst_DECL, size_t *szp)
|
||||
|
||||
#ifdef DASM_CHECKS
|
||||
#define CK(x, st) \
|
||||
do { if (!(x)) return DASM_S_##st|(p-D->actionlist-1); } while (0)
|
||||
do { if (!(x)) return DASM_S_##st|(int)(p-D->actionlist-1); } while (0)
|
||||
#else
|
||||
#define CK(x, st) ((void)0)
|
||||
#endif
|
||||
@@ -350,7 +345,7 @@ int dasm_encode(Dst_DECL, void *buffer)
|
||||
break;
|
||||
case DASM_REL_LG:
|
||||
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;
|
||||
}
|
||||
/* fallthrough */
|
||||
@@ -369,7 +364,7 @@ int dasm_encode(Dst_DECL, void *buffer)
|
||||
}
|
||||
break;
|
||||
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;
|
||||
case DASM_LABEL_PC: break;
|
||||
case DASM_IMMS:
|
||||
@@ -417,7 +412,7 @@ int dasm_checkstep(Dst_DECL, int secmatch)
|
||||
}
|
||||
if (D->status == DASM_S_OK && secmatch >= 0 &&
|
||||
D->section != &D->sections[secmatch])
|
||||
D->status = DASM_S_MATCH_SEC|(D->section-D->sections);
|
||||
D->status = DASM_S_MATCH_SEC|(int)(D->section-D->sections);
|
||||
return D->status;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
------------------------------------------------------------------------------
|
||||
-- DynASM MIPS32/MIPS64 module.
|
||||
--
|
||||
-- Copyright (C) 2005-2021 Mike Pall. All rights reserved.
|
||||
-- Copyright (C) 2005-2023 Mike Pall. All rights reserved.
|
||||
-- See dynasm.lua for full copyright notice.
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
------------------------------------------------------------------------------
|
||||
-- DynASM MIPS64 module.
|
||||
--
|
||||
-- Copyright (C) 2005-2021 Mike Pall. All rights reserved.
|
||||
-- Copyright (C) 2005-2023 Mike Pall. All rights reserved.
|
||||
-- See dynasm.lua for full copyright notice.
|
||||
------------------------------------------------------------------------------
|
||||
-- This module just sets 64 bit mode for the combined MIPS/MIPS64 module.
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
** DynASM PPC/PPC64 encoding engine.
|
||||
** Copyright (C) 2005-2021 Mike Pall. All rights reserved.
|
||||
** Copyright (C) 2005-2023 Mike Pall. All rights reserved.
|
||||
** Released under the MIT license. See dynasm.lua for full copyright notice.
|
||||
*/
|
||||
|
||||
@@ -69,7 +69,7 @@ struct dasm_State {
|
||||
size_t lgsize;
|
||||
int *pclabels; /* PC label chains/pos ptrs. */
|
||||
size_t pcsize;
|
||||
void **globals; /* Array of globals (bias -10). */
|
||||
void **globals; /* Array of globals. */
|
||||
dasm_Section *section; /* Pointer to active section. */
|
||||
size_t codesize; /* Total size of all code sections. */
|
||||
int maxsection; /* 0 <= sectionidx < maxsection. */
|
||||
@@ -86,7 +86,6 @@ void dasm_init(Dst_DECL, int maxsection)
|
||||
{
|
||||
dasm_State *D;
|
||||
size_t psz = 0;
|
||||
int i;
|
||||
Dst_REF = NULL;
|
||||
DASM_M_GROW(Dst, struct dasm_State, Dst_REF, psz, DASM_PSZ(maxsection));
|
||||
D = Dst_REF;
|
||||
@@ -97,12 +96,7 @@ void dasm_init(Dst_DECL, int maxsection)
|
||||
D->pcsize = 0;
|
||||
D->globals = NULL;
|
||||
D->maxsection = maxsection;
|
||||
for (i = 0; i < maxsection; i++) {
|
||||
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. */
|
||||
}
|
||||
memset((void *)D->sections, 0, maxsection * sizeof(dasm_Section));
|
||||
}
|
||||
|
||||
/* Free DynASM state. */
|
||||
@@ -122,7 +116,7 @@ void dasm_free(Dst_DECL)
|
||||
void dasm_setupglobal(Dst_DECL, void **gl, unsigned int maxgl)
|
||||
{
|
||||
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));
|
||||
}
|
||||
|
||||
@@ -147,6 +141,7 @@ void dasm_setup(Dst_DECL, const void *actionlist)
|
||||
if (D->pclabels) memset((void *)D->pclabels, 0, D->pcsize);
|
||||
for (i = 0; i < D->maxsection; 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;
|
||||
}
|
||||
}
|
||||
@@ -354,7 +349,7 @@ int dasm_encode(Dst_DECL, void *buffer)
|
||||
break;
|
||||
case DASM_REL_LG:
|
||||
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;
|
||||
}
|
||||
/* fallthrough */
|
||||
@@ -368,7 +363,7 @@ int dasm_encode(Dst_DECL, void *buffer)
|
||||
cp[-1] |= ((n+4) & ((ins & 2048) ? 0x0000fffc: 0x03fffffc));
|
||||
break;
|
||||
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;
|
||||
case DASM_LABEL_PC: break;
|
||||
case DASM_IMM:
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
------------------------------------------------------------------------------
|
||||
-- DynASM PPC/PPC64 module.
|
||||
--
|
||||
-- Copyright (C) 2005-2021 Mike Pall. All rights reserved.
|
||||
-- Copyright (C) 2005-2023 Mike Pall. All rights reserved.
|
||||
-- See dynasm.lua for full copyright notice.
|
||||
--
|
||||
-- Support for various extensions contributed by Caio Souza Oliveira.
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
** DynASM encoding engine prototypes.
|
||||
** Copyright (C) 2005-2021 Mike Pall. All rights reserved.
|
||||
** Copyright (C) 2005-2023 Mike Pall. All rights reserved.
|
||||
** Released under the MIT license. See dynasm.lua for full copyright notice.
|
||||
*/
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
------------------------------------------------------------------------------
|
||||
-- DynASM x64 module.
|
||||
--
|
||||
-- Copyright (C) 2005-2021 Mike Pall. All rights reserved.
|
||||
-- Copyright (C) 2005-2023 Mike Pall. All rights reserved.
|
||||
-- See dynasm.lua for full copyright notice.
|
||||
------------------------------------------------------------------------------
|
||||
-- This module just sets 64 bit mode for the combined x86/x64 module.
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
** DynASM x86 encoding engine.
|
||||
** Copyright (C) 2005-2021 Mike Pall. All rights reserved.
|
||||
** Copyright (C) 2005-2023 Mike Pall. All rights reserved.
|
||||
** Released under the MIT license. See dynasm.lua for full copyright notice.
|
||||
*/
|
||||
|
||||
@@ -68,7 +68,7 @@ struct dasm_State {
|
||||
size_t lgsize;
|
||||
int *pclabels; /* PC label chains/pos ptrs. */
|
||||
size_t pcsize;
|
||||
void **globals; /* Array of globals (bias -10). */
|
||||
void **globals; /* Array of globals. */
|
||||
dasm_Section *section; /* Pointer to active section. */
|
||||
size_t codesize; /* Total size of all code sections. */
|
||||
int maxsection; /* 0 <= sectionidx < maxsection. */
|
||||
@@ -88,7 +88,6 @@ void dasm_init(Dst_DECL, int maxsection)
|
||||
{
|
||||
dasm_State *D;
|
||||
size_t psz = 0;
|
||||
int i;
|
||||
Dst_REF = NULL;
|
||||
DASM_M_GROW(Dst, struct dasm_State, Dst_REF, psz, DASM_PSZ(maxsection));
|
||||
D = Dst_REF;
|
||||
@@ -99,12 +98,7 @@ void dasm_init(Dst_DECL, int maxsection)
|
||||
D->pcsize = 0;
|
||||
D->globals = NULL;
|
||||
D->maxsection = maxsection;
|
||||
for (i = 0; i < maxsection; i++) {
|
||||
D->sections[i].buf = NULL; /* Need this for pass3. */
|
||||
D->sections[i].rbuf = DASM_PTR_SUB(D->sections[i].buf, DASM_SEC2POS(i));
|
||||
D->sections[i].bsize = 0;
|
||||
D->sections[i].epos = 0; /* Wrong, but is recalculated after resize. */
|
||||
}
|
||||
memset((void *)D->sections, 0, maxsection * sizeof(dasm_Section));
|
||||
}
|
||||
|
||||
/* Free DynASM state. */
|
||||
@@ -124,7 +118,7 @@ void dasm_free(Dst_DECL)
|
||||
void dasm_setupglobal(Dst_DECL, void **gl, unsigned int maxgl)
|
||||
{
|
||||
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));
|
||||
}
|
||||
|
||||
@@ -149,6 +143,7 @@ void dasm_setup(Dst_DECL, const void *actionlist)
|
||||
if (D->pclabels) memset((void *)D->pclabels, 0, D->pcsize);
|
||||
for (i = 0; i < D->maxsection; i++) {
|
||||
D->sections[i].pos = DASM_SEC2POS(i);
|
||||
D->sections[i].rbuf = DASM_PTR_SUB(D->sections[i].buf, D->sections[i].pos);
|
||||
D->sections[i].ofs = 0;
|
||||
}
|
||||
}
|
||||
@@ -203,9 +198,9 @@ void dasm_put(Dst_DECL, int start, ...)
|
||||
case DASM_IMM_DB: if ((((unsigned)n+128)&-256) == 0) goto ob; /* fallthrough */
|
||||
case DASM_REL_A: /* Assumes ptrdiff_t is int. !x64 */
|
||||
case DASM_IMM_D: ofs += 4; break;
|
||||
case DASM_IMM_S: CK(((n+128)&-256) == 0, RANGE_I); goto ob;
|
||||
case DASM_IMM_S: CK((((unsigned)n+128)&-256) == 0, RANGE_I); goto ob;
|
||||
case DASM_IMM_B: CK((n&-256) == 0, RANGE_I); ob: ofs++; break;
|
||||
case DASM_IMM_WB: if (((n+128)&-256) == 0) goto ob; /* fallthrough */
|
||||
case DASM_IMM_WB: if ((((unsigned)n+128)&-256) == 0) goto ob; /* fallthrough */
|
||||
case DASM_IMM_W: CK((n&-65536) == 0, RANGE_I); ofs += 2; break;
|
||||
case DASM_SPACE: p++; ofs += n; break;
|
||||
case DASM_SETLABEL: b[pos-2] = -0x40000000; break; /* Neg. label ofs. */
|
||||
@@ -346,6 +341,7 @@ int dasm_link(Dst_DECL, size_t *szp)
|
||||
}
|
||||
/* fallthrough */
|
||||
case DASM_SPACE: case DASM_IMM_LG: case DASM_VREG: p++;
|
||||
/* fallthrough */
|
||||
case DASM_DISP: case DASM_IMM_S: case DASM_IMM_B: case DASM_IMM_W:
|
||||
case DASM_IMM_D: case DASM_IMM_WB: case DASM_IMM_DB:
|
||||
case DASM_SETLABEL: case DASM_REL_A: case DASM_IMM_PC: pos++; break;
|
||||
@@ -473,7 +469,7 @@ int dasm_encode(Dst_DECL, void *buffer)
|
||||
break;
|
||||
}
|
||||
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 */
|
||||
case DASM_REL_A: rel_a:
|
||||
n -= (unsigned int)(ptrdiff_t)(cp+4); goto wd; /* !x64 */
|
||||
@@ -487,7 +483,7 @@ int dasm_encode(Dst_DECL, void *buffer)
|
||||
}
|
||||
case DASM_IMM_LG:
|
||||
p++;
|
||||
if (n < 0) { dasma((ptrdiff_t)D->globals[-n]); break; }
|
||||
if (n < 0) { dasma((ptrdiff_t)D->globals[-n-10]); break; }
|
||||
/* fallthrough */
|
||||
case DASM_IMM_PC: {
|
||||
int *pb = DASM_POS2PTR(D, n);
|
||||
@@ -497,7 +493,7 @@ int dasm_encode(Dst_DECL, void *buffer)
|
||||
case DASM_LABEL_LG: {
|
||||
int idx = *p++;
|
||||
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;
|
||||
}
|
||||
case DASM_LABEL_PC: case DASM_SETLABEL: break;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
------------------------------------------------------------------------------
|
||||
-- DynASM x86/x64 module.
|
||||
--
|
||||
-- Copyright (C) 2005-2021 Mike Pall. All rights reserved.
|
||||
-- Copyright (C) 2005-2023 Mike Pall. All rights reserved.
|
||||
-- See dynasm.lua for full copyright notice.
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
@@ -627,7 +627,11 @@ local function wputmrmsib(t, imark, s, vsreg, psz, sk)
|
||||
werror("NYI: rip-relative displacement followed by immediate")
|
||||
end
|
||||
-- The previous byte in the action buffer cannot be 0xe9 or 0x80-0x8f.
|
||||
wputlabel("REL_", disp[1], 2)
|
||||
if disp[2] == "iPJ" then
|
||||
waction("REL_A", disp[1])
|
||||
else
|
||||
wputlabel("REL_", disp[1], 2)
|
||||
end
|
||||
else
|
||||
wputdarg(disp)
|
||||
end
|
||||
@@ -744,9 +748,9 @@ local function dispexpr(expr)
|
||||
return imm*map_opsizenum[ops]
|
||||
end
|
||||
local mode, iexpr = immexpr(dispt)
|
||||
if mode == "iJ" then
|
||||
if mode == "iJ" or mode == "iPJ" then
|
||||
if c == "-" then werror("cannot invert label reference") end
|
||||
return { iexpr }
|
||||
return { iexpr, mode }
|
||||
end
|
||||
return expr -- Need to return original signed expression.
|
||||
end
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
-- DynASM. A dynamic assembler for code generation engines.
|
||||
-- Originally designed and implemented for LuaJIT.
|
||||
--
|
||||
-- Copyright (C) 2005-2021 Mike Pall. All rights reserved.
|
||||
-- Copyright (C) 2005-2023 Mike Pall. All rights reserved.
|
||||
-- See below for full copyright notice.
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
@@ -17,7 +17,7 @@ local _info = {
|
||||
url = "https://luajit.org/dynasm.html",
|
||||
license = "MIT",
|
||||
copyright = [[
|
||||
Copyright (C) 2005-2021 Mike Pall. All rights reserved.
|
||||
Copyright (C) 2005-2023 Mike Pall. All rights reserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
|
||||
@@ -1134,7 +1134,7 @@ if(!cl->isC){
|
||||
CallInfo*ci;
|
||||
StkId st,base;
|
||||
Proto*p=cl->p;
|
||||
luaD_checkstack(L,p->maxstacksize);
|
||||
luaD_checkstack(L,p->maxstacksize+p->numparams);
|
||||
func=restorestack(L,funcr);
|
||||
if(!p->is_vararg){
|
||||
base=func+1;
|
||||
@@ -1639,6 +1639,7 @@ lua_number2int(k,n);
|
||||
if(luai_numeq(cast_num(k),nvalue(key)))
|
||||
return luaH_getnum(t,k);
|
||||
}
|
||||
/*fallthrough*/
|
||||
default:{
|
||||
Node*n=mainposition(t,key);
|
||||
do{
|
||||
@@ -2905,8 +2906,8 @@ if(sep>=0){
|
||||
read_long_string(ls,seminfo,sep);
|
||||
return TK_STRING;
|
||||
}
|
||||
else if(sep==-1)return'[';
|
||||
else luaX_lexerror(ls,"invalid long string delimiter",TK_STRING);
|
||||
else if (sep!=-1)luaX_lexerror(ls,"invalid long string delimiter",TK_STRING);
|
||||
return'[';
|
||||
}
|
||||
case'=':{
|
||||
next(ls);
|
||||
@@ -6985,9 +6986,14 @@ return os_pushresult(L,remove(filename)==0,filename);
|
||||
static int os_exit(lua_State*L){
|
||||
exit(luaL_optint(L,1,EXIT_SUCCESS));
|
||||
}
|
||||
static int os_clock(lua_State*L){
|
||||
lua_pushnumber(L,((lua_Number)clock())/(lua_Number)CLOCKS_PER_SEC);
|
||||
return 1;
|
||||
}
|
||||
static const luaL_Reg syslib[]={
|
||||
{"exit",os_exit},
|
||||
{"remove",os_remove},
|
||||
{"clock",os_clock},
|
||||
{NULL,NULL}
|
||||
};
|
||||
static int luaopen_os(lua_State*L){
|
||||
|
||||
@@ -368,6 +368,10 @@ void ir_free(ir_ctx *ctx)
|
||||
}
|
||||
if (ctx->regs) {
|
||||
ir_mem_free(ctx->regs);
|
||||
if (ctx->fused_regs) {
|
||||
ir_strtab_free(ctx->fused_regs);
|
||||
ir_mem_free(ctx->fused_regs);
|
||||
}
|
||||
}
|
||||
if (ctx->prev_ref) {
|
||||
ir_mem_free(ctx->prev_ref);
|
||||
|
||||
@@ -579,6 +579,7 @@ struct _ir_ctx {
|
||||
ir_arena *arena;
|
||||
ir_live_range *unused_ranges;
|
||||
ir_regs *regs;
|
||||
ir_strtab *fused_regs;
|
||||
ir_ref *prev_ref;
|
||||
union {
|
||||
void *data;
|
||||
|
||||
@@ -3234,14 +3234,18 @@ static void ir_emit_vstore(ir_ctx *ctx, ir_ref ref, ir_insn *insn)
|
||||
}
|
||||
}
|
||||
|
||||
static int32_t ir_fuse_addr(ir_ctx *ctx, ir_ref ref, ir_reg *preg1, ir_reg *preg2)
|
||||
static int32_t ir_fuse_addr(ir_ctx *ctx, ir_ref root, ir_ref ref, ir_reg *preg1, ir_reg *preg2)
|
||||
{
|
||||
ir_insn *addr_insn = &ctx->ir_base[ref];
|
||||
ir_reg reg;
|
||||
|
||||
IR_ASSERT(addr_insn->op == IR_ADD);
|
||||
IR_ASSERT(!IR_IS_CONST_REF(addr_insn->op1) && IR_IS_CONST_REF(addr_insn->op2));
|
||||
reg = ctx->regs[ref][1];
|
||||
if (UNEXPECTED(ctx->rules[ref] & IR_FUSED_REG)) {
|
||||
reg = ir_get_fused_reg(ctx, root, ref, 1);
|
||||
} else {
|
||||
reg = ctx->regs[ref][1];
|
||||
}
|
||||
if (IR_REG_SPILLED(reg)) {
|
||||
reg = IR_REG_NUM(reg);
|
||||
ir_emit_load(ctx, IR_ADDR, reg, addr_insn->op1);
|
||||
@@ -3266,7 +3270,7 @@ static void ir_emit_load_int(ir_ctx *ctx, ir_ref def, ir_insn *insn)
|
||||
IR_ASSERT(def_reg != IR_REG_NONE);
|
||||
if (!IR_IS_CONST_REF(insn->op2) && (ir_rule(ctx, insn->op2) & IR_FUSED)) {
|
||||
ir_reg op1_reg;
|
||||
int32_t offset = ir_fuse_addr(ctx, insn->op2, &op1_reg, &op2_reg);
|
||||
int32_t offset = ir_fuse_addr(ctx, def, insn->op2, &op1_reg, &op2_reg);
|
||||
|
||||
if (op2_reg == IR_REG_NONE) {
|
||||
if (IR_REG_SPILLED(ctx->regs[def][0]) && ir_is_same_spill_slot(ctx, def, op1_reg, offset)) {
|
||||
@@ -3334,7 +3338,7 @@ static void ir_emit_load_fp(ir_ctx *ctx, ir_ref def, ir_insn *insn)
|
||||
IR_ASSERT(def_reg != IR_REG_NONE);
|
||||
if (!IR_IS_CONST_REF(insn->op2) && (ir_rule(ctx, insn->op2) & IR_FUSED)) {
|
||||
ir_reg op1_reg;
|
||||
int32_t offset = ir_fuse_addr(ctx, insn->op2, &op1_reg, &op2_reg);
|
||||
int32_t offset = ir_fuse_addr(ctx, def, insn->op2, &op1_reg, &op2_reg);
|
||||
|
||||
if (op2_reg == IR_REG_NONE) {
|
||||
if (IR_REG_SPILLED(ctx->regs[def][0]) && ir_is_same_spill_slot(ctx, def, op1_reg, offset)) {
|
||||
@@ -3381,7 +3385,7 @@ static void ir_emit_store_int(ir_ctx *ctx, ir_ref ref, ir_insn *insn)
|
||||
|
||||
if (!IR_IS_CONST_REF(insn->op2) && (ir_rule(ctx, insn->op2) & IR_FUSED)) {
|
||||
ir_reg op1_reg;
|
||||
int32_t offset = ir_fuse_addr(ctx, insn->op2, &op1_reg, &op2_reg);
|
||||
int32_t offset = ir_fuse_addr(ctx, ref, insn->op2, &op1_reg, &op2_reg);
|
||||
|
||||
if (op2_reg == IR_REG_NONE) {
|
||||
if (!IR_IS_CONST_REF(insn->op3) && IR_REG_SPILLED(op3_reg) && ir_is_same_spill_slot(ctx, insn->op3, op1_reg, offset)) {
|
||||
@@ -3454,7 +3458,7 @@ static void ir_emit_store_fp(ir_ctx *ctx, ir_ref ref, ir_insn *insn)
|
||||
IR_ASSERT(op3_reg != IR_REG_NONE);
|
||||
if (!IR_IS_CONST_REF(insn->op2) && (ir_rule(ctx, insn->op2) & IR_FUSED)) {
|
||||
ir_reg op1_reg;
|
||||
int32_t offset = ir_fuse_addr(ctx, insn->op2, &op1_reg, &op2_reg);
|
||||
int32_t offset = ir_fuse_addr(ctx, ref, insn->op2, &op1_reg, &op2_reg);
|
||||
|
||||
if (op2_reg == IR_REG_NONE) {
|
||||
if (!IR_IS_CONST_REF(insn->op3) && IR_REG_SPILLED(op3_reg) && ir_is_same_spill_slot(ctx, insn->op3, op1_reg, offset)) {
|
||||
|
||||
@@ -595,7 +595,7 @@ void ir_dump_codegen(const ir_ctx *ctx, FILE *f)
|
||||
}
|
||||
if (ctx->rules) {
|
||||
uint32_t rule = ctx->rules[i];
|
||||
uint32_t id = rule & ~(IR_FUSED|IR_SKIPPED|IR_SIMPLE);
|
||||
uint32_t id = rule & ~(IR_FUSED_REG|IR_FUSED|IR_SKIPPED|IR_SIMPLE);
|
||||
|
||||
if (id < IR_LAST_OP) {
|
||||
fprintf(f, " # RULE(%s", ir_op_name[id]);
|
||||
|
||||
@@ -351,6 +351,24 @@ static void *ir_jmp_addr(ir_ctx *ctx, ir_insn *insn, ir_insn *addr_insn)
|
||||
return addr;
|
||||
}
|
||||
|
||||
static int8_t ir_get_fused_reg(ir_ctx *ctx, ir_ref root, ir_ref ref, uint8_t op_num)
|
||||
{
|
||||
if (ctx->fused_regs) {
|
||||
char key[10];
|
||||
ir_ref val;
|
||||
|
||||
memcpy(key, &root, sizeof(ir_ref));
|
||||
memcpy(key + 4, &ref, sizeof(ir_ref));
|
||||
memcpy(key + 8, &op_num, sizeof(uint8_t));
|
||||
|
||||
val = ir_strtab_find(ctx->fused_regs, key, 9);
|
||||
if (val) {
|
||||
return val;
|
||||
}
|
||||
}
|
||||
return ctx->regs[ref][op_num];
|
||||
}
|
||||
|
||||
#if defined(__GNUC__)
|
||||
# pragma GCC diagnostic push
|
||||
# pragma GCC diagnostic ignored "-Warray-bounds"
|
||||
|
||||
@@ -1210,6 +1210,7 @@ IR_ALWAYS_INLINE int8_t ir_get_alocated_reg(const ir_ctx *ctx, ir_ref ref, int o
|
||||
#define IR_FUSED (1U<<31) /* Insn is fused into others (code is generated as part of the fusion root) */
|
||||
#define IR_SKIPPED (1U<<30) /* Insn is skipped (code is not generated) */
|
||||
#define IR_SIMPLE (1U<<29) /* Insn doesn't have any target constraints */
|
||||
#define IR_FUSED_REG (1U<<28) /* Register assignemnt may be stored in ctx->fused_regs instead of ctx->regs */
|
||||
|
||||
#define IR_RULE_MASK 0xff
|
||||
|
||||
|
||||
@@ -1615,7 +1615,7 @@ static bool ir_try_coalesce(ir_ctx *ctx, ir_ref from, ir_ref to)
|
||||
} else if (from < to) {
|
||||
ir_vregs_join(ctx, v1, v2);
|
||||
if (f2 & IR_LIVE_INTERVAL_COALESCED) {
|
||||
for (i = 0; i < ctx->insns_count; i++) {
|
||||
for (i = 1; i < ctx->insns_count; i++) {
|
||||
if (ctx->vregs[i] == v2) {
|
||||
ctx->vregs[i] = v1;
|
||||
}
|
||||
@@ -1626,7 +1626,7 @@ static bool ir_try_coalesce(ir_ctx *ctx, ir_ref from, ir_ref to)
|
||||
} else {
|
||||
ir_vregs_join(ctx, v2, v1);
|
||||
if (f1 & IR_LIVE_INTERVAL_COALESCED) {
|
||||
for (i = 0; i < ctx->insns_count; i++) {
|
||||
for (i = 1; i < ctx->insns_count; i++) {
|
||||
if (ctx->vregs[i] == v1) {
|
||||
ctx->vregs[i] = v2;
|
||||
}
|
||||
@@ -3669,6 +3669,21 @@ static bool needs_spill_load(ir_ctx *ctx, ir_live_interval *ival, ir_use_pos *us
|
||||
return use_pos->next && use_pos->next->op_num != 0;
|
||||
}
|
||||
|
||||
static void ir_set_fused_reg(ir_ctx *ctx, ir_ref root, ir_ref ref, uint8_t op_num, int8_t reg)
|
||||
{
|
||||
char key[10];
|
||||
|
||||
IR_ASSERT(reg != IR_REG_NONE);
|
||||
if (!ctx->fused_regs) {
|
||||
ctx->fused_regs = ir_mem_malloc(sizeof(ir_strtab));
|
||||
ir_strtab_init(ctx->fused_regs, 8, 128);
|
||||
}
|
||||
memcpy(key, &root, sizeof(ir_ref));
|
||||
memcpy(key + 4, &ref, sizeof(ir_ref));
|
||||
memcpy(key + 8, &op_num, sizeof(uint8_t));
|
||||
ir_strtab_lookup(ctx->fused_regs, key, 9, 0x10000000 | reg);
|
||||
}
|
||||
|
||||
static void assign_regs(ir_ctx *ctx)
|
||||
{
|
||||
ir_ref i;
|
||||
@@ -3739,9 +3754,11 @@ static void assign_regs(ir_ctx *ctx)
|
||||
ref = IR_LIVE_POS_TO_REF(use_pos->pos);
|
||||
// TODO: Insert spill loads and stores in optimal positions (resolution)
|
||||
if (use_pos->op_num == 0) {
|
||||
ir_bitset_clear(available, ir_bitset_len(ctx->cfg_blocks_count + 1));
|
||||
if (ctx->ir_base[ref].op == IR_PHI) {
|
||||
/* Spilled PHI var is passed through memory */
|
||||
reg = IR_REG_NONE;
|
||||
prev_use_ref = IR_UNUSED;
|
||||
} else if (ctx->ir_base[ref].op == IR_PARAM
|
||||
&& (ival->flags & IR_LIVE_INTERVAL_MEM_PARAM)) {
|
||||
/* Stack PARAM var is passed through memory */
|
||||
@@ -3795,6 +3812,22 @@ static void assign_regs(ir_ctx *ctx)
|
||||
prev_use_ref = ref;
|
||||
}
|
||||
}
|
||||
if (use_pos->hint_ref < 0
|
||||
&& ctx->use_lists[-use_pos->hint_ref].count > 1
|
||||
&& (old_reg = ir_get_alocated_reg(ctx, -use_pos->hint_ref, use_pos->op_num)) != IR_REG_NONE) {
|
||||
if (top_ival->flags & IR_LIVE_INTERVAL_SPILL_SPECIAL) {
|
||||
reg |= IR_REG_SPILL_SPECIAL;
|
||||
} else {
|
||||
reg |= IR_REG_SPILL_LOAD;
|
||||
}
|
||||
if (reg != old_reg) {
|
||||
IR_ASSERT(ctx->rules[-use_pos->hint_ref] & IR_FUSED);
|
||||
ctx->rules[-use_pos->hint_ref] |= IR_FUSED_REG;
|
||||
ir_set_fused_reg(ctx, ref, -use_pos->hint_ref, use_pos->op_num, reg);
|
||||
use_pos = use_pos->next;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
} else if (use_pos->flags & IR_PHI_USE) {
|
||||
IR_ASSERT(use_pos->hint_ref < 0);
|
||||
IR_ASSERT(ctx->vregs[-use_pos->hint_ref]);
|
||||
@@ -3805,16 +3838,14 @@ static void assign_regs(ir_ctx *ctx)
|
||||
}
|
||||
} else if (use_pos->hint_ref < 0
|
||||
&& ctx->use_lists[-use_pos->hint_ref].count > 1
|
||||
&& (old_reg = ir_get_alocated_reg(ctx, -use_pos->hint_ref, use_pos->op_num)) != IR_REG_NONE
|
||||
&& (old_reg & (IR_REG_SPILL_SPECIAL|IR_REG_SPILL_LOAD))) {
|
||||
/* Force spill load */
|
||||
// TODO: Find a better solution ???
|
||||
if (top_ival->flags & IR_LIVE_INTERVAL_SPILL_SPECIAL) {
|
||||
reg |= IR_REG_SPILL_SPECIAL;
|
||||
} else {
|
||||
reg |= IR_REG_SPILL_LOAD;
|
||||
&& (old_reg = ir_get_alocated_reg(ctx, -use_pos->hint_ref, use_pos->op_num)) != IR_REG_NONE) {
|
||||
if (reg != old_reg) {
|
||||
IR_ASSERT(ctx->rules[-use_pos->hint_ref] & IR_FUSED);
|
||||
ctx->rules[-use_pos->hint_ref] |= IR_FUSED_REG;
|
||||
ir_set_fused_reg(ctx, ref, -use_pos->hint_ref, use_pos->op_num, reg);
|
||||
use_pos = use_pos->next;
|
||||
continue;
|
||||
}
|
||||
IR_ASSERT(reg == old_reg);
|
||||
} else {
|
||||
/* reuse register without spill load */
|
||||
}
|
||||
|
||||
@@ -741,7 +741,11 @@ int ir_sccp(ir_ctx *ctx)
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (!IR_IS_BOTTOM(insn->op2)) {
|
||||
if (!IR_IS_BOTTOM(insn->op2)
|
||||
#if IR_COMBO_COPY_PROPAGATION
|
||||
&& (IR_IS_CONST_REF(insn->op2) || _values[insn->op2].op != IR_COPY)
|
||||
#endif
|
||||
) {
|
||||
ir_ref use_case = IR_UNUSED;
|
||||
|
||||
use_list = &ctx->use_lists[i];
|
||||
|
||||
@@ -2330,14 +2330,18 @@ static void ir_emit_fp_mov(ir_ctx *ctx, ir_type type, ir_reg dst, ir_reg src)
|
||||
| ASM_FP_REG_REG_OP movaps, movapd, vmovaps, vmovapd, type, dst, src
|
||||
}
|
||||
|
||||
static int32_t ir_fuse_addr(ir_ctx *ctx, ir_ref ref, ir_reg *preg)
|
||||
static int32_t ir_fuse_addr(ir_ctx *ctx, ir_ref root, ir_ref ref, ir_reg *preg)
|
||||
{
|
||||
ir_insn *addr_insn = &ctx->ir_base[ref];
|
||||
ir_reg reg;
|
||||
|
||||
IR_ASSERT(addr_insn->op == IR_ADD);
|
||||
IR_ASSERT(!IR_IS_CONST_REF(addr_insn->op1) && IR_IS_CONST_REF(addr_insn->op2));
|
||||
reg = ctx->regs[ref][1];
|
||||
if (UNEXPECTED(ctx->rules[ref] & IR_FUSED_REG)) {
|
||||
reg = ir_get_fused_reg(ctx, root, ref, 1);
|
||||
} else {
|
||||
reg = ctx->regs[ref][1];
|
||||
}
|
||||
if (IR_REG_SPILLED(reg)) {
|
||||
reg = IR_REG_NUM(reg);
|
||||
ir_emit_load(ctx, IR_ADDR, reg, addr_insn->op1);
|
||||
@@ -2346,11 +2350,16 @@ static int32_t ir_fuse_addr(ir_ctx *ctx, ir_ref ref, ir_reg *preg)
|
||||
return ctx->ir_base[addr_insn->op2].val.i32;
|
||||
}
|
||||
|
||||
static int32_t ir_fuse_load(ir_ctx *ctx, ir_ref ref, ir_reg *preg)
|
||||
static int32_t ir_fuse_load(ir_ctx *ctx, ir_ref root, ir_ref ref, ir_reg *preg)
|
||||
{
|
||||
ir_insn *load_insn = &ctx->ir_base[ref];
|
||||
ir_reg reg = ctx->regs[ref][2];
|
||||
ir_reg reg;
|
||||
|
||||
if (UNEXPECTED(ctx->rules[ref] & IR_FUSED_REG)) {
|
||||
reg = ir_get_fused_reg(ctx, root, ref, 2);
|
||||
} else {
|
||||
reg = ctx->regs[ref][2];
|
||||
}
|
||||
IR_ASSERT(load_insn->op == IR_LOAD);
|
||||
if (IR_IS_CONST_REF(load_insn->op2)) {
|
||||
*preg = reg;
|
||||
@@ -2365,7 +2374,7 @@ static int32_t ir_fuse_load(ir_ctx *ctx, ir_ref ref, ir_reg *preg)
|
||||
return 0;
|
||||
}
|
||||
} else if (reg == IR_REG_NONE) {
|
||||
return ir_fuse_addr(ctx, load_insn->op2, preg);
|
||||
return ir_fuse_addr(ctx, root, load_insn->op2, preg);
|
||||
} else {
|
||||
if (IR_REG_SPILLED(reg)) {
|
||||
reg = IR_REG_NUM(reg);
|
||||
@@ -2622,7 +2631,7 @@ static void ir_emit_binop_int(ir_ctx *ctx, ir_ref def, ir_insn *insn)
|
||||
int32_t offset = 0;
|
||||
|
||||
if (ir_rule(ctx, op2) & IR_FUSED) {
|
||||
offset = ir_fuse_load(ctx, op2, &op2_reg);
|
||||
offset = ir_fuse_load(ctx, def, op2, &op2_reg);
|
||||
} else {
|
||||
offset = ir_ref_spill_slot(ctx, op2, &op2_reg);
|
||||
}
|
||||
@@ -2728,7 +2737,7 @@ static void ir_emit_imul3(ir_ctx *ctx, ir_ref def, ir_insn *insn)
|
||||
int32_t offset = 0;
|
||||
|
||||
if (ir_rule(ctx, op1) & IR_FUSED) {
|
||||
offset = ir_fuse_load(ctx, op1, &op1_reg);
|
||||
offset = ir_fuse_load(ctx, def, op1, &op1_reg);
|
||||
} else {
|
||||
offset = ir_ref_spill_slot(ctx, op1, &op1_reg);
|
||||
}
|
||||
@@ -2885,7 +2894,7 @@ static void ir_emit_mem_binop_int(ir_ctx *ctx, ir_ref def, ir_insn *insn)
|
||||
ir_emit_load(ctx, IR_ADDR, reg, insn->op2);
|
||||
}
|
||||
} else if (reg == IR_REG_NONE) {
|
||||
offset = ir_fuse_addr(ctx, insn->op2, ®);
|
||||
offset = ir_fuse_addr(ctx, def, insn->op2, ®);
|
||||
} else if (IR_REG_SPILLED(reg)) {
|
||||
reg = IR_REG_NUM(reg);
|
||||
ir_emit_load(ctx, IR_ADDR, reg, insn->op2);
|
||||
@@ -3119,7 +3128,7 @@ static void ir_emit_mem_mul_div_mod_pwr2(ir_ctx *ctx, ir_ref def, ir_insn *insn)
|
||||
ir_emit_load(ctx, IR_ADDR, reg, insn->op2);
|
||||
}
|
||||
} else if (reg == IR_REG_NONE) {
|
||||
offset = ir_fuse_addr(ctx, insn->op2, ®);
|
||||
offset = ir_fuse_addr(ctx, def, insn->op2, ®);
|
||||
} else if (IR_REG_SPILLED(reg)) {
|
||||
reg = IR_REG_NUM(reg);
|
||||
ir_emit_load(ctx, IR_ADDR, reg, insn->op2);
|
||||
@@ -3223,7 +3232,7 @@ static void ir_emit_mem_shift(ir_ctx *ctx, ir_ref def, ir_insn *insn)
|
||||
ir_emit_load(ctx, IR_ADDR, reg, insn->op2);
|
||||
}
|
||||
} else if (reg == IR_REG_NONE) {
|
||||
offset = ir_fuse_addr(ctx, insn->op2, ®);
|
||||
offset = ir_fuse_addr(ctx, def, insn->op2, ®);
|
||||
} else if (IR_REG_SPILLED(reg)) {
|
||||
reg = IR_REG_NUM(reg);
|
||||
ir_emit_load(ctx, IR_ADDR, reg, insn->op2);
|
||||
@@ -3337,7 +3346,7 @@ static void ir_emit_mem_shift_const(ir_ctx *ctx, ir_ref def, ir_insn *insn)
|
||||
ir_emit_load(ctx, IR_ADDR, reg, insn->op2);
|
||||
}
|
||||
} else if (reg == IR_REG_NONE) {
|
||||
offset = ir_fuse_addr(ctx, insn->op2, ®);
|
||||
offset = ir_fuse_addr(ctx, def, insn->op2, ®);
|
||||
} else if (IR_REG_SPILLED(reg)) {
|
||||
reg = IR_REG_NUM(reg);
|
||||
ir_emit_load(ctx, IR_ADDR, reg, insn->op2);
|
||||
@@ -3368,7 +3377,7 @@ static void ir_emit_mem_shift_const(ir_ctx *ctx, ir_ref def, ir_insn *insn)
|
||||
}
|
||||
}
|
||||
|
||||
static void ir_emit_op_int(ir_ctx *ctx, ir_ref def, ir_insn *insn)
|
||||
static void ir_emit_op_int(ir_ctx *ctx, ir_ref def, ir_insn *insn, uint32_t rule)
|
||||
{
|
||||
ir_backend_data *data = ctx->data;
|
||||
dasm_State **Dst = &data->dasm_state;
|
||||
@@ -3390,9 +3399,9 @@ static void ir_emit_op_int(ir_ctx *ctx, ir_ref def, ir_insn *insn)
|
||||
ir_emit_load(ctx, type, def_reg, op1);
|
||||
}
|
||||
}
|
||||
if (insn->op == IR_ADD) {
|
||||
if (rule == IR_INC) {
|
||||
| ASM_REG_OP inc, insn->type, def_reg
|
||||
} else if (insn->op == IR_SUB) {
|
||||
} else if (rule == IR_DEC) {
|
||||
| ASM_REG_OP dec, insn->type, def_reg
|
||||
} else if (insn->op == IR_NOT) {
|
||||
| ASM_REG_OP not, insn->type, def_reg
|
||||
@@ -3515,7 +3524,7 @@ static void ir_emit_bit_count(ir_ctx *ctx, ir_ref def, ir_insn *insn)
|
||||
int32_t offset = 0;
|
||||
|
||||
if (ir_rule(ctx, op1) & IR_FUSED) {
|
||||
offset = ir_fuse_load(ctx, op1, &op1_reg);
|
||||
offset = ir_fuse_load(ctx, def, op1, &op1_reg);
|
||||
} else {
|
||||
offset = ir_ref_spill_slot(ctx, op1, &op1_reg);
|
||||
}
|
||||
@@ -3779,7 +3788,7 @@ static void ir_emit_ctpop(ir_ctx *ctx, ir_ref def, ir_insn *insn)
|
||||
}
|
||||
}
|
||||
|
||||
static void ir_emit_mem_op_int(ir_ctx *ctx, ir_ref def, ir_insn *insn)
|
||||
static void ir_emit_mem_op_int(ir_ctx *ctx, ir_ref def, ir_insn *insn, uint32_t rule)
|
||||
{
|
||||
ir_backend_data *data = ctx->data;
|
||||
dasm_State **Dst = &data->dasm_state;
|
||||
@@ -3797,7 +3806,7 @@ static void ir_emit_mem_op_int(ir_ctx *ctx, ir_ref def, ir_insn *insn)
|
||||
ir_emit_load(ctx, IR_ADDR, reg, insn->op2);
|
||||
}
|
||||
} else if (reg == IR_REG_NONE) {
|
||||
offset = ir_fuse_addr(ctx, insn->op2, ®);
|
||||
offset = ir_fuse_addr(ctx, def, insn->op2, ®);
|
||||
} else if (IR_REG_SPILLED(reg)) {
|
||||
reg = IR_REG_NUM(reg);
|
||||
ir_emit_load(ctx, IR_ADDR, reg, insn->op2);
|
||||
@@ -3807,9 +3816,9 @@ static void ir_emit_mem_op_int(ir_ctx *ctx, ir_ref def, ir_insn *insn)
|
||||
offset = ir_var_spill_slot(ctx, insn->op2, ®);
|
||||
}
|
||||
|
||||
if (op_insn->op == IR_ADD) {
|
||||
if (rule == IR_MEM_INC) {
|
||||
| ASM_MEM_OP inc, type, [Ra(reg)+offset]
|
||||
} else if (op_insn->op == IR_SUB) {
|
||||
} else if (rule == IR_MEM_DEC) {
|
||||
| ASM_MEM_OP dec, type, [Ra(reg)+offset]
|
||||
} else if (op_insn->op == IR_NOT) {
|
||||
| ASM_MEM_OP not, type, [Ra(reg)+offset]
|
||||
@@ -3919,7 +3928,7 @@ static void ir_emit_mul_div_mod(ir_ctx *ctx, ir_ref def, ir_insn *insn)
|
||||
| ASM_REG_OP imul, type, op2_reg
|
||||
} else {
|
||||
if (ir_rule(ctx, op2) & IR_FUSED) {
|
||||
offset = ir_fuse_load(ctx, op2, &op2_reg);
|
||||
offset = ir_fuse_load(ctx, def, op2, &op2_reg);
|
||||
} else {
|
||||
offset = ir_ref_spill_slot(ctx, op2, &op2_reg);
|
||||
}
|
||||
@@ -3934,7 +3943,7 @@ static void ir_emit_mul_div_mod(ir_ctx *ctx, ir_ref def, ir_insn *insn)
|
||||
| ASM_REG_OP mul, type, op2_reg
|
||||
} else {
|
||||
if (ir_rule(ctx, op2) & IR_FUSED) {
|
||||
offset = ir_fuse_load(ctx, op2, &op2_reg);
|
||||
offset = ir_fuse_load(ctx, def, op2, &op2_reg);
|
||||
} else {
|
||||
offset = ir_ref_spill_slot(ctx, op2, &op2_reg);
|
||||
}
|
||||
@@ -3960,7 +3969,7 @@ static void ir_emit_mul_div_mod(ir_ctx *ctx, ir_ref def, ir_insn *insn)
|
||||
| ASM_REG_OP idiv, type, op2_reg
|
||||
} else {
|
||||
if (ir_rule(ctx, op2) & IR_FUSED) {
|
||||
offset = ir_fuse_load(ctx, op2, &op2_reg);
|
||||
offset = ir_fuse_load(ctx, def, op2, &op2_reg);
|
||||
} else {
|
||||
offset = ir_ref_spill_slot(ctx, op2, &op2_reg);
|
||||
}
|
||||
@@ -3980,7 +3989,7 @@ static void ir_emit_mul_div_mod(ir_ctx *ctx, ir_ref def, ir_insn *insn)
|
||||
| ASM_REG_OP div, type, op2_reg
|
||||
} else {
|
||||
if (ir_rule(ctx, op2) & IR_FUSED) {
|
||||
offset = ir_fuse_load(ctx, op2, &op2_reg);
|
||||
offset = ir_fuse_load(ctx, def, op2, &op2_reg);
|
||||
} else {
|
||||
offset = ir_ref_spill_slot(ctx, op2, &op2_reg);
|
||||
}
|
||||
@@ -4220,7 +4229,7 @@ static void ir_emit_binop_sse2(ir_ctx *ctx, ir_ref def, ir_insn *insn)
|
||||
int32_t offset = 0;
|
||||
|
||||
if (ir_rule(ctx, op2) & IR_FUSED) {
|
||||
offset = ir_fuse_load(ctx, op2, &op2_reg);
|
||||
offset = ir_fuse_load(ctx, def, op2, &op2_reg);
|
||||
} else {
|
||||
offset = ir_ref_spill_slot(ctx, op2, &op2_reg);
|
||||
}
|
||||
@@ -4327,7 +4336,7 @@ static void ir_emit_binop_avx(ir_ctx *ctx, ir_ref def, ir_insn *insn)
|
||||
int32_t offset = 0;
|
||||
|
||||
if (ir_rule(ctx, op2) & IR_FUSED) {
|
||||
offset = ir_fuse_load(ctx, op2, &op2_reg);
|
||||
offset = ir_fuse_load(ctx, def, op2, &op2_reg);
|
||||
} else {
|
||||
offset = ir_ref_spill_slot(ctx, op2, &op2_reg);
|
||||
}
|
||||
@@ -4359,7 +4368,7 @@ static void ir_emit_binop_avx(ir_ctx *ctx, ir_ref def, ir_insn *insn)
|
||||
}
|
||||
}
|
||||
|
||||
static void ir_emit_cmp_int_common(ir_ctx *ctx, ir_type type, ir_insn *insn, ir_reg op1_reg, ir_ref op1, ir_reg op2_reg, ir_ref op2)
|
||||
static void ir_emit_cmp_int_common(ir_ctx *ctx, ir_type type, ir_ref root, ir_insn *insn, ir_reg op1_reg, ir_ref op1, ir_reg op2_reg, ir_ref op2)
|
||||
{
|
||||
ir_backend_data *data = ctx->data;
|
||||
dasm_State **Dst = &data->dasm_state;
|
||||
@@ -4379,7 +4388,7 @@ static void ir_emit_cmp_int_common(ir_ctx *ctx, ir_type type, ir_insn *insn, ir_
|
||||
int32_t offset = 0;
|
||||
|
||||
if (ir_rule(ctx, op2) & IR_FUSED) {
|
||||
offset = ir_fuse_load(ctx, op2, &op2_reg);
|
||||
offset = ir_fuse_load(ctx, root, op2, &op2_reg);
|
||||
} else {
|
||||
offset = ir_ref_spill_slot(ctx, op2, &op2_reg);
|
||||
}
|
||||
@@ -4395,7 +4404,7 @@ static void ir_emit_cmp_int_common(ir_ctx *ctx, ir_type type, ir_insn *insn, ir_
|
||||
int32_t offset = 0;
|
||||
|
||||
if (ir_rule(ctx, insn->op1) & IR_FUSED) {
|
||||
offset = ir_fuse_load(ctx, insn->op1, &op1_reg);
|
||||
offset = ir_fuse_load(ctx, root, insn->op1, &op1_reg);
|
||||
} else {
|
||||
offset = ir_ref_spill_slot(ctx, insn->op1, &op1_reg);
|
||||
}
|
||||
@@ -4504,14 +4513,14 @@ static void ir_emit_cmp_int(ir_ctx *ctx, ir_ref def, ir_insn *insn)
|
||||
op = IR_NE;
|
||||
}
|
||||
}
|
||||
ir_emit_cmp_int_common(ctx, type, insn, op1_reg, op1, op2_reg, op2);
|
||||
ir_emit_cmp_int_common(ctx, type, def, insn, op1_reg, op1, op2_reg, op2);
|
||||
_ir_emit_setcc_int(ctx, op, def_reg);
|
||||
if (IR_REG_SPILLED(ctx->regs[def][0])) {
|
||||
ir_emit_store(ctx, insn->type, def, def_reg);
|
||||
}
|
||||
}
|
||||
|
||||
static void ir_emit_test_int_common(ir_ctx *ctx, ir_ref ref, ir_op op)
|
||||
static void ir_emit_test_int_common(ir_ctx *ctx, ir_ref root, ir_ref ref, ir_op op)
|
||||
{
|
||||
ir_backend_data *data = ctx->data;
|
||||
dasm_State **Dst = &data->dasm_state;
|
||||
@@ -4568,7 +4577,7 @@ static void ir_emit_test_int_common(ir_ctx *ctx, ir_ref ref, ir_op op)
|
||||
int32_t offset = 0;
|
||||
|
||||
if (ir_rule(ctx, op2) & IR_FUSED) {
|
||||
offset = ir_fuse_load(ctx, op2, &op2_reg);
|
||||
offset = ir_fuse_load(ctx, root, op2, &op2_reg);
|
||||
} else {
|
||||
offset = ir_ref_spill_slot(ctx, op2, &op2_reg);
|
||||
}
|
||||
@@ -4580,7 +4589,7 @@ static void ir_emit_test_int_common(ir_ctx *ctx, ir_ref ref, ir_op op)
|
||||
int32_t offset = 0;
|
||||
|
||||
if (ir_rule(ctx, op1) & IR_FUSED) {
|
||||
offset = ir_fuse_load(ctx, op1, &op1_reg);
|
||||
offset = ir_fuse_load(ctx, root, op1, &op1_reg);
|
||||
} else {
|
||||
offset = ir_ref_spill_slot(ctx, op1, &op1_reg);
|
||||
}
|
||||
@@ -4615,7 +4624,7 @@ static void ir_emit_testcc_int(ir_ctx *ctx, ir_ref def, ir_insn *insn)
|
||||
ir_reg def_reg = IR_REG_NUM(ctx->regs[def][0]);
|
||||
|
||||
IR_ASSERT(def_reg != IR_REG_NONE);
|
||||
ir_emit_test_int_common(ctx, insn->op1, insn->op);
|
||||
ir_emit_test_int_common(ctx, def, insn->op1, insn->op);
|
||||
_ir_emit_setcc_int(ctx, insn->op, def_reg);
|
||||
if (IR_REG_SPILLED(ctx->regs[def][0])) {
|
||||
ir_emit_store(ctx, insn->type, def, def_reg);
|
||||
@@ -4633,7 +4642,7 @@ static void ir_emit_setcc_int(ir_ctx *ctx, ir_ref def, ir_insn *insn)
|
||||
}
|
||||
}
|
||||
|
||||
static ir_op ir_emit_cmp_fp_common(ir_ctx *ctx, ir_ref cmp_ref, ir_insn *cmp_insn)
|
||||
static ir_op ir_emit_cmp_fp_common(ir_ctx *ctx, ir_ref root, ir_ref cmp_ref, ir_insn *cmp_insn)
|
||||
{
|
||||
ir_backend_data *data = ctx->data;
|
||||
dasm_State **Dst = &data->dasm_state;
|
||||
@@ -4681,7 +4690,7 @@ static ir_op ir_emit_cmp_fp_common(ir_ctx *ctx, ir_ref cmp_ref, ir_insn *cmp_ins
|
||||
int32_t offset = 0;
|
||||
|
||||
if (ir_rule(ctx, op2) & IR_FUSED) {
|
||||
offset = ir_fuse_load(ctx, op2, &op2_reg);
|
||||
offset = ir_fuse_load(ctx, root, op2, &op2_reg);
|
||||
} else {
|
||||
offset = ir_ref_spill_slot(ctx, op2, &op2_reg);
|
||||
}
|
||||
@@ -4694,7 +4703,7 @@ static void ir_emit_cmp_fp(ir_ctx *ctx, ir_ref def, ir_insn *insn)
|
||||
{
|
||||
ir_backend_data *data = ctx->data;
|
||||
dasm_State **Dst = &data->dasm_state;
|
||||
ir_op op = ir_emit_cmp_fp_common(ctx, def, insn);
|
||||
ir_op op = ir_emit_cmp_fp_common(ctx, def, def, insn);
|
||||
ir_reg def_reg = IR_REG_NUM(ctx->regs[def][0]);
|
||||
ir_reg tmp_reg = ctx->regs[def][3];
|
||||
|
||||
@@ -4942,7 +4951,7 @@ static void ir_emit_cmp_and_branch_int(ir_ctx *ctx, uint32_t b, ir_ref def, ir_i
|
||||
}
|
||||
}
|
||||
if (!same_comparison) {
|
||||
ir_emit_cmp_int_common(ctx, type, cmp_insn, op1_reg, op1, op2_reg, op2);
|
||||
ir_emit_cmp_int_common(ctx, type, def, cmp_insn, op1_reg, op1, op2_reg, op2);
|
||||
}
|
||||
ir_emit_jcc(ctx, op, b, def, insn, 1);
|
||||
}
|
||||
@@ -4959,13 +4968,13 @@ static void ir_emit_test_and_branch_int(ir_ctx *ctx, uint32_t b, ir_ref def, ir_
|
||||
op = IR_NE;
|
||||
}
|
||||
|
||||
ir_emit_test_int_common(ctx, op2, op);
|
||||
ir_emit_test_int_common(ctx, def, op2, op);
|
||||
ir_emit_jcc(ctx, op, b, def, insn, 1);
|
||||
}
|
||||
|
||||
static void ir_emit_cmp_and_branch_fp(ir_ctx *ctx, uint32_t b, ir_ref def, ir_insn *insn)
|
||||
{
|
||||
ir_op op = ir_emit_cmp_fp_common(ctx, insn->op2, &ctx->ir_base[insn->op2]);
|
||||
ir_op op = ir_emit_cmp_fp_common(ctx, def, insn->op2, &ctx->ir_base[insn->op2]);
|
||||
ir_emit_jcc(ctx, op, b, def, insn, 0);
|
||||
}
|
||||
|
||||
@@ -5000,7 +5009,7 @@ static void ir_emit_if_int(ir_ctx *ctx, uint32_t b, ir_ref def, ir_insn *insn)
|
||||
int32_t offset = 0;
|
||||
|
||||
if (ir_rule(ctx, insn->op2) & IR_FUSED) {
|
||||
offset = ir_fuse_load(ctx, insn->op2, &op2_reg);
|
||||
offset = ir_fuse_load(ctx, def, insn->op2, &op2_reg);
|
||||
} else {
|
||||
offset = ir_ref_spill_slot(ctx, insn->op2, &op2_reg);
|
||||
}
|
||||
@@ -5087,7 +5096,7 @@ static void ir_emit_cond(ir_ctx *ctx, ir_ref def, ir_insn *insn)
|
||||
} else if (IR_IS_CONST_REF(op2) || !(ir_rule(ctx, op2) & IR_FUSED)) {
|
||||
ir_emit_load(ctx, type, def_reg, op2);
|
||||
} else {
|
||||
int32_t offset = ir_fuse_load(ctx, op2, &op2_reg);
|
||||
int32_t offset = ir_fuse_load(ctx, def, op2, &op2_reg);
|
||||
|
||||
if (IR_IS_TYPE_INT(type)) {
|
||||
ir_emit_load_mem_int(ctx, type, def_reg, op2_reg, offset);
|
||||
@@ -5108,7 +5117,7 @@ static void ir_emit_cond(ir_ctx *ctx, ir_ref def, ir_insn *insn)
|
||||
} else if (IR_IS_CONST_REF(op3) || !(ir_rule(ctx, op3) & IR_FUSED)) {
|
||||
ir_emit_load(ctx, type, def_reg, op3);
|
||||
} else {
|
||||
int32_t offset = ir_fuse_load(ctx, op3, &op3_reg);
|
||||
int32_t offset = ir_fuse_load(ctx, def, op3, &op3_reg);
|
||||
|
||||
if (IR_IS_TYPE_INT(type)) {
|
||||
ir_emit_load_mem_int(ctx, type, def_reg, op3_reg, offset);
|
||||
@@ -5257,7 +5266,7 @@ static void ir_emit_sext(ir_ctx *ctx, ir_ref def, ir_insn *insn)
|
||||
int32_t offset = 0;
|
||||
|
||||
if (ir_rule(ctx, insn->op1) & IR_FUSED) {
|
||||
offset = ir_fuse_load(ctx, insn->op1, &op1_reg);
|
||||
offset = ir_fuse_load(ctx, def, insn->op1, &op1_reg);
|
||||
} else {
|
||||
offset = ir_ref_spill_slot(ctx, insn->op1, &op1_reg);
|
||||
}
|
||||
@@ -5380,7 +5389,7 @@ static void ir_emit_zext(ir_ctx *ctx, ir_ref def, ir_insn *insn)
|
||||
int32_t offset = 0;
|
||||
|
||||
if (ir_rule(ctx, insn->op1) & IR_FUSED) {
|
||||
offset = ir_fuse_load(ctx, insn->op1, &op1_reg);
|
||||
offset = ir_fuse_load(ctx, def, insn->op1, &op1_reg);
|
||||
} else {
|
||||
offset = ir_ref_spill_slot(ctx, insn->op1, &op1_reg);
|
||||
}
|
||||
@@ -5485,7 +5494,7 @@ static void ir_emit_bitcast(ir_ctx *ctx, ir_ref def, ir_insn *insn)
|
||||
IR_ASSERT(def_reg != IR_REG_NONE);
|
||||
if (IR_IS_TYPE_INT(src_type) && IR_IS_TYPE_INT(dst_type)) {
|
||||
if (!IR_IS_CONST_REF(insn->op1) && (ir_rule(ctx, insn->op1) & IR_FUSED)) {
|
||||
offset = ir_fuse_load(ctx, insn->op1, &op1_reg);
|
||||
offset = ir_fuse_load(ctx, def, insn->op1, &op1_reg);
|
||||
ir_emit_load_mem_int(ctx, dst_type, def_reg, op1_reg, offset);
|
||||
} else if (op1_reg != IR_REG_NONE) {
|
||||
if (IR_REG_SPILLED(op1_reg)) {
|
||||
@@ -5500,7 +5509,7 @@ static void ir_emit_bitcast(ir_ctx *ctx, ir_ref def, ir_insn *insn)
|
||||
}
|
||||
} else if (IR_IS_TYPE_FP(src_type) && IR_IS_TYPE_FP(dst_type)) {
|
||||
if (!IR_IS_CONST_REF(insn->op1) && (ir_rule(ctx, insn->op1) & IR_FUSED)) {
|
||||
offset = ir_fuse_load(ctx, insn->op1, &op1_reg);
|
||||
offset = ir_fuse_load(ctx, def, insn->op1, &op1_reg);
|
||||
ir_emit_load_mem_fp(ctx, dst_type, def_reg, op1_reg, offset);
|
||||
} else if (op1_reg != IR_REG_NONE) {
|
||||
if (IR_REG_SPILLED(op1_reg)) {
|
||||
@@ -5552,7 +5561,7 @@ static void ir_emit_bitcast(ir_ctx *ctx, ir_ref def, ir_insn *insn)
|
||||
int32_t offset = 0;
|
||||
|
||||
if (ir_rule(ctx, insn->op1) & IR_FUSED) {
|
||||
offset = ir_fuse_load(ctx, insn->op1, &op1_reg);
|
||||
offset = ir_fuse_load(ctx, def, insn->op1, &op1_reg);
|
||||
} else {
|
||||
offset = ir_ref_spill_slot(ctx, insn->op1, &op1_reg);
|
||||
}
|
||||
@@ -5599,7 +5608,7 @@ static void ir_emit_bitcast(ir_ctx *ctx, ir_ref def, ir_insn *insn)
|
||||
int32_t offset = 0;
|
||||
|
||||
if (ir_rule(ctx, insn->op1) & IR_FUSED) {
|
||||
offset = ir_fuse_load(ctx, insn->op1, &op1_reg);
|
||||
offset = ir_fuse_load(ctx, def, insn->op1, &op1_reg);
|
||||
} else {
|
||||
offset = ir_ref_spill_slot(ctx, insn->op1, &op1_reg);
|
||||
}
|
||||
@@ -5718,7 +5727,7 @@ static void ir_emit_int2fp(ir_ctx *ctx, ir_ref def, ir_insn *insn)
|
||||
bool src64 = ir_type_size[src_type] == 8;
|
||||
|
||||
if (ir_rule(ctx, insn->op1) & IR_FUSED) {
|
||||
offset = ir_fuse_load(ctx, insn->op1, &op1_reg);
|
||||
offset = ir_fuse_load(ctx, def, insn->op1, &op1_reg);
|
||||
} else {
|
||||
offset = ir_ref_spill_slot(ctx, insn->op1, &op1_reg);
|
||||
}
|
||||
@@ -5868,7 +5877,7 @@ static void ir_emit_fp2int(ir_ctx *ctx, ir_ref def, ir_insn *insn)
|
||||
int32_t offset = 0;
|
||||
|
||||
if (ir_rule(ctx, insn->op1) & IR_FUSED) {
|
||||
offset = ir_fuse_load(ctx, insn->op1, &op1_reg);
|
||||
offset = ir_fuse_load(ctx, def, insn->op1, &op1_reg);
|
||||
} else {
|
||||
offset = ir_ref_spill_slot(ctx, insn->op1, &op1_reg);
|
||||
}
|
||||
@@ -5969,7 +5978,7 @@ static void ir_emit_fp2fp(ir_ctx *ctx, ir_ref def, ir_insn *insn)
|
||||
int32_t offset = 0;
|
||||
|
||||
if (ir_rule(ctx, insn->op1) & IR_FUSED) {
|
||||
offset = ir_fuse_load(ctx, insn->op1, &op1_reg);
|
||||
offset = ir_fuse_load(ctx, def, insn->op1, &op1_reg);
|
||||
} else {
|
||||
offset = ir_ref_spill_slot(ctx, insn->op1, &op1_reg);
|
||||
}
|
||||
@@ -6172,7 +6181,7 @@ static void ir_emit_load_int(ir_ctx *ctx, ir_ref def, ir_insn *insn)
|
||||
offset = ctx->ir_base[insn->op2].val.i32;
|
||||
} else {
|
||||
IR_ASSERT(ir_rule(ctx, insn->op2) & IR_FUSED);
|
||||
offset = ir_fuse_addr(ctx, insn->op2, &op2_reg);
|
||||
offset = ir_fuse_addr(ctx, def, insn->op2, &op2_reg);
|
||||
if (IR_REG_SPILLED(ctx->regs[def][0]) && ir_is_same_spill_slot(ctx, def, op2_reg, offset)) {
|
||||
if (!ir_may_avoid_spill_load(ctx, def, def)) {
|
||||
ir_emit_load_mem_int(ctx, type, def_reg, op2_reg, offset);
|
||||
@@ -6214,7 +6223,7 @@ static void ir_emit_load_fp(ir_ctx *ctx, ir_ref def, ir_insn *insn)
|
||||
offset = ctx->ir_base[insn->op2].val.i32;
|
||||
} else {
|
||||
IR_ASSERT(ir_rule(ctx, insn->op2) & IR_FUSED);
|
||||
offset = ir_fuse_addr(ctx, insn->op2, &op2_reg);
|
||||
offset = ir_fuse_addr(ctx, def, insn->op2, &op2_reg);
|
||||
if (IR_REG_SPILLED(ctx->regs[def][0]) && ir_is_same_spill_slot(ctx, def, op2_reg, offset)) {
|
||||
if (!ir_may_avoid_spill_load(ctx, def, def)) {
|
||||
ir_emit_load_mem_fp(ctx, type, def_reg, op2_reg, offset);
|
||||
@@ -6252,7 +6261,7 @@ static void ir_emit_store_int(ir_ctx *ctx, ir_ref ref, ir_insn *insn)
|
||||
offset = ctx->ir_base[insn->op2].val.i32;
|
||||
} else {
|
||||
IR_ASSERT(ir_rule(ctx, insn->op2) & IR_FUSED);
|
||||
offset = ir_fuse_addr(ctx, insn->op2, &op2_reg);
|
||||
offset = ir_fuse_addr(ctx, ref, insn->op2, &op2_reg);
|
||||
if (!IR_IS_CONST_REF(insn->op3) && IR_REG_SPILLED(op3_reg) && ir_is_same_spill_slot(ctx, insn->op3, op2_reg, offset)) {
|
||||
if (!ir_may_avoid_spill_load(ctx, insn->op3, ref)) {
|
||||
op3_reg = IR_REG_NUM(op3_reg);
|
||||
@@ -6297,7 +6306,7 @@ static void ir_emit_store_fp(ir_ctx *ctx, ir_ref ref, ir_insn *insn)
|
||||
offset = ctx->ir_base[insn->op2].val.i32;
|
||||
} else {
|
||||
IR_ASSERT(ir_rule(ctx, insn->op2) & IR_FUSED);
|
||||
offset = ir_fuse_addr(ctx, insn->op2, &op2_reg);
|
||||
offset = ir_fuse_addr(ctx, ref, insn->op2, &op2_reg);
|
||||
if (!IR_IS_CONST_REF(insn->op3) && IR_REG_SPILLED(op3_reg) && ir_is_same_spill_slot(ctx, insn->op3, op2_reg, offset)) {
|
||||
if (!ir_may_avoid_spill_load(ctx, insn->op3, ref)) {
|
||||
op3_reg = IR_REG_NUM(op3_reg);
|
||||
@@ -6365,7 +6374,7 @@ static void ir_emit_rstore(ir_ctx *ctx, ir_ref ref, ir_insn *insn)
|
||||
ir_reg dst_reg = insn->op3;
|
||||
|
||||
if (!IR_IS_CONST_REF(insn->op2) && (ir_rule(ctx, insn->op2) & IR_FUSED)) {
|
||||
int32_t offset = ir_fuse_load(ctx, insn->op2, &op2_reg);
|
||||
int32_t offset = ir_fuse_load(ctx, ref, insn->op2, &op2_reg);
|
||||
if (IR_IS_TYPE_INT(type)) {
|
||||
ir_emit_load_mem_int(ctx, type, dst_reg, op2_reg, offset);
|
||||
} else {
|
||||
@@ -7444,7 +7453,7 @@ static void ir_emit_call_ex(ir_ctx *ctx, ir_ref def, ir_insn *insn, int32_t used
|
||||
int32_t offset;
|
||||
|
||||
if (ir_rule(ctx, insn->op2) & IR_FUSED) {
|
||||
offset = ir_fuse_load(ctx, insn->op2, &op2_reg);
|
||||
offset = ir_fuse_load(ctx, def, insn->op2, &op2_reg);
|
||||
} else {
|
||||
offset = ir_ref_spill_slot(ctx, insn->op2, &op2_reg);
|
||||
}
|
||||
@@ -7588,7 +7597,7 @@ static void ir_emit_tailcall(ir_ctx *ctx, ir_ref def, ir_insn *insn)
|
||||
int32_t offset;
|
||||
|
||||
if (ir_rule(ctx, insn->op2) & IR_FUSED) {
|
||||
offset = ir_fuse_load(ctx, insn->op2, &op2_reg);
|
||||
offset = ir_fuse_load(ctx, def, insn->op2, &op2_reg);
|
||||
} else {
|
||||
offset = ir_ref_spill_slot(ctx, insn->op2, &op2_reg);
|
||||
}
|
||||
@@ -7626,7 +7635,7 @@ static void ir_emit_ijmp(ir_ctx *ctx, ir_ref def, ir_insn *insn)
|
||||
} else if (ir_rule(ctx, insn->op2) & IR_FUSED) {
|
||||
int32_t offset;
|
||||
|
||||
offset = ir_fuse_load(ctx, insn->op2, &op2_reg);
|
||||
offset = ir_fuse_load(ctx, def, insn->op2, &op2_reg);
|
||||
if (op2_reg == IR_REG_NONE) {
|
||||
| jmp aword [offset]
|
||||
} else {
|
||||
@@ -7921,7 +7930,7 @@ static bool ir_emit_guard(ir_ctx *ctx, uint32_t b, ir_ref def, ir_insn *insn)
|
||||
int32_t offset = 0;
|
||||
|
||||
if (ir_rule(ctx, insn->op2) & IR_FUSED) {
|
||||
offset = ir_fuse_load(ctx, insn->op2, &op2_reg);
|
||||
offset = ir_fuse_load(ctx, def, insn->op2, &op2_reg);
|
||||
} else {
|
||||
offset = ir_ref_spill_slot(ctx, insn->op2, &op2_reg);
|
||||
}
|
||||
@@ -8013,7 +8022,7 @@ static bool ir_emit_guard_cmp_int(ir_ctx *ctx, uint32_t b, ir_ref def, ir_insn *
|
||||
op = IR_NE;
|
||||
}
|
||||
}
|
||||
ir_emit_cmp_int_common(ctx, type, cmp_insn, op1_reg, op1, op2_reg, op2);
|
||||
ir_emit_cmp_int_common(ctx, type, def, cmp_insn, op1_reg, op1, op2_reg, op2);
|
||||
|
||||
if (insn->op == IR_GUARD) {
|
||||
op ^= 1; // reverse
|
||||
@@ -8024,7 +8033,7 @@ static bool ir_emit_guard_cmp_int(ir_ctx *ctx, uint32_t b, ir_ref def, ir_insn *
|
||||
|
||||
static bool ir_emit_guard_cmp_fp(ir_ctx *ctx, uint32_t b, ir_ref def, ir_insn *insn)
|
||||
{
|
||||
ir_op op = ir_emit_cmp_fp_common(ctx, insn->op2, &ctx->ir_base[insn->op2]);
|
||||
ir_op op = ir_emit_cmp_fp_common(ctx, def, insn->op2, &ctx->ir_base[insn->op2]);
|
||||
void *addr = ir_jmp_addr(ctx, insn, &ctx->ir_base[insn->op3]);
|
||||
|
||||
if (insn->op == IR_GUARD) {
|
||||
@@ -8038,7 +8047,7 @@ static bool ir_emit_guard_test_int(ir_ctx *ctx, uint32_t b, ir_ref def, ir_insn
|
||||
void *addr = ir_jmp_addr(ctx, insn, &ctx->ir_base[insn->op3]);
|
||||
ir_op op = (insn->op == IR_GUARD) ? IR_EQ : IR_NE;
|
||||
|
||||
ir_emit_test_int_common(ctx, insn->op2, op);
|
||||
ir_emit_test_int_common(ctx, def, insn->op2, op);
|
||||
return ir_emit_guard_jcc(ctx, b, def, op, addr, 1);
|
||||
}
|
||||
|
||||
@@ -9319,7 +9328,7 @@ void *ir_emit_code(ir_ctx *ctx, size_t *size_ptr)
|
||||
case IR_INC:
|
||||
case IR_DEC:
|
||||
case IR_OP_INT:
|
||||
ir_emit_op_int(ctx, i, insn);
|
||||
ir_emit_op_int(ctx, i, insn, *rule);
|
||||
break;
|
||||
case IR_ABS_INT:
|
||||
ir_emit_abs_int(ctx, i, insn);
|
||||
@@ -9498,7 +9507,7 @@ void *ir_emit_code(ir_ctx *ctx, size_t *size_ptr)
|
||||
case IR_MEM_OP_INT:
|
||||
case IR_MEM_INC:
|
||||
case IR_MEM_DEC:
|
||||
ir_emit_mem_op_int(ctx, i, insn);
|
||||
ir_emit_mem_op_int(ctx, i, insn, *rule);
|
||||
break;
|
||||
case IR_MEM_BINOP_INT:
|
||||
ir_emit_mem_binop_int(ctx, i, insn);
|
||||
|
||||
Reference in New Issue
Block a user