diff options
| author | Mike Pall <mike> | 2012-07-08 16:25:38 +0200 |
|---|---|---|
| committer | Mike Pall <mike> | 2012-07-08 16:27:18 +0200 |
| commit | c00ffcb870cd51849ee2a0f1bf1862ac965026b7 (patch) | |
| tree | e9af978c9883e709b1b5e5a845ce8ef5b6d0c490 | |
| parent | e3dec0438d50dbdf0184078d4e0233e399725787 (diff) | |
| download | luajit-c00ffcb870cd51849ee2a0f1bf1862ac965026b7.tar.gz luajit-c00ffcb870cd51849ee2a0f1bf1862ac965026b7.tar.bz2 luajit-c00ffcb870cd51849ee2a0f1bf1862ac965026b7.zip | |
Change DynASM bit operations to use Lua BitOp.
| -rw-r--r-- | dynasm/dasm_arm.lua | 73 | ||||
| -rw-r--r-- | dynasm/dasm_mips.lua | 44 | ||||
| -rw-r--r-- | dynasm/dasm_ppc.lua | 66 | ||||
| -rw-r--r-- | dynasm/dasm_x86.lua | 52 | ||||
| -rw-r--r-- | src/Makefile | 2 |
5 files changed, 106 insertions, 131 deletions
diff --git a/dynasm/dasm_arm.lua b/dynasm/dasm_arm.lua index cc4fa177..4735f323 100644 --- a/dynasm/dasm_arm.lua +++ b/dynasm/dasm_arm.lua | |||
| @@ -26,6 +26,9 @@ local _s = string | |||
| 26 | local sub, format, byte, char = _s.sub, _s.format, _s.byte, _s.char | 26 | local sub, format, byte, char = _s.sub, _s.format, _s.byte, _s.char |
| 27 | local match, gmatch, gsub = _s.match, _s.gmatch, _s.gsub | 27 | local match, gmatch, gsub = _s.match, _s.gmatch, _s.gsub |
| 28 | local concat, sort, insert = table.concat, table.sort, table.insert | 28 | local concat, sort, insert = table.concat, table.sort, table.insert |
| 29 | local bit = bit or require("bit") | ||
| 30 | local band, shl, shr, sar = bit.band, bit.lshift, bit.rshift, bit.arshift | ||
| 31 | local ror, tohex = bit.ror, bit.tohex | ||
| 29 | 32 | ||
| 30 | -- Inherited tables and callbacks. | 33 | -- Inherited tables and callbacks. |
| 31 | local g_opt, g_arch | 34 | local g_opt, g_arch |
| @@ -60,11 +63,6 @@ local secpos = 1 | |||
| 60 | 63 | ||
| 61 | ------------------------------------------------------------------------------ | 64 | ------------------------------------------------------------------------------ |
| 62 | 65 | ||
| 63 | -- Return 8 digit hex number. | ||
| 64 | local function tohex(x) | ||
| 65 | return sub(format("%08x", x), -8) -- Avoid 64 bit portability problem in Lua. | ||
| 66 | end | ||
| 67 | |||
| 68 | -- Dump action names and numbers. | 66 | -- Dump action names and numbers. |
| 69 | local function dumpactions(out) | 67 | local function dumpactions(out) |
| 70 | out:write("DynASM encoding engine action codes:\n") | 68 | out:write("DynASM encoding engine action codes:\n") |
| @@ -483,8 +481,8 @@ local function parse_reglist(reglist) | |||
| 483 | if not reglist then werror("register list expected") end | 481 | if not reglist then werror("register list expected") end |
| 484 | local rr = 0 | 482 | local rr = 0 |
| 485 | for p in gmatch(reglist..",", "%s*([^,]*),") do | 483 | for p in gmatch(reglist..",", "%s*([^,]*),") do |
| 486 | local rbit = 2^parse_gpr(gsub(p, "%s+$", "")) | 484 | local rbit = shl(1, parse_gpr(gsub(p, "%s+$", ""))) |
| 487 | if ((rr - (rr % rbit)) / rbit) % 2 ~= 0 then | 485 | if band(rr, rbit) ~= 0 then |
| 488 | werror("duplicate register `"..p.."'") | 486 | werror("duplicate register `"..p.."'") |
| 489 | end | 487 | end |
| 490 | rr = rr + rbit | 488 | rr = rr + rbit |
| @@ -497,16 +495,14 @@ local function parse_imm(imm, bits, shift, scale, signed) | |||
| 497 | if not imm then werror("expected immediate operand") end | 495 | if not imm then werror("expected immediate operand") end |
| 498 | local n = tonumber(imm) | 496 | local n = tonumber(imm) |
| 499 | if n then | 497 | if n then |
| 500 | if n % 2^scale == 0 then | 498 | local m = sar(n, scale) |
| 501 | n = n / 2^scale | 499 | if shl(m, scale) == n then |
| 502 | if signed then | 500 | if signed then |
| 503 | if n >= 0 then | 501 | local s = sar(m, bits-1) |
| 504 | if n < 2^(bits-1) then return n*2^shift end | 502 | if s == 0 then return shl(m, shift) |
| 505 | else | 503 | elseif s == -1 then return shl(m + shl(1, bits), shift) end |
| 506 | if n >= -(2^(bits-1))-1 then return (n+2^bits)*2^shift end | ||
| 507 | end | ||
| 508 | else | 504 | else |
| 509 | if n >= 0 and n <= 2^bits-1 then return n*2^shift end | 505 | if sar(m, bits) == 0 then return shl(m, shift) end |
| 510 | end | 506 | end |
| 511 | end | 507 | end |
| 512 | werror("out of range immediate `"..imm.."'") | 508 | werror("out of range immediate `"..imm.."'") |
| @@ -519,11 +515,10 @@ end | |||
| 519 | local function parse_imm12(imm) | 515 | local function parse_imm12(imm) |
| 520 | local n = tonumber(imm) | 516 | local n = tonumber(imm) |
| 521 | if n then | 517 | if n then |
| 522 | local m = n | 518 | local m = band(n) |
| 523 | for i=0,-15,-1 do | 519 | for i=0,-15,-1 do |
| 524 | if m >= 0 and m <= 255 and n % 1 == 0 then return m + (i%16) * 256 end | 520 | if shr(m, 8) == 0 then return m + shl(band(i, 15), 8) end |
| 525 | local t = m % 4 | 521 | m = ror(m, 2) |
| 526 | m = (m - t) / 4 + t * 2^30 | ||
| 527 | end | 522 | end |
| 528 | werror("out of range immediate `"..imm.."'") | 523 | werror("out of range immediate `"..imm.."'") |
| 529 | else | 524 | else |
| @@ -537,10 +532,7 @@ local function parse_imm16(imm) | |||
| 537 | if not imm then werror("expected immediate operand") end | 532 | if not imm then werror("expected immediate operand") end |
| 538 | local n = tonumber(imm) | 533 | local n = tonumber(imm) |
| 539 | if n then | 534 | if n then |
| 540 | if n >= 0 and n <= 65535 and n % 1 == 0 then | 535 | if shr(n, 16) == 0 then return band(n, 0x0fff) + shl(band(n, 0xf000), 4) end |
| 541 | local t = n % 4096 | ||
| 542 | return (n - t) * 16 + t | ||
| 543 | end | ||
| 544 | werror("out of range immediate `"..imm.."'") | 536 | werror("out of range immediate `"..imm.."'") |
| 545 | else | 537 | else |
| 546 | waction("IMM16", 32*16, imm) | 538 | waction("IMM16", 32*16, imm) |
| @@ -555,7 +547,7 @@ local function parse_imm_load(imm, ext) | |||
| 555 | if n >= -255 and n <= 255 then | 547 | if n >= -255 and n <= 255 then |
| 556 | local up = 0x00800000 | 548 | local up = 0x00800000 |
| 557 | if n < 0 then n = -n; up = 0 end | 549 | if n < 0 then n = -n; up = 0 end |
| 558 | return (n-(n%16))*16+(n%16) + up | 550 | return shl(band(n, 0xf0), 4) + band(n, 0x0f) + up |
| 559 | end | 551 | end |
| 560 | else | 552 | else |
| 561 | if n >= -4095 and n <= 4095 then | 553 | if n >= -4095 and n <= 4095 then |
| @@ -565,7 +557,7 @@ local function parse_imm_load(imm, ext) | |||
| 565 | end | 557 | end |
| 566 | werror("out of range immediate `"..imm.."'") | 558 | werror("out of range immediate `"..imm.."'") |
| 567 | else | 559 | else |
| 568 | waction(ext and "IMML8" or "IMML12", 32768 + 32*(ext and 8 or 12), imm) | 560 | waction(ext and "IMML8" or "IMML12", 32768 + shl(ext and 8 or 12, 5), imm) |
| 569 | return 0 | 561 | return 0 |
| 570 | end | 562 | end |
| 571 | end | 563 | end |
| @@ -578,10 +570,10 @@ local function parse_shift(shift, gprok) | |||
| 578 | s = map_shift[s] | 570 | s = map_shift[s] |
| 579 | if not s then werror("expected shift operand") end | 571 | if not s then werror("expected shift operand") end |
| 580 | if sub(s2, 1, 1) == "#" then | 572 | if sub(s2, 1, 1) == "#" then |
| 581 | return parse_imm(s2, 5, 7, 0, false) + s * 32 | 573 | return parse_imm(s2, 5, 7, 0, false) + shl(s, 5) |
| 582 | else | 574 | else |
| 583 | if not gprok then werror("expected immediate shift operand") end | 575 | if not gprok then werror("expected immediate shift operand") end |
| 584 | return parse_gpr(s2) * 256 + s * 32 + 16 | 576 | return shl(parse_gpr(s2), 8) + shl(s, 5) + 16 |
| 585 | end | 577 | end |
| 586 | end | 578 | end |
| 587 | end | 579 | end |
| @@ -617,12 +609,12 @@ local function parse_label(label, def) | |||
| 617 | end | 609 | end |
| 618 | 610 | ||
| 619 | local function parse_load(params, nparams, n, op) | 611 | local function parse_load(params, nparams, n, op) |
| 620 | local oplo = op % 256 | 612 | local oplo = band(op, 255) |
| 621 | local ext, ldrd = (oplo ~= 0), (oplo == 208) | 613 | local ext, ldrd = (oplo ~= 0), (oplo == 208) |
| 622 | local d | 614 | local d |
| 623 | if (ldrd or oplo == 240) then | 615 | if (ldrd or oplo == 240) then |
| 624 | d = ((op - (op % 4096)) / 4096) % 16 | 616 | d = band(shr(op, 12), 15) |
| 625 | if d % 2 ~= 0 then werror("odd destination register") end | 617 | if band(d, 1) ~= 0 then werror("odd destination register") end |
| 626 | end | 618 | end |
| 627 | local pn = params[n] | 619 | local pn = params[n] |
| 628 | local p1, wb = match(pn, "^%[%s*(.-)%s*%](!?)$") | 620 | local p1, wb = match(pn, "^%[%s*(.-)%s*%](!?)$") |
| @@ -640,7 +632,7 @@ local function parse_load(params, nparams, n, op) | |||
| 640 | if tp then | 632 | if tp then |
| 641 | waction(ext and "IMML8" or "IMML12", 32768 + 32*(ext and 8 or 12), | 633 | waction(ext and "IMML8" or "IMML12", 32768 + 32*(ext and 8 or 12), |
| 642 | format(tp.ctypefmt, tailr)) | 634 | format(tp.ctypefmt, tailr)) |
| 643 | return op + d * 65536 + 0x01000000 + (ext and 0x00400000 or 0) | 635 | return op + shl(d, 16) + 0x01000000 + (ext and 0x00400000 or 0) |
| 644 | end | 636 | end |
| 645 | end | 637 | end |
| 646 | end | 638 | end |
| @@ -650,7 +642,7 @@ local function parse_load(params, nparams, n, op) | |||
| 650 | if p2 then | 642 | if p2 then |
| 651 | if wb == "!" then werror("bad use of '!'") end | 643 | if wb == "!" then werror("bad use of '!'") end |
| 652 | local p3 = params[n+2] | 644 | local p3 = params[n+2] |
| 653 | op = op + parse_gpr(p1) * 65536 | 645 | op = op + shl(parse_gpr(p1), 16) |
| 654 | local imm = match(p2, "^#(.*)$") | 646 | local imm = match(p2, "^#(.*)$") |
| 655 | if imm then | 647 | if imm then |
| 656 | local m = parse_imm_load(imm, ext) | 648 | local m = parse_imm_load(imm, ext) |
| @@ -664,7 +656,7 @@ local function parse_load(params, nparams, n, op) | |||
| 664 | end | 656 | end |
| 665 | else | 657 | else |
| 666 | local p1a, p2 = match(p1, "^([^,%s]*)%s*(.*)$") | 658 | local p1a, p2 = match(p1, "^([^,%s]*)%s*(.*)$") |
| 667 | op = op + parse_gpr(p1a) * 65536 + 0x01000000 | 659 | op = op + shl(parse_gpr(p1a), 16) + 0x01000000 |
| 668 | if p2 ~= "" then | 660 | if p2 ~= "" then |
| 669 | local imm = match(p2, "^,%s*#(.*)$") | 661 | local imm = match(p2, "^,%s*#(.*)$") |
| 670 | if imm then | 662 | if imm then |
| @@ -704,11 +696,11 @@ map_op[".template__"] = function(params, template, nparams) | |||
| 704 | -- Process each character. | 696 | -- Process each character. |
| 705 | for p in gmatch(sub(template, 9), ".") do | 697 | for p in gmatch(sub(template, 9), ".") do |
| 706 | if p == "D" then | 698 | if p == "D" then |
| 707 | op = op + parse_gpr(params[n]) * 4096; n = n + 1 | 699 | op = op + shl(parse_gpr(params[n]), 12); n = n + 1 |
| 708 | elseif p == "N" then | 700 | elseif p == "N" then |
| 709 | op = op + parse_gpr(params[n]) * 65536; n = n + 1 | 701 | op = op + shl(parse_gpr(params[n]), 16); n = n + 1 |
| 710 | elseif p == "S" then | 702 | elseif p == "S" then |
| 711 | op = op + parse_gpr(params[n]) * 256; n = n + 1 | 703 | op = op + shl(parse_gpr(params[n]), 8); n = n + 1 |
| 712 | elseif p == "M" then | 704 | elseif p == "M" then |
| 713 | op = op + parse_gpr(params[n]); n = n + 1 | 705 | op = op + parse_gpr(params[n]); n = n + 1 |
| 714 | elseif p == "P" then | 706 | elseif p == "P" then |
| @@ -738,7 +730,7 @@ map_op[".template__"] = function(params, template, nparams) | |||
| 738 | end | 730 | end |
| 739 | elseif p == "n" then | 731 | elseif p == "n" then |
| 740 | local r, wb = match(params[n], "^([^!]*)(!?)$") | 732 | local r, wb = match(params[n], "^([^!]*)(!?)$") |
| 741 | op = op + parse_gpr(r) * 65536 + (wb == "!" and 0x00200000 or 0) | 733 | op = op + shl(parse_gpr(r), 16) + (wb == "!" and 0x00200000 or 0) |
| 742 | n = n + 1 | 734 | n = n + 1 |
| 743 | elseif p == "R" then | 735 | elseif p == "R" then |
| 744 | op = op + parse_reglist(params[n]); n = n + 1 | 736 | op = op + parse_reglist(params[n]); n = n + 1 |
| @@ -751,17 +743,16 @@ map_op[".template__"] = function(params, template, nparams) | |||
| 751 | if imm then | 743 | if imm then |
| 752 | op = op + parse_imm(params[n], 5, 7, 0, false); n = n + 1 | 744 | op = op + parse_imm(params[n], 5, 7, 0, false); n = n + 1 |
| 753 | else | 745 | else |
| 754 | op = op + parse_gpr(params[n]) * 256 + 16 | 746 | op = op + shl(parse_gpr(params[n]), 8) + 16 |
| 755 | end | 747 | end |
| 756 | elseif p == "X" then | 748 | elseif p == "X" then |
| 757 | op = op + parse_imm(params[n], 5, 16, 0, false); n = n + 1 | 749 | op = op + parse_imm(params[n], 5, 16, 0, false); n = n + 1 |
| 758 | elseif p == "K" then | 750 | elseif p == "K" then |
| 759 | local imm = tonumber(match(params[n], "^#(.*)$")); n = n + 1 | 751 | local imm = tonumber(match(params[n], "^#(.*)$")); n = n + 1 |
| 760 | if not imm or imm % 1 ~= 0 or imm < 0 or imm > 0xffff then | 752 | if not imm or shr(imm, 16) ~= 0 then |
| 761 | werror("bad immediate operand") | 753 | werror("bad immediate operand") |
| 762 | end | 754 | end |
| 763 | local t = imm % 16 | 755 | op = op + shl(band(imm, 0xfff0), 4) + band(imm, 0x000f) |
| 764 | op = op + (imm - t) * 16 + t | ||
| 765 | elseif p == "T" then | 756 | elseif p == "T" then |
| 766 | op = op + parse_imm(params[n], 24, 0, 0, false); n = n + 1 | 757 | op = op + parse_imm(params[n], 24, 0, 0, false); n = n + 1 |
| 767 | elseif p == "s" then | 758 | elseif p == "s" then |
diff --git a/dynasm/dasm_mips.lua b/dynasm/dasm_mips.lua index aa33f0cc..c387d292 100644 --- a/dynasm/dasm_mips.lua +++ b/dynasm/dasm_mips.lua | |||
| @@ -26,6 +26,8 @@ local _s = string | |||
| 26 | local sub, format, byte, char = _s.sub, _s.format, _s.byte, _s.char | 26 | local sub, format, byte, char = _s.sub, _s.format, _s.byte, _s.char |
| 27 | local match, gmatch = _s.match, _s.gmatch | 27 | local match, gmatch = _s.match, _s.gmatch |
| 28 | local concat, sort = table.concat, table.sort | 28 | local concat, sort = table.concat, table.sort |
| 29 | local bit = bit or require("bit") | ||
| 30 | local band, shl, sar, tohex = bit.band, bit.lshift, bit.arshift, bit.tohex | ||
| 29 | 31 | ||
| 30 | -- Inherited tables and callbacks. | 32 | -- Inherited tables and callbacks. |
| 31 | local g_opt, g_arch | 33 | local g_opt, g_arch |
| @@ -60,11 +62,6 @@ local secpos = 1 | |||
| 60 | 62 | ||
| 61 | ------------------------------------------------------------------------------ | 63 | ------------------------------------------------------------------------------ |
| 62 | 64 | ||
| 63 | -- Return 8 digit hex number. | ||
| 64 | local function tohex(x) | ||
| 65 | return sub(format("%08x", x), -8) -- Avoid 64 bit portability problem in Lua. | ||
| 66 | end | ||
| 67 | |||
| 68 | -- Dump action names and numbers. | 65 | -- Dump action names and numbers. |
| 69 | local function dumpactions(out) | 66 | local function dumpactions(out) |
| 70 | out:write("DynASM encoding engine action codes:\n") | 67 | out:write("DynASM encoding engine action codes:\n") |
| @@ -639,16 +636,14 @@ end | |||
| 639 | local function parse_imm(imm, bits, shift, scale, signed) | 636 | local function parse_imm(imm, bits, shift, scale, signed) |
| 640 | local n = tonumber(imm) | 637 | local n = tonumber(imm) |
| 641 | if n then | 638 | if n then |
| 642 | if n % 2^scale == 0 then | 639 | local m = sar(n, scale) |
| 643 | n = n / 2^scale | 640 | if shl(m, scale) == n then |
| 644 | if signed then | 641 | if signed then |
| 645 | if n >= 0 then | 642 | local s = sar(m, bits-1) |
| 646 | if n < 2^(bits-1) then return n*2^shift end | 643 | if s == 0 then return shl(m, shift) |
| 647 | else | 644 | elseif s == -1 then return shl(m + shl(1, bits), shift) end |
| 648 | if n >= -(2^(bits-1))-1 then return (n+2^bits)*2^shift end | ||
| 649 | end | ||
| 650 | else | 645 | else |
| 651 | if n >= 0 and n <= 2^bits-1 then return n*2^shift end | 646 | if sar(m, bits) == 0 then return shl(m, shift) end |
| 652 | end | 647 | end |
| 653 | end | 648 | end |
| 654 | werror("out of range immediate `"..imm.."'") | 649 | werror("out of range immediate `"..imm.."'") |
| @@ -664,7 +659,7 @@ end | |||
| 664 | local function parse_disp(disp) | 659 | local function parse_disp(disp) |
| 665 | local imm, reg = match(disp, "^(.*)%(([%w_:]+)%)$") | 660 | local imm, reg = match(disp, "^(.*)%(([%w_:]+)%)$") |
| 666 | if imm then | 661 | if imm then |
| 667 | local r = parse_gpr(reg)*2^21 | 662 | local r = shl(parse_gpr(reg), 21) |
| 668 | local extname = match(imm, "^extern%s+(%S+)$") | 663 | local extname = match(imm, "^extern%s+(%S+)$") |
| 669 | if extname then | 664 | if extname then |
| 670 | waction("REL_EXT", map_extern[extname], nil, 1) | 665 | waction("REL_EXT", map_extern[extname], nil, 1) |
| @@ -678,7 +673,7 @@ local function parse_disp(disp) | |||
| 678 | local r, tp = parse_gpr(reg) | 673 | local r, tp = parse_gpr(reg) |
| 679 | if tp then | 674 | if tp then |
| 680 | waction("IMM", 32768+16*32, format(tp.ctypefmt, tailr)) | 675 | waction("IMM", 32768+16*32, format(tp.ctypefmt, tailr)) |
| 681 | return r*2^21 | 676 | return shl(r, 21) |
| 682 | end | 677 | end |
| 683 | end | 678 | end |
| 684 | werror("bad displacement `"..disp.."'") | 679 | werror("bad displacement `"..disp.."'") |
| @@ -689,7 +684,7 @@ local function parse_index(idx) | |||
| 689 | if rt then | 684 | if rt then |
| 690 | rt = parse_gpr(rt) | 685 | rt = parse_gpr(rt) |
| 691 | rs = parse_gpr(rs) | 686 | rs = parse_gpr(rs) |
| 692 | return rt*2^16 + rs*2^21 | 687 | return shl(rt, 16) + shl(rs, 21) |
| 693 | end | 688 | end |
| 694 | werror("bad index `"..idx.."'") | 689 | werror("bad index `"..idx.."'") |
| 695 | end | 690 | end |
| @@ -740,19 +735,19 @@ map_op[".template__"] = function(params, template, nparams) | |||
| 740 | -- Process each character. | 735 | -- Process each character. |
| 741 | for p in gmatch(sub(template, 9), ".") do | 736 | for p in gmatch(sub(template, 9), ".") do |
| 742 | if p == "D" then | 737 | if p == "D" then |
| 743 | op = op + parse_gpr(params[n]) * 2^11; n = n + 1 | 738 | op = op + shl(parse_gpr(params[n]), 11); n = n + 1 |
| 744 | elseif p == "T" then | 739 | elseif p == "T" then |
| 745 | op = op + parse_gpr(params[n]) * 2^16; n = n + 1 | 740 | op = op + shl(parse_gpr(params[n]), 16); n = n + 1 |
| 746 | elseif p == "S" then | 741 | elseif p == "S" then |
| 747 | op = op + parse_gpr(params[n]) * 2^21; n = n + 1 | 742 | op = op + shl(parse_gpr(params[n]), 21); n = n + 1 |
| 748 | elseif p == "F" then | 743 | elseif p == "F" then |
| 749 | op = op + parse_fpr(params[n]) * 2^6; n = n + 1 | 744 | op = op + shl(parse_fpr(params[n]), 6); n = n + 1 |
| 750 | elseif p == "G" then | 745 | elseif p == "G" then |
| 751 | op = op + parse_fpr(params[n]) * 2^11; n = n + 1 | 746 | op = op + shl(parse_fpr(params[n]), 11); n = n + 1 |
| 752 | elseif p == "H" then | 747 | elseif p == "H" then |
| 753 | op = op + parse_fpr(params[n]) * 2^16; n = n + 1 | 748 | op = op + shl(parse_fpr(params[n]), 16); n = n + 1 |
| 754 | elseif p == "R" then | 749 | elseif p == "R" then |
| 755 | op = op + parse_fpr(params[n]) * 2^21; n = n + 1 | 750 | op = op + shl(parse_fpr(params[n]), 21); n = n + 1 |
| 756 | elseif p == "I" then | 751 | elseif p == "I" then |
| 757 | op = op + parse_imm(params[n], 16, 0, 0, true); n = n + 1 | 752 | op = op + parse_imm(params[n], 16, 0, 0, true); n = n + 1 |
| 758 | elseif p == "U" then | 753 | elseif p == "U" then |
| @@ -783,8 +778,7 @@ map_op[".template__"] = function(params, template, nparams) | |||
| 783 | elseif p == "Z" then | 778 | elseif p == "Z" then |
| 784 | op = op + parse_imm(params[n], 10, 6, 0, false); n = n + 1 | 779 | op = op + parse_imm(params[n], 10, 6, 0, false); n = n + 1 |
| 785 | elseif p == "=" then | 780 | elseif p == "=" then |
| 786 | local d = ((op - op % 2^11) / 2^11) % 32 | 781 | op = op + shl(band(op, 0xf800), 5) -- Copy D to T for clz, clo. |
| 787 | op = op + d * 2^16 -- Copy D to T for clz, clo. | ||
| 788 | else | 782 | else |
| 789 | assert(false) | 783 | assert(false) |
| 790 | end | 784 | end |
diff --git a/dynasm/dasm_ppc.lua b/dynasm/dasm_ppc.lua index 7d64d81c..020ef0d9 100644 --- a/dynasm/dasm_ppc.lua +++ b/dynasm/dasm_ppc.lua | |||
| @@ -26,6 +26,9 @@ local _s = string | |||
| 26 | local sub, format, byte, char = _s.sub, _s.format, _s.byte, _s.char | 26 | local sub, format, byte, char = _s.sub, _s.format, _s.byte, _s.char |
| 27 | local match, gmatch = _s.match, _s.gmatch | 27 | local match, gmatch = _s.match, _s.gmatch |
| 28 | local concat, sort = table.concat, table.sort | 28 | local concat, sort = table.concat, table.sort |
| 29 | local bit = bit or require("bit") | ||
| 30 | local band, shl, shr, sar = bit.band, bit.lshift, bit.rshift, bit.arshift | ||
| 31 | local tohex = bit.tohex | ||
| 29 | 32 | ||
| 30 | -- Inherited tables and callbacks. | 33 | -- Inherited tables and callbacks. |
| 31 | local g_opt, g_arch | 34 | local g_opt, g_arch |
| @@ -60,11 +63,6 @@ local secpos = 1 | |||
| 60 | 63 | ||
| 61 | ------------------------------------------------------------------------------ | 64 | ------------------------------------------------------------------------------ |
| 62 | 65 | ||
| 63 | -- Return 8 digit hex number. | ||
| 64 | local function tohex(x) | ||
| 65 | return sub(format("%08x", x), -8) -- Avoid 64 bit portability problem in Lua. | ||
| 66 | end | ||
| 67 | |||
| 68 | -- Dump action names and numbers. | 66 | -- Dump action names and numbers. |
| 69 | local function dumpactions(out) | 67 | local function dumpactions(out) |
| 70 | out:write("DynASM encoding engine action codes:\n") | 68 | out:write("DynASM encoding engine action codes:\n") |
| @@ -837,7 +835,7 @@ end | |||
| 837 | -- Add more branch mnemonics. | 835 | -- Add more branch mnemonics. |
| 838 | for cond,c in pairs(map_cond) do | 836 | for cond,c in pairs(map_cond) do |
| 839 | local b1 = "b"..cond | 837 | local b1 = "b"..cond |
| 840 | local c1 = (c%4)*0x00010000 + (c < 4 and 0x01000000 or 0) | 838 | local c1 = shl(band(c, 3), 16) + (c < 4 and 0x01000000 or 0) |
| 841 | -- bX[l] | 839 | -- bX[l] |
| 842 | map_op[b1.."_1"] = tohex(0x40800000 + c1).."K" | 840 | map_op[b1.."_1"] = tohex(0x40800000 + c1).."K" |
| 843 | map_op[b1.."y_1"] = tohex(0x40a00000 + c1).."K" | 841 | map_op[b1.."y_1"] = tohex(0x40a00000 + c1).."K" |
| @@ -905,16 +903,14 @@ end | |||
| 905 | local function parse_imm(imm, bits, shift, scale, signed) | 903 | local function parse_imm(imm, bits, shift, scale, signed) |
| 906 | local n = tonumber(imm) | 904 | local n = tonumber(imm) |
| 907 | if n then | 905 | if n then |
| 908 | if n % 2^scale == 0 then | 906 | local m = sar(n, scale) |
| 909 | n = n / 2^scale | 907 | if shl(m, scale) == n then |
| 910 | if signed then | 908 | if signed then |
| 911 | if n >= 0 then | 909 | local s = sar(m, bits-1) |
| 912 | if n < 2^(bits-1) then return n*2^shift end | 910 | if s == 0 then return shl(m, shift) |
| 913 | else | 911 | elseif s == -1 then return shl(m + shl(1, bits), shift) end |
| 914 | if n >= -(2^(bits-1))-1 then return (n+2^bits)*2^shift end | ||
| 915 | end | ||
| 916 | else | 912 | else |
| 917 | if n >= 0 and n <= 2^bits-1 then return n*2^shift end | 913 | if sar(m, bits) == 0 then return shl(m, shift) end |
| 918 | end | 914 | end |
| 919 | end | 915 | end |
| 920 | werror("out of range immediate `"..imm.."'") | 916 | werror("out of range immediate `"..imm.."'") |
| @@ -930,10 +926,10 @@ end | |||
| 930 | local function parse_shiftmask(imm, isshift) | 926 | local function parse_shiftmask(imm, isshift) |
| 931 | local n = tonumber(imm) | 927 | local n = tonumber(imm) |
| 932 | if n then | 928 | if n then |
| 933 | if n % 1 == 0 and n >= 0 and n <= 63 then | 929 | if shr(n, 6) == 0 then |
| 934 | local lsb = imm % 32 | 930 | local lsb = band(imm, 31) |
| 935 | local msb = imm - lsb | 931 | local msb = imm - lsb |
| 936 | return isshift and (lsb*2048+msb/16) or (lsb*64+msb) | 932 | return isshift and (shl(lsb, 11)+shr(msb, 4)) or (shl(lsb, 6)+msb) |
| 937 | end | 933 | end |
| 938 | werror("out of range immediate `"..imm.."'") | 934 | werror("out of range immediate `"..imm.."'") |
| 939 | elseif match(imm, "^r([1-3]?[0-9])$") or | 935 | elseif match(imm, "^r([1-3]?[0-9])$") or |
| @@ -949,7 +945,7 @@ local function parse_disp(disp) | |||
| 949 | if imm then | 945 | if imm then |
| 950 | local r = parse_gpr(reg) | 946 | local r = parse_gpr(reg) |
| 951 | if r == 0 then werror("cannot use r0 in displacement") end | 947 | if r == 0 then werror("cannot use r0 in displacement") end |
| 952 | return r*65536 + parse_imm(imm, 16, 0, 0, true) | 948 | return shl(r, 16) + parse_imm(imm, 16, 0, 0, true) |
| 953 | end | 949 | end |
| 954 | local reg, tailr = match(disp, "^([%w_:]+)%s*(.*)$") | 950 | local reg, tailr = match(disp, "^([%w_:]+)%s*(.*)$") |
| 955 | if reg and tailr ~= "" then | 951 | if reg and tailr ~= "" then |
| @@ -957,7 +953,7 @@ local function parse_disp(disp) | |||
| 957 | if r == 0 then werror("cannot use r0 in displacement") end | 953 | if r == 0 then werror("cannot use r0 in displacement") end |
| 958 | if tp then | 954 | if tp then |
| 959 | waction("IMM", 32768+16*32, format(tp.ctypefmt, tailr)) | 955 | waction("IMM", 32768+16*32, format(tp.ctypefmt, tailr)) |
| 960 | return r*65536 | 956 | return shl(r, 16) |
| 961 | end | 957 | end |
| 962 | end | 958 | end |
| 963 | werror("bad displacement `"..disp.."'") | 959 | werror("bad displacement `"..disp.."'") |
| @@ -968,7 +964,7 @@ local function parse_u5disp(disp, scale) | |||
| 968 | if imm then | 964 | if imm then |
| 969 | local r = parse_gpr(reg) | 965 | local r = parse_gpr(reg) |
| 970 | if r == 0 then werror("cannot use r0 in displacement") end | 966 | if r == 0 then werror("cannot use r0 in displacement") end |
| 971 | return r*65536 + parse_imm(imm, 5, 11, scale, false) | 967 | return shl(r, 16) + parse_imm(imm, 5, 11, scale, false) |
| 972 | end | 968 | end |
| 973 | local reg, tailr = match(disp, "^([%w_:]+)%s*(.*)$") | 969 | local reg, tailr = match(disp, "^([%w_:]+)%s*(.*)$") |
| 974 | if reg and tailr ~= "" then | 970 | if reg and tailr ~= "" then |
| @@ -976,7 +972,7 @@ local function parse_u5disp(disp, scale) | |||
| 976 | if r == 0 then werror("cannot use r0 in displacement") end | 972 | if r == 0 then werror("cannot use r0 in displacement") end |
| 977 | if tp then | 973 | if tp then |
| 978 | waction("IMM", scale*1024+5*32+11, format(tp.ctypefmt, tailr)) | 974 | waction("IMM", scale*1024+5*32+11, format(tp.ctypefmt, tailr)) |
| 979 | return r*65536 | 975 | return shl(r, 16) |
| 980 | end | 976 | end |
| 981 | end | 977 | end |
| 982 | werror("bad displacement `"..disp.."'") | 978 | werror("bad displacement `"..disp.."'") |
| @@ -1028,9 +1024,9 @@ map_op[".template__"] = function(params, template, nparams) | |||
| 1028 | -- Process each character. | 1024 | -- Process each character. |
| 1029 | for p in gmatch(sub(template, 9), ".") do | 1025 | for p in gmatch(sub(template, 9), ".") do |
| 1030 | if p == "R" then | 1026 | if p == "R" then |
| 1031 | rs = rs - 5; op = op + parse_gpr(params[n]) * 2^rs; n = n + 1 | 1027 | rs = rs - 5; op = op + shl(parse_gpr(params[n]), rs); n = n + 1 |
| 1032 | elseif p == "F" then | 1028 | elseif p == "F" then |
| 1033 | rs = rs - 5; op = op + parse_fpr(params[n]) * 2^rs; n = n + 1 | 1029 | rs = rs - 5; op = op + shl(parse_fpr(params[n]), rs); n = n + 1 |
| 1034 | elseif p == "A" then | 1030 | elseif p == "A" then |
| 1035 | rs = rs - 5; op = op + parse_imm(params[n], 5, rs, 0, false); n = n + 1 | 1031 | rs = rs - 5; op = op + parse_imm(params[n], 5, rs, 0, false); n = n + 1 |
| 1036 | elseif p == "S" then | 1032 | elseif p == "S" then |
| @@ -1048,9 +1044,9 @@ map_op[".template__"] = function(params, template, nparams) | |||
| 1048 | elseif p == "8" then | 1044 | elseif p == "8" then |
| 1049 | op = op + parse_u5disp(params[n], 3); n = n + 1 | 1045 | op = op + parse_u5disp(params[n], 3); n = n + 1 |
| 1050 | elseif p == "C" then | 1046 | elseif p == "C" then |
| 1051 | rs = rs - 5; op = op + parse_cond(params[n]) * 2^rs; n = n + 1 | 1047 | rs = rs - 5; op = op + shl(parse_cond(params[n]), rs); n = n + 1 |
| 1052 | elseif p == "X" then | 1048 | elseif p == "X" then |
| 1053 | rs = rs - 5; op = op + parse_cr(params[n]) * 2^(rs+2); n = n + 1 | 1049 | rs = rs - 5; op = op + shl(parse_cr(params[n]), rs+2); n = n + 1 |
| 1054 | elseif p == "W" then | 1050 | elseif p == "W" then |
| 1055 | op = op + parse_cr(params[n]); n = n + 1 | 1051 | op = op + parse_cr(params[n]); n = n + 1 |
| 1056 | elseif p == "G" then | 1052 | elseif p == "G" then |
| @@ -1065,22 +1061,16 @@ map_op[".template__"] = function(params, template, nparams) | |||
| 1065 | waction("REL_"..mode, n, s, 1) | 1061 | waction("REL_"..mode, n, s, 1) |
| 1066 | n = n + 1 | 1062 | n = n + 1 |
| 1067 | elseif p == "0" then | 1063 | elseif p == "0" then |
| 1068 | local mm = 2^rs | 1064 | if band(shr(op, rs), 31) == 0 then werror("cannot use r0") end |
| 1069 | local t = op % mm | ||
| 1070 | if ((op - t) / mm) % 32 == 0 then werror("cannot use r0") end | ||
| 1071 | elseif p == "=" or p == "%" then | 1065 | elseif p == "=" or p == "%" then |
| 1072 | local mm = 2^(rs + (p == "%" and 5 or 0)) | 1066 | local t = band(shr(op, p == "%" and rs+5 or rs), 31) |
| 1073 | local t = ((op - op % mm) / mm) % 32 | ||
| 1074 | rs = rs - 5 | 1067 | rs = rs - 5 |
| 1075 | op = op + t * 2^rs | 1068 | op = op + shl(t, rs) |
| 1076 | elseif p == "~" then | 1069 | elseif p == "~" then |
| 1077 | local mm = 2^rs | 1070 | local mm = shl(31, rs) |
| 1078 | local t1l = op % mm | 1071 | local lo = band(op, mm) |
| 1079 | local t1h = (op - t1l) / mm | 1072 | local hi = band(op, shl(mm, 5)) |
| 1080 | local t2l = t1h % 32 | 1073 | op = op - lo - hi + shl(lo, 5) + shr(hi, 5) |
| 1081 | local t2h = (t1h - t2l) / 32 | ||
| 1082 | local t3l = t2h % 32 | ||
| 1083 | op = ((t2h - t3l + t2l)*32 + t3l)*mm + t1l | ||
| 1084 | elseif p == "-" then | 1074 | elseif p == "-" then |
| 1085 | rs = rs - 5 | 1075 | rs = rs - 5 |
| 1086 | elseif p == "." then | 1076 | elseif p == "." then |
diff --git a/dynasm/dasm_x86.lua b/dynasm/dasm_x86.lua index 3bebb83c..a5f5c37d 100644 --- a/dynasm/dasm_x86.lua +++ b/dynasm/dasm_x86.lua | |||
| @@ -28,6 +28,8 @@ local _s = string | |||
| 28 | local sub, format, byte, char = _s.sub, _s.format, _s.byte, _s.char | 28 | local sub, format, byte, char = _s.sub, _s.format, _s.byte, _s.char |
| 29 | local find, match, gmatch, gsub = _s.find, _s.match, _s.gmatch, _s.gsub | 29 | local find, match, gmatch, gsub = _s.find, _s.match, _s.gmatch, _s.gsub |
| 30 | local concat, sort = table.concat, table.sort | 30 | local concat, sort = table.concat, table.sort |
| 31 | local bit = bit or require("bit") | ||
| 32 | local band, shl, shr = bit.band, bit.lshift, bit.rshift | ||
| 31 | 33 | ||
| 32 | -- Inherited tables and callbacks. | 34 | -- Inherited tables and callbacks. |
| 33 | local g_opt, g_arch | 35 | local g_opt, g_arch |
| @@ -426,10 +428,10 @@ end | |||
| 426 | -- Put unsigned word or arg. | 428 | -- Put unsigned word or arg. |
| 427 | local function wputwarg(n) | 429 | local function wputwarg(n) |
| 428 | if type(n) == "number" then | 430 | if type(n) == "number" then |
| 429 | if n < 0 or n > 65535 then | 431 | if shr(n, 16) ~= 0 then |
| 430 | werror("unsigned immediate word out of range") | 432 | werror("unsigned immediate word out of range") |
| 431 | end | 433 | end |
| 432 | local r = n%256; n = (n-r)/256; wputb(r); wputb(n); | 434 | wputb(band(n, 255)); wputb(shr(n, 8)); |
| 433 | else waction("IMM_W", n) end | 435 | else waction("IMM_W", n) end |
| 434 | end | 436 | end |
| 435 | 437 | ||
| @@ -437,10 +439,10 @@ end | |||
| 437 | local function wputdarg(n) | 439 | local function wputdarg(n) |
| 438 | local tn = type(n) | 440 | local tn = type(n) |
| 439 | if tn == "number" then | 441 | if tn == "number" then |
| 440 | if n < 0 then n = n + 4294967296 end | 442 | wputb(band(n, 255)) |
| 441 | local r = n%256; n = (n-r)/256; wputb(r); | 443 | wputb(band(shr(n, 8), 255)) |
| 442 | r = n%256; n = (n-r)/256; wputb(r); | 444 | wputb(band(shr(n, 16), 255)) |
| 443 | r = n%256; n = (n-r)/256; wputb(r); wputb(n); | 445 | wputb(shr(n, 24)) |
| 444 | elseif tn == "table" then | 446 | elseif tn == "table" then |
| 445 | wputlabel("IMM_", n[1], 1) | 447 | wputlabel("IMM_", n[1], 1) |
| 446 | else | 448 | else |
| @@ -464,24 +466,23 @@ local function wputop(sz, op, rex) | |||
| 464 | if sz == "w" then wputb(102) end | 466 | if sz == "w" then wputb(102) end |
| 465 | -- Needs >32 bit numbers, but only for crc32 eax, word [ebx] | 467 | -- Needs >32 bit numbers, but only for crc32 eax, word [ebx] |
| 466 | if op >= 4294967296 then r = op%4294967296 wputb((op-r)/4294967296) op = r end | 468 | if op >= 4294967296 then r = op%4294967296 wputb((op-r)/4294967296) op = r end |
| 467 | if op >= 16777216 then r = op % 16777216 wputb((op-r) / 16777216) op = r end | 469 | if op >= 16777216 then wputb(shr(op, 24)); op = band(op, 0xffffff) end |
| 468 | if op >= 65536 then | 470 | if op >= 65536 then |
| 469 | if rex ~= 0 then | 471 | if rex ~= 0 then |
| 470 | local opc3 = op - op % 256 | 472 | local opc3 = band(op, 0xffff00) |
| 471 | if opc3 == 0x0f3a00 or opc3 == 0x0f3800 then | 473 | if opc3 == 0x0f3a00 or opc3 == 0x0f3800 then |
| 472 | wputb(64 + rex % 16); rex = 0 | 474 | wputb(64 + band(rex, 15)); rex = 0 |
| 473 | end | 475 | end |
| 474 | end | 476 | end |
| 475 | r = op % 65536 wputb((op-r) / 65536) op = r | 477 | wputb(shr(op, 16)); op = band(op, 0xffff) |
| 476 | end | 478 | end |
| 477 | if op >= 256 then | 479 | if op >= 256 then |
| 478 | r = op % 256 | 480 | local b = shr(op, 8) |
| 479 | local b = (op-r) / 256 | 481 | if b == 15 and rex ~= 0 then wputb(64 + band(rex, 15)); rex = 0 end |
| 480 | if b == 15 and rex ~= 0 then wputb(64 + rex % 16); rex = 0 end | ||
| 481 | wputb(b) | 482 | wputb(b) |
| 482 | op = r | 483 | op = band(op, 255) |
| 483 | end | 484 | end |
| 484 | if rex ~= 0 then wputb(64 + rex % 16) end | 485 | if rex ~= 0 then wputb(64 + band(rex, 15)) end |
| 485 | if sz == "b" then op = op - 1 end | 486 | if sz == "b" then op = op - 1 end |
| 486 | wputb(op) | 487 | wputb(op) |
| 487 | end | 488 | end |
| @@ -489,7 +490,7 @@ end | |||
| 489 | -- Put ModRM or SIB formatted byte. | 490 | -- Put ModRM or SIB formatted byte. |
| 490 | local function wputmodrm(m, s, rm, vs, vrm) | 491 | local function wputmodrm(m, s, rm, vs, vrm) |
| 491 | assert(m < 4 and s < 16 and rm < 16, "bad modrm operands") | 492 | assert(m < 4 and s < 16 and rm < 16, "bad modrm operands") |
| 492 | wputb(64*m + 8*(s%8) + (rm%8)) | 493 | wputb(shl(m, 6) + shl(band(s, 7), 3) + band(rm, 7)) |
| 493 | end | 494 | end |
| 494 | 495 | ||
| 495 | -- Put ModRM/SIB plus optional displacement. | 496 | -- Put ModRM/SIB plus optional displacement. |
| @@ -548,7 +549,7 @@ local function wputmrmsib(t, imark, s, vsreg) | |||
| 548 | 549 | ||
| 549 | local m | 550 | local m |
| 550 | if tdisp == "number" then -- Check displacement size at assembly time. | 551 | if tdisp == "number" then -- Check displacement size at assembly time. |
| 551 | if disp == 0 and (reg%8) ~= 5 then -- [ebp] -> [ebp+0] (in SIB, too) | 552 | if disp == 0 and band(reg, 7) ~= 5 then -- [ebp] -> [ebp+0] (in SIB, too) |
| 552 | if not vreg then m = 0 end -- Force DISP to allow [Rd(5)] -> [ebp+0] | 553 | if not vreg then m = 0 end -- Force DISP to allow [Rd(5)] -> [ebp+0] |
| 553 | elseif disp >= -128 and disp <= 127 then m = 1 | 554 | elseif disp >= -128 and disp <= 127 then m = 1 |
| 554 | else m = 2 end | 555 | else m = 2 end |
| @@ -557,7 +558,7 @@ local function wputmrmsib(t, imark, s, vsreg) | |||
| 557 | end | 558 | end |
| 558 | 559 | ||
| 559 | -- Index register present or esp as base register: need SIB encoding. | 560 | -- Index register present or esp as base register: need SIB encoding. |
| 560 | if xreg or (reg%8) == 4 then | 561 | if xreg or band(reg, 7) == 4 then |
| 561 | wputmodrm(m or 2, s, 4) -- ModRM. | 562 | wputmodrm(m or 2, s, 4) -- ModRM. |
| 562 | if m == nil or imark == "I" then waction("MARK") end | 563 | if m == nil or imark == "I" then waction("MARK") end |
| 563 | if vsreg then waction("VREG", vsreg); wputxb(2) end | 564 | if vsreg then waction("VREG", vsreg); wputxb(2) end |
| @@ -1410,7 +1411,7 @@ local map_op = { | |||
| 1410 | -- Arithmetic ops. | 1411 | -- Arithmetic ops. |
| 1411 | for name,n in pairs{ add = 0, ["or"] = 1, adc = 2, sbb = 3, | 1412 | for name,n in pairs{ add = 0, ["or"] = 1, adc = 2, sbb = 3, |
| 1412 | ["and"] = 4, sub = 5, xor = 6, cmp = 7 } do | 1413 | ["and"] = 4, sub = 5, xor = 6, cmp = 7 } do |
| 1413 | local n8 = n * 8 | 1414 | local n8 = shl(n, 3) |
| 1414 | map_op[name.."_2"] = format( | 1415 | map_op[name.."_2"] = format( |
| 1415 | "mr:%02XRm|rm:%02XrM|mI1qdw:81%XmI|mS1qdw:83%XmS|Ri1qdwb:%02Xri|mi1qdwb:81%Xmi", | 1416 | "mr:%02XRm|rm:%02XrM|mI1qdw:81%XmI|mS1qdw:83%XmS|Ri1qdwb:%02Xri|mi1qdwb:81%Xmi", |
| 1416 | 1+n8, 3+n8, n, n, 5+n8, n) | 1417 | 1+n8, 3+n8, n, n, 5+n8, n) |
| @@ -1432,7 +1433,7 @@ end | |||
| 1432 | -- FP arithmetic ops. | 1433 | -- FP arithmetic ops. |
| 1433 | for name,n in pairs{ add = 0, mul = 1, com = 2, comp = 3, | 1434 | for name,n in pairs{ add = 0, mul = 1, com = 2, comp = 3, |
| 1434 | sub = 4, subr = 5, div = 6, divr = 7 } do | 1435 | sub = 4, subr = 5, div = 6, divr = 7 } do |
| 1435 | local nc = 192 + n * 8 | 1436 | local nc = 0xc0 + shl(n, 3) |
| 1436 | local nr = nc + (n < 4 and 0 or (n % 2 == 0 and 8 or -8)) | 1437 | local nr = nc + (n < 4 and 0 or (n % 2 == 0 and 8 or -8)) |
| 1437 | local fn = "f"..name | 1438 | local fn = "f"..name |
| 1438 | map_op[fn.."_1"] = format("ff:D8%02Xr|xd:D8%Xm|xq:nDC%Xm", nc, n, n) | 1439 | map_op[fn.."_1"] = format("ff:D8%02Xr|xd:D8%Xm|xq:nDC%Xm", nc, n, n) |
| @@ -1448,8 +1449,7 @@ end | |||
| 1448 | 1449 | ||
| 1449 | -- FP conditional moves. | 1450 | -- FP conditional moves. |
| 1450 | for cc,n in pairs{ b=0, e=1, be=2, u=3, nb=4, ne=5, nbe=6, nu=7 } do | 1451 | for cc,n in pairs{ b=0, e=1, be=2, u=3, nb=4, ne=5, nbe=6, nu=7 } do |
| 1451 | local n4 = n % 4 | 1452 | local nc = 0xdac0 + shl(band(n, 3), 3) + shl(band(n, 4), 6) |
| 1452 | local nc = 56000 + n4 * 8 + (n-n4) * 64 | ||
| 1453 | map_op["fcmov"..cc.."_1"] = format("ff:%04Xr", nc) -- P6+ | 1453 | map_op["fcmov"..cc.."_1"] = format("ff:%04Xr", nc) -- P6+ |
| 1454 | map_op["fcmov"..cc.."_2"] = format("Fff:%04XR", nc) -- P6+ | 1454 | map_op["fcmov"..cc.."_2"] = format("Fff:%04XR", nc) -- P6+ |
| 1455 | end | 1455 | end |
| @@ -1499,10 +1499,10 @@ local function dopattern(pat, args, sz, op, needrex) | |||
| 1499 | local s | 1499 | local s |
| 1500 | if addin then | 1500 | if addin then |
| 1501 | s = addin.reg | 1501 | s = addin.reg |
| 1502 | opcode = opcode - (s%8) -- Undo regno opcode merge. | 1502 | opcode = opcode - band(s, 7) -- Undo regno opcode merge. |
| 1503 | else | 1503 | else |
| 1504 | s = opcode % 16 -- Undo last digit. | 1504 | s = band(opcode, 15) -- Undo last digit. |
| 1505 | opcode = (opcode - s) / 16 | 1505 | opcode = shr(opcode, 4) |
| 1506 | end | 1506 | end |
| 1507 | local nn = c == "m" and 1 or 2 | 1507 | local nn = c == "m" and 1 or 2 |
| 1508 | local t = args[nn] | 1508 | local t = args[nn] |
| @@ -1699,7 +1699,7 @@ if x64 then | |||
| 1699 | werror("bad operand mode") | 1699 | werror("bad operand mode") |
| 1700 | end | 1700 | end |
| 1701 | op64 = params[2] | 1701 | op64 = params[2] |
| 1702 | opcode = 0xb8 + (a.reg%8) -- !x64: no VREG support. | 1702 | opcode = 0xb8 + band(a.reg, 7) -- !x64: no VREG support. |
| 1703 | rex = a.reg > 7 and 9 or 8 | 1703 | rex = a.reg > 7 and 9 or 8 |
| 1704 | end | 1704 | end |
| 1705 | end | 1705 | end |
diff --git a/src/Makefile b/src/Makefile index 13344a77..531f8bab 100644 --- a/src/Makefile +++ b/src/Makefile | |||
| @@ -168,7 +168,7 @@ LDOPTIONS= $(CCDEBUG) $(LDFLAGS) | |||
| 168 | HOST_CC= $(CC) | 168 | HOST_CC= $(CC) |
| 169 | HOST_RM= rm -f | 169 | HOST_RM= rm -f |
| 170 | # If left blank, minilua is built and used. You can supply an installed | 170 | # If left blank, minilua is built and used. You can supply an installed |
| 171 | # copy of (plain) Lua 5.1 or 5.2, e.g. with: HOST_LUA=lua | 171 | # copy of (plain) Lua 5.1 or 5.2, plus Lua BitOp. E.g. with: HOST_LUA=lua |
| 172 | HOST_LUA= | 172 | HOST_LUA= |
| 173 | 173 | ||
| 174 | HOST_XCFLAGS= -I. | 174 | HOST_XCFLAGS= -I. |
