Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-winehq
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-winehq
Commits
6647987e
Commit
6647987e
authored
Apr 30, 2024
by
Alexandre Julliard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
rpcrt4: Move call_server_func() to a separate file.
And build it as x86-64 code on ARM64EC.
parent
fb8ae8ca
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
197 additions
and
231 deletions
+197
-231
ndr_stubless.c
dlls/rpcrt4/ndr_stubless.c
+2
-231
thunks.c
dlls/rpcrt4/thunks.c
+195
-0
No files found.
dlls/rpcrt4/ndr_stubless.c
View file @
6647987e
...
...
@@ -1061,63 +1061,6 @@ __ASM_GLOBAL_FUNC( NdrClientCall2,
#endif
#if defined(__aarch64__) || defined(__arm__)
static
void
__attribute__
((
used
))
args_stack_to_regs
(
void
**
args
,
void
**
regs
,
void
**
stack
,
const
NDR_PROC_PARTIAL_OIF_HEADER
*
header
)
{
const
NDR_PROC_HEADER_EXTS
*
ext
=
(
const
NDR_PROC_HEADER_EXTS
*
)(
header
+
1
);
unsigned
int
i
,
size
,
count
,
pos
;
unsigned
char
*
data
;
#ifdef __arm__
const
NDR_PARAM_OIF
*
params
=
(
const
NDR_PARAM_OIF
*
)((
const
char
*
)
ext
+
ext
->
Size
);
for
(
i
=
0
;
i
<
header
->
number_of_params
;
i
++
)
if
(
params
[
i
].
attr
.
IsIn
&&
params
[
i
].
attr
.
IsBasetype
)
{
int
*
arg
=
(
int
*
)((
char
*
)
args
+
params
[
i
].
stack_offset
);
switch
(
params
[
i
].
u
.
type_format_char
)
{
case
FC_BYTE
:
case
FC_USMALL
:
*
arg
=
(
unsigned
char
)
*
arg
;
break
;
case
FC_CHAR
:
case
FC_SMALL
:
*
arg
=
(
signed
char
)
*
arg
;
break
;
case
FC_WCHAR
:
case
FC_USHORT
:
*
arg
=
(
unsigned
short
)
*
arg
;
break
;
case
FC_SHORT
:
*
arg
=
(
short
)
*
arg
;
break
;
}
}
#endif
if
(
ext
->
Size
<
sizeof
(
*
ext
)
+
3
)
return
;
data
=
(
unsigned
char
*
)(
ext
+
1
);
size
=
min
(
ext
->
Size
-
sizeof
(
*
ext
)
-
3
,
data
[
2
]
);
data
+=
3
;
for
(
i
=
pos
=
0
;
i
<
size
;
i
++
,
pos
++
)
{
if
(
data
[
i
]
<
0x80
)
continue
;
else
if
(
data
[
i
]
<
0x94
)
regs
[
data
[
i
]
-
0x80
]
=
args
[
pos
];
else
if
(
data
[
i
]
==
0x9d
)
/* repeat */
{
if
(
i
+
3
>=
size
)
break
;
count
=
data
[
i
+
2
]
+
(
data
[
i
+
3
]
<<
8
);
memcpy
(
&
stack
[
pos
+
(
signed
char
)
data
[
i
+
1
]],
&
args
[
pos
],
count
*
sizeof
(
*
args
)
);
pos
+=
count
-
1
;
i
+=
3
;
}
else
if
(
data
[
i
]
<
0xa0
)
continue
;
else
stack
[
pos
+
(
signed
char
)
data
[
i
]]
=
args
[
pos
];
}
}
static
void
**
args_regs_to_stack
(
void
**
regs
,
void
**
fpu_regs
,
const
NDR_PROC_PARTIAL_OIF_HEADER
*
header
)
{
static
const
unsigned
int
nb_gpregs
=
sizeof
(
void
*
);
/* 4 gpregs on arm32, 8 on arm64 */
...
...
@@ -1152,180 +1095,8 @@ static void **args_regs_to_stack( void **regs, void **fpu_regs, const NDR_PROC_P
}
#endif
/* Calls a function with the specified arguments, restoring the stack
* properly afterwards as we don't know the calling convention of the
* function */
#if defined __i386__ && defined _MSC_VER
__declspec
(
naked
)
LONG_PTR
__cdecl
call_server_func
(
SERVER_ROUTINE
func
,
unsigned
char
*
args
,
unsigned
int
stack_size
,
const
NDR_PROC_PARTIAL_OIF_HEADER
*
header
)
{
__asm
{
push
ebp
mov
ebp
,
esp
push
edi
;
Save
registers
push
esi
mov
eax
,
[
ebp
+
16
]
;
Get
stack
size
sub
esp
,
eax
;
Make
room
in
stack
for
arguments
and
esp
,
0xFFFFFFF0
mov
edi
,
esp
mov
ecx
,
eax
mov
esi
,
[
ebp
+
12
]
shr
ecx
,
2
cld
rep
movsd
;
Copy
dword
blocks
call
[
ebp
+
8
]
;
Call
function
lea
esp
,
[
ebp
-
8
]
;
Restore
stack
pop
esi
;
Restore
registers
pop
edi
pop
ebp
ret
}
}
#elif defined __i386__ && defined __GNUC__
LONG_PTR
__cdecl
call_server_func
(
SERVER_ROUTINE
func
,
unsigned
char
*
args
,
unsigned
int
stack_size
,
const
NDR_PROC_PARTIAL_OIF_HEADER
*
header
);
__ASM_GLOBAL_FUNC
(
call_server_func
,
"pushl %ebp
\n\t
"
__ASM_CFI
(
".cfi_adjust_cfa_offset 4
\n\t
"
)
__ASM_CFI
(
".cfi_rel_offset %ebp,0
\n\t
"
)
"movl %esp,%ebp
\n\t
"
__ASM_CFI
(
".cfi_def_cfa_register %ebp
\n\t
"
)
"pushl %edi
\n\t
"
/* Save registers */
__ASM_CFI
(
".cfi_rel_offset %edi,-4
\n\t
"
)
"pushl %esi
\n\t
"
__ASM_CFI
(
".cfi_rel_offset %esi,-8
\n\t
"
)
"movl 16(%ebp), %eax
\n\t
"
/* Get stack size */
"subl %eax, %esp
\n\t
"
/* Make room in stack for arguments */
"andl $~15, %esp
\n\t
"
/* Make sure stack has 16-byte alignment for Mac OS X */
"movl %esp, %edi
\n\t
"
"movl %eax, %ecx
\n\t
"
"movl 12(%ebp), %esi
\n\t
"
"shrl $2, %ecx
\n\t
"
/* divide by 4 */
"cld
\n\t
"
"rep; movsl
\n\t
"
/* Copy dword blocks */
"call *8(%ebp)
\n\t
"
/* Call function */
"leal -8(%ebp), %esp
\n\t
"
/* Restore stack */
"popl %esi
\n\t
"
/* Restore registers */
__ASM_CFI
(
".cfi_same_value %esi
\n\t
"
)
"popl %edi
\n\t
"
__ASM_CFI
(
".cfi_same_value %edi
\n\t
"
)
"popl %ebp
\n\t
"
__ASM_CFI
(
".cfi_def_cfa %esp,4
\n\t
"
)
__ASM_CFI
(
".cfi_same_value %ebp
\n\t
"
)
"ret"
)
#elif defined __x86_64__
LONG_PTR
__cdecl
call_server_func
(
SERVER_ROUTINE
func
,
unsigned
char
*
args
,
unsigned
int
stack_size
,
const
NDR_PROC_PARTIAL_OIF_HEADER
*
header
);
__ASM_GLOBAL_FUNC
(
call_server_func
,
"pushq %rbp
\n\t
"
__ASM_SEH
(
".seh_pushreg %rbp
\n\t
"
)
__ASM_CFI
(
".cfi_adjust_cfa_offset 8
\n\t
"
)
__ASM_CFI
(
".cfi_rel_offset %rbp,0
\n\t
"
)
"movq %rsp,%rbp
\n\t
"
__ASM_SEH
(
".seh_setframe %rbp,0
\n\t
"
)
__ASM_CFI
(
".cfi_def_cfa_register %rbp
\n\t
"
)
"pushq %rsi
\n\t
"
__ASM_SEH
(
".seh_pushreg %rsi
\n\t
"
)
__ASM_CFI
(
".cfi_rel_offset %rsi,-8
\n\t
"
)
"pushq %rdi
\n\t
"
__ASM_SEH
(
".seh_pushreg %rdi
\n\t
"
)
__ASM_SEH
(
".seh_endprologue
\n\t
"
)
__ASM_CFI
(
".cfi_rel_offset %rdi,-16
\n\t
"
)
"movq %rcx,%rax
\n\t
"
/* function to call */
"movq $32,%rcx
\n\t
"
/* allocate max(32,stack_size) bytes of stack space */
"cmpq %rcx,%r8
\n\t
"
"cmovgq %r8,%rcx
\n\t
"
"subq %rcx,%rsp
\n\t
"
"andq $~15,%rsp
\n\t
"
"movq %r8,%rcx
\n\t
"
"shrq $3,%rcx
\n\t
"
"movq %rsp,%rdi
\n\t
"
"movq %rdx,%rsi
\n\t
"
"rep; movsq
\n\t
"
/* copy arguments */
"movq 0(%rsp),%rcx
\n\t
"
"movq 8(%rsp),%rdx
\n\t
"
"movq 16(%rsp),%r8
\n\t
"
"movq 24(%rsp),%r9
\n\t
"
"movq 0(%rsp),%xmm0
\n\t
"
"movq 8(%rsp),%xmm1
\n\t
"
"movq 16(%rsp),%xmm2
\n\t
"
"movq 24(%rsp),%xmm3
\n\t
"
"callq *%rax
\n\t
"
"leaq -16(%rbp),%rsp
\n\t
"
/* restore stack */
"popq %rdi
\n\t
"
__ASM_CFI
(
".cfi_same_value %rdi
\n\t
"
)
"popq %rsi
\n\t
"
__ASM_CFI
(
".cfi_same_value %rsi
\n\t
"
)
__ASM_CFI
(
".cfi_def_cfa_register %rsp
\n\t
"
)
"popq %rbp
\n\t
"
__ASM_CFI
(
".cfi_adjust_cfa_offset -8
\n\t
"
)
__ASM_CFI
(
".cfi_same_value %rbp
\n\t
"
)
"ret"
)
#elif defined __arm__
LONG_PTR
__cdecl
call_server_func
(
SERVER_ROUTINE
func
,
unsigned
char
*
args
,
unsigned
int
stack_size
,
const
NDR_PROC_PARTIAL_OIF_HEADER
*
header
);
__ASM_GLOBAL_FUNC
(
call_server_func
,
"push {r4,r5,fp,lr}
\n\t
"
".seh_save_regs_w {r4,r5,fp,lr}
\n\t
"
"mov fp, sp
\n\t
"
".seh_save_sp fp
\n\t
"
".seh_endprologue
\n\t
"
"add r2, r2, #20*4+8+4
\n\t
"
"and r2, r2, #~7
\n\t
"
"sub sp, sp, r2
\n\t
"
"mov r4, r0
\n\t
"
/* func */
"mov r0, r1
\n\t
"
/* args */
"add r1, sp, #8
\n\t
"
/* regs */
"add r2, r1, #20*4
\n\t
"
/* stack */
"bl args_stack_to_regs
\n\t
"
"add sp, sp, #8
\n\t
"
"pop {r0-r3}
\n\t
"
"vpop {s0-s15}
\n\t
"
"blx r4
\n\t
"
"mov sp, fp
\n\t
"
"pop {r4,r5,fp,pc}"
)
#elif defined __aarch64__
LONG_PTR
__cdecl
call_server_func
(
SERVER_ROUTINE
func
,
unsigned
char
*
args
,
unsigned
int
stack_size
,
const
NDR_PROC_PARTIAL_OIF_HEADER
*
header
);
__ASM_GLOBAL_FUNC
(
call_server_func
,
"stp x29, x30, [sp, #-0x20]!
\n\t
"
".seh_save_fplr_x 0x20
\n\t
"
"stp x19, x20, [sp, #0x10]
\n\t
"
".seh_save_regp x19, 0x10
\n\t
"
"mov x29, sp
\n\t
"
".seh_set_fp
\n\t
"
".seh_endprologue
\n\t
"
"add x9, x2, #16*8+15
\n\t
"
"lsr x9, x9, #4
\n\t
"
"sub sp, sp, x9, lsl #4
\n\t
"
"mov x19, x0
\n\t
"
/* func */
"mov x0, x1
\n\t
"
/* args */
"mov x1, sp
\n\t
"
/* regs */
"add x2, sp, #16*8
\n\t
"
/* stack */
"bl args_stack_to_regs
\n\t
"
"ldp x2, x3, [sp, #0x10]
\n\t
"
"ldp x4, x5, [sp, #0x20]
\n\t
"
"ldp x6, x7, [sp, #0x30]
\n\t
"
"ldp d0, d1, [sp, #0x40]
\n\t
"
"ldp d2, d3, [sp, #0x50]
\n\t
"
"ldp d4, d5, [sp, #0x60]
\n\t
"
"ldp d6, d7, [sp, #0x70]
\n\t
"
"ldp x0, x1, [sp], #0x80
\n\t
"
"blr x19
\n\t
"
"mov sp, x29
\n\t
"
"ldp x19, x20, [sp, #0x10]
\n\t
"
"ldp x29, x30, [sp], #0x20
\n\t
"
"ret"
)
#else
#warning call_server_func not implemented for your architecture
LONG_PTR
__cdecl
call_server_func
(
SERVER_ROUTINE
func
,
unsigned
char
*
args
,
unsigned
short
stack_size
,
const
NDR_PROC_PARTIAL_OIF_HEADER
*
header
)
{
FIXME
(
"Not implemented for your architecture
\n
"
);
return
0
;
}
#endif
extern
LONG_PTR
__cdecl
call_server_func
(
SERVER_ROUTINE
func
,
unsigned
char
*
args
,
unsigned
int
stack_size
,
const
NDR_PROC_PARTIAL_OIF_HEADER
*
header
);
#ifndef __i386__
LONG_PTR
WINAPI
ndr_stubless_client_call
(
unsigned
int
index
,
void
**
args
,
void
**
fpu_regs
)
...
...
dlls/rpcrt4/thunks.c
View file @
6647987e
...
...
@@ -31,6 +31,8 @@
#include "objbase.h"
#include "rpcproxy.h"
#include "cpsf.h"
#include "ndrtypes.h"
#include "ndr_stubless.h"
#include "wine/asm.h"
#define ALL_THUNK_ENTRIES \
...
...
@@ -319,3 +321,196 @@ const struct delegating_vtbl delegating_vtbl =
#undef T
}
};
#if defined(__aarch64__) || defined(__arm__)
static
void
__attribute__
((
used
))
args_stack_to_regs
(
void
**
args
,
void
**
regs
,
void
**
stack
,
const
NDR_PROC_PARTIAL_OIF_HEADER
*
header
)
{
const
NDR_PROC_HEADER_EXTS
*
ext
=
(
const
NDR_PROC_HEADER_EXTS
*
)(
header
+
1
);
unsigned
int
i
,
size
,
count
,
pos
;
unsigned
char
*
data
;
#ifdef __arm__
const
NDR_PARAM_OIF
*
params
=
(
const
NDR_PARAM_OIF
*
)((
const
char
*
)
ext
+
ext
->
Size
);
for
(
i
=
0
;
i
<
header
->
number_of_params
;
i
++
)
if
(
params
[
i
].
attr
.
IsIn
&&
params
[
i
].
attr
.
IsBasetype
)
{
int
*
arg
=
(
int
*
)((
char
*
)
args
+
params
[
i
].
stack_offset
);
switch
(
params
[
i
].
u
.
type_format_char
)
{
case
FC_BYTE
:
case
FC_USMALL
:
*
arg
=
(
unsigned
char
)
*
arg
;
break
;
case
FC_CHAR
:
case
FC_SMALL
:
*
arg
=
(
signed
char
)
*
arg
;
break
;
case
FC_WCHAR
:
case
FC_USHORT
:
*
arg
=
(
unsigned
short
)
*
arg
;
break
;
case
FC_SHORT
:
*
arg
=
(
short
)
*
arg
;
break
;
}
}
#endif
if
(
ext
->
Size
<
sizeof
(
*
ext
)
+
3
)
return
;
data
=
(
unsigned
char
*
)(
ext
+
1
);
size
=
min
(
ext
->
Size
-
sizeof
(
*
ext
)
-
3
,
data
[
2
]
);
data
+=
3
;
for
(
i
=
pos
=
0
;
i
<
size
;
i
++
,
pos
++
)
{
if
(
data
[
i
]
<
0x80
)
continue
;
else
if
(
data
[
i
]
<
0x94
)
regs
[
data
[
i
]
-
0x80
]
=
args
[
pos
];
else
if
(
data
[
i
]
==
0x9d
)
/* repeat */
{
if
(
i
+
3
>=
size
)
break
;
count
=
data
[
i
+
2
]
+
(
data
[
i
+
3
]
<<
8
);
memcpy
(
&
stack
[
pos
+
(
signed
char
)
data
[
i
+
1
]],
&
args
[
pos
],
count
*
sizeof
(
*
args
)
);
pos
+=
count
-
1
;
i
+=
3
;
}
else
if
(
data
[
i
]
<
0xa0
)
continue
;
else
stack
[
pos
+
(
signed
char
)
data
[
i
]]
=
args
[
pos
];
}
}
#endif
/* Call a function with the specified arguments, restoring the stack
* properly afterwards as we don't know the calling convention of the
* function */
#ifdef __i386__
__ASM_GLOBAL_FUNC
(
call_server_func
,
"pushl %ebp
\n\t
"
__ASM_CFI
(
".cfi_adjust_cfa_offset 4
\n\t
"
)
__ASM_CFI
(
".cfi_rel_offset %ebp,0
\n\t
"
)
"movl %esp,%ebp
\n\t
"
__ASM_CFI
(
".cfi_def_cfa_register %ebp
\n\t
"
)
"pushl %edi
\n\t
"
/* Save registers */
__ASM_CFI
(
".cfi_rel_offset %edi,-4
\n\t
"
)
"pushl %esi
\n\t
"
__ASM_CFI
(
".cfi_rel_offset %esi,-8
\n\t
"
)
"movl 16(%ebp), %eax
\n\t
"
/* Get stack size */
"subl %eax, %esp
\n\t
"
/* Make room in stack for arguments */
"andl $~15, %esp
\n\t
"
/* Make sure stack has 16-byte alignment for Mac OS X */
"movl %esp, %edi
\n\t
"
"movl %eax, %ecx
\n\t
"
"movl 12(%ebp), %esi
\n\t
"
"shrl $2, %ecx
\n\t
"
/* divide by 4 */
"cld
\n\t
"
"rep; movsl
\n\t
"
/* Copy dword blocks */
"call *8(%ebp)
\n\t
"
/* Call function */
"leal -8(%ebp), %esp
\n\t
"
/* Restore stack */
"popl %esi
\n\t
"
/* Restore registers */
__ASM_CFI
(
".cfi_same_value %esi
\n\t
"
)
"popl %edi
\n\t
"
__ASM_CFI
(
".cfi_same_value %edi
\n\t
"
)
"popl %ebp
\n\t
"
__ASM_CFI
(
".cfi_def_cfa %esp,4
\n\t
"
)
__ASM_CFI
(
".cfi_same_value %ebp
\n\t
"
)
"ret"
)
#elif defined __x86_64__
__ASM_GLOBAL_FUNC
(
call_server_func
,
"pushq %rbp
\n\t
"
__ASM_SEH
(
".seh_pushreg %rbp
\n\t
"
)
__ASM_CFI
(
".cfi_adjust_cfa_offset 8
\n\t
"
)
__ASM_CFI
(
".cfi_rel_offset %rbp,0
\n\t
"
)
"movq %rsp,%rbp
\n\t
"
__ASM_SEH
(
".seh_setframe %rbp,0
\n\t
"
)
__ASM_CFI
(
".cfi_def_cfa_register %rbp
\n\t
"
)
"pushq %rsi
\n\t
"
__ASM_SEH
(
".seh_pushreg %rsi
\n\t
"
)
__ASM_CFI
(
".cfi_rel_offset %rsi,-8
\n\t
"
)
"pushq %rdi
\n\t
"
__ASM_SEH
(
".seh_pushreg %rdi
\n\t
"
)
__ASM_SEH
(
".seh_endprologue
\n\t
"
)
__ASM_CFI
(
".cfi_rel_offset %rdi,-16
\n\t
"
)
"movq %rcx,%rax
\n\t
"
/* function to call */
"movq $32,%rcx
\n\t
"
/* allocate max(32,stack_size) bytes of stack space */
"cmpq %rcx,%r8
\n\t
"
"cmovgq %r8,%rcx
\n\t
"
"subq %rcx,%rsp
\n\t
"
"andq $~15,%rsp
\n\t
"
"movq %r8,%rcx
\n\t
"
"shrq $3,%rcx
\n\t
"
"movq %rsp,%rdi
\n\t
"
"movq %rdx,%rsi
\n\t
"
"rep; movsq
\n\t
"
/* copy arguments */
"movq 0(%rsp),%rcx
\n\t
"
"movq 8(%rsp),%rdx
\n\t
"
"movq 16(%rsp),%r8
\n\t
"
"movq 24(%rsp),%r9
\n\t
"
"movq 0(%rsp),%xmm0
\n\t
"
"movq 8(%rsp),%xmm1
\n\t
"
"movq 16(%rsp),%xmm2
\n\t
"
"movq 24(%rsp),%xmm3
\n\t
"
"callq *%rax
\n\t
"
"leaq -16(%rbp),%rsp
\n\t
"
/* restore stack */
"popq %rdi
\n\t
"
__ASM_CFI
(
".cfi_same_value %rdi
\n\t
"
)
"popq %rsi
\n\t
"
__ASM_CFI
(
".cfi_same_value %rsi
\n\t
"
)
__ASM_CFI
(
".cfi_def_cfa_register %rsp
\n\t
"
)
"popq %rbp
\n\t
"
__ASM_CFI
(
".cfi_adjust_cfa_offset -8
\n\t
"
)
__ASM_CFI
(
".cfi_same_value %rbp
\n\t
"
)
"ret"
)
#elif defined __arm__
__ASM_GLOBAL_FUNC
(
call_server_func
,
"push {r4,r5,fp,lr}
\n\t
"
".seh_save_regs_w {r4,r5,fp,lr}
\n\t
"
"mov fp, sp
\n\t
"
".seh_save_sp fp
\n\t
"
".seh_endprologue
\n\t
"
"add r2, r2, #20*4+8+4
\n\t
"
"and r2, r2, #~7
\n\t
"
"sub sp, sp, r2
\n\t
"
"mov r4, r0
\n\t
"
/* func */
"mov r0, r1
\n\t
"
/* args */
"add r1, sp, #8
\n\t
"
/* regs */
"add r2, r1, #20*4
\n\t
"
/* stack */
"bl args_stack_to_regs
\n\t
"
"add sp, sp, #8
\n\t
"
"pop {r0-r3}
\n\t
"
"vpop {s0-s15}
\n\t
"
"blx r4
\n\t
"
"mov sp, fp
\n\t
"
"pop {r4,r5,fp,pc}"
)
#elif defined __aarch64__
__ASM_GLOBAL_FUNC
(
call_server_func
,
"stp x29, x30, [sp, #-0x20]!
\n\t
"
".seh_save_fplr_x 0x20
\n\t
"
"stp x19, x20, [sp, #0x10]
\n\t
"
".seh_save_regp x19, 0x10
\n\t
"
"mov x29, sp
\n\t
"
".seh_set_fp
\n\t
"
".seh_endprologue
\n\t
"
"add x9, x2, #16*8+15
\n\t
"
"lsr x9, x9, #4
\n\t
"
"sub sp, sp, x9, lsl #4
\n\t
"
"mov x19, x0
\n\t
"
/* func */
"mov x0, x1
\n\t
"
/* args */
"mov x1, sp
\n\t
"
/* regs */
"add x2, sp, #16*8
\n\t
"
/* stack */
"bl args_stack_to_regs
\n\t
"
"ldp x2, x3, [sp, #0x10]
\n\t
"
"ldp x4, x5, [sp, #0x20]
\n\t
"
"ldp x6, x7, [sp, #0x30]
\n\t
"
"ldp d0, d1, [sp, #0x40]
\n\t
"
"ldp d2, d3, [sp, #0x50]
\n\t
"
"ldp d4, d5, [sp, #0x60]
\n\t
"
"ldp d6, d7, [sp, #0x70]
\n\t
"
"ldp x0, x1, [sp], #0x80
\n\t
"
"blr x19
\n\t
"
"mov sp, x29
\n\t
"
"ldp x19, x20, [sp, #0x10]
\n\t
"
"ldp x29, x30, [sp], #0x20
\n\t
"
"ret"
)
#endif
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment