aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Pall <mike>2009-12-16 05:47:52 +0100
committerMike Pall <mike>2009-12-16 05:47:52 +0100
commit3a18dba3f251ea1b50e031629af96ca5fc1086e8 (patch)
tree909324986a9b8d09ddabc60fb6888e82d535ddfe
parent85d32aeb36bf6055b8e3696432458d07ccdb4006 (diff)
downloadluajit-3a18dba3f251ea1b50e031629af96ca5fc1086e8.tar.gz
luajit-3a18dba3f251ea1b50e031629af96ca5fc1086e8.tar.bz2
luajit-3a18dba3f251ea1b50e031629af96ca5fc1086e8.zip
Add support for rip-relative displacements to DynASM x64.
-rw-r--r--dynasm/dasm_x86.lua26
1 files changed, 18 insertions, 8 deletions
diff --git a/dynasm/dasm_x86.lua b/dynasm/dasm_x86.lua
index aa1a5c32..e7f894d6 100644
--- a/dynasm/dasm_x86.lua
+++ b/dynasm/dasm_x86.lua
@@ -510,26 +510,36 @@ local function wputmrmsib(t, imark, s, vsreg)
510 local tdisp = type(disp) 510 local tdisp = type(disp)
511 -- No base register? 511 -- No base register?
512 if not reg then 512 if not reg then
513 local riprel = false
513 if xreg then 514 if xreg then
514 -- Indexed mode with index register only. 515 -- Indexed mode with index register only.
515 -- [xreg*xsc+disp] -> (0, s, esp) (xsc, xreg, ebp) 516 -- [xreg*xsc+disp] -> (0, s, esp) (xsc, xreg, ebp)
516 wputmodrm(0, s, 4) 517 wputmodrm(0, s, 4)
517 if imark then waction("MARK") end 518 if imark == "I" then waction("MARK") end
518 if vsreg then waction("VREG", vsreg); wputxb(2) end 519 if vsreg then waction("VREG", vsreg); wputxb(2) end
519 wputmodrm(t.xsc, xreg, 5) 520 wputmodrm(t.xsc, xreg, 5)
520 if vxreg then waction("VREG", vxreg); wputxb(3) end 521 if vxreg then waction("VREG", vxreg); wputxb(3) end
521 else 522 else
522 -- Pure 32 bit displacement. 523 -- Pure 32 bit displacement.
523 if x64 then 524 if x64 and tdisp ~= "table" then
524 wputmodrm(0, s, 4) -- [disp] -> (0, s, esp) (0, esp, ebp) 525 wputmodrm(0, s, 4) -- [disp] -> (0, s, esp) (0, esp, ebp)
525 wputmodrm(0, 4, 5) 526 wputmodrm(0, 4, 5)
526 else 527 else
527 wputmodrm(0, s, 5) -- [disp] -> (0, s, ebp) 528 riprel = x64
529 wputmodrm(0, s, 5) -- [disp|rip-label] -> (0, s, ebp)
528 end 530 end
529 if imark then waction("MARK") end 531 if imark == "I" then waction("MARK") end
530 if vsreg then waction("VREG", vsreg); wputxb(2) end 532 if vsreg then waction("VREG", vsreg); wputxb(2) end
531 end 533 end
532 wputdarg(disp) 534 if riprel then -- Emit rip-relative displacement.
535 if match("UWSiI", imark) then
536 werror("NYI: rip-relative displacement followed by immediate")
537 end
538 -- The previous byte in the action buffer cannot be 0xe9 or 0x80-0x8f.
539 wputlabel("REL_", disp[1], 2)
540 else
541 wputdarg(disp)
542 end
533 return 543 return
534 end 544 end
535 545
@@ -546,14 +556,14 @@ local function wputmrmsib(t, imark, s, vsreg)
546 -- Index register present or esp as base register: need SIB encoding. 556 -- Index register present or esp as base register: need SIB encoding.
547 if xreg or (reg%8) == 4 then 557 if xreg or (reg%8) == 4 then
548 wputmodrm(m or 2, s, 4) -- ModRM. 558 wputmodrm(m or 2, s, 4) -- ModRM.
549 if m == nil or imark then waction("MARK") end 559 if m == nil or imark == "I" then waction("MARK") end
550 if vsreg then waction("VREG", vsreg); wputxb(2) end 560 if vsreg then waction("VREG", vsreg); wputxb(2) end
551 wputmodrm(t.xsc or 0, xreg or 4, reg) -- SIB. 561 wputmodrm(t.xsc or 0, xreg or 4, reg) -- SIB.
552 if vxreg then waction("VREG", vxreg); wputxb(3) end 562 if vxreg then waction("VREG", vxreg); wputxb(3) end
553 if vreg then waction("VREG", vreg); wputxb(1) end 563 if vreg then waction("VREG", vreg); wputxb(1) end
554 else 564 else
555 wputmodrm(m or 2, s, reg) -- ModRM. 565 wputmodrm(m or 2, s, reg) -- ModRM.
556 if (imark and (m == 1 or m == 2)) or 566 if (imark == "I" and (m == 1 or m == 2)) or
557 (m == nil and (vsreg or vreg)) then waction("MARK") end 567 (m == nil and (vsreg or vreg)) then waction("MARK") end
558 if vsreg then waction("VREG", vsreg); wputxb(2) end 568 if vsreg then waction("VREG", vsreg); wputxb(2) end
559 if vreg then waction("VREG", vreg); wputxb(1) end 569 if vreg then waction("VREG", vreg); wputxb(1) end
@@ -1497,7 +1507,7 @@ local function dopattern(pat, args, sz, op)
1497 if t.xreg and t.xreg > 7 then rex = rex + 2 end 1507 if t.xreg and t.xreg > 7 then rex = rex + 2 end
1498 if s > 7 then rex = rex + 4 end 1508 if s > 7 then rex = rex + 4 end
1499 wputop(szov, opcode, rex); opcode = nil 1509 wputop(szov, opcode, rex); opcode = nil
1500 local imark = (sub(pat, -1) == "I") -- Force a mark (ugly). 1510 local imark = sub(pat, -1) -- Force a mark (ugly).
1501 -- Put ModRM/SIB with regno/last digit as spare. 1511 -- Put ModRM/SIB with regno/last digit as spare.
1502 wputmrmsib(t, imark, s, addin and addin.vreg) 1512 wputmrmsib(t, imark, s, addin and addin.vreg)
1503 addin = nil 1513 addin = nil