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