1a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project/* ----------------------------------------------------------------------- 2a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project ffi.c - Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008 Kaz Kojima 3a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project Copyright (c) 2008 Red Hat, Inc. 4a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 5a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project SuperH 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 4 34a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project#if defined(__SH4__) 35a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project#define NFREGARG 8 36a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project#endif 37a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 38a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project#if defined(__HITACHI__) 39a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project#define STRUCT_VALUE_ADDRESS_WITH_ARG 1 40a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project#else 41a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project#define STRUCT_VALUE_ADDRESS_WITH_ARG 0 42a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project#endif 43a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 44a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project/* If the structure has essentialy an unique element, return its type. */ 45a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Projectstatic int 46a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Projectsimple_type (ffi_type *arg) 47a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project{ 48a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project if (arg->type != FFI_TYPE_STRUCT) 49a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project return arg->type; 50a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project else if (arg->elements[1]) 51a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project return FFI_TYPE_STRUCT; 52a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 53a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project return simple_type (arg->elements[0]); 54a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project} 55a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 56a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Projectstatic int 57a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Projectreturn_type (ffi_type *arg) 58a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project{ 59a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project unsigned short type; 60a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 61a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project if (arg->type != FFI_TYPE_STRUCT) 62a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project return arg->type; 63a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 64a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project type = simple_type (arg->elements[0]); 65a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project if (! arg->elements[1]) 66a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project { 67a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project switch (type) 68a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project { 69a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project case FFI_TYPE_SINT8: 70a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project case FFI_TYPE_UINT8: 71a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project case FFI_TYPE_SINT16: 72a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project case FFI_TYPE_UINT16: 73a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project case FFI_TYPE_SINT32: 74a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project case FFI_TYPE_UINT32: 75a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project return FFI_TYPE_INT; 76a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 77a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project default: 78a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project return type; 79a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project } 80a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project } 81a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 82a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project /* gcc uses r0/r1 pair for some kind of structures. */ 83a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project if (arg->size <= 2 * sizeof (int)) 84a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project { 85a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project int i = 0; 86a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project ffi_type *e; 87a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 88a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project while ((e = arg->elements[i++])) 89a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project { 90a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project type = simple_type (e); 91a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project switch (type) 92a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project { 93a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project case FFI_TYPE_SINT32: 94a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project case FFI_TYPE_UINT32: 95a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project case FFI_TYPE_INT: 96a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project case FFI_TYPE_FLOAT: 97a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project return FFI_TYPE_UINT64; 98a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 99a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project default: 100a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project break; 101a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project } 102a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project } 103a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project } 104a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 105a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project return FFI_TYPE_STRUCT; 106a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project} 107a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 108a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project/* ffi_prep_args is called by the assembly routine once stack space 109a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project has been allocated for the function's arguments */ 110a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 111a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Projectvoid ffi_prep_args(char *stack, extended_cif *ecif) 112a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project{ 113a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project register unsigned int i; 114a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project register int tmp; 115a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project register unsigned int avn; 116a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project register void **p_argv; 117a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project register char *argp; 118a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project register ffi_type **p_arg; 119a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project int greg, ireg; 120a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project#if defined(__SH4__) 121a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project int freg = 0; 122a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project#endif 123a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 124a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project tmp = 0; 125a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project argp = stack; 126a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 127a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project if (return_type (ecif->cif->rtype) == FFI_TYPE_STRUCT) 128a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project { 129a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project *(void **) argp = ecif->rvalue; 130a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project argp += 4; 131a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project ireg = STRUCT_VALUE_ADDRESS_WITH_ARG ? 1 : 0; 132a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project } 133a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project else 134a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project ireg = 0; 135a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 136a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project /* Set arguments for registers. */ 137a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project greg = ireg; 138a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project avn = ecif->cif->nargs; 139a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project p_argv = ecif->avalue; 140a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 141a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project for (i = 0, p_arg = ecif->cif->arg_types; i < avn; i++, p_arg++, p_argv++) 142a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project { 143a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project size_t z; 144a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 145a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project z = (*p_arg)->size; 146a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project if (z < sizeof(int)) 147a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project { 148a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project if (greg++ >= NGREGARG) 149a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project continue; 150a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 151a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project z = sizeof(int); 152a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project switch ((*p_arg)->type) 153a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project { 154a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project case FFI_TYPE_SINT8: 155a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project *(signed int *) argp = (signed int)*(SINT8 *)(* p_argv); 156a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project break; 157a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 158a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project case FFI_TYPE_UINT8: 159a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project *(unsigned int *) argp = (unsigned int)*(UINT8 *)(* p_argv); 160a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project break; 161a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 162a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project case FFI_TYPE_SINT16: 163a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project *(signed int *) argp = (signed int)*(SINT16 *)(* p_argv); 164a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project break; 165a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 166a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project case FFI_TYPE_UINT16: 167a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project *(unsigned int *) argp = (unsigned int)*(UINT16 *)(* p_argv); 168a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project break; 169a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 170a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project case FFI_TYPE_STRUCT: 171a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project *(unsigned int *) argp = (unsigned int)*(UINT32 *)(* p_argv); 172a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project break; 173a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 174a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project default: 175a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project FFI_ASSERT(0); 176a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project } 177a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project argp += z; 178a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project } 179a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project else if (z == sizeof(int)) 180a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project { 181a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project#if defined(__SH4__) 182a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project if ((*p_arg)->type == FFI_TYPE_FLOAT) 183a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project { 184a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project if (freg++ >= NFREGARG) 185a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project continue; 186a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project } 187a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project else 188a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project#endif 189a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project { 190a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project if (greg++ >= NGREGARG) 191a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project continue; 192a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project } 193a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project *(unsigned int *) argp = (unsigned int)*(UINT32 *)(* p_argv); 194a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project argp += z; 195a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project } 196a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project#if defined(__SH4__) 197a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project else if ((*p_arg)->type == FFI_TYPE_DOUBLE) 198a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project { 199a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project if (freg + 1 >= NFREGARG) 200a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project continue; 201a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project freg = (freg + 1) & ~1; 202a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project freg += 2; 203a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project memcpy (argp, *p_argv, z); 204a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project argp += z; 205a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project } 206a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project#endif 207a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project else 208a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project { 209a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project int n = (z + sizeof (int) - 1) / sizeof (int); 210a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project#if defined(__SH4__) 211a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project if (greg + n - 1 >= NGREGARG) 212a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project continue; 213a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project#else 214a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project if (greg >= NGREGARG) 215a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project continue; 216a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project#endif 217a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project greg += n; 218a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project memcpy (argp, *p_argv, z); 219a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project argp += n * sizeof (int); 220a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project } 221a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project } 222a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 223a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project /* Set arguments on stack. */ 224a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project greg = ireg; 225a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project#if defined(__SH4__) 226a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project freg = 0; 227a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project#endif 228a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project p_argv = ecif->avalue; 229a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 230a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project for (i = 0, p_arg = ecif->cif->arg_types; i < avn; i++, p_arg++, p_argv++) 231a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project { 232a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project size_t z; 233a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 234a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project z = (*p_arg)->size; 235a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project if (z < sizeof(int)) 236a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project { 237a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project if (greg++ < NGREGARG) 238a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project continue; 239a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 240a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project z = sizeof(int); 241a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project switch ((*p_arg)->type) 242a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project { 243a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project case FFI_TYPE_SINT8: 244a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project *(signed int *) argp = (signed int)*(SINT8 *)(* p_argv); 245a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project break; 246a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 247a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project case FFI_TYPE_UINT8: 248a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project *(unsigned int *) argp = (unsigned int)*(UINT8 *)(* p_argv); 249a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project break; 250a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 251a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project case FFI_TYPE_SINT16: 252a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project *(signed int *) argp = (signed int)*(SINT16 *)(* p_argv); 253a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project break; 254a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 255a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project case FFI_TYPE_UINT16: 256a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project *(unsigned int *) argp = (unsigned int)*(UINT16 *)(* p_argv); 257a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project break; 258a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 259a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project case FFI_TYPE_STRUCT: 260a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project *(unsigned int *) argp = (unsigned int)*(UINT32 *)(* p_argv); 261a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project break; 262a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 263a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project default: 264a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project FFI_ASSERT(0); 265a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project } 266a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project argp += z; 267a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project } 268a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project else if (z == sizeof(int)) 269a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project { 270a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project#if defined(__SH4__) 271a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project if ((*p_arg)->type == FFI_TYPE_FLOAT) 272a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project { 273a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project if (freg++ < NFREGARG) 274a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project continue; 275a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project } 276a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project else 277a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project#endif 278a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project { 279a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project if (greg++ < NGREGARG) 280a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project continue; 281a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project } 282a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project *(unsigned int *) argp = (unsigned int)*(UINT32 *)(* p_argv); 283a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project argp += z; 284a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project } 285a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project#if defined(__SH4__) 286a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project else if ((*p_arg)->type == FFI_TYPE_DOUBLE) 287a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project { 288a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project if (freg + 1 < NFREGARG) 289a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project { 290a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project freg = (freg + 1) & ~1; 291a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project freg += 2; 292a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project continue; 293a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project } 294a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project memcpy (argp, *p_argv, z); 295a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project argp += z; 296a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project } 297a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project#endif 298a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project else 299a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project { 300a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project int n = (z + sizeof (int) - 1) / sizeof (int); 301a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project if (greg + n - 1 < NGREGARG) 302a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project { 303a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project greg += n; 304a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project continue; 305a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project } 306a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project#if (! defined(__SH4__)) 307a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project else if (greg < NGREGARG) 308a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project { 309a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project greg = NGREGARG; 310a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project continue; 311a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project } 312a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project#endif 313a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project memcpy (argp, *p_argv, z); 314a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project argp += n * sizeof (int); 315a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project } 316a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project } 317a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 318a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project return; 319a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project} 320a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 321a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project/* Perform machine dependent cif processing */ 322a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Projectffi_status ffi_prep_cif_machdep(ffi_cif *cif) 323a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project{ 324a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project int i, j; 325a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project int size, type; 326a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project int n, m; 327a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project int greg; 328a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project#if defined(__SH4__) 329a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project int freg = 0; 330a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project#endif 331a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 332a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project cif->flags = 0; 333a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 334a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project greg = ((return_type (cif->rtype) == FFI_TYPE_STRUCT) && 335a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project STRUCT_VALUE_ADDRESS_WITH_ARG) ? 1 : 0; 336a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 337a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project#if defined(__SH4__) 338a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project for (i = j = 0; i < cif->nargs && j < 12; i++) 339a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project { 340a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project type = (cif->arg_types)[i]->type; 341a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project switch (type) 342a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project { 343a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project case FFI_TYPE_FLOAT: 344a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project if (freg >= NFREGARG) 345a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project continue; 346a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project freg++; 347a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project cif->flags += ((cif->arg_types)[i]->type) << (2 * j); 348a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project j++; 349a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project break; 350a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 351a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project case FFI_TYPE_DOUBLE: 352a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project if ((freg + 1) >= NFREGARG) 353a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project continue; 354a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project freg = (freg + 1) & ~1; 355a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project freg += 2; 356a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project cif->flags += ((cif->arg_types)[i]->type) << (2 * j); 357a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project j++; 358a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project break; 359a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 360a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project default: 361a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project size = (cif->arg_types)[i]->size; 362a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project n = (size + sizeof (int) - 1) / sizeof (int); 363a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project if (greg + n - 1 >= NGREGARG) 364a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project continue; 365a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project greg += n; 366a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project for (m = 0; m < n; m++) 367a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project cif->flags += FFI_TYPE_INT << (2 * j++); 368a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project break; 369a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project } 370a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project } 371a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project#else 372a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project for (i = j = 0; i < cif->nargs && j < 4; i++) 373a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project { 374a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project size = (cif->arg_types)[i]->size; 375a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project n = (size + sizeof (int) - 1) / sizeof (int); 376a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project if (greg >= NGREGARG) 377a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project continue; 378a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project else if (greg + n - 1 >= NGREGARG) 379a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project n = NGREGARG - greg; 380a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project greg += n; 381a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project for (m = 0; m < n; m++) 382a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project cif->flags += FFI_TYPE_INT << (2 * j++); 383a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project } 384a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project#endif 385a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 386a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project /* Set the return type flag */ 387a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project switch (cif->rtype->type) 388a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project { 389a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project case FFI_TYPE_STRUCT: 390a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project cif->flags += (unsigned) (return_type (cif->rtype)) << 24; 391a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project break; 392a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 393a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project case FFI_TYPE_VOID: 394a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project case FFI_TYPE_FLOAT: 395a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project case FFI_TYPE_DOUBLE: 396a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project case FFI_TYPE_SINT64: 397a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project case FFI_TYPE_UINT64: 398a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project cif->flags += (unsigned) cif->rtype->type << 24; 399a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project break; 400a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 401a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project default: 402a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project cif->flags += FFI_TYPE_INT << 24; 403a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project break; 404a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project } 405a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 406a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project return FFI_OK; 407a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project} 408a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 409a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Projectextern void ffi_call_SYSV(void (*)(char *, extended_cif *), extended_cif *, 410a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project unsigned, unsigned, unsigned *, void (*fn)(void)); 411a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 412a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Projectvoid ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue) 413a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project{ 414a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project extended_cif ecif; 415a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project UINT64 trvalue; 416a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 417a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project ecif.cif = cif; 418a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project ecif.avalue = avalue; 419a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 420a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project /* If the return value is a struct and we don't have a return */ 421a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project /* value address then we need to make one */ 422a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 423a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project if (cif->rtype->type == FFI_TYPE_STRUCT 424a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project && return_type (cif->rtype) != FFI_TYPE_STRUCT) 425a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project ecif.rvalue = &trvalue; 426a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project else if ((rvalue == NULL) && 427a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project (cif->rtype->type == FFI_TYPE_STRUCT)) 428a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project { 429a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project ecif.rvalue = alloca(cif->rtype->size); 430a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project } 431a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project else 432a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project ecif.rvalue = rvalue; 433a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 434a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project switch (cif->abi) 435a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project { 436a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project case FFI_SYSV: 437a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project ffi_call_SYSV(ffi_prep_args, &ecif, cif->bytes, cif->flags, ecif.rvalue, 438a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project fn); 439a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project break; 440a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project default: 441a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project FFI_ASSERT(0); 442a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project break; 443a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project } 444a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 445a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project if (rvalue 446a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project && cif->rtype->type == FFI_TYPE_STRUCT 447a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project && return_type (cif->rtype) != FFI_TYPE_STRUCT) 448a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project memcpy (rvalue, &trvalue, cif->rtype->size); 449a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project} 450a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 451a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Projectextern void ffi_closure_SYSV (void); 452a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project#if defined(__SH4__) 453a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Projectextern void __ic_invalidate (void *line); 454a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project#endif 455a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 456a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Projectffi_status 457a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Projectffi_prep_closure_loc (ffi_closure* closure, 458a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project ffi_cif* cif, 459a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project void (*fun)(ffi_cif*, void*, void**, void*), 460a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project void *user_data, 461a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project void *codeloc) 462a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project{ 463a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project unsigned int *tramp; 464a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project unsigned int insn; 465a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 466a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project FFI_ASSERT (cif->abi == FFI_GCC_SYSV); 467a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 468a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project tramp = (unsigned int *) &closure->tramp[0]; 469a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project /* Set T bit if the function returns a struct pointed with R2. */ 470a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project insn = (return_type (cif->rtype) == FFI_TYPE_STRUCT 471a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project ? 0x0018 /* sett */ 472a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project : 0x0008 /* clrt */); 473a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 474a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project#ifdef __LITTLE_ENDIAN__ 475a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project tramp[0] = 0xd301d102; 476a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project tramp[1] = 0x0000412b | (insn << 16); 477a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project#else 478a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project tramp[0] = 0xd102d301; 479a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project tramp[1] = 0x412b0000 | insn; 480a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project#endif 481a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project *(void **) &tramp[2] = (void *)codeloc; /* ctx */ 482a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project *(void **) &tramp[3] = (void *)ffi_closure_SYSV; /* funaddr */ 483a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 484a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project closure->cif = cif; 485a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project closure->fun = fun; 486a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project closure->user_data = user_data; 487a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 488a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project#if defined(__SH4__) 489a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project /* Flush the icache. */ 490a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project __ic_invalidate(codeloc); 491a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project#endif 492a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 493a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project return FFI_OK; 494a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project} 495a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 496a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project/* Basically the trampoline invokes ffi_closure_SYSV, and on 497a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project * entry, r3 holds the address of the closure. 498a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project * After storing the registers that could possibly contain 499a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project * parameters to be passed into the stack frame and setting 500a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project * up space for a return value, ffi_closure_SYSV invokes the 501a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project * following helper function to do most of the work. 502a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project */ 503a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 504a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project#ifdef __LITTLE_ENDIAN__ 505a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project#define OFS_INT8 0 506a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project#define OFS_INT16 0 507a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project#else 508a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project#define OFS_INT8 3 509a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project#define OFS_INT16 2 510a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project#endif 511a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 512a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Projectint 513a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Projectffi_closure_helper_SYSV (ffi_closure *closure, void *rvalue, 514a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project unsigned long *pgr, unsigned long *pfr, 515a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project unsigned long *pst) 516a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project{ 517a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project void **avalue; 518a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project ffi_type **p_arg; 519a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project int i, avn; 520a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project int ireg, greg = 0; 521a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project#if defined(__SH4__) 522a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project int freg = 0; 523a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project#endif 524a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project ffi_cif *cif; 525a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 526a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project cif = closure->cif; 527a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project avalue = alloca(cif->nargs * sizeof(void *)); 528a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 529a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project /* Copy the caller's structure return value address so that the closure 530a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project returns the data directly to the caller. */ 531a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project if (cif->rtype->type == FFI_TYPE_STRUCT && STRUCT_VALUE_ADDRESS_WITH_ARG) 532a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project { 533a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project rvalue = (void *) *pgr++; 534a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project ireg = 1; 535a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project } 536a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project else 537a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project ireg = 0; 538a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 539a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project cif = closure->cif; 540a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project greg = ireg; 541a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project avn = cif->nargs; 542a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 543a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project /* Grab the addresses of the arguments from the stack frame. */ 544a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project for (i = 0, p_arg = cif->arg_types; i < avn; i++, p_arg++) 545a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project { 546a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project size_t z; 547a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 548a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project z = (*p_arg)->size; 549a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project if (z < sizeof(int)) 550a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project { 551a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project if (greg++ >= NGREGARG) 552a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project continue; 553a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 554a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project z = sizeof(int); 555a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project switch ((*p_arg)->type) 556a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project { 557a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project case FFI_TYPE_SINT8: 558a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project case FFI_TYPE_UINT8: 559a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project avalue[i] = (((char *)pgr) + OFS_INT8); 560a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project break; 561a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 562a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project case FFI_TYPE_SINT16: 563a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project case FFI_TYPE_UINT16: 564a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project avalue[i] = (((char *)pgr) + OFS_INT16); 565a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project break; 566a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 567a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project case FFI_TYPE_STRUCT: 568a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project avalue[i] = pgr; 569a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project break; 570a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 571a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project default: 572a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project FFI_ASSERT(0); 573a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project } 574a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project pgr++; 575a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project } 576a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project else if (z == sizeof(int)) 577a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project { 578a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project#if defined(__SH4__) 579a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project if ((*p_arg)->type == FFI_TYPE_FLOAT) 580a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project { 581a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project if (freg++ >= NFREGARG) 582a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project continue; 583a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project avalue[i] = pfr; 584a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project pfr++; 585a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project } 586a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project else 587a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project#endif 588a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project { 589a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project if (greg++ >= NGREGARG) 590a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project continue; 591a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project avalue[i] = pgr; 592a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project pgr++; 593a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project } 594a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project } 595a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project#if defined(__SH4__) 596a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project else if ((*p_arg)->type == FFI_TYPE_DOUBLE) 597a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project { 598a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project if (freg + 1 >= NFREGARG) 599a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project continue; 600a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project if (freg & 1) 601a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project pfr++; 602a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project freg = (freg + 1) & ~1; 603a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project freg += 2; 604a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project avalue[i] = pfr; 605a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project pfr += 2; 606a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project } 607a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project#endif 608a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project else 609a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project { 610a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project int n = (z + sizeof (int) - 1) / sizeof (int); 611a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project#if defined(__SH4__) 612a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project if (greg + n - 1 >= NGREGARG) 613a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project continue; 614a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project#else 615a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project if (greg >= NGREGARG) 616a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project continue; 617a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project#endif 618a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project greg += n; 619a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project avalue[i] = pgr; 620a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project pgr += n; 621a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project } 622a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project } 623a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 624a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project greg = ireg; 625a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project#if defined(__SH4__) 626a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project freg = 0; 627a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project#endif 628a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 629a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project for (i = 0, p_arg = cif->arg_types; i < avn; i++, p_arg++) 630a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project { 631a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project size_t z; 632a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 633a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project z = (*p_arg)->size; 634a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project if (z < sizeof(int)) 635a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project { 636a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project if (greg++ < NGREGARG) 637a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project continue; 638a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 639a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project z = sizeof(int); 640a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project switch ((*p_arg)->type) 641a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project { 642a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project case FFI_TYPE_SINT8: 643a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project case FFI_TYPE_UINT8: 644a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project avalue[i] = (((char *)pst) + OFS_INT8); 645a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project break; 646a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 647a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project case FFI_TYPE_SINT16: 648a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project case FFI_TYPE_UINT16: 649a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project avalue[i] = (((char *)pst) + OFS_INT16); 650a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project break; 651a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 652a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project case FFI_TYPE_STRUCT: 653a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project avalue[i] = pst; 654a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project break; 655a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 656a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project default: 657a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project FFI_ASSERT(0); 658a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project } 659a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project pst++; 660a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project } 661a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project else if (z == sizeof(int)) 662a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project { 663a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project#if defined(__SH4__) 664a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project if ((*p_arg)->type == FFI_TYPE_FLOAT) 665a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project { 666a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project if (freg++ < NFREGARG) 667a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project continue; 668a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project } 669a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project else 670a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project#endif 671a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project { 672a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project if (greg++ < NGREGARG) 673a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project continue; 674a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project } 675a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project avalue[i] = pst; 676a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project pst++; 677a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project } 678a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project#if defined(__SH4__) 679a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project else if ((*p_arg)->type == FFI_TYPE_DOUBLE) 680a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project { 681a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project if (freg + 1 < NFREGARG) 682a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project { 683a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project freg = (freg + 1) & ~1; 684a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project freg += 2; 685a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project continue; 686a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project } 687a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project avalue[i] = pst; 688a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project pst += 2; 689a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project } 690a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project#endif 691a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project else 692a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project { 693a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project int n = (z + sizeof (int) - 1) / sizeof (int); 694a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project if (greg + n - 1 < NGREGARG) 695a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project { 696a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project greg += n; 697a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project continue; 698a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project } 699a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project#if (! defined(__SH4__)) 700a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project else if (greg < NGREGARG) 701a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project { 702a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project greg += n; 703a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project pst += greg - NGREGARG; 704a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project continue; 705a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project } 706a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project#endif 707a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project avalue[i] = pst; 708a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project pst += n; 709a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project } 710a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project } 711a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 712a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project (closure->fun) (cif, rvalue, avalue, closure->user_data); 713a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 714a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project /* Tell ffi_closure_SYSV how to perform return type promotions. */ 715a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project return return_type (cif->rtype); 716a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project} 717