diff --git a/src/deps/src/luajit/doc/extensions.html b/src/deps/src/luajit/doc/extensions.html
index a4f20841a..c1c9a808c 100644
--- a/src/deps/src/luajit/doc/extensions.html
+++ b/src/deps/src/luajit/doc/extensions.html
@@ -160,13 +160,33 @@ passes any arguments after the error function to the function
which is called in a protected context.
-loadfile() etc. handle UTF-8 source code
+load*() handle UTF-8 source code
Non-ASCII characters are handled transparently by the Lua source code parser.
This allows the use of UTF-8 characters in identifiers and strings.
A UTF-8 BOM is skipped at the start of the source code.
+load*() add a mode parameter
+
+As an extension from Lua 5.2, the functions loadstring(),
+loadfile() and (new) load() add an optional
+mode parameter.
+
+
+The default mode string is "bt", which allows loading of both
+source code and bytecode. Use "t" to allow only source code
+or "b" to allow only bytecode to be loaded.
+
+
+By default, the load* functions generate the native bytecode format.
+For cross-compilation purposes, add W to the mode string to
+force the 32 bit format and X to force the 64 bit format.
+Add both to force the opposite format. Note that non-native bytecode
+generated by load* cannot be run, but can still be passed
+to string.dump.
+
+
tostring() etc. canonicalize NaN and ±Inf
All number-to-string conversions consistently convert non-finite numbers
@@ -186,26 +206,33 @@ works independently of the current locale and it supports hex floating-point
numbers (e.g. 0x1.5p-3).
-string.dump(f [,strip]) generates portable bytecode
+string.dump(f [,mode]) generates portable bytecode
An extra argument has been added to string.dump(). If set to
-true, 'stripped' bytecode without debug information is
-generated. This speeds up later bytecode loading and reduces memory
-usage. See also the
+true or to a string which contains the character s,
+'stripped' bytecode without debug information is generated. This speeds
+up later bytecode loading and reduces memory usage. See also the
-b command line option.
The generated bytecode is portable and can be loaded on any architecture
-that LuaJIT supports, independent of word size or endianess. However, the
-bytecode compatibility versions must match. Bytecode stays compatible
-for dot releases (x.y.0 → x.y.1), but may change with major or
-minor releases (2.0 → 2.1) or between any beta release. Foreign
-bytecode (e.g. from Lua 5.1) is incompatible and cannot be loaded.
+that LuaJIT supports. However, the bytecode compatibility versions must
+match. Bytecode only stays compatible within a major+minor version
+(x.y.aaa → x.y.bbb), except for development branches. Foreign bytecode
+(e.g. from Lua 5.1) is incompatible and cannot be loaded.
Note: LJ_GC64 mode requires a different frame layout, which implies
-a different, incompatible bytecode format for all 64 bit ports. This may be
-rectified in the future.
+a different, incompatible bytecode format between 32 bit and 64 bit ports.
+This may be rectified in the future. In the meantime, use the W
+and X modes of the load* functions
+for cross-compilation purposes.
+
+
+Due to VM hardening, bytecode is not deterministic. Add d to the
+mode string to dump it in a deterministic manner: identical source code
+always gives a byte-for-byte identical bytecode dump. This feature is
+mainly useful for reproducible builds.
table.new(narray, nhash) allocates a pre-sized table
@@ -286,7 +313,7 @@ enabled:
- goto and ::labels::.
-- Hex escapes '\x3F' and '\*' escape in strings.
+- Hex escapes '\x3F' and '\z' escape in strings.
- load(string|reader [, chunkname [,mode [,env]]]).
- loadstring() is an alias for load().
- loadfile(filename [,mode [,env]]).
diff --git a/src/deps/src/luajit/doc/install.html b/src/deps/src/luajit/doc/install.html
index 04bfe26d1..b64814431 100644
--- a/src/deps/src/luajit/doc/install.html
+++ b/src/deps/src/luajit/doc/install.html
@@ -269,6 +269,7 @@ for any supported target:
- Yes, you need a toolchain for both your host and your target!
- Both host and target architectures must have the same pointer size.
- E.g. if you want to cross-compile to a 32 bit target on a 64 bit host, you need to install the multilib development package (e.g. libc6-dev-i386 on Debian/Ubuntu) and build a 32 bit host part (HOST_CC="gcc -m32").
+- On some distro versions, multilib conflicts with cross-compilers. The workaround is to install the x86 cross-compiler package gcc-i686-linux-gnu and use it to build the host part (HOST_CC=i686-linux-gnu-gcc).
- 64 bit targets always require compilation on a 64 bit host.
diff --git a/src/deps/src/luajit/doc/running.html b/src/deps/src/luajit/doc/running.html
index 9dd2b411c..142b810fc 100644
--- a/src/deps/src/luajit/doc/running.html
+++ b/src/deps/src/luajit/doc/running.html
@@ -106,6 +106,9 @@ are accepted:
-l — Only list bytecode.
-s — Strip debug info (this is the default).
-g — Keep debug info.
+-W — Generate 32 bit (non-GC64) bytecode.
+-X — Generate 64 bit (GC64) bytecode.
+-d — Generate bytecode in deterministic manner.
-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).
diff --git a/src/deps/src/luajit/dynasm/dasm_x86.lua b/src/deps/src/luajit/dynasm/dasm_x86.lua
index 787163c0c..7c789f821 100644
--- a/src/deps/src/luajit/dynasm/dasm_x86.lua
+++ b/src/deps/src/luajit/dynasm/dasm_x86.lua
@@ -627,7 +627,11 @@ local function wputmrmsib(t, imark, s, vsreg, psz, sk)
werror("NYI: rip-relative displacement followed by immediate")
end
-- The previous byte in the action buffer cannot be 0xe9 or 0x80-0x8f.
- wputlabel("REL_", disp[1], 2)
+ if disp[2] == "iPJ" then
+ waction("REL_A", disp[1])
+ else
+ wputlabel("REL_", disp[1], 2)
+ end
else
wputdarg(disp)
end
@@ -744,9 +748,9 @@ local function dispexpr(expr)
return imm*map_opsizenum[ops]
end
local mode, iexpr = immexpr(dispt)
- if mode == "iJ" then
+ if mode == "iJ" or mode == "iPJ" then
if c == "-" then werror("cannot invert label reference") end
- return { iexpr }
+ return { iexpr, mode }
end
return expr -- Need to return original signed expression.
end
@@ -1147,6 +1151,8 @@ local map_op = {
rep_0 = "F3",
repe_0 = "F3",
repz_0 = "F3",
+ endbr32_0 = "F30F1EFB",
+ endbr64_0 = "F30F1EFA",
-- F4: *hlt
cmc_0 = "F5",
-- F6: test... mb,i; div... mb
diff --git a/src/deps/src/luajit/dynasm/dynasm.lua b/src/deps/src/luajit/dynasm/dynasm.lua
index 5be75f7fc..0d15a8728 100644
--- a/src/deps/src/luajit/dynasm/dynasm.lua
+++ b/src/deps/src/luajit/dynasm/dynasm.lua
@@ -75,7 +75,7 @@ local function wline(line, needindent)
g_synclineno = g_synclineno + 1
end
--- Write assembler line as a comment, if requestd.
+-- Write assembler line as a comment, if requested.
local function wcomment(aline)
if g_opt.comment then
wline(g_opt.comment..aline..g_opt.endcomment, true)
diff --git a/src/deps/src/luajit/src/host/genlibbc.lua b/src/deps/src/luajit/src/host/genlibbc.lua
index 3621c3f50..e697fceb8 100644
--- a/src/deps/src/luajit/src/host/genlibbc.lua
+++ b/src/deps/src/luajit/src/host/genlibbc.lua
@@ -138,65 +138,73 @@ local function fixup_dump(dump, fixup)
return { dump = ndump, startbc = startbc, sizebc = sizebc }
end
-local function find_defs(src)
+local function find_defs(src, mode)
local defs = {}
for name, code in string.gmatch(src, "LJLIB_LUA%(([^)]*)%)%s*/%*(.-)%*/") do
- local env = {}
local tcode, fixup = transform_lua(code)
- local func = assert(load(tcode, "", nil, env))()
- defs[name] = fixup_dump(string.dump(func, true), fixup)
+ local func = assert(load(tcode, "", mode))
+ defs[name] = fixup_dump(string.dump(func, mode), fixup)
defs[#defs+1] = name
end
return defs
end
-local function gen_header(defs)
+local function gen_header(defs32, defs64)
local t = {}
local function w(x) t[#t+1] = x end
w("/* This is a generated file. DO NOT EDIT! */\n\n")
w("static const int libbc_endian = ") w(isbe and 1 or 0) w(";\n\n")
- local s, sb = "", ""
- for i,name in ipairs(defs) do
- local d = defs[name]
- s = s .. d.dump
- sb = sb .. string.char(i) .. ("\0"):rep(d.startbc - 1)
- .. (isbe and "\0\0\0\255" or "\255\0\0\0"):rep(d.sizebc)
- .. ("\0"):rep(#d.dump - d.startbc - d.sizebc*4)
- end
- w("static const uint8_t libbc_code[] = {\n")
- local n = 0
- for i=1,#s do
- local x = string.byte(s, i)
- local xb = string.byte(sb, i)
- if xb == 255 then
- local name = BCN[x]
- local m = #name + 4
- if n + m > 78 then n = 0; w("\n") end
- n = n + m
- w("BC_"); w(name)
- else
- local m = x < 10 and 2 or (x < 100 and 3 or 4)
- if xb == 0 then
- if n + m > 78 then n = 0; w("\n") end
- else
- local name = defs[xb]:gsub("_", ".")
- if n ~= 0 then w("\n") end
- w("/* "); w(name); w(" */ ")
- n = #name + 7
- end
- n = n + m
- w(x)
+ for j,defs in ipairs{defs64, defs32} do
+ local s, sb = "", ""
+ for i,name in ipairs(defs) do
+ local d = defs[name]
+ s = s .. d.dump
+ sb = sb .. string.char(i) .. ("\0"):rep(d.startbc - 1)
+ .. (isbe and "\0\0\0\255" or "\255\0\0\0"):rep(d.sizebc)
+ .. ("\0"):rep(#d.dump - d.startbc - d.sizebc*4)
+ end
+ if j == 1 then
+ w("static const uint8_t libbc_code[] = {\n#if LJ_FR2\n")
+ else
+ w("\n#else\n")
+ end
+ local n = 0
+ for i=1,#s do
+ local x = string.byte(s, i)
+ local xb = string.byte(sb, i)
+ if xb == 255 then
+ local name = BCN[x]
+ local m = #name + 4
+ if n + m > 78 then n = 0; w("\n") end
+ n = n + m
+ w("BC_"); w(name)
+ else
+ local m = x < 10 and 2 or (x < 100 and 3 or 4)
+ if xb == 0 then
+ if n + m > 78 then n = 0; w("\n") end
+ else
+ local name = defs[xb]:gsub("_", ".")
+ if n ~= 0 then w("\n") end
+ w("/* "); w(name); w(" */ ")
+ n = #name + 7
+ end
+ n = n + m
+ w(x)
+ end
+ w(",")
end
- w(",")
end
- w("\n0\n};\n\n")
+ w("\n#endif\n0\n};\n\n")
w("static const struct { const char *name; int ofs; } libbc_map[] = {\n")
- local m = 0
- for _,name in ipairs(defs) do
- w('{"'); w(name); w('",'); w(m) w('},\n')
- m = m + #defs[name].dump
+ local m32, m64 = 0, 0
+ for i,name in ipairs(defs32) do
+ assert(name == defs64[i])
+ w('{"'); w(name); w('",'); w(m32) w('},\n')
+ m32 = m32 + #defs32[name].dump
+ m64 = m64 + #defs64[name].dump
+ assert(m32 == m64)
end
- w("{NULL,"); w(m); w("}\n};\n\n")
+ w("{NULL,"); w(m32); w("}\n};\n\n")
return table.concat(t)
end
@@ -219,7 +227,8 @@ end
local outfile = parse_arg(arg)
local src = read_files(arg)
-local defs = find_defs(src)
-local hdr = gen_header(defs)
+local defs32 = find_defs(src, "Wdts")
+local defs64 = find_defs(src, "Xdts")
+local hdr = gen_header(defs32, defs64)
write_file(outfile, hdr)
diff --git a/src/deps/src/luajit/src/host/genversion.lua b/src/deps/src/luajit/src/host/genversion.lua
index 28f7206c5..f0925160e 100644
--- a/src/deps/src/luajit/src/host/genversion.lua
+++ b/src/deps/src/luajit/src/host/genversion.lua
@@ -29,7 +29,7 @@ local function file_write_mod(file, data)
assert(fp:close())
end
-local text = file_read(FILE_ROLLING_H)
+local text = file_read(FILE_ROLLING_H):gsub("#error.-\n", "")
local relver = file_read(FILE_RELVER_TXT):match("(%d+)")
if relver then
diff --git a/src/deps/src/luajit/src/jit/bcsave.lua b/src/deps/src/luajit/src/jit/bcsave.lua
index f4163e20c..eba2a0c06 100644
--- a/src/deps/src/luajit/src/jit/bcsave.lua
+++ b/src/deps/src/luajit/src/jit/bcsave.lua
@@ -30,6 +30,9 @@ Save LuaJIT bytecode: luajit -b[options] input output
-L Only list bytecode with lineinfo.
-s Strip debug info (default).
-g Keep debug info.
+ -W Generate 32 bit (non-GC64) bytecode.
+ -X Generate 64 bit (GC64) bytecode.
+ -d Generate bytecode in deterministic manner.
-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).
@@ -52,8 +55,9 @@ local function check(ok, ...)
end
local function readfile(ctx, input)
- if type(input) == "function" then return input end
- if ctx.filename then
+ if ctx.string then
+ return check(loadstring(input, nil, ctx.mode))
+ elseif ctx.filename then
local data
if input == "-" then
data = io.stdin:read("*a")
@@ -62,10 +66,10 @@ local function readfile(ctx, input)
data = assert(fp:read("*a"))
assert(fp:close())
end
- return check(load(data, ctx.filename))
+ return check(load(data, ctx.filename, ctx.mode))
else
if input == "-" then input = nil end
- return check(loadfile(input))
+ return check(loadfile(input, ctx.mode))
end
end
@@ -626,7 +630,7 @@ end
local function bcsave(ctx, input, output)
local f = readfile(ctx, input)
- local s = string.dump(f, ctx.strip)
+ local s = string.dump(f, ctx.mode)
local t = ctx.type
if not t then
t = detecttype(output)
@@ -650,9 +654,11 @@ local function docmd(...)
local list = false
local lineinfo = false
local ctx = {
- strip = true, arch = jit.arch, os = jit.os:lower(),
- type = false, modname = false,
+ mode = "bt", arch = jit.arch, os = jit.os:lower(),
+ type = false, modname = false, string = false,
}
+ local strip = "s"
+ local gc64 = ""
while n <= #arg do
local a = arg[n]
if type(a) == "string" and a:sub(1, 1) == "-" and a ~= "-" then
@@ -666,14 +672,18 @@ local function docmd(...)
list = true
lineinfo = true
elseif opt == "s" then
- ctx.strip = true
+ strip = "s"
elseif opt == "g" then
- ctx.strip = false
+ strip = ""
+ elseif opt == "W" or opt == "X" then
+ gc64 = opt
+ elseif opt == "d" then
+ ctx.mode = ctx.mode .. opt
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]))
+ ctx.string = true
elseif opt == "n" then
ctx.modname = checkmodname(tremove(arg, n))
elseif opt == "t" then
@@ -693,6 +703,7 @@ local function docmd(...)
n = n + 1
end
end
+ ctx.mode = ctx.mode .. strip .. gc64
if list then
if #arg == 0 or #arg > 2 then usage() end
bclist(ctx, arg[1], arg[2] or "-", lineinfo)
diff --git a/src/deps/src/luajit/src/jit/dis_s390x.lua b/src/deps/src/luajit/src/jit/dis_s390x.lua
new file mode 100644
index 000000000..d03b8bb41
--- /dev/null
+++ b/src/deps/src/luajit/src/jit/dis_s390x.lua
@@ -0,0 +1,1593 @@
+----------------------------------------------------------------------------
+-- LuaJIT s390x disassembler module.
+--
+-- Copyright (C) 2005-2022 Mike Pall. All rights reserved.
+-- Released under the MIT license. See Copyright Notice in luajit.h
+--
+-- Contributed by Aditya Bisht from Open Mainframe.
+----------------------------------------------------------------------------
+-- This is a helper module used by the LuaJIT machine code dumper module.
+--
+-- NYI:
+------------------------------------------------------------------------------
+
+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 band, lshift, bor, rshift = bit.band, bit.lshift, bit.bor, bit.rshift
+local tohex = bit.tohex
+
+local ONELONG = "%08lx: "
+
+local OPERAND_GPR = 0x1 /* Operand printed as %rx */
+local OPERAND_FPR = 0x2 /* Operand printed as %fx */
+local OPERAND_AR = 0x4 /* Operand printed as %ax */
+local OPERAND_CR = 0x8 /* Operand printed as %cx */
+local OPERAND_DISP = 0x10 /* Operand printed as displacement */
+local OPERAND_BASE = 0x20 /* Operand printed as base register */
+local OPERAND_INDEX = 0x40 /* Operand printed as index register */
+local OPERAND_PCREL = 0x80 /* Operand printed as pc-relative symbol */
+local OPERAND_SIGNED = 0x100 /* Operand printed as signed value */
+local OPERAND_LENGTH = 0x200 /* Operand printed as length (+1) */
+
+-- Registers
+
+local UNUSED = 0, /* Indicates the end of the operand list */
+local R_8 = 1, /* GPR starting at position 8 */
+local R_12 = 2, /* GPR starting at position 12 */
+local R_16 = 3, /* GPR starting at position 16 */
+local R_20 = 4, /* GPR starting at position 20 */
+local R_24 = 5, /* GPR starting at position 24 */
+local R_28 = 6, /* GPR starting at position 28 */
+local R_32 = 7, /* GPR starting at position 32 */
+local F_8 = 8, /* FPR starting at position 8 */
+local F_12 = 9, /* FPR starting at position 12 */
+local F_16 = 10, /* FPR starting at position 16 */
+local F_20 = 11, /* FPR starting at position 16 */
+local F_24 = 12, /* FPR starting at position 24 */
+local F_28 = 13, /* FPR starting at position 28 */
+local F_32 = 14, /* FPR starting at position 32 */
+local A_8 = 15, /* Access reg. starting at position 8 */
+local A_12 = 16, /* Access reg. starting at position 12 */
+local A_24 = 17, /* Access reg. starting at position 24 */
+local A_28 = 18, /* Access reg. starting at position 28 */
+local C_8 = 19, /* Control reg. starting at position 8 */
+local C_12 = 20, /* Control reg. starting at position 12 */
+local B_16 = 21, /* Base register starting at position 16 */
+local B_32 = 22, /* Base register starting at position 32 */
+local X_12 = 23, /* Index register starting at position 12 */
+local D_20 = 24, /* Displacement starting at position 20 */
+local D_36 = 25, /* Displacement starting at position 36 */
+local D20_20 = 26, /* 20 bit displacement starting at 20 */
+local L4_8 = 27, /* 4 bit length starting at position 8 */
+local L4_12 = 28, /* 4 bit length starting at position 12 */
+local L8_8 = 29, /* 8 bit length starting at position 8 */
+local U4_8 = 30, /* 4 bit unsigned value starting at 8 */
+local U4_12 = 31, /* 4 bit unsigned value starting at 12 */
+local U4_16 = 32, /* 4 bit unsigned value starting at 16 */
+local U4_20 = 33, /* 4 bit unsigned value starting at 20 */
+local U4_32 = 34, /* 4 bit unsigned value starting at 32 */
+local U8_8 = 35, /* 8 bit unsigned value starting at 8 */
+local U8_16 = 36, /* 8 bit unsigned value starting at 16 */
+local U8_24 = 37, /* 8 bit unsigned value starting at 24 */
+local U8_32 = 38, /* 8 bit unsigned value starting at 32 */
+local I8_8 = 39, /* 8 bit signed value starting at 8 */
+local I8_32 = 40, /* 8 bit signed value starting at 32 */
+local I16_16 = 41, /* 16 bit signed value starting at 16 */
+local I16_32 = 42, /* 32 bit signed value starting at 16 */
+local U16_16 = 43, /* 16 bit unsigned value starting at 16 */
+local U16_32 = 44, /* 32 bit unsigned value starting at 16 */
+local J16_16 = 45, /* PC relative jump offset at 16 */
+local J32_16 = 46, /* PC relative long offset at 16 */
+local I32_16 = 47, /* 32 bit signed value starting at 16 */
+local U32_16 = 48, /* 32 bit unsigned value starting at 16 */
+local M_16 = 49, /* 4 bit optional mask starting at 16 */
+local RO_28 = 50 /* optional GPR starting at position 28 */
+
+-- Enumeration of the different instruction formats.
+-- For details consult the principles of operation.
+
+local INSTR_INVALID = 1,
+local INSTR_E = 2,
+local INSTR_RIE_R0IU = 3,
+local INSTR_RIE_R0UU = 4,
+local INSTR_RIE_RRP = 5,
+local INSTR_RIE_RRPU = 6,
+local INSTR_RIE_RRUUU = 7,
+local INSTR_RIE_RUPI = 8,
+local INSTR_RIE_RUPU = 9,
+local INSTR_RIL_RI = 10,
+local INSTR_RIL_RP = 11,
+local INSTR_RIL_RU = 12,
+local INSTR_RIL_UP = 13,
+local INSTR_RIS_R0RDU = 14,
+local INSTR_RIS_R0UU = 15,
+local INSTR_RIS_RURDI = 16,
+local INSTR_RIS_RURDU = 17,
+local INSTR_RI_RI = 18,
+local INSTR_RI_RP = 19,
+local INSTR_RI_RU = 20,
+local INSTR_RI_UP = 21,
+local INSTR_RRE_00 = 22,
+local INSTR_RRE_0R = 23,
+local INSTR_RRE_AA = 24,
+local INSTR_RRE_AR = 25,
+local INSTR_RRE_F0 = 26,
+local INSTR_RRE_FF = 27,
+local INSTR_RRE_FR = 28,
+local INSTR_RRE_R0 = 29,
+local INSTR_RRE_RA = 30,
+local INSTR_RRE_RF = 31,
+local INSTR_RRE_RR = 32,
+local INSTR_RRE_RR_OPT = 33,
+local INSTR_RRF_0UFF = 34,
+local INSTR_RRF_F0FF = 35,
+local INSTR_RRF_F0FF2 = 36,
+local INSTR_RRF_F0FR = 37,
+local INSTR_RRF_FFRU = 38,
+local INSTR_RRF_FUFF = 39,
+local INSTR_RRF_M0RR = 40,
+local INSTR_RRF_R0RR = 41,
+local INSTR_RRF_RURR = 42,
+local INSTR_RRF_U0FF = 43,
+local INSTR_RRF_U0RF = 44,
+local INSTR_RRF_U0RR = 45,
+local INSTR_RRF_UUFF = 46,
+local INSTR_RRR_F0FF = 47,
+local INSTR_RRS_RRRDU = 48,
+local INSTR_RR_FF = 49,
+local INSTR_RR_R0 = 50,
+local INSTR_RR_RR = 51,
+local INSTR_RR_U0 = 52,
+local INSTR_RR_UR = 53,
+local INSTR_RSE_CCRD = 54,
+local INSTR_RSE_RRRD = 55,
+local INSTR_RSE_RURD = 56,
+local INSTR_RSI_RRP = 57,
+local INSTR_RSL_R0RD = 58,
+local INSTR_RSY_AARD = 59,
+local INSTR_RSY_CCRD = 60,
+local INSTR_RSY_RRRD = 61,
+local INSTR_RSY_RURD = 62,
+local INSTR_RS_AARD = 63,
+local INSTR_RS_CCRD = 64,
+local INSTR_RS_R0RD = 65,
+local INSTR_RS_RRRD = 66,
+local INSTR_RS_RURD = 67,
+local INSTR_RXE_FRRD = 68,
+local INSTR_RXE_RRRD = 69,
+local INSTR_RXF_FRRDF = 70,
+local INSTR_RXY_FRRD = 71,
+local INSTR_RXY_RRRD = 72,
+local INSTR_RXY_URRD = 73,
+local INSTR_RX_FRRD = 74,
+local INSTR_RX_RRRD = 75,
+local INSTR_RX_URRD = 76,
+local INSTR_SIL_RDI = 77,
+local INSTR_SIL_RDU = 78,
+local INSTR_SIY_IRD = 79,
+local INSTR_SIY_URD = 80,
+local INSTR_SI_URD = 81,
+local INSTR_SSE_RDRD = 82,
+local INSTR_SSF_RRDRD = 83,
+local INSTR_SS_L0RDRD = 84,
+local INSTR_SS_LIRDRD = 85,
+local INSTR_SS_LLRDRD = 86,
+local INSTR_SS_RRRDRD = 87,
+local INSTR_SS_RRRDRD2 = 88,
+local INSTR_SS_RRRDRD3 = 89,
+local INSTR_S_00 = 90,
+local INSTR_S_RD = 91
+
+local operands = {
+ [UNUSED] = { 0, 0, 0 },
+ [R_8] = { 4, 8, OPERAND_GPR },
+ [R_12] = { 4, 12, OPERAND_GPR },
+ [R_16] = { 4, 16, OPERAND_GPR },
+ [R_20] = { 4, 20, OPERAND_GPR },
+ [R_24] = { 4, 24, OPERAND_GPR },
+ [R_28] = { 4, 28, OPERAND_GPR },
+ [R_32] = { 4, 32, OPERAND_GPR },
+ [F_8] = { 4, 8, OPERAND_FPR },
+ [F_12] = { 4, 12, OPERAND_FPR },
+ [F_16] = { 4, 16, OPERAND_FPR },
+ [F_20] = { 4, 16, OPERAND_FPR },
+ [F_24] = { 4, 24, OPERAND_FPR },
+ [F_28] = { 4, 28, OPERAND_FPR },
+ [F_32] = { 4, 32, OPERAND_FPR },
+ [A_8] = { 4, 8, OPERAND_AR },
+ [A_12] = { 4, 12, OPERAND_AR },
+ [A_24] = { 4, 24, OPERAND_AR },
+ [A_28] = { 4, 28, OPERAND_AR },
+ [C_8] = { 4, 8, OPERAND_CR },
+ [C_12] = { 4, 12, OPERAND_CR },
+ [B_16] = { 4, 16, OPERAND_BASE | OPERAND_GPR },
+ [B_32] = { 4, 32, OPERAND_BASE | OPERAND_GPR },
+ [X_12] = { 4, 12, OPERAND_INDEX | OPERAND_GPR },
+ [D_20] = { 12, 20, OPERAND_DISP },
+ [D_36] = { 12, 36, OPERAND_DISP },
+ [D20_20] = { 20, 20, OPERAND_DISP | OPERAND_SIGNED },
+ [L4_8] = { 4, 8, OPERAND_LENGTH },
+ [L4_12] = { 4, 12, OPERAND_LENGTH },
+ [L8_8] = { 8, 8, OPERAND_LENGTH },
+ [U4_8] = { 4, 8, 0 },
+ [U4_12] = { 4, 12, 0 },
+ [U4_16] = { 4, 16, 0 },
+ [U4_20] = { 4, 20, 0 },
+ [U4_32] = { 4, 32, 0 },
+ [U8_8] = { 8, 8, 0 },
+ [U8_16] = { 8, 16, 0 },
+ [U8_24] = { 8, 24, 0 },
+ [U8_32] = { 8, 32, 0 },
+ [I16_16] = { 16, 16, OPERAND_SIGNED },
+ [U16_16] = { 16, 16, 0 },
+ [U16_32] = { 16, 32, 0 },
+ [J16_16] = { 16, 16, OPERAND_PCREL },
+ [I16_32] = { 16, 32, OPERAND_SIGNED },
+ [J32_16] = { 32, 16, OPERAND_PCREL },
+ [I32_16] = { 32, 16, OPERAND_SIGNED },
+ [U32_16] = { 32, 16, 0 },
+ [M_16] = { 4, 16, 0 },
+ [RO_28] = { 4, 28, OPERAND_GPR }
+}
+
+local formats = {
+ [INSTR_E] = { 0xff, 0,0,0,0,0,0 },
+ [INSTR_RIE_R0UU] = { 0xff, R_8,U16_16,U4_32,0,0,0 },
+ [INSTR_RIE_RRPU] = { 0xff, R_8,R_12,U4_32,J16_16,0,0 },
+ [INSTR_RIE_RRP] = { 0xff, R_8,R_12,J16_16,0,0,0 },
+ [INSTR_RIE_RRUUU] = { 0xff, R_8,R_12,U8_16,U8_24,U8_32,0 },
+ [INSTR_RIE_RUPI] = { 0xff, R_8,I8_32,U4_12,J16_16,0,0 },
+ [INSTR_RIL_RI] = { 0x0f, R_8,I32_16,0,0,0,0 },
+ [INSTR_RIL_RP] = { 0x0f, R_8,J32_16,0,0,0,0 },
+ [INSTR_RIL_RU] = { 0x0f, R_8,U32_16,0,0,0,0 },
+ [INSTR_RIL_UP] = { 0x0f, U4_8,J32_16,0,0,0,0 },
+ [INSTR_RIS_R0RDU] = { 0xff, R_8,U8_32,D_20,B_16,0,0 },
+ [INSTR_RIS_RURDI] = { 0xff, R_8,I8_32,U4_12,D_20,B_16,0 },
+ [INSTR_RIS_RURDU] = { 0xff, R_8,U8_32,U4_12,D_20,B_16,0 },
+ [INSTR_RI_RI] = { 0x0f, R_8,I16_16,0,0,0,0 },
+ [INSTR_RI_RP] = { 0x0f, R_8,J16_16,0,0,0,0 },
+ [INSTR_RI_RU] = { 0x0f, R_8,U16_16,0,0,0,0 },
+ [INSTR_RI_UP] = { 0x0f, U4_8,J16_16,0,0,0,0 },
+ [INSTR_RRE_00] = { 0xff, 0,0,0,0,0,0 },
+ [INSTR_RRE_0R] = { 0xff, R_28,0,0,0,0,0 },
+ [INSTR_RRE_AA] = { 0xff, A_24,A_28,0,0,0,0 },
+ [INSTR_RRE_AR] = { 0xff, A_24,R_28,0,0,0,0 },
+ [INSTR_RRE_F0] = { 0xff, F_24,0,0,0,0,0 },
+ [INSTR_RRE_FF] = { 0xff, F_24,F_28,0,0,0,0 },
+ [INSTR_RRE_FR] = { 0xff, F_24,R_28,0,0,0,0 },
+ [INSTR_RRE_R0] = { 0xff, R_24,0,0,0,0,0 },
+ [INSTR_RRE_RA] = { 0xff, R_24,A_28,0,0,0,0 },
+ [INSTR_RRE_RF] = { 0xff, R_24,F_28,0,0,0,0 },
+ [INSTR_RRE_RR] = { 0xff, R_24,R_28,0,0,0,0 },
+ [INSTR_RRE_RR_OPT]= { 0xff, R_24,RO_28,0,0,0,0 },
+ [INSTR_RRF_0UFF] = { 0xff, F_24,F_28,U4_20,0,0,0 },
+ [INSTR_RRF_F0FF2] = { 0xff, F_24,F_16,F_28,0,0,0 },
+ [INSTR_RRF_F0FF] = { 0xff, F_16,F_24,F_28,0,0,0 },
+ [INSTR_RRF_F0FR] = { 0xff, F_24,F_16,R_28,0,0,0 },
+ [INSTR_RRF_FFRU] = { 0xff, F_24,F_16,R_28,U4_20,0,0 },
+ [INSTR_RRF_FUFF] = { 0xff, F_24,F_16,F_28,U4_20,0,0 },
+ [INSTR_RRF_M0RR] = { 0xff, R_24,R_28,M_16,0,0,0 },
+ [INSTR_RRF_R0RR] = { 0xff, R_24,R_16,R_28,0,0,0 },
+ [INSTR_RRF_RURR] = { 0xff, R_24,R_28,R_16,U4_20,0,0 },
+ [INSTR_RRF_U0FF] = { 0xff, F_24,U4_16,F_28,0,0,0 },
+ [INSTR_RRF_U0RF] = { 0xff, R_24,U4_16,F_28,0,0,0 },
+ [INSTR_RRF_U0RR] = { 0xff, R_24,R_28,U4_16,0,0,0 },
+ [INSTR_RRF_UUFF] = { 0xff, F_24,U4_16,F_28,U4_20,0,0 },
+ [INSTR_RRR_F0FF] = { 0xff, F_24,F_28,F_16,0,0,0 },
+ [INSTR_RRS_RRRDU] = { 0xff, R_8,R_12,U4_32,D_20,B_16,0 },
+ [INSTR_RR_FF] = { 0xff, F_8,F_12,0,0,0,0 },
+ [INSTR_RR_R0] = { 0xff, R_8, 0,0,0,0,0 },
+ [INSTR_RR_RR] = { 0xff, R_8,R_12,0,0,0,0 },
+ [INSTR_RR_U0] = { 0xff, U8_8, 0,0,0,0,0 },
+ [INSTR_RR_UR] = { 0xff, U4_8,R_12,0,0,0,0 },
+ [INSTR_RSE_CCRD] = { 0xff, C_8,C_12,D_20,B_16,0,0 },
+ [INSTR_RSE_RRRD] = { 0xff, R_8,R_12,D_20,B_16,0,0 },
+ [INSTR_RSE_RURD] = { 0xff, R_8,U4_12,D_20,B_16,0,0 },
+ [INSTR_RSI_RRP] = { 0xff, R_8,R_12,J16_16,0,0,0 },
+ [INSTR_RSL_R0RD] = { 0xff, D_20,L4_8,B_16,0,0,0 },
+ [INSTR_RSY_AARD] = { 0xff, A_8,A_12,D20_20,B_16,0,0 },
+ [INSTR_RSY_CCRD] = { 0xff, C_8,C_12,D20_20,B_16,0,0 },
+ [INSTR_RSY_RRRD] = { 0xff, R_8,R_12,D20_20,B_16,0,0 },
+ [INSTR_RSY_RURD] = { 0xff, R_8,U4_12,D20_20,B_16,0,0 },
+ [INSTR_RS_AARD] = { 0xff, A_8,A_12,D_20,B_16,0,0 },
+ [INSTR_RS_CCRD] = { 0xff, C_8,C_12,D_20,B_16,0,0 },
+ [INSTR_RS_R0RD] = { 0xff, R_8,D_20,B_16,0,0,0 },
+ [INSTR_RS_RRRD] = { 0xff, R_8,R_12,D_20,B_16,0,0 },
+ [INSTR_RS_RURD] = { 0xff, R_8,U4_12,D_20,B_16,0,0 },
+ [INSTR_RXE_FRRD] = { 0xff, F_8,D_20,X_12,B_16,0,0 },
+ [INSTR_RXE_RRRD] = { 0xff, R_8,D_20,X_12,B_16,0,0 },
+ [INSTR_RXF_FRRDF] = { 0xff, F_32,F_8,D_20,X_12,B_16,0 },
+ [INSTR_RXY_FRRD] = { 0xff, F_8,D20_20,X_12,B_16,0,0 },
+ [INSTR_RXY_RRRD] = { 0xff, R_8,D20_20,X_12,B_16,0,0 },
+ [INSTR_RXY_URRD] = { 0xff, U4_8,D20_20,X_12,B_16,0,0 },
+ [INSTR_RX_FRRD] = { 0xff, F_8,D_20,X_12,B_16,0,0 },
+ [INSTR_RX_RRRD] = { 0xff, R_8,D_20,X_12,B_16,0,0 },
+ [INSTR_RX_URRD] = { 0xff, U4_8,D_20,X_12,B_16,0,0 },
+ [INSTR_SIL_RDI] = { 0xff, D_20,B_16,I16_32,0,0,0 },
+ [INSTR_SIL_RDU] = { 0xff, D_20,B_16,U16_32,0,0,0 },
+ [INSTR_SIY_IRD] = { 0xff, D20_20,B_16,I8_8,0,0,0 },
+ [INSTR_SIY_URD] = { 0xff, D20_20,B_16,U8_8,0,0,0 },
+ [INSTR_SI_URD] = { 0xff, D_20,B_16,U8_8,0,0,0 },
+ [INSTR_SSE_RDRD] = { 0xff, D_20,B_16,D_36,B_32,0,0 },
+ [INSTR_SSF_RRDRD] = { 0x00, D_20,B_16,D_36,B_32,R_8,0 },
+ [INSTR_SS_L0RDRD] = { 0xff, D_20,L8_8,B_16,D_36,B_32,0 },
+ [INSTR_SS_LIRDRD] = { 0xff, D_20,L4_8,B_16,D_36,B_32,U4_12 },
+ [INSTR_SS_LLRDRD] = { 0xff, D_20,L4_8,B_16,D_36,L4_12,B_32 },
+ [INSTR_SS_RRRDRD2]= { 0xff, R_8,D_20,B_16,R_12,D_36,B_32 },
+ [INSTR_SS_RRRDRD3]= { 0xff, R_8,R_12,D_20,B_16,D_36,B_32 },
+ [INSTR_SS_RRRDRD] = { 0xff, D_20,R_8,B_16,D_36,B_32,R_12 },
+ [INSTR_S_00] = { 0xff, 0,0,0,0,0,0 },
+ [INSTR_S_RD] = { 0xff, D_20,B_16,0,0,0,0 },
+}
+
+local opcode = {
+ { "lmd", 0xef, INSTR_SS_RRRDRD3 },
+ { "spm", 0x04, INSTR_RR_R0 },
+ { "balr", 0x05, INSTR_RR_RR },
+ { "bctr", 0x06, INSTR_RR_RR },
+ { "bcr", 0x07, INSTR_RR_UR },
+ { "svc", 0x0a, INSTR_RR_U0 },
+ { "bsm", 0x0b, INSTR_RR_RR },
+ { "bassm", 0x0c, INSTR_RR_RR },
+ { "basr", 0x0d, INSTR_RR_RR },
+ { "mvcl", 0x0e, INSTR_RR_RR },
+ { "clcl", 0x0f, INSTR_RR_RR },
+ { "lpr", 0x10, INSTR_RR_RR },
+ { "lnr", 0x11, INSTR_RR_RR },
+ { "ltr", 0x12, INSTR_RR_RR },
+ { "lcr", 0x13, INSTR_RR_RR },
+ { "nr", 0x14, INSTR_RR_RR },
+ { "clr", 0x15, INSTR_RR_RR },
+ { "or", 0x16, INSTR_RR_RR },
+ { "xr", 0x17, INSTR_RR_RR },
+ { "lr", 0x18, INSTR_RR_RR },
+ { "cr", 0x19, INSTR_RR_RR },
+ { "ar", 0x1a, INSTR_RR_RR },
+ { "sr", 0x1b, INSTR_RR_RR },
+ { "mr", 0x1c, INSTR_RR_RR },
+ { "dr", 0x1d, INSTR_RR_RR },
+ { "alr", 0x1e, INSTR_RR_RR },
+ { "slr", 0x1f, INSTR_RR_RR },
+ { "lpdr", 0x20, INSTR_RR_FF },
+ { "lndr", 0x21, INSTR_RR_FF },
+ { "ltdr", 0x22, INSTR_RR_FF },
+ { "lcdr", 0x23, INSTR_RR_FF },
+ { "hdr", 0x24, INSTR_RR_FF },
+ { "ldxr", 0x25, INSTR_RR_FF },
+ { "lrdr", 0x25, INSTR_RR_FF },
+ { "mxr", 0x26, INSTR_RR_FF },
+ { "mxdr", 0x27, INSTR_RR_FF },
+ { "ldr", 0x28, INSTR_RR_FF },
+ { "cdr", 0x29, INSTR_RR_FF },
+ { "adr", 0x2a, INSTR_RR_FF },
+ { "sdr", 0x2b, INSTR_RR_FF },
+ { "mdr", 0x2c, INSTR_RR_FF },
+ { "ddr", 0x2d, INSTR_RR_FF },
+ { "awr", 0x2e, INSTR_RR_FF },
+ { "swr", 0x2f, INSTR_RR_FF },
+ { "lper", 0x30, INSTR_RR_FF },
+ { "lner", 0x31, INSTR_RR_FF },
+ { "lter", 0x32, INSTR_RR_FF },
+ { "lcer", 0x33, INSTR_RR_FF },
+ { "her", 0x34, INSTR_RR_FF },
+ { "ledr", 0x35, INSTR_RR_FF },
+ { "lrer", 0x35, INSTR_RR_FF },
+ { "axr", 0x36, INSTR_RR_FF },
+ { "sxr", 0x37, INSTR_RR_FF },
+ { "ler", 0x38, INSTR_RR_FF },
+ { "cer", 0x39, INSTR_RR_FF },
+ { "aer", 0x3a, INSTR_RR_FF },
+ { "ser", 0x3b, INSTR_RR_FF },
+ { "mder", 0x3c, INSTR_RR_FF },
+ { "mer", 0x3c, INSTR_RR_FF },
+ { "der", 0x3d, INSTR_RR_FF },
+ { "aur", 0x3e, INSTR_RR_FF },
+ { "sur", 0x3f, INSTR_RR_FF },
+ { "sth", 0x40, INSTR_RX_RRRD },
+ { "la", 0x41, INSTR_RX_RRRD },
+ { "stc", 0x42, INSTR_RX_RRRD },
+ { "ic", 0x43, INSTR_RX_RRRD },
+ { "ex", 0x44, INSTR_RX_RRRD },
+ { "bal", 0x45, INSTR_RX_RRRD },
+ { "bct", 0x46, INSTR_RX_RRRD },
+ { "bc", 0x47, INSTR_RX_URRD },
+ { "lh", 0x48, INSTR_RX_RRRD },
+ { "ch", 0x49, INSTR_RX_RRRD },
+ { "ah", 0x4a, INSTR_RX_RRRD },
+ { "sh", 0x4b, INSTR_RX_RRRD },
+ { "mh", 0x4c, INSTR_RX_RRRD },
+ { "bas", 0x4d, INSTR_RX_RRRD },
+ { "cvd", 0x4e, INSTR_RX_RRRD },
+ { "cvb", 0x4f, INSTR_RX_RRRD },
+ { "st", 0x50, INSTR_RX_RRRD },
+ { "lae", 0x51, INSTR_RX_RRRD },
+ { "n", 0x54, INSTR_RX_RRRD },
+ { "cl", 0x55, INSTR_RX_RRRD },
+ { "o", 0x56, INSTR_RX_RRRD },
+ { "x", 0x57, INSTR_RX_RRRD },
+ { "l", 0x58, INSTR_RX_RRRD },
+ { "c", 0x59, INSTR_RX_RRRD },
+ { "a", 0x5a, INSTR_RX_RRRD },
+ { "s", 0x5b, INSTR_RX_RRRD },
+ { "m", 0x5c, INSTR_RX_RRRD },
+ { "d", 0x5d, INSTR_RX_RRRD },
+ { "al", 0x5e, INSTR_RX_RRRD },
+ { "sl", 0x5f, INSTR_RX_RRRD },
+ { "std", 0x60, INSTR_RX_FRRD },
+ { "mxd", 0x67, INSTR_RX_FRRD },
+ { "ld", 0x68, INSTR_RX_FRRD },
+ { "cd", 0x69, INSTR_RX_FRRD },
+ { "ad", 0x6a, INSTR_RX_FRRD },
+ { "sd", 0x6b, INSTR_RX_FRRD },
+ { "md", 0x6c, INSTR_RX_FRRD },
+ { "dd", 0x6d, INSTR_RX_FRRD },
+ { "aw", 0x6e, INSTR_RX_FRRD },
+ { "sw", 0x6f, INSTR_RX_FRRD },
+ { "ste", 0x70, INSTR_RX_FRRD },
+ { "ms", 0x71, INSTR_RX_RRRD },
+ { "le", 0x78, INSTR_RX_FRRD },
+ { "ce", 0x79, INSTR_RX_FRRD },
+ { "ae", 0x7a, INSTR_RX_FRRD },
+ { "se", 0x7b, INSTR_RX_FRRD },
+ { "mde", 0x7c, INSTR_RX_FRRD },
+ { "me", 0x7c, INSTR_RX_FRRD },
+ { "de", 0x7d, INSTR_RX_FRRD },
+ { "au", 0x7e, INSTR_RX_FRRD },
+ { "su", 0x7f, INSTR_RX_FRRD },
+ { "ssm", 0x80, INSTR_S_RD },
+ { "lpsw", 0x82, INSTR_S_RD },
+ { "diag", 0x83, INSTR_RS_RRRD },
+ { "brxh", 0x84, INSTR_RSI_RRP },
+ { "brxle", 0x85, INSTR_RSI_RRP },
+ { "bxh", 0x86, INSTR_RS_RRRD },
+ { "bxle", 0x87, INSTR_RS_RRRD },
+ { "srl", 0x88, INSTR_RS_R0RD },
+ { "sll", 0x89, INSTR_RS_R0RD },
+ { "sra", 0x8a, INSTR_RS_R0RD },
+ { "sla", 0x8b, INSTR_RS_R0RD },
+ { "srdl", 0x8c, INSTR_RS_R0RD },
+ { "sldl", 0x8d, INSTR_RS_R0RD },
+ { "srda", 0x8e, INSTR_RS_R0RD },
+ { "slda", 0x8f, INSTR_RS_R0RD },
+ { "stm", 0x90, INSTR_RS_RRRD },
+ { "tm", 0x91, INSTR_SI_URD },
+ { "mvi", 0x92, INSTR_SI_URD },
+ { "ts", 0x93, INSTR_S_RD },
+ { "ni", 0x94, INSTR_SI_URD },
+ { "cli", 0x95, INSTR_SI_URD },
+ { "oi", 0x96, INSTR_SI_URD },
+ { "xi", 0x97, INSTR_SI_URD },
+ { "lm", 0x98, INSTR_RS_RRRD },
+ { "trace", 0x99, INSTR_RS_RRRD },
+ { "lam", 0x9a, INSTR_RS_AARD },
+ { "stam", 0x9b, INSTR_RS_AARD },
+ { "mvcle", 0xa8, INSTR_RS_RRRD },
+ { "clcle", 0xa9, INSTR_RS_RRRD },
+ { "stnsm", 0xac, INSTR_SI_URD },
+ { "stosm", 0xad, INSTR_SI_URD },
+ { "sigp", 0xae, INSTR_RS_RRRD },
+ { "mc", 0xaf, INSTR_SI_URD },
+ { "lra", 0xb1, INSTR_RX_RRRD },
+ { "stctl", 0xb6, INSTR_RS_CCRD },
+ { "lctl", 0xb7, INSTR_RS_CCRD },
+ { "cs", 0xba, INSTR_RS_RRRD },
+ { "cds", 0xbb, INSTR_RS_RRRD },
+ { "clm", 0xbd, INSTR_RS_RURD },
+ { "stcm", 0xbe, INSTR_RS_RURD },
+ { "icm", 0xbf, INSTR_RS_RURD },
+ { "mvn", 0xd1, INSTR_SS_L0RDRD },
+ { "mvc", 0xd2, INSTR_SS_L0RDRD },
+ { "mvz", 0xd3, INSTR_SS_L0RDRD },
+ { "nc", 0xd4, INSTR_SS_L0RDRD },
+ { "clc", 0xd5, INSTR_SS_L0RDRD },
+ { "oc", 0xd6, INSTR_SS_L0RDRD },
+ { "xc", 0xd7, INSTR_SS_L0RDRD },
+ { "mvck", 0xd9, INSTR_SS_RRRDRD },
+ { "mvcp", 0xda, INSTR_SS_RRRDRD },
+ { "mvcs", 0xdb, INSTR_SS_RRRDRD },
+ { "tr", 0xdc, INSTR_SS_L0RDRD },
+ { "trt", 0xdd, INSTR_SS_L0RDRD },
+ { "ed", 0xde, INSTR_SS_L0RDRD },
+ { "edmk", 0xdf, INSTR_SS_L0RDRD },
+ { "pku", 0xe1, INSTR_SS_L0RDRD },
+ { "unpku", 0xe2, INSTR_SS_L0RDRD },
+ { "mvcin", 0xe8, INSTR_SS_L0RDRD },
+ { "pka", 0xe9, INSTR_SS_L0RDRD },
+ { "unpka", 0xea, INSTR_SS_L0RDRD },
+ { "plo", 0xee, INSTR_SS_RRRDRD2 },
+ { "srp", 0xf0, INSTR_SS_LIRDRD },
+ { "mvo", 0xf1, INSTR_SS_LLRDRD },
+ { "pack", 0xf2, INSTR_SS_LLRDRD },
+ { "unpk", 0xf3, INSTR_SS_LLRDRD },
+ { "zap", 0xf8, INSTR_SS_LLRDRD },
+ { "cp", 0xf9, INSTR_SS_LLRDRD },
+ { "ap", 0xfa, INSTR_SS_LLRDRD },
+ { "sp", 0xfb, INSTR_SS_LLRDRD },
+ { "mp", 0xfc, INSTR_SS_LLRDRD },
+ { "dp", 0xfd, INSTR_SS_LLRDRD },
+ { "", 0, INSTR_INVALID }
+}
+
+local opcode_01 = {
+ { "sam64", 0x0e, INSTR_E },
+ { "pfpo", 0x0a, INSTR_E },
+ { "ptff", 0x04, INSTR_E },
+ { "pr", 0x01, INSTR_E },
+ { "upt", 0x02, INSTR_E },
+ { "sckpf", 0x07, INSTR_E },
+ { "tam", 0x0b, INSTR_E },
+ { "sam24", 0x0c, INSTR_E },
+ { "sam31", 0x0d, INSTR_E },
+ { "trap2", 0xff, INSTR_E },
+ { "", 0, INSTR_INVALID }
+}
+
+local opcode_a5 = {
+ { "iihh", 0x00, INSTR_RI_RU },
+ { "iihl", 0x01, INSTR_RI_RU },
+ { "iilh", 0x02, INSTR_RI_RU },
+ { "iill", 0x03, INSTR_RI_RU },
+ { "nihh", 0x04, INSTR_RI_RU },
+ { "nihl", 0x05, INSTR_RI_RU },
+ { "nilh", 0x06, INSTR_RI_RU },
+ { "nill", 0x07, INSTR_RI_RU },
+ { "oihh", 0x08, INSTR_RI_RU },
+ { "oihl", 0x09, INSTR_RI_RU },
+ { "oilh", 0x0a, INSTR_RI_RU },
+ { "oill", 0x0b, INSTR_RI_RU },
+ { "llihh", 0x0c, INSTR_RI_RU },
+ { "llihl", 0x0d, INSTR_RI_RU },
+ { "llilh", 0x0e, INSTR_RI_RU },
+ { "llill", 0x0f, INSTR_RI_RU },
+ { "", 0, INSTR_INVALID }
+}
+
+local opcode_a7 = {
+ { "tmhh", 0x02, INSTR_RI_RU },
+ { "tmhl", 0x03, INSTR_RI_RU },
+ { "brctg", 0x07, INSTR_RI_RP },
+ { "lghi", 0x09, INSTR_RI_RI },
+ { "aghi", 0x0b, INSTR_RI_RI },
+ { "mghi", 0x0d, INSTR_RI_RI },
+ { "cghi", 0x0f, INSTR_RI_RI },
+ { "tmlh", 0x00, INSTR_RI_RU },
+ { "tmll", 0x01, INSTR_RI_RU },
+ { "brc", 0x04, INSTR_RI_UP },
+ { "bras", 0x05, INSTR_RI_RP },
+ { "brct", 0x06, INSTR_RI_RP },
+ { "lhi", 0x08, INSTR_RI_RI },
+ { "ahi", 0x0a, INSTR_RI_RI },
+ { "mhi", 0x0c, INSTR_RI_RI },
+ { "chi", 0x0e, INSTR_RI_RI },
+ { "", 0, INSTR_INVALID }
+}
+
+local opcode_b2 = {
+ { "sske", 0x2b, INSTR_RRF_M0RR },
+ { "stckf", 0x7c, INSTR_S_RD },
+ { "cu21", 0xa6, INSTR_RRF_M0RR },
+ { "cuutf", 0xa6, INSTR_RRF_M0RR },
+ { "cu12", 0xa7, INSTR_RRF_M0RR },
+ { "cutfu", 0xa7, INSTR_RRF_M0RR },
+ { "stfle", 0xb0, INSTR_S_RD },
+ { "lpswe", 0xb2, INSTR_S_RD },
+ { "srnmt", 0xb9, INSTR_S_RD },
+ { "lfas", 0xbd, INSTR_S_RD },
+ { "stidp", 0x02, INSTR_S_RD },
+ { "sck", 0x04, INSTR_S_RD },
+ { "stck", 0x05, INSTR_S_RD },
+ { "sckc", 0x06, INSTR_S_RD },
+ { "stckc", 0x07, INSTR_S_RD },
+ { "spt", 0x08, INSTR_S_RD },
+ { "stpt", 0x09, INSTR_S_RD },
+ { "spka", 0x0a, INSTR_S_RD },
+ { "ipk", 0x0b, INSTR_S_00 },
+ { "ptlb", 0x0d, INSTR_S_00 },
+ { "spx", 0x10, INSTR_S_RD },
+ { "stpx", 0x11, INSTR_S_RD },
+ { "stap", 0x12, INSTR_S_RD },
+ { "sie", 0x14, INSTR_S_RD },
+ { "pc", 0x18, INSTR_S_RD },
+ { "sac", 0x19, INSTR_S_RD },
+ { "cfc", 0x1a, INSTR_S_RD },
+ { "ipte", 0x21, INSTR_RRE_RR },
+ { "ipm", 0x22, INSTR_RRE_R0 },
+ { "ivsk", 0x23, INSTR_RRE_RR },
+ { "iac", 0x24, INSTR_RRE_R0 },
+ { "ssar", 0x25, INSTR_RRE_R0 },
+ { "epar", 0x26, INSTR_RRE_R0 },
+ { "esar", 0x27, INSTR_RRE_R0 },
+ { "pt", 0x28, INSTR_RRE_RR },
+ { "iske", 0x29, INSTR_RRE_RR },
+ { "rrbe", 0x2a, INSTR_RRE_RR },
+ { "sske", 0x2b, INSTR_RRE_RR },
+ { "tb", 0x2c, INSTR_RRE_0R },
+ { "dxr", 0x2d, INSTR_RRE_F0 },
+ { "pgin", 0x2e, INSTR_RRE_RR },
+ { "pgout", 0x2f, INSTR_RRE_RR },
+ { "csch", 0x30, INSTR_S_00 },
+ { "hsch", 0x31, INSTR_S_00 },
+ { "msch", 0x32, INSTR_S_RD },
+ { "ssch", 0x33, INSTR_S_RD },
+ { "stsch", 0x34, INSTR_S_RD },
+ { "tsch", 0x35, INSTR_S_RD },
+ { "tpi", 0x36, INSTR_S_RD },
+ { "sal", 0x37, INSTR_S_00 },
+ { "rsch", 0x38, INSTR_S_00 },
+ { "stcrw", 0x39, INSTR_S_RD },
+ { "stcps", 0x3a, INSTR_S_RD },
+ { "rchp", 0x3b, INSTR_S_00 },
+ { "schm", 0x3c, INSTR_S_00 },
+ { "bakr", 0x40, INSTR_RRE_RR },
+ { "cksm", 0x41, INSTR_RRE_RR },
+ { "sqdr", 0x44, INSTR_RRE_F0 },
+ { "sqer", 0x45, INSTR_RRE_F0 },
+ { "stura", 0x46, INSTR_RRE_RR },
+ { "msta", 0x47, INSTR_RRE_R0 },
+ { "palb", 0x48, INSTR_RRE_00 },
+ { "ereg", 0x49, INSTR_RRE_RR },
+ { "esta", 0x4a, INSTR_RRE_RR },
+ { "lura", 0x4b, INSTR_RRE_RR },
+ { "tar", 0x4c, INSTR_RRE_AR },
+ { "cpya", 0x4d, INSTR_RRE_AA },
+ { "sar", 0x4e, INSTR_RRE_AR },
+ { "ear", 0x4f, INSTR_RRE_RA },
+ { "csp", 0x50, INSTR_RRE_RR },
+ { "msr", 0x52, INSTR_RRE_RR },
+ { "mvpg", 0x54, INSTR_RRE_RR },
+ { "mvst", 0x55, INSTR_RRE_RR },
+ { "cuse", 0x57, INSTR_RRE_RR },
+ { "bsg", 0x58, INSTR_RRE_RR },
+ { "bsa", 0x5a, INSTR_RRE_RR },
+ { "clst", 0x5d, INSTR_RRE_RR },
+ { "srst", 0x5e, INSTR_RRE_RR },
+ { "cmpsc", 0x63, INSTR_RRE_RR },
+ { "siga", 0x74, INSTR_S_RD },
+ { "xsch", 0x76, INSTR_S_00 },
+ { "rp", 0x77, INSTR_S_RD },
+ { "stcke", 0x78, INSTR_S_RD },
+ { "sacf", 0x79, INSTR_S_RD },
+ { "stsi", 0x7d, INSTR_S_RD },
+ { "srnm", 0x99, INSTR_S_RD },
+ { "stfpc", 0x9c, INSTR_S_RD },
+ { "lfpc", 0x9d, INSTR_S_RD },
+ { "tre", 0xa5, INSTR_RRE_RR },
+ { "cuutf", 0xa6, INSTR_RRE_RR },
+ { "cutfu", 0xa7, INSTR_RRE_RR },
+ { "stfl", 0xb1, INSTR_S_RD },
+ { "trap4", 0xff, INSTR_S_RD },
+ { "", 0, INSTR_INVALID }
+}
+
+local opcode_b3 = {
+ { "maylr", 0x38, INSTR_RRF_F0FF },
+ { "mylr", 0x39, INSTR_RRF_F0FF },
+ { "mayr", 0x3a, INSTR_RRF_F0FF },
+ { "myr", 0x3b, INSTR_RRF_F0FF },
+ { "mayhr", 0x3c, INSTR_RRF_F0FF },
+ { "myhr", 0x3d, INSTR_RRF_F0FF },
+ { "cegbr", 0xa4, INSTR_RRE_RR },
+ { "cdgbr", 0xa5, INSTR_RRE_RR },
+ { "cxgbr", 0xa6, INSTR_RRE_RR },
+ { "cgebr", 0xa8, INSTR_RRF_U0RF },
+ { "cgdbr", 0xa9, INSTR_RRF_U0RF },
+ { "cgxbr", 0xaa, INSTR_RRF_U0RF },
+ { "cfer", 0xb8, INSTR_RRF_U0RF },
+ { "cfdr", 0xb9, INSTR_RRF_U0RF },
+ { "cfxr", 0xba, INSTR_RRF_U0RF },
+ { "cegr", 0xc4, INSTR_RRE_RR },
+ { "cdgr", 0xc5, INSTR_RRE_RR },
+ { "cxgr", 0xc6, INSTR_RRE_RR },
+ { "cger", 0xc8, INSTR_RRF_U0RF },
+ { "cgdr", 0xc9, INSTR_RRF_U0RF },
+ { "cgxr", 0xca, INSTR_RRF_U0RF },
+ { "lpdfr", 0x70, INSTR_RRE_FF },
+ { "lndfr", 0x71, INSTR_RRE_FF },
+ { "cpsdr", 0x72, INSTR_RRF_F0FF2 },
+ { "lcdfr", 0x73, INSTR_RRE_FF },
+ { "ldgr", 0xc1, INSTR_RRE_FR },
+ { "lgdr", 0xcd, INSTR_RRE_RF },
+ { "adtr", 0xd2, INSTR_RRR_F0FF },
+ { "axtr", 0xda, INSTR_RRR_F0FF },
+ { "cdtr", 0xe4, INSTR_RRE_FF },
+ { "cxtr", 0xec, INSTR_RRE_FF },
+ { "kdtr", 0xe0, INSTR_RRE_FF },
+ { "kxtr", 0xe8, INSTR_RRE_FF },
+ { "cedtr", 0xf4, INSTR_RRE_FF },
+ { "cextr", 0xfc, INSTR_RRE_FF },
+ { "cdgtr", 0xf1, INSTR_RRE_FR },
+ { "cxgtr", 0xf9, INSTR_RRE_FR },
+ { "cdstr", 0xf3, INSTR_RRE_FR },
+ { "cxstr", 0xfb, INSTR_RRE_FR },
+ { "cdutr", 0xf2, INSTR_RRE_FR },
+ { "cxutr", 0xfa, INSTR_RRE_FR },
+ { "cgdtr", 0xe1, INSTR_RRF_U0RF },
+ { "cgxtr", 0xe9, INSTR_RRF_U0RF },
+ { "csdtr", 0xe3, INSTR_RRE_RF },
+ { "csxtr", 0xeb, INSTR_RRE_RF },
+ { "cudtr", 0xe2, INSTR_RRE_RF },
+ { "cuxtr", 0xea, INSTR_RRE_RF },
+ { "ddtr", 0xd1, INSTR_RRR_F0FF },
+ { "dxtr", 0xd9, INSTR_RRR_F0FF },
+ { "eedtr", 0xe5, INSTR_RRE_RF },
+ { "eextr", 0xed, INSTR_RRE_RF },
+ { "esdtr", 0xe7, INSTR_RRE_RF },
+ { "esxtr", 0xef, INSTR_RRE_RF },
+ { "iedtr", 0xf6, INSTR_RRF_F0FR },
+ { "iextr", 0xfe, INSTR_RRF_F0FR },
+ { "ltdtr", 0xd6, INSTR_RRE_FF },
+ { "ltxtr", 0xde, INSTR_RRE_FF },
+ { "fidtr", 0xd7, INSTR_RRF_UUFF },
+ { "fixtr", 0xdf, INSTR_RRF_UUFF },
+ { "ldetr", 0xd4, INSTR_RRF_0UFF },
+ { "lxdtr", 0xdc, INSTR_RRF_0UFF },
+ { "ledtr", 0xd5, INSTR_RRF_UUFF },
+ { "ldxtr", 0xdd, INSTR_RRF_UUFF },
+ { "mdtr", 0xd0, INSTR_RRR_F0FF },
+ { "mxtr", 0xd8, INSTR_RRR_F0FF },
+ { "qadtr", 0xf5, INSTR_RRF_FUFF },
+ { "qaxtr", 0xfd, INSTR_RRF_FUFF },
+ { "rrdtr", 0xf7, INSTR_RRF_FFRU },
+ { "rrxtr", 0xff, INSTR_RRF_FFRU },
+ { "sfasr", 0x85, INSTR_RRE_R0 },
+ { "sdtr", 0xd3, INSTR_RRR_F0FF },
+ { "sxtr", 0xdb, INSTR_RRR_F0FF },
+ { "lpebr", 0x00, INSTR_RRE_FF },
+ { "lnebr", 0x01, INSTR_RRE_FF },
+ { "ltebr", 0x02, INSTR_RRE_FF },
+ { "lcebr", 0x03, INSTR_RRE_FF },
+ { "ldebr", 0x04, INSTR_RRE_FF },
+ { "lxdbr", 0x05, INSTR_RRE_FF },
+ { "lxebr", 0x06, INSTR_RRE_FF },
+ { "mxdbr", 0x07, INSTR_RRE_FF },
+ { "kebr", 0x08, INSTR_RRE_FF },
+ { "cebr", 0x09, INSTR_RRE_FF },
+ { "aebr", 0x0a, INSTR_RRE_FF },
+ { "sebr", 0x0b, INSTR_RRE_FF },
+ { "mdebr", 0x0c, INSTR_RRE_FF },
+ { "debr", 0x0d, INSTR_RRE_FF },
+ { "maebr", 0x0e, INSTR_RRF_F0FF },
+ { "msebr", 0x0f, INSTR_RRF_F0FF },
+ { "lpdbr", 0x10, INSTR_RRE_FF },
+ { "lndbr", 0x11, INSTR_RRE_FF },
+ { "ltdbr", 0x12, INSTR_RRE_FF },
+ { "lcdbr", 0x13, INSTR_RRE_FF },
+ { "sqebr", 0x14, INSTR_RRE_FF },
+ { "sqdbr", 0x15, INSTR_RRE_FF },
+ { "sqxbr", 0x16, INSTR_RRE_FF },
+ { "meebr", 0x17, INSTR_RRE_FF },
+ { "kdbr", 0x18, INSTR_RRE_FF },
+ { "cdbr", 0x19, INSTR_RRE_FF },
+ { "adbr", 0x1a, INSTR_RRE_FF },
+ { "sdbr", 0x1b, INSTR_RRE_FF },
+ { "mdbr", 0x1c, INSTR_RRE_FF },
+ { "ddbr", 0x1d, INSTR_RRE_FF },
+ { "madbr", 0x1e, INSTR_RRF_F0FF },
+ { "msdbr", 0x1f, INSTR_RRF_F0FF },
+ { "lder", 0x24, INSTR_RRE_FF },
+ { "lxdr", 0x25, INSTR_RRE_FF },
+ { "lxer", 0x26, INSTR_RRE_FF },
+ { "maer", 0x2e, INSTR_RRF_F0FF },
+ { "mser", 0x2f, INSTR_RRF_F0FF },
+ { "sqxr", 0x36, INSTR_RRE_FF },
+ { "meer", 0x37, INSTR_RRE_FF },
+ { "madr", 0x3e, INSTR_RRF_F0FF },
+ { "msdr", 0x3f, INSTR_RRF_F0FF },
+ { "lpxbr", 0x40, INSTR_RRE_FF },
+ { "lnxbr", 0x41, INSTR_RRE_FF },
+ { "ltxbr", 0x42, INSTR_RRE_FF },
+ { "lcxbr", 0x43, INSTR_RRE_FF },
+ { "ledbr", 0x44, INSTR_RRE_FF },
+ { "ldxbr", 0x45, INSTR_RRE_FF },
+ { "lexbr", 0x46, INSTR_RRE_FF },
+ { "fixbr", 0x47, INSTR_RRF_U0FF },
+ { "kxbr", 0x48, INSTR_RRE_FF },
+ { "cxbr", 0x49, INSTR_RRE_FF },
+ { "axbr", 0x4a, INSTR_RRE_FF },
+ { "sxbr", 0x4b, INSTR_RRE_FF },
+ { "mxbr", 0x4c, INSTR_RRE_FF },
+ { "dxbr", 0x4d, INSTR_RRE_FF },
+ { "tbedr", 0x50, INSTR_RRF_U0FF },
+ { "tbdr", 0x51, INSTR_RRF_U0FF },
+ { "diebr", 0x53, INSTR_RRF_FUFF },
+ { "fiebr", 0x57, INSTR_RRF_U0FF },
+ { "thder", 0x58, INSTR_RRE_RR },
+ { "thdr", 0x59, INSTR_RRE_RR },
+ { "didbr", 0x5b, INSTR_RRF_FUFF },
+ { "fidbr", 0x5f, INSTR_RRF_U0FF },
+ { "lpxr", 0x60, INSTR_RRE_FF },
+ { "lnxr", 0x61, INSTR_RRE_FF },
+ { "ltxr", 0x62, INSTR_RRE_FF },
+ { "lcxr", 0x63, INSTR_RRE_FF },
+ { "lxr", 0x65, INSTR_RRE_RR },
+ { "lexr", 0x66, INSTR_RRE_FF },
+ { "fixr", 0x67, INSTR_RRF_U0FF },
+ { "cxr", 0x69, INSTR_RRE_FF },
+ { "lzer", 0x74, INSTR_RRE_R0 },
+ { "lzdr", 0x75, INSTR_RRE_R0 },
+ { "lzxr", 0x76, INSTR_RRE_R0 },
+ { "fier", 0x77, INSTR_RRF_U0FF },
+ { "fidr", 0x7f, INSTR_RRF_U0FF },
+ { "sfpc", 0x84, INSTR_RRE_RR_OPT },
+ { "efpc", 0x8c, INSTR_RRE_RR_OPT },
+ { "cefbr", 0x94, INSTR_RRE_RF },
+ { "cdfbr", 0x95, INSTR_RRE_RF },
+ { "cxfbr", 0x96, INSTR_RRE_RF },
+ { "cfebr", 0x98, INSTR_RRF_U0RF },
+ { "cfdbr", 0x99, INSTR_RRF_U0RF },
+ { "cfxbr", 0x9a, INSTR_RRF_U0RF },
+ { "cefr", 0xb4, INSTR_RRE_RF },
+ { "cdfr", 0xb5, INSTR_RRE_RF },
+ { "cxfr", 0xb6, INSTR_RRE_RF },
+ { "", 0, INSTR_INVALID }
+}
+
+local opcode_b9 = {
+ { "lpgr", 0x00, INSTR_RRE_RR },
+ { "lngr", 0x01, INSTR_RRE_RR },
+ { "ltgr", 0x02, INSTR_RRE_RR },
+ { "lcgr", 0x03, INSTR_RRE_RR },
+ { "lgr", 0x04, INSTR_RRE_RR },
+ { "lurag", 0x05, INSTR_RRE_RR },
+ { "lgbr", 0x06, INSTR_RRE_RR },
+ { "lghr", 0x07, INSTR_RRE_RR },
+ { "agr", 0x08, INSTR_RRE_RR },
+ { "sgr", 0x09, INSTR_RRE_RR },
+ { "algr", 0x0a, INSTR_RRE_RR },
+ { "slgr", 0x0b, INSTR_RRE_RR },
+ { "msgr", 0x0c, INSTR_RRE_RR },
+ { "dsgr", 0x0d, INSTR_RRE_RR },
+ { "eregg", 0x0e, INSTR_RRE_RR },
+ { "lrvgr", 0x0f, INSTR_RRE_RR },
+ { "lpgfr", 0x10, INSTR_RRE_RR },
+ { "lngfr", 0x11, INSTR_RRE_RR },
+ { "ltgfr", 0x12, INSTR_RRE_RR },
+ { "lcgfr", 0x13, INSTR_RRE_RR },
+ { "lgfr", 0x14, INSTR_RRE_RR },
+ { "llgfr", 0x16, INSTR_RRE_RR },
+ { "llgtr", 0x17, INSTR_RRE_RR },
+ { "agfr", 0x18, INSTR_RRE_RR },
+ { "sgfr", 0x19, INSTR_RRE_RR },
+ { "algfr", 0x1a, INSTR_RRE_RR },
+ { "slgfr", 0x1b, INSTR_RRE_RR },
+ { "msgfr", 0x1c, INSTR_RRE_RR },
+ { "dsgfr", 0x1d, INSTR_RRE_RR },
+ { "cgr", 0x20, INSTR_RRE_RR },
+ { "clgr", 0x21, INSTR_RRE_RR },
+ { "sturg", 0x25, INSTR_RRE_RR },
+ { "lbr", 0x26, INSTR_RRE_RR },
+ { "lhr", 0x27, INSTR_RRE_RR },
+ { "cgfr", 0x30, INSTR_RRE_RR },
+ { "clgfr", 0x31, INSTR_RRE_RR },
+ { "bctgr", 0x46, INSTR_RRE_RR },
+ { "ngr", 0x80, INSTR_RRE_RR },
+ { "ogr", 0x81, INSTR_RRE_RR },
+ { "xgr", 0x82, INSTR_RRE_RR },
+ { "flogr", 0x83, INSTR_RRE_RR },
+ { "llgcr", 0x84, INSTR_RRE_RR },
+ { "llghr", 0x85, INSTR_RRE_RR },
+ { "mlgr", 0x86, INSTR_RRE_RR },
+ { "dlgr", 0x87, INSTR_RRE_RR },
+ { "alcgr", 0x88, INSTR_RRE_RR },
+ { "slbgr", 0x89, INSTR_RRE_RR },
+ { "cspg", 0x8a, INSTR_RRE_RR },
+ { "idte", 0x8e, INSTR_RRF_R0RR },
+ { "llcr", 0x94, INSTR_RRE_RR },
+ { "llhr", 0x95, INSTR_RRE_RR },
+ { "esea", 0x9d, INSTR_RRE_R0 },
+ { "lptea", 0xaa, INSTR_RRF_RURR },
+ { "cu14", 0xb0, INSTR_RRF_M0RR },
+ { "cu24", 0xb1, INSTR_RRF_M0RR },
+ { "cu41", 0xb2, INSTR_RRF_M0RR },
+ { "cu42", 0xb3, INSTR_RRF_M0RR },
+ { "crt", 0x72, INSTR_RRF_U0RR },
+ { "cgrt", 0x60, INSTR_RRF_U0RR },
+ { "clrt", 0x73, INSTR_RRF_U0RR },
+ { "clgrt", 0x61, INSTR_RRF_U0RR },
+ { "ptf", 0xa2, INSTR_RRE_R0 },
+ { "pfmf", 0xaf, INSTR_RRE_RR },
+ { "trte", 0xbf, INSTR_RRF_M0RR },
+ { "trtre", 0xbd, INSTR_RRF_M0RR },
+ { "kmac", 0x1e, INSTR_RRE_RR },
+ { "lrvr", 0x1f, INSTR_RRE_RR },
+ { "km", 0x2e, INSTR_RRE_RR },
+ { "kmc", 0x2f, INSTR_RRE_RR },
+ { "kimd", 0x3e, INSTR_RRE_RR },
+ { "klmd", 0x3f, INSTR_RRE_RR },
+ { "epsw", 0x8d, INSTR_RRE_RR },
+ { "trtt", 0x90, INSTR_RRE_RR },
+ { "trtt", 0x90, INSTR_RRF_M0RR },
+ { "trto", 0x91, INSTR_RRE_RR },
+ { "trto", 0x91, INSTR_RRF_M0RR },
+ { "trot", 0x92, INSTR_RRE_RR },
+ { "trot", 0x92, INSTR_RRF_M0RR },
+ { "troo", 0x93, INSTR_RRE_RR },
+ { "troo", 0x93, INSTR_RRF_M0RR },
+ { "mlr", 0x96, INSTR_RRE_RR },
+ { "dlr", 0x97, INSTR_RRE_RR },
+ { "alcr", 0x98, INSTR_RRE_RR },
+ { "slbr", 0x99, INSTR_RRE_RR },
+ { "", 0, INSTR_INVALID }
+}
+
+local opcode_c0 = {
+ { "lgfi", 0x01, INSTR_RIL_RI },
+ { "xihf", 0x06, INSTR_RIL_RU },
+ { "xilf", 0x07, INSTR_RIL_RU },
+ { "iihf", 0x08, INSTR_RIL_RU },
+ { "iilf", 0x09, INSTR_RIL_RU },
+ { "nihf", 0x0a, INSTR_RIL_RU },
+ { "nilf", 0x0b, INSTR_RIL_RU },
+ { "oihf", 0x0c, INSTR_RIL_RU },
+ { "oilf", 0x0d, INSTR_RIL_RU },
+ { "llihf", 0x0e, INSTR_RIL_RU },
+ { "llilf", 0x0f, INSTR_RIL_RU },
+ { "larl", 0x00, INSTR_RIL_RP },
+ { "brcl", 0x04, INSTR_RIL_UP },
+ { "brasl", 0x05, INSTR_RIL_RP },
+ { "", 0, INSTR_INVALID }
+}
+
+local opcode_c2 = {
+ { "slgfi", 0x04, INSTR_RIL_RU },
+ { "slfi", 0x05, INSTR_RIL_RU },
+ { "agfi", 0x08, INSTR_RIL_RI },
+ { "afi", 0x09, INSTR_RIL_RI },
+ { "algfi", 0x0a, INSTR_RIL_RU },
+ { "alfi", 0x0b, INSTR_RIL_RU },
+ { "cgfi", 0x0c, INSTR_RIL_RI },
+ { "cfi", 0x0d, INSTR_RIL_RI },
+ { "clgfi", 0x0e, INSTR_RIL_RU },
+ { "clfi", 0x0f, INSTR_RIL_RU },
+ { "msfi", 0x01, INSTR_RIL_RI },
+ { "msgfi", 0x00, INSTR_RIL_RI },
+ { "", 0, INSTR_INVALID }
+}
+
+local opcode_c4 = {
+ { "lrl", 0x0d, INSTR_RIL_RP },
+ { "lgrl", 0x08, INSTR_RIL_RP },
+ { "lgfrl", 0x0c, INSTR_RIL_RP },
+ { "lhrl", 0x05, INSTR_RIL_RP },
+ { "lghrl", 0x04, INSTR_RIL_RP },
+ { "llgfrl", 0x0e, INSTR_RIL_RP },
+ { "llhrl", 0x02, INSTR_RIL_RP },
+ { "llghrl", 0x06, INSTR_RIL_RP },
+ { "strl", 0x0f, INSTR_RIL_RP },
+ { "stgrl", 0x0b, INSTR_RIL_RP },
+ { "sthrl", 0x07, INSTR_RIL_RP },
+ { "", 0, INSTR_INVALID }
+}
+
+local opcode_c6 = {
+ { "crl", 0x0d, INSTR_RIL_RP },
+ { "cgrl", 0x08, INSTR_RIL_RP },
+ { "cgfrl", 0x0c, INSTR_RIL_RP },
+ { "chrl", 0x05, INSTR_RIL_RP },
+ { "cghrl", 0x04, INSTR_RIL_RP },
+ { "clrl", 0x0f, INSTR_RIL_RP },
+ { "clgrl", 0x0a, INSTR_RIL_RP },
+ { "clgfrl", 0x0e, INSTR_RIL_RP },
+ { "clhrl", 0x07, INSTR_RIL_RP },
+ { "clghrl", 0x06, INSTR_RIL_RP },
+ { "pfdrl", 0x02, INSTR_RIL_UP },
+ { "exrl", 0x00, INSTR_RIL_RP },
+ { "", 0, INSTR_INVALID }
+}
+
+local opcode_c8 = {
+ { "mvcos", 0x00, INSTR_SSF_RRDRD },
+ { "ectg", 0x01, INSTR_SSF_RRDRD },
+ { "csst", 0x02, INSTR_SSF_RRDRD },
+ { "", 0, INSTR_INVALID }
+}
+
+local opcode_e3 = {
+ { "ltg", 0x02, INSTR_RXY_RRRD },
+ { "lrag", 0x03, INSTR_RXY_RRRD },
+ { "lg", 0x04, INSTR_RXY_RRRD },
+ { "cvby", 0x06, INSTR_RXY_RRRD },
+ { "ag", 0x08, INSTR_RXY_RRRD },
+ { "sg", 0x09, INSTR_RXY_RRRD },
+ { "alg", 0x0a, INSTR_RXY_RRRD },
+ { "slg", 0x0b, INSTR_RXY_RRRD },
+ { "msg", 0x0c, INSTR_RXY_RRRD },
+ { "dsg", 0x0d, INSTR_RXY_RRRD },
+ { "cvbg", 0x0e, INSTR_RXY_RRRD },
+ { "lrvg", 0x0f, INSTR_RXY_RRRD },
+ { "lt", 0x12, INSTR_RXY_RRRD },
+ { "lray", 0x13, INSTR_RXY_RRRD },
+ { "lgf", 0x14, INSTR_RXY_RRRD },
+ { "lgh", 0x15, INSTR_RXY_RRRD },
+ { "llgf", 0x16, INSTR_RXY_RRRD },
+ { "llgt", 0x17, INSTR_RXY_RRRD },
+ { "agf", 0x18, INSTR_RXY_RRRD },
+ { "sgf", 0x19, INSTR_RXY_RRRD },
+ { "algf", 0x1a, INSTR_RXY_RRRD },
+ { "slgf", 0x1b, INSTR_RXY_RRRD },
+ { "msgf", 0x1c, INSTR_RXY_RRRD },
+ { "dsgf", 0x1d, INSTR_RXY_RRRD },
+ { "cg", 0x20, INSTR_RXY_RRRD },
+ { "clg", 0x21, INSTR_RXY_RRRD },
+ { "stg", 0x24, INSTR_RXY_RRRD },
+ { "cvdy", 0x26, INSTR_RXY_RRRD },
+ { "cvdg", 0x2e, INSTR_RXY_RRRD },
+ { "strvg", 0x2f, INSTR_RXY_RRRD },
+ { "cgf", 0x30, INSTR_RXY_RRRD },
+ { "clgf", 0x31, INSTR_RXY_RRRD },
+ { "strvh", 0x3f, INSTR_RXY_RRRD },
+ { "bctg", 0x46, INSTR_RXY_RRRD },
+ { "sty", 0x50, INSTR_RXY_RRRD },
+ { "msy", 0x51, INSTR_RXY_RRRD },
+ { "ny", 0x54, INSTR_RXY_RRRD },
+ { "cly", 0x55, INSTR_RXY_RRRD },
+ { "oy", 0x56, INSTR_RXY_RRRD },
+ { "xy", 0x57, INSTR_RXY_RRRD },
+ { "ly", 0x58, INSTR_RXY_RRRD },
+ { "cy", 0x59, INSTR_RXY_RRRD },
+ { "ay", 0x5a, INSTR_RXY_RRRD },
+ { "sy", 0x5b, INSTR_RXY_RRRD },
+ { "aly", 0x5e, INSTR_RXY_RRRD },
+ { "sly", 0x5f, INSTR_RXY_RRRD },
+ { "sthy", 0x70, INSTR_RXY_RRRD },
+ { "lay", 0x71, INSTR_RXY_RRRD },
+ { "stcy", 0x72, INSTR_RXY_RRRD },
+ { "icy", 0x73, INSTR_RXY_RRRD },
+ { "lb", 0x76, INSTR_RXY_RRRD },
+ { "lgb", 0x77, INSTR_RXY_RRRD },
+ { "lhy", 0x78, INSTR_RXY_RRRD },
+ { "chy", 0x79, INSTR_RXY_RRRD },
+ { "ahy", 0x7a, INSTR_RXY_RRRD },
+ { "shy", 0x7b, INSTR_RXY_RRRD },
+ { "ng", 0x80, INSTR_RXY_RRRD },
+ { "og", 0x81, INSTR_RXY_RRRD },
+ { "xg", 0x82, INSTR_RXY_RRRD },
+ { "mlg", 0x86, INSTR_RXY_RRRD },
+ { "dlg", 0x87, INSTR_RXY_RRRD },
+ { "alcg", 0x88, INSTR_RXY_RRRD },
+ { "slbg", 0x89, INSTR_RXY_RRRD },
+ { "stpq", 0x8e, INSTR_RXY_RRRD },
+ { "lpq", 0x8f, INSTR_RXY_RRRD },
+ { "llgc", 0x90, INSTR_RXY_RRRD },
+ { "llgh", 0x91, INSTR_RXY_RRRD },
+ { "llc", 0x94, INSTR_RXY_RRRD },
+ { "llh", 0x95, INSTR_RXY_RRRD },
+ { "cgh", 0x34, INSTR_RXY_RRRD },
+ { "laey", 0x75, INSTR_RXY_RRRD },
+ { "ltgf", 0x32, INSTR_RXY_RRRD },
+ { "mfy", 0x5c, INSTR_RXY_RRRD },
+ { "mhy", 0x7c, INSTR_RXY_RRRD },
+ { "pfd", 0x36, INSTR_RXY_URRD },
+ { "lrv", 0x1e, INSTR_RXY_RRRD },
+ { "lrvh", 0x1f, INSTR_RXY_RRRD },
+ { "strv", 0x3e, INSTR_RXY_RRRD },
+ { "ml", 0x96, INSTR_RXY_RRRD },
+ { "dl", 0x97, INSTR_RXY_RRRD },
+ { "alc", 0x98, INSTR_RXY_RRRD },
+ { "slb", 0x99, INSTR_RXY_RRRD },
+ { "", 0, INSTR_INVALID }
+}
+
+local opcode_e5 = {
+ { "strag", 0x02, INSTR_SSE_RDRD },
+ { "chhsi", 0x54, INSTR_SIL_RDI },
+ { "chsi", 0x5c, INSTR_SIL_RDI },
+ { "cghsi", 0x58, INSTR_SIL_RDI },
+ { "clhhsi", 0x55, INSTR_SIL_RDU },
+ { "clfhsi", 0x5d, INSTR_SIL_RDU },
+ { "clghsi", 0x59, INSTR_SIL_RDU },
+ { "mvhhi", 0x44, INSTR_SIL_RDI },
+ { "mvhi", 0x4c, INSTR_SIL_RDI },
+ { "mvghi", 0x48, INSTR_SIL_RDI },
+ { "lasp", 0x00, INSTR_SSE_RDRD },
+ { "tprot", 0x01, INSTR_SSE_RDRD },
+ { "mvcsk", 0x0e, INSTR_SSE_RDRD },
+ { "mvcdk", 0x0f, INSTR_SSE_RDRD },
+ { "", 0, INSTR_INVALID }
+}
+
+local opcode_eb = {
+ { "lmg", 0x04, INSTR_RSY_RRRD },
+ { "srag", 0x0a, INSTR_RSY_RRRD },
+ { "slag", 0x0b, INSTR_RSY_RRRD },
+ { "srlg", 0x0c, INSTR_RSY_RRRD },
+ { "sllg", 0x0d, INSTR_RSY_RRRD },
+ { "tracg", 0x0f, INSTR_RSY_RRRD },
+ { "csy", 0x14, INSTR_RSY_RRRD },
+ { "rllg", 0x1c, INSTR_RSY_RRRD },
+ { "clmh", 0x20, INSTR_RSY_RURD },
+ { "clmy", 0x21, INSTR_RSY_RURD },
+ { "stmg", 0x24, INSTR_RSY_RRRD },
+ { "stctg", 0x25, INSTR_RSY_CCRD },
+ { "stmh", 0x26, INSTR_RSY_RRRD },
+ { "stcmh", 0x2c, INSTR_RSY_RURD },
+ { "stcmy", 0x2d, INSTR_RSY_RURD },
+ { "lctlg", 0x2f, INSTR_RSY_CCRD },
+ { "csg", 0x30, INSTR_RSY_RRRD },
+ { "cdsy", 0x31, INSTR_RSY_RRRD },
+ { "cdsg", 0x3e, INSTR_RSY_RRRD },
+ { "bxhg", 0x44, INSTR_RSY_RRRD },
+ { "bxleg", 0x45, INSTR_RSY_RRRD },
+ { "tmy", 0x51, INSTR_SIY_URD },
+ { "mviy", 0x52, INSTR_SIY_URD },
+ { "niy", 0x54, INSTR_SIY_URD },
+ { "cliy", 0x55, INSTR_SIY_URD },
+ { "oiy", 0x56, INSTR_SIY_URD },
+ { "xiy", 0x57, INSTR_SIY_URD },
+ { "icmh", 0x80, INSTR_RSE_RURD },
+ { "icmh", 0x80, INSTR_RSY_RURD },
+ { "icmy", 0x81, INSTR_RSY_RURD },
+ { "clclu", 0x8f, INSTR_RSY_RRRD },
+ { "stmy", 0x90, INSTR_RSY_RRRD },
+ { "lmh", 0x96, INSTR_RSY_RRRD },
+ { "lmy", 0x98, INSTR_RSY_RRRD },
+ { "lamy", 0x9a, INSTR_RSY_AARD },
+ { "stamy", 0x9b, INSTR_RSY_AARD },
+ { "asi", 0x6a, INSTR_SIY_IRD },
+ { "agsi", 0x7a, INSTR_SIY_IRD },
+ { "alsi", 0x6e, INSTR_SIY_IRD },
+ { "algsi", 0x7e, INSTR_SIY_IRD },
+ { "ecag", 0x4c, INSTR_RSY_RRRD },
+ { "rll", 0x1d, INSTR_RSY_RRRD },
+ { "mvclu", 0x8e, INSTR_RSY_RRRD },
+ { "tp", 0xc0, INSTR_RSL_R0RD },
+ { "", 0, INSTR_INVALID }
+}
+
+local opcode_ec = {
+ { "brxhg", 0x44, INSTR_RIE_RRP },
+ { "brxlg", 0x45, INSTR_RIE_RRP },
+ { "crb", 0xf6, INSTR_RRS_RRRDU },
+ { "cgrb", 0xe4, INSTR_RRS_RRRDU },
+ { "crj", 0x76, INSTR_RIE_RRPU },
+ { "cgrj", 0x64, INSTR_RIE_RRPU },
+ { "cib", 0xfe, INSTR_RIS_RURDI },
+ { "cgib", 0xfc, INSTR_RIS_RURDI },
+ { "cij", 0x7e, INSTR_RIE_RUPI },
+ { "cgij", 0x7c, INSTR_RIE_RUPI },
+ { "cit", 0x72, INSTR_RIE_R0IU },
+ { "cgit", 0x70, INSTR_RIE_R0IU },
+ { "clrb", 0xf7, INSTR_RRS_RRRDU },
+ { "clgrb", 0xe5, INSTR_RRS_RRRDU },
+ { "clrj", 0x77, INSTR_RIE_RRPU },
+ { "clgrj", 0x65, INSTR_RIE_RRPU },
+ { "clib", 0xff, INSTR_RIS_RURDU },
+ { "clgib", 0xfd, INSTR_RIS_RURDU },
+ { "clij", 0x7f, INSTR_RIE_RUPU },
+ { "clgij", 0x7d, INSTR_RIE_RUPU },
+ { "clfit", 0x73, INSTR_RIE_R0UU },
+ { "clgit", 0x71, INSTR_RIE_R0UU },
+ { "rnsbg", 0x54, INSTR_RIE_RRUUU },
+ { "rxsbg", 0x57, INSTR_RIE_RRUUU },
+ { "rosbg", 0x56, INSTR_RIE_RRUUU },
+ { "risbg", 0x55, INSTR_RIE_RRUUU },
+ { "", 0, INSTR_INVALID }
+}
+
+local opcode_ed[] = {
+ { "mayl", 0x38, INSTR_RXF_FRRDF },
+ { "myl", 0x39, INSTR_RXF_FRRDF },
+ { "may", 0x3a, INSTR_RXF_FRRDF },
+ { "my", 0x3b, INSTR_RXF_FRRDF },
+ { "mayh", 0x3c, INSTR_RXF_FRRDF },
+ { "myh", 0x3d, INSTR_RXF_FRRDF },
+ { "ley", 0x64, INSTR_RXY_FRRD },
+ { "ldy", 0x65, INSTR_RXY_FRRD },
+ { "stey", 0x66, INSTR_RXY_FRRD },
+ { "stdy", 0x67, INSTR_RXY_FRRD },
+ { "sldt", 0x40, INSTR_RXF_FRRDF },
+ { "slxt", 0x48, INSTR_RXF_FRRDF },
+ { "srdt", 0x41, INSTR_RXF_FRRDF },
+ { "srxt", 0x49, INSTR_RXF_FRRDF },
+ { "tdcet", 0x50, INSTR_RXE_FRRD },
+ { "tdcdt", 0x54, INSTR_RXE_FRRD },
+ { "tdcxt", 0x58, INSTR_RXE_FRRD },
+ { "tdget", 0x51, INSTR_RXE_FRRD },
+ { "tdgdt", 0x55, INSTR_RXE_FRRD },
+ { "tdgxt", 0x59, INSTR_RXE_FRRD },
+ { "ldeb", 0x04, INSTR_RXE_FRRD },
+ { "lxdb", 0x05, INSTR_RXE_FRRD },
+ { "lxeb", 0x06, INSTR_RXE_FRRD },
+ { "mxdb", 0x07, INSTR_RXE_FRRD },
+ { "keb", 0x08, INSTR_RXE_FRRD },
+ { "ceb", 0x09, INSTR_RXE_FRRD },
+ { "aeb", 0x0a, INSTR_RXE_FRRD },
+ { "seb", 0x0b, INSTR_RXE_FRRD },
+ { "mdeb", 0x0c, INSTR_RXE_FRRD },
+ { "deb", 0x0d, INSTR_RXE_FRRD },
+ { "maeb", 0x0e, INSTR_RXF_FRRDF },
+ { "mseb", 0x0f, INSTR_RXF_FRRDF },
+ { "tceb", 0x10, INSTR_RXE_FRRD },
+ { "tcdb", 0x11, INSTR_RXE_FRRD },
+ { "tcxb", 0x12, INSTR_RXE_FRRD },
+ { "sqeb", 0x14, INSTR_RXE_FRRD },
+ { "sqdb", 0x15, INSTR_RXE_FRRD },
+ { "meeb", 0x17, INSTR_RXE_FRRD },
+ { "kdb", 0x18, INSTR_RXE_FRRD },
+ { "cdb", 0x19, INSTR_RXE_FRRD },
+ { "adb", 0x1a, INSTR_RXE_FRRD },
+ { "sdb", 0x1b, INSTR_RXE_FRRD },
+ { "mdb", 0x1c, INSTR_RXE_FRRD },
+ { "ddb", 0x1d, INSTR_RXE_FRRD },
+ { "madb", 0x1e, INSTR_RXF_FRRDF },
+ { "msdb", 0x1f, INSTR_RXF_FRRDF },
+ { "lde", 0x24, INSTR_RXE_FRRD },
+ { "lxd", 0x25, INSTR_RXE_FRRD },
+ { "lxe", 0x26, INSTR_RXE_FRRD },
+ { "mae", 0x2e, INSTR_RXF_FRRDF },
+ { "mse", 0x2f, INSTR_RXF_FRRDF },
+ { "sqe", 0x34, INSTR_RXE_FRRD },
+ { "sqd", 0x35, INSTR_RXE_FRRD },
+ { "mee", 0x37, INSTR_RXE_FRRD },
+ { "mad", 0x3e, INSTR_RXF_FRRDF },
+ { "msd", 0x3f, INSTR_RXF_FRRDF },
+ { "", 0, INSTR_INVALID }
+}
+
+-- Extracts an operand value from an instruction.
+local function extract_operand(code, operand)
+ code += operand[2] / 8;
+ bits = band(operand[2], 7) + operand[1]
+ val = 0
+ repeat
+ val = lshift(val, 8)
+ val = bor(val, *code++)
+ bits -= 8
+ until(bits > 0)
+
+ val = rshift(val, -bits)
+ val = band(val, lshift(lshift(1U,operand[1] - 1), 1) - 1)
+
+ -- Check for special long displacement case.
+ if(operand[1] == 20 && operand[2] == 20) then
+ val = bor(lshift(band(val, 0xff), 12), rshift(band(val, 0xfff00), 8))
+ end
+
+ -- Sign extend value if the operand is signed or pc relative.
+ if(band(operand->flags, bor(OPERAND_SIGNED, OPERAND_PCREL)) && band(val, lshift(1U,(operand[1] - 1)))) then
+ val = bor(val, lshift(lshift(-1U, (operand[1] - 1)), 1))
+ end
+
+ -- Double value if the operand is pc relative.
+ if(band(operand[2], OPERAND_PCREL)) then
+ val = lshift(val, 1)
+ end
+
+ -- Length x in an instructions has real length x + 1.
+ if(band(operand[2], OPERAND_LENGTH)) then
+ val++
+ end
+ return val
+end
+
+local function insn_length(code)
+ return lshift((rshift((tonumber(code) + 64), 7) + 1), 1);
+end
+
+local find_insn(code){
+ opfrag = code[1]
+ table = opcode
+
+ if(code[0] == 0x01) then
+ table = opcode_01
+ elseif(code[0] == 0xa5)
+ table = opcode_a5
+ elseif(code[0] == 0xa7)
+ table = opcode_a7
+ elseif(code[0] == 0xb2)
+ table = opcode_b2
+ elseif(code[0] == 0xb3)
+ table = opcode_b3
+ elseif(code[0] == 0xb9)
+ table = opcode_b9
+ elseif(code[0] == 0xc0)
+ table = opcode_c0
+ elseif(code[0] == 0xc2)
+ table = opcode_c2
+ elseif(code[0] == 0xc4)
+ table = opcode_c4
+ elseif(code[0] == 0xc6)
+ table = opcode_c6
+ elseif(code[0] == 0xc8)
+ table = opcode_c8
+ elseif(code[0] == 0xe3)
+ table = opcode_e3
+ opfrag = code[5]
+ elseif(code[0] == 0xe5)
+ table = opcode_e5
+ elseif(code[0] == 0xeb)
+ table = opcode_eb
+ opfrag = code[5]
+ elseif(code[0] == 0xec)
+ table = opcode_ec
+ opfrag = code[5]
+ elseif(code[0] == 0xed)
+ table = opcode_ed
+ opfrag = code[5]
+ else
+ opfrag = code[0]
+ end
+
+ for k, insn in pairs(table) do
+ opmask = formats[insn[3]][1]
+ if(insn[2] == band(opfrag, opmask)) then
+ return insn
+ end
+ end
+ return NULL
+}
+
+------------------------------------------------------------------------------
+
+-- 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
+
+ print("noice")
+
+ -- 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/src/deps/src/luajit/src/lib_base.c b/src/deps/src/luajit/src/lib_base.c
index cd743e30d..cff9f7d90 100644
--- a/src/deps/src/luajit/src/lib_base.c
+++ b/src/deps/src/luajit/src/lib_base.c
@@ -361,7 +361,11 @@ LJLIB_ASM_(xpcall) LJLIB_REC(.)
static int load_aux(lua_State *L, int status, int envarg)
{
if (status == LUA_OK) {
- if (tvistab(L->base+envarg-1)) {
+ /*
+ ** Set environment table for top-level function.
+ ** Don't do this for non-native bytecode, which returns a prototype.
+ */
+ if (tvistab(L->base+envarg-1) && tvisfunc(L->top-1)) {
GCfunc *fn = funcV(L->top-1);
GCtab *t = tabV(L->base+envarg-1);
setgcref(fn->c.env, obj2gco(t));
diff --git a/src/deps/src/luajit/src/lib_jit.c b/src/deps/src/luajit/src/lib_jit.c
index db1662102..d1f0213ae 100644
--- a/src/deps/src/luajit/src/lib_jit.c
+++ b/src/deps/src/luajit/src/lib_jit.c
@@ -221,24 +221,6 @@ LJLIB_PUSH(top-2) LJLIB_SET(version)
/* -- Reflection API for Lua functions ------------------------------------ */
-/* Return prototype of first argument (Lua function or prototype object) */
-static GCproto *check_Lproto(lua_State *L, int nolua)
-{
- TValue *o = L->base;
- if (L->top > o) {
- if (tvisproto(o)) {
- return protoV(o);
- } else if (tvisfunc(o)) {
- if (isluafunc(funcV(o)))
- return funcproto(funcV(o));
- else if (nolua)
- return NULL;
- }
- }
- lj_err_argt(L, 1, LUA_TFUNCTION);
- return NULL; /* unreachable */
-}
-
static void setintfield(lua_State *L, GCtab *t, const char *name, int32_t val)
{
setintV(lj_tab_setstr(L, t, lj_str_newz(L, name)), val);
@@ -247,7 +229,7 @@ static void setintfield(lua_State *L, GCtab *t, const char *name, int32_t val)
/* local info = jit.util.funcinfo(func [,pc]) */
LJLIB_CF(jit_util_funcinfo)
{
- GCproto *pt = check_Lproto(L, 1);
+ GCproto *pt = lj_lib_checkLproto(L, 1, 1);
if (pt) {
BCPos pc = (BCPos)lj_lib_optint(L, 2, 0);
GCtab *t;
@@ -289,7 +271,7 @@ LJLIB_CF(jit_util_funcinfo)
/* local ins, m = jit.util.funcbc(func, pc) */
LJLIB_CF(jit_util_funcbc)
{
- GCproto *pt = check_Lproto(L, 0);
+ GCproto *pt = lj_lib_checkLproto(L, 1, 0);
BCPos pc = (BCPos)lj_lib_checkint(L, 2);
int lineinfo = lj_lib_optint(L, 3, 0);
if (pc < pt->sizebc) {
@@ -312,7 +294,7 @@ LJLIB_CF(jit_util_funcbc)
/* local k = jit.util.funck(func, idx) */
LJLIB_CF(jit_util_funck)
{
- GCproto *pt = check_Lproto(L, 0);
+ GCproto *pt = lj_lib_checkLproto(L, 1, 0);
ptrdiff_t idx = (ptrdiff_t)lj_lib_checkint(L, 2);
if (idx >= 0) {
if (idx < (ptrdiff_t)pt->sizekn) {
@@ -332,7 +314,7 @@ LJLIB_CF(jit_util_funck)
/* local name = jit.util.funcuvname(func, idx) */
LJLIB_CF(jit_util_funcuvname)
{
- GCproto *pt = check_Lproto(L, 0);
+ GCproto *pt = lj_lib_checkLproto(L, 1, 0);
uint32_t idx = (uint32_t)lj_lib_checkint(L, 2);
if (idx < pt->sizeuv) {
setstrV(L, L->top-1, lj_str_newz(L, lj_debug_uvname(pt, idx)));
diff --git a/src/deps/src/luajit/src/lib_string.c b/src/deps/src/luajit/src/lib_string.c
index 29bcb8fed..255689ced 100644
--- a/src/deps/src/luajit/src/lib_string.c
+++ b/src/deps/src/luajit/src/lib_string.c
@@ -122,11 +122,25 @@ static int writer_buf(lua_State *L, const void *p, size_t size, void *sb)
LJLIB_CF(string_dump)
{
- GCfunc *fn = lj_lib_checkfunc(L, 1);
- int strip = L->base+1 < L->top && tvistruecond(L->base+1);
- SBuf *sb = lj_buf_tmp_(L); /* Assumes lj_bcwrite() doesn't use tmpbuf. */
+ GCproto *pt = lj_lib_checkLproto(L, 1, 1);
+ uint32_t flags = 0;
+ SBuf *sb;
+ TValue *o = L->base+1;
+ if (o < L->top) {
+ if (tvisstr(o)) {
+ const char *mode = strVdata(o);
+ char c;
+ while ((c = *mode++)) {
+ if (c == 's') flags |= BCDUMP_F_STRIP;
+ if (c == 'd') flags |= BCDUMP_F_DETERMINISTIC;
+ }
+ } else if (tvistruecond(o)) {
+ flags |= BCDUMP_F_STRIP;
+ }
+ }
+ sb = lj_buf_tmp_(L); /* Assumes lj_bcwrite() doesn't use tmpbuf. */
L->top = L->base+1;
- if (!isluafunc(fn) || lj_bcwrite(L, funcproto(fn), writer_buf, sb, strip))
+ if (!pt || lj_bcwrite(L, pt, writer_buf, sb, flags))
lj_err_caller(L, LJ_ERR_STRDUMP);
setstrV(L, L->top-1, lj_buf_str(L, sb));
lj_gc_check(L);
diff --git a/src/deps/src/luajit/src/lj_api.c b/src/deps/src/luajit/src/lj_api.c
index 689585109..00fc0f1d4 100644
--- a/src/deps/src/luajit/src/lj_api.c
+++ b/src/deps/src/luajit/src/lj_api.c
@@ -1052,6 +1052,7 @@ LUA_API int lua_setmetatable(lua_State *L, int idx)
/* Flush cache, since traces specialize to basemt. But not during __gc. */
if (lj_trace_flushall(L))
lj_err_caller(L, LJ_ERR_NOGCMM);
+ o = index2adr(L, idx); /* Stack may have been reallocated. */
if (tvisbool(o)) {
/* NOBARRIER: basemt is a GC root. */
setgcref(basemt_it(g, LJ_TTRUE), obj2gco(mt));
diff --git a/src/deps/src/luajit/src/lj_asm_arm.h b/src/deps/src/luajit/src/lj_asm_arm.h
index 348cd79f8..bd5fbeb18 100644
--- a/src/deps/src/luajit/src/lj_asm_arm.h
+++ b/src/deps/src/luajit/src/lj_asm_arm.h
@@ -2042,11 +2042,12 @@ static void asm_stack_restore(ASMState *as, SnapShot *snap)
SnapEntry *map = &as->T->snapmap[snap->mapofs];
SnapEntry *flinks = &as->T->snapmap[snap_nextofs(as->T, snap)-1];
MSize n, nent = snap->nent;
+ int32_t bias = 0;
/* Store the value of all modified slots to the Lua stack. */
for (n = 0; n < nent; n++) {
SnapEntry sn = map[n];
BCReg s = snap_slot(sn);
- int32_t ofs = 8*((int32_t)s-1);
+ int32_t ofs = 8*((int32_t)s-1) - bias;
IRRef ref = snap_ref(sn);
IRIns *ir = IR(ref);
if ((sn & SNAP_NORESTORE))
@@ -2065,6 +2066,12 @@ static void asm_stack_restore(ASMState *as, SnapShot *snap)
emit_lso(as, ARMI_STR, tmp, RID_BASE, ofs+4);
#else
Reg src = ra_alloc1(as, ref, RSET_FPR);
+ if (LJ_UNLIKELY(ofs < -1020 || ofs > 1020)) {
+ int32_t adj = ofs & 0xffffff00; /* K12-friendly. */
+ bias += adj;
+ ofs -= adj;
+ emit_addptr(as, RID_BASE, -adj);
+ }
emit_vlso(as, ARMI_VSTR_D, src, RID_BASE, ofs);
#endif
} else {
@@ -2093,6 +2100,7 @@ static void asm_stack_restore(ASMState *as, SnapShot *snap)
}
checkmclim(as);
}
+ emit_addptr(as, RID_BASE, bias);
lj_assertA(map + nent == flinks, "inconsistent frames in snapshot");
}
diff --git a/src/deps/src/luajit/src/lj_asm_mips.h b/src/deps/src/luajit/src/lj_asm_mips.h
index d4e40c912..5b83e34d0 100644
--- a/src/deps/src/luajit/src/lj_asm_mips.h
+++ b/src/deps/src/luajit/src/lj_asm_mips.h
@@ -653,11 +653,11 @@ static void asm_conv(ASMState *as, IRIns *ir)
rset_exclude(RSET_GPR, dest));
emit_fg(as, MIPSI_TRUNC_L_D, tmp, left); /* Delay slot. */
#if !LJ_TARGET_MIPSR6
- emit_branch(as, MIPSI_BC1T, 0, 0, l_end);
- emit_fgh(as, MIPSI_C_OLT_D, 0, left, tmp);
+ emit_branch(as, MIPSI_BC1T, 0, 0, l_end);
+ emit_fgh(as, MIPSI_C_OLT_D, 0, left, tmp);
#else
- emit_branch(as, MIPSI_BC1NEZ, 0, (left&31), l_end);
- emit_fgh(as, MIPSI_CMP_LT_D, left, left, tmp);
+ emit_branch(as, MIPSI_BC1NEZ, 0, (tmp&31), l_end);
+ emit_fgh(as, MIPSI_CMP_LT_D, tmp, left, tmp);
#endif
emit_lsptr(as, MIPSI_LDC1, (tmp & 31),
(void *)&as->J->k64[LJ_K64_2P63],
@@ -670,11 +670,11 @@ static void asm_conv(ASMState *as, IRIns *ir)
rset_exclude(RSET_GPR, dest));
emit_fg(as, MIPSI_TRUNC_L_S, tmp, left); /* Delay slot. */
#if !LJ_TARGET_MIPSR6
- emit_branch(as, MIPSI_BC1T, 0, 0, l_end);
- emit_fgh(as, MIPSI_C_OLT_S, 0, left, tmp);
+ emit_branch(as, MIPSI_BC1T, 0, 0, l_end);
+ emit_fgh(as, MIPSI_C_OLT_S, 0, left, tmp);
#else
- emit_branch(as, MIPSI_BC1NEZ, 0, (left&31), l_end);
- emit_fgh(as, MIPSI_CMP_LT_S, left, left, tmp);
+ emit_branch(as, MIPSI_BC1NEZ, 0, (tmp&31), l_end);
+ emit_fgh(as, MIPSI_CMP_LT_S, tmp, left, tmp);
#endif
emit_lsptr(as, MIPSI_LWC1, (tmp & 31),
(void *)&as->J->k32[LJ_K32_2P63],
@@ -690,8 +690,8 @@ static void asm_conv(ASMState *as, IRIns *ir)
MIPSIns mi = irt_is64(ir->t) ?
(st == IRT_NUM ? MIPSI_TRUNC_L_D : MIPSI_TRUNC_L_S) :
(st == IRT_NUM ? MIPSI_TRUNC_W_D : MIPSI_TRUNC_W_S);
- emit_tg(as, irt_is64(ir->t) ? MIPSI_DMFC1 : MIPSI_MFC1, dest, left);
- emit_fg(as, mi, left, left);
+ emit_tg(as, irt_is64(ir->t) ? MIPSI_DMFC1 : MIPSI_MFC1, dest, tmp);
+ emit_fg(as, mi, tmp, left);
#endif
}
}
diff --git a/src/deps/src/luajit/src/lj_bcdump.h b/src/deps/src/luajit/src/lj_bcdump.h
index 6ba71e252..3e56e39c6 100644
--- a/src/deps/src/luajit/src/lj_bcdump.h
+++ b/src/deps/src/luajit/src/lj_bcdump.h
@@ -46,6 +46,8 @@
#define BCDUMP_F_KNOWN (BCDUMP_F_FR2*2-1)
+#define BCDUMP_F_DETERMINISTIC 0x80000000
+
/* Type codes for the GC constants of a prototype. Plus length for strings. */
enum {
BCDUMP_KGC_CHILD, BCDUMP_KGC_TAB, BCDUMP_KGC_I64, BCDUMP_KGC_U64,
@@ -61,7 +63,7 @@ enum {
/* -- Bytecode reader/writer ---------------------------------------------- */
LJ_FUNC int lj_bcwrite(lua_State *L, GCproto *pt, lua_Writer writer,
- void *data, int strip);
+ void *data, uint32_t flags);
LJ_FUNC GCproto *lj_bcread_proto(LexState *ls);
LJ_FUNC GCproto *lj_bcread(LexState *ls);
diff --git a/src/deps/src/luajit/src/lj_bcread.c b/src/deps/src/luajit/src/lj_bcread.c
index c98c0d423..637ef0679 100644
--- a/src/deps/src/luajit/src/lj_bcread.c
+++ b/src/deps/src/luajit/src/lj_bcread.c
@@ -281,8 +281,11 @@ static void bcread_knum(LexState *ls, GCproto *pt, MSize sizekn)
static void bcread_bytecode(LexState *ls, GCproto *pt, MSize sizebc)
{
BCIns *bc = proto_bc(pt);
- bc[0] = BCINS_AD((pt->flags & PROTO_VARARG) ? BC_FUNCV : BC_FUNCF,
- pt->framesize, 0);
+ BCIns op;
+ if (ls->fr2 != LJ_FR2) op = BC_NOT; /* Mark non-native prototype. */
+ else if ((pt->flags & PROTO_VARARG)) op = BC_FUNCV;
+ else op = BC_FUNCF;
+ bc[0] = BCINS_AD(op, pt->framesize, 0);
bcread_block(ls, bc+1, (sizebc-1)*(MSize)sizeof(BCIns));
/* Swap bytecode instructions if the endianess differs. */
if (bcread_swap(ls)) {
@@ -395,7 +398,7 @@ static int bcread_header(LexState *ls)
bcread_byte(ls) != BCDUMP_VERSION) return 0;
bcread_flags(ls) = flags = bcread_uleb128(ls);
if ((flags & ~(BCDUMP_F_KNOWN)) != 0) return 0;
- if ((flags & BCDUMP_F_FR2) != LJ_FR2*BCDUMP_F_FR2) return 0;
+ if ((flags & BCDUMP_F_FR2) != (uint32_t)ls->fr2*BCDUMP_F_FR2) return 0;
if ((flags & BCDUMP_F_FFI)) {
#if LJ_HASFFI
lua_State *L = ls->L;
diff --git a/src/deps/src/luajit/src/lj_bcwrite.c b/src/deps/src/luajit/src/lj_bcwrite.c
index dd9694135..ddfa46c56 100644
--- a/src/deps/src/luajit/src/lj_bcwrite.c
+++ b/src/deps/src/luajit/src/lj_bcwrite.c
@@ -27,7 +27,9 @@ typedef struct BCWriteCtx {
GCproto *pt; /* Root prototype. */
lua_Writer wfunc; /* Writer callback. */
void *wdata; /* Writer callback data. */
- int strip; /* Strip debug info. */
+ TValue **heap; /* Heap used for deterministic sorting. */
+ uint32_t heapsz; /* Size of heap. */
+ uint32_t flags; /* BCDUMP_F_* flags. */
int status; /* Status from writer callback. */
#ifdef LUA_USE_ASSERT
global_State *g;
@@ -76,6 +78,75 @@ static void bcwrite_ktabk(BCWriteCtx *ctx, cTValue *o, int narrow)
ctx->sb.w = p;
}
+/* Compare two template table keys. */
+static LJ_AINLINE int bcwrite_ktabk_lt(TValue *a, TValue *b)
+{
+ uint32_t at = itype(a), bt = itype(b);
+ if (at != bt) { /* This also handles false and true keys. */
+ return at < bt;
+ } else if (at == LJ_TSTR) {
+ return lj_str_cmp(strV(a), strV(b)) < 0;
+ } else {
+ return a->u64 < b->u64; /* This works for numbers and integers. */
+ }
+}
+
+/* Insert key into a sorted heap. */
+static void bcwrite_ktabk_heap_insert(TValue **heap, MSize idx, MSize end,
+ TValue *key)
+{
+ MSize child;
+ while ((child = idx * 2 + 1) < end) {
+ /* Find lower of the two children. */
+ TValue *c0 = heap[child];
+ if (child + 1 < end) {
+ TValue *c1 = heap[child + 1];
+ if (bcwrite_ktabk_lt(c1, c0)) {
+ c0 = c1;
+ child++;
+ }
+ }
+ if (bcwrite_ktabk_lt(key, c0)) break; /* Key lower? Found our position. */
+ heap[idx] = c0; /* Move lower child up. */
+ idx = child; /* Descend. */
+ }
+ heap[idx] = key; /* Insert key here. */
+}
+
+/* Resize heap, dropping content. */
+static void bcwrite_heap_resize(BCWriteCtx *ctx, uint32_t nsz)
+{
+ lua_State *L = sbufL(&ctx->sb);
+ if (ctx->heapsz) {
+ lj_mem_freevec(G(L), ctx->heap, ctx->heapsz, TValue *);
+ ctx->heapsz = 0;
+ }
+ if (nsz) {
+ ctx->heap = lj_mem_newvec(L, nsz, TValue *);
+ ctx->heapsz = nsz;
+ }
+}
+
+/* Write hash part of template table in sorted order. */
+static void bcwrite_ktab_sorted_hash(BCWriteCtx *ctx, Node *node, MSize nhash)
+{
+ TValue **heap = ctx->heap;
+ MSize i = nhash;
+ for (;; node--) { /* Build heap. */
+ if (!tvisnil(&node->key)) {
+ bcwrite_ktabk_heap_insert(heap, --i, nhash, &node->key);
+ if (i == 0) break;
+ }
+ }
+ do { /* Drain heap. */
+ TValue *key = heap[0]; /* Output lowest key from top. */
+ bcwrite_ktabk(ctx, key, 0);
+ bcwrite_ktabk(ctx, (TValue *)((char *)key - offsetof(Node, key)), 1);
+ key = heap[--nhash]; /* Remove last key. */
+ bcwrite_ktabk_heap_insert(heap, 0, nhash, key); /* Re-insert. */
+ } while (nhash);
+}
+
/* Write a template table. */
static void bcwrite_ktab(BCWriteCtx *ctx, char *p, const GCtab *t)
{
@@ -92,7 +163,7 @@ static void bcwrite_ktab(BCWriteCtx *ctx, char *p, const GCtab *t)
MSize i, hmask = t->hmask;
Node *node = noderef(t->node);
for (i = 0; i <= hmask; i++)
- nhash += !tvisnil(&node[i].val);
+ nhash += !tvisnil(&node[i].key);
}
/* Write number of array slots and hash slots. */
p = lj_strfmt_wuleb128(p, narray);
@@ -105,14 +176,20 @@ static void bcwrite_ktab(BCWriteCtx *ctx, char *p, const GCtab *t)
bcwrite_ktabk(ctx, o, 1);
}
if (nhash) { /* Write hash entries. */
- MSize i = nhash;
Node *node = noderef(t->node) + t->hmask;
- for (;; node--)
- if (!tvisnil(&node->val)) {
- bcwrite_ktabk(ctx, &node->key, 0);
- bcwrite_ktabk(ctx, &node->val, 1);
- if (--i == 0) break;
- }
+ if ((ctx->flags & BCDUMP_F_DETERMINISTIC) && nhash > 1) {
+ if (ctx->heapsz < nhash)
+ bcwrite_heap_resize(ctx, t->hmask + 1);
+ bcwrite_ktab_sorted_hash(ctx, node, nhash);
+ } else {
+ MSize i = nhash;
+ for (;; node--)
+ if (!tvisnil(&node->key)) {
+ bcwrite_ktabk(ctx, &node->key, 0);
+ bcwrite_ktabk(ctx, &node->val, 1);
+ if (--i == 0) break;
+ }
+ }
}
}
@@ -269,7 +346,7 @@ static void bcwrite_proto(BCWriteCtx *ctx, GCproto *pt)
p = lj_strfmt_wuleb128(p, pt->sizekgc);
p = lj_strfmt_wuleb128(p, pt->sizekn);
p = lj_strfmt_wuleb128(p, pt->sizebc-1);
- if (!ctx->strip) {
+ if (!(ctx->flags & BCDUMP_F_STRIP)) {
if (proto_lineinfo(pt))
sizedbg = pt->sizept - (MSize)((char *)proto_lineinfo(pt) - (char *)pt);
p = lj_strfmt_wuleb128(p, sizedbg);
@@ -317,11 +394,10 @@ static void bcwrite_header(BCWriteCtx *ctx)
*p++ = BCDUMP_HEAD2;
*p++ = BCDUMP_HEAD3;
*p++ = BCDUMP_VERSION;
- *p++ = (ctx->strip ? BCDUMP_F_STRIP : 0) +
+ *p++ = (ctx->flags & (BCDUMP_F_STRIP | BCDUMP_F_FR2)) +
LJ_BE*BCDUMP_F_BE +
- ((ctx->pt->flags & PROTO_FFI) ? BCDUMP_F_FFI : 0) +
- LJ_FR2*BCDUMP_F_FR2;
- if (!ctx->strip) {
+ ((ctx->pt->flags & PROTO_FFI) ? BCDUMP_F_FFI : 0);
+ if (!(ctx->flags & BCDUMP_F_STRIP)) {
p = lj_strfmt_wuleb128(p, len);
p = lj_buf_wmem(p, name, len);
}
@@ -352,14 +428,16 @@ static TValue *cpwriter(lua_State *L, lua_CFunction dummy, void *ud)
/* Write bytecode for a prototype. */
int lj_bcwrite(lua_State *L, GCproto *pt, lua_Writer writer, void *data,
- int strip)
+ uint32_t flags)
{
BCWriteCtx ctx;
int status;
ctx.pt = pt;
ctx.wfunc = writer;
ctx.wdata = data;
- ctx.strip = strip;
+ ctx.heapsz = 0;
+ if ((bc_op(proto_bc(pt)[0]) != BC_NOT) == LJ_FR2) flags |= BCDUMP_F_FR2;
+ ctx.flags = flags;
ctx.status = 0;
#ifdef LUA_USE_ASSERT
ctx.g = G(L);
@@ -368,6 +446,7 @@ int lj_bcwrite(lua_State *L, GCproto *pt, lua_Writer writer, void *data,
status = lj_vm_cpcall(L, NULL, &ctx, cpwriter);
if (status == 0) status = ctx.status;
lj_buf_free(G(sbufL(&ctx.sb)), &ctx.sb);
+ bcwrite_heap_resize(&ctx, 0);
return status;
}
diff --git a/src/deps/src/luajit/src/lj_debug.c b/src/deps/src/luajit/src/lj_debug.c
index 682d64140..3aa799aa3 100644
--- a/src/deps/src/luajit/src/lj_debug.c
+++ b/src/deps/src/luajit/src/lj_debug.c
@@ -64,6 +64,7 @@ static BCPos debug_framepc(lua_State *L, GCfunc *fn, cTValue *nextframe)
if (cf == NULL || (char *)cframe_pc(cf) == (char *)cframe_L(cf))
return NO_BCPOS;
ins = cframe_pc(cf); /* Only happens during error/hook handling. */
+ if (!ins) return NO_BCPOS;
} else {
if (frame_islua(nextframe)) {
ins = frame_pc(nextframe);
diff --git a/src/deps/src/luajit/src/lj_err.c b/src/deps/src/luajit/src/lj_err.c
index 16f633073..413cc6b02 100644
--- a/src/deps/src/luajit/src/lj_err.c
+++ b/src/deps/src/luajit/src/lj_err.c
@@ -822,7 +822,14 @@ LJ_NOINLINE void lj_err_mem(lua_State *L)
TValue *base = tvref(G(L)->jit_base);
if (base) L->base = base;
}
- if (curr_funcisL(L)) L->top = curr_topL(L);
+ if (curr_funcisL(L)) {
+ L->top = curr_topL(L);
+ if (LJ_UNLIKELY(L->top > tvref(L->maxstack))) {
+ /* The current Lua frame violates the stack. Replace it with a dummy. */
+ L->top = L->base;
+ setframe_gc(L->base - 1 - LJ_FR2, obj2gco(L), LJ_TTHREAD);
+ }
+ }
setstrV(L, L->top++, lj_err_str(L, LJ_ERR_ERRMEM));
lj_err_throw(L, LUA_ERRMEM);
}
@@ -883,9 +890,11 @@ LJ_NOINLINE void LJ_FASTCALL lj_err_run(lua_State *L)
{
ptrdiff_t ef = (LJ_HASJIT && tvref(G(L)->jit_base)) ? 0 : finderrfunc(L);
if (ef) {
- TValue *errfunc = restorestack(L, ef);
- TValue *top = L->top;
+ TValue *errfunc, *top;
+ lj_state_checkstack(L, LUA_MINSTACK * 2); /* Might raise new error. */
lj_trace_abort(G(L));
+ errfunc = restorestack(L, ef);
+ top = L->top;
if (!tvisfunc(errfunc) || L->status == LUA_ERRERR) {
setstrV(L, top-1, lj_err_str(L, LJ_ERR_ERRERR));
lj_err_throw(L, LUA_ERRERR);
@@ -900,7 +909,15 @@ LJ_NOINLINE void LJ_FASTCALL lj_err_run(lua_State *L)
lj_err_throw(L, LUA_ERRRUN);
}
+/* Stack overflow error. */
+void LJ_FASTCALL lj_err_stkov(lua_State *L)
+{
+ lj_debug_addloc(L, err2msg(LJ_ERR_STKOV), L->base-1, NULL);
+ lj_err_run(L);
+}
+
#if LJ_HASJIT
+/* Rethrow error after doing a trace exit. */
LJ_NOINLINE void LJ_FASTCALL lj_err_trace(lua_State *L, int errcode)
{
if (errcode == LUA_ERRRUN)
diff --git a/src/deps/src/luajit/src/lj_err.h b/src/deps/src/luajit/src/lj_err.h
index 8768fefdc..67686cb77 100644
--- a/src/deps/src/luajit/src/lj_err.h
+++ b/src/deps/src/luajit/src/lj_err.h
@@ -23,6 +23,7 @@ LJ_DATA const char *lj_err_allmsg;
LJ_FUNC GCstr *lj_err_str(lua_State *L, ErrMsg em);
LJ_FUNCA_NORET void LJ_FASTCALL lj_err_throw(lua_State *L, int errcode);
LJ_FUNC_NORET void lj_err_mem(lua_State *L);
+LJ_FUNC_NORET void LJ_FASTCALL lj_err_stkov(lua_State *L);
LJ_FUNC_NORET void LJ_FASTCALL lj_err_run(lua_State *L);
#if LJ_HASJIT
LJ_FUNCA_NORET void LJ_FASTCALL lj_err_trace(lua_State *L, int errcode);
diff --git a/src/deps/src/luajit/src/lj_ffrecord.c b/src/deps/src/luajit/src/lj_ffrecord.c
index c45e0fde7..396183a07 100644
--- a/src/deps/src/luajit/src/lj_ffrecord.c
+++ b/src/deps/src/luajit/src/lj_ffrecord.c
@@ -99,6 +99,14 @@ static ptrdiff_t results_wanted(jit_State *J)
return -1;
}
+static TValue *rec_stop_stitch_cp(lua_State *L, lua_CFunction dummy, void *ud)
+{
+ jit_State *J = (jit_State *)ud;
+ lj_record_stop(J, LJ_TRLINK_STITCH, 0);
+ UNUSED(L); UNUSED(dummy);
+ return NULL;
+}
+
/* Trace stitching: add continuation below frame to start a new trace. */
static void recff_stitch(jit_State *J)
{
@@ -109,10 +117,7 @@ static void recff_stitch(jit_State *J)
TValue *nframe = base + 1 + LJ_FR2;
const BCIns *pc = frame_pc(base-1);
TValue *pframe = frame_prevl(base-1);
-
- /* Check for this now. Throwing in lj_record_stop messes up the stack. */
- if (J->cur.nsnap >= (MSize)J->param[JIT_P_maxsnap])
- lj_trace_err(J, LJ_TRERR_SNAPOV);
+ int errcode;
/* Move func + args up in Lua stack and insert continuation. */
memmove(&base[1], &base[-1-LJ_FR2], sizeof(TValue)*nslot);
@@ -137,13 +142,19 @@ static void recff_stitch(jit_State *J)
J->baseslot += 2 + LJ_FR2;
J->framedepth++;
- lj_record_stop(J, LJ_TRLINK_STITCH, 0);
+ errcode = lj_vm_cpcall(L, NULL, J, rec_stop_stitch_cp);
/* Undo Lua stack changes. */
memmove(&base[-1-LJ_FR2], &base[1], sizeof(TValue)*nslot);
setframe_pc(base-1, pc);
L->base -= 2 + LJ_FR2;
L->top -= 2 + LJ_FR2;
+
+ if (errcode) {
+ if (errcode == LUA_ERRRUN)
+ copyTV(L, L->top-1, L->top + (1 + LJ_FR2));
+ lj_err_throw(L, errcode); /* Propagate errors. */
+ }
}
/* Fallback handler for fast functions that are not recorded (yet). */
@@ -1205,6 +1216,12 @@ static void LJ_FASTCALL recff_buffer_method_set(jit_State *J, RecordFFData *rd)
if (tref_isstr(tr)) {
TRef trp = emitir(IRT(IR_STRREF, IRT_PGC), tr, lj_ir_kint(J, 0));
TRef len = emitir(IRTI(IR_FLOAD), tr, IRFL_STR_LEN);
+ IRIns *irp = IR(tref_ref(trp));
+ /* trp must point into the anchored obj, even after folding. */
+ if (irp->o == IR_STRREF)
+ tr = irp->op1;
+ else if (!tref_isk(tr))
+ trp = emitir(IRT(IR_ADD, IRT_PGC), tr, lj_ir_kintpgc(J, sizeof(GCstr)));
lj_ir_call(J, IRCALL_lj_bufx_set, trbuf, trp, len, tr);
#if LJ_HASFFI
} else if (tref_iscdata(tr)) {
@@ -1445,6 +1462,15 @@ static void LJ_FASTCALL recff_table_new(jit_State *J, RecordFFData *rd)
{
TRef tra = lj_opt_narrow_toint(J, J->base[0]);
TRef trh = lj_opt_narrow_toint(J, J->base[1]);
+ if (tref_isk(tra) && tref_isk(trh)) {
+ int32_t a = IR(tref_ref(tra))->i;
+ if (a < 0x7fff) {
+ uint32_t hbits = hsize2hbits(IR(tref_ref(trh))->i);
+ a = a > 0 ? a+1 : 0;
+ J->base[0] = emitir(IRTG(IR_TNEW, IRT_TAB), (uint32_t)a, hbits);
+ return;
+ }
+ }
J->base[0] = lj_ir_call(J, IRCALL_lj_tab_new_ah, tra, trh);
UNUSED(rd);
}
diff --git a/src/deps/src/luajit/src/lj_gc.c b/src/deps/src/luajit/src/lj_gc.c
index c3a0c258d..eebc751b2 100644
--- a/src/deps/src/luajit/src/lj_gc.c
+++ b/src/deps/src/luajit/src/lj_gc.c
@@ -108,6 +108,9 @@ static void gc_mark_start(global_State *g)
gc_markobj(g, tabref(mainthread(g)->env));
gc_marktv(g, &g->registrytv);
gc_mark_gcroot(g);
+#if LJ_HASFFI
+ if (ctype_ctsG(g)) gc_markobj(g, ctype_ctsG(g)->finalizer);
+#endif
g->gc.state = GCSpropagate;
}
diff --git a/src/deps/src/luajit/src/lj_gdbjit.c b/src/deps/src/luajit/src/lj_gdbjit.c
index e8a66635a..56094cf10 100644
--- a/src/deps/src/luajit/src/lj_gdbjit.c
+++ b/src/deps/src/luajit/src/lj_gdbjit.c
@@ -637,7 +637,7 @@ static void LJ_FASTCALL gdbjit_debugabbrev(GDBJITctx *ctx)
DUV(DW_AT_low_pc); DUV(DW_FORM_addr);
DUV(DW_AT_high_pc); DUV(DW_FORM_addr);
DUV(DW_AT_stmt_list); DUV(DW_FORM_data4);
- DB(0); DB(0);
+ DB(0); DB(0); DB(0);
ctx->p = p;
}
diff --git a/src/deps/src/luajit/src/lj_ir.h b/src/deps/src/luajit/src/lj_ir.h
index 6cec51dd3..939211ffb 100644
--- a/src/deps/src/luajit/src/lj_ir.h
+++ b/src/deps/src/luajit/src/lj_ir.h
@@ -385,6 +385,7 @@ typedef struct IRType1 { uint8_t irt; } IRType1;
#define irt_isu32(t) (irt_type(t) == IRT_U32)
#define irt_isi64(t) (irt_type(t) == IRT_I64)
#define irt_isu64(t) (irt_type(t) == IRT_U64)
+#define irt_isp32(t) (irt_type(t) == IRT_P32)
#define irt_isfp(t) (irt_isnum(t) || irt_isfloat(t))
#define irt_isinteger(t) (irt_typerange((t), IRT_I8, IRT_INT))
diff --git a/src/deps/src/luajit/src/lj_lex.c b/src/deps/src/luajit/src/lj_lex.c
index 61b04c4b6..bd81dc40e 100644
--- a/src/deps/src/luajit/src/lj_lex.c
+++ b/src/deps/src/luajit/src/lj_lex.c
@@ -411,6 +411,7 @@ int lj_lex_setup(lua_State *L, LexState *ls)
ls->linenumber = 1;
ls->lastline = 1;
ls->endmark = 0;
+ ls->fr2 = LJ_FR2; /* Generate native bytecode by default. */
lex_next(ls); /* Read-ahead first char. */
if (ls->c == 0xef && ls->p + 2 <= ls->pe && (uint8_t)ls->p[0] == 0xbb &&
(uint8_t)ls->p[1] == 0xbf) { /* Skip UTF-8 BOM (if buffered). */
diff --git a/src/deps/src/luajit/src/lj_lex.h b/src/deps/src/luajit/src/lj_lex.h
index e46fbd893..2ef7fc770 100644
--- a/src/deps/src/luajit/src/lj_lex.h
+++ b/src/deps/src/luajit/src/lj_lex.h
@@ -74,6 +74,7 @@ typedef struct LexState {
MSize sizebcstack; /* Size of bytecode stack. */
uint32_t level; /* Syntactical nesting level. */
int endmark; /* Trust bytecode end marker, even if not at EOF. */
+ int fr2; /* Generate bytecode for LJ_FR2 mode. */
} LexState;
LJ_FUNC int lj_lex_setup(lua_State *L, LexState *ls);
diff --git a/src/deps/src/luajit/src/lj_lib.c b/src/deps/src/luajit/src/lj_lib.c
index 06fc0dfd4..fa45c804b 100644
--- a/src/deps/src/luajit/src/lj_lib.c
+++ b/src/deps/src/luajit/src/lj_lib.c
@@ -62,6 +62,7 @@ static const uint8_t *lib_read_lfunc(lua_State *L, const uint8_t *p, GCtab *tab)
ls.pe = (const char *)~(uintptr_t)0;
ls.c = -1;
ls.level = (BCDUMP_F_STRIP|(LJ_BE*BCDUMP_F_BE));
+ ls.fr2 = LJ_FR2;
ls.chunkname = name;
pt = lj_bcread_proto(&ls);
pt->firstline = ~(BCLine)0;
@@ -266,6 +267,23 @@ GCfunc *lj_lib_checkfunc(lua_State *L, int narg)
return funcV(o);
}
+GCproto *lj_lib_checkLproto(lua_State *L, int narg, int nolua)
+{
+ TValue *o = L->base + narg-1;
+ if (L->top > o) {
+ if (tvisproto(o)) {
+ return protoV(o);
+ } else if (tvisfunc(o)) {
+ if (isluafunc(funcV(o)))
+ return funcproto(funcV(o));
+ else if (nolua)
+ return NULL;
+ }
+ }
+ lj_err_argt(L, narg, LUA_TFUNCTION);
+ return NULL; /* unreachable */
+}
+
GCtab *lj_lib_checktab(lua_State *L, int narg)
{
TValue *o = L->base + narg-1;
diff --git a/src/deps/src/luajit/src/lj_lib.h b/src/deps/src/luajit/src/lj_lib.h
index 1fb600ac5..93c98b895 100644
--- a/src/deps/src/luajit/src/lj_lib.h
+++ b/src/deps/src/luajit/src/lj_lib.h
@@ -42,6 +42,7 @@ LJ_FUNC lua_Number lj_lib_checknum(lua_State *L, int narg);
LJ_FUNC int32_t lj_lib_checkint(lua_State *L, int narg);
LJ_FUNC int32_t lj_lib_optint(lua_State *L, int narg, int32_t def);
LJ_FUNC GCfunc *lj_lib_checkfunc(lua_State *L, int narg);
+LJ_FUNC GCproto *lj_lib_checkLproto(lua_State *L, int narg, int nolua);
LJ_FUNC GCtab *lj_lib_checktab(lua_State *L, int narg);
LJ_FUNC GCtab *lj_lib_checktabornil(lua_State *L, int narg);
LJ_FUNC int lj_lib_checkopt(lua_State *L, int narg, int def, const char *lst);
diff --git a/src/deps/src/luajit/src/lj_load.c b/src/deps/src/luajit/src/lj_load.c
index 073044876..152ef6daa 100644
--- a/src/deps/src/luajit/src/lj_load.c
+++ b/src/deps/src/luajit/src/lj_load.c
@@ -34,14 +34,28 @@ static TValue *cpparser(lua_State *L, lua_CFunction dummy, void *ud)
UNUSED(dummy);
cframe_errfunc(L->cframe) = -1; /* Inherit error function. */
bc = lj_lex_setup(L, ls);
- if (ls->mode && !strchr(ls->mode, bc ? 'b' : 't')) {
- setstrV(L, L->top++, lj_err_str(L, LJ_ERR_XMODE));
- lj_err_throw(L, LUA_ERRSYNTAX);
+ if (ls->mode) {
+ int xmode = 1;
+ const char *mode = ls->mode;
+ char c;
+ while ((c = *mode++)) {
+ if (c == (bc ? 'b' : 't')) xmode = 0;
+ if (c == (LJ_FR2 ? 'W' : 'X')) ls->fr2 = !LJ_FR2;
+ }
+ if (xmode) {
+ setstrV(L, L->top++, lj_err_str(L, LJ_ERR_XMODE));
+ lj_err_throw(L, LUA_ERRSYNTAX);
+ }
}
pt = bc ? lj_bcread(ls) : lj_parse(ls);
- fn = lj_func_newL_empty(L, pt, tabref(L->env));
- /* Don't combine above/below into one statement. */
- setfuncV(L, L->top++, fn);
+ if (ls->fr2 == LJ_FR2) {
+ fn = lj_func_newL_empty(L, pt, tabref(L->env));
+ /* Don't combine above/below into one statement. */
+ setfuncV(L, L->top++, fn);
+ } else {
+ /* Non-native generation returns a dumpable, but non-runnable prototype. */
+ setprotoV(L, L->top++, pt);
+ }
return NULL;
}
@@ -159,9 +173,10 @@ LUALIB_API int luaL_loadstring(lua_State *L, const char *s)
LUA_API int lua_dump(lua_State *L, lua_Writer writer, void *data)
{
cTValue *o = L->top-1;
+ uint32_t flags = LJ_FR2*BCDUMP_F_FR2; /* Default mode for legacy C API. */
lj_checkapi(L->top > L->base, "top slot empty");
if (tvisfunc(o) && isluafunc(funcV(o)))
- return lj_bcwrite(L, funcproto(funcV(o)), writer, data, 0);
+ return lj_bcwrite(L, funcproto(funcV(o)), writer, data, flags);
else
return 1;
}
diff --git a/src/deps/src/luajit/src/lj_opt_mem.c b/src/deps/src/luajit/src/lj_opt_mem.c
index 6d77b7bc3..1fd7ce137 100644
--- a/src/deps/src/luajit/src/lj_opt_mem.c
+++ b/src/deps/src/luajit/src/lj_opt_mem.c
@@ -217,25 +217,23 @@ static TRef fwd_ahload(jit_State *J, IRRef xref)
}
ref = store->prev;
}
- if (ir->o == IR_TNEW && !irt_isnil(fins->t))
- return 0; /* Type instability in loop-carried dependency. */
- if (irt_ispri(fins->t)) {
- return TREF_PRI(irt_type(fins->t));
- } else if (irt_isnum(fins->t) || (LJ_DUALNUM && irt_isint(fins->t)) ||
- irt_isstr(fins->t)) {
+ /* Simplified here: let loop_unroll() figure out any type instability. */
+ if (ir->o == IR_TNEW) {
+ return TREF_NIL;
+ } else {
TValue keyv;
cTValue *tv;
IRIns *key = IR(xr->op2);
if (key->o == IR_KSLOT) key = IR(key->op1);
lj_ir_kvalue(J->L, &keyv, key);
tv = lj_tab_get(J->L, ir_ktab(IR(ir->op1)), &keyv);
- if (itype2irt(tv) != irt_type(fins->t))
- return 0; /* Type instability in loop-carried dependency. */
- if (irt_isnum(fins->t))
+ if (tvispri(tv))
+ return TREF_PRI(itype2irt(tv));
+ else if (tvisnum(tv))
return lj_ir_knum_u64(J, tv->u64);
- else if (LJ_DUALNUM && irt_isint(fins->t))
+ else if (tvisint(tv))
return lj_ir_kint(J, intV(tv));
- else
+ else if (tvisgcv(tv))
return lj_ir_kstr(J, strV(tv));
}
/* Othwerwise: don't intern as a constant. */
@@ -964,6 +962,8 @@ int lj_opt_fwd_wasnonnil(jit_State *J, IROpT loadop, IRRef xref)
if (skref == xkref || !irref_isk(skref) || !irref_isk(xkref))
return 0; /* A nil store with same const key or var key MAY alias. */
/* Different const keys CANNOT alias. */
+ } else if (irt_isp32(IR(skref)->t) != irt_isp32(IR(xkref)->t)) {
+ return 0; /* HREF and HREFK MAY alias. */
} /* Different key types CANNOT alias. */
} /* Other non-nil stores MAY alias. */
ref = store->prev;
diff --git a/src/deps/src/luajit/src/lj_parse.c b/src/deps/src/luajit/src/lj_parse.c
index b48ab5363..423ad29e0 100644
--- a/src/deps/src/luajit/src/lj_parse.c
+++ b/src/deps/src/luajit/src/lj_parse.c
@@ -667,19 +667,20 @@ static void bcemit_store(FuncState *fs, ExpDesc *var, ExpDesc *e)
/* Emit method lookup expression. */
static void bcemit_method(FuncState *fs, ExpDesc *e, ExpDesc *key)
{
- BCReg idx, func, obj = expr_toanyreg(fs, e);
+ BCReg idx, func, fr2, obj = expr_toanyreg(fs, e);
expr_free(fs, e);
func = fs->freereg;
- bcemit_AD(fs, BC_MOV, func+1+LJ_FR2, obj); /* Copy object to 1st argument. */
+ fr2 = fs->ls->fr2;
+ bcemit_AD(fs, BC_MOV, func+1+fr2, obj); /* Copy object to 1st argument. */
lj_assertFS(expr_isstrk(key), "bad usage");
idx = const_str(fs, key);
if (idx <= BCMAX_C) {
- bcreg_reserve(fs, 2+LJ_FR2);
+ bcreg_reserve(fs, 2+fr2);
bcemit_ABC(fs, BC_TGETS, func, obj, idx);
} else {
- bcreg_reserve(fs, 3+LJ_FR2);
- bcemit_AD(fs, BC_KSTR, func+2+LJ_FR2, idx);
- bcemit_ABC(fs, BC_TGETV, func, obj, func+2+LJ_FR2);
+ bcreg_reserve(fs, 3+fr2);
+ bcemit_AD(fs, BC_KSTR, func+2+fr2, idx);
+ bcemit_ABC(fs, BC_TGETV, func, obj, func+2+fr2);
fs->freereg--;
}
e->u.s.info = func;
@@ -1326,9 +1327,12 @@ static void fs_fixup_bc(FuncState *fs, GCproto *pt, BCIns *bc, MSize n)
{
BCInsLine *base = fs->bcbase;
MSize i;
+ BCIns op;
pt->sizebc = n;
- bc[0] = BCINS_AD((fs->flags & PROTO_VARARG) ? BC_FUNCV : BC_FUNCF,
- fs->framesize, 0);
+ if (fs->ls->fr2 != LJ_FR2) op = BC_NOT; /* Mark non-native prototype. */
+ else if ((fs->flags & PROTO_VARARG)) op = BC_FUNCV;
+ else op = BC_FUNCF;
+ bc[0] = BCINS_AD(op, fs->framesize, 0);
for (i = 1; i < n; i++)
bc[i] = base[i].ins;
}
@@ -1937,11 +1941,11 @@ static void parse_args(LexState *ls, ExpDesc *e)
lj_assertFS(e->k == VNONRELOC, "bad expr type %d", e->k);
base = e->u.s.info; /* Base register for call. */
if (args.k == VCALL) {
- ins = BCINS_ABC(BC_CALLM, base, 2, args.u.s.aux - base - 1 - LJ_FR2);
+ ins = BCINS_ABC(BC_CALLM, base, 2, args.u.s.aux - base - 1 - ls->fr2);
} else {
if (args.k != VVOID)
expr_tonextreg(fs, &args);
- ins = BCINS_ABC(BC_CALL, base, 2, fs->freereg - base - LJ_FR2);
+ ins = BCINS_ABC(BC_CALL, base, 2, fs->freereg - base - ls->fr2);
}
expr_init(e, VCALL, bcemit_INS(fs, ins));
e->u.s.aux = base;
@@ -1981,7 +1985,7 @@ static void expr_primary(LexState *ls, ExpDesc *v)
parse_args(ls, v);
} else if (ls->tok == '(' || ls->tok == TK_string || ls->tok == '{') {
expr_tonextreg(fs, v);
- if (LJ_FR2) bcreg_reserve(fs, 1);
+ if (ls->fr2) bcreg_reserve(fs, 1);
parse_args(ls, v);
} else {
break;
@@ -2566,7 +2570,7 @@ static void parse_for_iter(LexState *ls, GCstr *indexname)
line = ls->linenumber;
assign_adjust(ls, 3, expr_list(ls, &e), &e);
/* The iterator needs another 3 [4] slots (func [pc] | state ctl). */
- bcreg_bump(fs, 3+LJ_FR2);
+ bcreg_bump(fs, 3+ls->fr2);
isnext = (nvars <= 5 && predict_next(ls, fs, exprpc));
var_add(ls, 3); /* Hidden control variables. */
lex_check(ls, TK_do);
diff --git a/src/deps/src/luajit/src/lj_record.c b/src/deps/src/luajit/src/lj_record.c
index 1b66df29a..5f36ab883 100644
--- a/src/deps/src/luajit/src/lj_record.c
+++ b/src/deps/src/luajit/src/lj_record.c
@@ -903,6 +903,7 @@ void lj_record_ret(jit_State *J, BCReg rbase, ptrdiff_t gotresults)
{
TValue *frame = J->L->base - 1;
ptrdiff_t i;
+ BCReg baseadj = 0;
for (i = 0; i < gotresults; i++)
(void)getslot(J, rbase+i); /* Ensure all results have a reference. */
while (frame_ispcall(frame)) { /* Immediately resolve pcall() returns. */
@@ -911,6 +912,7 @@ void lj_record_ret(jit_State *J, BCReg rbase, ptrdiff_t gotresults)
lj_trace_err(J, LJ_TRERR_NYIRETL);
lj_assertJ(J->baseslot > 1+LJ_FR2, "bad baseslot for return");
gotresults++;
+ baseadj += cbase;
rbase += cbase;
J->baseslot -= (BCReg)cbase;
J->base -= cbase;
@@ -935,6 +937,7 @@ void lj_record_ret(jit_State *J, BCReg rbase, ptrdiff_t gotresults)
if (--J->framedepth < 0) /* NYI: return of vararg func to lower frame. */
lj_trace_err(J, LJ_TRERR_NYIRETL);
lj_assertJ(J->baseslot > 1+LJ_FR2, "bad baseslot for return");
+ baseadj += cbase;
rbase += cbase;
J->baseslot -= (BCReg)cbase;
J->base -= cbase;
@@ -948,7 +951,7 @@ void lj_record_ret(jit_State *J, BCReg rbase, ptrdiff_t gotresults)
if ((pt->flags & PROTO_NOJIT))
lj_trace_err(J, LJ_TRERR_CJITOFF);
if (J->framedepth == 0 && J->pt && frame == J->L->base - 1) {
- if (check_downrec_unroll(J, pt)) {
+ if (!J->cur.root && check_downrec_unroll(J, pt)) {
J->maxslot = (BCReg)(rbase + gotresults);
lj_snap_purge(J);
lj_record_stop(J, LJ_TRLINK_DOWNREC, J->cur.traceno); /* Down-rec. */
@@ -970,6 +973,8 @@ void lj_record_ret(jit_State *J, BCReg rbase, ptrdiff_t gotresults)
lj_trace_err(J, LJ_TRERR_LLEAVE);
} else if (J->needsnap) { /* Tailcalled to ff with side-effects. */
lj_trace_err(J, LJ_TRERR_NYIRETL); /* No way to insert snapshot here. */
+ } else if (1 + pt->framesize >= LJ_MAX_JSLOTS) {
+ lj_trace_err(J, LJ_TRERR_STACKOV);
} else { /* Return to lower frame. Guard for the target we return to. */
TRef trpt = lj_ir_kgc(J, obj2gco(pt), IRT_PROTO);
TRef trpc = lj_ir_kptr(J, (void *)frame_pc(frame));
@@ -1003,7 +1008,8 @@ void lj_record_ret(jit_State *J, BCReg rbase, ptrdiff_t gotresults)
BCReg bslot = bc_b(*(frame_contpc(frame)-1));
TRef tr = gotresults ? J->base[cbase+rbase] : TREF_NIL;
if (bslot != J->maxslot) { /* Concatenate the remainder. */
- TValue *b = J->L->base, save; /* Simulate lower frame and result. */
+ /* Simulate lower frame and result. */
+ TValue *b = J->L->base - baseadj, save;
/* Can't handle MM_concat + CALLT + fast func side-effects. */
if (J->postproc != LJ_POST_NONE)
lj_trace_err(J, LJ_TRERR_NYIRETL);
@@ -1016,7 +1022,7 @@ void lj_record_ret(jit_State *J, BCReg rbase, ptrdiff_t gotresults)
J->L->base = b - cbase;
tr = rec_cat(J, bslot, cbase-(2<L->base + cbase; /* Undo. */
- J->L->base = b;
+ J->L->base = b + baseadj;
copyTV(J->L, b-(2<o, ir_k64(ir)->u64);
case IR_KPTR: return lj_ir_kptr(J, ir_kptr(ir)); /* Continuation. */
+ case IR_KNULL: return lj_ir_knull(J, irt_type(ir->t));
default: lj_assertJ(0, "bad IR constant op %d", ir->o); return TREF_NIL;
}
}
@@ -557,13 +558,15 @@ void lj_snap_replay(jit_State *J, GCtrace *T)
IRRef refp = snap_ref(sn);
IRIns *ir = &T->ir[refp];
if (regsp_reg(ir->r) == RID_SUNK) {
+ uint8_t m;
if (J->slot[snap_slot(sn)] != snap_slot(sn)) continue;
pass23 = 1;
lj_assertJ(ir->o == IR_TNEW || ir->o == IR_TDUP ||
ir->o == IR_CNEW || ir->o == IR_CNEWI,
"sunk parent IR %04d has bad op %d", refp - REF_BIAS, ir->o);
- if (ir->op1 >= T->nk) snap_pref(J, T, map, nent, seen, ir->op1);
- if (ir->op2 >= T->nk) snap_pref(J, T, map, nent, seen, ir->op2);
+ m = lj_ir_mode[ir->o];
+ if (irm_op1(m) == IRMref) snap_pref(J, T, map, nent, seen, ir->op1);
+ if (irm_op2(m) == IRMref) snap_pref(J, T, map, nent, seen, ir->op2);
if (LJ_HASFFI && ir->o == IR_CNEWI) {
if (LJ_32 && refp+1 < T->nins && (ir+1)->o == IR_HIOP)
snap_pref(J, T, map, nent, seen, (ir+1)->op2);
@@ -591,14 +594,16 @@ void lj_snap_replay(jit_State *J, GCtrace *T)
IRIns *ir = &T->ir[refp];
if (regsp_reg(ir->r) == RID_SUNK) {
TRef op1, op2;
+ uint8_t m;
if (J->slot[snap_slot(sn)] != snap_slot(sn)) { /* De-dup allocs. */
J->slot[snap_slot(sn)] = J->slot[J->slot[snap_slot(sn)]];
continue;
}
op1 = ir->op1;
- if (op1 >= T->nk) op1 = snap_pref(J, T, map, nent, seen, op1);
+ m = lj_ir_mode[ir->o];
+ if (irm_op1(m) == IRMref) op1 = snap_pref(J, T, map, nent, seen, op1);
op2 = ir->op2;
- if (op2 >= T->nk) op2 = snap_pref(J, T, map, nent, seen, op2);
+ if (irm_op2(m) == IRMref) op2 = snap_pref(J, T, map, nent, seen, op2);
if (LJ_HASFFI && ir->o == IR_CNEWI) {
if (LJ_32 && refp+1 < T->nins && (ir+1)->o == IR_HIOP) {
lj_needsplit(J); /* Emit joining HIOP. */
@@ -624,9 +629,25 @@ void lj_snap_replay(jit_State *J, GCtrace *T)
if (irr->o == IR_HREFK || irr->o == IR_AREF) {
IRIns *irf = &T->ir[irr->op1];
tmp = emitir(irf->ot, tmp, irf->op2);
+ } else if (irr->o == IR_NEWREF) {
+ IRRef allocref = tref_ref(tr);
+ IRRef keyref = tref_ref(key);
+ IRRef newref_ref = J->chain[IR_NEWREF];
+ IRIns *newref = &J->cur.ir[newref_ref];
+ lj_assertJ(irref_isk(keyref),
+ "sunk store for parent IR %04d with bad key %04d",
+ refp - REF_BIAS, keyref - REF_BIAS);
+ if (newref_ref > allocref && newref->op2 == keyref) {
+ lj_assertJ(newref->op1 == allocref,
+ "sunk store for parent IR %04d with bad tab %04d",
+ refp - REF_BIAS, allocref - REF_BIAS);
+ tmp = newref_ref;
+ goto skip_newref;
+ }
}
}
tmp = emitir(irr->ot, tmp, key);
+ skip_newref:
val = snap_pref(J, T, map, nent, seen, irs->op2);
if (val == 0) {
IRIns *irc = &T->ir[irs->op2];
@@ -882,9 +903,13 @@ static void snap_unsink(jit_State *J, GCtrace *T, ExitState *ex,
if (irk->o == IR_FREF) {
switch (irk->op2) {
case IRFL_TAB_META:
- snap_restoreval(J, T, ex, snapno, rfilt, irs->op2, &tmp);
- /* NOBARRIER: The table is new (marked white). */
- setgcref(t->metatable, obj2gco(tabV(&tmp)));
+ if (T->ir[irs->op2].o == IR_KNULL) {
+ setgcrefnull(t->metatable);
+ } else {
+ snap_restoreval(J, T, ex, snapno, rfilt, irs->op2, &tmp);
+ /* NOBARRIER: The table is new (marked white). */
+ setgcref(t->metatable, obj2gco(tabV(&tmp)));
+ }
break;
case IRFL_TAB_NOMM:
/* Negative metamethod cache invalidated by lj_tab_set() below. */
diff --git a/src/deps/src/luajit/src/lj_state.c b/src/deps/src/luajit/src/lj_state.c
index 7d7167869..1b793da98 100644
--- a/src/deps/src/luajit/src/lj_state.c
+++ b/src/deps/src/luajit/src/lj_state.c
@@ -102,27 +102,49 @@ void lj_state_shrinkstack(lua_State *L, MSize used)
/* Try to grow stack. */
void LJ_FASTCALL lj_state_growstack(lua_State *L, MSize need)
{
- MSize n;
- if (L->stacksize >= LJ_STACK_MAXEX) {
- /* 4. Throw 'error in error handling' when we are _over_ the limit. */
- if (L->stacksize > LJ_STACK_MAXEX)
- lj_err_throw(L, LUA_ERRERR); /* Does not invoke an error handler. */
- /* 1. We are _at_ the limit after the last growth. */
- if (L->status < LUA_ERRRUN) { /* 2. Throw 'stack overflow'. */
- L->status = LUA_ERRRUN; /* Prevent ending here again for pushed msg. */
- lj_err_msg(L, LJ_ERR_STKOV); /* May invoke an error handler. */
+ MSize n = L->stacksize + need;
+ if (LJ_LIKELY(n < LJ_STACK_MAX)) { /* The stack can grow as requested. */
+ if (n < 2 * L->stacksize) { /* Try to double the size. */
+ n = 2 * L->stacksize;
+ if (n > LJ_STACK_MAX)
+ n = LJ_STACK_MAX;
+ }
+ resizestack(L, n);
+ } else { /* Request would overflow. Raise a stack overflow error. */
+ if (LJ_HASJIT) {
+ TValue *base = tvref(G(L)->jit_base);
+ if (base) L->base = base;
+ }
+ if (curr_funcisL(L)) {
+ L->top = curr_topL(L);
+ if (L->top > tvref(L->maxstack)) {
+ /* The current Lua frame violates the stack, so replace it with a
+ ** dummy. This can happen when BC_IFUNCF is trying to grow the stack.
+ */
+ L->top = L->base;
+ setframe_gc(L->base - 1 - LJ_FR2, obj2gco(L), LJ_TTHREAD);
+ }
+ }
+ if (L->stacksize <= LJ_STACK_MAXEX) {
+ /* An error handler might want to inspect the stack overflow error, but
+ ** will need some stack space to run in. We give it a stack size beyond
+ ** the normal limit in order to do so, then rely on lj_state_relimitstack
+ ** calls during unwinding to bring us back to a convential stack size.
+ ** The + 1 is space for the error message, and 2 * LUA_MINSTACK is for
+ ** the lj_state_checkstack() call in lj_err_run().
+ */
+ resizestack(L, LJ_STACK_MAX + 1 + 2 * LUA_MINSTACK);
+ lj_err_stkov(L); /* May invoke an error handler. */
+ } else {
+ /* If we're here, then the stack overflow error handler is requesting
+ ** to grow the stack even further. We have no choice but to abort the
+ ** error handler.
+ */
+ GCstr *em = lj_err_str(L, LJ_ERR_STKOV); /* Might OOM. */
+ setstrV(L, L->top++, em); /* There is always space to push an error. */
+ lj_err_throw(L, LUA_ERRERR); /* Does not invoke an error handler. */
}
- /* 3. Add space (over the limit) for pushed message and error handler. */
}
- n = L->stacksize + need;
- if (n > LJ_STACK_MAX) {
- n += 2*LUA_MINSTACK;
- } else if (n < 2*L->stacksize) {
- n = 2*L->stacksize;
- if (n >= LJ_STACK_MAX)
- n = LJ_STACK_MAX;
- }
- resizestack(L, n);
}
void LJ_FASTCALL lj_state_growstack1(lua_State *L)
diff --git a/src/deps/src/luajit/src/lj_strfmt_num.c b/src/deps/src/luajit/src/lj_strfmt_num.c
index 79ec0263d..c6e776aa9 100644
--- a/src/deps/src/luajit/src/lj_strfmt_num.c
+++ b/src/deps/src/luajit/src/lj_strfmt_num.c
@@ -454,7 +454,8 @@ static char *lj_strfmt_wfnum(SBuf *sb, SFormat sf, lua_Number n, char *p)
prec--;
if (!i) {
if (ndlo == ndhi) { prec = 0; break; }
- lj_strfmt_wuint9(tail, nd[++ndlo]);
+ ndlo = (ndlo + 1) & 0x3f;
+ lj_strfmt_wuint9(tail, nd[ndlo]);
i = 9;
}
}
diff --git a/src/deps/src/luajit/src/lj_trace.c b/src/deps/src/luajit/src/lj_trace.c
index cc647500f..6dc77e286 100644
--- a/src/deps/src/luajit/src/lj_trace.c
+++ b/src/deps/src/luajit/src/lj_trace.c
@@ -936,7 +936,7 @@ int LJ_FASTCALL lj_trace_exit(jit_State *J, void *exptr)
} else if (G(L)->gc.state == GCSatomic || G(L)->gc.state == GCSfinalize) {
if (!(G(L)->hookmask & HOOK_GC))
lj_gc_step(L); /* Exited because of GC: drive GC forward. */
- } else {
+ } else if ((J->flags & JIT_F_ON)) {
trace_hotside(J, pc);
}
#ifdef LUA_USE_TRACE_LOGS
diff --git a/src/deps/src/luajit/src/luajit_rolling.h b/src/deps/src/luajit/src/luajit_rolling.h
index f08297451..cd617e7c6 100644
--- a/src/deps/src/luajit/src/luajit_rolling.h
+++ b/src/deps/src/luajit/src/luajit_rolling.h
@@ -78,4 +78,5 @@ LUA_API const char *luaJIT_profile_dumpstack(lua_State *L, const char *fmt,
/* Enforce (dynamic) linker error for version mismatches. Call from main. */
LUA_API void LUAJIT_VERSION_SYM(void);
+#error "DO NOT USE luajit_rolling.h -- only include build-generated luajit.h"
#endif
diff --git a/src/deps/src/luajit/src/msvcbuild.bat b/src/deps/src/luajit/src/msvcbuild.bat
index cd25beee1..91cfd0650 100644
--- a/src/deps/src/luajit/src/msvcbuild.bat
+++ b/src/deps/src/luajit/src/msvcbuild.bat
@@ -16,6 +16,7 @@
@rem Add more debug flags here, e.g. DEBUGCFLAGS=/DLUA_USE_APICHECK
@set DEBUGCFLAGS=
@set LJCOMPILE=cl /nologo /c /O2 /W3 /D_CRT_SECURE_NO_DEPRECATE /D_CRT_STDIO_INLINE=__declspec(dllexport)__inline
+@set LJDYNBUILD=/MD /DLUA_BUILD_AS_DLL
@set LJLINK=link /nologo
@set LJMT=mt /nologo
@set LJLIB=lib /nologo /nodefaultlib
@@ -93,12 +94,13 @@ buildvm -m folddef -o lj_folddef.h lj_opt_fold.c
@shift
@set BUILDTYPE=debug
@set LJCOMPILE=%LJCOMPILE% /Zi %DEBUGCFLAGS%
+@set LJDYNBUILD=/MDd /DLUA_BUILD_AS_DLL
@set LJLINK=%LJLINK% /opt:ref /opt:icf /incremental:no
:NODEBUG
@set LJLINK=%LJLINK% /%BUILDTYPE%
@if "%1"=="amalg" goto :AMALGDLL
@if "%1"=="static" goto :STATIC
-%LJCOMPILE% /MD /DLUA_BUILD_AS_DLL lj_*.c lib_*.c
+%LJCOMPILE% %LJDYNBUILD% lj_*.c lib_*.c
@if errorlevel 1 goto :BAD
%LJLINK% /DLL /out:%LJDLLNAME% lj_*.obj lib_*.obj
@if errorlevel 1 goto :BAD
@@ -110,7 +112,7 @@ buildvm -m folddef -o lj_folddef.h lj_opt_fold.c
@if errorlevel 1 goto :BAD
@goto :MTDLL
:AMALGDLL
-%LJCOMPILE% /MD /DLUA_BUILD_AS_DLL ljamalg.c
+%LJCOMPILE% %LJDYNBUILD% ljamalg.c
@if errorlevel 1 goto :BAD
%LJLINK% /DLL /out:%LJDLLNAME% ljamalg.obj lj_vm.obj
@if errorlevel 1 goto :BAD
diff --git a/src/deps/src/luajit/src/vm_ppc.dasc b/src/deps/src/luajit/src/vm_ppc.dasc
index 88ba96e5f..8bb5bcefa 100644
--- a/src/deps/src/luajit/src/vm_ppc.dasc
+++ b/src/deps/src/luajit/src/vm_ppc.dasc
@@ -1720,9 +1720,10 @@ static void build_subroutines(BuildCtx *ctx)
|
|//-- Base library: iterators -------------------------------------------
|
- |.ffunc next
+ |.ffunc_1 next
| cmplwi NARGS8:RC, 8
| lwz TAB:CARG1, WORD_LO(BASE)
+ | lwz CARG2, WORD_HI(BASE)
| blt ->fff_fallback
|.if ENDIAN_LE
| add TMP1, BASE, NARGS8:RC
@@ -1730,7 +1731,9 @@ static void build_subroutines(BuildCtx *ctx)
|.else
| stwx TISNIL, BASE, NARGS8:RC // Set missing 2nd arg to nil.
|.endif
+ | checktab CARG2
| lwz PC, FRAME_PC(BASE)
+ | bne ->fff_fallback
| stp BASE, L->base // Add frame since C call can throw.
| stp BASE, L->top // Dummy frame length is ok.
| la CARG2, 8(BASE)
@@ -5703,8 +5706,8 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop)
| crand 4*cr0+eq, 4*cr0+eq, 4*cr7+eq
| add TMP3, PC, TMP0
| bne cr0, >5
- | lus TMP1, 0xfffe
- | ori TMP1, TMP1, 0x7fff
+ | lus TMP1, (LJ_KEYINDEX >> 16)
+ | ori TMP1, TMP1, (LJ_KEYINDEX & 0xffff)
| stw ZERO, WORD_LO-8(RA) // Initialize control var.
| stw TMP1, WORD_HI-8(RA)
| addis PC, TMP3, -(BCBIAS_J*4 >> 16)
diff --git a/src/deps/src/luajit/src/vm_s390x.dasc b/src/deps/src/luajit/src/vm_s390x.dasc
index bd23e15d2..7f1a873fc 100644
--- a/src/deps/src/luajit/src/vm_s390x.dasc
+++ b/src/deps/src/luajit/src/vm_s390x.dasc
@@ -264,6 +264,19 @@
| lay PC, (-BCBIAS_J*4)(TMPR1, PC)
|.endmacro
|
+|// Decrement hashed hotcount and trigger trace recorder if zero.
+|.macro hotloop, reg
+| lgr reg, PC
+| srlg reg, reg, 1
+| nill reg, HOTCOUNT_PCMASK
+| afi reg, GG_DISP2HOT
+| agr reg, DISPATCH
+| lg TMPR1, (reg)
+| aghi TMPR1, -HOTCOUNT_LOOP
+| stg TMPR1, (reg)
+| jl ->vm_hotloop
+|.endmacro
+|
|// Set current VM state.
|.macro set_vmstate, st
| lghi TMPR1, ~LJ_VMST_..st
@@ -2030,9 +2043,24 @@ static void build_subroutines(BuildCtx *ctx)
| stg r0, 0
|
|->vm_hotloop: // Hot loop counter underflow.
- | stg r0, 0
- | stg r0, 0
- |
+ |.if JIT
+ | lg LFUNC:RB, -16(BASE)
+ | cleartp LFUNC:RB
+ | lg RB, LFUNC:RB->pc
+ | llgc RD, (PC2PROTO(framesize))(RB)
+ | sllg RD, RD, 3
+ | la RD, 0(RD, BASE)
+ | lg L:RB, SAVE_L
+ | stg BASE, L:RB->base
+ | stg RD, L:RB->top
+ | lgr CARG2, PC
+ | la CARG1, GG_DISP2J(DISPATCH)
+ | stg L:RB, (DISPATCH_J(L))(DISPATCH)
+ | stg PC, SAVE_PC
+ | brasl r14, extern lj_trace_hot // (jit_State *J, const BCIns *pc)
+ | j <3
+ |.endif
+ |
|->vm_callhook: // Dispatch target for call hooks.
| stg PC, SAVE_PC
|.if JIT
@@ -2131,7 +2159,8 @@ static void build_subroutines(BuildCtx *ctx)
|
|->vm_next:
|.if JIT
- | NYI // On big-endian.
+ | stg r0, 0 // NYI On big-endian.
+ | stg r0, 0
|.endif
|
|//-----------------------------------------------------------------------
@@ -2140,8 +2169,16 @@ static void build_subroutines(BuildCtx *ctx)
|
|// Handler for callback functions. Callback slot number in ah/al.
|->vm_ffi_callback:
- | stg r0, 0
- | stg r0, 0
+ |.if FFI
+ |.type CTSTATE, CTState, PC
+ | saveregs
+ | la DISPATCH, GG_G2DISP(RB)
+ | lg CTSTATE, GL:RB->ctype_state
+ | llgcr RC, RC
+ | stg RC, CTSTATE->cb.slot
+ |
+ | la RC, CFRAME_SIZE(sp)
+ |.endif
|
|->cont_ffi_callback: // Return from FFI callback.
| stg r0, 0
@@ -3758,11 +3795,13 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop)
|.define FOR_EXT, 24(RA)
case BC_FORL:
+ {
|.if JIT
| hotloop RB
|.endif
| // Fall through. Assumes BC_IFORL follows and ins_AJ is a no-op.
break;
+ }
case BC_JFORI:
case BC_JFORL: