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 |
