0
|
1 /*
|
|
2
|
|
3 Package: dyncall
|
|
4 Library: dyncallback
|
|
5 File: dyncallback/dyncall_callback_ppc32_apple.s
|
|
6 Description: Callback Thunk - PowerPC 32-bit System V ABI
|
|
7 License:
|
|
8
|
|
9 Copyright (c) 2007-2015 Daniel Adler <dadler@uni-goettingen.de>,
|
|
10 Tassilo Philipp <tphilipp@potion-studios.com>
|
|
11
|
|
12 Permission to use, copy, modify, and distribute this software for any
|
|
13 purpose with or without fee is hereby granted, provided that the above
|
|
14 copyright notice and this permission notice appear in all copies.
|
|
15
|
|
16 THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
17 WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
18 MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
19 ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
20 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
21 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
22 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
23
|
|
24 */
|
|
25
|
|
26 .machine ppc
|
|
27 .text
|
|
28 .align 2
|
|
29
|
|
30 /* Callback Thunk Entry code for PowerPC 32-bit Darwin/Apple Mac OS X. */
|
|
31
|
|
32
|
|
33 /* Stack Frame Layout:
|
|
34
|
|
35 204 DCValue ( )
|
|
36 56 DCArgs (32+104+4+8 = 148)
|
|
37 24 Parameter area ( 4*8 = 32 )
|
|
38 0 Linkage area ( 24 )
|
|
39
|
|
40
|
|
41 */
|
|
42
|
|
43 /* Constants. */
|
|
44 INT_REGS = 8
|
|
45 FLOAT_REGS = 13
|
|
46 SIZEOF_INT = 4
|
|
47 SIZEOF_DOUBLE = 8
|
|
48
|
|
49
|
|
50 /* Linkage area. */
|
|
51 LINK_SP = 0
|
|
52 LINK_CR = 4
|
|
53 LINK_LR = 8
|
|
54 LINK_OFFSET = 0
|
|
55 LINK_SIZE = 24
|
|
56 /* Parameter area. */
|
|
57 PAR_OFFSET = LINK_SIZE
|
|
58 PAR_SIZE = 32
|
|
59 /* local struct DCArgs */
|
|
60 ARGS_OFFSET = (PAR_OFFSET+PAR_SIZE)
|
|
61 ARGS_SIZE = (SIZEOF_INT*INT_REGS)+(SIZEOF_DOUBLE*FLOAT_REGS) /* = 136 */
|
|
62 /* local struct DCValue */
|
|
63 RESULT_OFFSET = (ARGS_OFFSET+ARGS_SIZE)
|
|
64 RESULT_SIZE = 16
|
|
65 /* additional locals (reg 30/31) */
|
|
66 LOCALS_OFFSET = (RESULT_OFFSET+RESULT_SIZE)
|
|
67 LOCALS_SIZE = 2*SIZEOF_INT
|
|
68 /* total */
|
|
69 FRAME_SIZE = ( (LOCALS_OFFSET+LOCALS_SIZE)+15 & (-16) )
|
|
70
|
|
71 /* struct DCCallback */
|
|
72 DCB_THUNK = 0
|
|
73 DCB_HANDLER = 24
|
|
74 DCB_STACKCLEAN = 28
|
|
75 DCB_USERDATA = 32
|
|
76
|
|
77 /* struct DCArgs */
|
|
78 DCA_IARRAY = 0
|
|
79 DCA_FARRAY = SIZEOF_INT*INT_REGS
|
|
80 DCA_SP = DCA_FARRAY + SIZEOF_DOUBLE*FLOAT_REGS
|
|
81 DCA_ICOUNT = DCA_SP + 4
|
|
82 DCA_FCOUNT = DCA_ICOUNT + 4
|
|
83
|
|
84 iregfile = ARGS_OFFSET+DCA_IARRAY
|
|
85 fregfile = ARGS_OFFSET+DCA_FARRAY
|
|
86 save_sp = ARGS_OFFSET+DCA_SP
|
|
87 icount = ARGS_OFFSET+DCA_ICOUNT
|
|
88 fcount = ARGS_OFFSET+DCA_FCOUNT
|
|
89 .globl _dcCallbackThunkEntry
|
|
90
|
|
91 /*
|
|
92 Thunk entry:
|
235
|
93 r2 = DCCallback*
|
0
|
94 */
|
|
95 _dcCallbackThunkEntry:
|
|
96
|
235
|
97 mflr r0
|
|
98 stw r0, 8(r1) /* store return address */
|
|
99 addi r12, r1, PAR_OFFSET /* temporary r12 = parameter area on callers stack frame */
|
|
100 stwu r1, -FRAME_SIZE(r1) /* save callers stack pointer and make new stack frame. */
|
|
101 stw r3, iregfile+0*4(r1) /* spill 8 integer parameter registers */
|
|
102 stw r4, iregfile+1*4(r1)
|
|
103 stw r5, iregfile+2*4(r1)
|
0
|
104 stw r6, iregfile+3*4(r1)
|
|
105 stw r7, iregfile+4*4(r1)
|
|
106 stw r8, iregfile+5*4(r1)
|
|
107 stw r9, iregfile+6*4(r1)
|
|
108 stw r10,iregfile+7*4(r1)
|
|
109 stfd f1, fregfile+ 0*8(r1) /* spill 13 float parameter registers */
|
|
110 stfd f2, fregfile+ 1*8(r1)
|
|
111 stfd f3, fregfile+ 2*8(r1)
|
|
112 stfd f4, fregfile+ 3*8(r1)
|
|
113 stfd f5, fregfile+ 4*8(r1)
|
|
114 stfd f6, fregfile+ 5*8(r1)
|
|
115 stfd f7, fregfile+ 6*8(r1)
|
|
116 stfd f8, fregfile+ 7*8(r1)
|
|
117 stfd f9, fregfile+ 8*8(r1)
|
|
118 stfd f10,fregfile+ 9*8(r1)
|
|
119 stfd f11,fregfile+10*8(r1)
|
|
120 stfd f12,fregfile+11*8(r1)
|
|
121 stfd f13,fregfile+12*8(r1)
|
|
122 /* initialize struct DCCallback */
|
|
123 stw r12,save_sp(r1) /* init stack pointer */
|
|
124 xor r0, r0, r0 /* init register counters */
|
|
125 stw r0, icount(r1)
|
|
126 stw r0, fcount(r1)
|
|
127 /* invoke callback handler */
|
|
128 mr r3, r2 /* arg 1: DCCallback* pcb */
|
|
129 addi r4, r1, ARGS_OFFSET /* arg 2: DCArgs* args */
|
|
130 addi r5, r1, RESULT_OFFSET /* arg 3: DCValue* result */
|
|
131 lwz r6, DCB_USERDATA(r2) /* arg 4: void* userdata */
|
|
132
|
|
133 /* branch-and-link to DCCallback.handler */
|
|
134 lwz r12, DCB_HANDLER(r2)
|
|
135 mtctr r12
|
|
136 bctrl
|
|
137 /* switch on base result type */
|
|
138 cmpi cr0, r3, 'f
|
|
139 beq .f32
|
|
140 cmpi cr0, r3, 'd
|
|
141 beq .f64
|
|
142 .i64: /* result is C double result */
|
235
|
143 lwz r3, RESULT_OFFSET (r1)
|
|
144 lwz r4, RESULT_OFFSET + 4 (r1)
|
0
|
145 .end:
|
|
146 lwz r1, 0(r1) /* restore stack pointer */
|
|
147 lwz r0, 8(r1) /* load link register with return address */
|
|
148 mtlr r0
|
|
149 blr /* branch back to link register */
|
235
|
150 .f32: /* result is C float result */
|
|
151 lfs f1, RESULT_OFFSET(r1)
|
|
152 b .end
|
|
153 .f64:
|
|
154 lfd f1, RESULT_OFFSET(r1)
|
|
155 b .end
|
0
|
156
|