Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/facebook/luaffifb.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSam Gross <colesbury@gmail.com>2016-01-19 23:11:18 +0300
committerSam Gross <colesbury@gmail.com>2016-01-19 23:11:18 +0300
commitf2d4048c6812884c45a3bec526d77d35e2e463a5 (patch)
tree8922257a446d8f6469a5a6eb554c987c1db5d985
parentd806f1ae30af77b2024d6c76868298db1b2980bc (diff)
parent25b88a472128670ba2a9a8f32793fe06013b759b (diff)
Merge pull request #7 from colesbury/arm
Add ARM header files
-rw-r--r--Makefile5
-rw-r--r--call_arm.dasc180
-rw-r--r--call_arm.h1013
3 files changed, 1090 insertions, 108 deletions
diff --git a/Makefile b/Makefile
index 715b269..79bbd4c 100644
--- a/Makefile
+++ b/Makefile
@@ -17,7 +17,7 @@ clean:
rm -f *.o *.so *.dylib
headers:
- $(MAKE) call_x86.h call_x64.h call_x64win.h
+ $(MAKE) call_x86.h call_x64.h call_x64win.h call_arm.h
call_x86.h: call_x86.dasc dynasm/*.lua
$(LUA) dynasm/dynasm.lua -LN -o $@ $<
@@ -27,3 +27,6 @@ call_x64.h: call_x86.dasc dynasm/*.lua
call_x64win.h: call_x86.dasc dynasm/*.lua
$(LUA) dynasm/dynasm.lua -D X64 -D X64WIN -LN -o $@ $<
+
+call_arm.h: call_arm.dasc dynasm/*.lua
+ $(LUA) dynasm/dynasm.lua -LNE -o $@ $<
diff --git a/call_arm.dasc b/call_arm.dasc
index 8b6de91..f857532 100644
--- a/call_arm.dasc
+++ b/call_arm.dasc
@@ -16,7 +16,7 @@
#define MAX_BRANCH ((INT32_MAX) >> 8)
#define BRANCH_OFF 4
-static void compile_extern_jump(struct jit* jit, lua_State* L, function_t func, uint8_t* code)
+static void compile_extern_jump(struct jit* jit, lua_State* L, cfunction func, uint8_t* code)
{
/* The jump code is the function pointer followed by a stub to call the
* function pointer. The stub exists so we can jump to functions with an
@@ -25,7 +25,7 @@ static void compile_extern_jump(struct jit* jit, lua_State* L, function_t func,
* Note we have to manually set this up since there are commands buffered
* in the jit state.
*/
- *(function_t*) code = func;
+ *(cfunction*) code = func;
/* ldr pc, [pc - 12] */
*(uint32_t*) &code[4] = 0xE51FF00CU;
}
@@ -52,9 +52,9 @@ void compile_globals(struct jit* jit, lua_State* L)
(void) jit;
}
-function_t push_callback(struct jit* jit, lua_State* L, int fidx, int ct_usr, const struct ctype* ct)
+cfunction compile_callback(lua_State* L, int fidx, int ct_usr, const struct ctype* ct)
{
- struct jit* Dst = jit;
+ struct jit* Dst = get_jit(L);;
int i, nargs, num_upvals, ref;
const struct ctype* mt;
@@ -118,7 +118,6 @@ function_t push_callback(struct jit* jit, lua_State* L, int fidx, int ct_usr, co
} else {
switch (mt->type) {
case INT64_TYPE:
- case UINT64_TYPE:
lua_rawseti(L, -2, ++num_upvals); /* mt */
| lcall extern lua_pushnil
| load32 r2, mt
@@ -132,7 +131,7 @@ function_t push_callback(struct jit* jit, lua_State* L, int fidx, int ct_usr, co
| lcall extern lua_remove // remove the nil usr
break;
- case UINTPTR_TYPE:
+ case INTPTR_TYPE:
lua_rawseti(L, -2, ++num_upvals); /* mt */
| lcall extern lua_pushnil
| load32 r2, mt
@@ -154,33 +153,26 @@ function_t push_callback(struct jit* jit, lua_State* L, int fidx, int ct_usr, co
lua_pop(L, 1);
| ldr r1, [DATA], #4
| mov r1, r1, lsl #24
- | mov r1, r1, asr #24
+ if (mt->is_unsigned) {
+ | mov r1, r1, lsr #24
+ } else {
+ | mov r1, r1, asr #24
+ }
| lcall extern push_int
break;
- case UINT8_TYPE:
- lua_pop(L, 1);
- | ldr r1, [DATA], #4
- | and r1, r1, #0xFF
- | lcall extern push_uint
- break;
-
case INT16_TYPE:
lua_pop(L, 1);
| ldr r1, [DATA], #4
| mov r1, r1, lsl #16
- | mov r1, r1, asr #16
+ if (mt->is_unsigned) {
+ | mov r1, r1, lsr #16
+ } else {
+ | mov r1, r1, asr #16
+ }
| lcall extern push_int
break;
- case UINT16_TYPE:
- lua_pop(L, 1);
- | ldr r1, [DATA], #4
- | mov r1, r1, lsl #16
- | mov r1, r1, lsr #16
- | lcall extern push_uint
- break;
-
case ENUM_TYPE:
case INT32_TYPE:
lua_pop(L, 1);
@@ -188,12 +180,6 @@ function_t push_callback(struct jit* jit, lua_State* L, int fidx, int ct_usr, co
| lcall extern push_int
break;
- case UINT32_TYPE:
- lua_pop(L, 1);
- | ldr r1, [DATA], #4
- | lcall extern push_uint
- break;
-
case FLOAT_TYPE:
lua_pop(L, 1);
| ldr r1, [DATA], #4
@@ -267,39 +253,35 @@ function_t push_callback(struct jit* jit, lua_State* L, int fidx, int ct_usr, co
case INT16_TYPE:
case INT32_TYPE:
| mvn r1, #0 // -1
- | lcall extern to_int32
- goto single;
-
- case UINT8_TYPE:
- case UINT16_TYPE:
- case UINT32_TYPE:
- | mvn r1, #0 // -1
- | lcall extern to_uint32
+ if (mt->is_unsigned) {
+ | lcall extern check_uint32
+ } else {
+ | lcall extern check_int32
+ }
goto single;
case INT64_TYPE:
| mvn r1, #0 // -1
- | lcall extern to_int64
- goto dual;
-
- case UINT64_TYPE:
- | mvn r1, #0 // -1
- | lcall extern to_uint64
+ if (mt->is_unsigned) {
+ | lcall extern check_uint64
+ } else {
+ | lcall extern check_int64
+ }
goto dual;
- case UINTPTR_TYPE:
+ case INTPTR_TYPE:
| mvn r1, #0 // -1
- | lcall extern to_uintptr
+ | lcall extern check_intptr
goto single;
case FLOAT_TYPE:
| mvn r1, #0 // -1
- | lcall extern to_float
+ | lcall extern check_float
goto single;
case DOUBLE_TYPE:
| mvn r1, #0 // -1
- | lcall extern to_double
+ | lcall extern check_double
goto dual;
single:
@@ -333,14 +315,14 @@ function_t push_callback(struct jit* jit, lua_State* L, int fidx, int ct_usr, co
{
void* p;
struct ctype ft;
- function_t func;
+ cfunction func;
- func = compile(jit, L, NULL, ref);
+ func = compile(Dst, L, NULL, ref);
ft = *ct;
ft.is_jitted = 1;
p = push_cdata(L, ct_usr, &ft);
- *(function_t*) p = func;
+ *(cfunction*) p = func;
assert(lua_gettop(L) == top + 1);
@@ -348,9 +330,9 @@ function_t push_callback(struct jit* jit, lua_State* L, int fidx, int ct_usr, co
}
}
-void push_function(struct jit* jit, lua_State* L, function_t func, int ct_usr, const struct ctype* ct)
+void compile_function(lua_State* L, cfunction func, int ct_usr, const struct ctype* ct)
{
- struct jit* Dst = jit;
+ struct jit* Dst = get_jit(L);;
int i, nargs, num_upvals;
const struct ctype* mt;
void* p;
@@ -361,7 +343,7 @@ void push_function(struct jit* jit, lua_State* L, function_t func, int ct_usr, c
nargs = (int) lua_rawlen(L, ct_usr);
p = push_cdata(L, ct_usr, ct);
- *(function_t*) p = func;
+ *(cfunction*) p = func;
num_upvals = 1;
dasm_setup(Dst, build_actionlist);
@@ -426,67 +408,60 @@ void push_function(struct jit* jit, lua_State* L, function_t func, int ct_usr, c
switch (mt->type) {
case INT8_TYPE:
- | lcall extern to_int32
- | mov r0, r0, lsl #24
- | mov r0, r0, asr #24
+ | lcall extern check_int32
+ if (mt->is_unsigned) {
+ | and r0, r0, #0xFF
+ } else {
+ | mov r0, r0, lsl #24
+ | mov r0, r0, asr #24
+ }
| str r0, [DATA], #4
break;
case INT16_TYPE:
- | lcall extern to_int32
- | mov r0, r0, lsl #16
- | mov r0, r0, asr #16
+ | lcall extern check_int32
+ if (mt->is_unsigned) {
+ | mov r0, r0, lsl #16
+ | mov r0, r0, lsr #16
+ } else {
+ | mov r0, r0, lsl #16
+ | mov r0, r0, asr #16
+ }
| str r0, [DATA], #4
break;
case INT32_TYPE:
- | lcall extern to_int32
- | str r0, [DATA], #4
- break;
-
- case UINT8_TYPE:
- | lcall extern to_uint32
- | and r0, r0, #0xFF
- | str r0, [DATA], #4
- break;
-
- case UINT16_TYPE:
- | lcall extern to_uint32
- | mov r0, r0, lsl #16
- | mov r0, r0, lsr #16
- | str r0, [DATA], #4
- break;
-
- case UINT32_TYPE:
- | lcall extern to_uint32
+ if (mt->is_unsigned) {
+ | lcall extern check_uint32
+ } else {
+ | lcall extern check_int32
+ }
| str r0, [DATA], #4
break;
case INT64_TYPE:
- | lcall extern to_int64
- | str r0, [DATA], #4
- | str r1, [DATA], #4
- break;
-
- case UINT64_TYPE:
- | lcall extern to_uint64
+ if (mt->is_unsigned) {
+ | lcall extern check_uint64
+ } else {
+ | lcall extern check_int64
+ }
| str r0, [DATA], #4
| str r1, [DATA], #4
break;
case DOUBLE_TYPE:
- | lcall extern to_double
+ | lcall extern check_double
| str r0, [DATA], #4
| str r1, [DATA], #4
break;
- case UINTPTR_TYPE:
- | lcall extern to_uintptr
+ case INTPTR_TYPE:
+ | lcall extern check_intptr
| str r0, [DATA], #4
break;
case FLOAT_TYPE:
- | lcall extern to_float
+ | lcall extern check_float
| str r0, [DATA], #4
break;
@@ -503,7 +478,7 @@ void push_function(struct jit* jit, lua_State* L, function_t func, int ct_usr, c
| lcall extern unpack_varargs_stack
}
- | load32 r0, &jit->last_errno
+ | load32 r0, &Dst->last_errno
| ldr r0, [r0]
| bl extern SetLastError
@@ -512,7 +487,7 @@ void push_function(struct jit* jit, lua_State* L, function_t func, int ct_usr, c
|.macro get_errno
| bl extern GetLastError
- | load32 r1, &jit->last_errno
+ | load32 r1, &Dst->last_errno
| str r0, [r1]
|.endmacro
@@ -541,7 +516,6 @@ void push_function(struct jit* jit, lua_State* L, function_t func, int ct_usr, c
} else {
switch (mt->type) {
case INT64_TYPE:
- case UINT64_TYPE:
num_upvals++;
| mov DATA, r0
| mov DATA2, r1
@@ -556,7 +530,7 @@ void push_function(struct jit* jit, lua_State* L, function_t func, int ct_usr, c
| return
break;
- case UINTPTR_TYPE:
+ case INTPTR_TYPE:
num_upvals++;
| mov DATA, r0
| get_errno
@@ -594,19 +568,11 @@ void push_function(struct jit* jit, lua_State* L, function_t func, int ct_usr, c
| mov DATA, r0
| get_errno
| mov r1, DATA
- | lcall extern push_int
- | mov r0, #1
- | return
- break;
-
- case UINT8_TYPE:
- case UINT16_TYPE:
- case UINT32_TYPE:
- lua_pop(L, 1);
- | mov DATA, r0
- | get_errno
- | mov r1, DATA
- | lcall extern push_uint
+ if (mt->is_unsigned) {
+ | lcall extern push_uint
+ } else {
+ | lcall extern push_int
+ }
| mov r0, #1
| return
break;
@@ -639,6 +605,6 @@ void push_function(struct jit* jit, lua_State* L, function_t func, int ct_usr, c
}
assert(lua_gettop(L) == top + num_upvals);
- lua_pushcclosure(L, (lua_CFunction) compile(jit, L, func, LUA_NOREF), num_upvals);
+ lua_pushcclosure(L, (lua_CFunction) compile(Dst, L, func, LUA_NOREF), num_upvals);
}
diff --git a/call_arm.h b/call_arm.h
new file mode 100644
index 0000000..efe7f95
--- /dev/null
+++ b/call_arm.h
@@ -0,0 +1,1013 @@
+/*
+** This file has been pre-processed with DynASM.
+** http://luajit.org/dynasm.html
+** DynASM version 1.3.0, DynASM arm version 1.3.0
+** DO NOT EDIT! The original file is in "call_arm.dasc".
+*/
+
+#if DASM_VERSION != 10300
+#error "Version mismatch between DynASM and included encoding engine"
+#endif
+
+/* vim: ts=4 sw=4 sts=4 et tw=78
+ * Portions copyright (c) 2015-present, Facebook, Inc. All rights reserved.
+ * Portions copyright (c) 2011 James R. McKaskill.
+ *
+ * This source code is licensed under the BSD-style license found in the
+ * LICENSE file in the root directory of this source tree. An additional grant
+ * of patent rights can be found in the PATENTS file in the same directory.
+ */
+static const unsigned int build_actionlist[546] = {
+0xe1a0c00d,
+0xe92d000f,
+0xe92d50f0,
+0xe24c6010,
+0xe59f5008,
+0xe59f2008,
+0xe59f1008,
+0xea000000,
+0x00050001,
+0x00090000,
+0x00090000,
+0x00090000,
+0x0006000b,
+0xe1a00005,
+0xeb000000,
+0x00030000,
+0x00000000,
+0xe3a02000,
+0x000b0000,
+0xe3e01000,
+0xe1a00005,
+0xeb000000,
+0x00030000,
+0x00000000,
+0xe3a02000,
+0x000b0000,
+0xe3e01000,
+0x000b0000,
+0xe1a00005,
+0xeb000000,
+0x00030000,
+0xe59f2000,
+0xea000000,
+0x00050005,
+0x00090000,
+0x0006000f,
+0xe3e01000,
+0xe1a00005,
+0xeb000000,
+0x00030001,
+0xe4962004,
+0xe5802000,
+0xe3e01001,
+0xe1a00005,
+0xeb000000,
+0x00030002,
+0x00000000,
+0xe1a00005,
+0xeb000000,
+0x00030003,
+0xe59f2000,
+0xea000000,
+0x00050005,
+0x00090000,
+0x0006000f,
+0xe3e01000,
+0xe1a00005,
+0xeb000000,
+0x00030001,
+0xe4962004,
+0xe4963004,
+0xe5802000,
+0xe5803004,
+0xe3e01001,
+0xe1a00005,
+0xeb000000,
+0x00030002,
+0x00000000,
+0xe1a00005,
+0xeb000000,
+0x00030003,
+0xe59f2000,
+0xea000000,
+0x00050005,
+0x00090000,
+0x0006000f,
+0xe3e01000,
+0xe1a00005,
+0xeb000000,
+0x00030001,
+0xe4962004,
+0xe5802000,
+0xe3e01001,
+0xe1a00005,
+0xeb000000,
+0x00030002,
+0x00000000,
+0xe4961004,
+0xe1a00005,
+0xeb000000,
+0x00030004,
+0x00000000,
+0xe4961004,
+0xe1a01c01,
+0x00000000,
+0xe1a01c21,
+0x00000000,
+0xe1a01c41,
+0x00000000,
+0xe1a00005,
+0xeb000000,
+0x00030005,
+0x00000000,
+0xe4961004,
+0xe1a01801,
+0x00000000,
+0xe1a01821,
+0x00000000,
+0xe1a01841,
+0x00000000,
+0xe1a00005,
+0xeb000000,
+0x00030005,
+0x00000000,
+0xe4961004,
+0xe1a00005,
+0xeb000000,
+0x00030005,
+0x00000000,
+0xe4961004,
+0xe1a00005,
+0xeb000000,
+0x00030006,
+0x00000000,
+0xe8b60006,
+0xe1a00005,
+0xeb000000,
+0x00030007,
+0x00000000,
+0xe3a03000,
+0xe3a02000,
+0x000b0000,
+0xe3a01000,
+0x000b0000,
+0xe1a00005,
+0xeb000000,
+0x00030008,
+0x00000000,
+0xe3a02000,
+0x000b0000,
+0xe3e01001,
+0xe1a00005,
+0xeb000000,
+0x00030000,
+0xe59f3000,
+0xea000000,
+0x00050005,
+0x00090000,
+0x0006000f,
+0xe3a02000,
+0xe3e01001,
+0xe1a00005,
+0xeb000000,
+0x00030009,
+0xe1a06000,
+0xe3e01003,
+0xe1a00005,
+0xeb000000,
+0x0003000a,
+0xe1a00006,
+0x00000000,
+0xe3a02000,
+0x000b0000,
+0xe3e01001,
+0xe1a00005,
+0xeb000000,
+0x00030000,
+0xe59f3000,
+0xea000000,
+0x00050005,
+0x00090000,
+0x0006000f,
+0xe3e02000,
+0xe3e01001,
+0xe1a00005,
+0xeb000000,
+0x0003000b,
+0xe1a06000,
+0xe3e01003,
+0xe1a00005,
+0xeb000000,
+0x0003000a,
+0xe1a00006,
+0x00000000,
+0xe3e01001,
+0xe1a00005,
+0xeb000000,
+0x0003000a,
+0x00000000,
+0xe3e01000,
+0x00000000,
+0xe1a00005,
+0xeb000000,
+0x0003000c,
+0x00000000,
+0xe1a00005,
+0xeb000000,
+0x0003000d,
+0x00000000,
+0xe3e01000,
+0x00000000,
+0xe1a00005,
+0xeb000000,
+0x0003000e,
+0x00000000,
+0xe1a00005,
+0xeb000000,
+0x0003000f,
+0x00000000,
+0xe3e01000,
+0xe1a00005,
+0xeb000000,
+0x00030010,
+0x00000000,
+0xe3e01000,
+0xe1a00005,
+0xeb000000,
+0x00030011,
+0x00000000,
+0xe3e01000,
+0xe1a00005,
+0xeb000000,
+0x00030012,
+0x00000000,
+0xe1a06000,
+0xe3e01002,
+0xe1a00005,
+0xeb000000,
+0x0003000a,
+0xe1a00006,
+0x00000000,
+0xe1a06000,
+0xe1a07001,
+0xe3e01002,
+0xe1a00005,
+0xeb000000,
+0x0003000a,
+0xe1a00006,
+0xe1a01007,
+0x00000000,
+0xe89da0f0,
+0x00000000,
+0xe1a0c00d,
+0xe92d0001,
+0xe92d58f0,
+0xe24cb004,
+0xe1a05000,
+0xe1a00005,
+0xeb000000,
+0x00030013,
+0xe1a04000,
+0xe3540000,
+0x000b0000,
+0x00000000,
+0xaa000000,
+0x00050001,
+0xe59f1000,
+0xea000000,
+0x00050005,
+0x00090000,
+0x0006000f,
+0xe1a00005,
+0xeb000000,
+0x00030014,
+0x0006000b,
+0x00000000,
+0x0a000000,
+0x00050001,
+0xe59f1000,
+0xea000000,
+0x00050005,
+0x00090000,
+0x0006000f,
+0xe1a00005,
+0xeb000000,
+0x00030014,
+0x0006000b,
+0x00000000,
+0xe04dd184,
+0xe24dd010,
+0xe1a0600d,
+0x00000000,
+0xe59f3004,
+0xe59f2004,
+0xea000000,
+0x00050001,
+0x00090000,
+0x00090000,
+0x0006000b,
+0xe3a01000,
+0x000b0000,
+0xe1a00005,
+0x00000000,
+0xeb000000,
+0x00030009,
+0x00000000,
+0xeb000000,
+0x00030015,
+0x00000000,
+0xeb000000,
+0x0003000b,
+0x00000000,
+0xe4860004,
+0x00000000,
+0xe3a01000,
+0x000b0000,
+0x00000000,
+0xe1a00005,
+0xeb000000,
+0x0003000d,
+0x00000000,
+0xe20000ff,
+0x00000000,
+0xe1a00c00,
+0xe1a00c40,
+0x00000000,
+0xe4860004,
+0x00000000,
+0xe1a00005,
+0xeb000000,
+0x0003000d,
+0x00000000,
+0xe1a00800,
+0xe1a00820,
+0x00000000,
+0xe1a00800,
+0xe1a00840,
+0x00000000,
+0xe4860004,
+0x00000000,
+0xe1a00005,
+0xeb000000,
+0x0003000c,
+0x00000000,
+0xe1a00005,
+0xeb000000,
+0x0003000d,
+0x00000000,
+0xe4860004,
+0x00000000,
+0xe1a00005,
+0xeb000000,
+0x0003000e,
+0x00000000,
+0xe1a00005,
+0xeb000000,
+0x0003000f,
+0x00000000,
+0xe4860004,
+0xe4861004,
+0x00000000,
+0xe1a00005,
+0xeb000000,
+0x00030012,
+0xe4860004,
+0xe4861004,
+0x00000000,
+0xe1a00005,
+0xeb000000,
+0x00030010,
+0xe4860004,
+0x00000000,
+0xe1a00005,
+0xeb000000,
+0x00030011,
+0xe4860004,
+0x00000000,
+0xe1a03006,
+0xe1a02004,
+0xe3a01000,
+0x000b0000,
+0xe1a00005,
+0xeb000000,
+0x00030016,
+0x00000000,
+0xe59f0000,
+0xea000000,
+0x00050005,
+0x00090000,
+0x0006000f,
+0xe5900000,
+0xeb000000,
+0x00030017,
+0x00000000,
+0xe8bd000f,
+0xeb000000,
+0x00030018,
+0x00000000,
+0xe1a06000,
+0xeb000000,
+0x00030019,
+0xe59f1000,
+0xea000000,
+0x00050005,
+0x00090000,
+0x0006000f,
+0xe5810000,
+0xe59f2004,
+0xe59f1004,
+0xea000000,
+0x00050001,
+0x00090000,
+0x00090000,
+0x0006000b,
+0xe1a00005,
+0xeb000000,
+0x00030001,
+0xe5806000,
+0xe3a00001,
+0xe91ba870,
+0x00000000,
+0xe1a06000,
+0xe1a07001,
+0xeb000000,
+0x00030019,
+0xe59f1000,
+0xea000000,
+0x00050005,
+0x00090000,
+0x0006000f,
+0xe5810000,
+0xe1a00005,
+0xeb000000,
+0x00030003,
+0xe59f2000,
+0xea000000,
+0x00050005,
+0x00090000,
+0x0006000f,
+0xe3e01000,
+0xe1a00005,
+0xeb000000,
+0x00030001,
+0xe5806000,
+0xe5807004,
+0xe3a00001,
+0xe91ba870,
+0x00000000,
+0xe1a06000,
+0xeb000000,
+0x00030019,
+0xe59f1000,
+0xea000000,
+0x00050005,
+0x00090000,
+0x0006000f,
+0xe5810000,
+0xe1a00005,
+0xeb000000,
+0x00030003,
+0xe59f2000,
+0xea000000,
+0x00050005,
+0x00090000,
+0x0006000f,
+0xe3e01000,
+0xe1a00005,
+0xeb000000,
+0x00030001,
+0xe5806000,
+0xe3a00001,
+0xe91ba870,
+0x00000000,
+0xeb000000,
+0x00030019,
+0xe59f1000,
+0xea000000,
+0x00050005,
+0x00090000,
+0x0006000f,
+0xe5810000,
+0xe3a00000,
+0xe91ba870,
+0x00000000,
+0xe1a06000,
+0xeb000000,
+0x00030019,
+0xe59f1000,
+0xea000000,
+0x00050005,
+0x00090000,
+0x0006000f,
+0xe5810000,
+0xe1a01006,
+0xe1a00005,
+0xeb000000,
+0x00030004,
+0xe3a00001,
+0xe91ba870,
+0x00000000,
+0xe1a06000,
+0xeb000000,
+0x00030019,
+0xe59f1000,
+0xea000000,
+0x00050005,
+0x00090000,
+0x0006000f,
+0xe5810000,
+0xe1a01006,
+0x00000000,
+0xe1a00005,
+0xeb000000,
+0x0003001a,
+0x00000000,
+0xe1a00005,
+0xeb000000,
+0x00030005,
+0x00000000,
+0xe3a00001,
+0xe91ba870,
+0x00000000,
+0xe1a06000,
+0xeb000000,
+0x00030019,
+0xe59f1000,
+0xea000000,
+0x00050005,
+0x00090000,
+0x0006000f,
+0xe5810000,
+0xe1a01006,
+0xe1a00005,
+0xeb000000,
+0x00030006,
+0xe3a00001,
+0xe91ba870,
+0x00000000,
+0xe1a06000,
+0xe1a07001,
+0xeb000000,
+0x00030019,
+0xe59f1000,
+0xea000000,
+0x00050005,
+0x00090000,
+0x0006000f,
+0xe5810000,
+0xe1a02007,
+0xe1a01006,
+0xe1a00005,
+0xeb000000,
+0x00030007,
+0xe3a00001,
+0xe91ba870,
+0x00000000
+};
+
+static const char *const globnames[] = {
+ (const char *)0
+};
+static const char *const extnames[] = {
+ "lua_rawgeti",
+ "push_cdata",
+ "lua_remove",
+ "lua_pushnil",
+ "lua_pushboolean",
+ "push_int",
+ "push_float",
+ "lua_pushnumber",
+ "lua_callk",
+ "to_typed_pointer",
+ "lua_settop",
+ "to_enum",
+ "check_uint32",
+ "check_int32",
+ "check_uint64",
+ "check_int64",
+ "check_intptr",
+ "check_float",
+ "check_double",
+ "lua_gettop",
+ "luaL_error",
+ "to_typed_function",
+ "unpack_varargs_stack",
+ "SetLastError",
+ "FUNCTION",
+ "GetLastError",
+ "push_uint",
+ (const char *)0
+};
+
+#define JUMP_SIZE 8
+#define MIN_BRANCH ((INT32_MIN) >> 8)
+#define MAX_BRANCH ((INT32_MAX) >> 8)
+#define BRANCH_OFF 4
+
+static void compile_extern_jump(struct jit* jit, lua_State* L, cfunction func, uint8_t* code)
+{
+ /* The jump code is the function pointer followed by a stub to call the
+ * function pointer. The stub exists so we can jump to functions with an
+ * offset greater than 32MB.
+ *
+ * Note we have to manually set this up since there are commands buffered
+ * in the jit state.
+ */
+ *(cfunction*) code = func;
+ /* ldr pc, [pc - 12] */
+ *(uint32_t*) &code[4] = 0xE51FF00CU;
+}
+
+
+
+
+void compile_globals(struct jit* jit, lua_State* L)
+{
+ (void) jit;
+}
+
+cfunction compile_callback(lua_State* L, int fidx, int ct_usr, const struct ctype* ct)
+{
+ struct jit* Dst = get_jit(L);;
+ int i, nargs, num_upvals, ref;
+ const struct ctype* mt;
+
+ int top = lua_gettop(L);
+
+ ct_usr = lua_absindex(L, ct_usr);
+ fidx = lua_absindex(L, fidx);
+ nargs = (int) lua_rawlen(L, ct_usr);
+
+ dasm_setup(Dst, build_actionlist);
+
+ lua_newtable(L);
+ lua_pushvalue(L, -1);
+ ref = luaL_ref(L, LUA_REGISTRYINDEX);
+ num_upvals = 0;
+
+ if (ct->has_var_arg) {
+ luaL_error(L, "can't create callbacks with varargs");
+ }
+
+ /* prolog and get the upval table */
+ dasm_put(Dst, 0, (uintptr_t)(L), (uintptr_t)(ref), (uintptr_t)(LUA_REGISTRYINDEX));
+
+ /* get the lua function */
+ lua_pushvalue(L, fidx);
+ lua_rawseti(L, -2, ++num_upvals);
+ dasm_put(Dst, 17, num_upvals);
+
+ for (i = 1; i <= nargs; i++) {
+ lua_rawgeti(L, ct_usr, i);
+ mt = (const struct ctype*) lua_touserdata(L, -1);
+
+ if (mt->pointers || mt->is_reference) {
+ lua_getuservalue(L, -1);
+ lua_rawseti(L, -3, ++num_upvals); /* usr value */
+ lua_rawseti(L, -2, ++num_upvals); /* mt */
+
+ dasm_put(Dst, 24, num_upvals-1, i, (uintptr_t)(mt));
+
+ } else {
+ switch (mt->type) {
+ case INT64_TYPE:
+ lua_rawseti(L, -2, ++num_upvals); /* mt */
+ dasm_put(Dst, 47, (uintptr_t)(mt));
+ break;
+
+ case INTPTR_TYPE:
+ lua_rawseti(L, -2, ++num_upvals); /* mt */
+ dasm_put(Dst, 68, (uintptr_t)(mt));
+ break;
+
+ case BOOL_TYPE:
+ lua_pop(L, 1);
+ dasm_put(Dst, 87);
+ break;
+
+ case INT8_TYPE:
+ lua_pop(L, 1);
+ dasm_put(Dst, 92);
+ if (mt->is_unsigned) {
+ dasm_put(Dst, 95);
+ } else {
+ dasm_put(Dst, 97);
+ }
+ dasm_put(Dst, 99);
+ break;
+
+ case INT16_TYPE:
+ lua_pop(L, 1);
+ dasm_put(Dst, 103);
+ if (mt->is_unsigned) {
+ dasm_put(Dst, 106);
+ } else {
+ dasm_put(Dst, 108);
+ }
+ dasm_put(Dst, 110);
+ break;
+
+ case ENUM_TYPE:
+ case INT32_TYPE:
+ lua_pop(L, 1);
+ dasm_put(Dst, 114);
+ break;
+
+ case FLOAT_TYPE:
+ lua_pop(L, 1);
+ dasm_put(Dst, 119);
+ break;
+
+ case DOUBLE_TYPE:
+ lua_pop(L, 1);
+ dasm_put(Dst, 124);
+ break;
+
+ default:
+ luaL_error(L, "NYI: callback arg type");
+ }
+ }
+ }
+
+ lua_rawgeti(L, ct_usr, 0);
+ mt = (const struct ctype*) lua_touserdata(L, -1);
+
+ dasm_put(Dst, 129, ((mt->pointers || mt->is_reference || mt->type != VOID_TYPE) ? 1 : 0), nargs);
+
+ if (mt->pointers || mt->is_reference) {
+ lua_getuservalue(L, -1);
+ lua_rawseti(L, -3, ++num_upvals); /* usr value */
+ lua_rawseti(L, -2, ++num_upvals); /* mt */
+
+ dasm_put(Dst, 138, num_upvals-1, (uintptr_t)(mt));
+ } else {
+ switch (mt->type) {
+ case ENUM_TYPE:
+ lua_getuservalue(L, -1);
+ lua_rawseti(L, -3, ++num_upvals); /* usr value */
+ lua_rawseti(L, -2, ++num_upvals); /* mt */
+
+ dasm_put(Dst, 161, num_upvals-1, (uintptr_t)(mt));
+ break;
+
+ case VOID_TYPE:
+ dasm_put(Dst, 184);
+ lua_pop(L, 1);
+ break;
+
+ case BOOL_TYPE:
+ case INT8_TYPE:
+ case INT16_TYPE:
+ case INT32_TYPE:
+ dasm_put(Dst, 189);
+ if (mt->is_unsigned) {
+ dasm_put(Dst, 191);
+ } else {
+ dasm_put(Dst, 195);
+ }
+ goto single;
+
+ case INT64_TYPE:
+ dasm_put(Dst, 199);
+ if (mt->is_unsigned) {
+ dasm_put(Dst, 201);
+ } else {
+ dasm_put(Dst, 205);
+ }
+ goto dual;
+
+ case INTPTR_TYPE:
+ dasm_put(Dst, 209);
+ goto single;
+
+ case FLOAT_TYPE:
+ dasm_put(Dst, 214);
+ goto single;
+
+ case DOUBLE_TYPE:
+ dasm_put(Dst, 219);
+ goto dual;
+
+ single:
+ dasm_put(Dst, 224);
+ lua_pop(L, 1);
+ break;
+
+ dual:
+ dasm_put(Dst, 231);
+ lua_pop(L, 1);
+ break;
+
+ default:
+ luaL_error(L, "NYI: callback return type");
+ }
+ }
+
+ dasm_put(Dst, 240);
+
+ lua_pop(L, 1); /* upval table - already in registry */
+ assert(lua_gettop(L) == top);
+
+ {
+ void* p;
+ struct ctype ft;
+ cfunction func;
+
+ func = compile(Dst, L, NULL, ref);
+
+ ft = *ct;
+ ft.is_jitted = 1;
+ p = push_cdata(L, ct_usr, &ft);
+ *(cfunction*) p = func;
+
+ assert(lua_gettop(L) == top + 1);
+
+ return func;
+ }
+}
+
+void compile_function(lua_State* L, cfunction func, int ct_usr, const struct ctype* ct)
+{
+ struct jit* Dst = get_jit(L);;
+ int i, nargs, num_upvals;
+ const struct ctype* mt;
+ void* p;
+
+ int top = lua_gettop(L);
+
+ ct_usr = lua_absindex(L, ct_usr);
+ nargs = (int) lua_rawlen(L, ct_usr);
+
+ p = push_cdata(L, ct_usr, ct);
+ *(cfunction*) p = func;
+ num_upvals = 1;
+
+ dasm_setup(Dst, build_actionlist);
+
+ dasm_put(Dst, 242, nargs);
+ if (ct->has_var_arg) {
+ dasm_put(Dst, 254, (uintptr_t)("too few arguments"));
+ } else {
+ dasm_put(Dst, 266, (uintptr_t)("incorrect number of arguments"));
+ }
+
+ /* reserve enough stack space for all of the arguments (8 bytes per
+ * argument for double and maintains alignment). Add an extra 16 bytes so
+ * that the pop {r0, r1, r2, r3} doesn't clean out our stack frame */
+ dasm_put(Dst, 278);
+
+ for (i = 1; i <= nargs; i++) {
+ lua_rawgeti(L, ct_usr, i);
+ mt = (const struct ctype*) lua_touserdata(L, -1);
+
+ if (mt->pointers || mt->is_reference || mt->type == FUNCTION_PTR_TYPE || mt->type == ENUM_TYPE) {
+ lua_getuservalue(L, -1);
+ num_upvals += 2;
+
+ dasm_put(Dst, 282, (uintptr_t)(mt), (uintptr_t)(lua_upvalueindex(num_upvals)), i);
+
+ if (mt->pointers || mt->is_reference) {
+ dasm_put(Dst, 293);
+ } else if (mt->type == FUNCTION_PTR_TYPE) {
+ dasm_put(Dst, 296);
+ } else if (mt->type == ENUM_TYPE) {
+ dasm_put(Dst, 299);
+ }
+
+ dasm_put(Dst, 302);
+
+ } else {
+ lua_pop(L, 1);
+ dasm_put(Dst, 304, i);
+
+ switch (mt->type) {
+ case INT8_TYPE:
+ dasm_put(Dst, 307);
+ if (mt->is_unsigned) {
+ dasm_put(Dst, 311);
+ } else {
+ dasm_put(Dst, 313);
+ }
+ dasm_put(Dst, 316);
+ break;
+
+ case INT16_TYPE:
+ dasm_put(Dst, 318);
+ if (mt->is_unsigned) {
+ dasm_put(Dst, 322);
+ } else {
+ dasm_put(Dst, 325);
+ }
+ dasm_put(Dst, 328);
+ break;
+
+ case INT32_TYPE:
+ if (mt->is_unsigned) {
+ dasm_put(Dst, 330);
+ } else {
+ dasm_put(Dst, 334);
+ }
+ dasm_put(Dst, 338);
+ break;
+
+ case INT64_TYPE:
+ if (mt->is_unsigned) {
+ dasm_put(Dst, 340);
+ } else {
+ dasm_put(Dst, 344);
+ }
+ dasm_put(Dst, 348);
+ break;
+
+ case DOUBLE_TYPE:
+ dasm_put(Dst, 351);
+ break;
+
+ case INTPTR_TYPE:
+ dasm_put(Dst, 357);
+ break;
+
+ case FLOAT_TYPE:
+ dasm_put(Dst, 362);
+ break;
+
+ default:
+ luaL_error(L, "NYI: call arg type");
+ }
+ }
+ }
+
+ if (ct->has_var_arg) {
+ dasm_put(Dst, 367, nargs+1);
+ }
+
+ dasm_put(Dst, 375, (uintptr_t)(&Dst->last_errno));
+
+ dasm_put(Dst, 384);
+
+
+
+ lua_rawgeti(L, ct_usr, 0);
+ mt = (const struct ctype*) lua_touserdata(L, -1);
+
+ if (mt->pointers || mt->is_reference) {
+ lua_getuservalue(L, -1);
+ num_upvals += 2;
+ dasm_put(Dst, 388, (uintptr_t)(&Dst->last_errno), (uintptr_t)(mt), (uintptr_t)(lua_upvalueindex(num_upvals)));
+
+ } else {
+ switch (mt->type) {
+ case INT64_TYPE:
+ num_upvals++;
+ dasm_put(Dst, 411, (uintptr_t)(&Dst->last_errno), (uintptr_t)(mt));
+ break;
+
+ case INTPTR_TYPE:
+ num_upvals++;
+ dasm_put(Dst, 438, (uintptr_t)(&Dst->last_errno), (uintptr_t)(mt));
+ break;
+
+ case VOID_TYPE:
+ lua_pop(L, 1);
+ dasm_put(Dst, 463, (uintptr_t)(&Dst->last_errno));
+ break;
+
+ case BOOL_TYPE:
+ lua_pop(L, 1);
+ dasm_put(Dst, 474, (uintptr_t)(&Dst->last_errno));
+ break;
+
+ case INT8_TYPE:
+ case INT16_TYPE:
+ case INT32_TYPE:
+ case ENUM_TYPE:
+ lua_pop(L, 1);
+ dasm_put(Dst, 490, (uintptr_t)(&Dst->last_errno));
+ if (mt->is_unsigned) {
+ dasm_put(Dst, 501);
+ } else {
+ dasm_put(Dst, 505);
+ }
+ dasm_put(Dst, 509);
+ break;
+
+ case FLOAT_TYPE:
+ lua_pop(L, 1);
+ dasm_put(Dst, 512, (uintptr_t)(&Dst->last_errno));
+ break;
+
+ case DOUBLE_TYPE:
+ lua_pop(L, 1);
+ dasm_put(Dst, 528, (uintptr_t)(&Dst->last_errno));
+ break;
+
+ default:
+ luaL_error(L, "NYI: call return type");
+ }
+ }
+
+ assert(lua_gettop(L) == top + num_upvals);
+ lua_pushcclosure(L, (lua_CFunction) compile(Dst, L, func, LUA_NOREF), num_upvals);
+}
+