1/* ----------------------------------------------------------------------- 2 v8.S - Copyright (c) 2013 The Written Word, Inc. 3 Copyright (c) 1996, 1997, 2003, 2004, 2008 Red Hat, Inc. 4 5 SPARC Foreign Function Interface 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 28#define LIBFFI_ASM 29#include <fficonfig.h> 30#include <ffi.h> 31 32#define STACKFRAME 96 /* Minimum stack framesize for SPARC */ 33#define ARGS (64+4) /* Offset of register area in frame */ 34 35#ifndef __GNUC__ 36 .text 37 .align 8 38.globl ffi_flush_icache 39.globl _ffi_flush_icache 40 41ffi_flush_icache: 42_ffi_flush_icache: 43 add %o0, %o1, %o2 44#ifdef SPARC64 451: flush %o0 46#else 471: iflush %o0 48#endif 49 add %o0, 8, %o0 50 cmp %o0, %o2 51 blt 1b 52 nop 53 nop 54 nop 55 nop 56 nop 57 retl 58 nop 59.ffi_flush_icache_end: 60 .size ffi_flush_icache,.ffi_flush_icache_end-ffi_flush_icache 61#endif 62 63 .text 64 .align 8 65.globl ffi_call_v8 66.globl _ffi_call_v8 67 68ffi_call_v8: 69_ffi_call_v8: 70.LLFB1: 71 save %sp, -STACKFRAME, %sp 72.LLCFI0: 73 74 sub %sp, %i2, %sp ! alloca() space in stack for frame to set up 75 add %sp, STACKFRAME, %l0 ! %l0 has start of 76 ! frame to set up 77 78 mov %l0, %o0 ! call routine to set up frame 79 call %i0 80 mov %i1, %o1 ! (delay) 81 82 ld [%l0+ARGS], %o0 ! call foreign function 83 ld [%l0+ARGS+4], %o1 84 ld [%l0+ARGS+8], %o2 85 ld [%l0+ARGS+12], %o3 86 ld [%l0+ARGS+16], %o4 87 ld [%l0+ARGS+20], %o5 88 call %i5 89 mov %l0, %sp ! (delay) switch to frame 90 nop ! STRUCT returning functions skip 12 instead of 8 bytes 91 92 ! If the return value pointer is NULL, assume no return value. 93 tst %i4 94 bz done 95 nop 96 97 cmp %i3, FFI_TYPE_INT 98 be,a done 99 st %o0, [%i4] ! (delay) 100 101 cmp %i3, FFI_TYPE_FLOAT 102 be,a done 103 st %f0, [%i4+0] ! (delay) 104 105 cmp %i3, FFI_TYPE_DOUBLE 106 be,a double 107 st %f0, [%i4+0] ! (delay) 108 109 cmp %i3, FFI_TYPE_SINT8 110 be,a sint8 111 sll %o0, 24, %o0 ! (delay) 112 113 cmp %i3, FFI_TYPE_UINT8 114 be,a uint8 115 sll %o0, 24, %o0 ! (delay) 116 117 cmp %i3, FFI_TYPE_SINT16 118 be,a sint16 119 sll %o0, 16, %o0 ! (delay) 120 121 cmp %i3, FFI_TYPE_UINT16 122 be,a uint16 123 sll %o0, 16, %o0 ! (delay) 124 125 cmp %i3, FFI_TYPE_SINT64 126 be,a longlong 127 st %o0, [%i4+0] ! (delay) 128done: 129 ret 130 restore 131 132double: 133 st %f1, [%i4+4] 134 ret 135 restore 136 137sint8: 138 sra %o0, 24, %o0 139 st %o0, [%i4+0] 140 ret 141 restore 142 143uint8: 144 srl %o0, 24, %o0 145 st %o0, [%i4+0] 146 ret 147 restore 148 149sint16: 150 sra %o0, 16, %o0 151 st %o0, [%i4+0] 152 ret 153 restore 154 155uint16: 156 srl %o0, 16, %o0 157 st %o0, [%i4+0] 158 ret 159 restore 160 161longlong: 162 st %o1, [%i4+4] 163 ret 164 restore 165.LLFE1: 166 167.ffi_call_v8_end: 168 .size ffi_call_v8,.ffi_call_v8_end-ffi_call_v8 169 170 171#undef STACKFRAME 172#define STACKFRAME 104 /* 16*4 register window + 173 1*4 struct return + 174 6*4 args backing store + 175 3*4 locals */ 176 177/* ffi_closure_v8(...) 178 179 Receives the closure argument in %g2. */ 180 181 .text 182 .align 8 183 .globl ffi_closure_v8 184 185ffi_closure_v8: 186#ifdef HAVE_AS_REGISTER_PSEUDO_OP 187 .register %g2, #scratch 188#endif 189.LLFB2: 190 ! Reserve frame space for all arguments in case 191 ! we need to align them on a 8-byte boundary. 192 ld [%g2+FFI_TRAMPOLINE_SIZE], %g1 193 ld [%g1+4], %g1 194 sll %g1, 3, %g1 195 add %g1, STACKFRAME, %g1 196 ! %g1 == STACKFRAME + 8*nargs 197 neg %g1 198 save %sp, %g1, %sp 199.LLCFI1: 200 201 ! Store all of the potential argument registers in va_list format. 202 st %i0, [%fp+68+0] 203 st %i1, [%fp+68+4] 204 st %i2, [%fp+68+8] 205 st %i3, [%fp+68+12] 206 st %i4, [%fp+68+16] 207 st %i5, [%fp+68+20] 208 209 ! Call ffi_closure_sparc_inner to do the bulk of the work. 210 mov %g2, %o0 211 add %fp, -8, %o1 212 add %fp, 64, %o2 213 call ffi_closure_sparc_inner_v8 214 add %fp, -16, %o3 215 216 ! Load up the return value in the proper type. 217 ! See ffi_prep_cif_machdep for the list of cases. 218 cmp %o0, FFI_TYPE_VOID 219 be done1 220 221 cmp %o0, FFI_TYPE_INT 222 be done1 223 ld [%fp-8], %i0 224 225 cmp %o0, FFI_TYPE_FLOAT 226 be,a done1 227 ld [%fp-8], %f0 228 229 cmp %o0, FFI_TYPE_DOUBLE 230 be,a done1 231 ldd [%fp-8], %f0 232 233#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE 234 cmp %o0, FFI_TYPE_LONGDOUBLE 235 be done2 236#endif 237 238 cmp %o0, FFI_TYPE_STRUCT 239 be done2 240 241 cmp %o0, FFI_TYPE_SINT64 242 be,a done1 243 ldd [%fp-8], %i0 244 245 cmp %o0, FFI_TYPE_UINT64 246 be,a done1 247 ldd [%fp-8], %i0 248 249 ld [%fp-8], %i0 250done1: 251 jmp %i7+8 252 restore 253done2: 254 ! Skip 'unimp'. 255 jmp %i7+12 256 restore 257.LLFE2: 258 259.ffi_closure_v8_end: 260 .size ffi_closure_v8,.ffi_closure_v8_end-ffi_closure_v8 261 262#ifdef SPARC64 263#define WS 8 264#define nword xword 265#define uanword uaxword 266#else 267#define WS 4 268#define nword long 269#define uanword uaword 270#endif 271 272#ifdef HAVE_RO_EH_FRAME 273 .section ".eh_frame",#alloc 274#else 275 .section ".eh_frame",#alloc,#write 276#endif 277.LLframe1: 278 .uaword .LLECIE1-.LLSCIE1 ! Length of Common Information Entry 279.LLSCIE1: 280 .uaword 0x0 ! CIE Identifier Tag 281 .byte 0x1 ! CIE Version 282 .ascii "zR\0" ! CIE Augmentation 283 .byte 0x1 ! uleb128 0x1; CIE Code Alignment Factor 284 .byte 0x80-WS ! sleb128 -WS; CIE Data Alignment Factor 285 .byte 0xf ! CIE RA Column 286 .byte 0x1 ! uleb128 0x1; Augmentation size 287#ifdef HAVE_AS_SPARC_UA_PCREL 288 .byte 0x1b ! FDE Encoding (pcrel sdata4) 289#else 290 .byte 0x50 ! FDE Encoding (aligned absolute) 291#endif 292 .byte 0xc ! DW_CFA_def_cfa 293 .byte 0xe ! uleb128 0xe 294 .byte 0x0 ! uleb128 0x0 295 .align WS 296.LLECIE1: 297.LLSFDE1: 298 .uaword .LLEFDE1-.LLASFDE1 ! FDE Length 299.LLASFDE1: 300 .uaword .LLASFDE1-.LLframe1 ! FDE CIE offset 301#ifdef HAVE_AS_SPARC_UA_PCREL 302 .uaword %r_disp32(.LLFB1) 303 .uaword .LLFE1-.LLFB1 ! FDE address range 304#else 305 .align WS 306 .nword .LLFB1 307 .uanword .LLFE1-.LLFB1 ! FDE address range 308#endif 309 .byte 0x0 ! uleb128 0x0; Augmentation size 310 .byte 0x4 ! DW_CFA_advance_loc4 311 .uaword .LLCFI0-.LLFB1 312 .byte 0xd ! DW_CFA_def_cfa_register 313 .byte 0x1e ! uleb128 0x1e 314 .byte 0x2d ! DW_CFA_GNU_window_save 315 .byte 0x9 ! DW_CFA_register 316 .byte 0xf ! uleb128 0xf 317 .byte 0x1f ! uleb128 0x1f 318 .align WS 319.LLEFDE1: 320.LLSFDE2: 321 .uaword .LLEFDE2-.LLASFDE2 ! FDE Length 322.LLASFDE2: 323 .uaword .LLASFDE2-.LLframe1 ! FDE CIE offset 324#ifdef HAVE_AS_SPARC_UA_PCREL 325 .uaword %r_disp32(.LLFB2) 326 .uaword .LLFE2-.LLFB2 ! FDE address range 327#else 328 .align WS 329 .nword .LLFB2 330 .uanword .LLFE2-.LLFB2 ! FDE address range 331#endif 332 .byte 0x0 ! uleb128 0x0; Augmentation size 333 .byte 0x4 ! DW_CFA_advance_loc4 334 .uaword .LLCFI1-.LLFB2 335 .byte 0xd ! DW_CFA_def_cfa_register 336 .byte 0x1e ! uleb128 0x1e 337 .byte 0x2d ! DW_CFA_GNU_window_save 338 .byte 0x9 ! DW_CFA_register 339 .byte 0xf ! uleb128 0xf 340 .byte 0x1f ! uleb128 0x1f 341 .align WS 342.LLEFDE2: 343 344#if defined __ELF__ && defined __linux__ 345 .section .note.GNU-stack,"",@progbits 346#endif 347