comparison dyncallback/dyncall_callback_mips_o32_gas.s @ 104:dbca6763f2be

- complete, working mips o32 callback (using hardware fp); fixes error from last commit, which ignored first 2 float args * currently tested on little endian, only * todo update, manual update, cleanups
author cslag
date Thu, 09 Jun 2016 15:13:53 +0200
parents b15d814ba274
children d595eb90efdd
comparison
equal deleted inserted replaced
103:b15d814ba274 104:dbca6763f2be
35 .align 2 35 .align 2
36 .globl dcCallbackThunkEntry 36 .globl dcCallbackThunkEntry
37 .ent dcCallbackThunkEntry 37 .ent dcCallbackThunkEntry
38 .type dcCallbackThunkEntry, @function 38 .type dcCallbackThunkEntry, @function
39 39
40 /* Called by thunk - thunk stores pointer to DCCallback in $12 ($t4), and pointer to called function in $25 ($t9, required for PIC) */ 40 /* Called by thunk - thunk stores pointer to DCCallback in $12 ($t4), and */
41 /* pointer to called function in $25 ($t9, required for PIC) */
41 dcCallbackThunkEntry: 42 dcCallbackThunkEntry:
42 .set noreorder 43 .set noreorder
43 .set nomacro 44 .set nomacro
44 45
45 /* Prolog. Just store the minimum, return address, frame pointer, spill area. */ 46 /* Prolog. Just store the minimum, return address, spill area. */
46 subu $sp, 32 /* open frame: 32b for 8b aligned frame (retval+ra+fp+spill) */ 47 /* Frame size of 48b comes from following areas (each 8b aligned); */
48 /* local: fpregs:16 + retval:8 + DCArgs:8 */
49 /* save: ra:4 (+ pad:4) */
50 /* param: spill:16 */
51 subu $sp, 56 /* open frame */
47 sw $ra, 20($sp) /* save link register */ 52 sw $ra, 20($sp) /* save link register */
48 53
49 .frame $fp,32,$31 /* specify our frame: fp,size,lr; creates virt $fp */ 54 .frame $fp,56,$31 /* specify our frame: fp,size,lr; creates virt $fp */
50 55
51 /* Init return value */ 56 /* Init return value */
57 sw $zero, 32($sp)
58 sw $zero, 36($sp)
59
60 /* Store the arguments passed via registers somewhere for dcArg* to access. */
61 /* For $4-$7 ($a0-$a3), use dedicated spill area (caller doesn't spill, but */
62 /* provides it at end of _caller's_ frame, so $fp points right to it). */
63 /* For $f12 and $f14 use our space (in local data), which is adjacent. */
64 s.d $f12, 40($sp) /* -16($fp) */
65 s.d $f14, 48($sp) /* -8($fp) */
66 sw $4, 0($fp)
67 sw $5, 4($fp)
68 sw $6, 8($fp)
69 sw $7, 12($fp)
70
71 /* Init DCArg, which contains reg_count and stackptr* to the args. Point */
72 /* stackptr to the area where the non-float args start (which is at $fp). */
52 sw $zero, 24($sp) 73 sw $zero, 24($sp)
53 sw $zero, 28($sp) 74 sw $fp, 28($sp)
54
55 /* If we spill the first four, all arguments will be in one out in consecutive block */
56 /* Caller doesn't and it's up to us to spill, so let's write $4-$7 ($a0-$a3) to the */
57 /* dedicated spill area, first (at end of _caller's_ frame, so $fp points right to it). */
58 sw $7, 12($fp)
59 sw $6, 8($fp)
60 sw $5, 4($fp)
61 sw $4, 0($fp)
62
63 /* Init DCArg, which contains stackptr* to the args, which is $fp. Use padding between */
64 /* stored return address and parameter area as place to store it (hacky, but saves 8b) */
65 sw $fp, 16($sp)
66 75
67 /* Prepare callback handler call. */ 76 /* Prepare callback handler call. */
68 move $4, $12 /* Param 0 = DCCallback*, $12 ($t4) holds pointer to thunk */ 77 move $4, $12 /* Param 0 = DCCallback*, $12 ($t4) holds pointer to thunk */
69 addiu $5, $sp, 16 /* Param 1 = DCArgs*, pointer to where pointer to args is stored */ 78 addiu $5, $sp, 24 /* Param 1 = DCArgs*, pointer to where pointer to args is stored */
70 addiu $6, $sp, 24 /* Param 2 = results pointer to 8b of local data on stack */ 79 addiu $6, $sp, 32 /* Param 2 = results pointer to 8b of local data on stack */
71 lw $7, 24($12) /* Param 3 = userdata pointer */ 80 lw $7, 24($12) /* Param 3 = userdata pointer */
72 81
73 lw $25, 20($12) /* store handler entry in $25 ($t9), required for PIC */ 82 lw $25, 20($12) /* store handler entry in $25 ($t9), required for PIC */
74 jalr $25 /* jump */ 83 jalr $25 /* jump */
75 nop 84 nop /* branch delay nop */
76 85
77 /* Copy result in corresponding registers $2-$3 ($v0-$v1) */ 86 /* Copy result in corresponding registers $2-$3 ($v0-$v1) and $f0 */
78 lw $2, 24($sp) 87 lw $2, 32($sp)
79 lw $3, 28($sp) 88 lw $3, 36($sp)
89 l.d $f0, 32($sp)
80 90
81 /* Epilog. Tear down frame and return. */ 91 /* Epilog. Tear down frame and return. */
82 lw $ra, 20($sp) /* restore return address */ 92 lw $ra, 20($sp) /* restore return address */
83 addiu $sp, $sp, 32 /* close frame */ 93 addiu $sp, $sp, 56 /* close frame */
84 j $ra /* return */ 94 j $ra /* return */
85 nop 95 nop /* branch delay nop */
86 96
87 .set macro 97 .set macro
88 .set reorder 98 .set reorder
89 .end dcCallbackThunkEntry 99 .end dcCallbackThunkEntry
90 .ident "handwritten" 100 .ident "handwritten"