]> git.ipfire.org Git - thirdparty/gcc.git/blame - libffi/src/powerpc/linux64_closure.S
004-09-02 Andreas Tobler <a.tobler@schweiz.ch>
[thirdparty/gcc.git] / libffi / src / powerpc / linux64_closure.S
CommitLineData
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 12ffi_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