aboutsummaryrefslogtreecommitdiff
path: root/dynasm/dasm_mips.lua
diff options
context:
space:
mode:
Diffstat (limited to 'dynasm/dasm_mips.lua')
-rw-r--r--dynasm/dasm_mips.lua44
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
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