1 /* ----------------------------------------------------------------------- 2 sysv.h - Copyright (c) 2003 Jakub Jelinek <jakub (at) redhat.com> 3 Copyright (c) 2008 Red Hat, Inc. 4 5 PowerPC64 Assembly glue. 6 7 Permission is hereby granted, free of charge, to any person obtaining 8 a copy of this software and associated documentation files (the 9 ``Software''), to deal in the Software without restriction, including 10 without limitation the rights to use, copy, modify, merge, publish, 11 distribute, sublicense, and/or sell copies of the Software, and to 12 permit persons to whom the Software is furnished to do so, subject to 13 the following conditions: 14 15 The above copyright notice and this permission notice shall be included 16 in all copies or substantial portions of the Software. 17 18 THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, 19 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 20 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 21 NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 22 HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 23 WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 25 DEALINGS IN THE SOFTWARE. 26 ----------------------------------------------------------------------- */ 27 #define LIBFFI_ASM 28 #include <fficonfig.h> 29 #include <ffi.h> 30 31 .file "linux64_closure.S" 32 33 #ifdef __powerpc64__ 34 FFI_HIDDEN (ffi_closure_LINUX64) 35 FFI_HIDDEN (.ffi_closure_LINUX64) 36 .globl ffi_closure_LINUX64, .ffi_closure_LINUX64 37 .section ".opd","aw" 38 .align 3 39 ffi_closure_LINUX64: 40 .quad .ffi_closure_LINUX64,.TOC.@tocbase,0 41 .size ffi_closure_LINUX64,24 42 .type .ffi_closure_LINUX64,@function 43 .text 44 .ffi_closure_LINUX64: 45 .LFB1: 46 # save general regs into parm save area 47 std %r3, 48(%r1) 48 std %r4, 56(%r1) 49 std %r5, 64(%r1) 50 std %r6, 72(%r1) 51 mflr %r0 52 53 std %r7, 80(%r1) 54 std %r8, 88(%r1) 55 std %r9, 96(%r1) 56 std %r10, 104(%r1) 57 std %r0, 16(%r1) 58 59 # mandatory 48 bytes special reg save area + 64 bytes parm save area 60 # + 16 bytes retval area + 13*8 bytes fpr save area + round to 16 61 stdu %r1, -240(%r1) 62 .LCFI0: 63 64 # next save fpr 1 to fpr 13 65 stfd %f1, 128+(0*8)(%r1) 66 stfd %f2, 128+(1*8)(%r1) 67 stfd %f3, 128+(2*8)(%r1) 68 stfd %f4, 128+(3*8)(%r1) 69 stfd %f5, 128+(4*8)(%r1) 70 stfd %f6, 128+(5*8)(%r1) 71 stfd %f7, 128+(6*8)(%r1) 72 stfd %f8, 128+(7*8)(%r1) 73 stfd %f9, 128+(8*8)(%r1) 74 stfd %f10, 128+(9*8)(%r1) 75 stfd %f11, 128+(10*8)(%r1) 76 stfd %f12, 128+(11*8)(%r1) 77 stfd %f13, 128+(12*8)(%r1) 78 79 # set up registers for the routine that actually does the work 80 # get the context pointer from the trampoline 81 mr %r3, %r11 82 83 # now load up the pointer to the result storage 84 addi %r4, %r1, 112 85 86 # now load up the pointer to the parameter save area 87 # in the previous frame 88 addi %r5, %r1, 240 + 48 89 90 # now load up the pointer to the saved fpr registers */ 91 addi %r6, %r1, 128 92 93 # make the call 94 bl .ffi_closure_helper_LINUX64 95 .Lret: 96 97 # now r3 contains the return type 98 # so use it to look up in a table 99 # so we know how to deal with each type 100 101 # look up the proper starting point in table 102 # by using return type as offset 103 mflr %r4 # move address of .Lret to r4 104 sldi %r3, %r3, 4 # now multiply return type by 16 105 addi %r4, %r4, .Lret_type0 - .Lret 106 ld %r0, 240+16(%r1) 107 add %r3, %r3, %r4 # add contents of table to table address 108 mtctr %r3 109 bctr # jump to it 110 111 # Each of the ret_typeX code fragments has to be exactly 16 bytes long 112 # (4 instructions). For cache effectiveness we align to a 16 byte boundary 113 # first. 114 .align 4 115 116 .Lret_type0: 117 # case FFI_TYPE_VOID 118 mtlr %r0 119 addi %r1, %r1, 240 120 blr 121 nop 122 # case FFI_TYPE_INT 123 lwa %r3, 112+4(%r1) 124 mtlr %r0 125 addi %r1, %r1, 240 126 blr 127 # case FFI_TYPE_FLOAT 128 lfs %f1, 112+0(%r1) 129 mtlr %r0 130 addi %r1, %r1, 240 131 blr 132 # case FFI_TYPE_DOUBLE 133 lfd %f1, 112+0(%r1) 134 mtlr %r0 135 addi %r1, %r1, 240 136 blr 137 # case FFI_TYPE_LONGDOUBLE 138 lfd %f1, 112+0(%r1) 139 mtlr %r0 140 lfd %f2, 112+8(%r1) 141 b .Lfinish 142 # case FFI_TYPE_UINT8 143 lbz %r3, 112+7(%r1) 144 mtlr %r0 145 addi %r1, %r1, 240 146 blr 147 # case FFI_TYPE_SINT8 148 lbz %r3, 112+7(%r1) 149 extsb %r3,%r3 150 mtlr %r0 151 b .Lfinish 152 # case FFI_TYPE_UINT16 153 lhz %r3, 112+6(%r1) 154 mtlr %r0 155 .Lfinish: 156 addi %r1, %r1, 240 157 blr 158 # case FFI_TYPE_SINT16 159 lha %r3, 112+6(%r1) 160 mtlr %r0 161 addi %r1, %r1, 240 162 blr 163 # case FFI_TYPE_UINT32 164 lwz %r3, 112+4(%r1) 165 mtlr %r0 166 addi %r1, %r1, 240 167 blr 168 # case FFI_TYPE_SINT32 169 lwa %r3, 112+4(%r1) 170 mtlr %r0 171 addi %r1, %r1, 240 172 blr 173 # case FFI_TYPE_UINT64 174 ld %r3, 112+0(%r1) 175 mtlr %r0 176 addi %r1, %r1, 240 177 blr 178 # case FFI_TYPE_SINT64 179 ld %r3, 112+0(%r1) 180 mtlr %r0 181 addi %r1, %r1, 240 182 blr 183 # case FFI_TYPE_STRUCT 184 mtlr %r0 185 addi %r1, %r1, 240 186 blr 187 nop 188 # case FFI_TYPE_POINTER 189 ld %r3, 112+0(%r1) 190 mtlr %r0 191 addi %r1, %r1, 240 192 blr 193 # esac 194 .LFE1: 195 .long 0 196 .byte 0,12,0,1,128,0,0,0 197 .size .ffi_closure_LINUX64,.-.ffi_closure_LINUX64 198 199 .section .eh_frame,EH_FRAME_FLAGS,@progbits 200 .Lframe1: 201 .4byte .LECIE1-.LSCIE1 # Length of Common Information Entry 202 .LSCIE1: 203 .4byte 0x0 # CIE Identifier Tag 204 .byte 0x1 # CIE Version 205 .ascii "zR\0" # CIE Augmentation 206 .uleb128 0x1 # CIE Code Alignment Factor 207 .sleb128 -8 # CIE Data Alignment Factor 208 .byte 0x41 # CIE RA Column 209 .uleb128 0x1 # Augmentation size 210 .byte 0x14 # FDE Encoding (pcrel udata8) 211 .byte 0xc # DW_CFA_def_cfa 212 .uleb128 0x1 213 .uleb128 0x0 214 .align 3 215 .LECIE1: 216 .LSFDE1: 217 .4byte .LEFDE1-.LASFDE1 # FDE Length 218 .LASFDE1: 219 .4byte .LASFDE1-.Lframe1 # FDE CIE offset 220 .8byte .LFB1-. # FDE initial location 221 .8byte .LFE1-.LFB1 # FDE address range 222 .uleb128 0x0 # Augmentation size 223 .byte 0x2 # DW_CFA_advance_loc1 224 .byte .LCFI0-.LFB1 225 .byte 0xe # DW_CFA_def_cfa_offset 226 .uleb128 240 227 .byte 0x11 # DW_CFA_offset_extended_sf 228 .uleb128 0x41 229 .sleb128 -2 230 .align 3 231 .LEFDE1: 232 #endif 233 234 #if defined __ELF__ && defined __linux__ 235 .section .note.GNU-stack,"",@progbits 236 #endif 237