diff options
Diffstat (limited to 'src/jit/dis_arm64.lua')
| -rw-r--r-- | src/jit/dis_arm64.lua | 232 |
1 files changed, 111 insertions, 121 deletions
diff --git a/src/jit/dis_arm64.lua b/src/jit/dis_arm64.lua index 896fab791..7464421e4 100644 --- a/src/jit/dis_arm64.lua +++ b/src/jit/dis_arm64.lua | |||
| @@ -18,9 +18,7 @@ local sub, byte, format = string.sub, string.byte, string.format | |||
| 18 | local match, gmatch, gsub = string.match, string.gmatch, string.gsub | 18 | local match, gmatch, gsub = string.match, string.gmatch, string.gsub |
| 19 | local concat = table.concat | 19 | local concat = table.concat |
| 20 | local bit = require("bit") | 20 | local bit = require("bit") |
| 21 | local band, bor, bxor, tohex = bit.band, bit.bor, bit.bxor, bit.tohex | 21 | local ror, tohex = bit.ror, bit.tohex |
| 22 | local lshift, rshift, arshift = bit.lshift, bit.rshift, bit.arshift | ||
| 23 | local ror = bit.ror | ||
| 24 | 22 | ||
| 25 | ------------------------------------------------------------------------------ | 23 | ------------------------------------------------------------------------------ |
| 26 | -- Opcode maps | 24 | -- Opcode maps |
| @@ -782,35 +780,35 @@ end | |||
| 782 | local imm13_rep = { 0x55555555, 0x11111111, 0x01010101, 0x00010001, 0x00000001 } | 780 | local imm13_rep = { 0x55555555, 0x11111111, 0x01010101, 0x00010001, 0x00000001 } |
| 783 | 781 | ||
| 784 | local function decode_imm13(op) | 782 | local function decode_imm13(op) |
| 785 | local imms = band(rshift(op, 10), 63) | 783 | local imms = (op >> 10) & 63 |
| 786 | local immr = band(rshift(op, 16), 63) | 784 | local immr = (op >> 16) & 63 |
| 787 | if band(op, 0x00400000) == 0 then | 785 | if op & 0x00400000 == 0 then |
| 788 | local len = 5 | 786 | local len = 5 |
| 789 | if imms >= 56 then | 787 | if imms >= 56 then |
| 790 | if imms >= 60 then len = 1 else len = 2 end | 788 | if imms >= 60 then len = 1 else len = 2 end |
| 791 | elseif imms >= 48 then len = 3 elseif imms >= 32 then len = 4 end | 789 | elseif imms >= 48 then len = 3 elseif imms >= 32 then len = 4 end |
| 792 | local l = lshift(1, len)-1 | 790 | local l = (1 << len) - 1 |
| 793 | local s = band(imms, l) | 791 | local s = imms & l |
| 794 | local r = band(immr, l) | 792 | local r = immr & l |
| 795 | local imm = ror(rshift(-1, 31-s), r) | 793 | local imm = ror(-1 >> 31-s, r) |
| 796 | if len ~= 5 then imm = band(imm, lshift(1, l)-1) + rshift(imm, 31-l) end | 794 | if len != 5 then imm = (imm & ((1 << l) - 1)) | (imm >> 31-l) end |
| 797 | imm = imm * imm13_rep[len] | 795 | imm *= imm13_rep[len] |
| 798 | local ix = fmt_hex32(imm) | 796 | local ix = fmt_hex32(imm) |
| 799 | if rshift(op, 31) ~= 0 then | 797 | if op >> 31 != 0 then |
| 800 | return ix..tohex(imm) | 798 | return ix..tohex(imm) |
| 801 | else | 799 | else |
| 802 | return ix | 800 | return ix |
| 803 | end | 801 | end |
| 804 | else | 802 | else |
| 805 | local lo, hi = -1, 0 | 803 | local lo, hi = -1, 0 |
| 806 | if imms < 32 then lo = rshift(-1, 31-imms) else hi = rshift(-1, 63-imms) end | 804 | if imms < 32 then lo = -1 >> 31-imms else hi = -1 >> 63-imms end |
| 807 | if immr ~= 0 then | 805 | if immr != 0 then |
| 808 | lo, hi = ror(lo, immr), ror(hi, immr) | 806 | lo, hi = ror(lo, immr), ror(hi, immr) |
| 809 | local x = immr == 32 and 0 or band(bxor(lo, hi), lshift(-1, 32-immr)) | 807 | local x = immr == 32 ? 0 : (lo ~ hi) & (-1 << 32-immr) |
| 810 | lo, hi = bxor(lo, x), bxor(hi, x) | 808 | lo, hi = lo ~ x, hi ~ x |
| 811 | if immr >= 32 then lo, hi = hi, lo end | 809 | if immr >= 32 then lo, hi = hi, lo end |
| 812 | end | 810 | end |
| 813 | if hi ~= 0 then | 811 | if hi != 0 then |
| 814 | return fmt_hex32(hi)..tohex(lo) | 812 | return fmt_hex32(hi)..tohex(lo) |
| 815 | else | 813 | else |
| 816 | return fmt_hex32(lo) | 814 | return fmt_hex32(lo) |
| @@ -820,33 +818,31 @@ end | |||
| 820 | 818 | ||
| 821 | local function parse_immpc(op, name) | 819 | local function parse_immpc(op, name) |
| 822 | if name == "b" or name == "bl" then | 820 | if name == "b" or name == "bl" then |
| 823 | return arshift(lshift(op, 6), 4) | 821 | return (op << 6) ~>> 4 |
| 824 | elseif name == "adr" or name == "adrp" then | 822 | elseif name == "adr" or name == "adrp" then |
| 825 | local immlo = band(rshift(op, 29), 3) | 823 | return (((op << 8) ~>> 13) << 2) | ((op >> 29) & 3) |
| 826 | local immhi = lshift(arshift(lshift(op, 8), 13), 2) | ||
| 827 | return bor(immhi, immlo) | ||
| 828 | elseif name == "tbz" or name == "tbnz" then | 824 | elseif name == "tbz" or name == "tbnz" then |
| 829 | return lshift(arshift(lshift(op, 13), 18), 2) | 825 | return ((op << 13) ~>> 18) << 2 |
| 830 | else | 826 | else |
| 831 | return lshift(arshift(lshift(op, 8), 13), 2) | 827 | return ((op << 8) ~>> 13) << 2 |
| 832 | end | 828 | end |
| 833 | end | 829 | end |
| 834 | 830 | ||
| 835 | local function parse_fpimm8(op) | 831 | local function parse_fpimm8(op) |
| 836 | local sign = band(op, 0x100000) == 0 and 1 or -1 | 832 | local sign = op & 0x100000 == 0 ? 1 : -1 |
| 837 | local exp = bxor(rshift(arshift(lshift(op, 12), 5), 24), 0x80) - 131 | 833 | local exp = ((((op << 12) ~>> 5) >> 24) ~ 0x80) - 131 |
| 838 | local frac = 16+band(rshift(op, 13), 15) | 834 | local frac = 16 + ((op >> 13) & 15) |
| 839 | return sign * frac * 2^exp | 835 | return sign * frac * 2^exp |
| 840 | end | 836 | end |
| 841 | 837 | ||
| 842 | local function decode_fpmovi(op) | 838 | local function decode_fpmovi(op) |
| 843 | local lo = rshift(op, 5) | 839 | local lo = op >> 5 |
| 844 | local hi = rshift(op, 9) | 840 | local hi = op >> 9 |
| 845 | lo = bor(band(lo, 1) * 0xff, band(lo, 2) * 0x7f80, band(lo, 4) * 0x3fc000, | 841 | lo = ((lo & 1) * 0xff) | ((lo & 2) * 0x7f80) | |
| 846 | band(lo, 8) * 0x1fe00000) | 842 | ((lo & 4) * 0x3fc000) | ((lo & 8) * 0x1fe00000) |
| 847 | hi = bor(band(hi, 1) * 0xff, band(hi, 0x80) * 0x1fe, | 843 | hi = ((hi & 1) * 0xff) | ((hi & 0x80) * 0x1fe) | |
| 848 | band(hi, 0x100) * 0xff00, band(hi, 0x200) * 0x7f8000) | 844 | ((hi & 0x100) * 0xff00) | ((hi & 0x200) * 0x7f8000) |
| 849 | if hi ~= 0 then | 845 | if hi != 0 then |
| 850 | return fmt_hex32(hi)..tohex(lo) | 846 | return fmt_hex32(hi)..tohex(lo) |
| 851 | else | 847 | else |
| 852 | return fmt_hex32(lo) | 848 | return fmt_hex32(lo) |
| @@ -861,7 +857,7 @@ local function prefer_bfx(sf, uns, imms, immr) | |||
| 861 | if sf == 0 and (imms == 7 or imms == 15) then | 857 | if sf == 0 and (imms == 7 or imms == 15) then |
| 862 | return false | 858 | return false |
| 863 | end | 859 | end |
| 864 | if sf ~= 0 and uns == 0 and (imms == 7 or imms == 15 or imms == 31) then | 860 | if sf != 0 and uns == 0 and (imms == 7 or imms == 15 or imms == 31) then |
| 865 | return false | 861 | return false |
| 866 | end | 862 | end |
| 867 | end | 863 | end |
| @@ -872,7 +868,7 @@ end | |||
| 872 | local function disass_ins(ctx) | 868 | local function disass_ins(ctx) |
| 873 | local pos = ctx.pos | 869 | local pos = ctx.pos |
| 874 | local b0, b1, b2, b3 = byte(ctx.code, pos+1, pos+4) | 870 | local b0, b1, b2, b3 = byte(ctx.code, pos+1, pos+4) |
| 875 | local op = bor(lshift(b3, 24), lshift(b2, 16), lshift(b1, 8), b0) | 871 | local op = (b3 << 24) | (b2 << 16) | (b1 << 8) | b0 |
| 876 | local operands = {} | 872 | local operands = {} |
| 877 | local suffix = "" | 873 | local suffix = "" |
| 878 | local last, name, pat | 874 | local last, name, pat |
| @@ -881,26 +877,26 @@ local function disass_ins(ctx) | |||
| 881 | ctx.rel = nil | 877 | ctx.rel = nil |
| 882 | last = nil | 878 | last = nil |
| 883 | local opat | 879 | local opat |
| 884 | opat = map_init[band(rshift(op, 25), 15)] | 880 | opat = map_init[(op >> 25) & 15] |
| 885 | while type(opat) ~= "string" do | 881 | while type(opat) != "string" do |
| 886 | if not opat then return unknown(ctx) end | 882 | if not opat then return unknown(ctx) end |
| 887 | opat = opat[band(rshift(op, opat.shift), opat.mask)] or opat._ | 883 | opat = opat[(op >> opat.shift) & opat.mask] or opat._ |
| 888 | end | 884 | end |
| 889 | name, pat = match(opat, "^([a-z0-9]*)(.*)") | 885 | name, pat = match(opat, "^([a-z0-9]*)(.*)") |
| 890 | local altname, pat2 = match(pat, "|([a-z0-9_.|]*)(.*)") | 886 | local altname, pat2 = match(pat, "|([a-z0-9_.|]*)(.*)") |
| 891 | if altname then pat = pat2 end | 887 | if altname then pat = pat2 end |
| 892 | if sub(pat, 1, 1) == "." then | 888 | if sub(pat, 1, 1) == "." then |
| 893 | local s2, p2 = match(pat, "^([a-z0-9.]*)(.*)") | 889 | local s2, p2 = match(pat, "^([a-z0-9.]*)(.*)") |
| 894 | suffix = suffix..s2 | 890 | suffix ..= s2 |
| 895 | pat = p2 | 891 | pat = p2 |
| 896 | end | 892 | end |
| 897 | 893 | ||
| 898 | local rt = match(pat, "[gf]") | 894 | local rt = match(pat, "[gf]") |
| 899 | if rt then | 895 | if rt then |
| 900 | if rt == "g" then | 896 | if rt == "g" then |
| 901 | map_reg = band(op, 0x80000000) ~= 0 and map_regs.x or map_regs.w | 897 | map_reg = map_regs[op & 0x80000000 != 0 ? "x" : "w"] |
| 902 | else | 898 | else |
| 903 | map_reg = band(op, 0x400000) ~= 0 and map_regs.d or map_regs.s | 899 | map_reg = map_regs[op & 0x400000 != 0 ? "d" : "s"] |
| 904 | end | 900 | end |
| 905 | end | 901 | end |
| 906 | 902 | ||
| @@ -909,41 +905,41 @@ local function disass_ins(ctx) | |||
| 909 | for p in gmatch(pat, ".") do | 905 | for p in gmatch(pat, ".") do |
| 910 | local x = nil | 906 | local x = nil |
| 911 | if p == "D" then | 907 | if p == "D" then |
| 912 | local regnum = band(op, 31) | 908 | local regnum = op & 31 |
| 913 | x = rt and map_reg[regnum] or match_reg(p, pat, regnum) | 909 | x = rt ? map_reg[regnum] : match_reg(p, pat, regnum) |
| 914 | elseif p == "N" then | 910 | elseif p == "N" then |
| 915 | local regnum = band(rshift(op, 5), 31) | 911 | local regnum = (op >> 5) & 31 |
| 916 | x = rt and map_reg[regnum] or match_reg(p, pat, regnum) | 912 | x = rt ? map_reg[regnum] : match_reg(p, pat, regnum) |
| 917 | elseif p == "M" then | 913 | elseif p == "M" then |
| 918 | local regnum = band(rshift(op, 16), 31) | 914 | local regnum = (op >> 16) & 31 |
| 919 | x = rt and map_reg[regnum] or match_reg(p, pat, regnum) | 915 | x = rt ? map_reg[regnum] : match_reg(p, pat, regnum) |
| 920 | elseif p == "A" then | 916 | elseif p == "A" then |
| 921 | local regnum = band(rshift(op, 10), 31) | 917 | local regnum = (op >> 10) & 31 |
| 922 | x = rt and map_reg[regnum] or match_reg(p, pat, regnum) | 918 | x = rt ? map_reg[regnum] : match_reg(p, pat, regnum) |
| 923 | elseif p == "B" then | 919 | elseif p == "B" then |
| 924 | local addr = ctx.addr + pos + parse_immpc(op, name) | 920 | local addr = ctx.addr + pos + parse_immpc(op, name) |
| 925 | ctx.rel = addr | 921 | ctx.rel = addr |
| 926 | x = format("0x%08x", addr) | 922 | x = format("0x%08x", addr) |
| 927 | elseif p == "T" then | 923 | elseif p == "T" then |
| 928 | x = bor(band(rshift(op, 26), 32), band(rshift(op, 19), 31)) | 924 | x = ((op >> 26) & 32) | ((op >> 19) & 31) |
| 929 | elseif p == "V" then | 925 | elseif p == "V" then |
| 930 | x = band(op, 15) | 926 | x = op & 15 |
| 931 | elseif p == "C" then | 927 | elseif p == "C" then |
| 932 | x = map_cond[band(rshift(op, 12), 15)] | 928 | x = map_cond[(op >> 12) & 15] |
| 933 | elseif p == "c" then | 929 | elseif p == "c" then |
| 934 | local rn = band(rshift(op, 5), 31) | 930 | local rn = (op >> 5) & 31 |
| 935 | local rm = band(rshift(op, 16), 31) | 931 | local rm = (op >> 16) & 31 |
| 936 | local cond = band(rshift(op, 12), 15) | 932 | local cond = (op >> 12) & 15 |
| 937 | local invc = bxor(cond, 1) | 933 | local invc = cond ~ 1 |
| 938 | x = map_cond[cond] | 934 | x = map_cond[cond] |
| 939 | if altname and cond ~= 14 and cond ~= 15 then | 935 | if altname and cond != 14 and cond != 15 then |
| 940 | local a1, a2 = match(altname, "([^|]*)|(.*)") | 936 | local a1, a2 = match(altname, "([^|]*)|(.*)") |
| 941 | if rn == rm then | 937 | if rn == rm then |
| 942 | local n = #operands | 938 | local n = #operands |
| 943 | operands[n] = nil | 939 | operands[n] = nil |
| 944 | x = map_cond[invc] | 940 | x = map_cond[invc] |
| 945 | if rn ~= 31 then | 941 | if rn != 31 then |
| 946 | if a1 then name = a1 else name = altname end | 942 | name = a1 ?? altname |
| 947 | else | 943 | else |
| 948 | operands[n-1] = nil | 944 | operands[n-1] = nil |
| 949 | name = a2 | 945 | name = a2 |
| @@ -951,65 +947,59 @@ local function disass_ins(ctx) | |||
| 951 | end | 947 | end |
| 952 | end | 948 | end |
| 953 | elseif p == "W" then | 949 | elseif p == "W" then |
| 954 | x = band(rshift(op, 5), 0xffff) | 950 | x = (op >> 5) & 0xffff |
| 955 | elseif p == "Y" then | 951 | elseif p == "Y" then |
| 956 | x = band(rshift(op, 5), 0xffff) | 952 | x = (op >> 5) & 0xffff |
| 957 | local hw = band(rshift(op, 21), 3) | 953 | local hw = (op >> 21) & 3 |
| 958 | if altname and (hw == 0 or x ~= 0) then | 954 | if altname and (hw == 0 or x != 0) then |
| 959 | name = altname | 955 | name = altname |
| 960 | end | 956 | end |
| 961 | elseif p == "L" then | 957 | elseif p == "L" then |
| 962 | local rn = map_regs.x[band(rshift(op, 5), 31)] | 958 | local rn = map_regs.x[(op >> 5) & 31] |
| 963 | local imm9 = arshift(lshift(op, 11), 23) | 959 | local imm9 = (op << 11) ~>> 23 |
| 964 | if band(op, 0x800) ~= 0 then | 960 | if op & 0x800 != 0 then |
| 965 | x = "["..rn..", #"..imm9.."]!" | 961 | x = "["..rn..", #"..imm9.."]!" |
| 966 | else | 962 | else |
| 967 | x = "["..rn.."], #"..imm9 | 963 | x = "["..rn.."], #"..imm9 |
| 968 | end | 964 | end |
| 969 | elseif p == "U" then | 965 | elseif p == "U" then |
| 970 | local rn = map_regs.x[band(rshift(op, 5), 31)] | 966 | local rn = map_regs.x[(op >> 5) & 31] |
| 971 | local sz = band(rshift(op, 30), 3) | 967 | local sz = (op >> 30) & 3 |
| 972 | local imm12 = lshift(rshift(lshift(op, 10), 20), sz) | 968 | local imm12 = ((op << 10) >> 20) << sz |
| 973 | if imm12 ~= 0 then | 969 | if imm12 != 0 then |
| 974 | x = "["..rn..", #"..imm12.."]" | 970 | x = "["..rn..", #"..imm12.."]" |
| 975 | else | 971 | else |
| 976 | x = "["..rn.."]" | 972 | x = "["..rn.."]" |
| 977 | end | 973 | end |
| 978 | elseif p == "K" then | 974 | elseif p == "K" then |
| 979 | local rn = map_regs.x[band(rshift(op, 5), 31)] | 975 | local rn = map_regs.x[(op >> 5) & 31] |
| 980 | local imm9 = arshift(lshift(op, 11), 23) | 976 | local imm9 = (op << 11) ~>> 23 |
| 981 | if imm9 ~= 0 then | 977 | if imm9 != 0 then |
| 982 | x = "["..rn..", #"..imm9.."]" | 978 | x = "["..rn..", #"..imm9.."]" |
| 983 | else | 979 | else |
| 984 | x = "["..rn.."]" | 980 | x = "["..rn.."]" |
| 985 | end | 981 | end |
| 986 | elseif p == "O" then | 982 | elseif p == "O" then |
| 987 | local rn, rm = map_regs.x[band(rshift(op, 5), 31)] | 983 | local rn = map_regs.x[(op >> 5) & 31] |
| 988 | local m = band(rshift(op, 13), 1) | 984 | local rm = map_regs[op & (1 << 13) == 0 ? "w" : "x"][(op >> 16) & 31] |
| 989 | if m == 0 then | ||
| 990 | rm = map_regs.w[band(rshift(op, 16), 31)] | ||
| 991 | else | ||
| 992 | rm = map_regs.x[band(rshift(op, 16), 31)] | ||
| 993 | end | ||
| 994 | x = "["..rn..", "..rm | 985 | x = "["..rn..", "..rm |
| 995 | local opt = band(rshift(op, 13), 7) | 986 | local opt = (op >> 13) & 7 |
| 996 | local s = band(rshift(op, 12), 1) | 987 | local s = (op >> 12) & 1 |
| 997 | local sz = band(rshift(op, 30), 3) | 988 | local sz = (op >> 30) & 3 |
| 998 | -- extension to be applied | ||
| 999 | if opt == 3 then | 989 | if opt == 3 then |
| 1000 | if s == 0 then x = x.."]" | 990 | if s == 0 then x ..= "]" |
| 1001 | else x = x..", lsl #"..sz.."]" end | 991 | else x = x..", lsl #"..sz.."]" end |
| 1002 | elseif opt == 2 or opt == 6 or opt == 7 then | 992 | elseif opt == 2 or opt == 6 or opt == 7 then |
| 1003 | if s == 0 then x = x..", "..map_extend[opt].."]" | 993 | if s == 0 then x = x..", "..map_extend[opt].."]" |
| 1004 | else x = x..", "..map_extend[opt].." #"..sz.."]" end | 994 | else x = x..", "..map_extend[opt].." #"..sz.."]" end |
| 1005 | else | 995 | else |
| 1006 | x = x.."]" | 996 | x ..= "]" |
| 1007 | end | 997 | end |
| 1008 | elseif p == "P" then | 998 | elseif p == "P" then |
| 1009 | local sh = 2 + rshift(op, 31 - band(rshift(op, 26), 1)) | 999 | local sh = 2 + (op >> (31 - ((op >> 26) & 1))) |
| 1010 | local imm7 = lshift(arshift(lshift(op, 10), 25), sh) | 1000 | local imm7 = ((op << 10) ~>> 25) << sh |
| 1011 | local rn = map_regs.x[band(rshift(op, 5), 31)] | 1001 | local rn = map_regs.x[(op >> 5) & 31] |
| 1012 | local ind = band(rshift(op, 23), 3) | 1002 | local ind = (op >> 23) & 3 |
| 1013 | if ind == 1 then | 1003 | if ind == 1 then |
| 1014 | x = "["..rn.."], #"..imm7 | 1004 | x = "["..rn.."], #"..imm7 |
| 1015 | elseif ind == 2 then | 1005 | elseif ind == 2 then |
| @@ -1022,9 +1012,9 @@ local function disass_ins(ctx) | |||
| 1022 | x = "["..rn..", #"..imm7.."]!" | 1012 | x = "["..rn..", #"..imm7.."]!" |
| 1023 | end | 1013 | end |
| 1024 | elseif p == "I" then | 1014 | elseif p == "I" then |
| 1025 | local shf = band(rshift(op, 22), 3) | 1015 | local shf = (op >> 22) & 3 |
| 1026 | local imm12 = band(rshift(op, 10), 0x0fff) | 1016 | local imm12 = (op >> 10) & 0x0fff |
| 1027 | local rn, rd = band(rshift(op, 5), 31), band(op, 31) | 1017 | local rn, rd = (op >> 5) & 31, op & 31 |
| 1028 | if altname == "mov" and shf == 0 and imm12 == 0 and (rn == 31 or rd == 31) then | 1018 | if altname == "mov" and shf == 0 and imm12 == 0 and (rn == 31 or rd == 31) then |
| 1029 | name = altname | 1019 | name = altname |
| 1030 | x = nil | 1020 | x = nil |
| @@ -1036,22 +1026,22 @@ local function disass_ins(ctx) | |||
| 1036 | elseif p == "i" then | 1026 | elseif p == "i" then |
| 1037 | x = "#0x"..decode_imm13(op) | 1027 | x = "#0x"..decode_imm13(op) |
| 1038 | elseif p == "1" then | 1028 | elseif p == "1" then |
| 1039 | immr = band(rshift(op, 16), 63) | 1029 | immr = (op >> 16) & 63 |
| 1040 | x = immr | 1030 | x = immr |
| 1041 | elseif p == "2" then | 1031 | elseif p == "2" then |
| 1042 | x = band(rshift(op, 10), 63) | 1032 | x = (op >> 10) & 63 |
| 1043 | if altname then | 1033 | if altname then |
| 1044 | local a1, a2, a3, a4, a5, a6 = | 1034 | local a1, a2, a3, a4, a5, a6 = |
| 1045 | match(altname, "([^|]*)|([^|]*)|([^|]*)|([^|]*)|([^|]*)|(.*)") | 1035 | match(altname, "([^|]*)|([^|]*)|([^|]*)|([^|]*)|([^|]*)|(.*)") |
| 1046 | local sf = band(rshift(op, 26), 32) | 1036 | local sf = (op >> 26) & 32 |
| 1047 | local uns = band(rshift(op, 30), 1) | 1037 | local uns = (op >> 30) & 1 |
| 1048 | if prefer_bfx(sf, uns, x, immr) then | 1038 | if prefer_bfx(sf, uns, x, immr) then |
| 1049 | name = a2 | 1039 | name = a2 |
| 1050 | x = x - immr + 1 | 1040 | x = x - immr + 1 |
| 1051 | elseif immr == 0 and x == 7 then | 1041 | elseif immr == 0 and x == 7 then |
| 1052 | local n = #operands | 1042 | local n = #operands |
| 1053 | operands[n] = nil | 1043 | operands[n] = nil |
| 1054 | if sf ~= 0 then | 1044 | if sf != 0 then |
| 1055 | operands[n-1] = gsub(operands[n-1], "x", "w") | 1045 | operands[n-1] = gsub(operands[n-1], "x", "w") |
| 1056 | end | 1046 | end |
| 1057 | last = operands[n-1] | 1047 | last = operands[n-1] |
| @@ -1060,7 +1050,7 @@ local function disass_ins(ctx) | |||
| 1060 | elseif immr == 0 and x == 15 then | 1050 | elseif immr == 0 and x == 15 then |
| 1061 | local n = #operands | 1051 | local n = #operands |
| 1062 | operands[n] = nil | 1052 | operands[n] = nil |
| 1063 | if sf ~= 0 then | 1053 | if sf != 0 then |
| 1064 | operands[n-1] = gsub(operands[n-1], "x", "w") | 1054 | operands[n-1] = gsub(operands[n-1], "x", "w") |
| 1065 | end | 1055 | end |
| 1066 | last = operands[n-1] | 1056 | last = operands[n-1] |
| @@ -1071,7 +1061,7 @@ local function disass_ins(ctx) | |||
| 1071 | name = a4 | 1061 | name = a4 |
| 1072 | local n = #operands | 1062 | local n = #operands |
| 1073 | operands[n] = nil | 1063 | operands[n] = nil |
| 1074 | if sf ~= 0 then | 1064 | if sf != 0 then |
| 1075 | operands[n-1] = gsub(operands[n-1], "x", "w") | 1065 | operands[n-1] = gsub(operands[n-1], "x", "w") |
| 1076 | end | 1066 | end |
| 1077 | last = operands[n-1] | 1067 | last = operands[n-1] |
| @@ -1079,7 +1069,7 @@ local function disass_ins(ctx) | |||
| 1079 | name = a3 | 1069 | name = a3 |
| 1080 | end | 1070 | end |
| 1081 | x = nil | 1071 | x = nil |
| 1082 | elseif band(x, 31) ~= 31 and immr == x+1 and name == "ubfm" then | 1072 | elseif x & 31 != 31 and immr == x+1 and name == "ubfm" then |
| 1083 | name = a4 | 1073 | name = a4 |
| 1084 | last = "#"..(sf+32 - immr) | 1074 | last = "#"..(sf+32 - immr) |
| 1085 | operands[#operands] = last | 1075 | operands[#operands] = last |
| @@ -1088,28 +1078,28 @@ local function disass_ins(ctx) | |||
| 1088 | name = a1 | 1078 | name = a1 |
| 1089 | last = "#"..(sf+32 - immr) | 1079 | last = "#"..(sf+32 - immr) |
| 1090 | operands[#operands] = last | 1080 | operands[#operands] = last |
| 1091 | x = x + 1 | 1081 | x += 1 |
| 1092 | end | 1082 | end |
| 1093 | end | 1083 | end |
| 1094 | elseif p == "3" then | 1084 | elseif p == "3" then |
| 1095 | x = band(rshift(op, 10), 63) | 1085 | x = (op >> 10) & 63 |
| 1096 | if altname then | 1086 | if altname then |
| 1097 | local a1, a2 = match(altname, "([^|]*)|(.*)") | 1087 | local a1, a2 = match(altname, "([^|]*)|(.*)") |
| 1098 | if x < immr then | 1088 | if x < immr then |
| 1099 | name = a1 | 1089 | name = a1 |
| 1100 | local sf = band(rshift(op, 26), 32) | 1090 | local sf = (op >> 26) & 32 |
| 1101 | last = "#"..(sf+32 - immr) | 1091 | last = "#"..(sf+32 - immr) |
| 1102 | operands[#operands] = last | 1092 | operands[#operands] = last |
| 1103 | x = x + 1 | 1093 | x += 1 |
| 1104 | else | 1094 | else |
| 1105 | name = a2 | 1095 | name = a2 |
| 1106 | x = x - immr + 1 | 1096 | x = x - immr + 1 |
| 1107 | end | 1097 | end |
| 1108 | end | 1098 | end |
| 1109 | elseif p == "4" then | 1099 | elseif p == "4" then |
| 1110 | x = band(rshift(op, 10), 63) | 1100 | x = (op >> 10) & 63 |
| 1111 | local rn = band(rshift(op, 5), 31) | 1101 | local rn = (op >> 5) & 31 |
| 1112 | local rm = band(rshift(op, 16), 31) | 1102 | local rm = (op >> 16) & 31 |
| 1113 | if altname and rn == rm then | 1103 | if altname and rn == rm then |
| 1114 | local n = #operands | 1104 | local n = #operands |
| 1115 | operands[n] = nil | 1105 | operands[n] = nil |
| @@ -1117,30 +1107,30 @@ local function disass_ins(ctx) | |||
| 1117 | name = altname | 1107 | name = altname |
| 1118 | end | 1108 | end |
| 1119 | elseif p == "5" then | 1109 | elseif p == "5" then |
| 1120 | x = band(rshift(op, 16), 31) | 1110 | x = (op >> 16) & 31 |
| 1121 | elseif p == "S" then | 1111 | elseif p == "S" then |
| 1122 | x = band(rshift(op, 10), 63) | 1112 | x = (op >> 10) & 63 |
| 1123 | if x == 0 then x = nil | 1113 | if x == 0 then x = nil |
| 1124 | else x = map_shift[band(rshift(op, 22), 3)].." #"..x end | 1114 | else x = map_shift[(op >> 22) & 3].." #"..x end |
| 1125 | elseif p == "X" then | 1115 | elseif p == "X" then |
| 1126 | local opt = band(rshift(op, 13), 7) | 1116 | local opt = (op >> 13) & 7 |
| 1127 | -- Width specifier <R>. | 1117 | -- Width specifier <R>. |
| 1128 | if opt ~= 3 and opt ~= 7 then | 1118 | if opt != 3 and opt != 7 then |
| 1129 | last = map_regs.w[band(rshift(op, 16), 31)] | 1119 | last = map_regs.w[(op >> 16) & 31] |
| 1130 | operands[#operands] = last | 1120 | operands[#operands] = last |
| 1131 | end | 1121 | end |
| 1132 | x = band(rshift(op, 10), 7) | 1122 | x = (op >> 10) & 7 |
| 1133 | -- Extension. | 1123 | -- Extension. |
| 1134 | if opt == 2 + band(rshift(op, 31), 1) and | 1124 | if opt == 2 + ((op >> 31) & 1) and |
| 1135 | band(rshift(op, second0 and 5 or 0), 31) == 31 then | 1125 | (op >> (second0 ? 5 : 0)) & 31 == 31 then |
| 1136 | if x == 0 then x = nil | 1126 | if x == 0 then x = nil |
| 1137 | else x = "lsl #"..x end | 1127 | else x = "lsl #"..x end |
| 1138 | else | 1128 | else |
| 1139 | if x == 0 then x = map_extend[band(rshift(op, 13), 7)] | 1129 | if x == 0 then x = map_extend[(op >> 13) & 7] |
| 1140 | else x = map_extend[band(rshift(op, 13), 7)].." #"..x end | 1130 | else x = map_extend[(op >> 13) & 7].." #"..x end |
| 1141 | end | 1131 | end |
| 1142 | elseif p == "R" then | 1132 | elseif p == "R" then |
| 1143 | x = band(rshift(op,21), 3) | 1133 | x = (op >> 21) & 3 |
| 1144 | if x == 0 then x = nil | 1134 | if x == 0 then x = nil |
| 1145 | else x = "lsl #"..x*16 end | 1135 | else x = "lsl #"..x*16 end |
| 1146 | elseif p == "z" then | 1136 | elseif p == "z" then |
