Mercurial > pub > dyncall > dyncall
diff dyncallback/dyncall_callback_mips_o32.S @ 302:d55f9d508074
- mips softfloat support for o32 callconv (calls and callbacks, little and big endian)
- cleanup of some mips files, removed unnecessary file, renamings..
- doc/manual cleanups, changelog entry
author | Tassilo Philipp |
---|---|
date | Mon, 21 May 2018 02:48:12 +0200 |
parents | dyncallback/dyncall_callback_mips_o32_gas.s@9e677d4c0b6b |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dyncallback/dyncall_callback_mips_o32.S Mon May 21 02:48:12 2018 +0200 @@ -0,0 +1,116 @@ +/* + + Package: dyncall + Library: dyncallback + File: dyncallback/dyncall_callback_mips_o32.S + Description: Callback Thunk - Implementation mips32 o32 + License: + + Copyright (c) 2016 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. + +*/ + + /* input: + $t4 -> thunk + $t4+20 -> cb handler + $t4+24 -> userdata + */ + + .section .mdebug.abi32 + .previous + .abicalls + .text + .align 2 + .globl dcCallbackThunkEntry + .ent dcCallbackThunkEntry + .type dcCallbackThunkEntry, @function + +/* Called by thunk - thunk stores pointer to DCCallback in $12 ($t4), and */ +/* pointer to called function in $25 ($t9, required for PIC) */ +dcCallbackThunkEntry: + .set noreorder + + /* Prolog. Just store the minimum, return address, spill area. */ + /* Frame size of 56b comes from following areas (each 8b aligned): */ + /* local: fpregs:16 + retval:8 + DCArgs:8 */ + /* save: ra:4 (+ pad:4) */ + /* param: spill:16 */ + subu $sp, 56 /* open frame */ + sw $ra, 20($sp) /* save link register */ + + .frame $fp,56,$31 /* specify our frame: fp,size,lr; creates virt $fp */ + /* code below doesn't use $fp though, as n/a with -O1 */ + /* Init return value */ + sw $zero, 32($sp) + sw $zero, 36($sp) + + /* Store the arguments passed via registers somewhere for dcArg* to access. */ + /* For $4-$7 ($a0-$a3), use dedicated spill area (caller doesn't spill, but */ + /* provides it at end of _caller's_ frame, so $fp points right to it). */ + /* For $f12 and $f14 use our space (in local data), which is adjacent. */ +#if defined(DC__ABI_HARDFLOAT) + s.d $f12, 40($sp) /* -16($fp) */ + s.d $f14, 48($sp) /* -8($fp) */ +#endif /* DC__ABI_HARDFLOAT */ + sw $4, 56($sp) /* 0($fp) */ + sw $5, 60($sp) /* 4($fp) */ + sw $6, 64($sp) /* 8($fp) */ + sw $7, 68($sp) /* 12($fp) */ + + /* Init DCArg, which contains reg_count and stackptr* to the args. Point */ + /* stackptr to the area where the non-float args start (which is at $fp). */ + addiu $4, $sp, 56 /* <- non-$fp replacement for: */ + sw $4, 28($sp) /* <- sw $fp, 28($sp) */ +#if defined(DC__ABI_HARDFLOAT) + sw $zero, 24($sp) /* init num float-regs (unused for soft-float) */ +#endif /* DC__ABI_HARDFLOAT */ + + /* Prepare callback handler call. */ + move $4, $12 /* Param 0 = DCCallback*, $12 ($t4) holds pointer to thunk */ + addiu $5, $sp, 24 /* Param 1 = DCArgs*, pointer to where pointer to args is stored */ + addiu $6, $sp, 32 /* Param 2 = results pointer to 8b of local data on stack */ + lw $7, 24($12) /* Param 3 = userdata pointer */ + + lw $25, 20($12) /* store handler entry in $25 ($t9), required for PIC */ + jalr $25 /* jump */ + nop /* branch delay nop */ + + /* Copy result to corresponding registers */ + /* Handle single precision soft-float retvals differently on big-endian */ + /* targets as they are right-justified in their 8b stack lots */ +#if !defined(DC__ABI_HARDFLOAT) && defined(DC__Endian_BIG) + xori $4, $2, 'f' /* $4 = 0 if cb-handler returned 'f' in $2 */ +#endif + lw $2, 32($sp) + lw $3, 36($sp) +#if defined(DC__ABI_HARDFLOAT) + l.d $f0, 32($sp) +#elif defined(DC__Endian_BIG) + bgtz $4, .nonf32r /* if no 'f' returned, $2 and $3 are good */ + nop /* branch delay nop */ + move $2, $3 +.nonf32r: +#endif /* DC__ABI_HARDFLOAT */ + + /* Epilog. Tear down frame and return. */ + lw $ra, 20($sp) /* restore return address */ + addiu $sp, $sp, 56 /* close frame */ + j $ra /* return */ + nop /* branch delay nop */ + + .set reorder + .end dcCallbackThunkEntry + .ident "handwritten" +