aboutsummaryrefslogtreecommitdiffstats
path: root/lib/LuaJIT/jit
diff options
context:
space:
mode:
Diffstat (limited to 'lib/LuaJIT/jit')
-rw-r--r--lib/LuaJIT/jit/.gitignore1
-rw-r--r--lib/LuaJIT/jit/bc.lua190
-rw-r--r--lib/LuaJIT/jit/bcsave.lua661
-rw-r--r--lib/LuaJIT/jit/dis_arm.lua689
-rw-r--r--lib/LuaJIT/jit/dis_arm64.lua1216
-rw-r--r--lib/LuaJIT/jit/dis_arm64be.lua12
-rw-r--r--lib/LuaJIT/jit/dis_mips.lua443
-rw-r--r--lib/LuaJIT/jit/dis_mips64.lua17
-rw-r--r--lib/LuaJIT/jit/dis_mips64el.lua17
-rw-r--r--lib/LuaJIT/jit/dis_mipsel.lua17
-rw-r--r--lib/LuaJIT/jit/dis_ppc.lua591
-rw-r--r--lib/LuaJIT/jit/dis_x64.lua17
-rw-r--r--lib/LuaJIT/jit/dis_x86.lua953
-rw-r--r--lib/LuaJIT/jit/dump.lua712
-rw-r--r--lib/LuaJIT/jit/p.lua311
-rw-r--r--lib/LuaJIT/jit/v.lua170
-rw-r--r--lib/LuaJIT/jit/zone.lua45
17 files changed, 0 insertions, 6062 deletions
diff --git a/lib/LuaJIT/jit/.gitignore b/lib/LuaJIT/jit/.gitignore
deleted file mode 100644
index 500e285..0000000
--- a/lib/LuaJIT/jit/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-vmdef.lua
diff --git a/lib/LuaJIT/jit/bc.lua b/lib/LuaJIT/jit/bc.lua
deleted file mode 100644
index 193cf01..0000000
--- a/lib/LuaJIT/jit/bc.lua
+++ /dev/null
@@ -1,190 +0,0 @@
-----------------------------------------------------------------------------
--- LuaJIT bytecode listing module.
---
--- Copyright (C) 2005-2017 Mike Pall. All rights reserved.
--- Released under the MIT license. See Copyright Notice in luajit.h
-----------------------------------------------------------------------------
---
--- This module lists the bytecode of a Lua function. If it's loaded by -jbc
--- it hooks into the parser and lists all functions of a chunk as they
--- are parsed.
---
--- Example usage:
---
--- luajit -jbc -e 'local x=0; for i=1,1e6 do x=x+i end; print(x)'
--- luajit -jbc=- foo.lua
--- luajit -jbc=foo.list foo.lua
---
--- Default output is to stderr. To redirect the output to a file, pass a
--- filename as an argument (use '-' for stdout) or set the environment
--- variable LUAJIT_LISTFILE. The file is overwritten every time the module
--- is started.
---
--- This module can also be used programmatically:
---
--- local bc = require("jit.bc")
---
--- local function foo() print("hello") end
---
--- bc.dump(foo) --> -- BYTECODE -- [...]
--- print(bc.line(foo, 2)) --> 0002 KSTR 1 1 ; "hello"
---
--- local out = {
--- -- Do something with each line:
--- write = function(t, ...) io.write(...) end,
--- close = function(t) end,
--- flush = function(t) end,
--- }
--- bc.dump(foo, out)
---
-------------------------------------------------------------------------------
-
--- Cache some library functions and objects.
-local jit = require("jit")
-assert(jit.version_num == 20100, "LuaJIT core/library version mismatch")
-local jutil = require("jit.util")
-local vmdef = require("jit.vmdef")
-local bit = require("bit")
-local sub, gsub, format = string.sub, string.gsub, string.format
-local byte, band, shr = string.byte, bit.band, bit.rshift
-local funcinfo, funcbc, funck = jutil.funcinfo, jutil.funcbc, jutil.funck
-local funcuvname = jutil.funcuvname
-local bcnames = vmdef.bcnames
-local stdout, stderr = io.stdout, io.stderr
-
-------------------------------------------------------------------------------
-
-local function ctlsub(c)
- if c == "\n" then return "\\n"
- elseif c == "\r" then return "\\r"
- elseif c == "\t" then return "\\t"
- else return format("\\%03d", byte(c))
- end
-end
-
--- Return one bytecode line.
-local function bcline(func, pc, prefix)
- local ins, m = funcbc(func, pc)
- if not ins then return end
- local ma, mb, mc = band(m, 7), band(m, 15*8), band(m, 15*128)
- local a = band(shr(ins, 8), 0xff)
- local oidx = 6*band(ins, 0xff)
- local op = sub(bcnames, oidx+1, oidx+6)
- local s = format("%04d %s %-6s %3s ",
- pc, prefix or " ", op, ma == 0 and "" or a)
- local d = shr(ins, 16)
- if mc == 13*128 then -- BCMjump
- return format("%s=> %04d\n", s, pc+d-0x7fff)
- end
- if mb ~= 0 then
- d = band(d, 0xff)
- elseif mc == 0 then
- return s.."\n"
- end
- local kc
- if mc == 10*128 then -- BCMstr
- kc = funck(func, -d-1)
- kc = format(#kc > 40 and '"%.40s"~' or '"%s"', gsub(kc, "%c", ctlsub))
- elseif mc == 9*128 then -- BCMnum
- kc = funck(func, d)
- if op == "TSETM " then kc = kc - 2^52 end
- elseif mc == 12*128 then -- BCMfunc
- local fi = funcinfo(funck(func, -d-1))
- if fi.ffid then
- kc = vmdef.ffnames[fi.ffid]
- else
- kc = fi.loc
- end
- elseif mc == 5*128 then -- BCMuv
- kc = funcuvname(func, d)
- end
- if ma == 5 then -- BCMuv
- local ka = funcuvname(func, a)
- if kc then kc = ka.." ; "..kc else kc = ka end
- end
- if mb ~= 0 then
- local b = shr(ins, 24)
- if kc then return format("%s%3d %3d ; %s\n", s, b, d, kc) end
- return format("%s%3d %3d\n", s, b, d)
- end
- if kc then return format("%s%3d ; %s\n", s, d, kc) end
- if mc == 7*128 and d > 32767 then d = d - 65536 end -- BCMlits
- return format("%s%3d\n", s, d)
-end
-
--- Collect branch targets of a function.
-local function bctargets(func)
- local target = {}
- for pc=1,1000000000 do
- local ins, m = funcbc(func, pc)
- if not ins then break end
- if band(m, 15*128) == 13*128 then target[pc+shr(ins, 16)-0x7fff] = true end
- end
- return target
-end
-
--- Dump bytecode instructions of a function.
-local function bcdump(func, out, all)
- if not out then out = stdout end
- local fi = funcinfo(func)
- if all and fi.children then
- for n=-1,-1000000000,-1 do
- local k = funck(func, n)
- if not k then break end
- if type(k) == "proto" then bcdump(k, out, true) end
- end
- end
- out:write(format("-- BYTECODE -- %s-%d\n", fi.loc, fi.lastlinedefined))
- local target = bctargets(func)
- for pc=1,1000000000 do
- local s = bcline(func, pc, target[pc] and "=>")
- if not s then break end
- out:write(s)
- end
- out:write("\n")
- out:flush()
-end
-
-------------------------------------------------------------------------------
-
--- Active flag and output file handle.
-local active, out
-
--- List handler.
-local function h_list(func)
- return bcdump(func, out)
-end
-
--- Detach list handler.
-local function bclistoff()
- if active then
- active = false
- jit.attach(h_list)
- if out and out ~= stdout and out ~= stderr then out:close() end
- out = nil
- end
-end
-
--- Open the output file and attach list handler.
-local function bcliston(outfile)
- if active then bclistoff() end
- if not outfile then outfile = os.getenv("LUAJIT_LISTFILE") end
- if outfile then
- out = outfile == "-" and stdout or assert(io.open(outfile, "w"))
- else
- out = stderr
- end
- jit.attach(h_list, "bc")
- active = true
-end
-
--- Public module functions.
-return {
- line = bcline,
- dump = bcdump,
- targets = bctargets,
- on = bcliston,
- off = bclistoff,
- start = bcliston -- For -j command line option.
-}
-
diff --git a/lib/LuaJIT/jit/bcsave.lua b/lib/LuaJIT/jit/bcsave.lua
deleted file mode 100644
index 2553d97..0000000
--- a/lib/LuaJIT/jit/bcsave.lua
+++ /dev/null
@@ -1,661 +0,0 @@
-----------------------------------------------------------------------------
--- LuaJIT module to save/list bytecode.
---
--- Copyright (C) 2005-2017 Mike Pall. All rights reserved.
--- Released under the MIT license. See Copyright Notice in luajit.h
-----------------------------------------------------------------------------
---
--- This module saves or lists the bytecode for an input file.
--- It's run by the -b command line option.
---
-------------------------------------------------------------------------------
-
-local jit = require("jit")
-assert(jit.version_num == 20100, "LuaJIT core/library version mismatch")
-local bit = require("bit")
-
--- Symbol name prefix for LuaJIT bytecode.
-local LJBC_PREFIX = "luaJIT_BC_"
-
-------------------------------------------------------------------------------
-
-local function usage()
- io.stderr:write[[
-Save LuaJIT bytecode: luajit -b[options] input output
- -l Only list bytecode.
- -s Strip debug info (default).
- -g Keep debug info.
- -n name Set module name (default: auto-detect from input name).
- -t type Set output file type (default: auto-detect from output name).
- -a arch Override architecture for object files (default: native).
- -o os Override OS for object files (default: native).
- -e chunk Use chunk string as input.
- -- Stop handling options.
- - Use stdin as input and/or stdout as output.
-
-File types: c h obj o raw (default)
-]]
- os.exit(1)
-end
-
-local function check(ok, ...)
- if ok then return ok, ... end
- io.stderr:write("luajit: ", ...)
- io.stderr:write("\n")
- os.exit(1)
-end
-
-local function readfile(input)
- if type(input) == "function" then return input end
- if input == "-" then input = nil end
- return check(loadfile(input))
-end
-
-local function savefile(name, mode)
- if name == "-" then return io.stdout end
- return check(io.open(name, mode))
-end
-
-------------------------------------------------------------------------------
-
-local map_type = {
- raw = "raw", c = "c", h = "h", o = "obj", obj = "obj",
-}
-
-local map_arch = {
- x86 = true, x64 = true, arm = true, arm64 = true, arm64be = true,
- ppc = true, mips = true, mipsel = true,
-}
-
-local map_os = {
- linux = true, windows = true, osx = true, freebsd = true, netbsd = true,
- openbsd = true, dragonfly = true, solaris = true,
-}
-
-local function checkarg(str, map, err)
- str = string.lower(str)
- local s = check(map[str], "unknown ", err)
- return s == true and str or s
-end
-
-local function detecttype(str)
- local ext = string.match(string.lower(str), "%.(%a+)$")
- return map_type[ext] or "raw"
-end
-
-local function checkmodname(str)
- check(string.match(str, "^[%w_.%-]+$"), "bad module name")
- return string.gsub(str, "[%.%-]", "_")
-end
-
-local function detectmodname(str)
- if type(str) == "string" then
- local tail = string.match(str, "[^/\\]+$")
- if tail then str = tail end
- local head = string.match(str, "^(.*)%.[^.]*$")
- if head then str = head end
- str = string.match(str, "^[%w_.%-]+")
- else
- str = nil
- end
- check(str, "cannot derive module name, use -n name")
- return string.gsub(str, "[%.%-]", "_")
-end
-
-------------------------------------------------------------------------------
-
-local function bcsave_tail(fp, output, s)
- local ok, err = fp:write(s)
- if ok and output ~= "-" then ok, err = fp:close() end
- check(ok, "cannot write ", output, ": ", err)
-end
-
-local function bcsave_raw(output, s)
- local fp = savefile(output, "wb")
- bcsave_tail(fp, output, s)
-end
-
-local function bcsave_c(ctx, output, s)
- local fp = savefile(output, "w")
- if ctx.type == "c" then
- fp:write(string.format([[
-#ifdef _cplusplus
-extern "C"
-#endif
-#ifdef _WIN32
-__declspec(dllexport)
-#endif
-const unsigned char %s%s[] = {
-]], LJBC_PREFIX, ctx.modname))
- else
- fp:write(string.format([[
-#define %s%s_SIZE %d
-static const unsigned char %s%s[] = {
-]], LJBC_PREFIX, ctx.modname, #s, LJBC_PREFIX, ctx.modname))
- end
- local t, n, m = {}, 0, 0
- for i=1,#s do
- local b = tostring(string.byte(s, i))
- m = m + #b + 1
- if m > 78 then
- fp:write(table.concat(t, ",", 1, n), ",\n")
- n, m = 0, #b + 1
- end
- n = n + 1
- t[n] = b
- end
- bcsave_tail(fp, output, table.concat(t, ",", 1, n).."\n};\n")
-end
-
-local function bcsave_elfobj(ctx, output, s, ffi)
- ffi.cdef[[
-typedef struct {
- uint8_t emagic[4], eclass, eendian, eversion, eosabi, eabiversion, epad[7];
- uint16_t type, machine;
- uint32_t version;
- uint32_t entry, phofs, shofs;
- uint32_t flags;
- uint16_t ehsize, phentsize, phnum, shentsize, shnum, shstridx;
-} ELF32header;
-typedef struct {
- uint8_t emagic[4], eclass, eendian, eversion, eosabi, eabiversion, epad[7];
- uint16_t type, machine;
- uint32_t version;
- uint64_t entry, phofs, shofs;
- uint32_t flags;
- uint16_t ehsize, phentsize, phnum, shentsize, shnum, shstridx;
-} ELF64header;
-typedef struct {
- uint32_t name, type, flags, addr, ofs, size, link, info, align, entsize;
-} ELF32sectheader;
-typedef struct {
- uint32_t name, type;
- uint64_t flags, addr, ofs, size;
- uint32_t link, info;
- uint64_t align, entsize;
-} ELF64sectheader;
-typedef struct {
- uint32_t name, value, size;
- uint8_t info, other;
- uint16_t sectidx;
-} ELF32symbol;
-typedef struct {
- uint32_t name;
- uint8_t info, other;
- uint16_t sectidx;
- uint64_t value, size;
-} ELF64symbol;
-typedef struct {
- ELF32header hdr;
- ELF32sectheader sect[6];
- ELF32symbol sym[2];
- uint8_t space[4096];
-} ELF32obj;
-typedef struct {
- ELF64header hdr;
- ELF64sectheader sect[6];
- ELF64symbol sym[2];
- uint8_t space[4096];
-} ELF64obj;
-]]
- local symname = LJBC_PREFIX..ctx.modname
- local is64, isbe = false, false
- if ctx.arch == "x64" or ctx.arch == "arm64" or ctx.arch == "arm64be" then
- is64 = true
- elseif ctx.arch == "ppc" or ctx.arch == "mips" then
- isbe = true
- end
-
- -- Handle different host/target endianess.
- local function f32(x) return x end
- local f16, fofs = f32, f32
- if ffi.abi("be") ~= isbe then
- f32 = bit.bswap
- function f16(x) return bit.rshift(bit.bswap(x), 16) end
- if is64 then
- local two32 = ffi.cast("int64_t", 2^32)
- function fofs(x) return bit.bswap(x)*two32 end
- else
- fofs = f32
- end
- end
-
- -- Create ELF object and fill in header.
- local o = ffi.new(is64 and "ELF64obj" or "ELF32obj")
- local hdr = o.hdr
- if ctx.os == "bsd" or ctx.os == "other" then -- Determine native hdr.eosabi.
- local bf = assert(io.open("/bin/ls", "rb"))
- local bs = bf:read(9)
- bf:close()
- ffi.copy(o, bs, 9)
- check(hdr.emagic[0] == 127, "no support for writing native object files")
- else
- hdr.emagic = "\127ELF"
- hdr.eosabi = ({ freebsd=9, netbsd=2, openbsd=12, solaris=6 })[ctx.os] or 0
- end
- hdr.eclass = is64 and 2 or 1
- hdr.eendian = isbe and 2 or 1
- hdr.eversion = 1
- hdr.type = f16(1)
- hdr.machine = f16(({ x86=3, x64=62, arm=40, arm64=183, arm64be=183, ppc=20, mips=8, mipsel=8 })[ctx.arch])
- if ctx.arch == "mips" or ctx.arch == "mipsel" then
- hdr.flags = f32(0x50001006)
- end
- hdr.version = f32(1)
- hdr.shofs = fofs(ffi.offsetof(o, "sect"))
- hdr.ehsize = f16(ffi.sizeof(hdr))
- hdr.shentsize = f16(ffi.sizeof(o.sect[0]))
- hdr.shnum = f16(6)
- hdr.shstridx = f16(2)
-
- -- Fill in sections and symbols.
- local sofs, ofs = ffi.offsetof(o, "space"), 1
- for i,name in ipairs{
- ".symtab", ".shstrtab", ".strtab", ".rodata", ".note.GNU-stack",
- } do
- local sect = o.sect[i]
- sect.align = fofs(1)
- sect.name = f32(ofs)
- ffi.copy(o.space+ofs, name)
- ofs = ofs + #name+1
- end
- o.sect[1].type = f32(2) -- .symtab
- o.sect[1].link = f32(3)
- o.sect[1].info = f32(1)
- o.sect[1].align = fofs(8)
- o.sect[1].ofs = fofs(ffi.offsetof(o, "sym"))
- o.sect[1].entsize = fofs(ffi.sizeof(o.sym[0]))
- o.sect[1].size = fofs(ffi.sizeof(o.sym))
- o.sym[1].name = f32(1)
- o.sym[1].sectidx = f16(4)
- o.sym[1].size = fofs(#s)
- o.sym[1].info = 17
- o.sect[2].type = f32(3) -- .shstrtab
- o.sect[2].ofs = fofs(sofs)
- o.sect[2].size = fofs(ofs)
- o.sect[3].type = f32(3) -- .strtab
- o.sect[3].ofs = fofs(sofs + ofs)
- o.sect[3].size = fofs(#symname+2)
- ffi.copy(o.space+ofs+1, symname)
- ofs = ofs + #symname + 2
- o.sect[4].type = f32(1) -- .rodata
- o.sect[4].flags = fofs(2)
- o.sect[4].ofs = fofs(sofs + ofs)
- o.sect[4].size = fofs(#s)
- o.sect[5].type = f32(1) -- .note.GNU-stack
- o.sect[5].ofs = fofs(sofs + ofs + #s)
-
- -- Write ELF object file.
- local fp = savefile(output, "wb")
- fp:write(ffi.string(o, ffi.sizeof(o)-4096+ofs))
- bcsave_tail(fp, output, s)
-end
-
-local function bcsave_peobj(ctx, output, s, ffi)
- ffi.cdef[[
-typedef struct {
- uint16_t arch, nsects;
- uint32_t time, symtabofs, nsyms;
- uint16_t opthdrsz, flags;
-} PEheader;
-typedef struct {
- char name[8];
- uint32_t vsize, vaddr, size, ofs, relocofs, lineofs;
- uint16_t nreloc, nline;
- uint32_t flags;
-} PEsection;
-typedef struct __attribute((packed)) {
- union {
- char name[8];
- uint32_t nameref[2];
- };
- uint32_t value;
- int16_t sect;
- uint16_t type;
- uint8_t scl, naux;
-} PEsym;
-typedef struct __attribute((packed)) {
- uint32_t size;
- uint16_t nreloc, nline;
- uint32_t cksum;
- uint16_t assoc;
- uint8_t comdatsel, unused[3];
-} PEsymaux;
-typedef struct {
- PEheader hdr;
- PEsection sect[2];
- // Must be an even number of symbol structs.
- PEsym sym0;
- PEsymaux sym0aux;
- PEsym sym1;
- PEsymaux sym1aux;
- PEsym sym2;
- PEsym sym3;
- uint32_t strtabsize;
- uint8_t space[4096];
-} PEobj;
-]]
- local symname = LJBC_PREFIX..ctx.modname
- local is64 = false
- if ctx.arch == "x86" then
- symname = "_"..symname
- elseif ctx.arch == "x64" then
- is64 = true
- end
- local symexport = " /EXPORT:"..symname..",DATA "
-
- -- The file format is always little-endian. Swap if the host is big-endian.
- local function f32(x) return x end
- local f16 = f32
- if ffi.abi("be") then
- f32 = bit.bswap
- function f16(x) return bit.rshift(bit.bswap(x), 16) end
- end
-
- -- Create PE object and fill in header.
- local o = ffi.new("PEobj")
- local hdr = o.hdr
- hdr.arch = f16(({ x86=0x14c, x64=0x8664, arm=0x1c0, ppc=0x1f2, mips=0x366, mipsel=0x366 })[ctx.arch])
- hdr.nsects = f16(2)
- hdr.symtabofs = f32(ffi.offsetof(o, "sym0"))
- hdr.nsyms = f32(6)
-
- -- Fill in sections and symbols.
- o.sect[0].name = ".drectve"
- o.sect[0].size = f32(#symexport)
- o.sect[0].flags = f32(0x00100a00)
- o.sym0.sect = f16(1)
- o.sym0.scl = 3
- o.sym0.name = ".drectve"
- o.sym0.naux = 1
- o.sym0aux.size = f32(#symexport)
- o.sect[1].name = ".rdata"
- o.sect[1].size = f32(#s)
- o.sect[1].flags = f32(0x40300040)
- o.sym1.sect = f16(2)
- o.sym1.scl = 3
- o.sym1.name = ".rdata"
- o.sym1.naux = 1
- o.sym1aux.size = f32(#s)
- o.sym2.sect = f16(2)
- o.sym2.scl = 2
- o.sym2.nameref[1] = f32(4)
- o.sym3.sect = f16(-1)
- o.sym3.scl = 2
- o.sym3.value = f32(1)
- o.sym3.name = "@feat.00" -- Mark as SafeSEH compliant.
- ffi.copy(o.space, symname)
- local ofs = #symname + 1
- o.strtabsize = f32(ofs + 4)
- o.sect[0].ofs = f32(ffi.offsetof(o, "space") + ofs)
- ffi.copy(o.space + ofs, symexport)
- ofs = ofs + #symexport
- o.sect[1].ofs = f32(ffi.offsetof(o, "space") + ofs)
-
- -- Write PE object file.
- local fp = savefile(output, "wb")
- fp:write(ffi.string(o, ffi.sizeof(o)-4096+ofs))
- bcsave_tail(fp, output, s)
-end
-
-local function bcsave_machobj(ctx, output, s, ffi)
- ffi.cdef[[
-typedef struct
-{
- uint32_t magic, cputype, cpusubtype, filetype, ncmds, sizeofcmds, flags;
-} mach_header;
-typedef struct
-{
- mach_header; uint32_t reserved;
-} mach_header_64;
-typedef struct {
- uint32_t cmd, cmdsize;
- char segname[16];
- uint32_t vmaddr, vmsize, fileoff, filesize;
- uint32_t maxprot, initprot, nsects, flags;
-} mach_segment_command;
-typedef struct {
- uint32_t cmd, cmdsize;
- char segname[16];
- uint64_t vmaddr, vmsize, fileoff, filesize;
- uint32_t maxprot, initprot, nsects, flags;
-} mach_segment_command_64;
-typedef struct {
- char sectname[16], segname[16];
- uint32_t addr, size;
- uint32_t offset, align, reloff, nreloc, flags;
- uint32_t reserved1, reserved2;
-} mach_section;
-typedef struct {
- char sectname[16], segname[16];
- uint64_t addr, size;
- uint32_t offset, align, reloff, nreloc, flags;
- uint32_t reserved1, reserved2, reserved3;
-} mach_section_64;
-typedef struct {
- uint32_t cmd, cmdsize, symoff, nsyms, stroff, strsize;
-} mach_symtab_command;
-typedef struct {
- int32_t strx;
- uint8_t type, sect;
- int16_t desc;
- uint32_t value;
-} mach_nlist;
-typedef struct {
- uint32_t strx;
- uint8_t type, sect;
- uint16_t desc;
- uint64_t value;
-} mach_nlist_64;
-typedef struct
-{
- uint32_t magic, nfat_arch;
-} mach_fat_header;
-typedef struct
-{
- uint32_t cputype, cpusubtype, offset, size, align;
-} mach_fat_arch;
-typedef struct {
- struct {
- mach_header hdr;
- mach_segment_command seg;
- mach_section sec;
- mach_symtab_command sym;
- } arch[1];
- mach_nlist sym_entry;
- uint8_t space[4096];
-} mach_obj;
-typedef struct {
- struct {
- mach_header_64 hdr;
- mach_segment_command_64 seg;
- mach_section_64 sec;
- mach_symtab_command sym;
- } arch[1];
- mach_nlist_64 sym_entry;
- uint8_t space[4096];
-} mach_obj_64;
-typedef struct {
- mach_fat_header fat;
- mach_fat_arch fat_arch[2];
- struct {
- mach_header hdr;
- mach_segment_command seg;
- mach_section sec;
- mach_symtab_command sym;
- } arch[2];
- mach_nlist sym_entry;
- uint8_t space[4096];
-} mach_fat_obj;
-]]
- local symname = '_'..LJBC_PREFIX..ctx.modname
- local isfat, is64, align, mobj = false, false, 4, "mach_obj"
- if ctx.arch == "x64" then
- is64, align, mobj = true, 8, "mach_obj_64"
- elseif ctx.arch == "arm" then
- isfat, mobj = true, "mach_fat_obj"
- elseif ctx.arch == "arm64" then
- is64, align, isfat, mobj = true, 8, true, "mach_fat_obj"
- else
- check(ctx.arch == "x86", "unsupported architecture for OSX")
- end
- local function aligned(v, a) return bit.band(v+a-1, -a) end
- local be32 = bit.bswap -- Mach-O FAT is BE, supported archs are LE.
-
- -- Create Mach-O object and fill in header.
- local o = ffi.new(mobj)
- local mach_size = aligned(ffi.offsetof(o, "space")+#symname+2, align)
- local cputype = ({ x86={7}, x64={0x01000007}, arm={7,12}, arm64={0x01000007,0x0100000c} })[ctx.arch]
- local cpusubtype = ({ x86={3}, x64={3}, arm={3,9}, arm64={3,0} })[ctx.arch]
- if isfat then
- o.fat.magic = be32(0xcafebabe)
- o.fat.nfat_arch = be32(#cpusubtype)
- end
-
- -- Fill in sections and symbols.
- for i=0,#cpusubtype-1 do
- local ofs = 0
- if isfat then
- local a = o.fat_arch[i]
- a.cputype = be32(cputype[i+1])
- a.cpusubtype = be32(cpusubtype[i+1])
- -- Subsequent slices overlap each other to share data.
- ofs = ffi.offsetof(o, "arch") + i*ffi.sizeof(o.arch[0])
- a.offset = be32(ofs)
- a.size = be32(mach_size-ofs+#s)
- end
- local a = o.arch[i]
- a.hdr.magic = is64 and 0xfeedfacf or 0xfeedface
- a.hdr.cputype = cputype[i+1]
- a.hdr.cpusubtype = cpusubtype[i+1]
- a.hdr.filetype = 1
- a.hdr.ncmds = 2
- a.hdr.sizeofcmds = ffi.sizeof(a.seg)+ffi.sizeof(a.sec)+ffi.sizeof(a.sym)
- a.seg.cmd = is64 and 0x19 or 0x1
- a.seg.cmdsize = ffi.sizeof(a.seg)+ffi.sizeof(a.sec)
- a.seg.vmsize = #s
- a.seg.fileoff = mach_size-ofs
- a.seg.filesize = #s
- a.seg.maxprot = 1
- a.seg.initprot = 1
- a.seg.nsects = 1
- ffi.copy(a.sec.sectname, "__data")
- ffi.copy(a.sec.segname, "__DATA")
- a.sec.size = #s
- a.sec.offset = mach_size-ofs
- a.sym.cmd = 2
- a.sym.cmdsize = ffi.sizeof(a.sym)
- a.sym.symoff = ffi.offsetof(o, "sym_entry")-ofs
- a.sym.nsyms = 1
- a.sym.stroff = ffi.offsetof(o, "sym_entry")+ffi.sizeof(o.sym_entry)-ofs
- a.sym.strsize = aligned(#symname+2, align)
- end
- o.sym_entry.type = 0xf
- o.sym_entry.sect = 1
- o.sym_entry.strx = 1
- ffi.copy(o.space+1, symname)
-
- -- Write Macho-O object file.
- local fp = savefile(output, "wb")
- fp:write(ffi.string(o, mach_size))
- bcsave_tail(fp, output, s)
-end
-
-local function bcsave_obj(ctx, output, s)
- local ok, ffi = pcall(require, "ffi")
- check(ok, "FFI library required to write this file type")
- if ctx.os == "windows" then
- return bcsave_peobj(ctx, output, s, ffi)
- elseif ctx.os == "osx" then
- return bcsave_machobj(ctx, output, s, ffi)
- else
- return bcsave_elfobj(ctx, output, s, ffi)
- end
-end
-
-------------------------------------------------------------------------------
-
-local function bclist(input, output)
- local f = readfile(input)
- require("jit.bc").dump(f, savefile(output, "w"), true)
-end
-
-local function bcsave(ctx, input, output)
- local f = readfile(input)
- local s = string.dump(f, ctx.strip)
- local t = ctx.type
- if not t then
- t = detecttype(output)
- ctx.type = t
- end
- if t == "raw" then
- bcsave_raw(output, s)
- else
- if not ctx.modname then ctx.modname = detectmodname(input) end
- if t == "obj" then
- bcsave_obj(ctx, output, s)
- else
- bcsave_c(ctx, output, s)
- end
- end
-end
-
-local function docmd(...)
- local arg = {...}
- local n = 1
- local list = false
- local ctx = {
- strip = true, arch = jit.arch, os = string.lower(jit.os),
- type = false, modname = false,
- }
- while n <= #arg do
- local a = arg[n]
- if type(a) == "string" and string.sub(a, 1, 1) == "-" and a ~= "-" then
- table.remove(arg, n)
- if a == "--" then break end
- for m=2,#a do
- local opt = string.sub(a, m, m)
- if opt == "l" then
- list = true
- elseif opt == "s" then
- ctx.strip = true
- elseif opt == "g" then
- ctx.strip = false
- else
- if arg[n] == nil or m ~= #a then usage() end
- if opt == "e" then
- if n ~= 1 then usage() end
- arg[1] = check(loadstring(arg[1]))
- elseif opt == "n" then
- ctx.modname = checkmodname(table.remove(arg, n))
- elseif opt == "t" then
- ctx.type = checkarg(table.remove(arg, n), map_type, "file type")
- elseif opt == "a" then
- ctx.arch = checkarg(table.remove(arg, n), map_arch, "architecture")
- elseif opt == "o" then
- ctx.os = checkarg(table.remove(arg, n), map_os, "OS name")
- else
- usage()
- end
- end
- end
- else
- n = n + 1
- end
- end
- if list then
- if #arg == 0 or #arg > 2 then usage() end
- bclist(arg[1], arg[2] or "-")
- else
- if #arg ~= 2 then usage() end
- bcsave(ctx, arg[1], arg[2])
- end
-end
-
-------------------------------------------------------------------------------
-
--- Public module functions.
-return {
- start = docmd -- Process -b command line option.
-}
-
diff --git a/lib/LuaJIT/jit/dis_arm.lua b/lib/LuaJIT/jit/dis_arm.lua
deleted file mode 100644
index c2dd776..0000000
--- a/lib/LuaJIT/jit/dis_arm.lua
+++ /dev/null
@@ -1,689 +0,0 @@
-----------------------------------------------------------------------------
--- LuaJIT ARM disassembler module.
---
--- Copyright (C) 2005-2017 Mike Pall. All rights reserved.
--- Released under the MIT license. See Copyright Notice in luajit.h
-----------------------------------------------------------------------------
--- This is a helper module used by the LuaJIT machine code dumper module.
---
--- It disassembles most user-mode ARMv7 instructions
--- NYI: Advanced SIMD and VFP instructions.
-------------------------------------------------------------------------------
-
-local type = type
-local sub, byte, format = string.sub, string.byte, string.format
-local match, gmatch = string.match, string.gmatch
-local concat = table.concat
-local bit = require("bit")
-local band, bor, ror, tohex = bit.band, bit.bor, bit.ror, bit.tohex
-local lshift, rshift, arshift = bit.lshift, bit.rshift, bit.arshift
-
-------------------------------------------------------------------------------
--- Opcode maps
-------------------------------------------------------------------------------
-
-local map_loadc = {
- shift = 8, mask = 15,
- [10] = {
- shift = 20, mask = 1,
- [0] = {
- shift = 23, mask = 3,
- [0] = "vmovFmDN", "vstmFNdr",
- _ = {
- shift = 21, mask = 1,
- [0] = "vstrFdl",
- { shift = 16, mask = 15, [13] = "vpushFdr", _ = "vstmdbFNdr", }
- },
- },
- {
- shift = 23, mask = 3,
- [0] = "vmovFDNm",
- { shift = 16, mask = 15, [13] = "vpopFdr", _ = "vldmFNdr", },
- _ = {
- shift = 21, mask = 1,
- [0] = "vldrFdl", "vldmdbFNdr",
- },
- },
- },
- [11] = {
- shift = 20, mask = 1,
- [0] = {
- shift = 23, mask = 3,
- [0] = "vmovGmDN", "vstmGNdr",
- _ = {
- shift = 21, mask = 1,
- [0] = "vstrGdl",
- { shift = 16, mask = 15, [13] = "vpushGdr", _ = "vstmdbGNdr", }
- },
- },
- {
- shift = 23, mask = 3,
- [0] = "vmovGDNm",
- { shift = 16, mask = 15, [13] = "vpopGdr", _ = "vldmGNdr", },
- _ = {
- shift = 21, mask = 1,
- [0] = "vldrGdl", "vldmdbGNdr",
- },
- },
- },
- _ = {
- shift = 0, mask = 0 -- NYI ldc, mcrr, mrrc.
- },
-}
-
-local map_vfps = {
- shift = 6, mask = 0x2c001,
- [0] = "vmlaF.dnm", "vmlsF.dnm",
- [0x04000] = "vnmlsF.dnm", [0x04001] = "vnmlaF.dnm",
- [0x08000] = "vmulF.dnm", [0x08001] = "vnmulF.dnm",
- [0x0c000] = "vaddF.dnm", [0x0c001] = "vsubF.dnm",
- [0x20000] = "vdivF.dnm",
- [0x24000] = "vfnmsF.dnm", [0x24001] = "vfnmaF.dnm",
- [0x28000] = "vfmaF.dnm", [0x28001] = "vfmsF.dnm",
- [0x2c000] = "vmovF.dY",
- [0x2c001] = {
- shift = 7, mask = 0x1e01,
- [0] = "vmovF.dm", "vabsF.dm",
- [0x0200] = "vnegF.dm", [0x0201] = "vsqrtF.dm",
- [0x0800] = "vcmpF.dm", [0x0801] = "vcmpeF.dm",
- [0x0a00] = "vcmpzF.d", [0x0a01] = "vcmpzeF.d",
- [0x0e01] = "vcvtG.dF.m",
- [0x1000] = "vcvt.f32.u32Fdm", [0x1001] = "vcvt.f32.s32Fdm",
- [0x1800] = "vcvtr.u32F.dm", [0x1801] = "vcvt.u32F.dm",
- [0x1a00] = "vcvtr.s32F.dm", [0x1a01] = "vcvt.s32F.dm",
- },
-}
-
-local map_vfpd = {
- shift = 6, mask = 0x2c001,
- [0] = "vmlaG.dnm", "vmlsG.dnm",
- [0x04000] = "vnmlsG.dnm", [0x04001] = "vnmlaG.dnm",
- [0x08000] = "vmulG.dnm", [0x08001] = "vnmulG.dnm",
- [0x0c000] = "vaddG.dnm", [0x0c001] = "vsubG.dnm",
- [0x20000] = "vdivG.dnm",
- [0x24000] = "vfnmsG.dnm", [0x24001] = "vfnmaG.dnm",
- [0x28000] = "vfmaG.dnm", [0x28001] = "vfmsG.dnm",
- [0x2c000] = "vmovG.dY",
- [0x2c001] = {
- shift = 7, mask = 0x1e01,
- [0] = "vmovG.dm", "vabsG.dm",
- [0x0200] = "vnegG.dm", [0x0201] = "vsqrtG.dm",
- [0x0800] = "vcmpG.dm", [0x0801] = "vcmpeG.dm",
- [0x0a00] = "vcmpzG.d", [0x0a01] = "vcmpzeG.d",
- [0x0e01] = "vcvtF.dG.m",
- [0x1000] = "vcvt.f64.u32GdFm", [0x1001] = "vcvt.f64.s32GdFm",
- [0x1800] = "vcvtr.u32FdG.m", [0x1801] = "vcvt.u32FdG.m",
- [0x1a00] = "vcvtr.s32FdG.m", [0x1a01] = "vcvt.s32FdG.m",
- },
-}
-
-local map_datac = {
- shift = 24, mask = 1,
- [0] = {
- shift = 4, mask = 1,
- [0] = {
- shift = 8, mask = 15,
- [10] = map_vfps,
- [11] = map_vfpd,
- -- NYI cdp, mcr, mrc.
- },
- {
- shift = 8, mask = 15,
- [10] = {
- shift = 20, mask = 15,
- [0] = "vmovFnD", "vmovFDn",
- [14] = "vmsrD",
- [15] = { shift = 12, mask = 15, [15] = "vmrs", _ = "vmrsD", },
- },
- },
- },
- "svcT",
-}
-
-local map_loadcu = {
- shift = 0, mask = 0, -- NYI unconditional CP load/store.
-}
-
-local map_datacu = {
- shift = 0, mask = 0, -- NYI unconditional CP data.
-}
-
-local map_simddata = {
- shift = 0, mask = 0, -- NYI SIMD data.
-}
-
-local map_simdload = {
- shift = 0, mask = 0, -- NYI SIMD load/store, preload.
-}
-
-local map_preload = {
- shift = 0, mask = 0, -- NYI preload.
-}
-
-local map_media = {
- shift = 20, mask = 31,
- [0] = false,
- { --01
- shift = 5, mask = 7,
- [0] = "sadd16DNM", "sasxDNM", "ssaxDNM", "ssub16DNM",
- "sadd8DNM", false, false, "ssub8DNM",
- },
- { --02
- shift = 5, mask = 7,
- [0] = "qadd16DNM", "qasxDNM", "qsaxDNM", "qsub16DNM",
- "qadd8DNM", false, false, "qsub8DNM",
- },
- { --03
- shift = 5, mask = 7,
- [0] = "shadd16DNM", "shasxDNM", "shsaxDNM", "shsub16DNM",
- "shadd8DNM", false, false, "shsub8DNM",
- },
- false,
- { --05
- shift = 5, mask = 7,
- [0] = "uadd16DNM", "uasxDNM", "usaxDNM", "usub16DNM",
- "uadd8DNM", false, false, "usub8DNM",
- },
- { --06
- shift = 5, mask = 7,
- [0] = "uqadd16DNM", "uqasxDNM", "uqsaxDNM", "uqsub16DNM",
- "uqadd8DNM", false, false, "uqsub8DNM",
- },
- { --07
- shift = 5, mask = 7,
- [0] = "uhadd16DNM", "uhasxDNM", "uhsaxDNM", "uhsub16DNM",
- "uhadd8DNM", false, false, "uhsub8DNM",
- },
- { --08
- shift = 5, mask = 7,
- [0] = "pkhbtDNMU", false, "pkhtbDNMU",
- { shift = 16, mask = 15, [15] = "sxtb16DMU", _ = "sxtab16DNMU", },
- "pkhbtDNMU", "selDNM", "pkhtbDNMU",
- },
- false,
- { --0a
- shift = 5, mask = 7,
- [0] = "ssatDxMu", "ssat16DxM", "ssatDxMu",
- { shift = 16, mask = 15, [15] = "sxtbDMU", _ = "sxtabDNMU", },
- "ssatDxMu", false, "ssatDxMu",
- },
- { --0b
- shift = 5, mask = 7,
- [0] = "ssatDxMu", "revDM", "ssatDxMu",
- { shift = 16, mask = 15, [15] = "sxthDMU", _ = "sxtahDNMU", },
- "ssatDxMu", "rev16DM", "ssatDxMu",
- },
- { --0c
- shift = 5, mask = 7,
- [3] = { shift = 16, mask = 15, [15] = "uxtb16DMU", _ = "uxtab16DNMU", },
- },
- false,
- { --0e
- shift = 5, mask = 7,
- [0] = "usatDwMu", "usat16DwM", "usatDwMu",
- { shift = 16, mask = 15, [15] = "uxtbDMU", _ = "uxtabDNMU", },
- "usatDwMu", false, "usatDwMu",
- },
- { --0f
- shift = 5, mask = 7,
- [0] = "usatDwMu", "rbitDM", "usatDwMu",
- { shift = 16, mask = 15, [15] = "uxthDMU", _ = "uxtahDNMU", },
- "usatDwMu", "revshDM", "usatDwMu",
- },
- { --10
- shift = 12, mask = 15,
- [15] = {
- shift = 5, mask = 7,
- "smuadNMS", "smuadxNMS", "smusdNMS", "smusdxNMS",
- },
- _ = {
- shift = 5, mask = 7,
- [0] = "smladNMSD", "smladxNMSD", "smlsdNMSD", "smlsdxNMSD",
- },
- },
- false, false, false,
- { --14
- shift = 5, mask = 7,
- [0] = "smlaldDNMS", "smlaldxDNMS", "smlsldDNMS", "smlsldxDNMS",
- },
- { --15
- shift = 5, mask = 7,
- [0] = { shift = 12, mask = 15, [15] = "smmulNMS", _ = "smmlaNMSD", },
- { shift = 12, mask = 15, [15] = "smmulrNMS", _ = "smmlarNMSD", },
- false, false, false, false,
- "smmlsNMSD", "smmlsrNMSD",
- },
- false, false,
- { --18
- shift = 5, mask = 7,
- [0] = { shift = 12, mask = 15, [15] = "usad8NMS", _ = "usada8NMSD", },
- },
- false,
- { --1a
- shift = 5, mask = 3, [2] = "sbfxDMvw",
- },
- { --1b
- shift = 5, mask = 3, [2] = "sbfxDMvw",
- },
- { --1c
- shift = 5, mask = 3,
- [0] = { shift = 0, mask = 15, [15] = "bfcDvX", _ = "bfiDMvX", },
- },
- { --1d
- shift = 5, mask = 3,
- [0] = { shift = 0, mask = 15, [15] = "bfcDvX", _ = "bfiDMvX", },
- },
- { --1e
- shift = 5, mask = 3, [2] = "ubfxDMvw",
- },
- { --1f
- shift = 5, mask = 3, [2] = "ubfxDMvw",
- },
-}
-
-local map_load = {
- shift = 21, mask = 9,
- {
- shift = 20, mask = 5,
- [0] = "strtDL", "ldrtDL", [4] = "strbtDL", [5] = "ldrbtDL",
- },
- _ = {
- shift = 20, mask = 5,
- [0] = "strDL", "ldrDL", [4] = "strbDL", [5] = "ldrbDL",
- }
-}
-
-local map_load1 = {
- shift = 4, mask = 1,
- [0] = map_load, map_media,
-}
-
-local map_loadm = {
- shift = 20, mask = 1,
- [0] = {
- shift = 23, mask = 3,
- [0] = "stmdaNR", "stmNR",
- { shift = 16, mask = 63, [45] = "pushR", _ = "stmdbNR", }, "stmibNR",
- },
- {
- shift = 23, mask = 3,
- [0] = "ldmdaNR", { shift = 16, mask = 63, [61] = "popR", _ = "ldmNR", },
- "ldmdbNR", "ldmibNR",
- },
-}
-
-local map_data = {
- shift = 21, mask = 15,
- [0] = "andDNPs", "eorDNPs", "subDNPs", "rsbDNPs",
- "addDNPs", "adcDNPs", "sbcDNPs", "rscDNPs",
- "tstNP", "teqNP", "cmpNP", "cmnNP",
- "orrDNPs", "movDPs", "bicDNPs", "mvnDPs",
-}
-
-local map_mul = {
- shift = 21, mask = 7,
- [0] = "mulNMSs", "mlaNMSDs", "umaalDNMS", "mlsDNMS",
- "umullDNMSs", "umlalDNMSs", "smullDNMSs", "smlalDNMSs",
-}
-
-local map_sync = {
- shift = 20, mask = 15, -- NYI: brackets around N. R(D+1) for ldrexd/strexd.
- [0] = "swpDMN", false, false, false,
- "swpbDMN", false, false, false,
- "strexDMN", "ldrexDN", "strexdDN", "ldrexdDN",
- "strexbDMN", "ldrexbDN", "strexhDN", "ldrexhDN",
-}
-
-local map_mulh = {
- shift = 21, mask = 3,
- [0] = { shift = 5, mask = 3,
- [0] = "smlabbNMSD", "smlatbNMSD", "smlabtNMSD", "smlattNMSD", },
- { shift = 5, mask = 3,
- [0] = "smlawbNMSD", "smulwbNMS", "smlawtNMSD", "smulwtNMS", },
- { shift = 5, mask = 3,
- [0] = "smlalbbDNMS", "smlaltbDNMS", "smlalbtDNMS", "smlalttDNMS", },
- { shift = 5, mask = 3,
- [0] = "smulbbNMS", "smultbNMS", "smulbtNMS", "smulttNMS", },
-}
-
-local map_misc = {
- shift = 4, mask = 7,
- -- NYI: decode PSR bits of msr.
- [0] = { shift = 21, mask = 1, [0] = "mrsD", "msrM", },
- { shift = 21, mask = 3, "bxM", false, "clzDM", },
- { shift = 21, mask = 3, "bxjM", },
- { shift = 21, mask = 3, "blxM", },
- false,
- { shift = 21, mask = 3, [0] = "qaddDMN", "qsubDMN", "qdaddDMN", "qdsubDMN", },
- false,
- { shift = 21, mask = 3, "bkptK", },
-}
-
-local map_datar = {
- shift = 4, mask = 9,
- [9] = {
- shift = 5, mask = 3,
- [0] = { shift = 24, mask = 1, [0] = map_mul, map_sync, },
- { shift = 20, mask = 1, [0] = "strhDL", "ldrhDL", },
- { shift = 20, mask = 1, [0] = "ldrdDL", "ldrsbDL", },
- { shift = 20, mask = 1, [0] = "strdDL", "ldrshDL", },
- },
- _ = {
- shift = 20, mask = 25,
- [16] = { shift = 7, mask = 1, [0] = map_misc, map_mulh, },
- _ = {
- shift = 0, mask = 0xffffffff,
- [bor(0xe1a00000)] = "nop",
- _ = map_data,
- }
- },
-}
-
-local map_datai = {
- shift = 20, mask = 31, -- NYI: decode PSR bits of msr. Decode imm12.
- [16] = "movwDW", [20] = "movtDW",
- [18] = { shift = 0, mask = 0xf00ff, [0] = "nopv6", _ = "msrNW", },
- [22] = "msrNW",
- _ = map_data,
-}
-
-local map_branch = {
- shift = 24, mask = 1,
- [0] = "bB", "blB"
-}
-
-local map_condins = {
- [0] = map_datar, map_datai, map_load, map_load1,
- map_loadm, map_branch, map_loadc, map_datac
-}
-
--- NYI: setend.
-local map_uncondins = {
- [0] = false, map_simddata, map_simdload, map_preload,
- false, "blxB", map_loadcu, map_datacu,
-}
-
-------------------------------------------------------------------------------
-
-local map_gpr = {
- [0] = "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
- "r8", "r9", "r10", "r11", "r12", "sp", "lr", "pc",
-}
-
-local map_cond = {
- [0] = "eq", "ne", "hs", "lo", "mi", "pl", "vs", "vc",
- "hi", "ls", "ge", "lt", "gt", "le", "al",
-}
-
-local map_shift = { [0] = "lsl", "lsr", "asr", "ror", }
-
-------------------------------------------------------------------------------
-
--- Output a nicely formatted line with an opcode and operands.
-local function putop(ctx, text, operands)
- local pos = ctx.pos
- local extra = ""
- if ctx.rel then
- local sym = ctx.symtab[ctx.rel]
- if sym then
- extra = "\t->"..sym
- elseif band(ctx.op, 0x0e000000) ~= 0x0a000000 then
- extra = "\t; 0x"..tohex(ctx.rel)
- end
- end
- if ctx.hexdump > 0 then
- ctx.out(format("%08x %s %-5s %s%s\n",
- ctx.addr+pos, tohex(ctx.op), text, concat(operands, ", "), extra))
- else
- ctx.out(format("%08x %-5s %s%s\n",
- ctx.addr+pos, text, concat(operands, ", "), extra))
- end
- ctx.pos = pos + 4
-end
-
--- Fallback for unknown opcodes.
-local function unknown(ctx)
- return putop(ctx, ".long", { "0x"..tohex(ctx.op) })
-end
-
--- Format operand 2 of load/store opcodes.
-local function fmtload(ctx, op, pos)
- local base = map_gpr[band(rshift(op, 16), 15)]
- local x, ofs
- local ext = (band(op, 0x04000000) == 0)
- if not ext and band(op, 0x02000000) == 0 then
- ofs = band(op, 4095)
- if band(op, 0x00800000) == 0 then ofs = -ofs end
- if base == "pc" then ctx.rel = ctx.addr + pos + 8 + ofs end
- ofs = "#"..ofs
- elseif ext and band(op, 0x00400000) ~= 0 then
- ofs = band(op, 15) + band(rshift(op, 4), 0xf0)
- if band(op, 0x00800000) == 0 then ofs = -ofs end
- if base == "pc" then ctx.rel = ctx.addr + pos + 8 + ofs end
- ofs = "#"..ofs
- else
- ofs = map_gpr[band(op, 15)]
- if ext or band(op, 0xfe0) == 0 then
- elseif band(op, 0xfe0) == 0x60 then
- ofs = format("%s, rrx", ofs)
- else
- local sh = band(rshift(op, 7), 31)
- if sh == 0 then sh = 32 end
- ofs = format("%s, %s #%d", ofs, map_shift[band(rshift(op, 5), 3)], sh)
- end
- if band(op, 0x00800000) == 0 then ofs = "-"..ofs end
- end
- if ofs == "#0" then
- x = format("[%s]", base)
- elseif band(op, 0x01000000) == 0 then
- x = format("[%s], %s", base, ofs)
- else
- x = format("[%s, %s]", base, ofs)
- end
- if band(op, 0x01200000) == 0x01200000 then x = x.."!" end
- return x
-end
-
--- Format operand 2 of vector load/store opcodes.
-local function fmtvload(ctx, op, pos)
- local base = map_gpr[band(rshift(op, 16), 15)]
- local ofs = band(op, 255)*4
- if band(op, 0x00800000) == 0 then ofs = -ofs end
- if base == "pc" then ctx.rel = ctx.addr + pos + 8 + ofs end
- if ofs == 0 then
- return format("[%s]", base)
- else
- return format("[%s, #%d]", base, ofs)
- end
-end
-
-local function fmtvr(op, vr, sh0, sh1)
- if vr == "s" then
- return format("s%d", 2*band(rshift(op, sh0), 15)+band(rshift(op, sh1), 1))
- else
- return format("d%d", band(rshift(op, sh0), 15)+band(rshift(op, sh1-4), 16))
- end
-end
-
--- Disassemble a single instruction.
-local function disass_ins(ctx)
- local pos = ctx.pos
- local b0, b1, b2, b3 = byte(ctx.code, pos+1, pos+4)
- local op = bor(lshift(b3, 24), lshift(b2, 16), lshift(b1, 8), b0)
- local operands = {}
- local suffix = ""
- local last, name, pat
- local vr
- ctx.op = op
- ctx.rel = nil
-
- local cond = rshift(op, 28)
- local opat
- if cond == 15 then
- opat = map_uncondins[band(rshift(op, 25), 7)]
- else
- if cond ~= 14 then suffix = map_cond[cond] end
- opat = map_condins[band(rshift(op, 25), 7)]
- end
- while type(opat) ~= "string" do
- if not opat then return unknown(ctx) end
- opat = opat[band(rshift(op, opat.shift), opat.mask)] or opat._
- end
- name, pat = match(opat, "^([a-z0-9]*)(.*)")
- if sub(pat, 1, 1) == "." then
- local s2, p2 = match(pat, "^([a-z0-9.]*)(.*)")
- suffix = suffix..s2
- pat = p2
- end
-
- for p in gmatch(pat, ".") do
- local x = nil
- if p == "D" then
- x = map_gpr[band(rshift(op, 12), 15)]
- elseif p == "N" then
- x = map_gpr[band(rshift(op, 16), 15)]
- elseif p == "S" then
- x = map_gpr[band(rshift(op, 8), 15)]
- elseif p == "M" then
- x = map_gpr[band(op, 15)]
- elseif p == "d" then
- x = fmtvr(op, vr, 12, 22)
- elseif p == "n" then
- x = fmtvr(op, vr, 16, 7)
- elseif p == "m" then
- x = fmtvr(op, vr, 0, 5)
- elseif p == "P" then
- if band(op, 0x02000000) ~= 0 then
- x = ror(band(op, 255), 2*band(rshift(op, 8), 15))
- else
- x = map_gpr[band(op, 15)]
- if band(op, 0xff0) ~= 0 then
- operands[#operands+1] = x
- local s = map_shift[band(rshift(op, 5), 3)]
- local r = nil
- if band(op, 0xf90) == 0 then
- if s == "ror" then s = "rrx" else r = "#32" end
- elseif band(op, 0x10) == 0 then
- r = "#"..band(rshift(op, 7), 31)
- else
- r = map_gpr[band(rshift(op, 8), 15)]
- end
- if name == "mov" then name = s; x = r
- elseif r then x = format("%s %s", s, r)
- else x = s end
- end
- end
- elseif p == "L" then
- x = fmtload(ctx, op, pos)
- elseif p == "l" then
- x = fmtvload(ctx, op, pos)
- elseif p == "B" then
- local addr = ctx.addr + pos + 8 + arshift(lshift(op, 8), 6)
- if cond == 15 then addr = addr + band(rshift(op, 23), 2) end
- ctx.rel = addr
- x = "0x"..tohex(addr)
- elseif p == "F" then
- vr = "s"
- elseif p == "G" then
- vr = "d"
- elseif p == "." then
- suffix = suffix..(vr == "s" and ".f32" or ".f64")
- elseif p == "R" then
- if band(op, 0x00200000) ~= 0 and #operands == 1 then
- operands[1] = operands[1].."!"
- end
- local t = {}
- for i=0,15 do
- if band(rshift(op, i), 1) == 1 then t[#t+1] = map_gpr[i] end
- end
- x = "{"..concat(t, ", ").."}"
- elseif p == "r" then
- if band(op, 0x00200000) ~= 0 and #operands == 2 then
- operands[1] = operands[1].."!"
- end
- local s = tonumber(sub(last, 2))
- local n = band(op, 255)
- if vr == "d" then n = rshift(n, 1) end
- operands[#operands] = format("{%s-%s%d}", last, vr, s+n-1)
- elseif p == "W" then
- x = band(op, 0x0fff) + band(rshift(op, 4), 0xf000)
- elseif p == "T" then
- x = "#0x"..tohex(band(op, 0x00ffffff), 6)
- elseif p == "U" then
- x = band(rshift(op, 7), 31)
- if x == 0 then x = nil end
- elseif p == "u" then
- x = band(rshift(op, 7), 31)
- if band(op, 0x40) == 0 then
- if x == 0 then x = nil else x = "lsl #"..x end
- else
- if x == 0 then x = "asr #32" else x = "asr #"..x end
- end
- elseif p == "v" then
- x = band(rshift(op, 7), 31)
- elseif p == "w" then
- x = band(rshift(op, 16), 31)
- elseif p == "x" then
- x = band(rshift(op, 16), 31) + 1
- elseif p == "X" then
- x = band(rshift(op, 16), 31) - last + 1
- elseif p == "Y" then
- x = band(rshift(op, 12), 0xf0) + band(op, 0x0f)
- elseif p == "K" then
- x = "#0x"..tohex(band(rshift(op, 4), 0x0000fff0) + band(op, 15), 4)
- elseif p == "s" then
- if band(op, 0x00100000) ~= 0 then suffix = "s"..suffix end
- else
- assert(false)
- end
- if x then
- last = x
- if type(x) == "number" then x = "#"..x end
- operands[#operands+1] = x
- end
- end
-
- return putop(ctx, name..suffix, operands)
-end
-
-------------------------------------------------------------------------------
-
--- Disassemble a block of code.
-local function disass_block(ctx, ofs, len)
- if not ofs then ofs = 0 end
- local stop = len and ofs+len or #ctx.code
- ctx.pos = ofs
- ctx.rel = nil
- while ctx.pos < stop do disass_ins(ctx) end
-end
-
--- Extended API: create a disassembler context. Then call ctx:disass(ofs, len).
-local function create(code, addr, out)
- local ctx = {}
- ctx.code = code
- ctx.addr = addr or 0
- ctx.out = out or io.write
- ctx.symtab = {}
- ctx.disass = disass_block
- ctx.hexdump = 8
- return ctx
-end
-
--- Simple API: disassemble code (a string) at address and output via out.
-local function disass(code, addr, out)
- create(code, addr, out):disass()
-end
-
--- Return register name for RID.
-local function regname(r)
- if r < 16 then return map_gpr[r] end
- return "d"..(r-16)
-end
-
--- Public module functions.
-return {
- create = create,
- disass = disass,
- regname = regname
-}
-
diff --git a/lib/LuaJIT/jit/dis_arm64.lua b/lib/LuaJIT/jit/dis_arm64.lua
deleted file mode 100644
index a717332..0000000
--- a/lib/LuaJIT/jit/dis_arm64.lua
+++ /dev/null
@@ -1,1216 +0,0 @@
-----------------------------------------------------------------------------
--- LuaJIT ARM64 disassembler module.
---
--- Copyright (C) 2005-2017 Mike Pall. All rights reserved.
--- Released under the MIT license. See Copyright Notice in luajit.h
---
--- Contributed by Djordje Kovacevic and Stefan Pejic from RT-RK.com.
--- Sponsored by Cisco Systems, Inc.
-----------------------------------------------------------------------------
--- This is a helper module used by the LuaJIT machine code dumper module.
---
--- It disassembles most user-mode AArch64 instructions.
--- NYI: Advanced SIMD and VFP instructions.
-------------------------------------------------------------------------------
-
-local type = type
-local sub, byte, format = string.sub, string.byte, string.format
-local match, gmatch, gsub = string.match, string.gmatch, string.gsub
-local concat = table.concat
-local bit = require("bit")
-local band, bor, bxor, tohex = bit.band, bit.bor, bit.bxor, bit.tohex
-local lshift, rshift, arshift = bit.lshift, bit.rshift, bit.arshift
-local ror = bit.ror
-
-------------------------------------------------------------------------------
--- Opcode maps
-------------------------------------------------------------------------------
-
-local map_adr = { -- PC-relative addressing.
- shift = 31, mask = 1,
- [0] = "adrDBx", "adrpDBx"
-}
-
-local map_addsubi = { -- Add/subtract immediate.
- shift = 29, mask = 3,
- [0] = "add|movDNIg", "adds|cmnD0NIg", "subDNIg", "subs|cmpD0NIg",
-}
-
-local map_logi = { -- Logical immediate.
- shift = 31, mask = 1,
- [0] = {
- shift = 22, mask = 1,
- [0] = {
- shift = 29, mask = 3,
- [0] = "andDNig", "orr|movDN0ig", "eorDNig", "ands|tstD0Nig"
- },
- false -- unallocated
- },
- {
- shift = 29, mask = 3,
- [0] = "andDNig", "orr|movDN0ig", "eorDNig", "ands|tstD0Nig"
- }
-}
-
-local map_movwi = { -- Move wide immediate.
- shift = 31, mask = 1,
- [0] = {
- shift = 22, mask = 1,
- [0] = {
- shift = 29, mask = 3,
- [0] = "movnDWRg", false, "movz|movDYRg", "movkDWRg"
- }, false -- unallocated
- },
- {
- shift = 29, mask = 3,
- [0] = "movnDWRg", false, "movz|movDYRg", "movkDWRg"
- },
-}
-
-local map_bitf = { -- Bitfield.
- shift = 31, mask = 1,
- [0] = {
- shift = 22, mask = 1,
- [0] = {
- shift = 29, mask = 3,
- [0] = "sbfm|sbfiz|sbfx|asr|sxtw|sxth|sxtbDN12w",
- "bfm|bfi|bfxilDN13w",
- "ubfm|ubfiz|ubfx|lsr|lsl|uxth|uxtbDN12w"
- }
- },
- {
- shift = 22, mask = 1,
- {
- shift = 29, mask = 3,
- [0] = "sbfm|sbfiz|sbfx|asr|sxtw|sxth|sxtbDN12x",
- "bfm|bfi|bfxilDN13x",
- "ubfm|ubfiz|ubfx|lsr|lsl|uxth|uxtbDN12x"
- }
- }
-}
-
-local map_datai = { -- Data processing - immediate.
- shift = 23, mask = 7,
- [0] = map_adr, map_adr, map_addsubi, false,
- map_logi, map_movwi, map_bitf,
- {
- shift = 15, mask = 0x1c0c1,
- [0] = "extr|rorDNM4w", [0x10080] = "extr|rorDNM4x",
- [0x10081] = "extr|rorDNM4x"
- }
-}
-
-local map_logsr = { -- Logical, shifted register.
- shift = 31, mask = 1,
- [0] = {
- shift = 15, mask = 1,
- [0] = {
- shift = 29, mask = 3,
- [0] = {
- shift = 21, mask = 7,
- [0] = "andDNMSg", "bicDNMSg", "andDNMSg", "bicDNMSg",
- "andDNMSg", "bicDNMSg", "andDNMg", "bicDNMg"
- },
- {
- shift = 21, mask = 7,
- [0] ="orr|movDN0MSg", "orn|mvnDN0MSg", "orr|movDN0MSg", "orn|mvnDN0MSg",
- "orr|movDN0MSg", "orn|mvnDN0MSg", "orr|movDN0Mg", "orn|mvnDN0Mg"
- },
- {
- shift = 21, mask = 7,
- [0] = "eorDNMSg", "eonDNMSg", "eorDNMSg", "eonDNMSg",
- "eorDNMSg", "eonDNMSg", "eorDNMg", "eonDNMg"
- },
- {
- shift = 21, mask = 7,
- [0] = "ands|tstD0NMSg", "bicsDNMSg", "ands|tstD0NMSg", "bicsDNMSg",
- "ands|tstD0NMSg", "bicsDNMSg", "ands|tstD0NMg", "bicsDNMg"
- }
- },
- false -- unallocated
- },
- {
- shift = 29, mask = 3,
- [0] = {
- shift = 21, mask = 7,
- [0] = "andDNMSg", "bicDNMSg", "andDNMSg", "bicDNMSg",
- "andDNMSg", "bicDNMSg", "andDNMg", "bicDNMg"
- },
- {
- shift = 21, mask = 7,
- [0] = "orr|movDN0MSg", "orn|mvnDN0MSg", "orr|movDN0MSg", "orn|mvnDN0MSg",
- "orr|movDN0MSg", "orn|mvnDN0MSg", "orr|movDN0Mg", "orn|mvnDN0Mg"
- },
- {
- shift = 21, mask = 7,
- [0] = "eorDNMSg", "eonDNMSg", "eorDNMSg", "eonDNMSg",
- "eorDNMSg", "eonDNMSg", "eorDNMg", "eonDNMg"
- },
- {
- shift = 21, mask = 7,
- [0] = "ands|tstD0NMSg", "bicsDNMSg", "ands|tstD0NMSg", "bicsDNMSg",
- "ands|tstD0NMSg", "bicsDNMSg", "ands|tstD0NMg", "bicsDNMg"
- }
- }
-}
-
-local map_assh = {
- shift = 31, mask = 1,
- [0] = {
- shift = 15, mask = 1,
- [0] = {
- shift = 29, mask = 3,
- [0] = {
- shift = 22, mask = 3,
- [0] = "addDNMSg", "addDNMSg", "addDNMSg", "addDNMg"
- },
- {
- shift = 22, mask = 3,
- [0] = "adds|cmnD0NMSg", "adds|cmnD0NMSg",
- "adds|cmnD0NMSg", "adds|cmnD0NMg"
- },
- {
- shift = 22, mask = 3,
- [0] = "sub|negDN0MSg", "sub|negDN0MSg", "sub|negDN0MSg", "sub|negDN0Mg"
- },
- {
- shift = 22, mask = 3,
- [0] = "subs|cmp|negsD0N0MzSg", "subs|cmp|negsD0N0MzSg",
- "subs|cmp|negsD0N0MzSg", "subs|cmp|negsD0N0Mzg"
- },
- },
- false -- unallocated
- },
- {
- shift = 29, mask = 3,
- [0] = {
- shift = 22, mask = 3,
- [0] = "addDNMSg", "addDNMSg", "addDNMSg", "addDNMg"
- },
- {
- shift = 22, mask = 3,
- [0] = "adds|cmnD0NMSg", "adds|cmnD0NMSg", "adds|cmnD0NMSg",
- "adds|cmnD0NMg"
- },
- {
- shift = 22, mask = 3,
- [0] = "sub|negDN0MSg", "sub|negDN0MSg", "sub|negDN0MSg", "sub|negDN0Mg"
- },
- {
- shift = 22, mask = 3,
- [0] = "subs|cmp|negsD0N0MzSg", "subs|cmp|negsD0N0MzSg",
- "subs|cmp|negsD0N0MzSg", "subs|cmp|negsD0N0Mzg"
- }
- }
-}
-
-local map_addsubsh = { -- Add/subtract, shifted register.
- shift = 22, mask = 3,
- [0] = map_assh, map_assh, map_assh
-}
-
-local map_addsubex = { -- Add/subtract, extended register.
- shift = 22, mask = 3,
- [0] = {
- shift = 29, mask = 3,
- [0] = "addDNMXg", "adds|cmnD0NMXg", "subDNMXg", "subs|cmpD0NMzXg",
- }
-}
-
-local map_addsubc = { -- Add/subtract, with carry.
- shift = 10, mask = 63,
- [0] = {
- shift = 29, mask = 3,
- [0] = "adcDNMg", "adcsDNMg", "sbc|ngcDN0Mg", "sbcs|ngcsDN0Mg",
- }
-}
-
-local map_ccomp = {
- shift = 4, mask = 1,
- [0] = {
- shift = 10, mask = 3,
- [0] = { -- Conditional compare register.
- shift = 29, mask = 3,
- "ccmnNMVCg", false, "ccmpNMVCg",
- },
- [2] = { -- Conditional compare immediate.
- shift = 29, mask = 3,
- "ccmnN5VCg", false, "ccmpN5VCg",
- }
- }
-}
-
-local map_csel = { -- Conditional select.
- shift = 11, mask = 1,
- [0] = {
- shift = 10, mask = 1,
- [0] = {
- shift = 29, mask = 3,
- [0] = "cselDNMzCg", false, "csinv|cinv|csetmDNMcg", false,
- },
- {
- shift = 29, mask = 3,
- [0] = "csinc|cinc|csetDNMcg", false, "csneg|cnegDNMcg", false,
- }
- }
-}
-
-local map_data1s = { -- Data processing, 1 source.
- shift = 29, mask = 1,
- [0] = {
- shift = 31, mask = 1,
- [0] = {
- shift = 10, mask = 0x7ff,
- [0] = "rbitDNg", "rev16DNg", "revDNw", false, "clzDNg", "clsDNg"
- },
- {
- shift = 10, mask = 0x7ff,
- [0] = "rbitDNg", "rev16DNg", "rev32DNx", "revDNx", "clzDNg", "clsDNg"
- }
- }
-}
-
-local map_data2s = { -- Data processing, 2 sources.
- shift = 29, mask = 1,
- [0] = {
- shift = 10, mask = 63,
- false, "udivDNMg", "sdivDNMg", false, false, false, false, "lslDNMg",
- "lsrDNMg", "asrDNMg", "rorDNMg"
- }
-}
-
-local map_data3s = { -- Data processing, 3 sources.
- shift = 29, mask = 7,
- [0] = {
- shift = 21, mask = 7,
- [0] = {
- shift = 15, mask = 1,
- [0] = "madd|mulDNMA0g", "msub|mnegDNMA0g"
- }
- }, false, false, false,
- {
- shift = 15, mask = 1,
- [0] = {
- shift = 21, mask = 7,
- [0] = "madd|mulDNMA0g", "smaddl|smullDxNMwA0x", "smulhDNMx", false,
- false, "umaddl|umullDxNMwA0x", "umulhDNMx"
- },
- {
- shift = 21, mask = 7,
- [0] = "msub|mnegDNMA0g", "smsubl|smneglDxNMwA0x", false, false,
- false, "umsubl|umneglDxNMwA0x"
- }
- }
-}
-
-local map_datar = { -- Data processing, register.
- shift = 28, mask = 1,
- [0] = {
- shift = 24, mask = 1,
- [0] = map_logsr,
- {
- shift = 21, mask = 1,
- [0] = map_addsubsh, map_addsubex
- }
- },
- {
- shift = 21, mask = 15,
- [0] = map_addsubc, false, map_ccomp, false, map_csel, false,
- {
- shift = 30, mask = 1,
- [0] = map_data2s, map_data1s
- },
- false, map_data3s, map_data3s, map_data3s, map_data3s, map_data3s,
- map_data3s, map_data3s, map_data3s
- }
-}
-
-local map_lrl = { -- Load register, literal.
- shift = 26, mask = 1,
- [0] = {
- shift = 30, mask = 3,
- [0] = "ldrDwB", "ldrDxB", "ldrswDxB"
- },
- {
- shift = 30, mask = 3,
- [0] = "ldrDsB", "ldrDdB"
- }
-}
-
-local map_lsriind = { -- Load/store register, immediate pre/post-indexed.
- shift = 30, mask = 3,
- [0] = {
- shift = 26, mask = 1,
- [0] = {
- shift = 22, mask = 3,
- [0] = "strbDwzL", "ldrbDwzL", "ldrsbDxzL", "ldrsbDwzL"
- }
- },
- {
- shift = 26, mask = 1,
- [0] = {
- shift = 22, mask = 3,
- [0] = "strhDwzL", "ldrhDwzL", "ldrshDxzL", "ldrshDwzL"
- }
- },
- {
- shift = 26, mask = 1,
- [0] = {
- shift = 22, mask = 3,
- [0] = "strDwzL", "ldrDwzL", "ldrswDxzL"
- },
- {
- shift = 22, mask = 3,
- [0] = "strDszL", "ldrDszL"
- }
- },
- {
- shift = 26, mask = 1,
- [0] = {
- shift = 22, mask = 3,
- [0] = "strDxzL", "ldrDxzL"
- },
- {
- shift = 22, mask = 3,
- [0] = "strDdzL", "ldrDdzL"
- }
- }
-}
-
-local map_lsriro = {
- shift = 21, mask = 1,
- [0] = { -- Load/store register immediate.
- shift = 10, mask = 3,
- [0] = { -- Unscaled immediate.
- shift = 26, mask = 1,
- [0] = {
- shift = 30, mask = 3,
- [0] = {
- shift = 22, mask = 3,
- [0] = "sturbDwK", "ldurbDwK"
- },
- {
- shift = 22, mask = 3,
- [0] = "sturhDwK", "ldurhDwK"
- },
- {
- shift = 22, mask = 3,
- [0] = "sturDwK", "ldurDwK"
- },
- {
- shift = 22, mask = 3,
- [0] = "sturDxK", "ldurDxK"
- }
- }
- }, map_lsriind, false, map_lsriind
- },
- { -- Load/store register, register offset.
- shift = 10, mask = 3,
- [2] = {
- shift = 26, mask = 1,
- [0] = {
- shift = 30, mask = 3,
- [0] = {
- shift = 22, mask = 3,
- [0] = "strbDwO", "ldrbDwO", "ldrsbDxO", "ldrsbDwO"
- },
- {
- shift = 22, mask = 3,
- [0] = "strhDwO", "ldrhDwO", "ldrshDxO", "ldrshDwO"
- },
- {
- shift = 22, mask = 3,
- [0] = "strDwO", "ldrDwO", "ldrswDxO"
- },
- {
- shift = 22, mask = 3,
- [0] = "strDxO", "ldrDxO"
- }
- },
- {
- shift = 30, mask = 3,
- [2] = {
- shift = 22, mask = 3,
- [0] = "strDsO", "ldrDsO"
- },
- [3] = {
- shift = 22, mask = 3,
- [0] = "strDdO", "ldrDdO"
- }
- }
- }
- }
-}
-
-local map_lsp = { -- Load/store register pair, offset.
- shift = 22, mask = 1,
- [0] = {
- shift = 30, mask = 3,
- [0] = {
- shift = 26, mask = 1,
- [0] = "stpDzAzwP", "stpDzAzsP",
- },
- {
- shift = 26, mask = 1,
- "stpDzAzdP"
- },
- {
- shift = 26, mask = 1,
- [0] = "stpDzAzxP"
- }
- },
- {
- shift = 30, mask = 3,
- [0] = {
- shift = 26, mask = 1,
- [0] = "ldpDzAzwP", "ldpDzAzsP",
- },
- {
- shift = 26, mask = 1,
- [0] = "ldpswDAxP", "ldpDzAzdP"
- },
- {
- shift = 26, mask = 1,
- [0] = "ldpDzAzxP"
- }
- }
-}
-
-local map_ls = { -- Loads and stores.
- shift = 24, mask = 0x31,
- [0x10] = map_lrl, [0x30] = map_lsriro,
- [0x20] = {
- shift = 23, mask = 3,
- map_lsp, map_lsp, map_lsp
- },
- [0x21] = {
- shift = 23, mask = 3,
- map_lsp, map_lsp, map_lsp
- },
- [0x31] = {
- shift = 26, mask = 1,
- [0] = {
- shift = 30, mask = 3,
- [0] = {
- shift = 22, mask = 3,
- [0] = "strbDwzU", "ldrbDwzU"
- },
- {
- shift = 22, mask = 3,
- [0] = "strhDwzU", "ldrhDwzU"
- },
- {
- shift = 22, mask = 3,
- [0] = "strDwzU", "ldrDwzU"
- },
- {
- shift = 22, mask = 3,
- [0] = "strDxzU", "ldrDxzU"
- }
- },
- {
- shift = 30, mask = 3,
- [2] = {
- shift = 22, mask = 3,
- [0] = "strDszU", "ldrDszU"
- },
- [3] = {
- shift = 22, mask = 3,
- [0] = "strDdzU", "ldrDdzU"
- }
- }
- },
-}
-
-local map_datafp = { -- Data processing, SIMD and FP.
- shift = 28, mask = 7,
- { -- 001
- shift = 24, mask = 1,
- [0] = {
- shift = 21, mask = 1,
- {
- shift = 10, mask = 3,
- [0] = {
- shift = 12, mask = 1,
- [0] = {
- shift = 13, mask = 1,
- [0] = {
- shift = 14, mask = 1,
- [0] = {
- shift = 15, mask = 1,
- [0] = { -- FP/int conversion.
- shift = 31, mask = 1,
- [0] = {
- shift = 16, mask = 0xff,
- [0x20] = "fcvtnsDwNs", [0x21] = "fcvtnuDwNs",
- [0x22] = "scvtfDsNw", [0x23] = "ucvtfDsNw",
- [0x24] = "fcvtasDwNs", [0x25] = "fcvtauDwNs",
- [0x26] = "fmovDwNs", [0x27] = "fmovDsNw",
- [0x28] = "fcvtpsDwNs", [0x29] = "fcvtpuDwNs",
- [0x30] = "fcvtmsDwNs", [0x31] = "fcvtmuDwNs",
- [0x38] = "fcvtzsDwNs", [0x39] = "fcvtzuDwNs",
- [0x60] = "fcvtnsDwNd", [0x61] = "fcvtnuDwNd",
- [0x62] = "scvtfDdNw", [0x63] = "ucvtfDdNw",
- [0x64] = "fcvtasDwNd", [0x65] = "fcvtauDwNd",
- [0x68] = "fcvtpsDwNd", [0x69] = "fcvtpuDwNd",
- [0x70] = "fcvtmsDwNd", [0x71] = "fcvtmuDwNd",
- [0x78] = "fcvtzsDwNd", [0x79] = "fcvtzuDwNd"
- },
- {
- shift = 16, mask = 0xff,
- [0x20] = "fcvtnsDxNs", [0x21] = "fcvtnuDxNs",
- [0x22] = "scvtfDsNx", [0x23] = "ucvtfDsNx",
- [0x24] = "fcvtasDxNs", [0x25] = "fcvtauDxNs",
- [0x28] = "fcvtpsDxNs", [0x29] = "fcvtpuDxNs",
- [0x30] = "fcvtmsDxNs", [0x31] = "fcvtmuDxNs",
- [0x38] = "fcvtzsDxNs", [0x39] = "fcvtzuDxNs",
- [0x60] = "fcvtnsDxNd", [0x61] = "fcvtnuDxNd",
- [0x62] = "scvtfDdNx", [0x63] = "ucvtfDdNx",
- [0x64] = "fcvtasDxNd", [0x65] = "fcvtauDxNd",
- [0x66] = "fmovDxNd", [0x67] = "fmovDdNx",
- [0x68] = "fcvtpsDxNd", [0x69] = "fcvtpuDxNd",
- [0x70] = "fcvtmsDxNd", [0x71] = "fcvtmuDxNd",
- [0x78] = "fcvtzsDxNd", [0x79] = "fcvtzuDxNd"
- }
- }
- },
- { -- FP data-processing, 1 source.
- shift = 31, mask = 1,
- [0] = {
- shift = 22, mask = 3,
- [0] = {
- shift = 15, mask = 63,
- [0] = "fmovDNf", "fabsDNf", "fnegDNf",
- "fsqrtDNf", false, "fcvtDdNs", false, false,
- "frintnDNf", "frintpDNf", "frintmDNf", "frintzDNf",
- "frintaDNf", false, "frintxDNf", "frintiDNf",
- },
- {
- shift = 15, mask = 63,
- [0] = "fmovDNf", "fabsDNf", "fnegDNf",
- "fsqrtDNf", "fcvtDsNd", false, false, false,
- "frintnDNf", "frintpDNf", "frintmDNf", "frintzDNf",
- "frintaDNf", false, "frintxDNf", "frintiDNf",
- }
- }
- }
- },
- { -- FP compare.
- shift = 31, mask = 1,
- [0] = {
- shift = 14, mask = 3,
- [0] = {
- shift = 23, mask = 1,
- [0] = {
- shift = 0, mask = 31,
- [0] = "fcmpNMf", [8] = "fcmpNZf",
- [16] = "fcmpeNMf", [24] = "fcmpeNZf",
- }
- }
- }
- }
- },
- { -- FP immediate.
- shift = 31, mask = 1,
- [0] = {
- shift = 5, mask = 31,
- [0] = {
- shift = 23, mask = 1,
- [0] = "fmovDFf"
- }
- }
- }
- },
- { -- FP conditional compare.
- shift = 31, mask = 1,
- [0] = {
- shift = 23, mask = 1,
- [0] = {
- shift = 4, mask = 1,
- [0] = "fccmpNMVCf", "fccmpeNMVCf"
- }
- }
- },
- { -- FP data-processing, 2 sources.
- shift = 31, mask = 1,
- [0] = {
- shift = 23, mask = 1,
- [0] = {
- shift = 12, mask = 15,
- [0] = "fmulDNMf", "fdivDNMf", "faddDNMf", "fsubDNMf",
- "fmaxDNMf", "fminDNMf", "fmaxnmDNMf", "fminnmDNMf",
- "fnmulDNMf"
- }
- }
- },
- { -- FP conditional select.
- shift = 31, mask = 1,
- [0] = {
- shift = 23, mask = 1,
- [0] = "fcselDNMCf"
- }
- }
- }
- },
- { -- FP data-processing, 3 sources.
- shift = 31, mask = 1,
- [0] = {
- shift = 15, mask = 1,
- [0] = {
- shift = 21, mask = 5,
- [0] = "fmaddDNMAf", "fnmaddDNMAf"
- },
- {
- shift = 21, mask = 5,
- [0] = "fmsubDNMAf", "fnmsubDNMAf"
- }
- }
- }
- }
-}
-
-local map_br = { -- Branches, exception generating and system instructions.
- shift = 29, mask = 7,
- [0] = "bB",
- { -- Compare & branch, immediate.
- shift = 24, mask = 3,
- [0] = "cbzDBg", "cbnzDBg", "tbzDTBw", "tbnzDTBw"
- },
- { -- Conditional branch, immediate.
- shift = 24, mask = 3,
- [0] = {
- shift = 4, mask = 1,
- [0] = {
- shift = 0, mask = 15,
- [0] = "beqB", "bneB", "bhsB", "bloB", "bmiB", "bplB", "bvsB", "bvcB",
- "bhiB", "blsB", "bgeB", "bltB", "bgtB", "bleB", "balB"
- }
- }
- }, false, "blB",
- { -- Compare & branch, immediate.
- shift = 24, mask = 3,
- [0] = "cbzDBg", "cbnzDBg", "tbzDTBx", "tbnzDTBx"
- },
- {
- shift = 24, mask = 3,
- [0] = { -- Exception generation.
- shift = 0, mask = 0xe0001f,
- [0x200000] = "brkW"
- },
- { -- System instructions.
- shift = 0, mask = 0x3fffff,
- [0x03201f] = "nop"
- },
- { -- Unconditional branch, register.
- shift = 0, mask = 0xfffc1f,
- [0x1f0000] = "brNx", [0x3f0000] = "blrNx",
- [0x5f0000] = "retNx"
- },
- }
-}
-
-local map_init = {
- shift = 25, mask = 15,
- [0] = false, false, false, false, map_ls, map_datar, map_ls, map_datafp,
- map_datai, map_datai, map_br, map_br, map_ls, map_datar, map_ls, map_datafp
-}
-
-------------------------------------------------------------------------------
-
-local map_regs = { x = {}, w = {}, d = {}, s = {} }
-
-for i=0,30 do
- map_regs.x[i] = "x"..i
- map_regs.w[i] = "w"..i
- map_regs.d[i] = "d"..i
- map_regs.s[i] = "s"..i
-end
-map_regs.x[31] = "sp"
-map_regs.w[31] = "wsp"
-map_regs.d[31] = "d31"
-map_regs.s[31] = "s31"
-
-local map_cond = {
- [0] = "eq", "ne", "cs", "cc", "mi", "pl", "vs", "vc",
- "hi", "ls", "ge", "lt", "gt", "le", "al",
-}
-
-local map_shift = { [0] = "lsl", "lsr", "asr", }
-
-local map_extend = {
- [0] = "uxtb", "uxth", "uxtw", "uxtx", "sxtb", "sxth", "sxtw", "sxtx",
-}
-
-------------------------------------------------------------------------------
-
--- Output a nicely formatted line with an opcode and operands.
-local function putop(ctx, text, operands)
- local pos = ctx.pos
- local extra = ""
- if ctx.rel then
- local sym = ctx.symtab[ctx.rel]
- if sym then
- extra = "\t->"..sym
- end
- end
- if ctx.hexdump > 0 then
- ctx.out(format("%08x %s %-5s %s%s\n",
- ctx.addr+pos, tohex(ctx.op), text, concat(operands, ", "), extra))
- else
- ctx.out(format("%08x %-5s %s%s\n",
- ctx.addr+pos, text, concat(operands, ", "), extra))
- end
- ctx.pos = pos + 4
-end
-
--- Fallback for unknown opcodes.
-local function unknown(ctx)
- return putop(ctx, ".long", { "0x"..tohex(ctx.op) })
-end
-
-local function match_reg(p, pat, regnum)
- return map_regs[match(pat, p.."%w-([xwds])")][regnum]
-end
-
-local function fmt_hex32(x)
- if x < 0 then
- return tohex(x)
- else
- return format("%x", x)
- end
-end
-
-local imm13_rep = { 0x55555555, 0x11111111, 0x01010101, 0x00010001, 0x00000001 }
-
-local function decode_imm13(op)
- local imms = band(rshift(op, 10), 63)
- local immr = band(rshift(op, 16), 63)
- if band(op, 0x00400000) == 0 then
- local len = 5
- if imms >= 56 then
- if imms >= 60 then len = 1 else len = 2 end
- elseif imms >= 48 then len = 3 elseif imms >= 32 then len = 4 end
- local l = lshift(1, len)-1
- local s = band(imms, l)
- local r = band(immr, l)
- local imm = ror(rshift(-1, 31-s), r)
- if len ~= 5 then imm = band(imm, lshift(1, l)-1) + rshift(imm, 31-l) end
- imm = imm * imm13_rep[len]
- local ix = fmt_hex32(imm)
- if rshift(op, 31) ~= 0 then
- return ix..tohex(imm)
- else
- return ix
- end
- else
- local lo, hi = -1, 0
- if imms < 32 then lo = rshift(-1, 31-imms) else hi = rshift(-1, 63-imms) end
- if immr ~= 0 then
- lo, hi = ror(lo, immr), ror(hi, immr)
- local x = immr == 32 and 0 or band(bxor(lo, hi), lshift(-1, 32-immr))
- lo, hi = bxor(lo, x), bxor(hi, x)
- if immr >= 32 then lo, hi = hi, lo end
- end
- if hi ~= 0 then
- return fmt_hex32(hi)..tohex(lo)
- else
- return fmt_hex32(lo)
- end
- end
-end
-
-local function parse_immpc(op, name)
- if name == "b" or name == "bl" then
- return arshift(lshift(op, 6), 4)
- elseif name == "adr" or name == "adrp" then
- local immlo = band(rshift(op, 29), 3)
- local immhi = lshift(arshift(lshift(op, 8), 13), 2)
- return bor(immhi, immlo)
- elseif name == "tbz" or name == "tbnz" then
- return lshift(arshift(lshift(op, 13), 18), 2)
- else
- return lshift(arshift(lshift(op, 8), 13), 2)
- end
-end
-
-local function parse_fpimm8(op)
- local sign = band(op, 0x100000) == 0 and 1 or -1
- local exp = bxor(rshift(arshift(lshift(op, 12), 5), 24), 0x80) - 131
- local frac = 16+band(rshift(op, 13), 15)
- return sign * frac * 2^exp
-end
-
-local function prefer_bfx(sf, uns, imms, immr)
- if imms < immr or imms == 31 or imms == 63 then
- return false
- end
- if immr == 0 then
- if sf == 0 and (imms == 7 or imms == 15) then
- return false
- end
- if sf ~= 0 and uns == 0 and (imms == 7 or imms == 15 or imms == 31) then
- return false
- end
- end
- return true
-end
-
--- Disassemble a single instruction.
-local function disass_ins(ctx)
- local pos = ctx.pos
- local b0, b1, b2, b3 = byte(ctx.code, pos+1, pos+4)
- local op = bor(lshift(b3, 24), lshift(b2, 16), lshift(b1, 8), b0)
- local operands = {}
- local suffix = ""
- local last, name, pat
- local map_reg
- ctx.op = op
- ctx.rel = nil
- last = nil
- local opat
- opat = map_init[band(rshift(op, 25), 15)]
- while type(opat) ~= "string" do
- if not opat then return unknown(ctx) end
- opat = opat[band(rshift(op, opat.shift), opat.mask)] or opat._
- end
- name, pat = match(opat, "^([a-z0-9]*)(.*)")
- local altname, pat2 = match(pat, "|([a-z0-9_.|]*)(.*)")
- if altname then pat = pat2 end
- if sub(pat, 1, 1) == "." then
- local s2, p2 = match(pat, "^([a-z0-9.]*)(.*)")
- suffix = suffix..s2
- pat = p2
- end
-
- local rt = match(pat, "[gf]")
- if rt then
- if rt == "g" then
- map_reg = band(op, 0x80000000) ~= 0 and map_regs.x or map_regs.w
- else
- map_reg = band(op, 0x400000) ~= 0 and map_regs.d or map_regs.s
- end
- end
-
- local second0, immr
-
- for p in gmatch(pat, ".") do
- local x = nil
- if p == "D" then
- local regnum = band(op, 31)
- x = rt and map_reg[regnum] or match_reg(p, pat, regnum)
- elseif p == "N" then
- local regnum = band(rshift(op, 5), 31)
- x = rt and map_reg[regnum] or match_reg(p, pat, regnum)
- elseif p == "M" then
- local regnum = band(rshift(op, 16), 31)
- x = rt and map_reg[regnum] or match_reg(p, pat, regnum)
- elseif p == "A" then
- local regnum = band(rshift(op, 10), 31)
- x = rt and map_reg[regnum] or match_reg(p, pat, regnum)
- elseif p == "B" then
- local addr = ctx.addr + pos + parse_immpc(op, name)
- ctx.rel = addr
- x = "0x"..tohex(addr)
- elseif p == "T" then
- x = bor(band(rshift(op, 26), 32), band(rshift(op, 19), 31))
- elseif p == "V" then
- x = band(op, 15)
- elseif p == "C" then
- x = map_cond[band(rshift(op, 12), 15)]
- elseif p == "c" then
- local rn = band(rshift(op, 5), 31)
- local rm = band(rshift(op, 16), 31)
- local cond = band(rshift(op, 12), 15)
- local invc = bxor(cond, 1)
- x = map_cond[cond]
- if altname and cond ~= 14 and cond ~= 15 then
- local a1, a2 = match(altname, "([^|]*)|(.*)")
- if rn == rm then
- local n = #operands
- operands[n] = nil
- x = map_cond[invc]
- if rn ~= 31 then
- if a1 then name = a1 else name = altname end
- else
- operands[n-1] = nil
- name = a2
- end
- end
- end
- elseif p == "W" then
- x = band(rshift(op, 5), 0xffff)
- elseif p == "Y" then
- x = band(rshift(op, 5), 0xffff)
- local hw = band(rshift(op, 21), 3)
- if altname and (hw == 0 or x ~= 0) then
- name = altname
- end
- elseif p == "L" then
- local rn = map_regs.x[band(rshift(op, 5), 31)]
- local imm9 = arshift(lshift(op, 11), 23)
- if band(op, 0x800) ~= 0 then
- x = "["..rn..", #"..imm9.."]!"
- else
- x = "["..rn.."], #"..imm9
- end
- elseif p == "U" then
- local rn = map_regs.x[band(rshift(op, 5), 31)]
- local sz = band(rshift(op, 30), 3)
- local imm12 = lshift(arshift(lshift(op, 10), 20), sz)
- if imm12 ~= 0 then
- x = "["..rn..", #"..imm12.."]"
- else
- x = "["..rn.."]"
- end
- elseif p == "K" then
- local rn = map_regs.x[band(rshift(op, 5), 31)]
- local imm9 = arshift(lshift(op, 11), 23)
- if imm9 ~= 0 then
- x = "["..rn..", #"..imm9.."]"
- else
- x = "["..rn.."]"
- end
- elseif p == "O" then
- local rn, rm = map_regs.x[band(rshift(op, 5), 31)]
- local m = band(rshift(op, 13), 1)
- if m == 0 then
- rm = map_regs.w[band(rshift(op, 16), 31)]
- else
- rm = map_regs.x[band(rshift(op, 16), 31)]
- end
- x = "["..rn..", "..rm
- local opt = band(rshift(op, 13), 7)
- local s = band(rshift(op, 12), 1)
- local sz = band(rshift(op, 30), 3)
- -- extension to be applied
- if opt == 3 then
- if s == 0 then x = x.."]"
- else x = x..", lsl #"..sz.."]" end
- elseif opt == 2 or opt == 6 or opt == 7 then
- if s == 0 then x = x..", "..map_extend[opt].."]"
- else x = x..", "..map_extend[opt].." #"..sz.."]" end
- else
- x = x.."]"
- end
- elseif p == "P" then
- local opcv, sh = rshift(op, 26), 2
- if opcv >= 0x2a then sh = 4 elseif opcv >= 0x1b then sh = 3 end
- local imm7 = lshift(arshift(lshift(op, 10), 25), sh)
- local rn = map_regs.x[band(rshift(op, 5), 31)]
- local ind = band(rshift(op, 23), 3)
- if ind == 1 then
- x = "["..rn.."], #"..imm7
- elseif ind == 2 then
- if imm7 == 0 then
- x = "["..rn.."]"
- else
- x = "["..rn..", #"..imm7.."]"
- end
- elseif ind == 3 then
- x = "["..rn..", #"..imm7.."]!"
- end
- elseif p == "I" then
- local shf = band(rshift(op, 22), 3)
- local imm12 = band(rshift(op, 10), 0x0fff)
- local rn, rd = band(rshift(op, 5), 31), band(op, 31)
- if altname == "mov" and shf == 0 and imm12 == 0 and (rn == 31 or rd == 31) then
- name = altname
- x = nil
- elseif shf == 0 then
- x = imm12
- elseif shf == 1 then
- x = imm12..", lsl #12"
- end
- elseif p == "i" then
- x = "#0x"..decode_imm13(op)
- elseif p == "1" then
- immr = band(rshift(op, 16), 63)
- x = immr
- elseif p == "2" then
- x = band(rshift(op, 10), 63)
- if altname then
- local a1, a2, a3, a4, a5, a6 =
- match(altname, "([^|]*)|([^|]*)|([^|]*)|([^|]*)|([^|]*)|(.*)")
- local sf = band(rshift(op, 26), 32)
- local uns = band(rshift(op, 30), 1)
- if prefer_bfx(sf, uns, x, immr) then
- name = a2
- x = x - immr + 1
- elseif immr == 0 and x == 7 then
- local n = #operands
- operands[n] = nil
- if sf ~= 0 then
- operands[n-1] = gsub(operands[n-1], "x", "w")
- end
- last = operands[n-1]
- name = a6
- x = nil
- elseif immr == 0 and x == 15 then
- local n = #operands
- operands[n] = nil
- if sf ~= 0 then
- operands[n-1] = gsub(operands[n-1], "x", "w")
- end
- last = operands[n-1]
- name = a5
- x = nil
- elseif x == 31 or x == 63 then
- if x == 31 and immr == 0 and name == "sbfm" then
- name = a4
- local n = #operands
- operands[n] = nil
- if sf ~= 0 then
- operands[n-1] = gsub(operands[n-1], "x", "w")
- end
- last = operands[n-1]
- else
- name = a3
- end
- x = nil
- elseif band(x, 31) ~= 31 and immr == x+1 and name == "ubfm" then
- name = a4
- last = "#"..(sf+32 - immr)
- operands[#operands] = last
- x = nil
- elseif x < immr then
- name = a1
- last = "#"..(sf+32 - immr)
- operands[#operands] = last
- x = x + 1
- end
- end
- elseif p == "3" then
- x = band(rshift(op, 10), 63)
- if altname then
- local a1, a2 = match(altname, "([^|]*)|(.*)")
- if x < immr then
- name = a1
- local sf = band(rshift(op, 26), 32)
- last = "#"..(sf+32 - immr)
- operands[#operands] = last
- x = x + 1
- elseif x >= immr then
- name = a2
- x = x - immr + 1
- end
- end
- elseif p == "4" then
- x = band(rshift(op, 10), 63)
- local rn = band(rshift(op, 5), 31)
- local rm = band(rshift(op, 16), 31)
- if altname and rn == rm then
- local n = #operands
- operands[n] = nil
- last = operands[n-1]
- name = altname
- end
- elseif p == "5" then
- x = band(rshift(op, 16), 31)
- elseif p == "S" then
- x = band(rshift(op, 10), 63)
- if x == 0 then x = nil
- else x = map_shift[band(rshift(op, 22), 3)].." #"..x end
- elseif p == "X" then
- local opt = band(rshift(op, 13), 7)
- -- Width specifier <R>.
- if opt ~= 3 and opt ~= 7 then
- last = map_regs.w[band(rshift(op, 16), 31)]
- operands[#operands] = last
- end
- x = band(rshift(op, 10), 7)
- -- Extension.
- if opt == 2 + band(rshift(op, 31), 1) and
- band(rshift(op, second0 and 5 or 0), 31) == 31 then
- if x == 0 then x = nil
- else x = "lsl #"..x end
- else
- if x == 0 then x = map_extend[band(rshift(op, 13), 7)]
- else x = map_extend[band(rshift(op, 13), 7)].." #"..x end
- end
- elseif p == "R" then
- x = band(rshift(op,21), 3)
- if x == 0 then x = nil
- else x = "lsl #"..x*16 end
- elseif p == "z" then
- local n = #operands
- if operands[n] == "sp" then operands[n] = "xzr"
- elseif operands[n] == "wsp" then operands[n] = "wzr"
- end
- elseif p == "Z" then
- x = 0
- elseif p == "F" then
- x = parse_fpimm8(op)
- elseif p == "g" or p == "f" or p == "x" or p == "w" or
- p == "d" or p == "s" then
- -- These are handled in D/N/M/A.
- elseif p == "0" then
- if last == "sp" or last == "wsp" then
- local n = #operands
- operands[n] = nil
- last = operands[n-1]
- if altname then
- local a1, a2 = match(altname, "([^|]*)|(.*)")
- if not a1 then
- name = altname
- elseif second0 then
- name, altname = a2, a1
- else
- name, altname = a1, a2
- end
- end
- end
- second0 = true
- else
- assert(false)
- end
- if x then
- last = x
- if type(x) == "number" then x = "#"..x end
- operands[#operands+1] = x
- end
- end
-
- return putop(ctx, name..suffix, operands)
-end
-
-------------------------------------------------------------------------------
-
--- Disassemble a block of code.
-local function disass_block(ctx, ofs, len)
- if not ofs then ofs = 0 end
- local stop = len and ofs+len or #ctx.code
- ctx.pos = ofs
- ctx.rel = nil
- while ctx.pos < stop do disass_ins(ctx) end
-end
-
--- Extended API: create a disassembler context. Then call ctx:disass(ofs, len).
-local function create(code, addr, out)
- local ctx = {}
- ctx.code = code
- ctx.addr = addr or 0
- ctx.out = out or io.write
- ctx.symtab = {}
- ctx.disass = disass_block
- ctx.hexdump = 8
- return ctx
-end
-
--- Simple API: disassemble code (a string) at address and output via out.
-local function disass(code, addr, out)
- create(code, addr, out):disass()
-end
-
--- Return register name for RID.
-local function regname(r)
- if r < 32 then return map_regs.x[r] end
- return map_regs.d[r-32]
-end
-
--- Public module functions.
-return {
- create = create,
- disass = disass,
- regname = regname
-}
-
diff --git a/lib/LuaJIT/jit/dis_arm64be.lua b/lib/LuaJIT/jit/dis_arm64be.lua
deleted file mode 100644
index 7eb389e..0000000
--- a/lib/LuaJIT/jit/dis_arm64be.lua
+++ /dev/null
@@ -1,12 +0,0 @@
-----------------------------------------------------------------------------
--- LuaJIT ARM64BE disassembler wrapper module.
---
--- Copyright (C) 2005-2017 Mike Pall. All rights reserved.
--- Released under the MIT license. See Copyright Notice in luajit.h
-----------------------------------------------------------------------------
--- ARM64 instructions are always little-endian. So just forward to the
--- common ARM64 disassembler module. All the interesting stuff is there.
-------------------------------------------------------------------------------
-
-return require((string.match(..., ".*%.") or "").."dis_arm64")
-
diff --git a/lib/LuaJIT/jit/dis_mips.lua b/lib/LuaJIT/jit/dis_mips.lua
deleted file mode 100644
index a12b8e6..0000000
--- a/lib/LuaJIT/jit/dis_mips.lua
+++ /dev/null
@@ -1,443 +0,0 @@
-----------------------------------------------------------------------------
--- LuaJIT MIPS disassembler module.
---
--- Copyright (C) 2005-2017 Mike Pall. All rights reserved.
--- Released under the MIT/X license. See Copyright Notice in luajit.h
-----------------------------------------------------------------------------
--- This is a helper module used by the LuaJIT machine code dumper module.
---
--- It disassembles all standard MIPS32R1/R2 instructions.
--- Default mode is big-endian, but see: dis_mipsel.lua
-------------------------------------------------------------------------------
-
-local type = type
-local byte, format = string.byte, string.format
-local match, gmatch = string.match, string.gmatch
-local concat = table.concat
-local bit = require("bit")
-local band, bor, tohex = bit.band, bit.bor, bit.tohex
-local lshift, rshift, arshift = bit.lshift, bit.rshift, bit.arshift
-
-------------------------------------------------------------------------------
--- Primary and extended opcode maps
-------------------------------------------------------------------------------
-
-local map_movci = { shift = 16, mask = 1, [0] = "movfDSC", "movtDSC", }
-local map_srl = { shift = 21, mask = 1, [0] = "srlDTA", "rotrDTA", }
-local map_srlv = { shift = 6, mask = 1, [0] = "srlvDTS", "rotrvDTS", }
-
-local map_special = {
- shift = 0, mask = 63,
- [0] = { shift = 0, mask = -1, [0] = "nop", _ = "sllDTA" },
- map_movci, map_srl, "sraDTA",
- "sllvDTS", false, map_srlv, "sravDTS",
- "jrS", "jalrD1S", "movzDST", "movnDST",
- "syscallY", "breakY", false, "sync",
- "mfhiD", "mthiS", "mfloD", "mtloS",
- "dsllvDST", false, "dsrlvDST", "dsravDST",
- "multST", "multuST", "divST", "divuST",
- "dmultST", "dmultuST", "ddivST", "ddivuST",
- "addDST", "addu|moveDST0", "subDST", "subu|neguDS0T",
- "andDST", "or|moveDST0", "xorDST", "nor|notDST0",
- false, false, "sltDST", "sltuDST",
- "daddDST", "dadduDST", "dsubDST", "dsubuDST",
- "tgeSTZ", "tgeuSTZ", "tltSTZ", "tltuSTZ",
- "teqSTZ", false, "tneSTZ", false,
- "dsllDTA", false, "dsrlDTA", "dsraDTA",
- "dsll32DTA", false, "dsrl32DTA", "dsra32DTA",
-}
-
-local map_special2 = {
- shift = 0, mask = 63,
- [0] = "maddST", "madduST", "mulDST", false,
- "msubST", "msubuST",
- [32] = "clzDS", [33] = "cloDS",
- [63] = "sdbbpY",
-}
-
-local map_bshfl = {
- shift = 6, mask = 31,
- [2] = "wsbhDT",
- [16] = "sebDT",
- [24] = "sehDT",
-}
-
-local map_dbshfl = {
- shift = 6, mask = 31,
- [2] = "dsbhDT",
- [5] = "dshdDT",
-}
-
-local map_special3 = {
- shift = 0, mask = 63,
- [0] = "extTSAK", [1] = "dextmTSAP", [3] = "dextTSAK",
- [4] = "insTSAL", [6] = "dinsuTSEQ", [7] = "dinsTSAL",
- [32] = map_bshfl, [36] = map_dbshfl, [59] = "rdhwrTD",
-}
-
-local map_regimm = {
- shift = 16, mask = 31,
- [0] = "bltzSB", "bgezSB", "bltzlSB", "bgezlSB",
- false, false, false, false,
- "tgeiSI", "tgeiuSI", "tltiSI", "tltiuSI",
- "teqiSI", false, "tneiSI", false,
- "bltzalSB", "bgezalSB", "bltzallSB", "bgezallSB",
- false, false, false, false,
- false, false, false, false,
- false, false, false, "synciSO",
-}
-
-local map_cop0 = {
- shift = 25, mask = 1,
- [0] = {
- shift = 21, mask = 15,
- [0] = "mfc0TDW", [4] = "mtc0TDW",
- [10] = "rdpgprDT",
- [11] = { shift = 5, mask = 1, [0] = "diT0", "eiT0", },
- [14] = "wrpgprDT",
- }, {
- shift = 0, mask = 63,
- [1] = "tlbr", [2] = "tlbwi", [6] = "tlbwr", [8] = "tlbp",
- [24] = "eret", [31] = "deret",
- [32] = "wait",
- },
-}
-
-local map_cop1s = {
- shift = 0, mask = 63,
- [0] = "add.sFGH", "sub.sFGH", "mul.sFGH", "div.sFGH",
- "sqrt.sFG", "abs.sFG", "mov.sFG", "neg.sFG",
- "round.l.sFG", "trunc.l.sFG", "ceil.l.sFG", "floor.l.sFG",
- "round.w.sFG", "trunc.w.sFG", "ceil.w.sFG", "floor.w.sFG",
- false,
- { shift = 16, mask = 1, [0] = "movf.sFGC", "movt.sFGC" },
- "movz.sFGT", "movn.sFGT",
- false, "recip.sFG", "rsqrt.sFG", false,
- false, false, false, false,
- false, false, false, false,
- false, "cvt.d.sFG", false, false,
- "cvt.w.sFG", "cvt.l.sFG", "cvt.ps.sFGH", false,
- false, false, false, false,
- false, false, false, false,
- "c.f.sVGH", "c.un.sVGH", "c.eq.sVGH", "c.ueq.sVGH",
- "c.olt.sVGH", "c.ult.sVGH", "c.ole.sVGH", "c.ule.sVGH",
- "c.sf.sVGH", "c.ngle.sVGH", "c.seq.sVGH", "c.ngl.sVGH",
- "c.lt.sVGH", "c.nge.sVGH", "c.le.sVGH", "c.ngt.sVGH",
-}
-
-local map_cop1d = {
- shift = 0, mask = 63,
- [0] = "add.dFGH", "sub.dFGH", "mul.dFGH", "div.dFGH",
- "sqrt.dFG", "abs.dFG", "mov.dFG", "neg.dFG",
- "round.l.dFG", "trunc.l.dFG", "ceil.l.dFG", "floor.l.dFG",
- "round.w.dFG", "trunc.w.dFG", "ceil.w.dFG", "floor.w.dFG",
- false,
- { shift = 16, mask = 1, [0] = "movf.dFGC", "movt.dFGC" },
- "movz.dFGT", "movn.dFGT",
- false, "recip.dFG", "rsqrt.dFG", false,
- false, false, false, false,
- false, false, false, false,
- "cvt.s.dFG", false, false, false,
- "cvt.w.dFG", "cvt.l.dFG", false, false,
- false, false, false, false,
- false, false, false, false,
- "c.f.dVGH", "c.un.dVGH", "c.eq.dVGH", "c.ueq.dVGH",
- "c.olt.dVGH", "c.ult.dVGH", "c.ole.dVGH", "c.ule.dVGH",
- "c.df.dVGH", "c.ngle.dVGH", "c.deq.dVGH", "c.ngl.dVGH",
- "c.lt.dVGH", "c.nge.dVGH", "c.le.dVGH", "c.ngt.dVGH",
-}
-
-local map_cop1ps = {
- shift = 0, mask = 63,
- [0] = "add.psFGH", "sub.psFGH", "mul.psFGH", false,
- false, "abs.psFG", "mov.psFG", "neg.psFG",
- false, false, false, false,
- false, false, false, false,
- false,
- { shift = 16, mask = 1, [0] = "movf.psFGC", "movt.psFGC" },
- "movz.psFGT", "movn.psFGT",
- false, false, false, false,
- false, false, false, false,
- false, false, false, false,
- "cvt.s.puFG", false, false, false,
- false, false, false, false,
- "cvt.s.plFG", false, false, false,
- "pll.psFGH", "plu.psFGH", "pul.psFGH", "puu.psFGH",
- "c.f.psVGH", "c.un.psVGH", "c.eq.psVGH", "c.ueq.psVGH",
- "c.olt.psVGH", "c.ult.psVGH", "c.ole.psVGH", "c.ule.psVGH",
- "c.psf.psVGH", "c.ngle.psVGH", "c.pseq.psVGH", "c.ngl.psVGH",
- "c.lt.psVGH", "c.nge.psVGH", "c.le.psVGH", "c.ngt.psVGH",
-}
-
-local map_cop1w = {
- shift = 0, mask = 63,
- [32] = "cvt.s.wFG", [33] = "cvt.d.wFG",
-}
-
-local map_cop1l = {
- shift = 0, mask = 63,
- [32] = "cvt.s.lFG", [33] = "cvt.d.lFG",
-}
-
-local map_cop1bc = {
- shift = 16, mask = 3,
- [0] = "bc1fCB", "bc1tCB", "bc1flCB", "bc1tlCB",
-}
-
-local map_cop1 = {
- shift = 21, mask = 31,
- [0] = "mfc1TG", "dmfc1TG", "cfc1TG", "mfhc1TG",
- "mtc1TG", "dmtc1TG", "ctc1TG", "mthc1TG",
- map_cop1bc, false, false, false,
- false, false, false, false,
- map_cop1s, map_cop1d, false, false,
- map_cop1w, map_cop1l, map_cop1ps,
-}
-
-local map_cop1x = {
- shift = 0, mask = 63,
- [0] = "lwxc1FSX", "ldxc1FSX", false, false,
- false, "luxc1FSX", false, false,
- "swxc1FSX", "sdxc1FSX", false, false,
- false, "suxc1FSX", false, "prefxMSX",
- false, false, false, false,
- false, false, false, false,
- false, false, false, false,
- false, false, "alnv.psFGHS", false,
- "madd.sFRGH", "madd.dFRGH", false, false,
- false, false, "madd.psFRGH", false,
- "msub.sFRGH", "msub.dFRGH", false, false,
- false, false, "msub.psFRGH", false,
- "nmadd.sFRGH", "nmadd.dFRGH", false, false,
- false, false, "nmadd.psFRGH", false,
- "nmsub.sFRGH", "nmsub.dFRGH", false, false,
- false, false, "nmsub.psFRGH", false,
-}
-
-local map_pri = {
- [0] = map_special, map_regimm, "jJ", "jalJ",
- "beq|beqz|bST00B", "bne|bnezST0B", "blezSB", "bgtzSB",
- "addiTSI", "addiu|liTS0I", "sltiTSI", "sltiuTSI",
- "andiTSU", "ori|liTS0U", "xoriTSU", "luiTU",
- map_cop0, map_cop1, false, map_cop1x,
- "beql|beqzlST0B", "bnel|bnezlST0B", "blezlSB", "bgtzlSB",
- "daddiTSI", "daddiuTSI", false, false,
- map_special2, "jalxJ", false, map_special3,
- "lbTSO", "lhTSO", "lwlTSO", "lwTSO",
- "lbuTSO", "lhuTSO", "lwrTSO", false,
- "sbTSO", "shTSO", "swlTSO", "swTSO",
- false, false, "swrTSO", "cacheNSO",
- "llTSO", "lwc1HSO", "lwc2TSO", "prefNSO",
- false, "ldc1HSO", "ldc2TSO", "ldTSO",
- "scTSO", "swc1HSO", "swc2TSO", false,
- false, "sdc1HSO", "sdc2TSO", "sdTSO",
-}
-
-------------------------------------------------------------------------------
-
-local map_gpr = {
- [0] = "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
- "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
- "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
- "r24", "r25", "r26", "r27", "r28", "sp", "r30", "ra",
-}
-
-------------------------------------------------------------------------------
-
--- Output a nicely formatted line with an opcode and operands.
-local function putop(ctx, text, operands)
- local pos = ctx.pos
- local extra = ""
- if ctx.rel then
- local sym = ctx.symtab[ctx.rel]
- if sym then extra = "\t->"..sym end
- end
- if ctx.hexdump > 0 then
- ctx.out(format("%08x %s %-7s %s%s\n",
- ctx.addr+pos, tohex(ctx.op), text, concat(operands, ", "), extra))
- else
- ctx.out(format("%08x %-7s %s%s\n",
- ctx.addr+pos, text, concat(operands, ", "), extra))
- end
- ctx.pos = pos + 4
-end
-
--- Fallback for unknown opcodes.
-local function unknown(ctx)
- return putop(ctx, ".long", { "0x"..tohex(ctx.op) })
-end
-
-local function get_be(ctx)
- local pos = ctx.pos
- local b0, b1, b2, b3 = byte(ctx.code, pos+1, pos+4)
- return bor(lshift(b0, 24), lshift(b1, 16), lshift(b2, 8), b3)
-end
-
-local function get_le(ctx)
- local pos = ctx.pos
- local b0, b1, b2, b3 = byte(ctx.code, pos+1, pos+4)
- return bor(lshift(b3, 24), lshift(b2, 16), lshift(b1, 8), b0)
-end
-
--- Disassemble a single instruction.
-local function disass_ins(ctx)
- local op = ctx:get()
- local operands = {}
- local last = nil
- ctx.op = op
- ctx.rel = nil
-
- local opat = map_pri[rshift(op, 26)]
- while type(opat) ~= "string" do
- if not opat then return unknown(ctx) end
- opat = opat[band(rshift(op, opat.shift), opat.mask)] or opat._
- end
- local name, pat = match(opat, "^([a-z0-9_.]*)(.*)")
- local altname, pat2 = match(pat, "|([a-z0-9_.|]*)(.*)")
- if altname then pat = pat2 end
-
- for p in gmatch(pat, ".") do
- local x = nil
- if p == "S" then
- x = map_gpr[band(rshift(op, 21), 31)]
- elseif p == "T" then
- x = map_gpr[band(rshift(op, 16), 31)]
- elseif p == "D" then
- x = map_gpr[band(rshift(op, 11), 31)]
- elseif p == "F" then
- x = "f"..band(rshift(op, 6), 31)
- elseif p == "G" then
- x = "f"..band(rshift(op, 11), 31)
- elseif p == "H" then
- x = "f"..band(rshift(op, 16), 31)
- elseif p == "R" then
- x = "f"..band(rshift(op, 21), 31)
- elseif p == "A" then
- x = band(rshift(op, 6), 31)
- elseif p == "E" then
- x = band(rshift(op, 6), 31) + 32
- elseif p == "M" then
- x = band(rshift(op, 11), 31)
- elseif p == "N" then
- x = band(rshift(op, 16), 31)
- elseif p == "C" then
- x = band(rshift(op, 18), 7)
- if x == 0 then x = nil end
- elseif p == "K" then
- x = band(rshift(op, 11), 31) + 1
- elseif p == "P" then
- x = band(rshift(op, 11), 31) + 33
- elseif p == "L" then
- x = band(rshift(op, 11), 31) - last + 1
- elseif p == "Q" then
- x = band(rshift(op, 11), 31) - last + 33
- elseif p == "I" then
- x = arshift(lshift(op, 16), 16)
- elseif p == "U" then
- x = band(op, 0xffff)
- elseif p == "O" then
- local disp = arshift(lshift(op, 16), 16)
- operands[#operands] = format("%d(%s)", disp, last)
- elseif p == "X" then
- local index = map_gpr[band(rshift(op, 16), 31)]
- operands[#operands] = format("%s(%s)", index, last)
- elseif p == "B" then
- x = ctx.addr + ctx.pos + arshift(lshift(op, 16), 16)*4 + 4
- ctx.rel = x
- x = format("0x%08x", x)
- elseif p == "J" then
- local a = ctx.addr + ctx.pos
- x = a - band(a, 0x0fffffff) + band(op, 0x03ffffff)*4
- ctx.rel = x
- x = format("0x%08x", x)
- elseif p == "V" then
- x = band(rshift(op, 8), 7)
- if x == 0 then x = nil end
- elseif p == "W" then
- x = band(op, 7)
- if x == 0 then x = nil end
- elseif p == "Y" then
- x = band(rshift(op, 6), 0x000fffff)
- if x == 0 then x = nil end
- elseif p == "Z" then
- x = band(rshift(op, 6), 1023)
- if x == 0 then x = nil end
- elseif p == "0" then
- if last == "r0" or last == 0 then
- local n = #operands
- operands[n] = nil
- last = operands[n-1]
- if altname then
- local a1, a2 = match(altname, "([^|]*)|(.*)")
- if a1 then name, altname = a1, a2
- else name = altname end
- end
- end
- elseif p == "1" then
- if last == "ra" then
- operands[#operands] = nil
- end
- else
- assert(false)
- end
- if x then operands[#operands+1] = x; last = x end
- end
-
- return putop(ctx, name, operands)
-end
-
-------------------------------------------------------------------------------
-
--- Disassemble a block of code.
-local function disass_block(ctx, ofs, len)
- if not ofs then ofs = 0 end
- local stop = len and ofs+len or #ctx.code
- stop = stop - stop % 4
- ctx.pos = ofs - ofs % 4
- ctx.rel = nil
- while ctx.pos < stop do disass_ins(ctx) end
-end
-
--- Extended API: create a disassembler context. Then call ctx:disass(ofs, len).
-local function create(code, addr, out)
- local ctx = {}
- ctx.code = code
- ctx.addr = addr or 0
- ctx.out = out or io.write
- ctx.symtab = {}
- ctx.disass = disass_block
- ctx.hexdump = 8
- ctx.get = get_be
- return ctx
-end
-
-local function create_el(code, addr, out)
- local ctx = create(code, addr, out)
- ctx.get = get_le
- return ctx
-end
-
--- Simple API: disassemble code (a string) at address and output via out.
-local function disass(code, addr, out)
- create(code, addr, out):disass()
-end
-
-local function disass_el(code, addr, out)
- create_el(code, addr, out):disass()
-end
-
--- Return register name for RID.
-local function regname(r)
- if r < 32 then return map_gpr[r] end
- return "f"..(r-32)
-end
-
--- Public module functions.
-return {
- create = create,
- create_el = create_el,
- disass = disass,
- disass_el = disass_el,
- regname = regname
-}
-
diff --git a/lib/LuaJIT/jit/dis_mips64.lua b/lib/LuaJIT/jit/dis_mips64.lua
deleted file mode 100644
index c437492..0000000
--- a/lib/LuaJIT/jit/dis_mips64.lua
+++ /dev/null
@@ -1,17 +0,0 @@
-----------------------------------------------------------------------------
--- LuaJIT MIPS64 disassembler wrapper module.
---
--- Copyright (C) 2005-2017 Mike Pall. All rights reserved.
--- Released under the MIT license. See Copyright Notice in luajit.h
-----------------------------------------------------------------------------
--- This module just exports the big-endian functions from the
--- MIPS disassembler module. All the interesting stuff is there.
-------------------------------------------------------------------------------
-
-local dis_mips = require((string.match(..., ".*%.") or "").."dis_mips")
-return {
- create = dis_mips.create,
- disass = dis_mips.disass,
- regname = dis_mips.regname
-}
-
diff --git a/lib/LuaJIT/jit/dis_mips64el.lua b/lib/LuaJIT/jit/dis_mips64el.lua
deleted file mode 100644
index 2b1470a..0000000
--- a/lib/LuaJIT/jit/dis_mips64el.lua
+++ /dev/null
@@ -1,17 +0,0 @@
-----------------------------------------------------------------------------
--- LuaJIT MIPS64EL disassembler wrapper module.
---
--- Copyright (C) 2005-2017 Mike Pall. All rights reserved.
--- Released under the MIT license. See Copyright Notice in luajit.h
-----------------------------------------------------------------------------
--- This module just exports the little-endian functions from the
--- MIPS disassembler module. All the interesting stuff is there.
-------------------------------------------------------------------------------
-
-local dis_mips = require((string.match(..., ".*%.") or "").."dis_mips")
-return {
- create = dis_mips.create_el,
- disass = dis_mips.disass_el,
- regname = dis_mips.regname
-}
-
diff --git a/lib/LuaJIT/jit/dis_mipsel.lua b/lib/LuaJIT/jit/dis_mipsel.lua
deleted file mode 100644
index f69b11f..0000000
--- a/lib/LuaJIT/jit/dis_mipsel.lua
+++ /dev/null
@@ -1,17 +0,0 @@
-----------------------------------------------------------------------------
--- LuaJIT MIPSEL disassembler wrapper module.
---
--- Copyright (C) 2005-2017 Mike Pall. All rights reserved.
--- Released under the MIT license. See Copyright Notice in luajit.h
-----------------------------------------------------------------------------
--- This module just exports the little-endian functions from the
--- MIPS disassembler module. All the interesting stuff is there.
-------------------------------------------------------------------------------
-
-local dis_mips = require((string.match(..., ".*%.") or "").."dis_mips")
-return {
- create = dis_mips.create_el,
- disass = dis_mips.disass_el,
- regname = dis_mips.regname
-}
-
diff --git a/lib/LuaJIT/jit/dis_ppc.lua b/lib/LuaJIT/jit/dis_ppc.lua
deleted file mode 100644
index 2aeb1b2..0000000
--- a/lib/LuaJIT/jit/dis_ppc.lua
+++ /dev/null
@@ -1,591 +0,0 @@
-----------------------------------------------------------------------------
--- LuaJIT PPC disassembler module.
---
--- Copyright (C) 2005-2017 Mike Pall. All rights reserved.
--- Released under the MIT/X license. See Copyright Notice in luajit.h
-----------------------------------------------------------------------------
--- This is a helper module used by the LuaJIT machine code dumper module.
---
--- It disassembles all common, non-privileged 32/64 bit PowerPC instructions
--- plus the e500 SPE instructions and some Cell/Xenon extensions.
---
--- NYI: VMX, VMX128
-------------------------------------------------------------------------------
-
-local type = type
-local byte, format = string.byte, string.format
-local match, gmatch, gsub = string.match, string.gmatch, string.gsub
-local concat = table.concat
-local bit = require("bit")
-local band, bor, tohex = bit.band, bit.bor, bit.tohex
-local lshift, rshift, arshift = bit.lshift, bit.rshift, bit.arshift
-
-------------------------------------------------------------------------------
--- Primary and extended opcode maps
-------------------------------------------------------------------------------
-
-local map_crops = {
- shift = 1, mask = 1023,
- [0] = "mcrfXX",
- [33] = "crnor|crnotCCC=", [129] = "crandcCCC",
- [193] = "crxor|crclrCCC%", [225] = "crnandCCC",
- [257] = "crandCCC", [289] = "creqv|crsetCCC%",
- [417] = "crorcCCC", [449] = "cror|crmoveCCC=",
- [16] = "b_lrKB", [528] = "b_ctrKB",
- [150] = "isync",
-}
-
-local map_rlwinm = setmetatable({
- shift = 0, mask = -1,
-},
-{ __index = function(t, x)
- local rot = band(rshift(x, 11), 31)
- local mb = band(rshift(x, 6), 31)
- local me = band(rshift(x, 1), 31)
- if mb == 0 and me == 31-rot then
- return "slwiRR~A."
- elseif me == 31 and mb == 32-rot then
- return "srwiRR~-A."
- else
- return "rlwinmRR~AAA."
- end
- end
-})
-
-local map_rld = {
- shift = 2, mask = 7,
- [0] = "rldiclRR~HM.", "rldicrRR~HM.", "rldicRR~HM.", "rldimiRR~HM.",
- {
- shift = 1, mask = 1,
- [0] = "rldclRR~RM.", "rldcrRR~RM.",
- },
-}
-
-local map_ext = setmetatable({
- shift = 1, mask = 1023,
-
- [0] = "cmp_YLRR", [32] = "cmpl_YLRR",
- [4] = "twARR", [68] = "tdARR",
-
- [8] = "subfcRRR.", [40] = "subfRRR.",
- [104] = "negRR.", [136] = "subfeRRR.",
- [200] = "subfzeRR.", [232] = "subfmeRR.",
- [520] = "subfcoRRR.", [552] = "subfoRRR.",
- [616] = "negoRR.", [648] = "subfeoRRR.",
- [712] = "subfzeoRR.", [744] = "subfmeoRR.",
-
- [9] = "mulhduRRR.", [73] = "mulhdRRR.", [233] = "mulldRRR.",
- [457] = "divduRRR.", [489] = "divdRRR.",
- [745] = "mulldoRRR.",
- [969] = "divduoRRR.", [1001] = "divdoRRR.",
-
- [10] = "addcRRR.", [138] = "addeRRR.",
- [202] = "addzeRR.", [234] = "addmeRR.", [266] = "addRRR.",
- [522] = "addcoRRR.", [650] = "addeoRRR.",
- [714] = "addzeoRR.", [746] = "addmeoRR.", [778] = "addoRRR.",
-
- [11] = "mulhwuRRR.", [75] = "mulhwRRR.", [235] = "mullwRRR.",
- [459] = "divwuRRR.", [491] = "divwRRR.",
- [747] = "mullwoRRR.",
- [971] = "divwouRRR.", [1003] = "divwoRRR.",
-
- [15] = "iselltRRR", [47] = "iselgtRRR", [79] = "iseleqRRR",
-
- [144] = { shift = 20, mask = 1, [0] = "mtcrfRZ~", "mtocrfRZ~", },
- [19] = { shift = 20, mask = 1, [0] = "mfcrR", "mfocrfRZ", },
- [371] = { shift = 11, mask = 1023, [392] = "mftbR", [424] = "mftbuR", },
- [339] = {
- shift = 11, mask = 1023,
- [32] = "mferR", [256] = "mflrR", [288] = "mfctrR", [16] = "mfspefscrR",
- },
- [467] = {
- shift = 11, mask = 1023,
- [32] = "mtxerR", [256] = "mtlrR", [288] = "mtctrR", [16] = "mtspefscrR",
- },
-
- [20] = "lwarxRR0R", [84] = "ldarxRR0R",
-
- [21] = "ldxRR0R", [53] = "lduxRRR",
- [149] = "stdxRR0R", [181] = "stduxRRR",
- [341] = "lwaxRR0R", [373] = "lwauxRRR",
-
- [23] = "lwzxRR0R", [55] = "lwzuxRRR",
- [87] = "lbzxRR0R", [119] = "lbzuxRRR",
- [151] = "stwxRR0R", [183] = "stwuxRRR",
- [215] = "stbxRR0R", [247] = "stbuxRRR",
- [279] = "lhzxRR0R", [311] = "lhzuxRRR",
- [343] = "lhaxRR0R", [375] = "lhauxRRR",
- [407] = "sthxRR0R", [439] = "sthuxRRR",
-
- [54] = "dcbst-R0R", [86] = "dcbf-R0R",
- [150] = "stwcxRR0R.", [214] = "stdcxRR0R.",
- [246] = "dcbtst-R0R", [278] = "dcbt-R0R",
- [310] = "eciwxRR0R", [438] = "ecowxRR0R",
- [470] = "dcbi-RR",
-
- [598] = {
- shift = 21, mask = 3,
- [0] = "sync", "lwsync", "ptesync",
- },
- [758] = "dcba-RR",
- [854] = "eieio", [982] = "icbi-R0R", [1014] = "dcbz-R0R",
-
- [26] = "cntlzwRR~", [58] = "cntlzdRR~",
- [122] = "popcntbRR~",
- [154] = "prtywRR~", [186] = "prtydRR~",
-
- [28] = "andRR~R.", [60] = "andcRR~R.", [124] = "nor|notRR~R=.",
- [284] = "eqvRR~R.", [316] = "xorRR~R.",
- [412] = "orcRR~R.", [444] = "or|mrRR~R=.", [476] = "nandRR~R.",
- [508] = "cmpbRR~R",
-
- [512] = "mcrxrX",
-
- [532] = "ldbrxRR0R", [660] = "stdbrxRR0R",
-
- [533] = "lswxRR0R", [597] = "lswiRR0A",
- [661] = "stswxRR0R", [725] = "stswiRR0A",
-
- [534] = "lwbrxRR0R", [662] = "stwbrxRR0R",
- [790] = "lhbrxRR0R", [918] = "sthbrxRR0R",
-
- [535] = "lfsxFR0R", [567] = "lfsuxFRR",
- [599] = "lfdxFR0R", [631] = "lfduxFRR",
- [663] = "stfsxFR0R", [695] = "stfsuxFRR",
- [727] = "stfdxFR0R", [759] = "stfduxFR0R",
- [855] = "lfiwaxFR0R",
- [983] = "stfiwxFR0R",
-
- [24] = "slwRR~R.",
-
- [27] = "sldRR~R.", [536] = "srwRR~R.",
- [792] = "srawRR~R.", [824] = "srawiRR~A.",
-
- [794] = "sradRR~R.", [826] = "sradiRR~H.", [827] = "sradiRR~H.",
- [922] = "extshRR~.", [954] = "extsbRR~.", [986] = "extswRR~.",
-
- [539] = "srdRR~R.",
-},
-{ __index = function(t, x)
- if band(x, 31) == 15 then return "iselRRRC" end
- end
-})
-
-local map_ld = {
- shift = 0, mask = 3,
- [0] = "ldRRE", "lduRRE", "lwaRRE",
-}
-
-local map_std = {
- shift = 0, mask = 3,
- [0] = "stdRRE", "stduRRE",
-}
-
-local map_fps = {
- shift = 5, mask = 1,
- {
- shift = 1, mask = 15,
- [0] = false, false, "fdivsFFF.", false,
- "fsubsFFF.", "faddsFFF.", "fsqrtsF-F.", false,
- "fresF-F.", "fmulsFF-F.", "frsqrtesF-F.", false,
- "fmsubsFFFF~.", "fmaddsFFFF~.", "fnmsubsFFFF~.", "fnmaddsFFFF~.",
- }
-}
-
-local map_fpd = {
- shift = 5, mask = 1,
- [0] = {
- shift = 1, mask = 1023,
- [0] = "fcmpuXFF", [32] = "fcmpoXFF", [64] = "mcrfsXX",
- [38] = "mtfsb1A.", [70] = "mtfsb0A.", [134] = "mtfsfiA>>-A>",
- [8] = "fcpsgnFFF.", [40] = "fnegF-F.", [72] = "fmrF-F.",
- [136] = "fnabsF-F.", [264] = "fabsF-F.",
- [12] = "frspF-F.",
- [14] = "fctiwF-F.", [15] = "fctiwzF-F.",
- [583] = "mffsF.", [711] = "mtfsfZF.",
- [392] = "frinF-F.", [424] = "frizF-F.",
- [456] = "fripF-F.", [488] = "frimF-F.",
- [814] = "fctidF-F.", [815] = "fctidzF-F.", [846] = "fcfidF-F.",
- },
- {
- shift = 1, mask = 15,
- [0] = false, false, "fdivFFF.", false,
- "fsubFFF.", "faddFFF.", "fsqrtF-F.", "fselFFFF~.",
- "freF-F.", "fmulFF-F.", "frsqrteF-F.", false,
- "fmsubFFFF~.", "fmaddFFFF~.", "fnmsubFFFF~.", "fnmaddFFFF~.",
- }
-}
-
-local map_spe = {
- shift = 0, mask = 2047,
-
- [512] = "evaddwRRR", [514] = "evaddiwRAR~",
- [516] = "evsubwRRR~", [518] = "evsubiwRAR~",
- [520] = "evabsRR", [521] = "evnegRR",
- [522] = "evextsbRR", [523] = "evextshRR", [524] = "evrndwRR",
- [525] = "evcntlzwRR", [526] = "evcntlswRR",
-
- [527] = "brincRRR",
-
- [529] = "evandRRR", [530] = "evandcRRR", [534] = "evxorRRR",
- [535] = "evor|evmrRRR=", [536] = "evnor|evnotRRR=",
- [537] = "eveqvRRR", [539] = "evorcRRR", [542] = "evnandRRR",
-
- [544] = "evsrwuRRR", [545] = "evsrwsRRR",
- [546] = "evsrwiuRRA", [547] = "evsrwisRRA",
- [548] = "evslwRRR", [550] = "evslwiRRA",
- [552] = "evrlwRRR", [553] = "evsplatiRS",
- [554] = "evrlwiRRA", [555] = "evsplatfiRS",
- [556] = "evmergehiRRR", [557] = "evmergeloRRR",
- [558] = "evmergehiloRRR", [559] = "evmergelohiRRR",
-
- [560] = "evcmpgtuYRR", [561] = "evcmpgtsYRR",
- [562] = "evcmpltuYRR", [563] = "evcmpltsYRR",
- [564] = "evcmpeqYRR",
-
- [632] = "evselRRR", [633] = "evselRRRW",
- [634] = "evselRRRW", [635] = "evselRRRW",
- [636] = "evselRRRW", [637] = "evselRRRW",
- [638] = "evselRRRW", [639] = "evselRRRW",
-
- [640] = "evfsaddRRR", [641] = "evfssubRRR",
- [644] = "evfsabsRR", [645] = "evfsnabsRR", [646] = "evfsnegRR",
- [648] = "evfsmulRRR", [649] = "evfsdivRRR",
- [652] = "evfscmpgtYRR", [653] = "evfscmpltYRR", [654] = "evfscmpeqYRR",
- [656] = "evfscfuiR-R", [657] = "evfscfsiR-R",
- [658] = "evfscfufR-R", [659] = "evfscfsfR-R",
- [660] = "evfsctuiR-R", [661] = "evfsctsiR-R",
- [662] = "evfsctufR-R", [663] = "evfsctsfR-R",
- [664] = "evfsctuizR-R", [666] = "evfsctsizR-R",
- [668] = "evfststgtYRR", [669] = "evfststltYRR", [670] = "evfststeqYRR",
-
- [704] = "efsaddRRR", [705] = "efssubRRR",
- [708] = "efsabsRR", [709] = "efsnabsRR", [710] = "efsnegRR",
- [712] = "efsmulRRR", [713] = "efsdivRRR",
- [716] = "efscmpgtYRR", [717] = "efscmpltYRR", [718] = "efscmpeqYRR",
- [719] = "efscfdR-R",
- [720] = "efscfuiR-R", [721] = "efscfsiR-R",
- [722] = "efscfufR-R", [723] = "efscfsfR-R",
- [724] = "efsctuiR-R", [725] = "efsctsiR-R",
- [726] = "efsctufR-R", [727] = "efsctsfR-R",
- [728] = "efsctuizR-R", [730] = "efsctsizR-R",
- [732] = "efststgtYRR", [733] = "efststltYRR", [734] = "efststeqYRR",
-
- [736] = "efdaddRRR", [737] = "efdsubRRR",
- [738] = "efdcfuidR-R", [739] = "efdcfsidR-R",
- [740] = "efdabsRR", [741] = "efdnabsRR", [742] = "efdnegRR",
- [744] = "efdmulRRR", [745] = "efddivRRR",
- [746] = "efdctuidzR-R", [747] = "efdctsidzR-R",
- [748] = "efdcmpgtYRR", [749] = "efdcmpltYRR", [750] = "efdcmpeqYRR",
- [751] = "efdcfsR-R",
- [752] = "efdcfuiR-R", [753] = "efdcfsiR-R",
- [754] = "efdcfufR-R", [755] = "efdcfsfR-R",
- [756] = "efdctuiR-R", [757] = "efdctsiR-R",
- [758] = "efdctufR-R", [759] = "efdctsfR-R",
- [760] = "efdctuizR-R", [762] = "efdctsizR-R",
- [764] = "efdtstgtYRR", [765] = "efdtstltYRR", [766] = "efdtsteqYRR",
-
- [768] = "evlddxRR0R", [769] = "evlddRR8",
- [770] = "evldwxRR0R", [771] = "evldwRR8",
- [772] = "evldhxRR0R", [773] = "evldhRR8",
- [776] = "evlhhesplatxRR0R", [777] = "evlhhesplatRR2",
- [780] = "evlhhousplatxRR0R", [781] = "evlhhousplatRR2",
- [782] = "evlhhossplatxRR0R", [783] = "evlhhossplatRR2",
- [784] = "evlwhexRR0R", [785] = "evlwheRR4",
- [788] = "evlwhouxRR0R", [789] = "evlwhouRR4",
- [790] = "evlwhosxRR0R", [791] = "evlwhosRR4",
- [792] = "evlwwsplatxRR0R", [793] = "evlwwsplatRR4",
- [796] = "evlwhsplatxRR0R", [797] = "evlwhsplatRR4",
-
- [800] = "evstddxRR0R", [801] = "evstddRR8",
- [802] = "evstdwxRR0R", [803] = "evstdwRR8",
- [804] = "evstdhxRR0R", [805] = "evstdhRR8",
- [816] = "evstwhexRR0R", [817] = "evstwheRR4",
- [820] = "evstwhoxRR0R", [821] = "evstwhoRR4",
- [824] = "evstwwexRR0R", [825] = "evstwweRR4",
- [828] = "evstwwoxRR0R", [829] = "evstwwoRR4",
-
- [1027] = "evmhessfRRR", [1031] = "evmhossfRRR", [1032] = "evmheumiRRR",
- [1033] = "evmhesmiRRR", [1035] = "evmhesmfRRR", [1036] = "evmhoumiRRR",
- [1037] = "evmhosmiRRR", [1039] = "evmhosmfRRR", [1059] = "evmhessfaRRR",
- [1063] = "evmhossfaRRR", [1064] = "evmheumiaRRR", [1065] = "evmhesmiaRRR",
- [1067] = "evmhesmfaRRR", [1068] = "evmhoumiaRRR", [1069] = "evmhosmiaRRR",
- [1071] = "evmhosmfaRRR", [1095] = "evmwhssfRRR", [1096] = "evmwlumiRRR",
- [1100] = "evmwhumiRRR", [1101] = "evmwhsmiRRR", [1103] = "evmwhsmfRRR",
- [1107] = "evmwssfRRR", [1112] = "evmwumiRRR", [1113] = "evmwsmiRRR",
- [1115] = "evmwsmfRRR", [1127] = "evmwhssfaRRR", [1128] = "evmwlumiaRRR",
- [1132] = "evmwhumiaRRR", [1133] = "evmwhsmiaRRR", [1135] = "evmwhsmfaRRR",
- [1139] = "evmwssfaRRR", [1144] = "evmwumiaRRR", [1145] = "evmwsmiaRRR",
- [1147] = "evmwsmfaRRR",
-
- [1216] = "evaddusiaawRR", [1217] = "evaddssiaawRR",
- [1218] = "evsubfusiaawRR", [1219] = "evsubfssiaawRR",
- [1220] = "evmraRR",
- [1222] = "evdivwsRRR", [1223] = "evdivwuRRR",
- [1224] = "evaddumiaawRR", [1225] = "evaddsmiaawRR",
- [1226] = "evsubfumiaawRR", [1227] = "evsubfsmiaawRR",
-
- [1280] = "evmheusiaawRRR", [1281] = "evmhessiaawRRR",
- [1283] = "evmhessfaawRRR", [1284] = "evmhousiaawRRR",
- [1285] = "evmhossiaawRRR", [1287] = "evmhossfaawRRR",
- [1288] = "evmheumiaawRRR", [1289] = "evmhesmiaawRRR",
- [1291] = "evmhesmfaawRRR", [1292] = "evmhoumiaawRRR",
- [1293] = "evmhosmiaawRRR", [1295] = "evmhosmfaawRRR",
- [1320] = "evmhegumiaaRRR", [1321] = "evmhegsmiaaRRR",
- [1323] = "evmhegsmfaaRRR", [1324] = "evmhogumiaaRRR",
- [1325] = "evmhogsmiaaRRR", [1327] = "evmhogsmfaaRRR",
- [1344] = "evmwlusiaawRRR", [1345] = "evmwlssiaawRRR",
- [1352] = "evmwlumiaawRRR", [1353] = "evmwlsmiaawRRR",
- [1363] = "evmwssfaaRRR", [1368] = "evmwumiaaRRR",
- [1369] = "evmwsmiaaRRR", [1371] = "evmwsmfaaRRR",
- [1408] = "evmheusianwRRR", [1409] = "evmhessianwRRR",
- [1411] = "evmhessfanwRRR", [1412] = "evmhousianwRRR",
- [1413] = "evmhossianwRRR", [1415] = "evmhossfanwRRR",
- [1416] = "evmheumianwRRR", [1417] = "evmhesmianwRRR",
- [1419] = "evmhesmfanwRRR", [1420] = "evmhoumianwRRR",
- [1421] = "evmhosmianwRRR", [1423] = "evmhosmfanwRRR",
- [1448] = "evmhegumianRRR", [1449] = "evmhegsmianRRR",
- [1451] = "evmhegsmfanRRR", [1452] = "evmhogumianRRR",
- [1453] = "evmhogsmianRRR", [1455] = "evmhogsmfanRRR",
- [1472] = "evmwlusianwRRR", [1473] = "evmwlssianwRRR",
- [1480] = "evmwlumianwRRR", [1481] = "evmwlsmianwRRR",
- [1491] = "evmwssfanRRR", [1496] = "evmwumianRRR",
- [1497] = "evmwsmianRRR", [1499] = "evmwsmfanRRR",
-}
-
-local map_pri = {
- [0] = false, false, "tdiARI", "twiARI",
- map_spe, false, false, "mulliRRI",
- "subficRRI", false, "cmpl_iYLRU", "cmp_iYLRI",
- "addicRRI", "addic.RRI", "addi|liRR0I", "addis|lisRR0I",
- "b_KBJ", "sc", "bKJ", map_crops,
- "rlwimiRR~AAA.", map_rlwinm, false, "rlwnmRR~RAA.",
- "oriNRR~U", "orisRR~U", "xoriRR~U", "xorisRR~U",
- "andi.RR~U", "andis.RR~U", map_rld, map_ext,
- "lwzRRD", "lwzuRRD", "lbzRRD", "lbzuRRD",
- "stwRRD", "stwuRRD", "stbRRD", "stbuRRD",
- "lhzRRD", "lhzuRRD", "lhaRRD", "lhauRRD",
- "sthRRD", "sthuRRD", "lmwRRD", "stmwRRD",
- "lfsFRD", "lfsuFRD", "lfdFRD", "lfduFRD",
- "stfsFRD", "stfsuFRD", "stfdFRD", "stfduFRD",
- false, false, map_ld, map_fps,
- false, false, map_std, map_fpd,
-}
-
-------------------------------------------------------------------------------
-
-local map_gpr = {
- [0] = "r0", "sp", "r2", "r3", "r4", "r5", "r6", "r7",
- "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
- "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
- "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
-}
-
-local map_cond = { [0] = "lt", "gt", "eq", "so", "ge", "le", "ne", "ns", }
-
--- Format a condition bit.
-local function condfmt(cond)
- if cond <= 3 then
- return map_cond[band(cond, 3)]
- else
- return format("4*cr%d+%s", rshift(cond, 2), map_cond[band(cond, 3)])
- end
-end
-
-------------------------------------------------------------------------------
-
--- Output a nicely formatted line with an opcode and operands.
-local function putop(ctx, text, operands)
- local pos = ctx.pos
- local extra = ""
- if ctx.rel then
- local sym = ctx.symtab[ctx.rel]
- if sym then extra = "\t->"..sym end
- end
- if ctx.hexdump > 0 then
- ctx.out(format("%08x %s %-7s %s%s\n",
- ctx.addr+pos, tohex(ctx.op), text, concat(operands, ", "), extra))
- else
- ctx.out(format("%08x %-7s %s%s\n",
- ctx.addr+pos, text, concat(operands, ", "), extra))
- end
- ctx.pos = pos + 4
-end
-
--- Fallback for unknown opcodes.
-local function unknown(ctx)
- return putop(ctx, ".long", { "0x"..tohex(ctx.op) })
-end
-
--- Disassemble a single instruction.
-local function disass_ins(ctx)
- local pos = ctx.pos
- local b0, b1, b2, b3 = byte(ctx.code, pos+1, pos+4)
- local op = bor(lshift(b0, 24), lshift(b1, 16), lshift(b2, 8), b3)
- local operands = {}
- local last = nil
- local rs = 21
- ctx.op = op
- ctx.rel = nil
-
- local opat = map_pri[rshift(b0, 2)]
- while type(opat) ~= "string" do
- if not opat then return unknown(ctx) end
- opat = opat[band(rshift(op, opat.shift), opat.mask)]
- end
- local name, pat = match(opat, "^([a-z0-9_.]*)(.*)")
- local altname, pat2 = match(pat, "|([a-z0-9_.]*)(.*)")
- if altname then pat = pat2 end
-
- for p in gmatch(pat, ".") do
- local x = nil
- if p == "R" then
- x = map_gpr[band(rshift(op, rs), 31)]
- rs = rs - 5
- elseif p == "F" then
- x = "f"..band(rshift(op, rs), 31)
- rs = rs - 5
- elseif p == "A" then
- x = band(rshift(op, rs), 31)
- rs = rs - 5
- elseif p == "S" then
- x = arshift(lshift(op, 27-rs), 27)
- rs = rs - 5
- elseif p == "I" then
- x = arshift(lshift(op, 16), 16)
- elseif p == "U" then
- x = band(op, 0xffff)
- elseif p == "D" or p == "E" then
- local disp = arshift(lshift(op, 16), 16)
- if p == "E" then disp = band(disp, -4) end
- if last == "r0" then last = "0" end
- operands[#operands] = format("%d(%s)", disp, last)
- elseif p >= "2" and p <= "8" then
- local disp = band(rshift(op, rs), 31) * p
- if last == "r0" then last = "0" end
- operands[#operands] = format("%d(%s)", disp, last)
- elseif p == "H" then
- x = band(rshift(op, rs), 31) + lshift(band(op, 2), 4)
- rs = rs - 5
- elseif p == "M" then
- x = band(rshift(op, rs), 31) + band(op, 0x20)
- elseif p == "C" then
- x = condfmt(band(rshift(op, rs), 31))
- rs = rs - 5
- elseif p == "B" then
- local bo = rshift(op, 21)
- local cond = band(rshift(op, 16), 31)
- local cn = ""
- rs = rs - 10
- if band(bo, 4) == 0 then
- cn = band(bo, 2) == 0 and "dnz" or "dz"
- if band(bo, 0x10) == 0 then
- cn = cn..(band(bo, 8) == 0 and "f" or "t")
- end
- if band(bo, 0x10) == 0 then x = condfmt(cond) end
- name = name..(band(bo, 1) == band(rshift(op, 15), 1) and "-" or "+")
- elseif band(bo, 0x10) == 0 then
- cn = map_cond[band(cond, 3) + (band(bo, 8) == 0 and 4 or 0)]
- if cond > 3 then x = "cr"..rshift(cond, 2) end
- name = name..(band(bo, 1) == band(rshift(op, 15), 1) and "-" or "+")
- end
- name = gsub(name, "_", cn)
- elseif p == "J" then
- x = arshift(lshift(op, 27-rs), 29-rs)*4
- if band(op, 2) == 0 then x = ctx.addr + pos + x end
- ctx.rel = x
- x = "0x"..tohex(x)
- elseif p == "K" then
- if band(op, 1) ~= 0 then name = name.."l" end
- if band(op, 2) ~= 0 then name = name.."a" end
- elseif p == "X" or p == "Y" then
- x = band(rshift(op, rs+2), 7)
- if x == 0 and p == "Y" then x = nil else x = "cr"..x end
- rs = rs - 5
- elseif p == "W" then
- x = "cr"..band(op, 7)
- elseif p == "Z" then
- x = band(rshift(op, rs-4), 255)
- rs = rs - 10
- elseif p == ">" then
- operands[#operands] = rshift(operands[#operands], 1)
- elseif p == "0" then
- if last == "r0" then
- operands[#operands] = nil
- if altname then name = altname end
- end
- elseif p == "L" then
- name = gsub(name, "_", band(op, 0x00200000) ~= 0 and "d" or "w")
- elseif p == "." then
- if band(op, 1) == 1 then name = name.."." end
- elseif p == "N" then
- if op == 0x60000000 then name = "nop"; break end
- elseif p == "~" then
- local n = #operands
- operands[n-1], operands[n] = operands[n], operands[n-1]
- elseif p == "=" then
- local n = #operands
- if last == operands[n-1] then
- operands[n] = nil
- name = altname
- end
- elseif p == "%" then
- local n = #operands
- if last == operands[n-1] and last == operands[n-2] then
- operands[n] = nil
- operands[n-1] = nil
- name = altname
- end
- elseif p == "-" then
- rs = rs - 5
- else
- assert(false)
- end
- if x then operands[#operands+1] = x; last = x end
- end
-
- return putop(ctx, name, operands)
-end
-
-------------------------------------------------------------------------------
-
--- Disassemble a block of code.
-local function disass_block(ctx, ofs, len)
- if not ofs then ofs = 0 end
- local stop = len and ofs+len or #ctx.code
- stop = stop - stop % 4
- ctx.pos = ofs - ofs % 4
- ctx.rel = nil
- while ctx.pos < stop do disass_ins(ctx) end
-end
-
--- Extended API: create a disassembler context. Then call ctx:disass(ofs, len).
-local function create(code, addr, out)
- local ctx = {}
- ctx.code = code
- ctx.addr = addr or 0
- ctx.out = out or io.write
- ctx.symtab = {}
- ctx.disass = disass_block
- ctx.hexdump = 8
- return ctx
-end
-
--- Simple API: disassemble code (a string) at address and output via out.
-local function disass(code, addr, out)
- create(code, addr, out):disass()
-end
-
--- Return register name for RID.
-local function regname(r)
- if r < 32 then return map_gpr[r] end
- return "f"..(r-32)
-end
-
--- Public module functions.
-return {
- create = create,
- disass = disass,
- regname = regname
-}
-
diff --git a/lib/LuaJIT/jit/dis_x64.lua b/lib/LuaJIT/jit/dis_x64.lua
deleted file mode 100644
index d5714ee..0000000
--- a/lib/LuaJIT/jit/dis_x64.lua
+++ /dev/null
@@ -1,17 +0,0 @@
-----------------------------------------------------------------------------
--- LuaJIT x64 disassembler wrapper module.
---
--- Copyright (C) 2005-2017 Mike Pall. All rights reserved.
--- Released under the MIT license. See Copyright Notice in luajit.h
-----------------------------------------------------------------------------
--- This module just exports the 64 bit functions from the combined
--- x86/x64 disassembler module. All the interesting stuff is there.
-------------------------------------------------------------------------------
-
-local dis_x86 = require((string.match(..., ".*%.") or "").."dis_x86")
-return {
- create = dis_x86.create64,
- disass = dis_x86.disass64,
- regname = dis_x86.regname64
-}
-
diff --git a/lib/LuaJIT/jit/dis_x86.lua b/lib/LuaJIT/jit/dis_x86.lua
deleted file mode 100644
index 3a68c93..0000000
--- a/lib/LuaJIT/jit/dis_x86.lua
+++ /dev/null
@@ -1,953 +0,0 @@
-----------------------------------------------------------------------------
--- LuaJIT x86/x64 disassembler module.
---
--- Copyright (C) 2005-2017 Mike Pall. All rights reserved.
--- Released under the MIT license. See Copyright Notice in luajit.h
-----------------------------------------------------------------------------
--- This is a helper module used by the LuaJIT machine code dumper module.
---
--- Sending small code snippets to an external disassembler and mixing the
--- output with our own stuff was too fragile. So I had to bite the bullet
--- and write yet another x86 disassembler. Oh well ...
---
--- The output format is very similar to what ndisasm generates. But it has
--- been developed independently by looking at the opcode tables from the
--- Intel and AMD manuals. The supported instruction set is quite extensive
--- and reflects what a current generation Intel or AMD CPU implements in
--- 32 bit and 64 bit mode. Yes, this includes MMX, SSE, SSE2, SSE3, SSSE3,
--- SSE4.1, SSE4.2, SSE4a, AVX, AVX2 and even privileged and hypervisor
--- (VMX/SVM) instructions.
---
--- Notes:
--- * The (useless) a16 prefix, 3DNow and pre-586 opcodes are unsupported.
--- * No attempt at optimization has been made -- it's fast enough for my needs.
-------------------------------------------------------------------------------
-
-local type = type
-local sub, byte, format = string.sub, string.byte, string.format
-local match, gmatch, gsub = string.match, string.gmatch, string.gsub
-local lower, rep = string.lower, string.rep
-local bit = require("bit")
-local tohex = bit.tohex
-
--- Map for 1st opcode byte in 32 bit mode. Ugly? Well ... read on.
-local map_opc1_32 = {
---0x
-[0]="addBmr","addVmr","addBrm","addVrm","addBai","addVai","push es","pop es",
-"orBmr","orVmr","orBrm","orVrm","orBai","orVai","push cs","opc2*",
---1x
-"adcBmr","adcVmr","adcBrm","adcVrm","adcBai","adcVai","push ss","pop ss",
-"sbbBmr","sbbVmr","sbbBrm","sbbVrm","sbbBai","sbbVai","push ds","pop ds",
---2x
-"andBmr","andVmr","andBrm","andVrm","andBai","andVai","es:seg","daa",
-"subBmr","subVmr","subBrm","subVrm","subBai","subVai","cs:seg","das",
---3x
-"xorBmr","xorVmr","xorBrm","xorVrm","xorBai","xorVai","ss:seg","aaa",
-"cmpBmr","cmpVmr","cmpBrm","cmpVrm","cmpBai","cmpVai","ds:seg","aas",
---4x
-"incVR","incVR","incVR","incVR","incVR","incVR","incVR","incVR",
-"decVR","decVR","decVR","decVR","decVR","decVR","decVR","decVR",
---5x
-"pushUR","pushUR","pushUR","pushUR","pushUR","pushUR","pushUR","pushUR",
-"popUR","popUR","popUR","popUR","popUR","popUR","popUR","popUR",
---6x
-"sz*pushaw,pusha","sz*popaw,popa","boundVrm","arplWmr",
-"fs:seg","gs:seg","o16:","a16",
-"pushUi","imulVrmi","pushBs","imulVrms",
-"insb","insVS","outsb","outsVS",
---7x
-"joBj","jnoBj","jbBj","jnbBj","jzBj","jnzBj","jbeBj","jaBj",
-"jsBj","jnsBj","jpeBj","jpoBj","jlBj","jgeBj","jleBj","jgBj",
---8x
-"arith!Bmi","arith!Vmi","arith!Bmi","arith!Vms",
-"testBmr","testVmr","xchgBrm","xchgVrm",
-"movBmr","movVmr","movBrm","movVrm",
-"movVmg","leaVrm","movWgm","popUm",
---9x
-"nop*xchgVaR|pause|xchgWaR|repne nop","xchgVaR","xchgVaR","xchgVaR",
-"xchgVaR","xchgVaR","xchgVaR","xchgVaR",
-"sz*cbw,cwde,cdqe","sz*cwd,cdq,cqo","call farViw","wait",
-"sz*pushfw,pushf","sz*popfw,popf","sahf","lahf",
---Ax
-"movBao","movVao","movBoa","movVoa",
-"movsb","movsVS","cmpsb","cmpsVS",
-"testBai","testVai","stosb","stosVS",
-"lodsb","lodsVS","scasb","scasVS",
---Bx
-"movBRi","movBRi","movBRi","movBRi","movBRi","movBRi","movBRi","movBRi",
-"movVRI","movVRI","movVRI","movVRI","movVRI","movVRI","movVRI","movVRI",
---Cx
-"shift!Bmu","shift!Vmu","retBw","ret","vex*3$lesVrm","vex*2$ldsVrm","movBmi","movVmi",
-"enterBwu","leave","retfBw","retf","int3","intBu","into","iretVS",
---Dx
-"shift!Bm1","shift!Vm1","shift!Bmc","shift!Vmc","aamBu","aadBu","salc","xlatb",
-"fp*0","fp*1","fp*2","fp*3","fp*4","fp*5","fp*6","fp*7",
---Ex
-"loopneBj","loopeBj","loopBj","sz*jcxzBj,jecxzBj,jrcxzBj",
-"inBau","inVau","outBua","outVua",
-"callVj","jmpVj","jmp farViw","jmpBj","inBad","inVad","outBda","outVda",
---Fx
-"lock:","int1","repne:rep","rep:","hlt","cmc","testb!Bm","testv!Vm",
-"clc","stc","cli","sti","cld","std","incb!Bm","incd!Vm",
-}
-assert(#map_opc1_32 == 255)
-
--- Map for 1st opcode byte in 64 bit mode (overrides only).
-local map_opc1_64 = setmetatable({
- [0x06]=false, [0x07]=false, [0x0e]=false,
- [0x16]=false, [0x17]=false, [0x1e]=false, [0x1f]=false,
- [0x27]=false, [0x2f]=false, [0x37]=false, [0x3f]=false,
- [0x60]=false, [0x61]=false, [0x62]=false, [0x63]="movsxdVrDmt", [0x67]="a32:",
- [0x40]="rex*", [0x41]="rex*b", [0x42]="rex*x", [0x43]="rex*xb",
- [0x44]="rex*r", [0x45]="rex*rb", [0x46]="rex*rx", [0x47]="rex*rxb",
- [0x48]="rex*w", [0x49]="rex*wb", [0x4a]="rex*wx", [0x4b]="rex*wxb",
- [0x4c]="rex*wr", [0x4d]="rex*wrb", [0x4e]="rex*wrx", [0x4f]="rex*wrxb",
- [0x82]=false, [0x9a]=false, [0xc4]="vex*3", [0xc5]="vex*2", [0xce]=false,
- [0xd4]=false, [0xd5]=false, [0xd6]=false, [0xea]=false,
-}, { __index = map_opc1_32 })
-
--- Map for 2nd opcode byte (0F xx). True CISC hell. Hey, I told you.
--- Prefix dependent MMX/SSE opcodes: (none)|rep|o16|repne, -|F3|66|F2
-local map_opc2 = {
---0x
-[0]="sldt!Dmp","sgdt!Ump","larVrm","lslVrm",nil,"syscall","clts","sysret",
-"invd","wbinvd",nil,"ud1",nil,"$prefetch!Bm","femms","3dnowMrmu",
---1x
-"movupsXrm|movssXrvm|movupdXrm|movsdXrvm",
-"movupsXmr|movssXmvr|movupdXmr|movsdXmvr",
-"movhlpsXrm$movlpsXrm|movsldupXrm|movlpdXrm|movddupXrm",
-"movlpsXmr||movlpdXmr",
-"unpcklpsXrvm||unpcklpdXrvm",
-"unpckhpsXrvm||unpckhpdXrvm",
-"movlhpsXrm$movhpsXrm|movshdupXrm|movhpdXrm",
-"movhpsXmr||movhpdXmr",
-"$prefetcht!Bm","hintnopVm","hintnopVm","hintnopVm",
-"hintnopVm","hintnopVm","hintnopVm","hintnopVm",
---2x
-"movUmx$","movUmy$","movUxm$","movUym$","movUmz$",nil,"movUzm$",nil,
-"movapsXrm||movapdXrm",
-"movapsXmr||movapdXmr",
-"cvtpi2psXrMm|cvtsi2ssXrvVmt|cvtpi2pdXrMm|cvtsi2sdXrvVmt",
-"movntpsXmr|movntssXmr|movntpdXmr|movntsdXmr",
-"cvttps2piMrXm|cvttss2siVrXm|cvttpd2piMrXm|cvttsd2siVrXm",
-"cvtps2piMrXm|cvtss2siVrXm|cvtpd2piMrXm|cvtsd2siVrXm",
-"ucomissXrm||ucomisdXrm",
-"comissXrm||comisdXrm",
---3x
-"wrmsr","rdtsc","rdmsr","rdpmc","sysenter","sysexit",nil,"getsec",
-"opc3*38",nil,"opc3*3a",nil,nil,nil,nil,nil,
---4x
-"cmovoVrm","cmovnoVrm","cmovbVrm","cmovnbVrm",
-"cmovzVrm","cmovnzVrm","cmovbeVrm","cmovaVrm",
-"cmovsVrm","cmovnsVrm","cmovpeVrm","cmovpoVrm",
-"cmovlVrm","cmovgeVrm","cmovleVrm","cmovgVrm",
---5x
-"movmskpsVrXm$||movmskpdVrXm$","sqrtpsXrm|sqrtssXrm|sqrtpdXrm|sqrtsdXrm",
-"rsqrtpsXrm|rsqrtssXrvm","rcppsXrm|rcpssXrvm",
-"andpsXrvm||andpdXrvm","andnpsXrvm||andnpdXrvm",
-"orpsXrvm||orpdXrvm","xorpsXrvm||xorpdXrvm",
-"addpsXrvm|addssXrvm|addpdXrvm|addsdXrvm","mulpsXrvm|mulssXrvm|mulpdXrvm|mulsdXrvm",
-"cvtps2pdXrm|cvtss2sdXrvm|cvtpd2psXrm|cvtsd2ssXrvm",
-"cvtdq2psXrm|cvttps2dqXrm|cvtps2dqXrm",
-"subpsXrvm|subssXrvm|subpdXrvm|subsdXrvm","minpsXrvm|minssXrvm|minpdXrvm|minsdXrvm",
-"divpsXrvm|divssXrvm|divpdXrvm|divsdXrvm","maxpsXrvm|maxssXrvm|maxpdXrvm|maxsdXrvm",
---6x
-"punpcklbwPrvm","punpcklwdPrvm","punpckldqPrvm","packsswbPrvm",
-"pcmpgtbPrvm","pcmpgtwPrvm","pcmpgtdPrvm","packuswbPrvm",
-"punpckhbwPrvm","punpckhwdPrvm","punpckhdqPrvm","packssdwPrvm",
-"||punpcklqdqXrvm","||punpckhqdqXrvm",
-"movPrVSm","movqMrm|movdquXrm|movdqaXrm",
---7x
-"pshufwMrmu|pshufhwXrmu|pshufdXrmu|pshuflwXrmu","pshiftw!Pvmu",
-"pshiftd!Pvmu","pshiftq!Mvmu||pshiftdq!Xvmu",
-"pcmpeqbPrvm","pcmpeqwPrvm","pcmpeqdPrvm","emms*|",
-"vmreadUmr||extrqXmuu$|insertqXrmuu$","vmwriteUrm||extrqXrm$|insertqXrm$",
-nil,nil,
-"||haddpdXrvm|haddpsXrvm","||hsubpdXrvm|hsubpsXrvm",
-"movVSmMr|movqXrm|movVSmXr","movqMmr|movdquXmr|movdqaXmr",
---8x
-"joVj","jnoVj","jbVj","jnbVj","jzVj","jnzVj","jbeVj","jaVj",
-"jsVj","jnsVj","jpeVj","jpoVj","jlVj","jgeVj","jleVj","jgVj",
---9x
-"setoBm","setnoBm","setbBm","setnbBm","setzBm","setnzBm","setbeBm","setaBm",
-"setsBm","setnsBm","setpeBm","setpoBm","setlBm","setgeBm","setleBm","setgBm",
---Ax
-"push fs","pop fs","cpuid","btVmr","shldVmru","shldVmrc",nil,nil,
-"push gs","pop gs","rsm","btsVmr","shrdVmru","shrdVmrc","fxsave!Dmp","imulVrm",
---Bx
-"cmpxchgBmr","cmpxchgVmr","$lssVrm","btrVmr",
-"$lfsVrm","$lgsVrm","movzxVrBmt","movzxVrWmt",
-"|popcntVrm","ud2Dp","bt!Vmu","btcVmr",
-"bsfVrm","bsrVrm|lzcntVrm|bsrWrm","movsxVrBmt","movsxVrWmt",
---Cx
-"xaddBmr","xaddVmr",
-"cmppsXrvmu|cmpssXrvmu|cmppdXrvmu|cmpsdXrvmu","$movntiVmr|",
-"pinsrwPrvWmu","pextrwDrPmu",
-"shufpsXrvmu||shufpdXrvmu","$cmpxchg!Qmp",
-"bswapVR","bswapVR","bswapVR","bswapVR","bswapVR","bswapVR","bswapVR","bswapVR",
---Dx
-"||addsubpdXrvm|addsubpsXrvm","psrlwPrvm","psrldPrvm","psrlqPrvm",
-"paddqPrvm","pmullwPrvm",
-"|movq2dqXrMm|movqXmr|movdq2qMrXm$","pmovmskbVrMm||pmovmskbVrXm",
-"psubusbPrvm","psubuswPrvm","pminubPrvm","pandPrvm",
-"paddusbPrvm","padduswPrvm","pmaxubPrvm","pandnPrvm",
---Ex
-"pavgbPrvm","psrawPrvm","psradPrvm","pavgwPrvm",
-"pmulhuwPrvm","pmulhwPrvm",
-"|cvtdq2pdXrm|cvttpd2dqXrm|cvtpd2dqXrm","$movntqMmr||$movntdqXmr",
-"psubsbPrvm","psubswPrvm","pminswPrvm","porPrvm",
-"paddsbPrvm","paddswPrvm","pmaxswPrvm","pxorPrvm",
---Fx
-"|||lddquXrm","psllwPrvm","pslldPrvm","psllqPrvm",
-"pmuludqPrvm","pmaddwdPrvm","psadbwPrvm","maskmovqMrm||maskmovdquXrm$",
-"psubbPrvm","psubwPrvm","psubdPrvm","psubqPrvm",
-"paddbPrvm","paddwPrvm","padddPrvm","ud",
-}
-assert(map_opc2[255] == "ud")
-
--- Map for three-byte opcodes. Can't wait for their next invention.
-local map_opc3 = {
-["38"] = { -- [66] 0f 38 xx
---0x
-[0]="pshufbPrvm","phaddwPrvm","phadddPrvm","phaddswPrvm",
-"pmaddubswPrvm","phsubwPrvm","phsubdPrvm","phsubswPrvm",
-"psignbPrvm","psignwPrvm","psigndPrvm","pmulhrswPrvm",
-"||permilpsXrvm","||permilpdXrvm",nil,nil,
---1x
-"||pblendvbXrma",nil,nil,nil,
-"||blendvpsXrma","||blendvpdXrma","||permpsXrvm","||ptestXrm",
-"||broadcastssXrm","||broadcastsdXrm","||broadcastf128XrlXm",nil,
-"pabsbPrm","pabswPrm","pabsdPrm",nil,
---2x
-"||pmovsxbwXrm","||pmovsxbdXrm","||pmovsxbqXrm","||pmovsxwdXrm",
-"||pmovsxwqXrm","||pmovsxdqXrm",nil,nil,
-"||pmuldqXrvm","||pcmpeqqXrvm","||$movntdqaXrm","||packusdwXrvm",
-"||maskmovpsXrvm","||maskmovpdXrvm","||maskmovpsXmvr","||maskmovpdXmvr",
---3x
-"||pmovzxbwXrm","||pmovzxbdXrm","||pmovzxbqXrm","||pmovzxwdXrm",
-"||pmovzxwqXrm","||pmovzxdqXrm","||permdXrvm","||pcmpgtqXrvm",
-"||pminsbXrvm","||pminsdXrvm","||pminuwXrvm","||pminudXrvm",
-"||pmaxsbXrvm","||pmaxsdXrvm","||pmaxuwXrvm","||pmaxudXrvm",
---4x
-"||pmulddXrvm","||phminposuwXrm",nil,nil,
-nil,"||psrlvVSXrvm","||psravdXrvm","||psllvVSXrvm",
---5x
-[0x58] = "||pbroadcastdXrlXm",[0x59] = "||pbroadcastqXrlXm",
-[0x5a] = "||broadcasti128XrlXm",
---7x
-[0x78] = "||pbroadcastbXrlXm",[0x79] = "||pbroadcastwXrlXm",
---8x
-[0x8c] = "||pmaskmovXrvVSm",
-[0x8e] = "||pmaskmovVSmXvr",
---9x
-[0x96] = "||fmaddsub132pHXrvm",[0x97] = "||fmsubadd132pHXrvm",
-[0x98] = "||fmadd132pHXrvm",[0x99] = "||fmadd132sHXrvm",
-[0x9a] = "||fmsub132pHXrvm",[0x9b] = "||fmsub132sHXrvm",
-[0x9c] = "||fnmadd132pHXrvm",[0x9d] = "||fnmadd132sHXrvm",
-[0x9e] = "||fnmsub132pHXrvm",[0x9f] = "||fnmsub132sHXrvm",
---Ax
-[0xa6] = "||fmaddsub213pHXrvm",[0xa7] = "||fmsubadd213pHXrvm",
-[0xa8] = "||fmadd213pHXrvm",[0xa9] = "||fmadd213sHXrvm",
-[0xaa] = "||fmsub213pHXrvm",[0xab] = "||fmsub213sHXrvm",
-[0xac] = "||fnmadd213pHXrvm",[0xad] = "||fnmadd213sHXrvm",
-[0xae] = "||fnmsub213pHXrvm",[0xaf] = "||fnmsub213sHXrvm",
---Bx
-[0xb6] = "||fmaddsub231pHXrvm",[0xb7] = "||fmsubadd231pHXrvm",
-[0xb8] = "||fmadd231pHXrvm",[0xb9] = "||fmadd231sHXrvm",
-[0xba] = "||fmsub231pHXrvm",[0xbb] = "||fmsub231sHXrvm",
-[0xbc] = "||fnmadd231pHXrvm",[0xbd] = "||fnmadd231sHXrvm",
-[0xbe] = "||fnmsub231pHXrvm",[0xbf] = "||fnmsub231sHXrvm",
---Dx
-[0xdc] = "||aesencXrvm", [0xdd] = "||aesenclastXrvm",
-[0xde] = "||aesdecXrvm", [0xdf] = "||aesdeclastXrvm",
---Fx
-[0xf0] = "|||crc32TrBmt",[0xf1] = "|||crc32TrVmt",
-[0xf7] = "| sarxVrmv| shlxVrmv| shrxVrmv",
-},
-
-["3a"] = { -- [66] 0f 3a xx
---0x
-[0x00]="||permqXrmu","||permpdXrmu","||pblenddXrvmu",nil,
-"||permilpsXrmu","||permilpdXrmu","||perm2f128Xrvmu",nil,
-"||roundpsXrmu","||roundpdXrmu","||roundssXrvmu","||roundsdXrvmu",
-"||blendpsXrvmu","||blendpdXrvmu","||pblendwXrvmu","palignrPrvmu",
---1x
-nil,nil,nil,nil,
-"||pextrbVmXru","||pextrwVmXru","||pextrVmSXru","||extractpsVmXru",
-"||insertf128XrvlXmu","||extractf128XlXmYru",nil,nil,
-nil,nil,nil,nil,
---2x
-"||pinsrbXrvVmu","||insertpsXrvmu","||pinsrXrvVmuS",nil,
---3x
-[0x38] = "||inserti128Xrvmu",[0x39] = "||extracti128XlXmYru",
---4x
-[0x40] = "||dppsXrvmu",
-[0x41] = "||dppdXrvmu",
-[0x42] = "||mpsadbwXrvmu",
-[0x44] = "||pclmulqdqXrvmu",
-[0x46] = "||perm2i128Xrvmu",
-[0x4a] = "||blendvpsXrvmb",[0x4b] = "||blendvpdXrvmb",
-[0x4c] = "||pblendvbXrvmb",
---6x
-[0x60] = "||pcmpestrmXrmu",[0x61] = "||pcmpestriXrmu",
-[0x62] = "||pcmpistrmXrmu",[0x63] = "||pcmpistriXrmu",
-[0xdf] = "||aeskeygenassistXrmu",
---Fx
-[0xf0] = "||| rorxVrmu",
-},
-}
-
--- Map for VMX/SVM opcodes 0F 01 C0-FF (sgdt group with register operands).
-local map_opcvm = {
-[0xc1]="vmcall",[0xc2]="vmlaunch",[0xc3]="vmresume",[0xc4]="vmxoff",
-[0xc8]="monitor",[0xc9]="mwait",
-[0xd8]="vmrun",[0xd9]="vmmcall",[0xda]="vmload",[0xdb]="vmsave",
-[0xdc]="stgi",[0xdd]="clgi",[0xde]="skinit",[0xdf]="invlpga",
-[0xf8]="swapgs",[0xf9]="rdtscp",
-}
-
--- Map for FP opcodes. And you thought stack machines are simple?
-local map_opcfp = {
--- D8-DF 00-BF: opcodes with a memory operand.
--- D8
-[0]="faddFm","fmulFm","fcomFm","fcompFm","fsubFm","fsubrFm","fdivFm","fdivrFm",
-"fldFm",nil,"fstFm","fstpFm","fldenvVm","fldcwWm","fnstenvVm","fnstcwWm",
--- DA
-"fiaddDm","fimulDm","ficomDm","ficompDm",
-"fisubDm","fisubrDm","fidivDm","fidivrDm",
--- DB
-"fildDm","fisttpDm","fistDm","fistpDm",nil,"fld twordFmp",nil,"fstp twordFmp",
--- DC
-"faddGm","fmulGm","fcomGm","fcompGm","fsubGm","fsubrGm","fdivGm","fdivrGm",
--- DD
-"fldGm","fisttpQm","fstGm","fstpGm","frstorDmp",nil,"fnsaveDmp","fnstswWm",
--- DE
-"fiaddWm","fimulWm","ficomWm","ficompWm",
-"fisubWm","fisubrWm","fidivWm","fidivrWm",
--- DF
-"fildWm","fisttpWm","fistWm","fistpWm",
-"fbld twordFmp","fildQm","fbstp twordFmp","fistpQm",
--- xx C0-FF: opcodes with a pseudo-register operand.
--- D8
-"faddFf","fmulFf","fcomFf","fcompFf","fsubFf","fsubrFf","fdivFf","fdivrFf",
--- D9
-"fldFf","fxchFf",{"fnop"},nil,
-{"fchs","fabs",nil,nil,"ftst","fxam"},
-{"fld1","fldl2t","fldl2e","fldpi","fldlg2","fldln2","fldz"},
-{"f2xm1","fyl2x","fptan","fpatan","fxtract","fprem1","fdecstp","fincstp"},
-{"fprem","fyl2xp1","fsqrt","fsincos","frndint","fscale","fsin","fcos"},
--- DA
-"fcmovbFf","fcmoveFf","fcmovbeFf","fcmovuFf",nil,{nil,"fucompp"},nil,nil,
--- DB
-"fcmovnbFf","fcmovneFf","fcmovnbeFf","fcmovnuFf",
-{nil,nil,"fnclex","fninit"},"fucomiFf","fcomiFf",nil,
--- DC
-"fadd toFf","fmul toFf",nil,nil,
-"fsub toFf","fsubr toFf","fdivr toFf","fdiv toFf",
--- DD
-"ffreeFf",nil,"fstFf","fstpFf","fucomFf","fucompFf",nil,nil,
--- DE
-"faddpFf","fmulpFf",nil,{nil,"fcompp"},
-"fsubrpFf","fsubpFf","fdivrpFf","fdivpFf",
--- DF
-nil,nil,nil,nil,{"fnstsw ax"},"fucomipFf","fcomipFf",nil,
-}
-assert(map_opcfp[126] == "fcomipFf")
-
--- Map for opcode groups. The subkey is sp from the ModRM byte.
-local map_opcgroup = {
- arith = { "add", "or", "adc", "sbb", "and", "sub", "xor", "cmp" },
- shift = { "rol", "ror", "rcl", "rcr", "shl", "shr", "sal", "sar" },
- testb = { "testBmi", "testBmi", "not", "neg", "mul", "imul", "div", "idiv" },
- testv = { "testVmi", "testVmi", "not", "neg", "mul", "imul", "div", "idiv" },
- incb = { "inc", "dec" },
- incd = { "inc", "dec", "callUmp", "$call farDmp",
- "jmpUmp", "$jmp farDmp", "pushUm" },
- sldt = { "sldt", "str", "lldt", "ltr", "verr", "verw" },
- sgdt = { "vm*$sgdt", "vm*$sidt", "$lgdt", "vm*$lidt",
- "smsw", nil, "lmsw", "vm*$invlpg" },
- bt = { nil, nil, nil, nil, "bt", "bts", "btr", "btc" },
- cmpxchg = { nil, "sz*,cmpxchg8bQmp,cmpxchg16bXmp", nil, nil,
- nil, nil, "vmptrld|vmxon|vmclear", "vmptrst" },
- pshiftw = { nil, nil, "psrlw", nil, "psraw", nil, "psllw" },
- pshiftd = { nil, nil, "psrld", nil, "psrad", nil, "pslld" },
- pshiftq = { nil, nil, "psrlq", nil, nil, nil, "psllq" },
- pshiftdq = { nil, nil, "psrlq", "psrldq", nil, nil, "psllq", "pslldq" },
- fxsave = { "$fxsave", "$fxrstor", "$ldmxcsr", "$stmxcsr",
- nil, "lfenceDp$", "mfenceDp$", "sfenceDp$clflush" },
- prefetch = { "prefetch", "prefetchw" },
- prefetcht = { "prefetchnta", "prefetcht0", "prefetcht1", "prefetcht2" },
-}
-
-------------------------------------------------------------------------------
-
--- Maps for register names.
-local map_regs = {
- B = { "al", "cl", "dl", "bl", "ah", "ch", "dh", "bh",
- "r8b", "r9b", "r10b", "r11b", "r12b", "r13b", "r14b", "r15b" },
- B64 = { "al", "cl", "dl", "bl", "spl", "bpl", "sil", "dil",
- "r8b", "r9b", "r10b", "r11b", "r12b", "r13b", "r14b", "r15b" },
- W = { "ax", "cx", "dx", "bx", "sp", "bp", "si", "di",
- "r8w", "r9w", "r10w", "r11w", "r12w", "r13w", "r14w", "r15w" },
- D = { "eax", "ecx", "edx", "ebx", "esp", "ebp", "esi", "edi",
- "r8d", "r9d", "r10d", "r11d", "r12d", "r13d", "r14d", "r15d" },
- Q = { "rax", "rcx", "rdx", "rbx", "rsp", "rbp", "rsi", "rdi",
- "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15" },
- M = { "mm0", "mm1", "mm2", "mm3", "mm4", "mm5", "mm6", "mm7",
- "mm0", "mm1", "mm2", "mm3", "mm4", "mm5", "mm6", "mm7" }, -- No x64 ext!
- X = { "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7",
- "xmm8", "xmm9", "xmm10", "xmm11", "xmm12", "xmm13", "xmm14", "xmm15" },
- Y = { "ymm0", "ymm1", "ymm2", "ymm3", "ymm4", "ymm5", "ymm6", "ymm7",
- "ymm8", "ymm9", "ymm10", "ymm11", "ymm12", "ymm13", "ymm14", "ymm15" },
-}
-local map_segregs = { "es", "cs", "ss", "ds", "fs", "gs", "segr6", "segr7" }
-
--- Maps for size names.
-local map_sz2n = {
- B = 1, W = 2, D = 4, Q = 8, M = 8, X = 16, Y = 32,
-}
-local map_sz2prefix = {
- B = "byte", W = "word", D = "dword",
- Q = "qword",
- M = "qword", X = "xword", Y = "yword",
- F = "dword", G = "qword", -- No need for sizes/register names for these two.
-}
-
-------------------------------------------------------------------------------
-
--- Output a nicely formatted line with an opcode and operands.
-local function putop(ctx, text, operands)
- local code, pos, hex = ctx.code, ctx.pos, ""
- local hmax = ctx.hexdump
- if hmax > 0 then
- for i=ctx.start,pos-1 do
- hex = hex..format("%02X", byte(code, i, i))
- end
- if #hex > hmax then hex = sub(hex, 1, hmax)..". "
- else hex = hex..rep(" ", hmax-#hex+2) end
- end
- if operands then text = text.." "..operands end
- if ctx.o16 then text = "o16 "..text; ctx.o16 = false end
- if ctx.a32 then text = "a32 "..text; ctx.a32 = false end
- if ctx.rep then text = ctx.rep.." "..text; ctx.rep = false end
- if ctx.rex then
- local t = (ctx.rexw and "w" or "")..(ctx.rexr and "r" or "")..
- (ctx.rexx and "x" or "")..(ctx.rexb and "b" or "")..
- (ctx.vexl and "l" or "")
- if ctx.vexv and ctx.vexv ~= 0 then t = t.."v"..ctx.vexv end
- if t ~= "" then text = ctx.rex.."."..t.." "..gsub(text, "^ ", "")
- elseif ctx.rex == "vex" then text = gsub("v"..text, "^v ", "") end
- ctx.rexw = false; ctx.rexr = false; ctx.rexx = false; ctx.rexb = false
- ctx.rex = false; ctx.vexl = false; ctx.vexv = false
- end
- if ctx.seg then
- local text2, n = gsub(text, "%[", "["..ctx.seg..":")
- if n == 0 then text = ctx.seg.." "..text else text = text2 end
- ctx.seg = false
- end
- if ctx.lock then text = "lock "..text; ctx.lock = false end
- local imm = ctx.imm
- if imm then
- local sym = ctx.symtab[imm]
- if sym then text = text.."\t->"..sym end
- end
- ctx.out(format("%08x %s%s\n", ctx.addr+ctx.start, hex, text))
- ctx.mrm = false
- ctx.vexv = false
- ctx.start = pos
- ctx.imm = nil
-end
-
--- Clear all prefix flags.
-local function clearprefixes(ctx)
- ctx.o16 = false; ctx.seg = false; ctx.lock = false; ctx.rep = false
- ctx.rexw = false; ctx.rexr = false; ctx.rexx = false; ctx.rexb = false
- ctx.rex = false; ctx.a32 = false; ctx.vexl = false
-end
-
--- Fallback for incomplete opcodes at the end.
-local function incomplete(ctx)
- ctx.pos = ctx.stop+1
- clearprefixes(ctx)
- return putop(ctx, "(incomplete)")
-end
-
--- Fallback for unknown opcodes.
-local function unknown(ctx)
- clearprefixes(ctx)
- return putop(ctx, "(unknown)")
-end
-
--- Return an immediate of the specified size.
-local function getimm(ctx, pos, n)
- if pos+n-1 > ctx.stop then return incomplete(ctx) end
- local code = ctx.code
- if n == 1 then
- local b1 = byte(code, pos, pos)
- return b1
- elseif n == 2 then
- local b1, b2 = byte(code, pos, pos+1)
- return b1+b2*256
- else
- local b1, b2, b3, b4 = byte(code, pos, pos+3)
- local imm = b1+b2*256+b3*65536+b4*16777216
- ctx.imm = imm
- return imm
- end
-end
-
--- Process pattern string and generate the operands.
-local function putpat(ctx, name, pat)
- local operands, regs, sz, mode, sp, rm, sc, rx, sdisp
- local code, pos, stop, vexl = ctx.code, ctx.pos, ctx.stop, ctx.vexl
-
- -- Chars used: 1DFGHIMPQRSTUVWXYabcdfgijlmoprstuvwxyz
- for p in gmatch(pat, ".") do
- local x = nil
- if p == "V" or p == "U" then
- if ctx.rexw then sz = "Q"; ctx.rexw = false
- elseif ctx.o16 then sz = "W"; ctx.o16 = false
- elseif p == "U" and ctx.x64 then sz = "Q"
- else sz = "D" end
- regs = map_regs[sz]
- elseif p == "T" then
- if ctx.rexw then sz = "Q"; ctx.rexw = false else sz = "D" end
- regs = map_regs[sz]
- elseif p == "B" then
- sz = "B"
- regs = ctx.rex and map_regs.B64 or map_regs.B
- elseif match(p, "[WDQMXYFG]") then
- sz = p
- if sz == "X" and vexl then sz = "Y"; ctx.vexl = false end
- regs = map_regs[sz]
- elseif p == "P" then
- sz = ctx.o16 and "X" or "M"; ctx.o16 = false
- if sz == "X" and vexl then sz = "Y"; ctx.vexl = false end
- regs = map_regs[sz]
- elseif p == "H" then
- name = name..(ctx.rexw and "d" or "s")
- ctx.rexw = false
- elseif p == "S" then
- name = name..lower(sz)
- elseif p == "s" then
- local imm = getimm(ctx, pos, 1); if not imm then return end
- x = imm <= 127 and format("+0x%02x", imm)
- or format("-0x%02x", 256-imm)
- pos = pos+1
- elseif p == "u" then
- local imm = getimm(ctx, pos, 1); if not imm then return end
- x = format("0x%02x", imm)
- pos = pos+1
- elseif p == "b" then
- local imm = getimm(ctx, pos, 1); if not imm then return end
- x = regs[imm/16+1]
- pos = pos+1
- elseif p == "w" then
- local imm = getimm(ctx, pos, 2); if not imm then return end
- x = format("0x%x", imm)
- pos = pos+2
- elseif p == "o" then -- [offset]
- if ctx.x64 then
- local imm1 = getimm(ctx, pos, 4); if not imm1 then return end
- local imm2 = getimm(ctx, pos+4, 4); if not imm2 then return end
- x = format("[0x%08x%08x]", imm2, imm1)
- pos = pos+8
- else
- local imm = getimm(ctx, pos, 4); if not imm then return end
- x = format("[0x%08x]", imm)
- pos = pos+4
- end
- elseif p == "i" or p == "I" then
- local n = map_sz2n[sz]
- if n == 8 and ctx.x64 and p == "I" then
- local imm1 = getimm(ctx, pos, 4); if not imm1 then return end
- local imm2 = getimm(ctx, pos+4, 4); if not imm2 then return end
- x = format("0x%08x%08x", imm2, imm1)
- else
- if n == 8 then n = 4 end
- local imm = getimm(ctx, pos, n); if not imm then return end
- if sz == "Q" and (imm < 0 or imm > 0x7fffffff) then
- imm = (0xffffffff+1)-imm
- x = format(imm > 65535 and "-0x%08x" or "-0x%x", imm)
- else
- x = format(imm > 65535 and "0x%08x" or "0x%x", imm)
- end
- end
- pos = pos+n
- elseif p == "j" then
- local n = map_sz2n[sz]
- if n == 8 then n = 4 end
- local imm = getimm(ctx, pos, n); if not imm then return end
- if sz == "B" and imm > 127 then imm = imm-256
- elseif imm > 2147483647 then imm = imm-4294967296 end
- pos = pos+n
- imm = imm + pos + ctx.addr
- if imm > 4294967295 and not ctx.x64 then imm = imm-4294967296 end
- ctx.imm = imm
- if sz == "W" then
- x = format("word 0x%04x", imm%65536)
- elseif ctx.x64 then
- local lo = imm % 0x1000000
- x = format("0x%02x%06x", (imm-lo) / 0x1000000, lo)
- else
- x = "0x"..tohex(imm)
- end
- elseif p == "R" then
- local r = byte(code, pos-1, pos-1)%8
- if ctx.rexb then r = r + 8; ctx.rexb = false end
- x = regs[r+1]
- elseif p == "a" then x = regs[1]
- elseif p == "c" then x = "cl"
- elseif p == "d" then x = "dx"
- elseif p == "1" then x = "1"
- else
- if not mode then
- mode = ctx.mrm
- if not mode then
- if pos > stop then return incomplete(ctx) end
- mode = byte(code, pos, pos)
- pos = pos+1
- end
- rm = mode%8; mode = (mode-rm)/8
- sp = mode%8; mode = (mode-sp)/8
- sdisp = ""
- if mode < 3 then
- if rm == 4 then
- if pos > stop then return incomplete(ctx) end
- sc = byte(code, pos, pos)
- pos = pos+1
- rm = sc%8; sc = (sc-rm)/8
- rx = sc%8; sc = (sc-rx)/8
- if ctx.rexx then rx = rx + 8; ctx.rexx = false end
- if rx == 4 then rx = nil end
- end
- if mode > 0 or rm == 5 then
- local dsz = mode
- if dsz ~= 1 then dsz = 4 end
- local disp = getimm(ctx, pos, dsz); if not disp then return end
- if mode == 0 then rm = nil end
- if rm or rx or (not sc and ctx.x64 and not ctx.a32) then
- if dsz == 1 and disp > 127 then
- sdisp = format("-0x%x", 256-disp)
- elseif disp >= 0 and disp <= 0x7fffffff then
- sdisp = format("+0x%x", disp)
- else
- sdisp = format("-0x%x", (0xffffffff+1)-disp)
- end
- else
- sdisp = format(ctx.x64 and not ctx.a32 and
- not (disp >= 0 and disp <= 0x7fffffff)
- and "0xffffffff%08x" or "0x%08x", disp)
- end
- pos = pos+dsz
- end
- end
- if rm and ctx.rexb then rm = rm + 8; ctx.rexb = false end
- if ctx.rexr then sp = sp + 8; ctx.rexr = false end
- end
- if p == "m" then
- if mode == 3 then x = regs[rm+1]
- else
- local aregs = ctx.a32 and map_regs.D or ctx.aregs
- local srm, srx = "", ""
- if rm then srm = aregs[rm+1]
- elseif not sc and ctx.x64 and not ctx.a32 then srm = "rip" end
- ctx.a32 = false
- if rx then
- if rm then srm = srm.."+" end
- srx = aregs[rx+1]
- if sc > 0 then srx = srx.."*"..(2^sc) end
- end
- x = format("[%s%s%s]", srm, srx, sdisp)
- end
- if mode < 3 and
- (not match(pat, "[aRrgp]") or match(pat, "t")) then -- Yuck.
- x = map_sz2prefix[sz].." "..x
- end
- elseif p == "r" then x = regs[sp+1]
- elseif p == "g" then x = map_segregs[sp+1]
- elseif p == "p" then -- Suppress prefix.
- elseif p == "f" then x = "st"..rm
- elseif p == "x" then
- if sp == 0 and ctx.lock and not ctx.x64 then
- x = "CR8"; ctx.lock = false
- else
- x = "CR"..sp
- end
- elseif p == "v" then
- if ctx.vexv then
- x = regs[ctx.vexv+1]; ctx.vexv = false
- end
- elseif p == "y" then x = "DR"..sp
- elseif p == "z" then x = "TR"..sp
- elseif p == "l" then vexl = false
- elseif p == "t" then
- else
- error("bad pattern `"..pat.."'")
- end
- end
- if x then operands = operands and operands..", "..x or x end
- end
- ctx.pos = pos
- return putop(ctx, name, operands)
-end
-
--- Forward declaration.
-local map_act
-
--- Fetch and cache MRM byte.
-local function getmrm(ctx)
- local mrm = ctx.mrm
- if not mrm then
- local pos = ctx.pos
- if pos > ctx.stop then return nil end
- mrm = byte(ctx.code, pos, pos)
- ctx.pos = pos+1
- ctx.mrm = mrm
- end
- return mrm
-end
-
--- Dispatch to handler depending on pattern.
-local function dispatch(ctx, opat, patgrp)
- if not opat then return unknown(ctx) end
- if match(opat, "%|") then -- MMX/SSE variants depending on prefix.
- local p
- if ctx.rep then
- p = ctx.rep=="rep" and "%|([^%|]*)" or "%|[^%|]*%|[^%|]*%|([^%|]*)"
- ctx.rep = false
- elseif ctx.o16 then p = "%|[^%|]*%|([^%|]*)"; ctx.o16 = false
- else p = "^[^%|]*" end
- opat = match(opat, p)
- if not opat then return unknown(ctx) end
--- ctx.rep = false; ctx.o16 = false
- --XXX fails for 66 f2 0f 38 f1 06 crc32 eax,WORD PTR [esi]
- --XXX remove in branches?
- end
- if match(opat, "%$") then -- reg$mem variants.
- local mrm = getmrm(ctx); if not mrm then return incomplete(ctx) end
- opat = match(opat, mrm >= 192 and "^[^%$]*" or "%$(.*)")
- if opat == "" then return unknown(ctx) end
- end
- if opat == "" then return unknown(ctx) end
- local name, pat = match(opat, "^([a-z0-9 ]*)(.*)")
- if pat == "" and patgrp then pat = patgrp end
- return map_act[sub(pat, 1, 1)](ctx, name, pat)
-end
-
--- Get a pattern from an opcode map and dispatch to handler.
-local function dispatchmap(ctx, opcmap)
- local pos = ctx.pos
- local opat = opcmap[byte(ctx.code, pos, pos)]
- pos = pos + 1
- ctx.pos = pos
- return dispatch(ctx, opat)
-end
-
--- Map for action codes. The key is the first char after the name.
-map_act = {
- -- Simple opcodes without operands.
- [""] = function(ctx, name, pat)
- return putop(ctx, name)
- end,
-
- -- Operand size chars fall right through.
- B = putpat, W = putpat, D = putpat, Q = putpat,
- V = putpat, U = putpat, T = putpat,
- M = putpat, X = putpat, P = putpat,
- F = putpat, G = putpat, Y = putpat,
- H = putpat,
-
- -- Collect prefixes.
- [":"] = function(ctx, name, pat)
- ctx[pat == ":" and name or sub(pat, 2)] = name
- if ctx.pos - ctx.start > 5 then return unknown(ctx) end -- Limit #prefixes.
- end,
-
- -- Chain to special handler specified by name.
- ["*"] = function(ctx, name, pat)
- return map_act[name](ctx, name, sub(pat, 2))
- end,
-
- -- Use named subtable for opcode group.
- ["!"] = function(ctx, name, pat)
- local mrm = getmrm(ctx); if not mrm then return incomplete(ctx) end
- return dispatch(ctx, map_opcgroup[name][((mrm-(mrm%8))/8)%8+1], sub(pat, 2))
- end,
-
- -- o16,o32[,o64] variants.
- sz = function(ctx, name, pat)
- if ctx.o16 then ctx.o16 = false
- else
- pat = match(pat, ",(.*)")
- if ctx.rexw then
- local p = match(pat, ",(.*)")
- if p then pat = p; ctx.rexw = false end
- end
- end
- pat = match(pat, "^[^,]*")
- return dispatch(ctx, pat)
- end,
-
- -- Two-byte opcode dispatch.
- opc2 = function(ctx, name, pat)
- return dispatchmap(ctx, map_opc2)
- end,
-
- -- Three-byte opcode dispatch.
- opc3 = function(ctx, name, pat)
- return dispatchmap(ctx, map_opc3[pat])
- end,
-
- -- VMX/SVM dispatch.
- vm = function(ctx, name, pat)
- return dispatch(ctx, map_opcvm[ctx.mrm])
- end,
-
- -- Floating point opcode dispatch.
- fp = function(ctx, name, pat)
- local mrm = getmrm(ctx); if not mrm then return incomplete(ctx) end
- local rm = mrm%8
- local idx = pat*8 + ((mrm-rm)/8)%8
- if mrm >= 192 then idx = idx + 64 end
- local opat = map_opcfp[idx]
- if type(opat) == "table" then opat = opat[rm+1] end
- return dispatch(ctx, opat)
- end,
-
- -- REX prefix.
- rex = function(ctx, name, pat)
- if ctx.rex then return unknown(ctx) end -- Only 1 REX or VEX prefix allowed.
- for p in gmatch(pat, ".") do ctx["rex"..p] = true end
- ctx.rex = "rex"
- end,
-
- -- VEX prefix.
- vex = function(ctx, name, pat)
- if ctx.rex then return unknown(ctx) end -- Only 1 REX or VEX prefix allowed.
- ctx.rex = "vex"
- local pos = ctx.pos
- if ctx.mrm then
- ctx.mrm = nil
- pos = pos-1
- end
- local b = byte(ctx.code, pos, pos)
- if not b then return incomplete(ctx) end
- pos = pos+1
- if b < 128 then ctx.rexr = true end
- local m = 1
- if pat == "3" then
- m = b%32; b = (b-m)/32
- local nb = b%2; b = (b-nb)/2
- if nb == 0 then ctx.rexb = true end
- local nx = b%2
- if nx == 0 then ctx.rexx = true end
- b = byte(ctx.code, pos, pos)
- if not b then return incomplete(ctx) end
- pos = pos+1
- if b >= 128 then ctx.rexw = true end
- end
- ctx.pos = pos
- local map
- if m == 1 then map = map_opc2
- elseif m == 2 then map = map_opc3["38"]
- elseif m == 3 then map = map_opc3["3a"]
- else return unknown(ctx) end
- local p = b%4; b = (b-p)/4
- if p == 1 then ctx.o16 = "o16"
- elseif p == 2 then ctx.rep = "rep"
- elseif p == 3 then ctx.rep = "repne" end
- local l = b%2; b = (b-l)/2
- if l ~= 0 then ctx.vexl = true end
- ctx.vexv = (-1-b)%16
- return dispatchmap(ctx, map)
- end,
-
- -- Special case for nop with REX prefix.
- nop = function(ctx, name, pat)
- return dispatch(ctx, ctx.rex and pat or "nop")
- end,
-
- -- Special case for 0F 77.
- emms = function(ctx, name, pat)
- if ctx.rex ~= "vex" then
- return putop(ctx, "emms")
- elseif ctx.vexl then
- ctx.vexl = false
- return putop(ctx, "zeroall")
- else
- return putop(ctx, "zeroupper")
- end
- end,
-}
-
-------------------------------------------------------------------------------
-
--- Disassemble a block of code.
-local function disass_block(ctx, ofs, len)
- if not ofs then ofs = 0 end
- local stop = len and ofs+len or #ctx.code
- ofs = ofs + 1
- ctx.start = ofs
- ctx.pos = ofs
- ctx.stop = stop
- ctx.imm = nil
- ctx.mrm = false
- clearprefixes(ctx)
- while ctx.pos <= stop do dispatchmap(ctx, ctx.map1) end
- if ctx.pos ~= ctx.start then incomplete(ctx) end
-end
-
--- Extended API: create a disassembler context. Then call ctx:disass(ofs, len).
-local function create(code, addr, out)
- local ctx = {}
- ctx.code = code
- ctx.addr = (addr or 0) - 1
- ctx.out = out or io.write
- ctx.symtab = {}
- ctx.disass = disass_block
- ctx.hexdump = 16
- ctx.x64 = false
- ctx.map1 = map_opc1_32
- ctx.aregs = map_regs.D
- return ctx
-end
-
-local function create64(code, addr, out)
- local ctx = create(code, addr, out)
- ctx.x64 = true
- ctx.map1 = map_opc1_64
- ctx.aregs = map_regs.Q
- return ctx
-end
-
--- Simple API: disassemble code (a string) at address and output via out.
-local function disass(code, addr, out)
- create(code, addr, out):disass()
-end
-
-local function disass64(code, addr, out)
- create64(code, addr, out):disass()
-end
-
--- Return register name for RID.
-local function regname(r)
- if r < 8 then return map_regs.D[r+1] end
- return map_regs.X[r-7]
-end
-
-local function regname64(r)
- if r < 16 then return map_regs.Q[r+1] end
- return map_regs.X[r-15]
-end
-
--- Public module functions.
-return {
- create = create,
- create64 = create64,
- disass = disass,
- disass64 = disass64,
- regname = regname,
- regname64 = regname64
-}
-
diff --git a/lib/LuaJIT/jit/dump.lua b/lib/LuaJIT/jit/dump.lua
deleted file mode 100644
index 2bea652..0000000
--- a/lib/LuaJIT/jit/dump.lua
+++ /dev/null
@@ -1,712 +0,0 @@
-----------------------------------------------------------------------------
--- LuaJIT compiler dump module.
---
--- Copyright (C) 2005-2017 Mike Pall. All rights reserved.
--- Released under the MIT license. See Copyright Notice in luajit.h
-----------------------------------------------------------------------------
---
--- This module can be used to debug the JIT compiler itself. It dumps the
--- code representations and structures used in various compiler stages.
---
--- Example usage:
---
--- luajit -jdump -e "local x=0; for i=1,1e6 do x=x+i end; print(x)"
--- luajit -jdump=im -e "for i=1,1000 do for j=1,1000 do end end" | less -R
--- luajit -jdump=is myapp.lua | less -R
--- luajit -jdump=-b myapp.lua
--- luajit -jdump=+aH,myapp.html myapp.lua
--- luajit -jdump=ixT,myapp.dump myapp.lua
---
--- The first argument specifies the dump mode. The second argument gives
--- the output file name. Default output is to stdout, unless the environment
--- variable LUAJIT_DUMPFILE is set. The file is overwritten every time the
--- module is started.
---
--- Different features can be turned on or off with the dump mode. If the
--- mode starts with a '+', the following features are added to the default
--- set of features; a '-' removes them. Otherwise the features are replaced.
---
--- The following dump features are available (* marks the default):
---
--- * t Print a line for each started, ended or aborted trace (see also -jv).
--- * b Dump the traced bytecode.
--- * i Dump the IR (intermediate representation).
--- r Augment the IR with register/stack slots.
--- s Dump the snapshot map.
--- * m Dump the generated machine code.
--- x Print each taken trace exit.
--- X Print each taken trace exit and the contents of all registers.
--- a Print the IR of aborted traces, too.
---
--- The output format can be set with the following characters:
---
--- T Plain text output.
--- A ANSI-colored text output
--- H Colorized HTML + CSS output.
---
--- The default output format is plain text. It's set to ANSI-colored text
--- if the COLORTERM variable is set. Note: this is independent of any output
--- redirection, which is actually considered a feature.
---
--- You probably want to use less -R to enjoy viewing ANSI-colored text from
--- a pipe or a file. Add this to your ~/.bashrc: export LESS="-R"
---
-------------------------------------------------------------------------------
-
--- Cache some library functions and objects.
-local jit = require("jit")
-assert(jit.version_num == 20100, "LuaJIT core/library version mismatch")
-local jutil = require("jit.util")
-local vmdef = require("jit.vmdef")
-local funcinfo, funcbc = jutil.funcinfo, jutil.funcbc
-local traceinfo, traceir, tracek = jutil.traceinfo, jutil.traceir, jutil.tracek
-local tracemc, tracesnap = jutil.tracemc, jutil.tracesnap
-local traceexitstub, ircalladdr = jutil.traceexitstub, jutil.ircalladdr
-local bit = require("bit")
-local band, shr, tohex = bit.band, bit.rshift, bit.tohex
-local sub, gsub, format = string.sub, string.gsub, string.format
-local byte, rep = string.byte, string.rep
-local type, tostring = type, tostring
-local stdout, stderr = io.stdout, io.stderr
-
--- Load other modules on-demand.
-local bcline, disass
-
--- Active flag, output file handle and dump mode.
-local active, out, dumpmode
-
-------------------------------------------------------------------------------
-
-local symtabmt = { __index = false }
-local symtab = {}
-local nexitsym = 0
-
--- Fill nested symbol table with per-trace exit stub addresses.
-local function fillsymtab_tr(tr, nexit)
- local t = {}
- symtabmt.__index = t
- if jit.arch:sub(1, 4) == "mips" then
- t[traceexitstub(tr, 0)] = "exit"
- return
- end
- for i=0,nexit-1 do
- local addr = traceexitstub(tr, i)
- if addr < 0 then addr = addr + 2^32 end
- t[addr] = tostring(i)
- end
- local addr = traceexitstub(tr, nexit)
- if addr then t[addr] = "stack_check" end
-end
-
--- Fill symbol table with trace exit stub addresses.
-local function fillsymtab(tr, nexit)
- local t = symtab
- if nexitsym == 0 then
- local ircall = vmdef.ircall
- for i=0,#ircall do
- local addr = ircalladdr(i)
- if addr ~= 0 then
- if addr < 0 then addr = addr + 2^32 end
- t[addr] = ircall[i]
- end
- end
- end
- if nexitsym == 1000000 then -- Per-trace exit stubs.
- fillsymtab_tr(tr, nexit)
- elseif nexit > nexitsym then -- Shared exit stubs.
- for i=nexitsym,nexit-1 do
- local addr = traceexitstub(i)
- if addr == nil then -- Fall back to per-trace exit stubs.
- fillsymtab_tr(tr, nexit)
- setmetatable(symtab, symtabmt)
- nexit = 1000000
- break
- end
- if addr < 0 then addr = addr + 2^32 end
- t[addr] = tostring(i)
- end
- nexitsym = nexit
- end
- return t
-end
-
-local function dumpwrite(s)
- out:write(s)
-end
-
--- Disassemble machine code.
-local function dump_mcode(tr)
- local info = traceinfo(tr)
- if not info then return end
- local mcode, addr, loop = tracemc(tr)
- if not mcode then return end
- if not disass then disass = require("jit.dis_"..jit.arch) end
- if addr < 0 then addr = addr + 2^32 end
- out:write("---- TRACE ", tr, " mcode ", #mcode, "\n")
- local ctx = disass.create(mcode, addr, dumpwrite)
- ctx.hexdump = 0
- ctx.symtab = fillsymtab(tr, info.nexit)
- if loop ~= 0 then
- symtab[addr+loop] = "LOOP"
- ctx:disass(0, loop)
- out:write("->LOOP:\n")
- ctx:disass(loop, #mcode-loop)
- symtab[addr+loop] = nil
- else
- ctx:disass(0, #mcode)
- end
-end
-
-------------------------------------------------------------------------------
-
-local irtype_text = {
- [0] = "nil",
- "fal",
- "tru",
- "lud",
- "str",
- "p32",
- "thr",
- "pro",
- "fun",
- "p64",
- "cdt",
- "tab",
- "udt",
- "flt",
- "num",
- "i8 ",
- "u8 ",
- "i16",
- "u16",
- "int",
- "u32",
- "i64",
- "u64",
- "sfp",
-}
-
-local colortype_ansi = {
- [0] = "%s",
- "%s",
- "%s",
- "\027[36m%s\027[m",
- "\027[32m%s\027[m",
- "%s",
- "\027[1m%s\027[m",
- "%s",
- "\027[1m%s\027[m",
- "%s",
- "\027[33m%s\027[m",
- "\027[31m%s\027[m",
- "\027[36m%s\027[m",
- "\027[34m%s\027[m",
- "\027[34m%s\027[m",
- "\027[35m%s\027[m",
- "\027[35m%s\027[m",
- "\027[35m%s\027[m",
- "\027[35m%s\027[m",
- "\027[35m%s\027[m",
- "\027[35m%s\027[m",
- "\027[35m%s\027[m",
- "\027[35m%s\027[m",
- "\027[35m%s\027[m",
-}
-
-local function colorize_text(s)
- return s
-end
-
-local function colorize_ansi(s, t)
- return format(colortype_ansi[t], s)
-end
-
-local irtype_ansi = setmetatable({},
- { __index = function(tab, t)
- local s = colorize_ansi(irtype_text[t], t); tab[t] = s; return s; end })
-
-local html_escape = { ["<"] = "&lt;", [">"] = "&gt;", ["&"] = "&amp;", }
-
-local function colorize_html(s, t)
- s = gsub(s, "[<>&]", html_escape)
- return format('<span class="irt_%s">%s</span>', irtype_text[t], s)
-end
-
-local irtype_html = setmetatable({},
- { __index = function(tab, t)
- local s = colorize_html(irtype_text[t], t); tab[t] = s; return s; end })
-
-local header_html = [[
-<style type="text/css">
-background { background: #ffffff; color: #000000; }
-pre.ljdump {
-font-size: 10pt;
-background: #f0f4ff;
-color: #000000;
-border: 1px solid #bfcfff;
-padding: 0.5em;
-margin-left: 2em;
-margin-right: 2em;
-}
-span.irt_str { color: #00a000; }
-span.irt_thr, span.irt_fun { color: #404040; font-weight: bold; }
-span.irt_tab { color: #c00000; }
-span.irt_udt, span.irt_lud { color: #00c0c0; }
-span.irt_num { color: #4040c0; }
-span.irt_int, span.irt_i8, span.irt_u8, span.irt_i16, span.irt_u16 { color: #b040b0; }
-</style>
-]]
-
-local colorize, irtype
-
--- Lookup tables to convert some literals into names.
-local litname = {
- ["SLOAD "] = setmetatable({}, { __index = function(t, mode)
- local s = ""
- if band(mode, 1) ~= 0 then s = s.."P" end
- if band(mode, 2) ~= 0 then s = s.."F" end
- if band(mode, 4) ~= 0 then s = s.."T" end
- if band(mode, 8) ~= 0 then s = s.."C" end
- if band(mode, 16) ~= 0 then s = s.."R" end
- if band(mode, 32) ~= 0 then s = s.."I" end
- t[mode] = s
- return s
- end}),
- ["XLOAD "] = { [0] = "", "R", "V", "RV", "U", "RU", "VU", "RVU", },
- ["CONV "] = setmetatable({}, { __index = function(t, mode)
- local s = irtype[band(mode, 31)]
- s = irtype[band(shr(mode, 5), 31)].."."..s
- if band(mode, 0x800) ~= 0 then s = s.." sext" end
- local c = shr(mode, 14)
- if c == 2 then s = s.." index" elseif c == 3 then s = s.." check" end
- t[mode] = s
- return s
- end}),
- ["FLOAD "] = vmdef.irfield,
- ["FREF "] = vmdef.irfield,
- ["FPMATH"] = vmdef.irfpm,
- ["BUFHDR"] = { [0] = "RESET", "APPEND" },
- ["TOSTR "] = { [0] = "INT", "NUM", "CHAR" },
-}
-
-local function ctlsub(c)
- if c == "\n" then return "\\n"
- elseif c == "\r" then return "\\r"
- elseif c == "\t" then return "\\t"
- else return format("\\%03d", byte(c))
- end
-end
-
-local function fmtfunc(func, pc)
- local fi = funcinfo(func, pc)
- if fi.loc then
- return fi.loc
- elseif fi.ffid then
- return vmdef.ffnames[fi.ffid]
- elseif fi.addr then
- return format("C:%x", fi.addr)
- else
- return "(?)"
- end
-end
-
-local function formatk(tr, idx, sn)
- local k, t, slot = tracek(tr, idx)
- local tn = type(k)
- local s
- if tn == "number" then
- if band(sn or 0, 0x30000) ~= 0 then
- s = band(sn, 0x20000) ~= 0 and "contpc" or "ftsz"
- elseif k == 2^52+2^51 then
- s = "bias"
- else
- s = format(0 < k and k < 0x1p-1026 and "%+a" or "%+.14g", k)
- end
- elseif tn == "string" then
- s = format(#k > 20 and '"%.20s"~' or '"%s"', gsub(k, "%c", ctlsub))
- elseif tn == "function" then
- s = fmtfunc(k)
- elseif tn == "table" then
- s = format("{%p}", k)
- elseif tn == "userdata" then
- if t == 12 then
- s = format("userdata:%p", k)
- else
- s = format("[%p]", k)
- if s == "[NULL]" then s = "NULL" end
- end
- elseif t == 21 then -- int64_t
- s = sub(tostring(k), 1, -3)
- if sub(s, 1, 1) ~= "-" then s = "+"..s end
- elseif sn == 0x1057fff then -- SNAP(1, SNAP_FRAME | SNAP_NORESTORE, REF_NIL)
- return "----" -- Special case for LJ_FR2 slot 1.
- else
- s = tostring(k) -- For primitives.
- end
- s = colorize(format("%-4s", s), t)
- if slot then
- s = format("%s @%d", s, slot)
- end
- return s
-end
-
-local function printsnap(tr, snap)
- local n = 2
- for s=0,snap[1]-1 do
- local sn = snap[n]
- if shr(sn, 24) == s then
- n = n + 1
- local ref = band(sn, 0xffff) - 0x8000 -- REF_BIAS
- if ref < 0 then
- out:write(formatk(tr, ref, sn))
- elseif band(sn, 0x80000) ~= 0 then -- SNAP_SOFTFPNUM
- out:write(colorize(format("%04d/%04d", ref, ref+1), 14))
- else
- local m, ot, op1, op2 = traceir(tr, ref)
- out:write(colorize(format("%04d", ref), band(ot, 31)))
- end
- out:write(band(sn, 0x10000) == 0 and " " or "|") -- SNAP_FRAME
- else
- out:write("---- ")
- end
- end
- out:write("]\n")
-end
-
--- Dump snapshots (not interleaved with IR).
-local function dump_snap(tr)
- out:write("---- TRACE ", tr, " snapshots\n")
- for i=0,1000000000 do
- local snap = tracesnap(tr, i)
- if not snap then break end
- out:write(format("#%-3d %04d [ ", i, snap[0]))
- printsnap(tr, snap)
- end
-end
-
--- Return a register name or stack slot for a rid/sp location.
-local function ridsp_name(ridsp, ins)
- if not disass then disass = require("jit.dis_"..jit.arch) end
- local rid, slot = band(ridsp, 0xff), shr(ridsp, 8)
- if rid == 253 or rid == 254 then
- return (slot == 0 or slot == 255) and " {sink" or format(" {%04d", ins-slot)
- end
- if ridsp > 255 then return format("[%x]", slot*4) end
- if rid < 128 then return disass.regname(rid) end
- return ""
-end
-
--- Dump CALL* function ref and return optional ctype.
-local function dumpcallfunc(tr, ins)
- local ctype
- if ins > 0 then
- local m, ot, op1, op2 = traceir(tr, ins)
- if band(ot, 31) == 0 then -- nil type means CARG(func, ctype).
- ins = op1
- ctype = formatk(tr, op2)
- end
- end
- if ins < 0 then
- out:write(format("[0x%x](", tonumber((tracek(tr, ins)))))
- else
- out:write(format("%04d (", ins))
- end
- return ctype
-end
-
--- Recursively gather CALL* args and dump them.
-local function dumpcallargs(tr, ins)
- if ins < 0 then
- out:write(formatk(tr, ins))
- else
- local m, ot, op1, op2 = traceir(tr, ins)
- local oidx = 6*shr(ot, 8)
- local op = sub(vmdef.irnames, oidx+1, oidx+6)
- if op == "CARG " then
- dumpcallargs(tr, op1)
- if op2 < 0 then
- out:write(" ", formatk(tr, op2))
- else
- out:write(" ", format("%04d", op2))
- end
- else
- out:write(format("%04d", ins))
- end
- end
-end
-
--- Dump IR and interleaved snapshots.
-local function dump_ir(tr, dumpsnap, dumpreg)
- local info = traceinfo(tr)
- if not info then return end
- local nins = info.nins
- out:write("---- TRACE ", tr, " IR\n")
- local irnames = vmdef.irnames
- local snapref = 65536
- local snap, snapno
- if dumpsnap then
- snap = tracesnap(tr, 0)
- snapref = snap[0]
- snapno = 0
- end
- for ins=1,nins do
- if ins >= snapref then
- if dumpreg then
- out:write(format(".... SNAP #%-3d [ ", snapno))
- else
- out:write(format(".... SNAP #%-3d [ ", snapno))
- end
- printsnap(tr, snap)
- snapno = snapno + 1
- snap = tracesnap(tr, snapno)
- snapref = snap and snap[0] or 65536
- end
- local m, ot, op1, op2, ridsp = traceir(tr, ins)
- local oidx, t = 6*shr(ot, 8), band(ot, 31)
- local op = sub(irnames, oidx+1, oidx+6)
- if op == "LOOP " then
- if dumpreg then
- out:write(format("%04d ------------ LOOP ------------\n", ins))
- else
- out:write(format("%04d ------ LOOP ------------\n", ins))
- end
- elseif op ~= "NOP " and op ~= "CARG " and
- (dumpreg or op ~= "RENAME") then
- local rid = band(ridsp, 255)
- if dumpreg then
- out:write(format("%04d %-6s", ins, ridsp_name(ridsp, ins)))
- else
- out:write(format("%04d ", ins))
- end
- out:write(format("%s%s %s %s ",
- (rid == 254 or rid == 253) and "}" or
- (band(ot, 128) == 0 and " " or ">"),
- band(ot, 64) == 0 and " " or "+",
- irtype[t], op))
- local m1, m2 = band(m, 3), band(m, 3*4)
- if sub(op, 1, 4) == "CALL" then
- local ctype
- if m2 == 1*4 then -- op2 == IRMlit
- out:write(format("%-10s (", vmdef.ircall[op2]))
- else
- ctype = dumpcallfunc(tr, op2)
- end
- if op1 ~= -1 then dumpcallargs(tr, op1) end
- out:write(")")
- if ctype then out:write(" ctype ", ctype) end
- elseif op == "CNEW " and op2 == -1 then
- out:write(formatk(tr, op1))
- elseif m1 ~= 3 then -- op1 != IRMnone
- if op1 < 0 then
- out:write(formatk(tr, op1))
- else
- out:write(format(m1 == 0 and "%04d" or "#%-3d", op1))
- end
- if m2 ~= 3*4 then -- op2 != IRMnone
- if m2 == 1*4 then -- op2 == IRMlit
- local litn = litname[op]
- if litn and litn[op2] then
- out:write(" ", litn[op2])
- elseif op == "UREFO " or op == "UREFC " then
- out:write(format(" #%-3d", shr(op2, 8)))
- else
- out:write(format(" #%-3d", op2))
- end
- elseif op2 < 0 then
- out:write(" ", formatk(tr, op2))
- else
- out:write(format(" %04d", op2))
- end
- end
- end
- out:write("\n")
- end
- end
- if snap then
- if dumpreg then
- out:write(format(".... SNAP #%-3d [ ", snapno))
- else
- out:write(format(".... SNAP #%-3d [ ", snapno))
- end
- printsnap(tr, snap)
- end
-end
-
-------------------------------------------------------------------------------
-
-local recprefix = ""
-local recdepth = 0
-
--- Format trace error message.
-local function fmterr(err, info)
- if type(err) == "number" then
- if type(info) == "function" then info = fmtfunc(info) end
- err = format(vmdef.traceerr[err], info)
- end
- return err
-end
-
--- Dump trace states.
-local function dump_trace(what, tr, func, pc, otr, oex)
- if what == "stop" or (what == "abort" and dumpmode.a) then
- if dumpmode.i then dump_ir(tr, dumpmode.s, dumpmode.r and what == "stop")
- elseif dumpmode.s then dump_snap(tr) end
- if dumpmode.m then dump_mcode(tr) end
- end
- if what == "start" then
- if dumpmode.H then out:write('<pre class="ljdump">\n') end
- out:write("---- TRACE ", tr, " ", what)
- if otr then out:write(" ", otr, "/", oex == -1 and "stitch" or oex) end
- out:write(" ", fmtfunc(func, pc), "\n")
- elseif what == "stop" or what == "abort" then
- out:write("---- TRACE ", tr, " ", what)
- if what == "abort" then
- out:write(" ", fmtfunc(func, pc), " -- ", fmterr(otr, oex), "\n")
- else
- local info = traceinfo(tr)
- local link, ltype = info.link, info.linktype
- if link == tr or link == 0 then
- out:write(" -> ", ltype, "\n")
- elseif ltype == "root" then
- out:write(" -> ", link, "\n")
- else
- out:write(" -> ", link, " ", ltype, "\n")
- end
- end
- if dumpmode.H then out:write("</pre>\n\n") else out:write("\n") end
- else
- if what == "flush" then symtab, nexitsym = {}, 0 end
- out:write("---- TRACE ", what, "\n\n")
- end
- out:flush()
-end
-
--- Dump recorded bytecode.
-local function dump_record(tr, func, pc, depth, callee)
- if depth ~= recdepth then
- recdepth = depth
- recprefix = rep(" .", depth)
- end
- local line
- if pc >= 0 then
- line = bcline(func, pc, recprefix)
- if dumpmode.H then line = gsub(line, "[<>&]", html_escape) end
- else
- line = "0000 "..recprefix.." FUNCC \n"
- callee = func
- end
- if pc <= 0 then
- out:write(sub(line, 1, -2), " ; ", fmtfunc(func), "\n")
- else
- out:write(line)
- end
- if pc >= 0 and band(funcbc(func, pc), 0xff) < 16 then -- ORDER BC
- out:write(bcline(func, pc+1, recprefix)) -- Write JMP for cond.
- end
-end
-
-------------------------------------------------------------------------------
-
--- Dump taken trace exits.
-local function dump_texit(tr, ex, ngpr, nfpr, ...)
- out:write("---- TRACE ", tr, " exit ", ex, "\n")
- if dumpmode.X then
- local regs = {...}
- if jit.arch == "x64" then
- for i=1,ngpr do
- out:write(format(" %016x", regs[i]))
- if i % 4 == 0 then out:write("\n") end
- end
- else
- for i=1,ngpr do
- out:write(" ", tohex(regs[i]))
- if i % 8 == 0 then out:write("\n") end
- end
- end
- if jit.arch == "mips" or jit.arch == "mipsel" then
- for i=1,nfpr,2 do
- out:write(format(" %+17.14g", regs[ngpr+i]))
- if i % 8 == 7 then out:write("\n") end
- end
- else
- for i=1,nfpr do
- out:write(format(" %+17.14g", regs[ngpr+i]))
- if i % 4 == 0 then out:write("\n") end
- end
- end
- end
-end
-
-------------------------------------------------------------------------------
-
--- Detach dump handlers.
-local function dumpoff()
- if active then
- active = false
- jit.attach(dump_texit)
- jit.attach(dump_record)
- jit.attach(dump_trace)
- if out and out ~= stdout and out ~= stderr then out:close() end
- out = nil
- end
-end
-
--- Open the output file and attach dump handlers.
-local function dumpon(opt, outfile)
- if active then dumpoff() end
-
- local term = os.getenv("TERM")
- local colormode = (term and term:match("color") or os.getenv("COLORTERM")) and "A" or "T"
- if opt then
- opt = gsub(opt, "[TAH]", function(mode) colormode = mode; return ""; end)
- end
-
- local m = { t=true, b=true, i=true, m=true, }
- if opt and opt ~= "" then
- local o = sub(opt, 1, 1)
- if o ~= "+" and o ~= "-" then m = {} end
- for i=1,#opt do m[sub(opt, i, i)] = (o ~= "-") end
- end
- dumpmode = m
-
- if m.t or m.b or m.i or m.s or m.m then
- jit.attach(dump_trace, "trace")
- end
- if m.b then
- jit.attach(dump_record, "record")
- if not bcline then bcline = require("jit.bc").line end
- end
- if m.x or m.X then
- jit.attach(dump_texit, "texit")
- end
-
- if not outfile then outfile = os.getenv("LUAJIT_DUMPFILE") end
- if outfile then
- out = outfile == "-" and stdout or assert(io.open(outfile, "w"))
- else
- out = stdout
- end
-
- m[colormode] = true
- if colormode == "A" then
- colorize = colorize_ansi
- irtype = irtype_ansi
- elseif colormode == "H" then
- colorize = colorize_html
- irtype = irtype_html
- out:write(header_html)
- else
- colorize = colorize_text
- irtype = irtype_text
- end
-
- active = true
-end
-
--- Public module functions.
-return {
- on = dumpon,
- off = dumpoff,
- start = dumpon -- For -j command line option.
-}
-
diff --git a/lib/LuaJIT/jit/p.lua b/lib/LuaJIT/jit/p.lua
deleted file mode 100644
index 7be1058..0000000
--- a/lib/LuaJIT/jit/p.lua
+++ /dev/null
@@ -1,311 +0,0 @@
-----------------------------------------------------------------------------
--- LuaJIT profiler.
---
--- Copyright (C) 2005-2017 Mike Pall. All rights reserved.
--- Released under the MIT license. See Copyright Notice in luajit.h
-----------------------------------------------------------------------------
---
--- This module is a simple command line interface to the built-in
--- low-overhead profiler of LuaJIT.
---
--- The lower-level API of the profiler is accessible via the "jit.profile"
--- module or the luaJIT_profile_* C API.
---
--- Example usage:
---
--- luajit -jp myapp.lua
--- luajit -jp=s myapp.lua
--- luajit -jp=-s myapp.lua
--- luajit -jp=vl myapp.lua
--- luajit -jp=G,profile.txt myapp.lua
---
--- The following dump features are available:
---
--- f Stack dump: function name, otherwise module:line. Default mode.
--- F Stack dump: ditto, but always prepend module.
--- l Stack dump: module:line.
--- <number> stack dump depth (callee < caller). Default: 1.
--- -<number> Inverse stack dump depth (caller > callee).
--- s Split stack dump after first stack level. Implies abs(depth) >= 2.
--- p Show full path for module names.
--- v Show VM states. Can be combined with stack dumps, e.g. vf or fv.
--- z Show zones. Can be combined with stack dumps, e.g. zf or fz.
--- r Show raw sample counts. Default: show percentages.
--- a Annotate excerpts from source code files.
--- A Annotate complete source code files.
--- G Produce raw output suitable for graphical tools (e.g. flame graphs).
--- m<number> Minimum sample percentage to be shown. Default: 3.
--- i<number> Sampling interval in milliseconds. Default: 10.
---
-----------------------------------------------------------------------------
-
--- Cache some library functions and objects.
-local jit = require("jit")
-assert(jit.version_num == 20100, "LuaJIT core/library version mismatch")
-local profile = require("jit.profile")
-local vmdef = require("jit.vmdef")
-local math = math
-local pairs, ipairs, tonumber, floor = pairs, ipairs, tonumber, math.floor
-local sort, format = table.sort, string.format
-local stdout = io.stdout
-local zone -- Load jit.zone module on demand.
-
--- Output file handle.
-local out
-
-------------------------------------------------------------------------------
-
-local prof_ud
-local prof_states, prof_split, prof_min, prof_raw, prof_fmt, prof_depth
-local prof_ann, prof_count1, prof_count2, prof_samples
-
-local map_vmmode = {
- N = "Compiled",
- I = "Interpreted",
- C = "C code",
- G = "Garbage Collector",
- J = "JIT Compiler",
-}
-
--- Profiler callback.
-local function prof_cb(th, samples, vmmode)
- prof_samples = prof_samples + samples
- local key_stack, key_stack2, key_state
- -- Collect keys for sample.
- if prof_states then
- if prof_states == "v" then
- key_state = map_vmmode[vmmode] or vmmode
- else
- key_state = zone:get() or "(none)"
- end
- end
- if prof_fmt then
- key_stack = profile.dumpstack(th, prof_fmt, prof_depth)
- key_stack = key_stack:gsub("%[builtin#(%d+)%]", function(x)
- return vmdef.ffnames[tonumber(x)]
- end)
- if prof_split == 2 then
- local k1, k2 = key_stack:match("(.-) [<>] (.*)")
- if k2 then key_stack, key_stack2 = k1, k2 end
- elseif prof_split == 3 then
- key_stack2 = profile.dumpstack(th, "l", 1)
- end
- end
- -- Order keys.
- local k1, k2
- if prof_split == 1 then
- if key_state then
- k1 = key_state
- if key_stack then k2 = key_stack end
- end
- elseif key_stack then
- k1 = key_stack
- if key_stack2 then k2 = key_stack2 elseif key_state then k2 = key_state end
- end
- -- Coalesce samples in one or two levels.
- if k1 then
- local t1 = prof_count1
- t1[k1] = (t1[k1] or 0) + samples
- if k2 then
- local t2 = prof_count2
- local t3 = t2[k1]
- if not t3 then t3 = {}; t2[k1] = t3 end
- t3[k2] = (t3[k2] or 0) + samples
- end
- end
-end
-
-------------------------------------------------------------------------------
-
--- Show top N list.
-local function prof_top(count1, count2, samples, indent)
- local t, n = {}, 0
- for k in pairs(count1) do
- n = n + 1
- t[n] = k
- end
- sort(t, function(a, b) return count1[a] > count1[b] end)
- for i=1,n do
- local k = t[i]
- local v = count1[k]
- local pct = floor(v*100/samples + 0.5)
- if pct < prof_min then break end
- if not prof_raw then
- out:write(format("%s%2d%% %s\n", indent, pct, k))
- elseif prof_raw == "r" then
- out:write(format("%s%5d %s\n", indent, v, k))
- else
- out:write(format("%s %d\n", k, v))
- end
- if count2 then
- local r = count2[k]
- if r then
- prof_top(r, nil, v, (prof_split == 3 or prof_split == 1) and " -- " or
- (prof_depth < 0 and " -> " or " <- "))
- end
- end
- end
-end
-
--- Annotate source code
-local function prof_annotate(count1, samples)
- local files = {}
- local ms = 0
- for k, v in pairs(count1) do
- local pct = floor(v*100/samples + 0.5)
- ms = math.max(ms, v)
- if pct >= prof_min then
- local file, line = k:match("^(.*):(%d+)$")
- if not file then file = k; line = 0 end
- local fl = files[file]
- if not fl then fl = {}; files[file] = fl; files[#files+1] = file end
- line = tonumber(line)
- fl[line] = prof_raw and v or pct
- end
- end
- sort(files)
- local fmtv, fmtn = " %3d%% | %s\n", " | %s\n"
- if prof_raw then
- local n = math.max(5, math.ceil(math.log10(ms)))
- fmtv = "%"..n.."d | %s\n"
- fmtn = (" "):rep(n).." | %s\n"
- end
- local ann = prof_ann
- for _, file in ipairs(files) do
- local f0 = file:byte()
- if f0 == 40 or f0 == 91 then
- out:write(format("\n====== %s ======\n[Cannot annotate non-file]\n", file))
- break
- end
- local fp, err = io.open(file)
- if not fp then
- out:write(format("====== ERROR: %s: %s\n", file, err))
- break
- end
- out:write(format("\n====== %s ======\n", file))
- local fl = files[file]
- local n, show = 1, false
- if ann ~= 0 then
- for i=1,ann do
- if fl[i] then show = true; out:write("@@ 1 @@\n"); break end
- end
- end
- for line in fp:lines() do
- if line:byte() == 27 then
- out:write("[Cannot annotate bytecode file]\n")
- break
- end
- local v = fl[n]
- if ann ~= 0 then
- local v2 = fl[n+ann]
- if show then
- if v2 then show = n+ann elseif v then show = n
- elseif show+ann < n then show = false end
- elseif v2 then
- show = n+ann
- out:write(format("@@ %d @@\n", n))
- end
- if not show then goto next end
- end
- if v then
- out:write(format(fmtv, v, line))
- else
- out:write(format(fmtn, line))
- end
- ::next::
- n = n + 1
- end
- fp:close()
- end
-end
-
-------------------------------------------------------------------------------
-
--- Finish profiling and dump result.
-local function prof_finish()
- if prof_ud then
- profile.stop()
- local samples = prof_samples
- if samples == 0 then
- if prof_raw ~= true then out:write("[No samples collected]\n") end
- return
- end
- if prof_ann then
- prof_annotate(prof_count1, samples)
- else
- prof_top(prof_count1, prof_count2, samples, "")
- end
- prof_count1 = nil
- prof_count2 = nil
- prof_ud = nil
- end
-end
-
--- Start profiling.
-local function prof_start(mode)
- local interval = ""
- mode = mode:gsub("i%d*", function(s) interval = s; return "" end)
- prof_min = 3
- mode = mode:gsub("m(%d+)", function(s) prof_min = tonumber(s); return "" end)
- prof_depth = 1
- mode = mode:gsub("%-?%d+", function(s) prof_depth = tonumber(s); return "" end)
- local m = {}
- for c in mode:gmatch(".") do m[c] = c end
- prof_states = m.z or m.v
- if prof_states == "z" then zone = require("jit.zone") end
- local scope = m.l or m.f or m.F or (prof_states and "" or "f")
- local flags = (m.p or "")
- prof_raw = m.r
- if m.s then
- prof_split = 2
- if prof_depth == -1 or m["-"] then prof_depth = -2
- elseif prof_depth == 1 then prof_depth = 2 end
- elseif mode:find("[fF].*l") then
- scope = "l"
- prof_split = 3
- else
- prof_split = (scope == "" or mode:find("[zv].*[lfF]")) and 1 or 0
- end
- prof_ann = m.A and 0 or (m.a and 3)
- if prof_ann then
- scope = "l"
- prof_fmt = "pl"
- prof_split = 0
- prof_depth = 1
- elseif m.G and scope ~= "" then
- prof_fmt = flags..scope.."Z;"
- prof_depth = -100
- prof_raw = true
- prof_min = 0
- elseif scope == "" then
- prof_fmt = false
- else
- local sc = prof_split == 3 and m.f or m.F or scope
- prof_fmt = flags..sc..(prof_depth >= 0 and "Z < " or "Z > ")
- end
- prof_count1 = {}
- prof_count2 = {}
- prof_samples = 0
- profile.start(scope:lower()..interval, prof_cb)
- prof_ud = newproxy(true)
- getmetatable(prof_ud).__gc = prof_finish
-end
-
-------------------------------------------------------------------------------
-
-local function start(mode, outfile)
- if not outfile then outfile = os.getenv("LUAJIT_PROFILEFILE") end
- if outfile then
- out = outfile == "-" and stdout or assert(io.open(outfile, "w"))
- else
- out = stdout
- end
- prof_start(mode or "f")
-end
-
--- Public module functions.
-return {
- start = start, -- For -j command line option.
- stop = prof_finish
-}
-
diff --git a/lib/LuaJIT/jit/v.lua b/lib/LuaJIT/jit/v.lua
deleted file mode 100644
index 934de98..0000000
--- a/lib/LuaJIT/jit/v.lua
+++ /dev/null
@@ -1,170 +0,0 @@
-----------------------------------------------------------------------------
--- Verbose mode of the LuaJIT compiler.
---
--- Copyright (C) 2005-2017 Mike Pall. All rights reserved.
--- Released under the MIT license. See Copyright Notice in luajit.h
-----------------------------------------------------------------------------
---
--- This module shows verbose information about the progress of the
--- JIT compiler. It prints one line for each generated trace. This module
--- is useful to see which code has been compiled or where the compiler
--- punts and falls back to the interpreter.
---
--- Example usage:
---
--- luajit -jv -e "for i=1,1000 do for j=1,1000 do end end"
--- luajit -jv=myapp.out myapp.lua
---
--- Default output is to stderr. To redirect the output to a file, pass a
--- filename as an argument (use '-' for stdout) or set the environment
--- variable LUAJIT_VERBOSEFILE. The file is overwritten every time the
--- module is started.
---
--- The output from the first example should look like this:
---
--- [TRACE 1 (command line):1 loop]
--- [TRACE 2 (1/3) (command line):1 -> 1]
---
--- The first number in each line is the internal trace number. Next are
--- the file name ('(command line)') and the line number (':1') where the
--- trace has started. Side traces also show the parent trace number and
--- the exit number where they are attached to in parentheses ('(1/3)').
--- An arrow at the end shows where the trace links to ('-> 1'), unless
--- it loops to itself.
---
--- In this case the inner loop gets hot and is traced first, generating
--- a root trace. Then the last exit from the 1st trace gets hot, too,
--- and triggers generation of the 2nd trace. The side trace follows the
--- path along the outer loop and *around* the inner loop, back to its
--- start, and then links to the 1st trace. Yes, this may seem unusual,
--- if you know how traditional compilers work. Trace compilers are full
--- of surprises like this -- have fun! :-)
---
--- Aborted traces are shown like this:
---
--- [TRACE --- foo.lua:44 -- leaving loop in root trace at foo:lua:50]
---
--- Don't worry -- trace aborts are quite common, even in programs which
--- can be fully compiled. The compiler may retry several times until it
--- finds a suitable trace.
---
--- Of course this doesn't work with features that are not-yet-implemented
--- (NYI error messages). The VM simply falls back to the interpreter. This
--- may not matter at all if the particular trace is not very high up in
--- the CPU usage profile. Oh, and the interpreter is quite fast, too.
---
--- Also check out the -jdump module, which prints all the gory details.
---
-------------------------------------------------------------------------------
-
--- Cache some library functions and objects.
-local jit = require("jit")
-assert(jit.version_num == 20100, "LuaJIT core/library version mismatch")
-local jutil = require("jit.util")
-local vmdef = require("jit.vmdef")
-local funcinfo, traceinfo = jutil.funcinfo, jutil.traceinfo
-local type, format = type, string.format
-local stdout, stderr = io.stdout, io.stderr
-
--- Active flag and output file handle.
-local active, out
-
-------------------------------------------------------------------------------
-
-local startloc, startex
-
-local function fmtfunc(func, pc)
- local fi = funcinfo(func, pc)
- if fi.loc then
- return fi.loc
- elseif fi.ffid then
- return vmdef.ffnames[fi.ffid]
- elseif fi.addr then
- return format("C:%x", fi.addr)
- else
- return "(?)"
- end
-end
-
--- Format trace error message.
-local function fmterr(err, info)
- if type(err) == "number" then
- if type(info) == "function" then info = fmtfunc(info) end
- err = format(vmdef.traceerr[err], info)
- end
- return err
-end
-
--- Dump trace states.
-local function dump_trace(what, tr, func, pc, otr, oex)
- if what == "start" then
- startloc = fmtfunc(func, pc)
- startex = otr and "("..otr.."/"..(oex == -1 and "stitch" or oex)..") " or ""
- else
- if what == "abort" then
- local loc = fmtfunc(func, pc)
- if loc ~= startloc then
- out:write(format("[TRACE --- %s%s -- %s at %s]\n",
- startex, startloc, fmterr(otr, oex), loc))
- else
- out:write(format("[TRACE --- %s%s -- %s]\n",
- startex, startloc, fmterr(otr, oex)))
- end
- elseif what == "stop" then
- local info = traceinfo(tr)
- local link, ltype = info.link, info.linktype
- if ltype == "interpreter" then
- out:write(format("[TRACE %3s %s%s -- fallback to interpreter]\n",
- tr, startex, startloc))
- elseif ltype == "stitch" then
- out:write(format("[TRACE %3s %s%s %s %s]\n",
- tr, startex, startloc, ltype, fmtfunc(func, pc)))
- elseif link == tr or link == 0 then
- out:write(format("[TRACE %3s %s%s %s]\n",
- tr, startex, startloc, ltype))
- elseif ltype == "root" then
- out:write(format("[TRACE %3s %s%s -> %d]\n",
- tr, startex, startloc, link))
- else
- out:write(format("[TRACE %3s %s%s -> %d %s]\n",
- tr, startex, startloc, link, ltype))
- end
- else
- out:write(format("[TRACE %s]\n", what))
- end
- out:flush()
- end
-end
-
-------------------------------------------------------------------------------
-
--- Detach dump handlers.
-local function dumpoff()
- if active then
- active = false
- jit.attach(dump_trace)
- if out and out ~= stdout and out ~= stderr then out:close() end
- out = nil
- end
-end
-
--- Open the output file and attach dump handlers.
-local function dumpon(outfile)
- if active then dumpoff() end
- if not outfile then outfile = os.getenv("LUAJIT_VERBOSEFILE") end
- if outfile then
- out = outfile == "-" and stdout or assert(io.open(outfile, "w"))
- else
- out = stderr
- end
- jit.attach(dump_trace, "trace")
- active = true
-end
-
--- Public module functions.
-return {
- on = dumpon,
- off = dumpoff,
- start = dumpon -- For -j command line option.
-}
-
diff --git a/lib/LuaJIT/jit/zone.lua b/lib/LuaJIT/jit/zone.lua
deleted file mode 100644
index fa702c4..0000000
--- a/lib/LuaJIT/jit/zone.lua
+++ /dev/null
@@ -1,45 +0,0 @@
-----------------------------------------------------------------------------
--- LuaJIT profiler zones.
---
--- Copyright (C) 2005-2017 Mike Pall. All rights reserved.
--- Released under the MIT license. See Copyright Notice in luajit.h
-----------------------------------------------------------------------------
---
--- This module implements a simple hierarchical zone model.
---
--- Example usage:
---
--- local zone = require("jit.zone")
--- zone("AI")
--- ...
--- zone("A*")
--- ...
--- print(zone:get()) --> "A*"
--- ...
--- zone()
--- ...
--- print(zone:get()) --> "AI"
--- ...
--- zone()
---
-----------------------------------------------------------------------------
-
-local remove = table.remove
-
-return setmetatable({
- flush = function(t)
- for i=#t,1,-1 do t[i] = nil end
- end,
- get = function(t)
- return t[#t]
- end
-}, {
- __call = function(t, zone)
- if zone then
- t[#t+1] = zone
- else
- return (assert(remove(t), "empty zone stack"))
- end
- end
-})
-