1 /* ----------------------------------------------------------------------- 2 sysv.S - Copyright (c) 2003, 2004, 2008 Kaz Kojima 3 4 SuperH SHmedia Foreign Function Interface 5 6 Permission is hereby granted, free of charge, to any person obtaining 7 a copy of this software and associated documentation files (the 8 ``Software''), to deal in the Software without restriction, including 9 without limitation the rights to use, copy, modify, merge, publish, 10 distribute, sublicense, and/or sell copies of the Software, and to 11 permit persons to whom the Software is furnished to do so, subject to 12 the following conditions: 13 14 The above copyright notice and this permission notice shall be included 15 in all copies or substantial portions of the Software. 16 17 THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS 18 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 19 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 20 IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR 21 ANY CLAIM, DAMAGES OR 22 OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 23 ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 24 OTHER DEALINGS IN THE SOFTWARE. 25 ----------------------------------------------------------------------- */ 26 27 #define LIBFFI_ASM 28 #include <fficonfig.h> 29 #include <ffi.h> 30 #ifdef HAVE_MACHINE_ASM_H 31 #include <machine/asm.h> 32 #else 33 /* XXX these lose for some platforms, I'm sure. */ 34 #define CNAME(x) x 35 #define ENTRY(x) .globl CNAME(x); .type CNAME(x),%function; CNAME(x): 36 #endif 37 38 #ifdef __LITTLE_ENDIAN__ 39 #define OFS_FLT 0 40 #else 41 #define OFS_FLT 4 42 #endif 43 44 .section .text..SHmedia32,"ax" 45 46 # r2: ffi_prep_args 47 # r3: &ecif 48 # r4: bytes 49 # r5: flags 50 # r6: flags2 51 # r7: rvalue 52 # r8: fn 53 54 # This assumes we are using gas. 55 .align 5 56 ENTRY(ffi_call_SYSV) 57 # Save registers 58 .LFB1: 59 addi.l r15, -48, r15 60 .LCFI0: 61 st.q r15, 40, r32 62 st.q r15, 32, r31 63 st.q r15, 24, r30 64 st.q r15, 16, r29 65 st.q r15, 8, r28 66 st.l r15, 4, r18 67 st.l r15, 0, r14 68 .LCFI1: 69 add.l r15, r63, r14 70 .LCFI2: 71 # add r4, r63, r28 72 add r5, r63, r29 73 add r6, r63, r30 74 add r7, r63, r31 75 add r8, r63, r32 76 77 addi r4, (64 + 7), r4 78 andi r4, ~7, r4 79 sub.l r15, r4, r15 80 81 ptabs/l r2, tr0 82 add r15, r63, r2 83 blink tr0, r18 84 85 addi r15, 64, r22 86 movi 0, r0 87 movi 0, r1 88 89 pt/l 1f, tr1 90 bnei/l r29, FFI_TYPE_STRUCT, tr1 91 ld.l r15, 0, r19 92 addi r15, 8, r15 93 addi r0, 1, r0 94 1: 95 96 .L_pass: 97 andi r30, 3, r20 98 shlri r30, 2, r30 99 100 pt/l .L_call_it, tr0 101 pt/l .L_pass_i, tr1 102 pt/l .L_pass_f, tr2 103 104 beqi/l r20, FFI_TYPE_VOID, tr0 105 beqi/l r20, FFI_TYPE_INT, tr1 106 beqi/l r20, FFI_TYPE_FLOAT, tr2 107 108 .L_pass_d: 109 addi r0, 1, r0 110 addi r1, 1, r1 111 andi r1, ~1, r1 112 113 pt/l 3f, tr0 114 movi 12, r20 115 bge/l r1, r20, tr0 116 117 pt/l .L_pop_d, tr1 118 pt/l 2f, tr0 119 blink tr1, r63 120 2: 121 addi.l r15, 8, r15 122 3: 123 pt/l .L_pass, tr0 124 addi r1, 2, r1 125 blink tr0, r63 126 127 .L_pop_d: 128 pt/l .L_pop_d_tbl, tr1 129 gettr tr1, r20 130 shlli r1, 2, r21 131 add r20, r21, r20 132 ptabs/l r20, tr1 133 blink tr1, r63 134 135 .L_pop_d_tbl: 136 fld.d r15, 0, dr0 137 blink tr0, r63 138 fld.d r15, 0, dr2 139 blink tr0, r63 140 fld.d r15, 0, dr4 141 blink tr0, r63 142 fld.d r15, 0, dr6 143 blink tr0, r63 144 fld.d r15, 0, dr8 145 blink tr0, r63 146 fld.d r15, 0, dr10 147 blink tr0, r63 148 149 .L_pass_f: 150 addi r0, 1, r0 151 pt/l 3f, tr0 152 movi 12, r20 153 bge/l r1, r20, tr0 154 155 pt/l .L_pop_f, tr1 156 pt/l 2f, tr0 157 blink tr1, r63 158 2: 159 addi.l r15, 8, r15 160 3: 161 pt/l .L_pass, tr0 162 addi r1, 1, r1 163 blink tr0, r63 164 165 .L_pop_f: 166 pt/l .L_pop_f_tbl, tr1 167 gettr tr1, r20 168 shlli r1, 3, r21 169 add r20, r21, r20 170 ptabs/l r20, tr1 171 blink tr1, r63 172 173 .L_pop_f_tbl: 174 fld.s r15, OFS_FLT, fr0 175 blink tr0, r63 176 fld.s r15, OFS_FLT, fr1 177 blink tr0, r63 178 fld.s r15, OFS_FLT, fr2 179 blink tr0, r63 180 fld.s r15, OFS_FLT, fr3 181 blink tr0, r63 182 fld.s r15, OFS_FLT, fr4 183 blink tr0, r63 184 fld.s r15, OFS_FLT, fr5 185 blink tr0, r63 186 fld.s r15, OFS_FLT, fr6 187 blink tr0, r63 188 fld.s r15, OFS_FLT, fr7 189 blink tr0, r63 190 fld.s r15, OFS_FLT, fr8 191 blink tr0, r63 192 fld.s r15, OFS_FLT, fr9 193 blink tr0, r63 194 fld.s r15, OFS_FLT, fr10 195 blink tr0, r63 196 fld.s r15, OFS_FLT, fr11 197 blink tr0, r63 198 199 .L_pass_i: 200 pt/l 3f, tr0 201 movi 8, r20 202 bge/l r0, r20, tr0 203 204 pt/l .L_pop_i, tr1 205 pt/l 2f, tr0 206 blink tr1, r63 207 2: 208 addi.l r15, 8, r15 209 3: 210 pt/l .L_pass, tr0 211 addi r0, 1, r0 212 blink tr0, r63 213 214 .L_pop_i: 215 pt/l .L_pop_i_tbl, tr1 216 gettr tr1, r20 217 shlli r0, 3, r21 218 add r20, r21, r20 219 ptabs/l r20, tr1 220 blink tr1, r63 221 222 .L_pop_i_tbl: 223 ld.q r15, 0, r2 224 blink tr0, r63 225 ld.q r15, 0, r3 226 blink tr0, r63 227 ld.q r15, 0, r4 228 blink tr0, r63 229 ld.q r15, 0, r5 230 blink tr0, r63 231 ld.q r15, 0, r6 232 blink tr0, r63 233 ld.q r15, 0, r7 234 blink tr0, r63 235 ld.q r15, 0, r8 236 blink tr0, r63 237 ld.q r15, 0, r9 238 blink tr0, r63 239 240 .L_call_it: 241 # call function 242 pt/l 1f, tr1 243 bnei/l r29, FFI_TYPE_STRUCT, tr1 244 add r19, r63, r2 245 1: 246 add r22, r63, r15 247 ptabs/l r32, tr0 248 blink tr0, r18 249 250 pt/l .L_ret_i, tr0 251 pt/l .L_ret_ll, tr1 252 pt/l .L_ret_d, tr2 253 pt/l .L_ret_f, tr3 254 pt/l .L_epilogue, tr4 255 256 beqi/l r29, FFI_TYPE_INT, tr0 257 beqi/l r29, FFI_TYPE_UINT32, tr0 258 beqi/l r29, FFI_TYPE_SINT64, tr1 259 beqi/l r29, FFI_TYPE_UINT64, tr1 260 beqi/l r29, FFI_TYPE_DOUBLE, tr2 261 beqi/l r29, FFI_TYPE_FLOAT, tr3 262 263 pt/l .L_ret_q, tr0 264 pt/l .L_ret_h, tr1 265 266 beqi/l r29, FFI_TYPE_UINT8, tr0 267 beqi/l r29, FFI_TYPE_UINT16, tr1 268 blink tr4, r63 269 270 .L_ret_d: 271 fst.d r31, 0, dr0 272 blink tr4, r63 273 274 .L_ret_ll: 275 st.q r31, 0, r2 276 blink tr4, r63 277 278 .L_ret_f: 279 fst.s r31, OFS_FLT, fr0 280 blink tr4, r63 281 282 .L_ret_q: 283 st.b r31, 0, r2 284 blink tr4, r63 285 286 .L_ret_h: 287 st.w r31, 0, r2 288 blink tr4, r63 289 290 .L_ret_i: 291 st.l r31, 0, r2 292 # Fall 293 294 .L_epilogue: 295 # Remove the space we pushed for the args 296 add r14, r63, r15 297 298 ld.l r15, 0, r14 299 ld.l r15, 4, r18 300 ld.q r15, 8, r28 301 ld.q r15, 16, r29 302 ld.q r15, 24, r30 303 ld.q r15, 32, r31 304 ld.q r15, 40, r32 305 addi.l r15, 48, r15 306 ptabs r18, tr0 307 blink tr0, r63 308 309 .LFE1: 310 .ffi_call_SYSV_end: 311 .size CNAME(ffi_call_SYSV),.ffi_call_SYSV_end-CNAME(ffi_call_SYSV) 312 313 .align 5 314 ENTRY(ffi_closure_SYSV) 315 .LFB2: 316 addi.l r15, -136, r15 317 .LCFI3: 318 st.l r15, 12, r18 319 st.l r15, 8, r14 320 st.l r15, 4, r12 321 .LCFI4: 322 add r15, r63, r14 323 .LCFI5: 324 /* Stack layout: 325 ... 326 64 bytes (register parameters) 327 48 bytes (floating register parameters) 328 8 bytes (result) 329 4 bytes (r18) 330 4 bytes (r14) 331 4 bytes (r12) 332 4 bytes (for align) 333 <- new stack pointer 334 */ 335 fst.d r14, 24, dr0 336 fst.d r14, 32, dr2 337 fst.d r14, 40, dr4 338 fst.d r14, 48, dr6 339 fst.d r14, 56, dr8 340 fst.d r14, 64, dr10 341 st.q r14, 72, r2 342 st.q r14, 80, r3 343 st.q r14, 88, r4 344 st.q r14, 96, r5 345 st.q r14, 104, r6 346 st.q r14, 112, r7 347 st.q r14, 120, r8 348 st.q r14, 128, r9 349 350 add r1, r63, r2 351 addi r14, 16, r3 352 addi r14, 72, r4 353 addi r14, 24, r5 354 addi r14, 136, r6 355 #ifdef PIC 356 movi (((datalabel _GLOBAL_OFFSET_TABLE_-(.LPCS0-.)) >> 16) & 65535), r12 357 shori ((datalabel _GLOBAL_OFFSET_TABLE_-(.LPCS0-.)) & 65535), r12 358 .LPCS0: ptrel/u r12, tr0 359 movi ((ffi_closure_helper_SYSV@GOTPLT) & 65535), r1 360 gettr tr0, r12 361 ldx.l r1, r12, r1 362 ptabs r1, tr0 363 #else 364 pt/l ffi_closure_helper_SYSV, tr0 365 #endif 366 blink tr0, r18 367 368 shlli r2, 1, r1 369 movi (((datalabel .L_table) >> 16) & 65535), r2 370 shori ((datalabel .L_table) & 65535), r2 371 ldx.w r2, r1, r1 372 add r1, r2, r1 373 pt/l .L_case_v, tr1 374 ptabs r1, tr0 375 blink tr0, r63 376 377 .align 2 378 .L_table: 379 .word .L_case_v - datalabel .L_table /* FFI_TYPE_VOID */ 380 .word .L_case_i - datalabel .L_table /* FFI_TYPE_INT */ 381 .word .L_case_f - datalabel .L_table /* FFI_TYPE_FLOAT */ 382 .word .L_case_d - datalabel .L_table /* FFI_TYPE_DOUBLE */ 383 .word .L_case_d - datalabel .L_table /* FFI_TYPE_LONGDOUBLE */ 384 .word .L_case_uq - datalabel .L_table /* FFI_TYPE_UINT8 */ 385 .word .L_case_q - datalabel .L_table /* FFI_TYPE_SINT8 */ 386 .word .L_case_uh - datalabel .L_table /* FFI_TYPE_UINT16 */ 387 .word .L_case_h - datalabel .L_table /* FFI_TYPE_SINT16 */ 388 .word .L_case_i - datalabel .L_table /* FFI_TYPE_UINT32 */ 389 .word .L_case_i - datalabel .L_table /* FFI_TYPE_SINT32 */ 390 .word .L_case_ll - datalabel .L_table /* FFI_TYPE_UINT64 */ 391 .word .L_case_ll - datalabel .L_table /* FFI_TYPE_SINT64 */ 392 .word .L_case_v - datalabel .L_table /* FFI_TYPE_STRUCT */ 393 .word .L_case_i - datalabel .L_table /* FFI_TYPE_POINTER */ 394 395 .align 2 396 .L_case_d: 397 fld.d r14, 16, dr0 398 blink tr1, r63 399 .L_case_f: 400 fld.s r14, 16, fr0 401 blink tr1, r63 402 .L_case_ll: 403 ld.q r14, 16, r2 404 blink tr1, r63 405 .L_case_i: 406 ld.l r14, 16, r2 407 blink tr1, r63 408 .L_case_q: 409 ld.b r14, 16, r2 410 blink tr1, r63 411 .L_case_uq: 412 ld.ub r14, 16, r2 413 blink tr1, r63 414 .L_case_h: 415 ld.w r14, 16, r2 416 blink tr1, r63 417 .L_case_uh: 418 ld.uw r14, 16, r2 419 blink tr1, r63 420 .L_case_v: 421 add.l r14, r63, r15 422 ld.l r15, 4, r12 423 ld.l r15, 8, r14 424 ld.l r15, 12, r18 425 addi.l r15, 136, r15 426 ptabs r18, tr0 427 blink tr0, r63 428 429 .LFE2: 430 .ffi_closure_SYSV_end: 431 .size CNAME(ffi_closure_SYSV),.ffi_closure_SYSV_end-CNAME(ffi_closure_SYSV) 432 433 #if defined __ELF__ && defined __linux__ 434 .section .note.GNU-stack,"",@progbits 435 #endif 436 437 .section ".eh_frame","aw",@progbits 438 __FRAME_BEGIN__: 439 .4byte .LECIE1-.LSCIE1 /* Length of Common Information Entry */ 440 .LSCIE1: 441 .4byte 0x0 /* CIE Identifier Tag */ 442 .byte 0x1 /* CIE Version */ 443 #ifdef PIC 444 .ascii "zR\0" /* CIE Augmentation */ 445 #else 446 .byte 0x0 /* CIE Augmentation */ 447 #endif 448 .uleb128 0x1 /* CIE Code Alignment Factor */ 449 .sleb128 -4 /* CIE Data Alignment Factor */ 450 .byte 0x12 /* CIE RA Column */ 451 #ifdef PIC 452 .uleb128 0x1 /* Augmentation size */ 453 .byte 0x10 /* FDE Encoding (pcrel) */ 454 #endif 455 .byte 0xc /* DW_CFA_def_cfa */ 456 .uleb128 0xf 457 .uleb128 0x0 458 .align 2 459 .LECIE1: 460 .LSFDE1: 461 .4byte datalabel .LEFDE1-datalabel .LASFDE1 /* FDE Length */ 462 .LASFDE1: 463 .4byte datalabel .LASFDE1-datalabel __FRAME_BEGIN__ 464 #ifdef PIC 465 .4byte .LFB1-. /* FDE initial location */ 466 #else 467 .4byte .LFB1 /* FDE initial location */ 468 #endif 469 .4byte datalabel .LFE1-datalabel .LFB1 /* FDE address range */ 470 #ifdef PIC 471 .uleb128 0x0 /* Augmentation size */ 472 #endif 473 .byte 0x4 /* DW_CFA_advance_loc4 */ 474 .4byte datalabel .LCFI0-datalabel .LFB1 475 .byte 0xe /* DW_CFA_def_cfa_offset */ 476 .uleb128 0x30 477 .byte 0x4 /* DW_CFA_advance_loc4 */ 478 .4byte datalabel .LCFI1-datalabel .LCFI0 479 .byte 0x8e /* DW_CFA_offset, column 0xe */ 480 .uleb128 0xc 481 .byte 0x92 /* DW_CFA_offset, column 0x12 */ 482 .uleb128 0xb 483 .byte 0x9c /* DW_CFA_offset, column 0x1c */ 484 .uleb128 0xa 485 .byte 0x9d /* DW_CFA_offset, column 0x1d */ 486 .uleb128 0x8 487 .byte 0x9e /* DW_CFA_offset, column 0x1e */ 488 .uleb128 0x6 489 .byte 0x9f /* DW_CFA_offset, column 0x1f */ 490 .uleb128 0x4 491 .byte 0xa0 /* DW_CFA_offset, column 0x20 */ 492 .uleb128 0x2 493 .byte 0x4 /* DW_CFA_advance_loc4 */ 494 .4byte datalabel .LCFI2-datalabel .LCFI1 495 .byte 0xd /* DW_CFA_def_cfa_register */ 496 .uleb128 0xe 497 .align 2 498 .LEFDE1: 499 500 .LSFDE3: 501 .4byte datalabel .LEFDE3-datalabel .LASFDE3 /* FDE Length */ 502 .LASFDE3: 503 .4byte datalabel .LASFDE3-datalabel __FRAME_BEGIN__ 504 #ifdef PIC 505 .4byte .LFB2-. /* FDE initial location */ 506 #else 507 .4byte .LFB2 /* FDE initial location */ 508 #endif 509 .4byte datalabel .LFE2-datalabel .LFB2 /* FDE address range */ 510 #ifdef PIC 511 .uleb128 0x0 /* Augmentation size */ 512 #endif 513 .byte 0x4 /* DW_CFA_advance_loc4 */ 514 .4byte datalabel .LCFI3-datalabel .LFB2 515 .byte 0xe /* DW_CFA_def_cfa_offset */ 516 .uleb128 0x88 517 .byte 0x4 /* DW_CFA_advance_loc4 */ 518 .4byte datalabel .LCFI4-datalabel .LCFI3 519 .byte 0x8c /* DW_CFA_offset, column 0xc */ 520 .uleb128 0x21 521 .byte 0x8e /* DW_CFA_offset, column 0xe */ 522 .uleb128 0x20 523 .byte 0x92 /* DW_CFA_offset, column 0x12 */ 524 .uleb128 0x1f 525 .byte 0x4 /* DW_CFA_advance_loc4 */ 526 .4byte datalabel .LCFI5-datalabel .LCFI4 527 .byte 0xd /* DW_CFA_def_cfa_register */ 528 .uleb128 0xe 529 .align 2 530 .LEFDE3: 531