diff options
author | Mike Pall <mike> | 2009-12-16 05:47:52 +0100 |
---|---|---|
committer | Mike Pall <mike> | 2009-12-16 05:47:52 +0100 |
commit | 3a18dba3f251ea1b50e031629af96ca5fc1086e8 (patch) | |
tree | 909324986a9b8d09ddabc60fb6888e82d535ddfe | |
parent | 85d32aeb36bf6055b8e3696432458d07ccdb4006 (diff) | |
download | luajit-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.lua | 26 |
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 |