diff options
Diffstat (limited to 'dynasm/dasm_mips.lua')
-rw-r--r-- | dynasm/dasm_mips.lua | 44 |
1 files changed, 19 insertions, 25 deletions
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 |