OSDN Git Service

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