oops - omiited from previous delta:
[official-gcc.git] / libffi / src / powerpc / ppc_closure.S
blobe402fb5cda3f48e3b332c9c0617b5d50140be9ae
1 #define LIBFFI_ASM
2 #include <powerpc/asm.h>
4         .file   "ppc_closure.S"
6 ENTRY(ffi_closure_SYSV)
7 .LFB1:
8         stwu %r1,-144(%r1)
9 .LCFI0:
10         mflr %r0
11 .LCFI1:
12         stw %r0,148(%r1)
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)
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)
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
47         # now load up the pointer to the saved fpr registers */
48         addi %r6,%r1,48
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)
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
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
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
69         mtctr %r3
70         bctr               # jump to it
71 .LFE1:
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
78         nop
79         nop
80         nop
81 .Lget_ret_type0_addr:
82         blrl
84 # case FFI_TYPE_VOID
85 .Lret_type0:
86         b .Lfinish
87         nop
88         nop
89         nop
91 # case FFI_TYPE_INT
92 .Lret_type1:
93         lwz %r3,0(%r5)
94         b .Lfinish
95         nop
96         nop
98 # case FFI_TYPE_FLOAT
99 .Lret_type2:
100         lfs %f1,0(%r5)
101         b .Lfinish
102         nop
103         nop
105 # case FFI_TYPE_DOUBLE
106 .Lret_type3:
107         lfd %f1,0(%r5)
108         b .Lfinish
109         nop
110         nop
112 # case FFI_TYPE_LONGDOUBLE
113 .Lret_type4:
114         lfd %f1,0(%r5)
115         b .Lfinish
116         nop
117         nop
119 # case FFI_TYPE_UINT8
120 .Lret_type5:
121         lbz %r3,3(%r5)
122         b .Lfinish
123         nop
124         nop
126 # case FFI_TYPE_SINT8
127 .Lret_type6:
128         lbz %r3,3(%r5)
129         extsb %r3,%r3
130         b .Lfinish
131         nop
133 # case FFI_TYPE_UINT16
134 .Lret_type7:
135         lhz %r3,2(%r5)
136         b .Lfinish
137         nop
138         nop
140 # case FFI_TYPE_SINT16
141 .Lret_type8:
142         lha %r3,2(%r5)
143         b .Lfinish
144         nop
145         nop
147 # case FFI_TYPE_UINT32
148 .Lret_type9:
149         lwz %r3,0(%r5)
150         b .Lfinish
151         nop
152         nop
154 # case FFI_TYPE_SINT32
155 .Lret_type10:
156         lwz %r3,0(%r5)
157         b .Lfinish
158         nop
159         nop
161 # case FFI_TYPE_UINT64
162 .Lret_type11:
163         lwz %r3,0(%r5)
164         lwz %r4,4(%r5)
165         b .Lfinish
166         nop
168 # case FFI_TYPE_SINT64
169 .Lret_type12:
170         lwz %r3,0(%r5)
171         lwz %r4,4(%r5)
172         b .Lfinish
173         nop
175 # case FFI_TYPE_STRUCT
176 .Lret_type13:
177         b .Lfinish
178         nop
179         nop
180         nop
182 # case FFI_TYPE_POINTER
183 .Lret_type14:
184         lwz %r3,0(%r5)
185         b .Lfinish
186         nop
187         nop
189 # case done     
190 .Lfinish:
191         
192         lwz %r0,148(%r1)
193         mtlr %r0
194         addi %r1,%r1,144
195         blr
196 END(ffi_closure_SYSV)
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: