0
|
1 /*
|
|
2
|
|
3 Package: dyncall
|
|
4 Library: dyncallback
|
|
5 File: dyncallback/dyncall_callback_ppc32.S
|
|
6 Description: Callback Thunk Entry for PowerPC 32-bit System V Big-Endian ABI
|
|
7 License:
|
|
8
|
|
9 Copyright (c) 2015 Daniel Adler <dadler@uni-goettingen.de>
|
|
10
|
|
11 Permission to use, copy, modify, and distribute this software for any
|
|
12 purpose with or without fee is hereby granted, provided that the above
|
|
13 copyright notice and this permission notice appear in all copies.
|
|
14
|
|
15 THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
16 WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
17 MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
18 ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
19 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
20 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
21 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
22
|
|
23 */
|
|
24
|
|
25
|
|
26 #include "../portasm/portasm-ppc.S"
|
|
27
|
239
|
28 .machine ppc
|
|
29 .text
|
|
30 .align 2
|
0
|
31
|
|
32 /* Struct DCCallback */
|
|
33
|
239
|
34 DCB_THUNK = 0
|
|
35 DCB_HANDLER = 24
|
|
36 DCB_CLEANUP = 28
|
|
37 DCB_USERDATA = 32
|
0
|
38
|
|
39 /* Struct DCArgs */
|
|
40
|
|
41 ARGS_IREGS = 0
|
|
42 ARGS_FREGS = ARGS_IREGS + 4*8
|
|
43 ARGS_SP = ARGS_FREGS + 8*13
|
|
44 ARGS_ICNT = ARGS_SP + 4
|
|
45 ARGS_FCNT = ARGS_ICNT + 4
|
|
46 ARGS_SIZE = ARGS_FCNT + 4
|
|
47
|
|
48 /* Struct DCValue */
|
|
49
|
|
50 RESULT_SIZE = 8
|
|
51
|
|
52 /* Stack Offsets: */
|
|
53
|
|
54 SP_PREV = 0
|
|
55 SP_LR = (SP_PREV + 4)
|
|
56 SP_PAR = SP_LR + 4
|
|
57 PAR_SZ = 0
|
|
58 SP_ARGS = SP_PAR + PAR_SZ
|
|
59 SP_IREGS = SP_ARGS + ARGS_IREGS
|
|
60 SP_FREGS = SP_ARGS + ARGS_FREGS
|
|
61 SP_SP = SP_ARGS + ARGS_SP
|
|
62 SP_ICNT = SP_ARGS + ARGS_ICNT
|
|
63 SP_FCNT = SP_ARGS + ARGS_FCNT
|
|
64 SP_RESULT = SP_ARGS + ARGS_SIZE
|
|
65 SP_SIZE = SP_RESULT + RESULT_SIZE
|
|
66
|
|
67 #define ALIGN(M,X) ( M+(X-1) & (-X) )
|
|
68
|
|
69 FRAMESIZE = ALIGN(SP_SIZE,16)
|
|
70
|
|
71 GLOBAL_C(dcCallbackThunkEntry)
|
|
72 ENTRY_C(dcCallbackThunkEntry)
|
|
73
|
|
74 /* --------------------------------------------------------------------------
|
|
75
|
|
76 Input:
|
239
|
77 r1 Stack Pointer
|
|
78 r3-r10 Integer Arguments
|
|
79 f1-f8 Floating-point Arguments
|
|
80 r11 Thunk Pointer
|
0
|
81
|
|
82 */
|
239
|
83
|
0
|
84 /* prolog */
|
|
85
|
239
|
86 mflr r0
|
|
87 stw r0, SP_LR(r1) /* store return address */
|
|
88 addi r12,r1, SP_PAR /* temporary r12: parameter area on callers stack frame */
|
0
|
89 stwu r1, -FRAMESIZE(r1)
|
239
|
90
|
|
91 stw r3, SP_IREGS + 0*4(r1) /* spill 8 integer parameter registers */
|
|
92 stw r4, SP_IREGS + 1*4(r1)
|
|
93 stw r5, SP_IREGS + 2*4(r1)
|
0
|
94 stw r6, SP_IREGS + 3*4(r1)
|
|
95 stw r7, SP_IREGS + 4*4(r1)
|
|
96 stw r8, SP_IREGS + 5*4(r1)
|
|
97 stw r9, SP_IREGS + 6*4(r1)
|
|
98 stw r10,SP_IREGS + 7*4(r1)
|
239
|
99
|
|
100 stfd f1, SP_FREGS + 0*8(r1) /* spill 8 (of 13) float parameter registers */
|
0
|
101 stfd f2, SP_FREGS + 1*8(r1)
|
|
102 stfd f3, SP_FREGS + 2*8(r1)
|
|
103 stfd f4, SP_FREGS + 3*8(r1)
|
|
104 stfd f5, SP_FREGS + 4*8(r1)
|
|
105 stfd f6, SP_FREGS + 5*8(r1)
|
|
106 stfd f7, SP_FREGS + 6*8(r1)
|
|
107 stfd f8, SP_FREGS + 7*8(r1)
|
|
108
|
239
|
109 stw r12,SP_SP(r1) /* init stack pointer */
|
|
110 xor r0, r0, r0 /* init register counters */
|
|
111 stw r0, SP_ICNT(r1)
|
|
112 stw r0, SP_FCNT(r1)
|
|
113 stw r0, SP_RESULT(r1) /* init result object */
|
|
114 stw r0, SP_RESULT + 4(r1)
|
|
115 /* invoke callback handler */
|
|
116 mr r3, r11 /* arg 1: DCCallback* pcb (r11 = thunk ptr) */
|
|
117 addi r4, r1, SP_ARGS /* arg 2: DCArgs* args */
|
|
118 addi r5, r1, SP_RESULT /* arg 3: DCValue* result */
|
|
119 lwz r6, DCB_USERDATA(r11) /* arg 4: void* userdata */
|
0
|
120
|
239
|
121 /* branch-and-link to DCCallback.handler */
|
|
122 lwz r12, DCB_HANDLER(r11)
|
|
123 mtctr r12
|
0
|
124 bctrl
|
239
|
125 /* check result type */
|
|
126 cmpi cr0, r3, 'f
|
|
127 beq .f32
|
|
128 cmpi cr0, r3, 'd
|
|
129 beq .f64
|
0
|
130 .i64:
|
239
|
131 lwz r3, SP_RESULT (r1)
|
|
132 lwz r4, SP_RESULT + 4 (r1)
|
0
|
133 .end:
|
239
|
134 lwz r1, SP_PREV(r1) /* restore stack pointer */
|
|
135 lwz r0, SP_LR(r1) /* load link register with return address */
|
|
136 mtlr r0
|
|
137 blr /* branch back to link register */
|
|
138 .f32:
|
|
139 lfs f1, SP_RESULT(r1)
|
|
140 b .end
|
0
|
141 .f64:
|
239
|
142 lfd f1, SP_RESULT(r1)
|
|
143 b .end
|
|
144
|