# HG changeset patch # User cslag # Date 1465345632 -7200 # Node ID b15d814ba27430de786d750494529d0a9ebeb3c7 # Parent b7a9b524f0c3e12d47fdcb35749a663636284c04 - mostly functional mips o32 callbacks (seems to still have problems with 64bit params) diff -r b7a9b524f0c3 -r b15d814ba274 dyncallback/dyncall_callback_mips_o32_gas.s --- a/dyncallback/dyncall_callback_mips_o32_gas.s Tue Jun 07 09:05:34 2016 +0200 +++ b/dyncallback/dyncall_callback_mips_o32_gas.s Wed Jun 08 02:27:12 2016 +0200 @@ -39,43 +39,47 @@ /* Called by thunk - thunk stores pointer to DCCallback in $12 ($t4), and pointer to called function in $25 ($t9, required for PIC) */ dcCallbackThunkEntry: - .frame $fp,32,$31 /* infos for debugger: reg use, sizes, */ - /*.mask 0x00000000,0 /* int stack usage, */ - /*.fmask 0x00000000,0 /* fp stack usage */ .set noreorder .set nomacro /* Prolog. Just store the minimum, return address, frame pointer, spill area. */ - addiu $sp, $sp, -32 /* open frame: 32b for 8b aligned frame (retval+ra+fp+spill) */ - sw $ra, 20($sp) /* save link register */ - sw $fp, 16($sp) /* save frame pointer */ - nop - move $fp, $sp /* frame pointer = sp */ + subu $sp, 32 /* open frame: 32b for 8b aligned frame (retval+ra+fp+spill) */ + sw $ra, 20($sp) /* save link register */ + + .frame $fp,32,$31 /* specify our frame: fp,size,lr; creates virt $fp */ + + /* Init return value */ + sw $zero, 24($sp) + sw $zero, 28($sp) - /* Since all arguments are in one consecutive block, we'll pass the pointer */ - /* to them as second argument to the callback handler. Caller doesn't spill */ - /* though, so let's write $4-$7 ($a0-$a3) to the dedicated spill area, first */ - /* (which is in _caller's_ frame). */ - sw $7, 44($sp) - sw $6, 40($sp) - sw $5, 36($sp) - sw $4, 32($sp) + /* If we spill the first four, all arguments will be in one out in consecutive block */ + /* Caller doesn't and it's up to us to spill, so let's write $4-$7 ($a0-$a3) to the */ + /* dedicated spill area, first (at end of _caller's_ frame, so $fp points right to it). */ + sw $7, 12($fp) + sw $6, 8($fp) + sw $5, 4($fp) + sw $4, 0($fp) + + /* Init DCArg, which contains stackptr* to the args, which is $fp. Use padding between */ + /* stored return address and parameter area as place to store it (hacky, but saves 8b) */ + sw $fp, 16($sp) /* Prepare callback handler call. */ - move $4, $12 /* Param 0 = DCCallback*, $12 ($t4) holds pointer to thunk */ - addiu $5, $sp, 16 /* Param 1 = DCArgs*, basically location of where fp is stored */ - addiu $6, $sp, 24 /* Param 2 = results pointer to 8b of local data on stack */ - lw $7, 24($12) /* Param 3 = userdata pointer */ + move $4, $12 /* Param 0 = DCCallback*, $12 ($t4) holds pointer to thunk */ + addiu $5, $sp, 16 /* Param 1 = DCArgs*, pointer to where pointer to args is stored */ + addiu $6, $sp, 24 /* 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) */ - jalr $25 /* jump */ + lw $25, 20($12) /* store handler entry in $25 ($t9), required for PIC */ + jalr $25 /* jump */ nop + /* Copy result in corresponding registers $2-$3 ($v0-$v1) */ + lw $2, 24($sp) + lw $3, 28($sp) + /* Epilog. Tear down frame and return. */ - move $sp, $fp /* restore stack pointer */ - nop lw $ra, 20($sp) /* restore return address */ - lw $fp, 16($sp) /* restore frame pointer */ addiu $sp, $sp, 32 /* close frame */ j $ra /* return */ nop