github.com/prattmic/llgo-embedded@v0.0.0-20150820070356-41cfecea0e1e/third_party/gofrontend/libffi/src/mips/ffi.c (about) 1 /* ----------------------------------------------------------------------- 2 ffi.c - Copyright (c) 2011 Anthony Green 3 Copyright (c) 2008 David Daney 4 Copyright (c) 1996, 2007, 2008, 2011 Red Hat, Inc. 5 6 MIPS Foreign Function Interface 7 8 Permission is hereby granted, free of charge, to any person obtaining 9 a copy of this software and associated documentation files (the 10 ``Software''), to deal in the Software without restriction, including 11 without limitation the rights to use, copy, modify, merge, publish, 12 distribute, sublicense, and/or sell copies of the Software, and to 13 permit persons to whom the Software is furnished to do so, subject to 14 the following conditions: 15 16 The above copyright notice and this permission notice shall be included 17 in all copies or substantial portions of the Software. 18 19 THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, 20 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 21 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 22 NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 23 HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 24 WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 25 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 26 DEALINGS IN THE SOFTWARE. 27 ----------------------------------------------------------------------- */ 28 29 #include <ffi.h> 30 #include <ffi_common.h> 31 32 #include <stdlib.h> 33 34 #ifdef __GNUC__ 35 # if (__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 3)) 36 # define USE__BUILTIN___CLEAR_CACHE 1 37 # endif 38 #endif 39 40 #ifndef USE__BUILTIN___CLEAR_CACHE 41 # if defined(__OpenBSD__) 42 # include <mips64/sysarch.h> 43 # else 44 # include <sys/cachectl.h> 45 # endif 46 #endif 47 48 #ifdef FFI_DEBUG 49 # define FFI_MIPS_STOP_HERE() ffi_stop_here() 50 #else 51 # define FFI_MIPS_STOP_HERE() do {} while(0) 52 #endif 53 54 #ifdef FFI_MIPS_N32 55 #define FIX_ARGP \ 56 FFI_ASSERT(argp <= &stack[bytes]); \ 57 if (argp == &stack[bytes]) \ 58 { \ 59 argp = stack; \ 60 FFI_MIPS_STOP_HERE(); \ 61 } 62 #else 63 #define FIX_ARGP 64 #endif 65 66 67 /* ffi_prep_args is called by the assembly routine once stack space 68 has been allocated for the function's arguments */ 69 70 static void ffi_prep_args(char *stack, 71 extended_cif *ecif, 72 int bytes, 73 int flags) 74 { 75 int i; 76 void **p_argv; 77 char *argp; 78 ffi_type **p_arg; 79 80 #ifdef FFI_MIPS_N32 81 /* If more than 8 double words are used, the remainder go 82 on the stack. We reorder stuff on the stack here to 83 support this easily. */ 84 if (bytes > 8 * sizeof(ffi_arg)) 85 argp = &stack[bytes - (8 * sizeof(ffi_arg))]; 86 else 87 argp = stack; 88 #else 89 argp = stack; 90 #endif 91 92 memset(stack, 0, bytes); 93 94 #ifdef FFI_MIPS_N32 95 if ( ecif->cif->rstruct_flag != 0 ) 96 #else 97 if ( ecif->cif->rtype->type == FFI_TYPE_STRUCT ) 98 #endif 99 { 100 *(ffi_arg *) argp = (ffi_arg) ecif->rvalue; 101 argp += sizeof(ffi_arg); 102 FIX_ARGP; 103 } 104 105 p_argv = ecif->avalue; 106 107 for (i = 0, p_arg = ecif->cif->arg_types; i < ecif->cif->nargs; i++, p_arg++) 108 { 109 size_t z; 110 unsigned int a; 111 112 /* Align if necessary. */ 113 a = (*p_arg)->alignment; 114 if (a < sizeof(ffi_arg)) 115 a = sizeof(ffi_arg); 116 117 if ((a - 1) & (unsigned long) argp) 118 { 119 argp = (char *) ALIGN(argp, a); 120 FIX_ARGP; 121 } 122 123 z = (*p_arg)->size; 124 if (z <= sizeof(ffi_arg)) 125 { 126 int type = (*p_arg)->type; 127 z = sizeof(ffi_arg); 128 129 /* The size of a pointer depends on the ABI */ 130 if (type == FFI_TYPE_POINTER) 131 type = (ecif->cif->abi == FFI_N64 132 || ecif->cif->abi == FFI_N64_SOFT_FLOAT) 133 ? FFI_TYPE_SINT64 : FFI_TYPE_SINT32; 134 135 if (i < 8 && (ecif->cif->abi == FFI_N32_SOFT_FLOAT 136 || ecif->cif->abi == FFI_N64_SOFT_FLOAT)) 137 { 138 switch (type) 139 { 140 case FFI_TYPE_FLOAT: 141 type = FFI_TYPE_UINT32; 142 break; 143 case FFI_TYPE_DOUBLE: 144 type = FFI_TYPE_UINT64; 145 break; 146 default: 147 break; 148 } 149 } 150 switch (type) 151 { 152 case FFI_TYPE_SINT8: 153 *(ffi_arg *)argp = *(SINT8 *)(* p_argv); 154 break; 155 156 case FFI_TYPE_UINT8: 157 *(ffi_arg *)argp = *(UINT8 *)(* p_argv); 158 break; 159 160 case FFI_TYPE_SINT16: 161 *(ffi_arg *)argp = *(SINT16 *)(* p_argv); 162 break; 163 164 case FFI_TYPE_UINT16: 165 *(ffi_arg *)argp = *(UINT16 *)(* p_argv); 166 break; 167 168 case FFI_TYPE_SINT32: 169 *(ffi_arg *)argp = *(SINT32 *)(* p_argv); 170 break; 171 172 case FFI_TYPE_UINT32: 173 #ifdef FFI_MIPS_N32 174 /* The N32 ABI requires that 32-bit integers 175 be sign-extended to 64-bits, regardless of 176 whether they are signed or unsigned. */ 177 *(ffi_arg *)argp = *(SINT32 *)(* p_argv); 178 #else 179 *(ffi_arg *)argp = *(UINT32 *)(* p_argv); 180 #endif 181 break; 182 183 /* This can only happen with 64bit slots. */ 184 case FFI_TYPE_FLOAT: 185 *(float *) argp = *(float *)(* p_argv); 186 break; 187 188 /* Handle structures. */ 189 default: 190 memcpy(argp, *p_argv, (*p_arg)->size); 191 break; 192 } 193 } 194 else 195 { 196 #ifdef FFI_MIPS_O32 197 memcpy(argp, *p_argv, z); 198 #else 199 { 200 unsigned long end = (unsigned long) argp + z; 201 unsigned long cap = (unsigned long) stack + bytes; 202 203 /* Check if the data will fit within the register space. 204 Handle it if it doesn't. */ 205 206 if (end <= cap) 207 memcpy(argp, *p_argv, z); 208 else 209 { 210 unsigned long portion = cap - (unsigned long)argp; 211 212 memcpy(argp, *p_argv, portion); 213 argp = stack; 214 z -= portion; 215 memcpy(argp, (void*)((unsigned long)(*p_argv) + portion), 216 z); 217 } 218 } 219 #endif 220 } 221 p_argv++; 222 argp += z; 223 FIX_ARGP; 224 } 225 } 226 227 #ifdef FFI_MIPS_N32 228 229 /* The n32 spec says that if "a chunk consists solely of a double 230 float field (but not a double, which is part of a union), it 231 is passed in a floating point register. Any other chunk is 232 passed in an integer register". This code traverses structure 233 definitions and generates the appropriate flags. */ 234 235 static unsigned 236 calc_n32_struct_flags(int soft_float, ffi_type *arg, 237 unsigned *loc, unsigned *arg_reg) 238 { 239 unsigned flags = 0; 240 unsigned index = 0; 241 242 ffi_type *e; 243 244 if (soft_float) 245 return 0; 246 247 while ((e = arg->elements[index])) 248 { 249 /* Align this object. */ 250 *loc = ALIGN(*loc, e->alignment); 251 if (e->type == FFI_TYPE_DOUBLE) 252 { 253 /* Already aligned to FFI_SIZEOF_ARG. */ 254 *arg_reg = *loc / FFI_SIZEOF_ARG; 255 if (*arg_reg > 7) 256 break; 257 flags += (FFI_TYPE_DOUBLE << (*arg_reg * FFI_FLAG_BITS)); 258 *loc += e->size; 259 } 260 else 261 *loc += e->size; 262 index++; 263 } 264 /* Next Argument register at alignment of FFI_SIZEOF_ARG. */ 265 *arg_reg = ALIGN(*loc, FFI_SIZEOF_ARG) / FFI_SIZEOF_ARG; 266 267 return flags; 268 } 269 270 static unsigned 271 calc_n32_return_struct_flags(int soft_float, ffi_type *arg) 272 { 273 unsigned flags = 0; 274 unsigned small = FFI_TYPE_SMALLSTRUCT; 275 ffi_type *e; 276 277 /* Returning structures under n32 is a tricky thing. 278 A struct with only one or two floating point fields 279 is returned in $f0 (and $f2 if necessary). Any other 280 struct results at most 128 bits are returned in $2 281 (the first 64 bits) and $3 (remainder, if necessary). 282 Larger structs are handled normally. */ 283 284 if (arg->size > 16) 285 return 0; 286 287 if (arg->size > 8) 288 small = FFI_TYPE_SMALLSTRUCT2; 289 290 e = arg->elements[0]; 291 292 if (e->type == FFI_TYPE_DOUBLE) 293 flags = FFI_TYPE_DOUBLE; 294 else if (e->type == FFI_TYPE_FLOAT) 295 flags = FFI_TYPE_FLOAT; 296 297 if (flags && (e = arg->elements[1])) 298 { 299 if (e->type == FFI_TYPE_DOUBLE) 300 flags += FFI_TYPE_DOUBLE << FFI_FLAG_BITS; 301 else if (e->type == FFI_TYPE_FLOAT) 302 flags += FFI_TYPE_FLOAT << FFI_FLAG_BITS; 303 else 304 return small; 305 306 if (flags && (arg->elements[2])) 307 { 308 /* There are three arguments and the first two are 309 floats! This must be passed the old way. */ 310 return small; 311 } 312 if (soft_float) 313 flags += FFI_TYPE_STRUCT_SOFT; 314 } 315 else 316 if (!flags) 317 return small; 318 319 return flags; 320 } 321 322 #endif 323 324 /* Perform machine dependent cif processing */ 325 ffi_status ffi_prep_cif_machdep(ffi_cif *cif) 326 { 327 cif->flags = 0; 328 329 #ifdef FFI_MIPS_O32 330 /* Set the flags necessary for O32 processing. FFI_O32_SOFT_FLOAT 331 * does not have special handling for floating point args. 332 */ 333 334 if (cif->rtype->type != FFI_TYPE_STRUCT && cif->abi == FFI_O32) 335 { 336 if (cif->nargs > 0) 337 { 338 switch ((cif->arg_types)[0]->type) 339 { 340 case FFI_TYPE_FLOAT: 341 case FFI_TYPE_DOUBLE: 342 cif->flags += (cif->arg_types)[0]->type; 343 break; 344 345 default: 346 break; 347 } 348 349 if (cif->nargs > 1) 350 { 351 /* Only handle the second argument if the first 352 is a float or double. */ 353 if (cif->flags) 354 { 355 switch ((cif->arg_types)[1]->type) 356 { 357 case FFI_TYPE_FLOAT: 358 case FFI_TYPE_DOUBLE: 359 cif->flags += (cif->arg_types)[1]->type << FFI_FLAG_BITS; 360 break; 361 362 default: 363 break; 364 } 365 } 366 } 367 } 368 } 369 370 /* Set the return type flag */ 371 372 if (cif->abi == FFI_O32_SOFT_FLOAT) 373 { 374 switch (cif->rtype->type) 375 { 376 case FFI_TYPE_VOID: 377 case FFI_TYPE_STRUCT: 378 cif->flags += cif->rtype->type << (FFI_FLAG_BITS * 2); 379 break; 380 381 case FFI_TYPE_SINT64: 382 case FFI_TYPE_UINT64: 383 case FFI_TYPE_DOUBLE: 384 cif->flags += FFI_TYPE_UINT64 << (FFI_FLAG_BITS * 2); 385 break; 386 387 case FFI_TYPE_FLOAT: 388 default: 389 cif->flags += FFI_TYPE_INT << (FFI_FLAG_BITS * 2); 390 break; 391 } 392 } 393 else 394 { 395 /* FFI_O32 */ 396 switch (cif->rtype->type) 397 { 398 case FFI_TYPE_VOID: 399 case FFI_TYPE_STRUCT: 400 case FFI_TYPE_FLOAT: 401 case FFI_TYPE_DOUBLE: 402 cif->flags += cif->rtype->type << (FFI_FLAG_BITS * 2); 403 break; 404 405 case FFI_TYPE_SINT64: 406 case FFI_TYPE_UINT64: 407 cif->flags += FFI_TYPE_UINT64 << (FFI_FLAG_BITS * 2); 408 break; 409 410 default: 411 cif->flags += FFI_TYPE_INT << (FFI_FLAG_BITS * 2); 412 break; 413 } 414 } 415 #endif 416 417 #ifdef FFI_MIPS_N32 418 /* Set the flags necessary for N32 processing */ 419 { 420 int type; 421 unsigned arg_reg = 0; 422 unsigned loc = 0; 423 unsigned count = (cif->nargs < 8) ? cif->nargs : 8; 424 unsigned index = 0; 425 426 unsigned struct_flags = 0; 427 int soft_float = (cif->abi == FFI_N32_SOFT_FLOAT 428 || cif->abi == FFI_N64_SOFT_FLOAT); 429 430 if (cif->rtype->type == FFI_TYPE_STRUCT) 431 { 432 struct_flags = calc_n32_return_struct_flags(soft_float, cif->rtype); 433 434 if (struct_flags == 0) 435 { 436 /* This means that the structure is being passed as 437 a hidden argument */ 438 439 arg_reg = 1; 440 count = (cif->nargs < 7) ? cif->nargs : 7; 441 442 cif->rstruct_flag = !0; 443 } 444 else 445 cif->rstruct_flag = 0; 446 } 447 else 448 cif->rstruct_flag = 0; 449 450 while (count-- > 0 && arg_reg < 8) 451 { 452 type = (cif->arg_types)[index]->type; 453 if (soft_float) 454 { 455 switch (type) 456 { 457 case FFI_TYPE_FLOAT: 458 type = FFI_TYPE_UINT32; 459 break; 460 case FFI_TYPE_DOUBLE: 461 type = FFI_TYPE_UINT64; 462 break; 463 default: 464 break; 465 } 466 } 467 switch (type) 468 { 469 case FFI_TYPE_FLOAT: 470 case FFI_TYPE_DOUBLE: 471 cif->flags += 472 ((cif->arg_types)[index]->type << (arg_reg * FFI_FLAG_BITS)); 473 arg_reg++; 474 break; 475 case FFI_TYPE_LONGDOUBLE: 476 /* Align it. */ 477 arg_reg = ALIGN(arg_reg, 2); 478 /* Treat it as two adjacent doubles. */ 479 if (soft_float) 480 { 481 arg_reg += 2; 482 } 483 else 484 { 485 cif->flags += 486 (FFI_TYPE_DOUBLE << (arg_reg * FFI_FLAG_BITS)); 487 arg_reg++; 488 cif->flags += 489 (FFI_TYPE_DOUBLE << (arg_reg * FFI_FLAG_BITS)); 490 arg_reg++; 491 } 492 break; 493 494 case FFI_TYPE_STRUCT: 495 loc = arg_reg * FFI_SIZEOF_ARG; 496 cif->flags += calc_n32_struct_flags(soft_float, 497 (cif->arg_types)[index], 498 &loc, &arg_reg); 499 break; 500 501 default: 502 arg_reg++; 503 break; 504 } 505 506 index++; 507 } 508 509 /* Set the return type flag */ 510 switch (cif->rtype->type) 511 { 512 case FFI_TYPE_STRUCT: 513 { 514 if (struct_flags == 0) 515 { 516 /* The structure is returned through a hidden 517 first argument. Do nothing, 'cause FFI_TYPE_VOID 518 is 0 */ 519 } 520 else 521 { 522 /* The structure is returned via some tricky 523 mechanism */ 524 cif->flags += FFI_TYPE_STRUCT << (FFI_FLAG_BITS * 8); 525 cif->flags += struct_flags << (4 + (FFI_FLAG_BITS * 8)); 526 } 527 break; 528 } 529 530 case FFI_TYPE_VOID: 531 /* Do nothing, 'cause FFI_TYPE_VOID is 0 */ 532 break; 533 534 case FFI_TYPE_POINTER: 535 if (cif->abi == FFI_N32_SOFT_FLOAT || cif->abi == FFI_N32) 536 cif->flags += FFI_TYPE_SINT32 << (FFI_FLAG_BITS * 8); 537 else 538 cif->flags += FFI_TYPE_INT << (FFI_FLAG_BITS * 8); 539 break; 540 541 case FFI_TYPE_FLOAT: 542 if (soft_float) 543 { 544 cif->flags += FFI_TYPE_SINT32 << (FFI_FLAG_BITS * 8); 545 break; 546 } 547 /* else fall through */ 548 case FFI_TYPE_DOUBLE: 549 if (soft_float) 550 cif->flags += FFI_TYPE_INT << (FFI_FLAG_BITS * 8); 551 else 552 cif->flags += cif->rtype->type << (FFI_FLAG_BITS * 8); 553 break; 554 555 case FFI_TYPE_LONGDOUBLE: 556 /* Long double is returned as if it were a struct containing 557 two doubles. */ 558 if (soft_float) 559 { 560 cif->flags += FFI_TYPE_STRUCT << (FFI_FLAG_BITS * 8); 561 cif->flags += FFI_TYPE_SMALLSTRUCT2 << (4 + (FFI_FLAG_BITS * 8)); 562 } 563 else 564 { 565 cif->flags += FFI_TYPE_STRUCT << (FFI_FLAG_BITS * 8); 566 cif->flags += (FFI_TYPE_DOUBLE 567 + (FFI_TYPE_DOUBLE << FFI_FLAG_BITS)) 568 << (4 + (FFI_FLAG_BITS * 8)); 569 } 570 break; 571 default: 572 cif->flags += FFI_TYPE_INT << (FFI_FLAG_BITS * 8); 573 break; 574 } 575 } 576 #endif 577 578 return FFI_OK; 579 } 580 581 /* Low level routine for calling O32 functions */ 582 extern int ffi_call_O32(void (*)(char *, extended_cif *, int, int), 583 extended_cif *, unsigned, 584 unsigned, unsigned *, void (*)(void)); 585 586 /* Low level routine for calling N32 functions */ 587 extern int ffi_call_N32(void (*)(char *, extended_cif *, int, int), 588 extended_cif *, unsigned, 589 unsigned, void *, void (*)(void)); 590 591 void ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue) 592 { 593 extended_cif ecif; 594 595 ecif.cif = cif; 596 ecif.avalue = avalue; 597 598 /* If the return value is a struct and we don't have a return */ 599 /* value address then we need to make one */ 600 601 if ((rvalue == NULL) && 602 (cif->rtype->type == FFI_TYPE_STRUCT)) 603 ecif.rvalue = alloca(cif->rtype->size); 604 else 605 ecif.rvalue = rvalue; 606 607 switch (cif->abi) 608 { 609 #ifdef FFI_MIPS_O32 610 case FFI_O32: 611 case FFI_O32_SOFT_FLOAT: 612 ffi_call_O32(ffi_prep_args, &ecif, cif->bytes, 613 cif->flags, ecif.rvalue, fn); 614 break; 615 #endif 616 617 #ifdef FFI_MIPS_N32 618 case FFI_N32: 619 case FFI_N32_SOFT_FLOAT: 620 case FFI_N64: 621 case FFI_N64_SOFT_FLOAT: 622 { 623 int copy_rvalue = 0; 624 int copy_offset = 0; 625 char *rvalue_copy = ecif.rvalue; 626 if (cif->rtype->type == FFI_TYPE_STRUCT && cif->rtype->size < 16) 627 { 628 /* For structures smaller than 16 bytes we clobber memory 629 in 8 byte increments. Make a copy so we don't clobber 630 the callers memory outside of the struct bounds. */ 631 rvalue_copy = alloca(16); 632 copy_rvalue = 1; 633 } 634 else if (cif->rtype->type == FFI_TYPE_FLOAT 635 && (cif->abi == FFI_N64_SOFT_FLOAT 636 || cif->abi == FFI_N32_SOFT_FLOAT)) 637 { 638 rvalue_copy = alloca (8); 639 copy_rvalue = 1; 640 #if defined(__MIPSEB__) || defined(_MIPSEB) 641 copy_offset = 4; 642 #endif 643 } 644 ffi_call_N32(ffi_prep_args, &ecif, cif->bytes, 645 cif->flags, rvalue_copy, fn); 646 if (copy_rvalue) 647 memcpy(ecif.rvalue, rvalue_copy + copy_offset, cif->rtype->size); 648 } 649 break; 650 #endif 651 652 default: 653 FFI_ASSERT(0); 654 break; 655 } 656 } 657 658 #if FFI_CLOSURES 659 #if defined(FFI_MIPS_O32) 660 extern void ffi_closure_O32(void); 661 #else 662 extern void ffi_closure_N32(void); 663 #endif /* FFI_MIPS_O32 */ 664 665 ffi_status 666 ffi_prep_closure_loc (ffi_closure *closure, 667 ffi_cif *cif, 668 void (*fun)(ffi_cif*,void*,void**,void*), 669 void *user_data, 670 void *codeloc) 671 { 672 unsigned int *tramp = (unsigned int *) &closure->tramp[0]; 673 void * fn; 674 char *clear_location = (char *) codeloc; 675 676 #if defined(FFI_MIPS_O32) 677 if (cif->abi != FFI_O32 && cif->abi != FFI_O32_SOFT_FLOAT) 678 return FFI_BAD_ABI; 679 fn = ffi_closure_O32; 680 #else 681 #if _MIPS_SIM ==_ABIN32 682 if (cif->abi != FFI_N32 683 && cif->abi != FFI_N32_SOFT_FLOAT) 684 return FFI_BAD_ABI; 685 #else 686 if (cif->abi != FFI_N64 687 && cif->abi != FFI_N64_SOFT_FLOAT) 688 return FFI_BAD_ABI; 689 #endif 690 fn = ffi_closure_N32; 691 #endif /* FFI_MIPS_O32 */ 692 693 #if defined(FFI_MIPS_O32) || (_MIPS_SIM ==_ABIN32) 694 /* lui $25,high(fn) */ 695 tramp[0] = 0x3c190000 | ((unsigned)fn >> 16); 696 /* ori $25,low(fn) */ 697 tramp[1] = 0x37390000 | ((unsigned)fn & 0xffff); 698 /* lui $12,high(codeloc) */ 699 tramp[2] = 0x3c0c0000 | ((unsigned)codeloc >> 16); 700 /* jr $25 */ 701 tramp[3] = 0x03200008; 702 /* ori $12,low(codeloc) */ 703 tramp[4] = 0x358c0000 | ((unsigned)codeloc & 0xffff); 704 #else 705 /* N64 has a somewhat larger trampoline. */ 706 /* lui $25,high(fn) */ 707 tramp[0] = 0x3c190000 | ((unsigned long)fn >> 48); 708 /* lui $12,high(codeloc) */ 709 tramp[1] = 0x3c0c0000 | ((unsigned long)codeloc >> 48); 710 /* ori $25,mid-high(fn) */ 711 tramp[2] = 0x37390000 | (((unsigned long)fn >> 32 ) & 0xffff); 712 /* ori $12,mid-high(codeloc) */ 713 tramp[3] = 0x358c0000 | (((unsigned long)codeloc >> 32) & 0xffff); 714 /* dsll $25,$25,16 */ 715 tramp[4] = 0x0019cc38; 716 /* dsll $12,$12,16 */ 717 tramp[5] = 0x000c6438; 718 /* ori $25,mid-low(fn) */ 719 tramp[6] = 0x37390000 | (((unsigned long)fn >> 16 ) & 0xffff); 720 /* ori $12,mid-low(codeloc) */ 721 tramp[7] = 0x358c0000 | (((unsigned long)codeloc >> 16) & 0xffff); 722 /* dsll $25,$25,16 */ 723 tramp[8] = 0x0019cc38; 724 /* dsll $12,$12,16 */ 725 tramp[9] = 0x000c6438; 726 /* ori $25,low(fn) */ 727 tramp[10] = 0x37390000 | ((unsigned long)fn & 0xffff); 728 /* jr $25 */ 729 tramp[11] = 0x03200008; 730 /* ori $12,low(codeloc) */ 731 tramp[12] = 0x358c0000 | ((unsigned long)codeloc & 0xffff); 732 733 #endif 734 735 closure->cif = cif; 736 closure->fun = fun; 737 closure->user_data = user_data; 738 739 #ifdef USE__BUILTIN___CLEAR_CACHE 740 __builtin___clear_cache(clear_location, clear_location + FFI_TRAMPOLINE_SIZE); 741 #else 742 cacheflush (clear_location, FFI_TRAMPOLINE_SIZE, ICACHE); 743 #endif 744 return FFI_OK; 745 } 746 747 /* 748 * Decodes the arguments to a function, which will be stored on the 749 * stack. AR is the pointer to the beginning of the integer arguments 750 * (and, depending upon the arguments, some floating-point arguments 751 * as well). FPR is a pointer to the area where floating point 752 * registers have been saved, if any. 753 * 754 * RVALUE is the location where the function return value will be 755 * stored. CLOSURE is the prepared closure to invoke. 756 * 757 * This function should only be called from assembly, which is in 758 * turn called from a trampoline. 759 * 760 * Returns the function return type. 761 * 762 * Based on the similar routine for sparc. 763 */ 764 int 765 ffi_closure_mips_inner_O32 (ffi_closure *closure, 766 void *rvalue, ffi_arg *ar, 767 double *fpr) 768 { 769 ffi_cif *cif; 770 void **avaluep; 771 ffi_arg *avalue; 772 ffi_type **arg_types; 773 int i, avn, argn, seen_int; 774 775 cif = closure->cif; 776 avalue = alloca (cif->nargs * sizeof (ffi_arg)); 777 avaluep = alloca (cif->nargs * sizeof (ffi_arg)); 778 779 seen_int = (cif->abi == FFI_O32_SOFT_FLOAT); 780 argn = 0; 781 782 if ((cif->flags >> (FFI_FLAG_BITS * 2)) == FFI_TYPE_STRUCT) 783 { 784 rvalue = (void *)(UINT32)ar[0]; 785 argn = 1; 786 } 787 788 i = 0; 789 avn = cif->nargs; 790 arg_types = cif->arg_types; 791 792 while (i < avn) 793 { 794 if (i < 2 && !seen_int && 795 (arg_types[i]->type == FFI_TYPE_FLOAT || 796 arg_types[i]->type == FFI_TYPE_DOUBLE || 797 arg_types[i]->type == FFI_TYPE_LONGDOUBLE)) 798 { 799 #if defined(__MIPSEB__) || defined(_MIPSEB) 800 if (arg_types[i]->type == FFI_TYPE_FLOAT) 801 avaluep[i] = ((char *) &fpr[i]) + sizeof (float); 802 else 803 #endif 804 avaluep[i] = (char *) &fpr[i]; 805 } 806 else 807 { 808 if (arg_types[i]->alignment == 8 && (argn & 0x1)) 809 argn++; 810 switch (arg_types[i]->type) 811 { 812 case FFI_TYPE_SINT8: 813 avaluep[i] = &avalue[i]; 814 *(SINT8 *) &avalue[i] = (SINT8) ar[argn]; 815 break; 816 817 case FFI_TYPE_UINT8: 818 avaluep[i] = &avalue[i]; 819 *(UINT8 *) &avalue[i] = (UINT8) ar[argn]; 820 break; 821 822 case FFI_TYPE_SINT16: 823 avaluep[i] = &avalue[i]; 824 *(SINT16 *) &avalue[i] = (SINT16) ar[argn]; 825 break; 826 827 case FFI_TYPE_UINT16: 828 avaluep[i] = &avalue[i]; 829 *(UINT16 *) &avalue[i] = (UINT16) ar[argn]; 830 break; 831 832 default: 833 avaluep[i] = (char *) &ar[argn]; 834 break; 835 } 836 seen_int = 1; 837 } 838 argn += ALIGN(arg_types[i]->size, FFI_SIZEOF_ARG) / FFI_SIZEOF_ARG; 839 i++; 840 } 841 842 /* Invoke the closure. */ 843 (closure->fun) (cif, rvalue, avaluep, closure->user_data); 844 845 if (cif->abi == FFI_O32_SOFT_FLOAT) 846 { 847 switch (cif->rtype->type) 848 { 849 case FFI_TYPE_FLOAT: 850 return FFI_TYPE_INT; 851 case FFI_TYPE_DOUBLE: 852 return FFI_TYPE_UINT64; 853 default: 854 return cif->rtype->type; 855 } 856 } 857 else 858 { 859 return cif->rtype->type; 860 } 861 } 862 863 #if defined(FFI_MIPS_N32) 864 865 static void 866 copy_struct_N32(char *target, unsigned offset, ffi_abi abi, ffi_type *type, 867 int argn, unsigned arg_offset, ffi_arg *ar, 868 ffi_arg *fpr, int soft_float) 869 { 870 ffi_type **elt_typep = type->elements; 871 while(*elt_typep) 872 { 873 ffi_type *elt_type = *elt_typep; 874 unsigned o; 875 char *tp; 876 char *argp; 877 char *fpp; 878 879 o = ALIGN(offset, elt_type->alignment); 880 arg_offset += o - offset; 881 offset = o; 882 argn += arg_offset / sizeof(ffi_arg); 883 arg_offset = arg_offset % sizeof(ffi_arg); 884 885 argp = (char *)(ar + argn); 886 fpp = (char *)(argn >= 8 ? ar + argn : fpr + argn); 887 888 tp = target + offset; 889 890 if (elt_type->type == FFI_TYPE_DOUBLE && !soft_float) 891 *(double *)tp = *(double *)fpp; 892 else 893 memcpy(tp, argp + arg_offset, elt_type->size); 894 895 offset += elt_type->size; 896 arg_offset += elt_type->size; 897 elt_typep++; 898 argn += arg_offset / sizeof(ffi_arg); 899 arg_offset = arg_offset % sizeof(ffi_arg); 900 } 901 } 902 903 /* 904 * Decodes the arguments to a function, which will be stored on the 905 * stack. AR is the pointer to the beginning of the integer 906 * arguments. FPR is a pointer to the area where floating point 907 * registers have been saved. 908 * 909 * RVALUE is the location where the function return value will be 910 * stored. CLOSURE is the prepared closure to invoke. 911 * 912 * This function should only be called from assembly, which is in 913 * turn called from a trampoline. 914 * 915 * Returns the function return flags. 916 * 917 */ 918 int 919 ffi_closure_mips_inner_N32 (ffi_closure *closure, 920 void *rvalue, ffi_arg *ar, 921 ffi_arg *fpr) 922 { 923 ffi_cif *cif; 924 void **avaluep; 925 ffi_arg *avalue; 926 ffi_type **arg_types; 927 int i, avn, argn; 928 int soft_float; 929 ffi_arg *argp; 930 931 cif = closure->cif; 932 soft_float = cif->abi == FFI_N64_SOFT_FLOAT 933 || cif->abi == FFI_N32_SOFT_FLOAT; 934 avalue = alloca (cif->nargs * sizeof (ffi_arg)); 935 avaluep = alloca (cif->nargs * sizeof (ffi_arg)); 936 937 argn = 0; 938 939 if (cif->rstruct_flag) 940 { 941 #if _MIPS_SIM==_ABIN32 942 rvalue = (void *)(UINT32)ar[0]; 943 #else /* N64 */ 944 rvalue = (void *)ar[0]; 945 #endif 946 argn = 1; 947 } 948 949 i = 0; 950 avn = cif->nargs; 951 arg_types = cif->arg_types; 952 953 while (i < avn) 954 { 955 if (arg_types[i]->type == FFI_TYPE_FLOAT 956 || arg_types[i]->type == FFI_TYPE_DOUBLE 957 || arg_types[i]->type == FFI_TYPE_LONGDOUBLE) 958 { 959 argp = (argn >= 8 || soft_float) ? ar + argn : fpr + argn; 960 if ((arg_types[i]->type == FFI_TYPE_LONGDOUBLE) && ((unsigned)argp & (arg_types[i]->alignment-1))) 961 { 962 argp=(ffi_arg*)ALIGN(argp,arg_types[i]->alignment); 963 argn++; 964 } 965 #if defined(__MIPSEB__) || defined(_MIPSEB) 966 if (arg_types[i]->type == FFI_TYPE_FLOAT && argn < 8) 967 avaluep[i] = ((char *) argp) + sizeof (float); 968 else 969 #endif 970 avaluep[i] = (char *) argp; 971 } 972 else 973 { 974 unsigned type = arg_types[i]->type; 975 976 if (arg_types[i]->alignment > sizeof(ffi_arg)) 977 argn = ALIGN(argn, arg_types[i]->alignment / sizeof(ffi_arg)); 978 979 argp = ar + argn; 980 981 /* The size of a pointer depends on the ABI */ 982 if (type == FFI_TYPE_POINTER) 983 type = (cif->abi == FFI_N64 || cif->abi == FFI_N64_SOFT_FLOAT) 984 ? FFI_TYPE_SINT64 : FFI_TYPE_SINT32; 985 986 if (soft_float && type == FFI_TYPE_FLOAT) 987 type = FFI_TYPE_UINT32; 988 989 switch (type) 990 { 991 case FFI_TYPE_SINT8: 992 avaluep[i] = &avalue[i]; 993 *(SINT8 *) &avalue[i] = (SINT8) *argp; 994 break; 995 996 case FFI_TYPE_UINT8: 997 avaluep[i] = &avalue[i]; 998 *(UINT8 *) &avalue[i] = (UINT8) *argp; 999 break; 1000 1001 case FFI_TYPE_SINT16: 1002 avaluep[i] = &avalue[i]; 1003 *(SINT16 *) &avalue[i] = (SINT16) *argp; 1004 break; 1005 1006 case FFI_TYPE_UINT16: 1007 avaluep[i] = &avalue[i]; 1008 *(UINT16 *) &avalue[i] = (UINT16) *argp; 1009 break; 1010 1011 case FFI_TYPE_SINT32: 1012 avaluep[i] = &avalue[i]; 1013 *(SINT32 *) &avalue[i] = (SINT32) *argp; 1014 break; 1015 1016 case FFI_TYPE_UINT32: 1017 avaluep[i] = &avalue[i]; 1018 *(UINT32 *) &avalue[i] = (UINT32) *argp; 1019 break; 1020 1021 case FFI_TYPE_STRUCT: 1022 if (argn < 8) 1023 { 1024 /* Allocate space for the struct as at least part of 1025 it was passed in registers. */ 1026 avaluep[i] = alloca(arg_types[i]->size); 1027 copy_struct_N32(avaluep[i], 0, cif->abi, arg_types[i], 1028 argn, 0, ar, fpr, soft_float); 1029 1030 break; 1031 } 1032 /* Else fall through. */ 1033 default: 1034 avaluep[i] = (char *) argp; 1035 break; 1036 } 1037 } 1038 argn += ALIGN(arg_types[i]->size, sizeof(ffi_arg)) / sizeof(ffi_arg); 1039 i++; 1040 } 1041 1042 /* Invoke the closure. */ 1043 (closure->fun) (cif, rvalue, avaluep, closure->user_data); 1044 1045 return cif->flags >> (FFI_FLAG_BITS * 8); 1046 } 1047 1048 #endif /* FFI_MIPS_N32 */ 1049 1050 #endif /* FFI_CLOSURES */