mirror of
https://github.com/LuaJIT/LuaJIT.git
synced 2025-04-22 06:43:27 +00:00
DynASM/X86_64: Better support for 64-bit .aword
This allows creation of 64-bit jump tables using regular DynASM label syntax | lea r0, aword [>1] | jmp aword [r0 + r1 * 8] | | .align aword |1: | .aword &label | .aword >2 | .aword =>label
This commit is contained in:
parent
20f556e531
commit
a59fba279a
@ -17,11 +17,11 @@
|
||||
|
||||
/* Action definitions. DASM_STOP must be 255. */
|
||||
enum {
|
||||
DASM_DISP = 233,
|
||||
DASM_DISP = 231,
|
||||
DASM_IMM_S, DASM_IMM_B, DASM_IMM_W, DASM_IMM_D, DASM_IMM_WB, DASM_IMM_DB,
|
||||
DASM_VREG, DASM_SPACE, DASM_SETLABEL, DASM_REL_A, DASM_REL_LG, DASM_REL_PC,
|
||||
DASM_IMM_LG, DASM_IMM_PC, DASM_LABEL_LG, DASM_LABEL_PC, DASM_ALIGN,
|
||||
DASM_EXTERN, DASM_ESC, DASM_MARK, DASM_SECTION, DASM_STOP
|
||||
DASM_IMM_LG, DASM_IMM_LG64, DASM_IMM_PC, DASM_IMM_PC64, DASM_LABEL_LG, DASM_LABEL_PC,
|
||||
DASM_ALIGN, DASM_EXTERN, DASM_ESC, DASM_MARK, DASM_SECTION, DASM_STOP
|
||||
};
|
||||
|
||||
/* Maximum number of section buffer positions for a single dasm_put() call. */
|
||||
@ -218,6 +218,7 @@ void dasm_put(Dst_DECL, int start, ...)
|
||||
} else {
|
||||
int *pl, n;
|
||||
switch (action) {
|
||||
case DASM_IMM_LG64: ofs += 4;
|
||||
case DASM_REL_LG:
|
||||
case DASM_IMM_LG:
|
||||
n = *p++; pl = D->lglabels + n;
|
||||
@ -226,6 +227,7 @@ void dasm_put(Dst_DECL, int start, ...)
|
||||
pl -= 246; n = *pl;
|
||||
if (n < 0) n = 0; /* Start new chain for fwd rel if label exists. */
|
||||
goto linkrel;
|
||||
case DASM_IMM_PC64: ofs += 4;
|
||||
case DASM_REL_PC:
|
||||
case DASM_IMM_PC: pl = D->pclabels + va_arg(ap, int); CKPL(pc, PC);
|
||||
putrel:
|
||||
@ -333,11 +335,12 @@ int dasm_link(Dst_DECL, size_t *szp)
|
||||
break;
|
||||
}
|
||||
/* fallthrough */
|
||||
case DASM_SPACE: case DASM_IMM_LG: case DASM_VREG: p++;
|
||||
case DASM_SPACE: case DASM_IMM_LG: case DASM_IMM_LG64: 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;
|
||||
case DASM_SETLABEL: case DASM_REL_A: case DASM_IMM_PC: case DASM_IMM_PC64:
|
||||
pos++; break;
|
||||
case DASM_LABEL_LG: p++;
|
||||
/* fallthrough */
|
||||
case DASM_LABEL_PC: b[pos++] += ofs; break; /* Fix label offset. */
|
||||
@ -365,9 +368,12 @@ int dasm_link(Dst_DECL, size_t *szp)
|
||||
do { *((unsigned short *)cp) = (unsigned short)(x); cp+=2; } while (0)
|
||||
#define dasmd(x) \
|
||||
do { *((unsigned int *)cp) = (unsigned int)(x); cp+=4; } while (0)
|
||||
#define dasmq(x) \
|
||||
do { *((uint64_t *)cp) = (uint64_t)(x); cp+=8; } while (0)
|
||||
#else
|
||||
#define dasmw(x) do { dasmb(x); dasmb((x)>>8); } while (0)
|
||||
#define dasmd(x) do { dasmw(x); dasmw((x)>>16); } while (0)
|
||||
#define dasmq(x) do { dasmd(x); dasmd((x)>>32); } while (0)
|
||||
#endif
|
||||
|
||||
/* Pass 3: Encode sections. */
|
||||
@ -450,6 +456,16 @@ int dasm_encode(Dst_DECL, void *buffer)
|
||||
n = *pb < 0 ? pb[1] : (*pb + (int)(ptrdiff_t)base);
|
||||
goto wd;
|
||||
}
|
||||
case DASM_IMM_LG64: {
|
||||
p++;
|
||||
if (n < 0)
|
||||
dasmq((ptrdiff_t)D->globals[-n]);
|
||||
}
|
||||
case DASM_IMM_PC64: {
|
||||
int *pb = DASM_POS2PTR(D, n);
|
||||
dasmq(*pb < 0 ? pb[1] : (*pb + (ptrdiff_t)base));
|
||||
break;
|
||||
}
|
||||
case DASM_LABEL_LG: {
|
||||
int idx = *p++;
|
||||
if (idx >= 10)
|
||||
|
@ -46,8 +46,8 @@ local action_names = {
|
||||
"SETLABEL", "REL_A",
|
||||
-- action arg (1 byte) or int arg, 2 buffer pos (link, offset):
|
||||
"REL_LG", "REL_PC",
|
||||
-- action arg (1 byte) or int arg, 1 buffer pos (link):
|
||||
"IMM_LG", "IMM_PC",
|
||||
-- action arg (1 byte) or ptrdiff_t arg, 1 buffer pos (link):
|
||||
"IMM_LG", "IMM_LG64", "IMM_PC", "IMM_PC64",
|
||||
-- action arg (1 byte) or int arg, 1 buffer pos (offset):
|
||||
"LABEL_LG", "LABEL_PC",
|
||||
-- action arg (1 byte), 1 buffer pos (offset):
|
||||
@ -438,6 +438,16 @@ local function wputlabel(aprefix, imm, num)
|
||||
end
|
||||
end
|
||||
|
||||
-- Put action for label arg (IMM_LG64, IMM_PC64, REL_LG, REL_PC).
|
||||
local function wputlabel64(aprefix, imm, num)
|
||||
if type(imm) == "number" then
|
||||
waction("IMM_LG64", nil, num);
|
||||
wputxb(imm)
|
||||
else
|
||||
waction("IMM_PC64", imm, num)
|
||||
end
|
||||
end
|
||||
|
||||
-- Put signed byte or arg.
|
||||
local function wputsbarg(n)
|
||||
if type(n) == "number" then
|
||||
@ -469,6 +479,26 @@ local function wputwarg(n)
|
||||
else waction("IMM_W", n) end
|
||||
end
|
||||
|
||||
-- Put signed or unsigned qword or arg.
|
||||
local function wputqarg(n)
|
||||
local tn = type(n)
|
||||
if tn == "number" then
|
||||
wputb(band(n, 255))
|
||||
wputb(band(shr(n, 8), 255))
|
||||
wputb(band(shr(n, 16), 255))
|
||||
wputb(band(shr(n, 24), 255))
|
||||
wputb(band(shr(n, 32), 255))
|
||||
wputb(band(shr(n, 40), 255))
|
||||
wputb(band(shr(n, 48), 255))
|
||||
wputb(shr(n, 56))
|
||||
elseif tn == "table" then
|
||||
wputlabel64("IMM_", n[1], 1)
|
||||
else
|
||||
waction("IMM_D", format("(unsigned int)(%s)", n))
|
||||
waction("IMM_D", format("(unsigned int)((%s)>>32)", n))
|
||||
end
|
||||
end
|
||||
|
||||
-- Put signed or unsigned dword or arg.
|
||||
local function wputdarg(n)
|
||||
local tn = type(n)
|
||||
@ -2151,9 +2181,17 @@ local function op_data(params)
|
||||
werror("bad mode or size in `"..p.."'")
|
||||
end
|
||||
if a.mode == "iJ" then
|
||||
wputlabel("IMM_", a.imm, 1)
|
||||
if sz == 'q' then
|
||||
wputlabel64("IMM_", a.imm, 1)
|
||||
else
|
||||
wputlabel("IMM_", a.imm, 1)
|
||||
end
|
||||
else
|
||||
wputszarg(sz, a.imm)
|
||||
if sz == 'q' then
|
||||
wputqarg(a.imm)
|
||||
else
|
||||
wputszarg(sz, a.imm)
|
||||
end
|
||||
end
|
||||
if secpos+2 > maxsecpos then wflush() end
|
||||
end
|
||||
|
Loading…
Reference in New Issue
Block a user