OSDN Git Service

* src/powerpc/ffi.c (ffi_prep_args64): Modify for changed gcc
[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 .Lret:
68
69         # now r3 contains the return type
70         # so use it to look up in a table
71         # so we know how to deal with each type
72
73         # look up the proper starting point in table 
74         # by using return type as offset
75         mflr %r4                # move address of .Lret to r4
76         sldi %r3, %r3, 4        # now multiply return type by 16
77         addi %r4, %r4, .Lret_type0 - .Lret
78         ld %r0, 224+16(%r1)
79         add %r3, %r3, %r4       # add contents of table to table address
80         mtctr %r3
81         bctr                    # jump to it
82
83 # Each of the ret_typeX code fragments has to be exactly 16 bytes long
84 # (4 instructions). For cache effectiveness we align to a 16 byte boundary
85 # first.
86         .align 4
87
88 .Lret_type0:
89 # case FFI_TYPE_VOID
90         mtlr %r0
91         addi %r1, %r1, 224
92         blr
93         nop
94 # case FFI_TYPE_INT
95         lwa %r3, 112+4(%r1)
96         mtlr %r0
97         addi %r1, %r1, 224
98         blr
99 # case FFI_TYPE_FLOAT
100         lfs %f1, 112+4(%r1)
101         mtlr %r0
102         addi %r1, %r1, 224
103         blr
104 # case FFI_TYPE_DOUBLE
105         lfd %f1, 112+0(%r1)
106         mtlr %r0
107         addi %r1, %r1, 224
108         blr
109 # case FFI_TYPE_LONGDOUBLE
110         lfd %f1, 112+0(%r1)
111         mtlr %r0
112         addi %r1, %r1, 224
113         blr
114 # case FFI_TYPE_UINT8
115         lbz %r3, 112+7(%r1)
116         mtlr %r0
117         addi %r1, %r1, 224
118         blr
119 # case FFI_TYPE_SINT8
120         lbz %r3, 112+7(%r1)
121         extsb %r3,%r3
122         mtlr %r0
123         b .Lfinish
124 # case FFI_TYPE_UINT16
125         lhz %r3, 112+6(%r1)
126         mtlr %r0
127 .Lfinish:
128         addi %r1, %r1, 224
129         blr
130 # case FFI_TYPE_SINT16
131         lha %r3, 112+6(%r1)
132         mtlr %r0
133         addi %r1, %r1, 224
134         blr
135 # case FFI_TYPE_UINT32
136         lwz %r3, 112+4(%r1)
137         mtlr %r0
138         addi %r1, %r1, 224
139         blr
140 # case FFI_TYPE_SINT32
141         lwa %r3, 112+4(%r1)
142         mtlr %r0
143         addi %r1, %r1, 224
144         blr
145 # case FFI_TYPE_UINT64
146         ld %r3, 112+0(%r1)
147         mtlr %r0
148         addi %r1, %r1, 224
149         blr
150 # case FFI_TYPE_SINT64
151         ld %r3, 112+0(%r1)
152         mtlr %r0
153         addi %r1, %r1, 224
154         blr
155 # case FFI_TYPE_STRUCT
156         mtlr %r0
157         addi %r1, %r1, 224
158         blr
159         nop
160 # case FFI_TYPE_POINTER
161         ld %r3, 112+0(%r1)
162         mtlr %r0
163         addi %r1, %r1, 224
164         blr
165 # esac
166 .LFE1:
167         .long   0
168         .byte   0,12,0,1,128,0,0,0
169         .size   .ffi_closure_LINUX64,.-.ffi_closure_LINUX64
170
171         .section        .eh_frame,EH_FRAME_FLAGS,@progbits
172 .Lframe1:
173         .4byte  .LECIE1-.LSCIE1  # Length of Common Information Entry
174 .LSCIE1:
175         .4byte  0x0      # CIE Identifier Tag
176         .byte   0x1      # CIE Version
177         .ascii "zR\0"    # CIE Augmentation
178         .uleb128 0x1     # CIE Code Alignment Factor
179         .sleb128 -8      # CIE Data Alignment Factor
180         .byte   0x41     # CIE RA Column
181         .uleb128 0x1     # Augmentation size
182         .byte   0x14     # FDE Encoding (pcrel udata8)
183         .byte   0xc      # DW_CFA_def_cfa
184         .uleb128 0x1
185         .uleb128 0x0
186         .align 3
187 .LECIE1:
188 .LSFDE1:
189         .4byte  .LEFDE1-.LASFDE1         # FDE Length
190 .LASFDE1:
191         .4byte  .LASFDE1-.Lframe1        # FDE CIE offset
192         .8byte  .LFB1-.  # FDE initial location
193         .8byte  .LFE1-.LFB1      # FDE address range
194         .uleb128 0x0     # Augmentation size
195         .byte   0x2      # DW_CFA_advance_loc1
196         .byte   .LCFI0-.LFB1
197         .byte   0xe      # DW_CFA_def_cfa_offset
198         .uleb128 224
199         .byte   0x11     # DW_CFA_offset_extended_sf
200         .uleb128 0x41
201         .sleb128 -2
202         .align 3
203 .LEFDE1:
204 #endif