Mercurial > pub > dyncall > dyncall
diff dyncallback/dyncall_callback_ppc32.S @ 0:3e629dc19168
initial from svn dyncall-1745
author | Daniel Adler |
---|---|
date | Thu, 19 Mar 2015 22:24:28 +0100 |
parents | |
children | c04be81f4874 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dyncallback/dyncall_callback_ppc32.S Thu Mar 19 22:24:28 2015 +0100 @@ -0,0 +1,144 @@ +/* + + Package: dyncall + Library: dyncallback + File: dyncallback/dyncall_callback_ppc32.S + Description: Callback Thunk Entry for PowerPC 32-bit System V Big-Endian ABI + License: + + Copyright (c) 2015 Daniel Adler <dadler@uni-goettingen.de> + + 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-ppc.S" + + .machine ppc + .text + .align 2 + +/* Struct DCCallback */ + +DCB_THUNK = 0 +DCB_HANDLER = 24 +DCB_CLEANUP = 28 +DCB_USERDATA = 32 + +/* Struct DCArgs */ + +ARGS_IREGS = 0 +ARGS_FREGS = ARGS_IREGS + 4*8 +ARGS_SP = ARGS_FREGS + 8*13 +ARGS_ICNT = ARGS_SP + 4 +ARGS_FCNT = ARGS_ICNT + 4 +ARGS_SIZE = ARGS_FCNT + 4 + +/* Struct DCValue */ + +RESULT_SIZE = 8 + +/* Stack Offsets: */ + +SP_PREV = 0 +SP_LR = (SP_PREV + 4) +SP_PAR = SP_LR + 4 +PAR_SZ = 0 +SP_ARGS = SP_PAR + PAR_SZ +SP_IREGS = SP_ARGS + ARGS_IREGS +SP_FREGS = SP_ARGS + ARGS_FREGS +SP_SP = SP_ARGS + ARGS_SP +SP_ICNT = SP_ARGS + ARGS_ICNT +SP_FCNT = SP_ARGS + ARGS_FCNT +SP_RESULT = SP_ARGS + ARGS_SIZE +SP_SIZE = SP_RESULT + RESULT_SIZE + +#define ALIGN(M,X) ( M+(X-1) & (-X) ) + +FRAMESIZE = ALIGN(SP_SIZE,16) + +GLOBAL_C(dcCallbackThunkEntry) +ENTRY_C(dcCallbackThunkEntry) + +/* -------------------------------------------------------------------------- + +Input: + r1 Stack Pointer + r3-r10 Integer Arguments + f1-f8 Floating-point Arguments + r11 Thunk Pointer + +*/ + + /* prolog */ + + mflr r0 + stw r0, SP_LR(r1) /* store return address */ + addi r12, r1, SP_PAR /* temporary r12: parameter area on callers stack frame */ + stwu r1, -FRAMESIZE(r1) + + stw r3, SP_IREGS + 0*4(r1) /* spill 8 integer parameter registers */ + stw r4, SP_IREGS + 1*4(r1) + stw r5, SP_IREGS + 2*4(r1) + stw r6, SP_IREGS + 3*4(r1) + stw r7, SP_IREGS + 4*4(r1) + stw r8, SP_IREGS + 5*4(r1) + stw r9, SP_IREGS + 6*4(r1) + stw r10,SP_IREGS + 7*4(r1) + + stfd f1, SP_FREGS + 0*8(r1) /* spill 8 (of 13) float parameter registers */ + stfd f2, SP_FREGS + 1*8(r1) + stfd f3, SP_FREGS + 2*8(r1) + stfd f4, SP_FREGS + 3*8(r1) + stfd f5, SP_FREGS + 4*8(r1) + stfd f6, SP_FREGS + 5*8(r1) + stfd f7, SP_FREGS + 6*8(r1) + stfd f8, SP_FREGS + 7*8(r1) + + stw r12, SP_SP(r1) /* init stack pointer */ + xor r0, r0, r0 /* init register counters */ + stw r0, SP_ICNT(r1) + stw r0, SP_FCNT(r1) + stw r0, SP_RESULT(r1) /* init result object */ + stw r0, SP_RESULT + 4(r1) + /* invoke callback handler */ + mr r3, r11 /* arg 1: DCCallback* pcb (r11 is thunk pointer) */ + addi r4, r1, SP_ARGS /* arg 2: DCArgs* args */ + addi r5, r1, SP_RESULT /* arg 3: DCValue* result */ + lwz r6, DCB_USERDATA(r11) /* arg 4: void* userdata */ + + /* branch-and-link to DCCallback.handler */ + lwz r12, DCB_HANDLER(r11) + mtctr r12 + bctrl + /* check result type */ + cmpi cr0, r3, 'f + beq .f32 + cmpi cr0, r3, 'd + beq .f64 +.i64: + lwz r3, SP_RESULT (r1) + lwz r4, SP_RESULT + 4 (r1) +.end: + lwz r1, SP_PREV(r1) /* restore stack pointer */ + lwz r0, SP_LR(r1) /* load link register with return address */ + mtlr r0 + blr /* branch back to link register */ +.f32: + lfs f1, SP_RESULT(r1) + b .end +.f64: + lfd f1, SP_RESULT(r1) + b .end +