changeset 103:b15d814ba274

- mostly functional mips o32 callbacks (seems to still have problems with 64bit params)
author cslag
date Wed, 08 Jun 2016 02:27:12 +0200
parents b7a9b524f0c3
children dbca6763f2be
files dyncallback/dyncall_callback_mips_o32_gas.s
diffstat 1 files changed, 29 insertions(+), 25 deletions(-) [+]
line wrap: on
line diff
--- 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