1 | /* -----------------------------------------------------------------------
|
---|
2 | darwin.S - Copyright (c) 2000 John Hornkvist
|
---|
3 |
|
---|
4 | PowerPC Assembly glue.
|
---|
5 |
|
---|
6 | Permission is hereby granted, free of charge, to any person obtaining
|
---|
7 | a copy of this software and associated documentation files (the
|
---|
8 | ``Software''), to deal in the Software without restriction, including
|
---|
9 | without limitation the rights to use, copy, modify, merge, publish,
|
---|
10 | distribute, sublicense, and/or sell copies of the Software, and to
|
---|
11 | permit persons to whom the Software is furnished to do so, subject to
|
---|
12 | the following conditions:
|
---|
13 |
|
---|
14 | The above copyright notice and this permission notice shall be included
|
---|
15 | in all copies or substantial portions of the Software.
|
---|
16 |
|
---|
17 | THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
---|
18 | OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
---|
19 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
---|
20 | IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
---|
21 | OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
---|
22 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
---|
23 | OTHER DEALINGS IN THE SOFTWARE.
|
---|
24 | ----------------------------------------------------------------------- */
|
---|
25 |
|
---|
26 | #define LIBFFI_ASM
|
---|
27 | #include <ffi.h>
|
---|
28 | #define JUMPTARGET(name) name
|
---|
29 | #define L(x) x
|
---|
30 | .text
|
---|
31 | .align 2
|
---|
32 | .globl _ffi_prep_args
|
---|
33 |
|
---|
34 | .text
|
---|
35 | .align 2
|
---|
36 | .globl _ffi_call_DARWIN
|
---|
37 | .text
|
---|
38 | .align 2
|
---|
39 | _ffi_call_DARWIN:
|
---|
40 | LFB0:
|
---|
41 | mr r12,r8 /* We only need r12 until the call,
|
---|
42 | so it doesn't have to be saved... */
|
---|
43 | LFB1:
|
---|
44 | /* Save the old stack pointer as AP. */
|
---|
45 | mr r8,r1
|
---|
46 | LCFI0:
|
---|
47 | /* Allocate the stack space we need. */
|
---|
48 | stwux r1,r1,r4
|
---|
49 |
|
---|
50 | /* Save registers we use. */
|
---|
51 | mflr r9
|
---|
52 |
|
---|
53 | stw r28,-16(r8)
|
---|
54 | stw r29,-12(r8)
|
---|
55 | stw r30, -8(r8)
|
---|
56 | stw r31, -4(r8)
|
---|
57 |
|
---|
58 | stw r9, 8(r8)
|
---|
59 | stw r2, 20(r1)
|
---|
60 | LCFI1:
|
---|
61 |
|
---|
62 | /* Save arguments over call... */
|
---|
63 | mr r31,r5 /* flags, */
|
---|
64 | mr r30,r6 /* rvalue, */
|
---|
65 | mr r29,r7 /* function address, */
|
---|
66 | mr r28,r8 /* our AP. */
|
---|
67 | LCFI2:
|
---|
68 | /* Call ffi_prep_args. */
|
---|
69 | mr r4,r1
|
---|
70 | li r9,0
|
---|
71 |
|
---|
72 | mtctr r12 // r12 holds address of _ffi_prep_args
|
---|
73 | bctrl
|
---|
74 | lwz r2,20(r1)
|
---|
75 |
|
---|
76 | /* Now do the call. */
|
---|
77 | /* Set up cr1 with bits 4-7 of the flags. */
|
---|
78 | mtcrf 0x40,r31
|
---|
79 | /* Get the address to call into CTR. */
|
---|
80 | mtctr r29
|
---|
81 | /* Load all those argument registers. */
|
---|
82 | // We have set up a nice stack frame, just load it into registers.
|
---|
83 | lwz r3, 20+(1*4)(r1)
|
---|
84 | lwz r4, 20+(2*4)(r1)
|
---|
85 | lwz r5, 20+(3*4)(r1)
|
---|
86 | lwz r6, 20+(4*4)(r1)
|
---|
87 | nop
|
---|
88 | lwz r7, 20+(5*4)(r1)
|
---|
89 | lwz r8, 20+(6*4)(r1)
|
---|
90 | lwz r9, 20+(7*4)(r1)
|
---|
91 | lwz r10,20+(8*4)(r1)
|
---|
92 |
|
---|
93 | L1:
|
---|
94 | /* Load all the FP registers. */
|
---|
95 | bf 6,L2 // 2f + 0x18
|
---|
96 | lfd f1,-16-(13*8)(r28)
|
---|
97 | lfd f2,-16-(12*8)(r28)
|
---|
98 | lfd f3,-16-(11*8)(r28)
|
---|
99 | lfd f4,-16-(10*8)(r28)
|
---|
100 | nop
|
---|
101 | lfd f5,-16-(9*8)(r28)
|
---|
102 | lfd f6,-16-(8*8)(r28)
|
---|
103 | lfd f7,-16-(7*8)(r28)
|
---|
104 | lfd f8,-16-(6*8)(r28)
|
---|
105 | nop
|
---|
106 | lfd f9,-16-(5*8)(r28)
|
---|
107 | lfd f10,-16-(4*8)(r28)
|
---|
108 | lfd f11,-16-(3*8)(r28)
|
---|
109 | lfd f12,-16-(2*8)(r28)
|
---|
110 | nop
|
---|
111 | lfd f13,-16-(1*8)(r28)
|
---|
112 |
|
---|
113 | L2:
|
---|
114 | mr r12,r29 // Put the target address in r12 as specified.
|
---|
115 | mtctr r12
|
---|
116 | nop
|
---|
117 | nop
|
---|
118 | /* Make the call. */
|
---|
119 | bctrl
|
---|
120 |
|
---|
121 | /* Now, deal with the return value. */
|
---|
122 | mtcrf 0x01,r31
|
---|
123 |
|
---|
124 | bt 30,L(done_return_value)
|
---|
125 | bt 29,L(fp_return_value)
|
---|
126 | stw r3,0(r30)
|
---|
127 | bf 28,L(done_return_value)
|
---|
128 | stw r4,4(r30)
|
---|
129 |
|
---|
130 | /* Fall through... */
|
---|
131 |
|
---|
132 | L(done_return_value):
|
---|
133 | /* Restore the registers we used and return. */
|
---|
134 | lwz r9, 8(r28)
|
---|
135 | lwz r31, -4(r28)
|
---|
136 | mtlr r9
|
---|
137 | lwz r30, -8(r28)
|
---|
138 | lwz r29,-12(r28)
|
---|
139 | lwz r28,-16(r28)
|
---|
140 | lwz r1,0(r1)
|
---|
141 | blr
|
---|
142 |
|
---|
143 | L(fp_return_value):
|
---|
144 | bf 28,L(float_return_value)
|
---|
145 | stfd f1,0(r30)
|
---|
146 | b L(done_return_value)
|
---|
147 | L(float_return_value):
|
---|
148 | stfs f1,0(r30)
|
---|
149 | b L(done_return_value)
|
---|
150 | LFE1:
|
---|
151 | /* END(_ffi_call_DARWIN) */
|
---|
152 |
|
---|
153 | /* Provide a null definition of _ffi_call_AIX. */
|
---|
154 | .text
|
---|
155 | .align 2
|
---|
156 | .globl _ffi_call_AIX
|
---|
157 | .text
|
---|
158 | .align 2
|
---|
159 | _ffi_call_AIX:
|
---|
160 | blr
|
---|
161 | /* END(_ffi_call_AIX) */
|
---|
162 |
|
---|
163 | .data
|
---|
164 | .section __TEXT,__eh_frame
|
---|
165 | Lframe1:
|
---|
166 | .set L$set$0,LECIE1-LSCIE1
|
---|
167 | .long L$set$0 ; Length of Common Information Entry
|
---|
168 | LSCIE1:
|
---|
169 | .long 0x0 ; CIE Identifier Tag
|
---|
170 | .byte 0x1 ; CIE Version
|
---|
171 | .ascii "zR\0" ; CIE Augmentation
|
---|
172 | .byte 0x1 ; uleb128 0x1; CIE Code Alignment Factor
|
---|
173 | .byte 0x7c ; sleb128 -4; CIE Data Alignment Factor
|
---|
174 | .byte 0x41 ; CIE RA Column
|
---|
175 | .byte 0x1 ; uleb128 0x1; Augmentation size
|
---|
176 | .byte 0x10 ; FDE Encoding (pcrel)
|
---|
177 | .byte 0xc ; DW_CFA_def_cfa
|
---|
178 | .byte 0x1 ; uleb128 0x1
|
---|
179 | .byte 0x0 ; uleb128 0x0
|
---|
180 | .align 2
|
---|
181 | LECIE1:
|
---|
182 | LSFDE1:
|
---|
183 | .set L$set$1,LEFDE1-LASFDE1
|
---|
184 | .long L$set$1 ; FDE Length
|
---|
185 | LASFDE1:
|
---|
186 | .set L$set$2,LASFDE1-Lframe1
|
---|
187 | .long L$set$2 ; FDE CIE offset
|
---|
188 | .long LFB0-. ; FDE initial location
|
---|
189 | .set L$set$3,LFE1-LFB0
|
---|
190 | .long L$set$3 ; FDE address range
|
---|
191 | .byte 0x0 ; uleb128 0x0; Augmentation size
|
---|
192 | .byte 0x4 ; DW_CFA_advance_loc4
|
---|
193 | .set L$set$4,LCFI0-LFB1
|
---|
194 | .long L$set$4
|
---|
195 | .byte 0xd ; DW_CFA_def_cfa_register
|
---|
196 | .byte 0x08 ; uleb128 0x08
|
---|
197 | .byte 0x4 ; DW_CFA_advance_loc4
|
---|
198 | .set L$set$5,LCFI1-LCFI0
|
---|
199 | .long L$set$5
|
---|
200 | .byte 0x11 ; DW_CFA_offset_extended_sf
|
---|
201 | .byte 0x41 ; uleb128 0x41
|
---|
202 | .byte 0x7e ; sleb128 -2
|
---|
203 | .byte 0x9f ; DW_CFA_offset, column 0x1f
|
---|
204 | .byte 0x1 ; uleb128 0x1
|
---|
205 | .byte 0x9e ; DW_CFA_offset, column 0x1e
|
---|
206 | .byte 0x2 ; uleb128 0x2
|
---|
207 | .byte 0x9d ; DW_CFA_offset, column 0x1d
|
---|
208 | .byte 0x3 ; uleb128 0x3
|
---|
209 | .byte 0x9c ; DW_CFA_offset, column 0x1c
|
---|
210 | .byte 0x4 ; uleb128 0x4
|
---|
211 | .byte 0x4 ; DW_CFA_advance_loc4
|
---|
212 | .set L$set$6,LCFI2-LCFI1
|
---|
213 | .long L$set$6
|
---|
214 | .byte 0xd ; DW_CFA_def_cfa_register
|
---|
215 | .byte 0x1c ; uleb128 0x1c
|
---|
216 | .align 2
|
---|
217 | LEFDE1:
|
---|
218 |
|
---|