aboutsummaryrefslogtreecommitdiff
path: root/dynasm
diff options
context:
space:
mode:
authorMike Pall <mike>2012-07-08 16:25:38 +0200
committerMike Pall <mike>2012-07-08 16:27:18 +0200
commitc00ffcb870cd51849ee2a0f1bf1862ac965026b7 (patch)
treee9af978c9883e709b1b5e5a845ce8ef5b6d0c490 /dynasm
parente3dec0438d50dbdf0184078d4e0233e399725787 (diff)
downloadluajit-c00ffcb870cd51849ee2a0f1bf1862ac965026b7.tar.gz
luajit-c00ffcb870cd51849ee2a0f1bf1862ac965026b7.tar.bz2
luajit-c00ffcb870cd51849ee2a0f1bf1862ac965026b7.zip
Change DynASM bit operations to use Lua BitOp.
Diffstat (limited to 'dynasm')
-rw-r--r--dynasm/dasm_arm.lua73
-rw-r--r--dynasm/dasm_mips.lua44
-rw-r--r--dynasm/dasm_ppc.lua66
-rw-r--r--dynasm/dasm_x86.lua52
4 files changed, 105 insertions, 130 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
26local sub, format, byte, char = _s.sub, _s.format, _s.byte, _s.char 26local sub, format, byte, char = _s.sub, _s.format, _s.byte, _s.char
27local match, gmatch, gsub = _s.match, _s.gmatch, _s.gsub 27local match, gmatch, gsub = _s.match, _s.gmatch, _s.gsub
28local concat, sort, insert = table.concat, table.sort, table.insert 28local concat, sort, insert = table.concat, table.sort, table.insert
29local bit = bit or require("bit")
30local band, shl, shr, sar = bit.band, bit.lshift, bit.rshift, bit.arshift
31local ror, tohex = bit.ror, bit.tohex
29 32
30-- Inherited tables and callbacks. 33-- Inherited tables and callbacks.
31local g_opt, g_arch 34local g_opt, g_arch
@@ -60,11 +63,6 @@ local secpos = 1
60 63
61------------------------------------------------------------------------------ 64------------------------------------------------------------------------------
62 65
63-- Return 8 digit hex number.
64local function tohex(x)
65 return sub(format("%08x", x), -8) -- Avoid 64 bit portability problem in Lua.
66end
67
68-- Dump action names and numbers. 66-- Dump action names and numbers.
69local function dumpactions(out) 67local 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
519local function parse_imm12(imm) 515local 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
571end 563end
@@ -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
587end 579end
@@ -617,12 +609,12 @@ local function parse_label(label, def)
617end 609end
618 610
619local function parse_load(params, nparams, n, op) 611local 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
26local sub, format, byte, char = _s.sub, _s.format, _s.byte, _s.char 26local sub, format, byte, char = _s.sub, _s.format, _s.byte, _s.char
27local match, gmatch = _s.match, _s.gmatch 27local match, gmatch = _s.match, _s.gmatch
28local concat, sort = table.concat, table.sort 28local concat, sort = table.concat, table.sort
29local bit = bit or require("bit")
30local band, shl, sar, tohex = bit.band, bit.lshift, bit.arshift, bit.tohex
29 31
30-- Inherited tables and callbacks. 32-- Inherited tables and callbacks.
31local g_opt, g_arch 33local g_opt, g_arch
@@ -60,11 +62,6 @@ local secpos = 1
60 62
61------------------------------------------------------------------------------ 63------------------------------------------------------------------------------
62 64
63-- Return 8 digit hex number.
64local function tohex(x)
65 return sub(format("%08x", x), -8) -- Avoid 64 bit portability problem in Lua.
66end
67
68-- Dump action names and numbers. 65-- Dump action names and numbers.
69local function dumpactions(out) 66local 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
639local function parse_imm(imm, bits, shift, scale, signed) 636local 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
664local function parse_disp(disp) 659local 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.."'")
695end 690end
@@ -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
26local sub, format, byte, char = _s.sub, _s.format, _s.byte, _s.char 26local sub, format, byte, char = _s.sub, _s.format, _s.byte, _s.char
27local match, gmatch = _s.match, _s.gmatch 27local match, gmatch = _s.match, _s.gmatch
28local concat, sort = table.concat, table.sort 28local concat, sort = table.concat, table.sort
29local bit = bit or require("bit")
30local band, shl, shr, sar = bit.band, bit.lshift, bit.rshift, bit.arshift
31local tohex = bit.tohex
29 32
30-- Inherited tables and callbacks. 33-- Inherited tables and callbacks.
31local g_opt, g_arch 34local g_opt, g_arch
@@ -60,11 +63,6 @@ local secpos = 1
60 63
61------------------------------------------------------------------------------ 64------------------------------------------------------------------------------
62 65
63-- Return 8 digit hex number.
64local function tohex(x)
65 return sub(format("%08x", x), -8) -- Avoid 64 bit portability problem in Lua.
66end
67
68-- Dump action names and numbers. 66-- Dump action names and numbers.
69local function dumpactions(out) 67local 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.
838for cond,c in pairs(map_cond) do 836for 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
905local function parse_imm(imm, bits, shift, scale, signed) 903local 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
930local function parse_shiftmask(imm, isshift) 926local 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
28local sub, format, byte, char = _s.sub, _s.format, _s.byte, _s.char 28local sub, format, byte, char = _s.sub, _s.format, _s.byte, _s.char
29local find, match, gmatch, gsub = _s.find, _s.match, _s.gmatch, _s.gsub 29local find, match, gmatch, gsub = _s.find, _s.match, _s.gmatch, _s.gsub
30local concat, sort = table.concat, table.sort 30local concat, sort = table.concat, table.sort
31local bit = bit or require("bit")
32local band, shl, shr = bit.band, bit.lshift, bit.rshift
31 33
32-- Inherited tables and callbacks. 34-- Inherited tables and callbacks.
33local g_opt, g_arch 35local g_opt, g_arch
@@ -426,10 +428,10 @@ end
426-- Put unsigned word or arg. 428-- Put unsigned word or arg.
427local function wputwarg(n) 429local 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
434end 436end
435 437
@@ -437,10 +439,10 @@ end
437local function wputdarg(n) 439local 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)
487end 488end
@@ -489,7 +490,7 @@ end
489-- Put ModRM or SIB formatted byte. 490-- Put ModRM or SIB formatted byte.
490local function wputmodrm(m, s, rm, vs, vrm) 491local 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))
493end 494end
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.
1411for name,n in pairs{ add = 0, ["or"] = 1, adc = 2, sbb = 3, 1412for 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.
1433for name,n in pairs{ add = 0, mul = 1, com = 2, comp = 3, 1434for 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.
1450for cc,n in pairs{ b=0, e=1, be=2, u=3, nb=4, ne=5, nbe=6, nu=7 } do 1451for 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+
1455end 1455end
@@ -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