OSDN Git Service

1159c1e77a83f17a429f47427ec7d4d55684f630
[pf3gnuchains/gcc-fork.git] / libffi / src / powerpc / linux64_closure.S
1 #define LIBFFI_ASM
2 #include <ffi.h>
3
4         .file   "linux64_closure.S"
5
6 #ifdef __powerpc64__
7         .hidden ffi_closure_LINUX64, .ffi_closure_LINUX64
8         .globl  ffi_closure_LINUX64, .ffi_closure_LINUX64
9         .section        ".opd","aw"
10         .align  3
11 ffi_closure_LINUX64:
12         .quad   .ffi_closure_LINUX64,.TOC.@tocbase,0
13         .size   ffi_closure_LINUX64,24
14         .type   .ffi_closure_LINUX64,@function
15         .text
16 .ffi_closure_LINUX64:
17 .LFB1:
18         # save general regs into parm save area
19         std     %r3, 48(%r1)
20         std     %r4, 56(%r1)
21         std     %r5, 64(%r1)
22         std     %r6, 72(%r1)
23         mflr    %r0
24
25         std     %r7, 80(%r1)
26         std     %r8, 88(%r1)
27         std     %r9, 96(%r1)
28         std     %r10, 104(%r1)
29         std     %r0, 16(%r1)
30
31         # mandatory 48 bytes special reg save area + 64 bytes parm save area
32         # + 8 bytes retval area + 13*8 bytes fpr save area
33         stdu    %r1, -224(%r1)
34 .LCFI0:
35
36         # next save fpr 1 to fpr 13
37         stfd  %f1, 120+(0*8)(%r1)
38         stfd  %f2, 120+(1*8)(%r1)
39         stfd  %f3, 120+(2*8)(%r1)
40         stfd  %f4, 120+(3*8)(%r1)
41         stfd  %f5, 120+(4*8)(%r1)
42         stfd  %f6, 120+(5*8)(%r1)
43         stfd  %f7, 120+(6*8)(%r1)
44         stfd  %f8, 120+(7*8)(%r1)
45         stfd  %f9, 120+(8*8)(%r1)
46         stfd  %f10, 120+(9*8)(%r1)
47         stfd  %f11, 120+(10*8)(%r1)
48         stfd  %f12, 120+(11*8)(%r1)
49         stfd  %f13, 120+(12*8)(%r1)
50
51         # set up registers for the routine that actually does the work
52         # get the context pointer from the trampoline
53         mr %r3, %r11
54
55         # now load up the pointer to the result storage
56         addi %r4, %r1, 112
57
58         # now load up the pointer to the parameter save area
59         # in the previous frame
60         addi %r5, %r1, 224 + 48
61
62         # now load up the pointer to the saved fpr registers */
63         addi %r6, %r1, 120
64
65         # make the call
66         bl .ffi_closure_helper_LINUX64
67
68         # now r3 contains the return type
69         # so use it to look up in a table
70         # so we know how to deal with each type
71
72         # look up the proper starting point in table 
73         # by using return type as offset
74         addi %r5, %r1, 112      # get pointer to results area
75         bl .Lget_ret_type0_addr # get pointer to .Lret_type0 into LR
76         mflr %r4                # move to r4
77         sldi %r3, %r3, 4        # now multiply return type by 16
78         add %r3, %r3, %r4       # add contents of table to table address
79         mtctr %r3
80         bctr                    # jump to it
81
82 # Each of the ret_typeX code fragments has to be exactly 16 bytes long
83 # (4 instructions). For cache effectiveness we align to a 16 byte boundary
84 # first.
85         .align 4
86
87         nop
88         nop
89         nop
90 .Lget_ret_type0_addr:
91         blrl
92
93 .Lret_type0:
94 # case FFI_TYPE_VOID
95         b .Lfinish
96         nop
97         nop
98         nop
99 # case FFI_TYPE_INT
100         lwa %r3, 4(%r5)
101         b .Lfinish
102         nop
103         nop
104 # case FFI_TYPE_FLOAT
105         lfs %f1, 4(%r5)
106         b .Lfinish
107         nop
108         nop
109 # case FFI_TYPE_DOUBLE
110         lfd %f1, 0(%r5)
111         b .Lfinish
112         nop
113         nop
114 # case FFI_TYPE_LONGDOUBLE
115         lfd %f1, 0(%r5)
116         b .Lfinish
117         nop
118         nop
119 # case FFI_TYPE_UINT8
120         lbz %r3, 7(%r5)
121         b .Lfinish
122         nop
123         nop
124 # case FFI_TYPE_SINT8
125         lbz %r3, 7(%r5)
126         extsb %r3,%r3
127         b .Lfinish
128         nop
129 # case FFI_TYPE_UINT16
130         lhz %r3, 6(%r5)
131         b .Lfinish
132         nop
133         nop
134 # case FFI_TYPE_SINT16
135         lha %r3, 6(%r5)
136         b .Lfinish
137         nop
138         nop
139 # case FFI_TYPE_UINT32
140         lwz %r3, 4(%r5)
141         b .Lfinish
142         nop
143         nop
144 # case FFI_TYPE_SINT32
145         lwa %r3, 4(%r5)
146         b .Lfinish
147         nop
148         nop
149 # case FFI_TYPE_UINT64
150         ld %r3, 0(%r5)
151         b .Lfinish
152         nop
153         nop
154 # case FFI_TYPE_SINT64
155         ld %r3, 0(%r5)
156         b .Lfinish
157         nop
158         nop
159 # case FFI_TYPE_STRUCT
160         b .Lfinish
161         nop
162         nop
163         nop
164 # case FFI_TYPE_POINTER
165         ld %r3, 0(%r5)
166         b .Lfinish
167         nop
168         nop
169 # esac
170 .Lfinish:
171         ld %r0, 224+16(%r1)
172         mtlr %r0
173         addi %r1, %r1, 224
174         blr
175 .LFE1:
176         .long   0
177         .byte   0,12,0,1,128,0,0,0
178         .size   .ffi_closure_LINUX64,.-.ffi_closure_LINUX64
179
180         .section        .eh_frame,EH_FRAME_FLAGS,@progbits
181 .Lframe1:
182         .4byte  .LECIE1-.LSCIE1  # Length of Common Information Entry
183 .LSCIE1:
184         .4byte  0x0      # CIE Identifier Tag
185         .byte   0x1      # CIE Version
186         .ascii "zR\0"    # CIE Augmentation
187         .uleb128 0x1     # CIE Code Alignment Factor
188         .sleb128 -8      # CIE Data Alignment Factor
189         .byte   0x41     # CIE RA Column
190         .uleb128 0x1     # Augmentation size
191         .byte   0x14     # FDE Encoding (pcrel udata8)
192         .byte   0xc      # DW_CFA_def_cfa
193         .uleb128 0x1
194         .uleb128 0x0
195         .align 3
196 .LECIE1:
197 .LSFDE1:
198         .4byte  .LEFDE1-.LASFDE1         # FDE Length
199 .LASFDE1:
200         .4byte  .LASFDE1-.Lframe1        # FDE CIE offset
201         .8byte  .LFB1-.  # FDE initial location
202         .8byte  .LFE1-.LFB1      # FDE address range
203         .uleb128 0x0     # Augmentation size
204         .byte   0x2      # DW_CFA_advance_loc1
205         .byte   .LCFI0-.LFB1
206         .byte   0xe      # DW_CFA_def_cfa_offset
207         .uleb128 224
208         .byte   0x11     # DW_CFA_offset_extended_sf
209         .uleb128 0x41
210         .sleb128 -2
211         .align 3
212 .LEFDE1:
213 #endif