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