mirror of
https://github.com/LuaJIT/LuaJIT.git
synced 2025-02-07 15:14:08 +00:00
Add support for rip-relative displacements to DynASM x64.
This commit is contained in:
parent
85d32aeb36
commit
3a18dba3f2
@ -510,26 +510,36 @@ local function wputmrmsib(t, imark, s, vsreg)
|
|||||||
local tdisp = type(disp)
|
local tdisp = type(disp)
|
||||||
-- No base register?
|
-- No base register?
|
||||||
if not reg then
|
if not reg then
|
||||||
|
local riprel = false
|
||||||
if xreg then
|
if xreg then
|
||||||
-- Indexed mode with index register only.
|
-- Indexed mode with index register only.
|
||||||
-- [xreg*xsc+disp] -> (0, s, esp) (xsc, xreg, ebp)
|
-- [xreg*xsc+disp] -> (0, s, esp) (xsc, xreg, ebp)
|
||||||
wputmodrm(0, s, 4)
|
wputmodrm(0, s, 4)
|
||||||
if imark then waction("MARK") end
|
if imark == "I" then waction("MARK") end
|
||||||
if vsreg then waction("VREG", vsreg); wputxb(2) end
|
if vsreg then waction("VREG", vsreg); wputxb(2) end
|
||||||
wputmodrm(t.xsc, xreg, 5)
|
wputmodrm(t.xsc, xreg, 5)
|
||||||
if vxreg then waction("VREG", vxreg); wputxb(3) end
|
if vxreg then waction("VREG", vxreg); wputxb(3) end
|
||||||
else
|
else
|
||||||
-- Pure 32 bit displacement.
|
-- Pure 32 bit displacement.
|
||||||
if x64 then
|
if x64 and tdisp ~= "table" then
|
||||||
wputmodrm(0, s, 4) -- [disp] -> (0, s, esp) (0, esp, ebp)
|
wputmodrm(0, s, 4) -- [disp] -> (0, s, esp) (0, esp, ebp)
|
||||||
wputmodrm(0, 4, 5)
|
wputmodrm(0, 4, 5)
|
||||||
else
|
else
|
||||||
wputmodrm(0, s, 5) -- [disp] -> (0, s, ebp)
|
riprel = x64
|
||||||
|
wputmodrm(0, s, 5) -- [disp|rip-label] -> (0, s, ebp)
|
||||||
end
|
end
|
||||||
if imark then waction("MARK") end
|
if imark == "I" then waction("MARK") end
|
||||||
if vsreg then waction("VREG", vsreg); wputxb(2) end
|
if vsreg then waction("VREG", vsreg); wputxb(2) end
|
||||||
end
|
end
|
||||||
wputdarg(disp)
|
if riprel then -- Emit rip-relative displacement.
|
||||||
|
if match("UWSiI", imark) then
|
||||||
|
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)
|
||||||
|
else
|
||||||
|
wputdarg(disp)
|
||||||
|
end
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -546,14 +556,14 @@ local function wputmrmsib(t, imark, s, vsreg)
|
|||||||
-- Index register present or esp as base register: need SIB encoding.
|
-- Index register present or esp as base register: need SIB encoding.
|
||||||
if xreg or (reg%8) == 4 then
|
if xreg or (reg%8) == 4 then
|
||||||
wputmodrm(m or 2, s, 4) -- ModRM.
|
wputmodrm(m or 2, s, 4) -- ModRM.
|
||||||
if m == nil or imark then waction("MARK") end
|
if m == nil or imark == "I" then waction("MARK") end
|
||||||
if vsreg then waction("VREG", vsreg); wputxb(2) end
|
if vsreg then waction("VREG", vsreg); wputxb(2) end
|
||||||
wputmodrm(t.xsc or 0, xreg or 4, reg) -- SIB.
|
wputmodrm(t.xsc or 0, xreg or 4, reg) -- SIB.
|
||||||
if vxreg then waction("VREG", vxreg); wputxb(3) end
|
if vxreg then waction("VREG", vxreg); wputxb(3) end
|
||||||
if vreg then waction("VREG", vreg); wputxb(1) end
|
if vreg then waction("VREG", vreg); wputxb(1) end
|
||||||
else
|
else
|
||||||
wputmodrm(m or 2, s, reg) -- ModRM.
|
wputmodrm(m or 2, s, reg) -- ModRM.
|
||||||
if (imark and (m == 1 or m == 2)) or
|
if (imark == "I" and (m == 1 or m == 2)) or
|
||||||
(m == nil and (vsreg or vreg)) then waction("MARK") end
|
(m == nil and (vsreg or vreg)) then waction("MARK") end
|
||||||
if vsreg then waction("VREG", vsreg); wputxb(2) end
|
if vsreg then waction("VREG", vsreg); wputxb(2) end
|
||||||
if vreg then waction("VREG", vreg); wputxb(1) end
|
if vreg then waction("VREG", vreg); wputxb(1) end
|
||||||
@ -1497,7 +1507,7 @@ local function dopattern(pat, args, sz, op)
|
|||||||
if t.xreg and t.xreg > 7 then rex = rex + 2 end
|
if t.xreg and t.xreg > 7 then rex = rex + 2 end
|
||||||
if s > 7 then rex = rex + 4 end
|
if s > 7 then rex = rex + 4 end
|
||||||
wputop(szov, opcode, rex); opcode = nil
|
wputop(szov, opcode, rex); opcode = nil
|
||||||
local imark = (sub(pat, -1) == "I") -- Force a mark (ugly).
|
local imark = sub(pat, -1) -- Force a mark (ugly).
|
||||||
-- Put ModRM/SIB with regno/last digit as spare.
|
-- Put ModRM/SIB with regno/last digit as spare.
|
||||||
wputmrmsib(t, imark, s, addin and addin.vreg)
|
wputmrmsib(t, imark, s, addin and addin.vreg)
|
||||||
addin = nil
|
addin = nil
|
||||||
|
Loading…
Reference in New Issue
Block a user