Mercurial > pub > dyncall > dyncall
diff dyncall/dyncall_call_arm64.S @ 0:3e629dc19168
initial from svn dyncall-1745
author | Daniel Adler |
---|---|
date | Thu, 19 Mar 2015 22:24:28 +0100 |
parents | |
children | 450c4f06cb14 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dyncall/dyncall_call_arm64.S Thu Mar 19 22:24:28 2015 +0100 @@ -0,0 +1,226 @@ +/* + + Package: dyncall + Library: dyncall + File: dyncall/dyncall_call_arm64.S + Description: Call Kernel for ARM 64-bit Architecture (aka ARM64, AArch64) + License: + + Copyright (c) 2015 Daniel Adler <dadler@uni-goettingen.de>, + Tassilo Philipp <tphilipp@potion-studios.com> + + Permission to use, copy, modify, and distribute this software for any + purpose with or without fee is hereby granted, provided that the above + copyright notice and this permission notice appear in all copies. + + THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +*/ + + + +#include "../portasm/portasm-arm.S" + +/* ============================================================================ + DynCall Call Kernel for ARM 64-bit ARM Architecture + ---------------------------------------------------------------------------- + C Interface: + dcCall_arm64 (DCpointer target, DCpointer data, DCsize size, DCfloat* regdata); + + This Call Kernel was tested on Debian/qemu-debootstrap arm64 jessie. +*/ + +.text + +// +// DynCall Back-End arm64 +// +// Supported ABIs: +// - 'ARM 64-bit AArch64 PCS' (@dadler: work in progress) +// +// Useful Links: +// - http://lxr.free-electrons.com/source/arch/arm64/kernel/stacktrace.c + +GLOBAL_C(dcCall_arm64) +ENTRY_C(dcCall_arm64) + +// input: +// x0: target (address of target) +// x1: data (address of stack copy data) +// x2: size (number of 'pair' 16-byte units) +// x3: regdata (address of register data) + +// prolog: + + stp x29, x30, [sp, #-16]! // allocate frame + mov x29, sp + +// load 64-bit floating-point registers + + ldr d0, [x3,#0 ] + ldr d1, [x3,#8 ] + ldr d2, [x3,#16] + ldr d3, [x3,#24] + ldr d4, [x3,#32] + ldr d5, [x3,#40] + ldr d6, [x3,#48] + ldr d7, [x3,#56] + +// copy to stack + + sub sp, sp, x2 // create call-frame + + eor x4, x4, x4 // x4: cnt = 0 + + mov x5, x1 // x5: read pointer = data + mov x6, sp // x6: write pointer = sp + +.next: + cmp x4, x2 + b.ge .done + + ldp x7, x9, [x5], #16 // get pair from data + stp x7, x9, [x6], #16 // put to stack + add x4, x4, 16 // advance 16 bytes + + b .next + +.done: + +// rescue temp int registers + + mov x9 , x0 // x9: target + add x10, x3, 64 // x3: integer reg buffer + +// load 64-bit integer registers ( 8 x 64-bit ) + + // load register set + + ldr x0, [x10, #0] + ldr x1, [x10, #8] + ldr x2, [x10, #16] + ldr x3, [x10, #24] + ldr x4, [x10, #32] + ldr x5, [x10, #40] + ldr x6, [x10, #48] + ldr x7, [x10, #56] + +// call target: + + blr x9 + +// epilog: + + mov sp, x29 + ldp x29, x30, [sp], 16 + + ret + +#if 0 + + + +// epilog: + + add sp, x28, 0 // remove call record + + ret + + // -- OLD: + + str x27, [sp, 16] // use 1 local var (size) + + + ldr q0, [x3,#0 ] + ldr q1, [x3,#8 ] + ldr q2, [x3,#16] + ldr q3, [x3,#24] + ldr q4, [x3,#32] + ldr q5, [x3,#40] + ldr q6, [x3,#48] + ldr q7, [x3,#56] + + ldr d8, [x3,#32] + ldr d9, [x3,#36] + ldr d10, [x3,#40] + ldr d11, [x3,#44] + ldr d12, [x3,#48] + ldr d13, [x3,#52] + ldr d14, [x3,#56] + ldr d15, [x3,#60] + + + // load float ( 16 x 32-bit ) + + ldr s0, [x3,#0 ] + ldr s1, [x3,#4 ] + ldr s2, [x3,#8 ] + ldr s3, [x3,#12] + ldr s4, [x3,#16] + ldr s5, [x3,#20] + ldr s6, [x3,#24] + ldr s7, [x3,#28] + ldr s8, [x3,#32] + ldr s9, [x3,#36] + ldr s10, [x3,#40] + ldr s11, [x3,#44] + ldr s12, [x3,#48] + ldr s13, [x3,#52] + ldr s14, [x3,#56] + ldr s15, [x3,#60] + + // call + + blr x0 + + // epilog + + ldp x29, x30, [sp], 32 + ret + + // stack copy + + sub sp, sp, x2 // decrement stack by size (x2) + eor x3, x3, x3 // x3 = counter, set to zero + +// .next: + ldr x4, [x1, x3] // x4 = 64-bit stack data + str x4, [sp, x3] // store to stack + add x3, x3, #8 + cmp x3, x2 + blt .next + + + // rescue int registers + + mov x9 , x0 // x9 = code ptr + mov x10, x2 + + // load int ( 8 x 64-bit ) + + ldr x0, [sp, #0] + ldr x1, [sp, #8] + ldr x2, [sp, #16] + ldr x3, [sp, #24] + ldr x4, [sp, #32] + ldr x5, [sp, #40] + ldr x6, [sp, #48] + ldr x7, [sp, #56] + + // call + + blr x9 + + // epilog + + ldp x29, x30, [sp], 32 + ret +#endif + +