mirror of
https://github.com/LuaJIT/LuaJIT.git
synced 2025-02-07 15:14:08 +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_STOP: case DASM_SECTION: goto stop;
|
||||||
case DASM_ESC: *cp++ = *p++; break;
|
case DASM_ESC: *cp++ = *p++; break;
|
||||||
case DASM_REL_EXT:
|
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;
|
goto patchrel;
|
||||||
case DASM_ALIGN:
|
case DASM_ALIGN:
|
||||||
ins &= 255; while ((((char *)cp - base) & ins)) *cp++ = 0xe1a00000;
|
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);
|
CK(n >= 0, UNDEF_LG);
|
||||||
case DASM_REL_PC:
|
case DASM_REL_PC:
|
||||||
CK(n >= 0, UNDEF_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:
|
patchrel:
|
||||||
CK((n & 3) == 0 && ((n-4+0x02000000) >> 26) == 0, RANGE_REL);
|
if ((ins & 0x800) == 0) {
|
||||||
cp[-1] |= (((n-4) >> 2) & 0x00ffffff);
|
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;
|
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-10] = (void *)(base + n);
|
||||||
@ -387,11 +395,11 @@ int dasm_encode(Dst_DECL, void *buffer)
|
|||||||
case DASM_IMM16:
|
case DASM_IMM16:
|
||||||
cp[-1] |= ((n & 0xf000) << 4) | (n & 0x0fff);
|
cp[-1] |= ((n & 0xf000) << 4) | (n & 0x0fff);
|
||||||
break;
|
break;
|
||||||
case DASM_IMML8:
|
case DASM_IMML8: patchimml8:
|
||||||
cp[-1] |= n >= 0 ? (0x00800000 | (n & 0x0f) | ((n & 0xf0) << 4)) :
|
cp[-1] |= n >= 0 ? (0x00800000 | (n & 0x0f) | ((n & 0xf0) << 4)) :
|
||||||
((-n & 0x0f) | ((-n & 0xf0) << 4));
|
((-n & 0x0f) | ((-n & 0xf0) << 4));
|
||||||
break;
|
break;
|
||||||
case DASM_IMML12:
|
case DASM_IMML12: patchimml12:
|
||||||
cp[-1] |= n >= 0 ? (0x00800000 | n) : (-n);
|
cp[-1] |= n >= 0 ? (0x00800000 | n) : (-n);
|
||||||
break;
|
break;
|
||||||
default: *cp++ = ins; break;
|
default: *cp++ = ins; break;
|
||||||
|
@ -586,6 +586,36 @@ local function parse_shift(shift, gprok)
|
|||||||
end
|
end
|
||||||
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 function parse_load(params, nparams, n, op)
|
||||||
local oplo = op % 256
|
local oplo = op % 256
|
||||||
local ext, ldrd = (oplo ~= 0), (oplo == 208)
|
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
|
d = ((op - (op % 4096)) / 4096) % 16
|
||||||
if d % 2 ~= 0 then werror("odd destination register") end
|
if d % 2 ~= 0 then werror("odd destination register") end
|
||||||
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]
|
local p2 = params[n+1]
|
||||||
if not p1 then
|
if not p1 then
|
||||||
if not p2 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
|
if reg and tailr ~= "" then
|
||||||
local d, tp = parse_gpr(reg)
|
local d, tp = parse_gpr(reg)
|
||||||
if tp then
|
if tp then
|
||||||
@ -653,36 +689,6 @@ local function parse_load(params, nparams, n, op)
|
|||||||
return op
|
return op
|
||||||
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
|
|
||||||
|
|
||||||
------------------------------------------------------------------------------
|
------------------------------------------------------------------------------
|
||||||
|
|
||||||
-- Handle opcodes defined with template strings.
|
-- Handle opcodes defined with template strings.
|
||||||
|
Loading…
Reference in New Issue
Block a user