diff options
Diffstat (limited to 'src/jit/dis_x86.lua')
| -rw-r--r-- | src/jit/dis_x86.lua | 152 |
1 files changed, 74 insertions, 78 deletions
diff --git a/src/jit/dis_x86.lua b/src/jit/dis_x86.lua index 80bf721b1..b85061292 100644 --- a/src/jit/dis_x86.lua +++ b/src/jit/dis_x86.lua | |||
| @@ -421,21 +421,21 @@ local function putop(ctx, text, operands) | |||
| 421 | local hmax = ctx.hexdump | 421 | local hmax = ctx.hexdump |
| 422 | if hmax > 0 then | 422 | if hmax > 0 then |
| 423 | for i=ctx.start,pos-1 do | 423 | for i=ctx.start,pos-1 do |
| 424 | hex = hex..format("%02X", byte(code, i, i)) | 424 | hex ..= format("%02X", byte(code, i)) |
| 425 | end | 425 | end |
| 426 | if #hex > hmax then hex = sub(hex, 1, hmax)..". " | 426 | if #hex > hmax then hex = sub(hex, 1, hmax)..". " |
| 427 | else hex = hex..rep(" ", hmax-#hex+2) end | 427 | else hex ..= rep(" ", hmax-#hex+2) end |
| 428 | end | 428 | end |
| 429 | if operands then text = text.." "..operands end | 429 | if operands then text = text.." "..operands end |
| 430 | if ctx.o16 then text = "o16 "..text; ctx.o16 = false end | 430 | if ctx.o16 then text = "o16 "..text; ctx.o16 = false end |
| 431 | if ctx.a32 then text = "a32 "..text; ctx.a32 = false end | 431 | if ctx.a32 then text = "a32 "..text; ctx.a32 = false end |
| 432 | if ctx.rep then text = ctx.rep.." "..text; ctx.rep = false end | 432 | if ctx.rep then text = ctx.rep.." "..text; ctx.rep = false end |
| 433 | if ctx.rex then | 433 | if ctx.rex then |
| 434 | local t = (ctx.rexw and "w" or "")..(ctx.rexr and "r" or "").. | 434 | local t = (ctx.rexw ? "w" : "")..(ctx.rexr ? "r" : "").. |
| 435 | (ctx.rexx and "x" or "")..(ctx.rexb and "b" or "").. | 435 | (ctx.rexx ? "x" : "")..(ctx.rexb ? "b" : "").. |
| 436 | (ctx.vexl and "l" or "") | 436 | (ctx.vexl ? "l" : "") |
| 437 | if ctx.vexv and ctx.vexv ~= 0 then t = t.."v"..ctx.vexv end | 437 | if ctx.vexv and ctx.vexv != 0 then t = t.."v"..ctx.vexv end |
| 438 | if t ~= "" then text = ctx.rex.."."..t.." "..gsub(text, "^ ", "") | 438 | if t != "" then text = ctx.rex.."."..t.." "..gsub(text, "^ ", "") |
| 439 | elseif ctx.rex == "vex" then text = gsub("v"..text, "^v ", "") end | 439 | elseif ctx.rex == "vex" then text = gsub("v"..text, "^v ", "") end |
| 440 | ctx.rexw = false; ctx.rexr = false; ctx.rexx = false; ctx.rexb = false | 440 | ctx.rexw = false; ctx.rexr = false; ctx.rexx = false; ctx.rexb = false |
| 441 | ctx.rex = false; ctx.vexl = false; ctx.vexv = false | 441 | ctx.rex = false; ctx.vexl = false; ctx.vexv = false |
| @@ -483,7 +483,7 @@ local function getimm(ctx, pos, n) | |||
| 483 | if pos+n-1 > ctx.stop then return incomplete(ctx) end | 483 | if pos+n-1 > ctx.stop then return incomplete(ctx) end |
| 484 | local code = ctx.code | 484 | local code = ctx.code |
| 485 | if n == 1 then | 485 | if n == 1 then |
| 486 | local b1 = byte(code, pos, pos) | 486 | local b1 = byte(code, pos) |
| 487 | return b1 | 487 | return b1 |
| 488 | elseif n == 2 then | 488 | elseif n == 2 then |
| 489 | local b1, b2 = byte(code, pos, pos+1) | 489 | local b1, b2 = byte(code, pos, pos+1) |
| @@ -521,41 +521,41 @@ local function putpat(ctx, name, pat) | |||
| 521 | if sz == "X" and vexl then sz = "Y"; ctx.vexl = false end | 521 | if sz == "X" and vexl then sz = "Y"; ctx.vexl = false end |
| 522 | regs = map_regs[sz] | 522 | regs = map_regs[sz] |
| 523 | elseif p == "P" then | 523 | elseif p == "P" then |
| 524 | sz = ctx.o16 and "X" or "M"; ctx.o16 = false | 524 | sz = ctx.o16 ? "X" : "M"; ctx.o16 = false |
| 525 | if sz == "X" and vexl then sz = "Y"; ctx.vexl = false end | 525 | if sz == "X" and vexl then sz = "Y"; ctx.vexl = false end |
| 526 | regs = map_regs[sz] | 526 | regs = map_regs[sz] |
| 527 | elseif p == "H" then | 527 | elseif p == "H" then |
| 528 | name = name..(ctx.rexw and "d" or "s") | 528 | name ..= ctx.rexw ? "d" : "s" |
| 529 | ctx.rexw = false | 529 | ctx.rexw = false |
| 530 | elseif p == "S" then | 530 | elseif p == "S" then |
| 531 | name = name..lower(sz) | 531 | name ..= lower(sz) |
| 532 | elseif p == "s" then | 532 | elseif p == "s" then |
| 533 | local imm = getimm(ctx, pos, 1); if not imm then return end | 533 | local imm = getimm(ctx, pos, 1); if not imm then return end |
| 534 | x = imm <= 127 and format("+0x%02x", imm) | 534 | x = imm <= 127 ? format("+0x%02x", imm) |
| 535 | or format("-0x%02x", 256-imm) | 535 | : format("-0x%02x", 256-imm) |
| 536 | pos = pos+1 | 536 | pos += 1 |
| 537 | elseif p == "u" then | 537 | elseif p == "u" then |
| 538 | local imm = getimm(ctx, pos, 1); if not imm then return end | 538 | local imm = getimm(ctx, pos, 1); if not imm then return end |
| 539 | x = format("0x%02x", imm) | 539 | x = format("0x%02x", imm) |
| 540 | pos = pos+1 | 540 | pos += 1 |
| 541 | elseif p == "b" then | 541 | elseif p == "b" then |
| 542 | local imm = getimm(ctx, pos, 1); if not imm then return end | 542 | local imm = getimm(ctx, pos, 1); if not imm then return end |
| 543 | x = regs[imm/16+1] | 543 | x = regs[imm/16+1] |
| 544 | pos = pos+1 | 544 | pos += 1 |
| 545 | elseif p == "w" then | 545 | elseif p == "w" then |
| 546 | local imm = getimm(ctx, pos, 2); if not imm then return end | 546 | local imm = getimm(ctx, pos, 2); if not imm then return end |
| 547 | x = format("0x%x", imm) | 547 | x = format("0x%x", imm) |
| 548 | pos = pos+2 | 548 | pos += 2 |
| 549 | elseif p == "o" then -- [offset] | 549 | elseif p == "o" then -- [offset] |
| 550 | if ctx.x64 then | 550 | if ctx.x64 then |
| 551 | local imm1 = getimm(ctx, pos, 4); if not imm1 then return end | 551 | local imm1 = getimm(ctx, pos, 4); if not imm1 then return end |
| 552 | local imm2 = getimm(ctx, pos+4, 4); if not imm2 then return end | 552 | local imm2 = getimm(ctx, pos+4, 4); if not imm2 then return end |
| 553 | x = format("[0x%08x%08x]", imm2, imm1) | 553 | x = format("[0x%08x%08x]", imm2, imm1) |
| 554 | pos = pos+8 | 554 | pos += 8 |
| 555 | else | 555 | else |
| 556 | local imm = getimm(ctx, pos, 4); if not imm then return end | 556 | local imm = getimm(ctx, pos, 4); if not imm then return end |
| 557 | x = format("[0x%08x]", imm) | 557 | x = format("[0x%08x]", imm) |
| 558 | pos = pos+4 | 558 | pos += 4 |
| 559 | end | 559 | end |
| 560 | elseif p == "i" or p == "I" then | 560 | elseif p == "i" or p == "I" then |
| 561 | local n = map_sz2n[sz] | 561 | local n = map_sz2n[sz] |
| @@ -568,21 +568,21 @@ local function putpat(ctx, name, pat) | |||
| 568 | local imm = getimm(ctx, pos, n); if not imm then return end | 568 | local imm = getimm(ctx, pos, n); if not imm then return end |
| 569 | if sz == "Q" and (imm < 0 or imm > 0x7fffffff) then | 569 | if sz == "Q" and (imm < 0 or imm > 0x7fffffff) then |
| 570 | imm = (0xffffffff+1)-imm | 570 | imm = (0xffffffff+1)-imm |
| 571 | x = format(imm > 65535 and "-0x%08x" or "-0x%x", imm) | 571 | x = format(imm > 65535 ? "-0x%08x" : "-0x%x", imm) |
| 572 | else | 572 | else |
| 573 | x = format(imm > 65535 and "0x%08x" or "0x%x", imm) | 573 | x = format(imm > 65535 ? "0x%08x" : "0x%x", imm) |
| 574 | end | 574 | end |
| 575 | end | 575 | end |
| 576 | pos = pos+n | 576 | pos += n |
| 577 | elseif p == "j" then | 577 | elseif p == "j" then |
| 578 | local n = map_sz2n[sz] | 578 | local n = map_sz2n[sz] |
| 579 | if n == 8 then n = 4 end | 579 | if n == 8 then n = 4 end |
| 580 | local imm = getimm(ctx, pos, n); if not imm then return end | 580 | local imm = getimm(ctx, pos, n); if not imm then return end |
| 581 | if sz == "B" and imm > 127 then imm = imm-256 | 581 | if sz == "B" and imm > 127 then imm -= 256 |
| 582 | elseif imm > 2147483647 then imm = imm-4294967296 end | 582 | elseif imm > 2147483647 then imm -= 4294967296 end |
| 583 | pos = pos+n | 583 | pos += n |
| 584 | imm = imm + pos + ctx.addr | 584 | imm = imm + pos + ctx.addr |
| 585 | if imm > 4294967295 and not ctx.x64 then imm = imm-4294967296 end | 585 | if imm > 4294967295 and not ctx.x64 then imm -= 4294967296 end |
| 586 | ctx.imm = imm | 586 | ctx.imm = imm |
| 587 | if sz == "W" then | 587 | if sz == "W" then |
| 588 | x = format("word 0x%04x", imm%65536) | 588 | x = format("word 0x%04x", imm%65536) |
| @@ -593,8 +593,8 @@ local function putpat(ctx, name, pat) | |||
| 593 | x = "0x"..tohex(imm) | 593 | x = "0x"..tohex(imm) |
| 594 | end | 594 | end |
| 595 | elseif p == "R" then | 595 | elseif p == "R" then |
| 596 | local r = byte(code, pos-1, pos-1)%8 | 596 | local r = byte(code, pos-1) & 7 |
| 597 | if ctx.rexb then r = r + 8; ctx.rexb = false end | 597 | if ctx.rexb then r += 8; ctx.rexb = false end |
| 598 | x = regs[r+1] | 598 | x = regs[r+1] |
| 599 | elseif p == "a" then x = regs[1] | 599 | elseif p == "a" then x = regs[1] |
| 600 | elseif p == "c" then x = "cl" | 600 | elseif p == "c" then x = "cl" |
| @@ -605,25 +605,25 @@ local function putpat(ctx, name, pat) | |||
| 605 | mode = ctx.mrm | 605 | mode = ctx.mrm |
| 606 | if not mode then | 606 | if not mode then |
| 607 | if pos > stop then return incomplete(ctx) end | 607 | if pos > stop then return incomplete(ctx) end |
| 608 | mode = byte(code, pos, pos) | 608 | mode = byte(code, pos) |
| 609 | pos = pos+1 | 609 | pos += 1 |
| 610 | end | 610 | end |
| 611 | rm = mode%8; mode = (mode-rm)/8 | 611 | rm = mode & 7; mode >>= 3 |
| 612 | sp = mode%8; mode = (mode-sp)/8 | 612 | sp = mode & 7; mode >>= 3 |
| 613 | sdisp = "" | 613 | sdisp = "" |
| 614 | if mode < 3 then | 614 | if mode < 3 then |
| 615 | if rm == 4 then | 615 | if rm == 4 then |
| 616 | if pos > stop then return incomplete(ctx) end | 616 | if pos > stop then return incomplete(ctx) end |
| 617 | sc = byte(code, pos, pos) | 617 | sc = byte(code, pos) |
| 618 | pos = pos+1 | 618 | pos += 1 |
| 619 | rm = sc%8; sc = (sc-rm)/8 | 619 | rm = sc & 7; sc >>= 3 |
| 620 | rx = sc%8; sc = (sc-rx)/8 | 620 | rx = sc & 7; sc >>= 3 |
| 621 | if ctx.rexx then rx = rx + 8; ctx.rexx = false end | 621 | if ctx.rexx then rx += 8; ctx.rexx = false end |
| 622 | if rx == 4 then rx = nil end | 622 | if rx == 4 then rx = nil end |
| 623 | end | 623 | end |
| 624 | if mode > 0 or rm == 5 then | 624 | if mode > 0 or rm == 5 then |
| 625 | local dsz = mode | 625 | local dsz = mode |
| 626 | if dsz ~= 1 then dsz = 4 end | 626 | if dsz != 1 then dsz = 4 end |
| 627 | local disp = getimm(ctx, pos, dsz); if not disp then return end | 627 | local disp = getimm(ctx, pos, dsz); if not disp then return end |
| 628 | if mode == 0 then rm = nil end | 628 | if mode == 0 then rm = nil end |
| 629 | if rm or rx or (not sc and ctx.x64 and not ctx.a32) then | 629 | if rm or rx or (not sc and ctx.x64 and not ctx.a32) then |
| @@ -637,26 +637,26 @@ local function putpat(ctx, name, pat) | |||
| 637 | else | 637 | else |
| 638 | sdisp = format(ctx.x64 and not ctx.a32 and | 638 | sdisp = format(ctx.x64 and not ctx.a32 and |
| 639 | not (disp >= 0 and disp <= 0x7fffffff) | 639 | not (disp >= 0 and disp <= 0x7fffffff) |
| 640 | and "0xffffffff%08x" or "0x%08x", disp) | 640 | ? "0xffffffff%08x" : "0x%08x", disp) |
| 641 | end | 641 | end |
| 642 | pos = pos+dsz | 642 | pos += dsz |
| 643 | end | 643 | end |
| 644 | end | 644 | end |
| 645 | if rm and ctx.rexb then rm = rm + 8; ctx.rexb = false end | 645 | if rm and ctx.rexb then rm += 8; ctx.rexb = false end |
| 646 | if ctx.rexr then sp = sp + 8; ctx.rexr = false end | 646 | if ctx.rexr then sp += 8; ctx.rexr = false end |
| 647 | end | 647 | end |
| 648 | if p == "m" then | 648 | if p == "m" then |
| 649 | if mode == 3 then x = regs[rm+1] | 649 | if mode == 3 then x = regs[rm+1] |
| 650 | else | 650 | else |
| 651 | local aregs = ctx.a32 and map_regs.D or ctx.aregs | 651 | local aregs = ctx.a32 ? map_regs.D : ctx.aregs |
| 652 | local srm, srx = "", "" | 652 | local srm, srx = "", "" |
| 653 | if rm then srm = aregs[rm+1] | 653 | if rm then srm = aregs[rm+1] |
| 654 | elseif not sc and ctx.x64 and not ctx.a32 then srm = "rip" end | 654 | elseif not sc and ctx.x64 and not ctx.a32 then srm = "rip" end |
| 655 | ctx.a32 = false | 655 | ctx.a32 = false |
| 656 | if rx then | 656 | if rx then |
| 657 | if rm then srm = srm.."+" end | 657 | if rm then srm ..= "+" end |
| 658 | srx = aregs[rx+1] | 658 | srx = aregs[rx+1] |
| 659 | if sc > 0 then srx = srx.."*"..(2^sc) end | 659 | if sc > 0 then srx = srx.."*"..(1 << sc) end |
| 660 | end | 660 | end |
| 661 | x = format("[%s%s%s]", srm, srx, sdisp) | 661 | x = format("[%s%s%s]", srm, srx, sdisp) |
| 662 | end | 662 | end |
| @@ -686,7 +686,7 @@ local function putpat(ctx, name, pat) | |||
| 686 | error("bad pattern `"..pat.."'") | 686 | error("bad pattern `"..pat.."'") |
| 687 | end | 687 | end |
| 688 | end | 688 | end |
| 689 | if x then operands = operands and operands..", "..x or x end | 689 | if x then operands = operands ? operands..", "..x : x end |
| 690 | end | 690 | end |
| 691 | ctx.pos = pos | 691 | ctx.pos = pos |
| 692 | return putop(ctx, name, operands) | 692 | return putop(ctx, name, operands) |
| @@ -701,8 +701,8 @@ local function getmrm(ctx) | |||
| 701 | if not mrm then | 701 | if not mrm then |
| 702 | local pos = ctx.pos | 702 | local pos = ctx.pos |
| 703 | if pos > ctx.stop then return nil end | 703 | if pos > ctx.stop then return nil end |
| 704 | mrm = byte(ctx.code, pos, pos) | 704 | mrm = byte(ctx.code, pos) |
| 705 | ctx.pos = pos+1 | 705 | ctx.pos = pos + 1 |
| 706 | ctx.mrm = mrm | 706 | ctx.mrm = mrm |
| 707 | end | 707 | end |
| 708 | return mrm | 708 | return mrm |
| @@ -714,7 +714,7 @@ local function dispatch(ctx, opat, patgrp) | |||
| 714 | if match(opat, "%|") then -- MMX/SSE variants depending on prefix. | 714 | if match(opat, "%|") then -- MMX/SSE variants depending on prefix. |
| 715 | local p | 715 | local p |
| 716 | if ctx.rep then | 716 | if ctx.rep then |
| 717 | p = ctx.rep=="rep" and "%|([^%|]*)" or "%|[^%|]*%|[^%|]*%|([^%|]*)" | 717 | p = ctx.rep == "rep" ? "%|([^%|]*)" : "%|[^%|]*%|[^%|]*%|([^%|]*)" |
| 718 | ctx.rep = false | 718 | ctx.rep = false |
| 719 | elseif ctx.o16 then p = "%|[^%|]*%|([^%|]*)"; ctx.o16 = false | 719 | elseif ctx.o16 then p = "%|[^%|]*%|([^%|]*)"; ctx.o16 = false |
| 720 | else p = "^[^%|]*" end | 720 | else p = "^[^%|]*" end |
| @@ -726,7 +726,7 @@ local function dispatch(ctx, opat, patgrp) | |||
| 726 | end | 726 | end |
| 727 | if match(opat, "%$") then -- reg$mem variants. | 727 | if match(opat, "%$") then -- reg$mem variants. |
| 728 | local mrm = getmrm(ctx); if not mrm then return incomplete(ctx) end | 728 | local mrm = getmrm(ctx); if not mrm then return incomplete(ctx) end |
| 729 | opat = match(opat, mrm >= 192 and "^[^%$]*" or "%$(.*)") | 729 | opat = match(opat, mrm >= 192 ? "^[^%$]*" : "%$(.*)") |
| 730 | if opat == "" then return unknown(ctx) end | 730 | if opat == "" then return unknown(ctx) end |
| 731 | end | 731 | end |
| 732 | if opat == "" then return unknown(ctx) end | 732 | if opat == "" then return unknown(ctx) end |
| @@ -738,9 +738,8 @@ end | |||
| 738 | -- Get a pattern from an opcode map and dispatch to handler. | 738 | -- Get a pattern from an opcode map and dispatch to handler. |
| 739 | local function dispatchmap(ctx, opcmap) | 739 | local function dispatchmap(ctx, opcmap) |
| 740 | local pos = ctx.pos | 740 | local pos = ctx.pos |
| 741 | local opat = opcmap[byte(ctx.code, pos, pos)] | 741 | local opat = opcmap[byte(ctx.code, pos)] |
| 742 | pos = pos + 1 | 742 | ctx.pos = pos + 1 |
| 743 | ctx.pos = pos | ||
| 744 | return dispatch(ctx, opat) | 743 | return dispatch(ctx, opat) |
| 745 | end | 744 | end |
| 746 | 745 | ||
| @@ -760,7 +759,7 @@ map_act = { | |||
| 760 | 759 | ||
| 761 | -- Collect prefixes. | 760 | -- Collect prefixes. |
| 762 | [":"] = function(ctx, name, pat) | 761 | [":"] = function(ctx, name, pat) |
| 763 | ctx[pat == ":" and name or sub(pat, 2)] = name | 762 | ctx[pat == ":" ? name : sub(pat, 2)] = name |
| 764 | if ctx.pos - ctx.start > 5 then return unknown(ctx) end -- Limit #prefixes. | 763 | if ctx.pos - ctx.start > 5 then return unknown(ctx) end -- Limit #prefixes. |
| 765 | end, | 764 | end, |
| 766 | 765 | ||
| @@ -772,7 +771,7 @@ map_act = { | |||
| 772 | -- Use named subtable for opcode group. | 771 | -- Use named subtable for opcode group. |
| 773 | ["!"] = function(ctx, name, pat) | 772 | ["!"] = function(ctx, name, pat) |
| 774 | local mrm = getmrm(ctx); if not mrm then return incomplete(ctx) end | 773 | local mrm = getmrm(ctx); if not mrm then return incomplete(ctx) end |
| 775 | return dispatch(ctx, map_opcgroup[name][((mrm-(mrm%8))/8)%8+1], sub(pat, 2)) | 774 | return dispatch(ctx, map_opcgroup[name][((mrm >> 3) & 7)+1], sub(pat, 2)) |
| 776 | end, | 775 | end, |
| 777 | 776 | ||
| 778 | -- o16,o32[,o64] variants. | 777 | -- o16,o32[,o64] variants. |
| @@ -825,9 +824,9 @@ map_act = { | |||
| 825 | -- Floating point opcode dispatch. | 824 | -- Floating point opcode dispatch. |
| 826 | fp = function(ctx, name, pat) | 825 | fp = function(ctx, name, pat) |
| 827 | local mrm = getmrm(ctx); if not mrm then return incomplete(ctx) end | 826 | local mrm = getmrm(ctx); if not mrm then return incomplete(ctx) end |
| 828 | local rm = mrm%8 | 827 | local rm = mrm & 7 |
| 829 | local idx = pat*8 + ((mrm-rm)/8)%8 | 828 | local idx = ((byte(pat) - 0x30) << 3) | ((mrm >> 3) & 7) |
| 830 | if mrm >= 192 then idx = idx + 64 end | 829 | if mrm >= 192 then idx += 64 end |
| 831 | local opat = map_opcfp[idx] | 830 | local opat = map_opcfp[idx] |
| 832 | if type(opat) == "table" then opat = opat[rm+1] end | 831 | if type(opat) == "table" then opat = opat[rm+1] end |
| 833 | return dispatch(ctx, opat) | 832 | return dispatch(ctx, opat) |
| @@ -847,23 +846,21 @@ map_act = { | |||
| 847 | local pos = ctx.pos | 846 | local pos = ctx.pos |
| 848 | if ctx.mrm then | 847 | if ctx.mrm then |
| 849 | ctx.mrm = nil | 848 | ctx.mrm = nil |
| 850 | pos = pos-1 | 849 | pos -= 1 |
| 851 | end | 850 | end |
| 852 | local b = byte(ctx.code, pos, pos) | 851 | local b = byte(ctx.code, pos) |
| 853 | if not b then return incomplete(ctx) end | 852 | if not b then return incomplete(ctx) end |
| 854 | pos = pos+1 | 853 | pos += 1 |
| 855 | if b < 128 then ctx.rexr = true end | 854 | if b < 128 then ctx.rexr = true end |
| 856 | local m = 1 | 855 | local m = 1 |
| 857 | if pat == "3" then | 856 | if pat == "3" then |
| 858 | m = b%32; b = (b-m)/32 | 857 | m = b & 0x1f |
| 859 | local nb = b%2; b = (b-nb)/2 | 858 | if b & 0x20 == 0 then ctx.rexb = true end |
| 860 | if nb == 0 then ctx.rexb = true end | 859 | if b & 0x40 == 0 then ctx.rexx = true end |
| 861 | local nx = b%2 | 860 | b = byte(ctx.code, pos) |
| 862 | if nx == 0 then ctx.rexx = true end | ||
| 863 | b = byte(ctx.code, pos, pos) | ||
| 864 | if not b then return incomplete(ctx) end | 861 | if not b then return incomplete(ctx) end |
| 865 | pos = pos+1 | 862 | pos += 1 |
| 866 | if b >= 128 then ctx.rexw = true end | 863 | if b & 0x80 then ctx.rexw = true end |
| 867 | end | 864 | end |
| 868 | ctx.pos = pos | 865 | ctx.pos = pos |
| 869 | local map | 866 | local map |
| @@ -871,24 +868,23 @@ map_act = { | |||
| 871 | elseif m == 2 then map = map_opc3["38"] | 868 | elseif m == 2 then map = map_opc3["38"] |
| 872 | elseif m == 3 then map = map_opc3["3a"] | 869 | elseif m == 3 then map = map_opc3["3a"] |
| 873 | else return unknown(ctx) end | 870 | else return unknown(ctx) end |
| 874 | local p = b%4; b = (b-p)/4 | 871 | local p = b & 3 |
| 875 | if p == 1 then ctx.o16 = "o16" | 872 | if p == 1 then ctx.o16 = "o16" |
| 876 | elseif p == 2 then ctx.rep = "rep" | 873 | elseif p == 2 then ctx.rep = "rep" |
| 877 | elseif p == 3 then ctx.rep = "repne" end | 874 | elseif p == 3 then ctx.rep = "repne" end |
| 878 | local l = b%2; b = (b-l)/2 | 875 | if b & 4 != 0 then ctx.vexl = true end |
| 879 | if l ~= 0 then ctx.vexl = true end | 876 | ctx.vexv = ~(b >> 3) & 15 |
| 880 | ctx.vexv = (-1-b)%16 | ||
| 881 | return dispatchmap(ctx, map) | 877 | return dispatchmap(ctx, map) |
| 882 | end, | 878 | end, |
| 883 | 879 | ||
| 884 | -- Special case for nop with REX prefix. | 880 | -- Special case for nop with REX prefix. |
| 885 | nop = function(ctx, name, pat) | 881 | nop = function(ctx, name, pat) |
| 886 | return dispatch(ctx, ctx.rex and pat or "nop") | 882 | return dispatch(ctx, ctx.rex ? pat : "nop") |
| 887 | end, | 883 | end, |
| 888 | 884 | ||
| 889 | -- Special case for 0F 77. | 885 | -- Special case for 0F 77. |
| 890 | emms = function(ctx, name, pat) | 886 | emms = function(ctx, name, pat) |
| 891 | if ctx.rex ~= "vex" then | 887 | if ctx.rex != "vex" then |
| 892 | return putop(ctx, "emms") | 888 | return putop(ctx, "emms") |
| 893 | elseif ctx.vexl then | 889 | elseif ctx.vexl then |
| 894 | ctx.vexl = false | 890 | ctx.vexl = false |
| @@ -904,8 +900,8 @@ map_act = { | |||
| 904 | -- Disassemble a block of code. | 900 | -- Disassemble a block of code. |
| 905 | local function disass_block(ctx, ofs, len) | 901 | local function disass_block(ctx, ofs, len) |
| 906 | if not ofs then ofs = 0 end | 902 | if not ofs then ofs = 0 end |
| 907 | local stop = len and ofs+len or #ctx.code | 903 | local stop = len ? ofs+len : #ctx.code |
| 908 | ofs = ofs + 1 | 904 | ofs += 1 |
| 909 | ctx.start = ofs | 905 | ctx.start = ofs |
| 910 | ctx.pos = ofs | 906 | ctx.pos = ofs |
| 911 | ctx.stop = stop | 907 | ctx.stop = stop |
| @@ -913,7 +909,7 @@ local function disass_block(ctx, ofs, len) | |||
| 913 | ctx.mrm = false | 909 | ctx.mrm = false |
| 914 | clearprefixes(ctx) | 910 | clearprefixes(ctx) |
| 915 | while ctx.pos <= stop do dispatchmap(ctx, ctx.map1) end | 911 | while ctx.pos <= stop do dispatchmap(ctx, ctx.map1) end |
| 916 | if ctx.pos ~= ctx.start then incomplete(ctx) end | 912 | if ctx.pos != ctx.start then incomplete(ctx) end |
| 917 | end | 913 | end |
| 918 | 914 | ||
| 919 | -- Extended API: create a disassembler context. Then call ctx:disass(ofs, len). | 915 | -- Extended API: create a disassembler context. Then call ctx:disass(ofs, len). |
