mirror of
https://github.com/LuaJIT/LuaJIT.git
synced 2025-02-07 23:24:09 +00:00
ARM: Add pc-relative loads to DynASM.
This commit is contained in:
parent
1a56dacbcf
commit
3f8fed5358
@ -360,7 +360,7 @@ int dasm_encode(Dst_DECL, void *buffer)
|
||||
case DASM_STOP: case DASM_SECTION: goto stop;
|
||||
case DASM_ESC: *cp++ = *p++; break;
|
||||
case DASM_REL_EXT:
|
||||
n = DASM_EXTERN(Dst, (unsigned char *)cp, (ins & 2047), 1);
|
||||
n = DASM_EXTERN(Dst, (unsigned char *)cp, (ins&2047), !(ins&2048));
|
||||
goto patchrel;
|
||||
case DASM_ALIGN:
|
||||
ins &= 255; while ((((char *)cp - base) & ins)) *cp++ = 0xe1a00000;
|
||||
@ -369,10 +369,18 @@ int dasm_encode(Dst_DECL, void *buffer)
|
||||
CK(n >= 0, UNDEF_LG);
|
||||
case DASM_REL_PC:
|
||||
CK(n >= 0, UNDEF_PC);
|
||||
n = *DASM_POS2PTR(D, n) - (int)((char *)cp - base);
|
||||
n = *DASM_POS2PTR(D, n) - (int)((char *)cp - base) - 4;
|
||||
patchrel:
|
||||
CK((n & 3) == 0 && ((n-4+0x02000000) >> 26) == 0, RANGE_REL);
|
||||
cp[-1] |= (((n-4) >> 2) & 0x00ffffff);
|
||||
if ((ins & 0x800) == 0) {
|
||||
CK((n & 3) == 0 && ((n+0x02000000) >> 26) == 0, RANGE_REL);
|
||||
cp[-1] |= ((n >> 2) & 0x00ffffff);
|
||||
} else if ((ins & 0x1000)) {
|
||||
CK((n & 3) == 0 && -256 <= n && n <= 256, RANGE_REL);
|
||||
goto patchimml8;
|
||||
} else {
|
||||
CK((n & 3) == 0 && -4096 <= n && n <= 4096, RANGE_REL);
|
||||
goto patchimml12;
|
||||
}
|
||||
break;
|
||||
case DASM_LABEL_LG:
|
||||
ins &= 2047; if (ins >= 20) D->globals[ins-10] = (void *)(base + n);
|
||||
@ -387,11 +395,11 @@ int dasm_encode(Dst_DECL, void *buffer)
|
||||
case DASM_IMM16:
|
||||
cp[-1] |= ((n & 0xf000) << 4) | (n & 0x0fff);
|
||||
break;
|
||||
case DASM_IMML8:
|
||||
case DASM_IMML8: patchimml8:
|
||||
cp[-1] |= n >= 0 ? (0x00800000 | (n & 0x0f) | ((n & 0xf0) << 4)) :
|
||||
((-n & 0x0f) | ((-n & 0xf0) << 4));
|
||||
break;
|
||||
case DASM_IMML12:
|
||||
case DASM_IMML12: patchimml12:
|
||||
cp[-1] |= n >= 0 ? (0x00800000 | n) : (-n);
|
||||
break;
|
||||
default: *cp++ = ins; break;
|
||||
|
@ -586,6 +586,36 @@ local function parse_shift(shift, gprok)
|
||||
end
|
||||
end
|
||||
|
||||
local function parse_label(label, def)
|
||||
local prefix = sub(label, 1, 2)
|
||||
-- =>label (pc label reference)
|
||||
if prefix == "=>" then
|
||||
return "PC", 0, sub(label, 3)
|
||||
end
|
||||
-- ->name (global label reference)
|
||||
if prefix == "->" then
|
||||
return "LG", map_global[sub(label, 3)]
|
||||
end
|
||||
if def then
|
||||
-- [1-9] (local label definition)
|
||||
if match(label, "^[1-9]$") then
|
||||
return "LG", 10+tonumber(label)
|
||||
end
|
||||
else
|
||||
-- [<>][1-9] (local label reference)
|
||||
local dir, lnum = match(label, "^([<>])([1-9])$")
|
||||
if dir then -- Fwd: 1-9, Bkwd: 11-19.
|
||||
return "LG", lnum + (dir == ">" and 0 or 10)
|
||||
end
|
||||
-- extern label (extern label reference)
|
||||
local extname = match(label, "^extern%s+(%S+)$")
|
||||
if extname then
|
||||
return "EXT", map_extern[extname]
|
||||
end
|
||||
end
|
||||
werror("bad label `"..label.."'")
|
||||
end
|
||||
|
||||
local function parse_load(params, nparams, n, op)
|
||||
local oplo = op % 256
|
||||
local ext, ldrd = (oplo ~= 0), (oplo == 208)
|
||||
@ -594,11 +624,17 @@ local function parse_load(params, nparams, n, op)
|
||||
d = ((op - (op % 4096)) / 4096) % 16
|
||||
if d % 2 ~= 0 then werror("odd destination register") end
|
||||
end
|
||||
local p1, wb = match(params[n], "^%[%s*(.-)%s*%](!?)$")
|
||||
local pn = params[n]
|
||||
local p1, wb = match(pn, "^%[%s*(.-)%s*%](!?)$")
|
||||
local p2 = params[n+1]
|
||||
if not p1 then
|
||||
if not p2 then
|
||||
local reg, tailr = match(params[n], "^([%w_:]+)%s*(.*)$")
|
||||
if match(pn, "^[<>=%-]") or match(pn, "^extern%s+") then
|
||||
local mode, n, s = parse_label(pn, false)
|
||||
waction("REL_"..mode, n + (ext and 0x1800 or 0x0800), s, 1)
|
||||
return op + 15 * 65536 + 0x01000000 + (ext and 0x00400000 or 0)
|
||||
end
|
||||
local reg, tailr = match(pn, "^([%w_:]+)%s*(.*)$")
|
||||
if reg and tailr ~= "" then
|
||||
local d, tp = parse_gpr(reg)
|
||||
if tp then
|
||||
@ -653,36 +689,6 @@ local function parse_load(params, nparams, n, op)
|
||||
return op
|
||||
end
|
||||
|
||||
local function parse_label(label, def)
|
||||
local prefix = sub(label, 1, 2)
|
||||
-- =>label (pc label reference)
|
||||
if prefix == "=>" then
|
||||
return "PC", 0, sub(label, 3)
|
||||
end
|
||||
-- ->name (global label reference)
|
||||
if prefix == "->" then
|
||||
return "LG", map_global[sub(label, 3)]
|
||||
end
|
||||
if def then
|
||||
-- [1-9] (local label definition)
|
||||
if match(label, "^[1-9]$") then
|
||||
return "LG", 10+tonumber(label)
|
||||
end
|
||||
else
|
||||
-- [<>][1-9] (local label reference)
|
||||
local dir, lnum = match(label, "^([<>])([1-9])$")
|
||||
if dir then -- Fwd: 1-9, Bkwd: 11-19.
|
||||
return "LG", lnum + (dir == ">" and 0 or 10)
|
||||
end
|
||||
-- extern label (extern label reference)
|
||||
local extname = match(label, "^extern%s+(%S+)$")
|
||||
if extname then
|
||||
return "EXT", map_extern[extname]
|
||||
end
|
||||
end
|
||||
werror("bad label `"..label.."'")
|
||||
end
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
-- Handle opcodes defined with template strings.
|
||||
|
Loading…
Reference in New Issue
Block a user