OSDN Git Service

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