1a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project/* ----------------------------------------------------------------------- 2a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project ffi.c - Copyright (c) 2003, 2004 Kaz Kojima 3a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project Copyright (c) 2008 Anthony Green 4a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 5a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project SuperH SHmedia Foreign Function Interface 6a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 7a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project Permission is hereby granted, free of charge, to any person obtaining 8a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project a copy of this software and associated documentation files (the 9a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project ``Software''), to deal in the Software without restriction, including 10a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project without limitation the rights to use, copy, modify, merge, publish, 11a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project distribute, sublicense, and/or sell copies of the Software, and to 12a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project permit persons to whom the Software is furnished to do so, subject to 13a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project the following conditions: 14a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 15a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project The above copyright notice and this permission notice shall be included 16a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project in all copies or substantial portions of the Software. 17a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 18a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, 19a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 20a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 21a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 22a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 23a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 25a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project DEALINGS IN THE SOFTWARE. 26a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project ----------------------------------------------------------------------- */ 27a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 28a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project#include <ffi.h> 29a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project#include <ffi_common.h> 30a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 31a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project#include <stdlib.h> 32a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 33a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project#define NGREGARG 8 34a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project#define NFREGARG 12 35a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 36a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Projectstatic int 37a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Projectreturn_type (ffi_type *arg) 38a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project{ 39a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 40a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project if (arg->type != FFI_TYPE_STRUCT) 41a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project return arg->type; 42a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 43a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project /* gcc uses r2 if the result can be packed in on register. */ 44a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project if (arg->size <= sizeof (UINT8)) 45a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project return FFI_TYPE_UINT8; 46a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project else if (arg->size <= sizeof (UINT16)) 47a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project return FFI_TYPE_UINT16; 48a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project else if (arg->size <= sizeof (UINT32)) 49a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project return FFI_TYPE_UINT32; 50a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project else if (arg->size <= sizeof (UINT64)) 51a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project return FFI_TYPE_UINT64; 52a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 53a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project return FFI_TYPE_STRUCT; 54a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project} 55a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 56a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project/* ffi_prep_args is called by the assembly routine once stack space 57a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project has been allocated for the function's arguments */ 58a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 59a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project/*@-exportheader@*/ 60a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Projectvoid ffi_prep_args(char *stack, extended_cif *ecif) 61a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project/*@=exportheader@*/ 62a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project{ 63a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project register unsigned int i; 64a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project register unsigned int avn; 65a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project register void **p_argv; 66a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project register char *argp; 67a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project register ffi_type **p_arg; 68a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 69a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project argp = stack; 70a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 71a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project if (return_type (ecif->cif->rtype) == FFI_TYPE_STRUCT) 72a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project { 73a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project *(void **) argp = ecif->rvalue; 74a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project argp += sizeof (UINT64); 75a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project } 76a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 77a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project avn = ecif->cif->nargs; 78a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project p_argv = ecif->avalue; 79a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 80a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project for (i = 0, p_arg = ecif->cif->arg_types; i < avn; i++, p_arg++, p_argv++) 81a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project { 82a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project size_t z; 83a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project int align; 84a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 85a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project z = (*p_arg)->size; 86a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project align = (*p_arg)->alignment; 87a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project if (z < sizeof (UINT32)) 88a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project { 89a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project switch ((*p_arg)->type) 90a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project { 91a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project case FFI_TYPE_SINT8: 92a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project *(SINT64 *) argp = (SINT64) *(SINT8 *)(*p_argv); 93a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project break; 94a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 95a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project case FFI_TYPE_UINT8: 96a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project *(UINT64 *) argp = (UINT64) *(UINT8 *)(*p_argv); 97a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project break; 98a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 99a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project case FFI_TYPE_SINT16: 100a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project *(SINT64 *) argp = (SINT64) *(SINT16 *)(*p_argv); 101a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project break; 102a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 103a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project case FFI_TYPE_UINT16: 104a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project *(UINT64 *) argp = (UINT64) *(UINT16 *)(*p_argv); 105a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project break; 106a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 107a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project case FFI_TYPE_STRUCT: 108a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project memcpy (argp, *p_argv, z); 109a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project break; 110a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 111a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project default: 112a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project FFI_ASSERT(0); 113a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project } 114a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project argp += sizeof (UINT64); 115a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project } 116a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project else if (z == sizeof (UINT32) && align == sizeof (UINT32)) 117a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project { 118a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project switch ((*p_arg)->type) 119a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project { 120a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project case FFI_TYPE_INT: 121a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project case FFI_TYPE_SINT32: 122a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project *(SINT64 *) argp = (SINT64) *(SINT32 *) (*p_argv); 123a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project break; 124a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 125a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project case FFI_TYPE_FLOAT: 126a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project case FFI_TYPE_POINTER: 127a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project case FFI_TYPE_UINT32: 128a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project case FFI_TYPE_STRUCT: 129a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project *(UINT64 *) argp = (UINT64) *(UINT32 *) (*p_argv); 130a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project break; 131a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 132a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project default: 133a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project FFI_ASSERT(0); 134a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project break; 135a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project } 136a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project argp += sizeof (UINT64); 137a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project } 138a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project else if (z == sizeof (UINT64) 139a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project && align == sizeof (UINT64) 140a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project && ((int) *p_argv & (sizeof (UINT64) - 1)) == 0) 141a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project { 142a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project *(UINT64 *) argp = *(UINT64 *) (*p_argv); 143a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project argp += sizeof (UINT64); 144a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project } 145a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project else 146a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project { 147a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project int n = (z + sizeof (UINT64) - 1) / sizeof (UINT64); 148a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 149a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project memcpy (argp, *p_argv, z); 150a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project argp += n * sizeof (UINT64); 151a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project } 152a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project } 153a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 154a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project return; 155a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project} 156a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 157a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project/* Perform machine dependent cif processing */ 158a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Projectffi_status ffi_prep_cif_machdep(ffi_cif *cif) 159a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project{ 160a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project int i, j; 161a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project int size, type; 162a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project int n, m; 163a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project int greg; 164a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project int freg; 165a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 166a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project greg = (return_type (cif->rtype) == FFI_TYPE_STRUCT ? 1 : 0); 167a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project freg = 0; 168a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project cif->flags2 = 0; 169a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 170a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project for (i = j = 0; i < cif->nargs; i++) 171a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project { 172a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project type = (cif->arg_types)[i]->type; 173a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project switch (type) 174a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project { 175a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project case FFI_TYPE_FLOAT: 176a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project greg++; 177a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project cif->bytes += sizeof (UINT64) - sizeof (float); 178a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project if (freg >= NFREGARG - 1) 179a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project continue; 180a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project freg++; 181a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project cif->flags2 += ((cif->arg_types)[i]->type) << (2 * j++); 182a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project break; 183a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 184a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project case FFI_TYPE_DOUBLE: 185a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project if (greg++ >= NGREGARG && (freg + 1) >= NFREGARG) 186a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project continue; 187a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project if ((freg + 1) < NFREGARG) 188a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project { 189a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project freg = (freg + 1) & ~1; 190a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project freg += 2; 191a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project cif->flags2 += ((cif->arg_types)[i]->type) << (2 * j++); 192a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project } 193a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project else 194a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project cif->flags2 += FFI_TYPE_INT << (2 * j++); 195a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project break; 196a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 197a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project default: 198a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project size = (cif->arg_types)[i]->size; 199a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project if (size < sizeof (UINT64)) 200a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project cif->bytes += sizeof (UINT64) - size; 201a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project n = (size + sizeof (UINT64) - 1) / sizeof (UINT64); 202a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project if (greg >= NGREGARG) 203a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project continue; 204a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project else if (greg + n - 1 >= NGREGARG) 205a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project greg = NGREGARG; 206a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project else 207a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project greg += n; 208a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project for (m = 0; m < n; m++) 209a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project cif->flags2 += FFI_TYPE_INT << (2 * j++); 210a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project break; 211a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project } 212a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project } 213a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 214a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project /* Set the return type flag */ 215a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project switch (cif->rtype->type) 216a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project { 217a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project case FFI_TYPE_STRUCT: 218a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project cif->flags = return_type (cif->rtype); 219a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project break; 220a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 221a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project case FFI_TYPE_VOID: 222a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project case FFI_TYPE_FLOAT: 223a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project case FFI_TYPE_DOUBLE: 224a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project case FFI_TYPE_SINT64: 225a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project case FFI_TYPE_UINT64: 226a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project cif->flags = cif->rtype->type; 227a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project break; 228a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 229a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project default: 230a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project cif->flags = FFI_TYPE_INT; 231a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project break; 232a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project } 233a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 234a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project return FFI_OK; 235a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project} 236a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 237a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project/*@-declundef@*/ 238a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project/*@-exportheader@*/ 239a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Projectextern void ffi_call_SYSV(void (*)(char *, extended_cif *), 240a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project /*@out@*/ extended_cif *, 241a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project unsigned, unsigned, long long, 242a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project /*@out@*/ unsigned *, 243a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project void (*fn)(void)); 244a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project/*@=declundef@*/ 245a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project/*@=exportheader@*/ 246a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 247a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Projectvoid ffi_call(/*@dependent@*/ ffi_cif *cif, 248a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project void (*fn)(void), 249a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project /*@out@*/ void *rvalue, 250a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project /*@dependent@*/ void **avalue) 251a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project{ 252a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project extended_cif ecif; 253a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project UINT64 trvalue; 254a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 255a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project ecif.cif = cif; 256a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project ecif.avalue = avalue; 257a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 258a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project /* If the return value is a struct and we don't have a return */ 259a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project /* value address then we need to make one */ 260a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 261a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project if (cif->rtype->type == FFI_TYPE_STRUCT 262a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project && return_type (cif->rtype) != FFI_TYPE_STRUCT) 263a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project ecif.rvalue = &trvalue; 264a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project else if ((rvalue == NULL) && 265a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project (cif->rtype->type == FFI_TYPE_STRUCT)) 266a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project { 267a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project /*@-sysunrecog@*/ 268a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project ecif.rvalue = alloca(cif->rtype->size); 269a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project /*@=sysunrecog@*/ 270a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project } 271a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project else 272a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project ecif.rvalue = rvalue; 273a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 274a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project switch (cif->abi) 275a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project { 276a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project case FFI_SYSV: 277a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project /*@-usedef@*/ 278a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project ffi_call_SYSV(ffi_prep_args, &ecif, cif->bytes, 279a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project cif->flags, cif->flags2, ecif.rvalue, fn); 280a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project /*@=usedef@*/ 281a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project break; 282a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project default: 283a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project FFI_ASSERT(0); 284a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project break; 285a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project } 286a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 287a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project if (rvalue 288a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project && cif->rtype->type == FFI_TYPE_STRUCT 289a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project && return_type (cif->rtype) != FFI_TYPE_STRUCT) 290a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project memcpy (rvalue, &trvalue, cif->rtype->size); 291a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project} 292a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 293a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Projectextern void ffi_closure_SYSV (void); 294a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Projectextern void __ic_invalidate (void *line); 295a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 296a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Projectffi_status 297a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Projectffi_prep_closure (ffi_closure *closure, 298a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project ffi_cif *cif, 299a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project void (*fun)(ffi_cif*, void*, void**, void*), 300a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project void *user_data) 301a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project{ 302a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project unsigned int *tramp; 303a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 304a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project FFI_ASSERT (cif->abi == FFI_GCC_SYSV); 305a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 306a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project tramp = (unsigned int *) &closure->tramp[0]; 307a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project /* Since ffi_closure is an aligned object, the ffi trampoline is 308a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project called as an SHcompact code. Sigh. 309a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project SHcompact part: 310a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project mova @(1,pc),r0; add #1,r0; jmp @r0; nop; 311a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project SHmedia part: 312a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project movi fnaddr >> 16,r1; shori fnaddr,r1; ptabs/l r1,tr0 313a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project movi cxt >> 16,r1; shori cxt,r1; blink tr0,r63 */ 314a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project#ifdef __LITTLE_ENDIAN__ 315a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project tramp[0] = 0x7001c701; 316a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project tramp[1] = 0x0009402b; 317a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project#else 318a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project tramp[0] = 0xc7017001; 319a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project tramp[1] = 0x402b0009; 320a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project#endif 321a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project tramp[2] = 0xcc000010 | (((UINT32) ffi_closure_SYSV) >> 16) << 10; 322a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project tramp[3] = 0xc8000010 | (((UINT32) ffi_closure_SYSV) & 0xffff) << 10; 323a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project tramp[4] = 0x6bf10600; 324a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project tramp[5] = 0xcc000010 | (((UINT32) closure) >> 16) << 10; 325a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project tramp[6] = 0xc8000010 | (((UINT32) closure) & 0xffff) << 10; 326a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project tramp[7] = 0x4401fff0; 327a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 328a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project closure->cif = cif; 329a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project closure->fun = fun; 330a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project closure->user_data = user_data; 331a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 332a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project /* Flush the icache. */ 333a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project asm volatile ("ocbwb %0,0; synco; icbi %0,0; synci" : : "r" (tramp)); 334a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 335a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project return FFI_OK; 336a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project} 337a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 338a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project/* Basically the trampoline invokes ffi_closure_SYSV, and on 339a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project * entry, r3 holds the address of the closure. 340a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project * After storing the registers that could possibly contain 341a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project * parameters to be passed into the stack frame and setting 342a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project * up space for a return value, ffi_closure_SYSV invokes the 343a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project * following helper function to do most of the work. 344a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project */ 345a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 346a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Projectint 347a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Projectffi_closure_helper_SYSV (ffi_closure *closure, UINT64 *rvalue, 348a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project UINT64 *pgr, UINT64 *pfr, UINT64 *pst) 349a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project{ 350a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project void **avalue; 351a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project ffi_type **p_arg; 352a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project int i, avn; 353a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project int greg, freg; 354a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project ffi_cif *cif; 355a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 356a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project cif = closure->cif; 357a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project avalue = alloca (cif->nargs * sizeof (void *)); 358a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 359a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project /* Copy the caller's structure return value address so that the closure 360a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project returns the data directly to the caller. */ 361a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project if (return_type (cif->rtype) == FFI_TYPE_STRUCT) 362a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project { 363a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project rvalue = *pgr; 364a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project greg = 1; 365a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project } 366a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project else 367a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project greg = 0; 368a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 369a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project freg = 0; 370a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project cif = closure->cif; 371a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project avn = cif->nargs; 372a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 373a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project /* Grab the addresses of the arguments from the stack frame. */ 374a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project for (i = 0, p_arg = cif->arg_types; i < avn; i++, p_arg++) 375a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project { 376a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project size_t z; 377a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project void *p; 378a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 379a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project z = (*p_arg)->size; 380a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project if (z < sizeof (UINT32)) 381a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project { 382a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project p = pgr + greg++; 383a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 384a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project switch ((*p_arg)->type) 385a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project { 386a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project case FFI_TYPE_SINT8: 387a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project case FFI_TYPE_UINT8: 388a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project case FFI_TYPE_SINT16: 389a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project case FFI_TYPE_UINT16: 390a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project case FFI_TYPE_STRUCT: 391a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project#ifdef __LITTLE_ENDIAN__ 392a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project avalue[i] = p; 393a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project#else 394a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project avalue[i] = ((char *) p) + sizeof (UINT32) - z; 395a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project#endif 396a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project break; 397a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 398a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project default: 399a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project FFI_ASSERT(0); 400a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project } 401a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project } 402a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project else if (z == sizeof (UINT32)) 403a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project { 404a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project if ((*p_arg)->type == FFI_TYPE_FLOAT) 405a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project { 406a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project if (freg < NFREGARG - 1) 407a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project#ifdef __LITTLE_ENDIAN__ 408a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project avalue[i] = (UINT32 *) pfr + (1 ^ freg++); 409a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project#else 410a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project avalue[i] = (UINT32 *) pfr + freg++; 411a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project#endif 412a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project else 413a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project#ifdef __LITTLE_ENDIAN__ 414a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project avalue[i] = pgr + greg; 415a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project#else 416a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project avalue[i] = (UINT32 *) (pgr + greg) + 1; 417a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project#endif 418a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project } 419a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project else 420a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project#ifdef __LITTLE_ENDIAN__ 421a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project avalue[i] = pgr + greg; 422a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project#else 423a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project avalue[i] = (UINT32 *) (pgr + greg) + 1; 424a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project#endif 425a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project greg++; 426a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project } 427a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project else if ((*p_arg)->type == FFI_TYPE_DOUBLE) 428a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project { 429a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project if (freg + 1 >= NFREGARG) 430a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project avalue[i] = pgr + greg; 431a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project else 432a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project { 433a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project freg = (freg + 1) & ~1; 434a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project avalue[i] = pfr + (freg >> 1); 435a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project freg += 2; 436a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project } 437a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project greg++; 438a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project } 439a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project else 440a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project { 441a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project int n = (z + sizeof (UINT64) - 1) / sizeof (UINT64); 442a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 443a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project avalue[i] = pgr + greg; 444a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project greg += n; 445a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project } 446a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project } 447a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 448a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project (closure->fun) (cif, rvalue, avalue, closure->user_data); 449a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 450a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project /* Tell ffi_closure_SYSV how to perform return type promotions. */ 451a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project return return_type (cif->rtype); 452a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project} 453a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 454