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:
Diffstat (limited to 'call_x86.dasc')
-rwxr-xr-x[-rw-r--r--]call_x86.dasc342
1 files changed, 175 insertions, 167 deletions
diff --git a/call_x86.dasc b/call_x86.dasc
index 9d7b147..4a72b98 100644..100755
--- a/call_x86.dasc
+++ b/call_x86.dasc
@@ -21,6 +21,14 @@
|.define RET_L, eax
|.endif
+|.if X64
+|.define L_ARG, r12
+|.define TOP, r13
+|.else
+|.define L_ARG, rdi
+|.define TOP, rsi
+|.endif
+
|.if X64WIN
|
|.macro call_rrrp, func, arg0, arg1, arg2, arg3
@@ -173,6 +181,146 @@
|
|.endif
+|.macro epilog
+|.if X64
+| mov TOP, [rbp-16]
+| mov L_ARG, [rbp-8]
+|.else
+| mov TOP, [rbp-8]
+| mov L_ARG, [rbp-4]
+|.endif
+| mov rsp, rbp
+| pop rbp
+| ret
+|.endmacro
+
+|.macro get_errno // note trashes registers
+| call extern GetLastError
+| mov64 rcx, perr
+| mov dword [rcx], eax
+|.endmacro
+
+|.macro too_few_arguments
+| mov ax, 0
+| call_rp extern luaL_error, L_ARG, &"too few arguments"
+|.endmacro
+
+|.macro too_many_arguments
+| mov ax, 0
+| call_rp extern luaL_error, L_ARG, &"too many arguments"
+|.endmacro
+
+|.macro lua_return_arg
+| mov eax, 1
+| epilog
+|.endmacro
+
+|.macro lua_return_void
+| get_errno
+| mov eax, 0
+| epilog
+|.endmacro
+
+|.macro lua_return_double
+|.if X64
+| movq qword [rsp+32], xmm0
+|.else
+| fstp qword [rsp+4] // note get_errno doesn't require any stack on x86
+|.endif
+|
+| get_errno
+|
+|.if X64WIN
+| movq xmm1, qword [rsp+32]
+| mov rcx, L_ARG
+|.elif X64
+| movq xmm0, qword [rsp+32]
+| mov rdi, L_ARG
+|.else
+| mov [rsp], L_ARG
+|.endif
+| call extern lua_pushnumber
+| lua_return_arg
+|.endmacro
+
+|.macro lua_return_bool
+| movzx eax, al
+| mov [rsp+32], eax
+| get_errno
+| mov eax, [rsp+32]
+| call_rr extern lua_pushboolean, L_ARG, rax
+| lua_return_arg
+|.endmacro
+
+|.macro lua_return_int
+| mov [rsp+32], eax
+| get_errno
+| mov eax, [rsp+32]
+| call_rr extern push_int, L_ARG, rax
+| lua_return_arg
+|.endmacro
+
+|.macro lua_return_uint
+| mov [rsp+32], eax
+| get_errno
+| mov eax, [rsp+32]
+| call_rr extern push_uint, L_ARG, rax
+| lua_return_arg
+|.endmacro
+
+|.macro lua_return_long
+| mov [rsp+32], rax
+| get_errno
+| mov rax, [rsp+32]
+| call_rr extern lua_pushinteger, L_ARG, rax
+| lua_return_arg
+|.endmacro
+
+|.macro lua_return_ulong
+| mov [rsp+32], rax
+| get_errno
+| mov rax, [rsp+32]
+| call_rr extern lua_pushinteger, L_ARG, rax
+| lua_return_arg
+|.endmacro
+
+|.macro save_registers
+| // use rbp relative so we store values in the outer stack frame
+|.if X64WIN
+| // use the provided shadow space for int registers above prev rbp and
+| // return address
+| mov [rbp+16], rcx
+| mov [rbp+24], rdx
+| mov [rbp+32], r8
+| mov [rbp+40], r9
+| // use the extra space we added for float registers
+| // -16 to store underneath previous value of L_ARG
+| movq qword [rbp-16], xmm0
+| movq qword [rbp-24], xmm1
+| movq qword [rbp-32], xmm2
+| movq qword [rbp-40], xmm3
+|.elif X64
+| movq qword [rbp-16], xmm0
+| movq qword [rbp-24], xmm1
+| movq qword [rbp-32], xmm2
+| movq qword [rbp-40], xmm3
+| movq qword [rbp-48], xmm4
+| movq qword [rbp-56], xmm5
+| movq qword [rbp-64], xmm6
+| movq qword [rbp-72], xmm7
+| mov [rbp-80], rdi
+| mov [rbp-88], rsi
+| mov [rbp-96], rdx
+| mov [rbp-104], rcx
+| mov [rbp-112], r8
+| mov [rbp-120], r9
+|.else
+| // fastcall, -8 to store underneath previous value of L_ARG
+| mov [rbp-8], ecx
+| mov [rbp-12], edx
+|.endif
+|.endmacro
+
#if defined _WIN64 || defined __amd64__
#define JUMP_SIZE 14
#else
@@ -224,154 +372,7 @@ void compile_globals(struct jit* jit, lua_State* L)
* stack
*/
- |.if X64
- |.define L_ARG, r12
- |.define TOP, r13
- |.else
- |.define L_ARG, rdi
- |.define TOP, rsi
- |.endif
-
- |.macro epilog
- |.if X64
- | mov TOP, [rbp-16]
- | mov L_ARG, [rbp-8]
- |.else
- | mov TOP, [rbp-8]
- | mov L_ARG, [rbp-4]
- |.endif
- | mov rsp, rbp
- | pop rbp
- | ret
- |.endmacro
-
- |.macro get_errno // note trashes registers
- | call extern GetLastError
- | mov64 rcx, perr
- | mov dword [rcx], eax
- |.endmacro
-
- /* the general idea for the return functions is:
- * 1) Save return value on stack
- * 2) Call get_errno (this trashes the registers hence #1)
- * 3) Unpack return value from stack
- * 4) Call lua push function
- * 5) Set eax to number of returned args (0 or 1)
- * 6) Call return which pops our stack frame
- */
-
- |->lua_return_arg:
- | mov eax, 1
- | epilog
-
- |->lua_return_void:
- | get_errno
- | mov eax, 0
- | epilog
-
- |->lua_return_double:
- |.if X64
- | movq qword [rsp+32], xmm0
- |.else
- | fstp qword [rsp+4] // note get_errno doesn't require any stack on x86
- |.endif
- |
- | get_errno
- |
- |.if X64WIN
- | movq xmm1, qword [rsp+32]
- | mov rcx, L_ARG
- |.elif X64
- | movq xmm0, qword [rsp+32]
- | mov rdi, L_ARG
- |.else
- | mov [rsp], L_ARG
- |.endif
- | call extern lua_pushnumber
- | jmp ->lua_return_arg
-
- |->lua_return_bool:
- | movzx eax, al
- | mov [rsp+32], eax
- | get_errno
- | mov eax, [rsp+32]
- | call_rr extern lua_pushboolean, L_ARG, rax
- | jmp ->lua_return_arg
-
- |->lua_return_int:
- | mov [rsp+32], eax
- | get_errno
- | mov eax, [rsp+32]
- | call_rr extern push_int, L_ARG, rax
- | jmp ->lua_return_arg
-
- |->lua_return_uint:
- | mov [rsp+32], eax
- | get_errno
- | mov eax, [rsp+32]
- | call_rr extern push_uint, L_ARG, rax
- | jmp ->lua_return_arg
-#if LUA_VERSION_NUM == 503
- |->lua_return_long:
- | mov [rsp+32], rax
- | get_errno
- | mov rax, [rsp+32]
- | call_rr extern lua_pushinteger, L_ARG, rax
- | jmp ->lua_return_arg
-
- |->lua_return_ulong:
- | mov [rsp+32], rax
- | get_errno
- | mov rax, [rsp+32]
- | call_rr extern lua_pushinteger, L_ARG, rax
- | jmp ->lua_return_arg
-#endif
-
- |->too_few_arguments:
- | mov ax, 0
- | call_rp extern luaL_error, L_ARG, &"too few arguments"
-
- |->too_many_arguments:
- | mov ax, 0
- | call_rp extern luaL_error, L_ARG, &"too many arguments"
-
- |->save_registers:
- | // use rbp relative so we store values in the outer stack frame
- |.if X64WIN
- | // use the provided shadow space for int registers above prev rbp and
- | // return address
- | mov [rbp+16], rcx
- | mov [rbp+24], rdx
- | mov [rbp+32], r8
- | mov [rbp+40], r9
- | // use the extra space we added for float registers
- | // -16 to store underneath previous value of L_ARG
- | movq qword [rbp-16], xmm0
- | movq qword [rbp-24], xmm1
- | movq qword [rbp-32], xmm2
- | movq qword [rbp-40], xmm3
- |.elif X64
- | movq qword [rbp-16], xmm0
- | movq qword [rbp-24], xmm1
- | movq qword [rbp-32], xmm2
- | movq qword [rbp-40], xmm3
- | movq qword [rbp-48], xmm4
- | movq qword [rbp-56], xmm5
- | movq qword [rbp-64], xmm6
- | movq qword [rbp-72], xmm7
- | mov [rbp-80], rdi
- | mov [rbp-88], rsi
- | mov [rbp-96], rdx
- | mov [rbp-104], rcx
- | mov [rbp-112], r8
- | mov [rbp-120], r9
- |.else
- | // fastcall, -8 to store underneath previous value of L_ARG
- | mov [rbp-8], ecx
- | mov [rbp-12], edx
- |.endif
- | ret
compile(Dst, L, NULL, LUA_NOREF);
}
@@ -689,12 +690,12 @@ cfunction compile_callback(lua_State* L, int fidx, int ct_usr, const struct ctyp
|.if X64
| // 8 to realign, 16 for return vars, 32 for local calls, rest to save registers
| sub rsp, 8 + 16 + 32 + REGISTER_STACK_SPACE(ct)
- | call ->save_registers
+ | save_registers
|.else
| // 4 to realign, 16 for return vars, 32 for local calls, rest to save registers
| sub rsp, 4 + 16 + 32 + REGISTER_STACK_SPACE(ct)
if (ct->calling_convention == FAST_CALL) {
- | call ->save_registers
+ | save_registers
}
|.endif
@@ -1088,12 +1089,19 @@ void compile_function(lua_State* L, cfunction func, int ct_usr, const struct cty
| call_r extern lua_gettop, L_ARG
| mov TOP, rax // no need for movzxd rax, eax - high word guarenteed to be zero by x86-64
| cmp rax, nargs
- | jl ->too_few_arguments
-
if (!ct->has_var_arg) {
- | jg ->too_many_arguments
+ | jge >2
+ | too_few_arguments
+ | 2:
+ | jle >1
+ | too_many_arguments
+ } else {
+ | jge >1
+ | too_few_arguments
}
+ | 1:
+
/* no need to zero extend eax returned by lua_gettop to rax as x86-64
* preguarentees that the upper 32 bits will be zero */
| shl rax, 4 // reserve 16 bytes per argument - this maintains the alignment mod 16
@@ -1452,7 +1460,7 @@ void compile_function(lua_State* L, cfunction func, int ct_usr, const struct cty
| call_rrp extern push_cdata, L_ARG, lua_upvalueindex(num_upvals), mbr_ct
| mov rcx, [rsp+32]
| mov [rax], rcx // *(void**) cdata = val
- | jmp ->lua_return_arg
+ | lua_return_arg
} else {
switch (mbr_ct->type) {
@@ -1464,16 +1472,16 @@ void compile_function(lua_State* L, cfunction func, int ct_usr, const struct cty
| call_rrp extern push_cdata, L_ARG, lua_upvalueindex(num_upvals), mbr_ct
| mov rcx, [rsp+32]
| mov [rax], rcx // *(cfunction**) cdata = val
- | jmp ->lua_return_arg
+ | lua_return_arg
break;
case INT64_TYPE:
#if LUA_VERSION_NUM == 503
lua_pop(L, 1);
if (mbr_ct->is_unsigned) {
- | jmp ->lua_return_ulong
+ | lua_return_ulong
} else {
- | jmp ->lua_return_long
+ | lua_return_long
}
#else
num_upvals++;
@@ -1499,7 +1507,7 @@ void compile_function(lua_State* L, cfunction func, int ct_usr, const struct cty
| mov [rax], rdx
|.endif
|
- | jmp ->lua_return_arg
+ | lua_return_arg
#endif
break;
@@ -1529,7 +1537,7 @@ void compile_function(lua_State* L, cfunction func, int ct_usr, const struct cty
| mov [rax+4], ecx
|.endif
|
- | jmp ->lua_return_arg
+ | lua_return_arg
break;
case COMPLEX_DOUBLE_TYPE:
@@ -1559,17 +1567,17 @@ void compile_function(lua_State* L, cfunction func, int ct_usr, const struct cty
| get_errno
|.endif
|
- | jmp ->lua_return_arg
+ | lua_return_arg
break;
case VOID_TYPE:
lua_pop(L, 1);
- | jmp ->lua_return_void
+ | lua_return_void
break;
case BOOL_TYPE:
lua_pop(L, 1);
- | jmp ->lua_return_bool
+ | lua_return_bool
break;
case INT8_TYPE:
@@ -1579,7 +1587,7 @@ void compile_function(lua_State* L, cfunction func, int ct_usr, const struct cty
} else {
| movsx eax, al
}
- | jmp ->lua_return_int
+ | lua_return_int
break;
case INT16_TYPE:
@@ -1589,16 +1597,16 @@ void compile_function(lua_State* L, cfunction func, int ct_usr, const struct cty
} else {
| movsx eax, ax
}
- | jmp ->lua_return_int
+ | lua_return_int
break;
case INT32_TYPE:
case ENUM_TYPE:
lua_pop(L, 1);
if (mbr_ct->is_unsigned) {
- | jmp ->lua_return_uint
+ | lua_return_uint
} else {
- | jmp ->lua_return_int
+ | lua_return_int
}
break;
@@ -1607,12 +1615,12 @@ void compile_function(lua_State* L, cfunction func, int ct_usr, const struct cty
|.if X64
| cvtss2sd xmm0, xmm0
|.endif
- | jmp ->lua_return_double
+ | lua_return_double
break;
case DOUBLE_TYPE:
lua_pop(L, 1);
- | jmp ->lua_return_double
+ | lua_return_double
break;
default: