]>
Commit | Line | Data |
---|---|---|
cc4c8975 KH |
1 | #define LIBFFI_ASM |
2 | #include <powerpc/asm.h> | |
3 | ||
c33402e2 | 4 | .file "ppc_closure.S" |
cc4c8975 KH |
5 | |
6 | ENTRY(ffi_closure_SYSV) | |
552cb45a | 7 | .LFB1: |
cc4c8975 | 8 | stwu %r1,-144(%r1) |
552cb45a | 9 | .LCFI0: |
cc4c8975 | 10 | mflr %r0 |
552cb45a | 11 | .LCFI1: |
cc4c8975 KH |
12 | stw %r0,148(%r1) |
13 | ||
14 | # we want to build up an areas for the parameters passed | |
15 | # in registers (both floating point and integer) | |
16 | ||
17 | # so first save gpr 3 to gpr 10 (aligned to 4) | |
18 | stw %r3, 16(%r1) | |
19 | stw %r4, 20(%r1) | |
20 | stw %r5, 24(%r1) | |
21 | stw %r6, 28(%r1) | |
22 | stw %r7, 32(%r1) | |
23 | stw %r8, 36(%r1) | |
24 | stw %r9, 40(%r1) | |
25 | stw %r10,44(%r1) | |
26 | ||
27 | # next save fpr 1 to fpr 8 (aligned to 8) | |
28 | stfd %f1, 48(%r1) | |
29 | stfd %f2, 56(%r1) | |
30 | stfd %f3, 64(%r1) | |
31 | stfd %f4, 72(%r1) | |
32 | stfd %f5, 80(%r1) | |
33 | stfd %f6, 88(%r1) | |
34 | stfd %f7, 96(%r1) | |
35 | stfd %f8, 104(%r1) | |
36 | ||
37 | # set up registers for the routine that actually does the work | |
38 | # get the context pointer from the trampoline | |
39 | mr %r3,%r11 | |
40 | ||
41 | # now load up the pointer to the result storage | |
42 | addi %r4,%r1,112 | |
43 | ||
44 | # now load up the pointer to the saved gpr registers | |
45 | addi %r5,%r1,16 | |
46 | ||
47 | # now load up the pointer to the saved fpr registers */ | |
48 | addi %r6,%r1,48 | |
49 | ||
50 | # now load up the pointer to the outgoing parameter | |
51 | # stack in the previous frame | |
52 | # i.e. the previous frame pointer + 8 | |
53 | addi %r7,%r1,152 | |
54 | ||
55 | # make the call | |
56 | bl JUMPTARGET(ffi_closure_helper_SYSV) | |
57 | ||
58 | # now r3 contains the return type | |
59 | # so use it to look up in a table | |
60 | # so we know how to deal with each type | |
61 | ||
62 | # look up the proper starting point in table | |
63 | # by using return type as offset | |
64 | addi %r5,%r1,112 # get pointer to results area | |
c33402e2 FS |
65 | bl .Lget_ret_type0_addr # get pointer to .Lret_type0 into LR |
66 | mflr %r4 # move to r4 | |
67 | slwi %r3,%r3,4 # now multiply return type by 16 | |
68 | add %r3,%r3,%r4 # add contents of table to table address | |
cc4c8975 KH |
69 | mtctr %r3 |
70 | bctr # jump to it | |
552cb45a | 71 | .LFE1: |
cc4c8975 | 72 | |
c33402e2 FS |
73 | # Each of the ret_typeX code fragments has to be exactly 16 bytes long |
74 | # (4 instructions). For cache effectiveness we align to a 16 byte boundary | |
75 | # first. | |
76 | .align 4 | |
77 | ||
78 | nop | |
79 | nop | |
80 | nop | |
81 | .Lget_ret_type0_addr: | |
82 | blrl | |
83 | ||
84 | # case FFI_TYPE_VOID | |
85 | .Lret_type0: | |
86 | b .Lfinish | |
87 | nop | |
88 | nop | |
89 | nop | |
90 | ||
91 | # case FFI_TYPE_INT | |
92 | .Lret_type1: | |
93 | lwz %r3,0(%r5) | |
94 | b .Lfinish | |
95 | nop | |
96 | nop | |
97 | ||
98 | # case FFI_TYPE_FLOAT | |
99 | .Lret_type2: | |
cc4c8975 | 100 | lfs %f1,0(%r5) |
c33402e2 FS |
101 | b .Lfinish |
102 | nop | |
103 | nop | |
104 | ||
105 | # case FFI_TYPE_DOUBLE | |
106 | .Lret_type3: | |
107 | lfd %f1,0(%r5) | |
108 | b .Lfinish | |
109 | nop | |
110 | nop | |
111 | ||
112 | # case FFI_TYPE_LONGDOUBLE | |
113 | .Lret_type4: | |
114 | lfd %f1,0(%r5) | |
115 | b .Lfinish | |
116 | nop | |
117 | nop | |
118 | ||
119 | # case FFI_TYPE_UINT8 | |
120 | .Lret_type5: | |
121 | lbz %r3,3(%r5) | |
122 | b .Lfinish | |
123 | nop | |
124 | nop | |
125 | ||
126 | # case FFI_TYPE_SINT8 | |
127 | .Lret_type6: | |
128 | lbz %r3,3(%r5) | |
129 | extsb %r3,%r3 | |
130 | b .Lfinish | |
131 | nop | |
132 | ||
133 | # case FFI_TYPE_UINT16 | |
134 | .Lret_type7: | |
135 | lhz %r3,2(%r5) | |
136 | b .Lfinish | |
137 | nop | |
138 | nop | |
139 | ||
140 | # case FFI_TYPE_SINT16 | |
141 | .Lret_type8: | |
142 | lha %r3,2(%r5) | |
143 | b .Lfinish | |
144 | nop | |
145 | nop | |
146 | ||
147 | # case FFI_TYPE_UINT32 | |
148 | .Lret_type9: | |
149 | lwz %r3,0(%r5) | |
150 | b .Lfinish | |
151 | nop | |
152 | nop | |
153 | ||
154 | # case FFI_TYPE_SINT32 | |
155 | .Lret_type10: | |
156 | lwz %r3,0(%r5) | |
157 | b .Lfinish | |
158 | nop | |
159 | nop | |
160 | ||
161 | # case FFI_TYPE_UINT64 | |
162 | .Lret_type11: | |
cc4c8975 KH |
163 | lwz %r3,0(%r5) |
164 | lwz %r4,4(%r5) | |
c33402e2 FS |
165 | b .Lfinish |
166 | nop | |
167 | ||
168 | # case FFI_TYPE_SINT64 | |
169 | .Lret_type12: | |
cc4c8975 | 170 | lwz %r3,0(%r5) |
c33402e2 FS |
171 | lwz %r4,4(%r5) |
172 | b .Lfinish | |
173 | nop | |
174 | ||
175 | # case FFI_TYPE_STRUCT | |
176 | .Lret_type13: | |
177 | b .Lfinish | |
178 | nop | |
179 | nop | |
180 | nop | |
181 | ||
182 | # case FFI_TYPE_POINTER | |
183 | .Lret_type14: | |
184 | lwz %r3,0(%r5) | |
185 | b .Lfinish | |
186 | nop | |
187 | nop | |
188 | ||
189 | # case done | |
190 | .Lfinish: | |
cc4c8975 | 191 | |
c33402e2 | 192 | lwz %r0,148(%r1) |
cc4c8975 | 193 | mtlr %r0 |
c33402e2 | 194 | addi %r1,%r1,144 |
cc4c8975 KH |
195 | blr |
196 | END(ffi_closure_SYSV) | |
197 | ||
552cb45a AH |
198 | .section ".eh_frame","aw" |
199 | __FRAME_BEGIN__: | |
200 | .4byte .LECIE1-.LSCIE1 # Length of Common Information Entry | |
201 | .LSCIE1: | |
202 | .4byte 0x0 # CIE Identifier Tag | |
203 | .byte 0x1 # CIE Version | |
204 | .ascii "\0" # CIE Augmentation | |
205 | .byte 0x1 # uleb128 0x1; CIE Code Alignment Factor | |
206 | .byte 0x7c # sleb128 -4; CIE Data Alignment Factor | |
207 | .byte 0x41 # CIE RA Column | |
208 | .byte 0xc # DW_CFA_def_cfa | |
209 | .byte 0x1 # uleb128 0x1 | |
210 | .byte 0x0 # uleb128 0x0 | |
211 | .align 2 | |
212 | .LECIE1: | |
213 | .LSFDE1: | |
214 | .4byte .LEFDE1-.LASFDE1 # FDE Length | |
215 | .LASFDE1: | |
216 | .4byte .LASFDE1-__FRAME_BEGIN__ # FDE CIE offset | |
217 | .4byte .LFB1 # FDE initial location | |
218 | .4byte .LFE1-.LFB1 # FDE address range | |
219 | .byte 0x4 # DW_CFA_advance_loc4 | |
220 | .4byte .LCFI0-.LFB1 | |
221 | .byte 0xe # DW_CFA_def_cfa_offset | |
222 | .byte 144,1 # uleb128 144 | |
223 | .byte 0x4 # DW_CFA_advance_loc4 | |
224 | .4byte .LCFI1-.LCFI0 | |
225 | .byte 0x2f # DW_CFA_GNU_negative_offset_extended | |
226 | .byte 0x41 # uleb128 0x41 | |
227 | .byte 0x1 # uleb128 0x1 | |
228 | .align 2 | |
229 | .LEFDE1: |