diff options
Diffstat (limited to 'Modules/_ctypes/libffi/src/microblaze')
-rw-r--r-- | Modules/_ctypes/libffi/src/microblaze/ffi.c | 321 | ||||
-rw-r--r-- | Modules/_ctypes/libffi/src/microblaze/ffitarget.h | 53 | ||||
-rw-r--r-- | Modules/_ctypes/libffi/src/microblaze/sysv.S | 302 |
3 files changed, 0 insertions, 676 deletions
diff --git a/Modules/_ctypes/libffi/src/microblaze/ffi.c b/Modules/_ctypes/libffi/src/microblaze/ffi.c deleted file mode 100644 index ea962ea483..0000000000 --- a/Modules/_ctypes/libffi/src/microblaze/ffi.c +++ /dev/null @@ -1,321 +0,0 @@ -/* ----------------------------------------------------------------------- - ffi.c - Copyright (c) 2012, 2013 Xilinx, Inc - - MicroBlaze Foreign Function Interface - - Permission is hereby granted, free of charge, to any person obtaining - a copy of this software and associated documentation files (the - ``Software''), to deal in the Software without restriction, including - without limitation the rights to use, copy, modify, merge, publish, - distribute, sublicense, and/or sell copies of the Software, and to - permit persons to whom the Software is furnished to do so, subject to - the following conditions: - - The above copyright notice and this permission notice shall be included - in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, - EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - DEALINGS IN THE SOFTWARE. - ----------------------------------------------------------------------- */ - -#include <ffi.h> -#include <ffi_common.h> - -extern void ffi_call_SYSV(void (*)(void*, extended_cif*), extended_cif*, - unsigned int, unsigned int, unsigned int*, void (*fn)(void), - unsigned int, unsigned int); - -extern void ffi_closure_SYSV(void); - -#define WORD_SIZE sizeof(unsigned int) -#define ARGS_REGISTER_SIZE (WORD_SIZE * 6) -#define WORD_ALIGN(x) ALIGN(x, WORD_SIZE) - -/* ffi_prep_args is called by the assembly routine once stack space - has been allocated for the function's arguments */ -void ffi_prep_args(void* stack, extended_cif* ecif) -{ - unsigned int i; - ffi_type** p_arg; - void** p_argv; - void* stack_args_p = stack; - - p_argv = ecif->avalue; - - if (ecif == NULL || ecif->cif == NULL) { - return; /* no description to prepare */ - } - - if ((ecif->cif->rtype != NULL) && - (ecif->cif->rtype->type == FFI_TYPE_STRUCT)) - { - /* if return type is a struct which is referenced on the stack/reg5, - * by a pointer. Stored the return value pointer in r5. - */ - char* addr = stack_args_p; - memcpy(addr, &(ecif->rvalue), WORD_SIZE); - stack_args_p += WORD_SIZE; - } - - if (ecif->avalue == NULL) { - return; /* no arguments to prepare */ - } - - for (i = 0, p_arg = ecif->cif->arg_types; i < ecif->cif->nargs; - i++, p_arg++) - { - size_t size = (*p_arg)->size; - int type = (*p_arg)->type; - void* value = p_argv[i]; - char* addr = stack_args_p; - int aligned_size = WORD_ALIGN(size); - - /* force word alignment on the stack */ - stack_args_p += aligned_size; - - switch (type) - { - case FFI_TYPE_UINT8: - *(unsigned int *)addr = (unsigned int)*(UINT8*)(value); - break; - case FFI_TYPE_SINT8: - *(signed int *)addr = (signed int)*(SINT8*)(value); - break; - case FFI_TYPE_UINT16: - *(unsigned int *)addr = (unsigned int)*(UINT16*)(value); - break; - case FFI_TYPE_SINT16: - *(signed int *)addr = (signed int)*(SINT16*)(value); - break; - case FFI_TYPE_STRUCT: -#if __BIG_ENDIAN__ - /* - * MicroBlaze toolchain appears to emit: - * bsrli r5, r5, 8 (caller) - * ... - * <branch to callee> - * ... - * bslli r5, r5, 8 (callee) - * - * For structs like "struct a { uint8_t a[3]; };", when passed - * by value. - * - * Structs like "struct b { uint16_t a; };" are also expected - * to be packed strangely in registers. - * - * This appears to be because the microblaze toolchain expects - * "struct b == uint16_t", which is only any issue for big - * endian. - * - * The following is a work around for big-endian only, for the - * above mentioned case, it will re-align the contents of a - * <= 3-byte struct value. - */ - if (size < WORD_SIZE) - { - memcpy (addr + (WORD_SIZE - size), value, size); - break; - } -#endif - case FFI_TYPE_SINT32: - case FFI_TYPE_UINT32: - case FFI_TYPE_FLOAT: - case FFI_TYPE_SINT64: - case FFI_TYPE_UINT64: - case FFI_TYPE_DOUBLE: - default: - memcpy(addr, value, aligned_size); - } - } -} - -ffi_status ffi_prep_cif_machdep(ffi_cif* cif) -{ - /* check ABI */ - switch (cif->abi) - { - case FFI_SYSV: - break; - default: - return FFI_BAD_ABI; - } - return FFI_OK; -} - -void ffi_call(ffi_cif* cif, void (*fn)(void), void* rvalue, void** avalue) -{ - extended_cif ecif; - ecif.cif = cif; - ecif.avalue = avalue; - - /* If the return value is a struct and we don't have a return */ - /* value address then we need to make one */ - if ((rvalue == NULL) && (cif->rtype->type == FFI_TYPE_STRUCT)) { - ecif.rvalue = alloca(cif->rtype->size); - } else { - ecif.rvalue = rvalue; - } - - switch (cif->abi) - { - case FFI_SYSV: - ffi_call_SYSV(ffi_prep_args, &ecif, cif->bytes, cif->flags, - ecif.rvalue, fn, cif->rtype->type, cif->rtype->size); - break; - default: - FFI_ASSERT(0); - break; - } -} - -void ffi_closure_call_SYSV(void* register_args, void* stack_args, - ffi_closure* closure, void* rvalue, - unsigned int* rtype, unsigned int* rsize) -{ - /* prepare arguments for closure call */ - ffi_cif* cif = closure->cif; - ffi_type** arg_types = cif->arg_types; - - /* re-allocate data for the args. This needs to be done in order to keep - * multi-word objects (e.g. structs) in contiguous memory. Callers are not - * required to store the value of args in the lower 6 words in the stack - * (although they are allocated in the stack). - */ - char* stackclone = alloca(cif->bytes); - void** avalue = alloca(cif->nargs * sizeof(void*)); - void* struct_rvalue = NULL; - char* ptr = stackclone; - int i; - - /* copy registers into stack clone */ - int registers_used = cif->bytes; - if (registers_used > ARGS_REGISTER_SIZE) { - registers_used = ARGS_REGISTER_SIZE; - } - memcpy(stackclone, register_args, registers_used); - - /* copy stack allocated args into stack clone */ - if (cif->bytes > ARGS_REGISTER_SIZE) { - int stack_used = cif->bytes - ARGS_REGISTER_SIZE; - memcpy(stackclone + ARGS_REGISTER_SIZE, stack_args, stack_used); - } - - /* preserve struct type return pointer passing */ - if ((cif->rtype != NULL) && (cif->rtype->type == FFI_TYPE_STRUCT)) { - struct_rvalue = *((void**)ptr); - ptr += WORD_SIZE; - } - - /* populate arg pointer list */ - for (i = 0; i < cif->nargs; i++) - { - switch (arg_types[i]->type) - { - case FFI_TYPE_SINT8: - case FFI_TYPE_UINT8: -#ifdef __BIG_ENDIAN__ - avalue[i] = ptr + 3; -#else - avalue[i] = ptr; -#endif - break; - case FFI_TYPE_SINT16: - case FFI_TYPE_UINT16: -#ifdef __BIG_ENDIAN__ - avalue[i] = ptr + 2; -#else - avalue[i] = ptr; -#endif - break; - case FFI_TYPE_STRUCT: -#if __BIG_ENDIAN__ - /* - * Work around strange ABI behaviour. - * (see info in ffi_prep_args) - */ - if (arg_types[i]->size < WORD_SIZE) - { - memcpy (ptr, ptr + (WORD_SIZE - arg_types[i]->size), arg_types[i]->size); - } -#endif - avalue[i] = (void*)ptr; - break; - case FFI_TYPE_UINT64: - case FFI_TYPE_SINT64: - case FFI_TYPE_DOUBLE: - avalue[i] = ptr; - break; - case FFI_TYPE_SINT32: - case FFI_TYPE_UINT32: - case FFI_TYPE_FLOAT: - default: - /* default 4-byte argument */ - avalue[i] = ptr; - break; - } - ptr += WORD_ALIGN(arg_types[i]->size); - } - - /* set the return type info passed back to the wrapper */ - *rsize = cif->rtype->size; - *rtype = cif->rtype->type; - if (struct_rvalue != NULL) { - closure->fun(cif, struct_rvalue, avalue, closure->user_data); - /* copy struct return pointer value into function return value */ - *((void**)rvalue) = struct_rvalue; - } else { - closure->fun(cif, rvalue, avalue, closure->user_data); - } -} - -ffi_status ffi_prep_closure_loc( - ffi_closure* closure, ffi_cif* cif, - void (*fun)(ffi_cif*, void*, void**, void*), - void* user_data, void* codeloc) -{ - unsigned long* tramp = (unsigned long*)&(closure->tramp[0]); - unsigned long cls = (unsigned long)codeloc; - unsigned long fn = 0; - unsigned long fn_closure_call_sysv = (unsigned long)ffi_closure_call_SYSV; - - closure->cif = cif; - closure->fun = fun; - closure->user_data = user_data; - - switch (cif->abi) - { - case FFI_SYSV: - fn = (unsigned long)ffi_closure_SYSV; - - /* load r11 (temp) with fn */ - /* imm fn(upper) */ - tramp[0] = 0xb0000000 | ((fn >> 16) & 0xffff); - /* addik r11, r0, fn(lower) */ - tramp[1] = 0x31600000 | (fn & 0xffff); - - /* load r12 (temp) with cls */ - /* imm cls(upper) */ - tramp[2] = 0xb0000000 | ((cls >> 16) & 0xffff); - /* addik r12, r0, cls(lower) */ - tramp[3] = 0x31800000 | (cls & 0xffff); - - /* load r3 (temp) with ffi_closure_call_SYSV */ - /* imm fn_closure_call_sysv(upper) */ - tramp[4] = 0xb0000000 | ((fn_closure_call_sysv >> 16) & 0xffff); - /* addik r3, r0, fn_closure_call_sysv(lower) */ - tramp[5] = 0x30600000 | (fn_closure_call_sysv & 0xffff); - /* branch/jump to address stored in r11 (fn) */ - tramp[6] = 0x98085800; /* bra r11 */ - - break; - default: - return FFI_BAD_ABI; - } - return FFI_OK; -} diff --git a/Modules/_ctypes/libffi/src/microblaze/ffitarget.h b/Modules/_ctypes/libffi/src/microblaze/ffitarget.h deleted file mode 100644 index c6fa5a4115..0000000000 --- a/Modules/_ctypes/libffi/src/microblaze/ffitarget.h +++ /dev/null @@ -1,53 +0,0 @@ -/* ----------------------------------------------------------------------- - ffitarget.h - Copyright (c) 2012, 2013 Xilinx, Inc - - Target configuration macros for MicroBlaze. - - Permission is hereby granted, free of charge, to any person obtaining - a copy of this software and associated documentation files (the - ``Software''), to deal in the Software without restriction, including - without limitation the rights to use, copy, modify, merge, publish, - distribute, sublicense, and/or sell copies of the Software, and to - permit persons to whom the Software is furnished to do so, subject to - the following conditions: - - The above copyright notice and this permission notice shall be included - in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, - EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - DEALINGS IN THE SOFTWARE. - ----------------------------------------------------------------------- */ - -#ifndef LIBFFI_TARGET_H -#define LIBFFI_TARGET_H - -#ifndef LIBFFI_H -#error "Please do not include ffitarget.h directly into your source. Use ffi.h instead." -#endif - -#ifndef LIBFFI_ASM -typedef unsigned long ffi_arg; -typedef signed long ffi_sarg; - -typedef enum ffi_abi { - FFI_FIRST_ABI = 0, - FFI_SYSV, - FFI_LAST_ABI, - FFI_DEFAULT_ABI = FFI_SYSV -} ffi_abi; -#endif - -/* Definitions for closures */ - -#define FFI_CLOSURES 1 -#define FFI_NATIVE_RAW_API 0 - -#define FFI_TRAMPOLINE_SIZE (4*8) - -#endif diff --git a/Modules/_ctypes/libffi/src/microblaze/sysv.S b/Modules/_ctypes/libffi/src/microblaze/sysv.S deleted file mode 100644 index ea43e9d545..0000000000 --- a/Modules/_ctypes/libffi/src/microblaze/sysv.S +++ /dev/null @@ -1,302 +0,0 @@ -/* ----------------------------------------------------------------------- - sysv.S - Copyright (c) 2012, 2013 Xilinx, Inc - - MicroBlaze Foreign Function Interface - - Permission is hereby granted, free of charge, to any person obtaining - a copy of this software and associated documentation files (the - ``Software''), to deal in the Software without restriction, including - without limitation the rights to use, copy, modify, merge, publish, - distribute, sublicense, and/or sell copies of the Software, and to - permit persons to whom the Software is furnished to do so, subject to - the following conditions: - - The above copyright notice and this permission notice shall be included - in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, - EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - DEALINGS IN THE SOFTWARE. - ----------------------------------------------------------------------- */ - -#define LIBFFI_ASM -#include <fficonfig.h> -#include <ffi.h> - - /* - * arg[0] (r5) = ffi_prep_args, - * arg[1] (r6) = &ecif, - * arg[2] (r7) = cif->bytes, - * arg[3] (r8) = cif->flags, - * arg[4] (r9) = ecif.rvalue, - * arg[5] (r10) = fn - * arg[6] (sp[0]) = cif->rtype->type - * arg[7] (sp[4]) = cif->rtype->size - */ - .text - .globl ffi_call_SYSV - .type ffi_call_SYSV, @function -ffi_call_SYSV: - /* push callee saves */ - addik r1, r1, -20 - swi r19, r1, 0 /* Frame Pointer */ - swi r20, r1, 4 /* PIC register */ - swi r21, r1, 8 /* PIC register */ - swi r22, r1, 12 /* save for locals */ - swi r23, r1, 16 /* save for locals */ - - /* save the r5-r10 registers in the stack */ - addik r1, r1, -24 /* increment sp to store 6x 32-bit words */ - swi r5, r1, 0 - swi r6, r1, 4 - swi r7, r1, 8 - swi r8, r1, 12 - swi r9, r1, 16 - swi r10, r1, 20 - - /* save function pointer */ - addik r3, r5, 0 /* copy ffi_prep_args into r3 */ - addik r22, r1, 0 /* save sp for unallocated args into r22 (callee-saved) */ - addik r23, r10, 0 /* save function address into r23 (callee-saved) */ - - /* prepare stack with allocation for n (bytes = r7) args */ - rsub r1, r7, r1 /* subtract bytes from sp */ - - /* prep args for ffi_prep_args call */ - addik r5, r1, 0 /* store stack pointer into arg[0] */ - /* r6 still holds ecif for arg[1] */ - - /* Call ffi_prep_args(stack, &ecif). */ - addik r1, r1, -4 - swi r15, r1, 0 /* store the link register in the frame */ - brald r15, r3 - nop /* branch has delay slot */ - lwi r15, r1, 0 - addik r1, r1, 4 /* restore the link register from the frame */ - /* returns calling stack pointer location */ - - /* prepare args for fn call, prep_args populates them onto the stack */ - lwi r5, r1, 0 /* arg[0] */ - lwi r6, r1, 4 /* arg[1] */ - lwi r7, r1, 8 /* arg[2] */ - lwi r8, r1, 12 /* arg[3] */ - lwi r9, r1, 16 /* arg[4] */ - lwi r10, r1, 20 /* arg[5] */ - - /* call (fn) (...). */ - addik r1, r1, -4 - swi r15, r1, 0 /* store the link register in the frame */ - brald r15, r23 - nop /* branch has delay slot */ - lwi r15, r1, 0 - addik r1, r1, 4 /* restore the link register from the frame */ - - /* Remove the space we pushed for the args. */ - addik r1, r22, 0 /* restore old SP */ - - /* restore this functions parameters */ - lwi r5, r1, 0 /* arg[0] */ - lwi r6, r1, 4 /* arg[1] */ - lwi r7, r1, 8 /* arg[2] */ - lwi r8, r1, 12 /* arg[3] */ - lwi r9, r1, 16 /* arg[4] */ - lwi r10, r1, 20 /* arg[5] */ - addik r1, r1, 24 /* decrement sp to de-allocate 6x 32-bit words */ - - /* If the return value pointer is NULL, assume no return value. */ - beqi r9, ffi_call_SYSV_end - - lwi r22, r1, 48 /* get return type (20 for locals + 28 for arg[6]) */ - lwi r23, r1, 52 /* get return size (20 for locals + 32 for arg[7]) */ - - /* Check if return type is actually a struct, do nothing */ - rsubi r11, r22, FFI_TYPE_STRUCT - beqi r11, ffi_call_SYSV_end - - /* Return 8bit */ - rsubi r11, r23, 1 - beqi r11, ffi_call_SYSV_store8 - - /* Return 16bit */ - rsubi r11, r23, 2 - beqi r11, ffi_call_SYSV_store16 - - /* Return 32bit */ - rsubi r11, r23, 4 - beqi r11, ffi_call_SYSV_store32 - - /* Return 64bit */ - rsubi r11, r23, 8 - beqi r11, ffi_call_SYSV_store64 - - /* Didn't match anything */ - bri ffi_call_SYSV_end - -ffi_call_SYSV_store64: - swi r3, r9, 0 /* store word r3 into return value */ - swi r4, r9, 4 /* store word r4 into return value */ - bri ffi_call_SYSV_end - -ffi_call_SYSV_store32: - swi r3, r9, 0 /* store word r3 into return value */ - bri ffi_call_SYSV_end - -ffi_call_SYSV_store16: -#ifdef __BIG_ENDIAN__ - shi r3, r9, 2 /* store half-word r3 into return value */ -#else - shi r3, r9, 0 /* store half-word r3 into return value */ -#endif - bri ffi_call_SYSV_end - -ffi_call_SYSV_store8: -#ifdef __BIG_ENDIAN__ - sbi r3, r9, 3 /* store byte r3 into return value */ -#else - sbi r3, r9, 0 /* store byte r3 into return value */ -#endif - bri ffi_call_SYSV_end - -ffi_call_SYSV_end: - /* callee restores */ - lwi r19, r1, 0 /* frame pointer */ - lwi r20, r1, 4 /* PIC register */ - lwi r21, r1, 8 /* PIC register */ - lwi r22, r1, 12 - lwi r23, r1, 16 - addik r1, r1, 20 - - /* return from sub-routine (with delay slot) */ - rtsd r15, 8 - nop - - .size ffi_call_SYSV, . - ffi_call_SYSV - -/* ------------------------------------------------------------------------- */ - - /* - * args passed into this function, are passed down to the callee. - * this function is the target of the closure trampoline, as such r12 is - * a pointer to the closure object. - */ - .text - .globl ffi_closure_SYSV - .type ffi_closure_SYSV, @function -ffi_closure_SYSV: - /* push callee saves */ - addik r11, r1, 28 /* save stack args start location (excluding regs/link) */ - addik r1, r1, -12 - swi r19, r1, 0 /* Frame Pointer */ - swi r20, r1, 4 /* PIC register */ - swi r21, r1, 8 /* PIC register */ - - /* store register args on stack */ - addik r1, r1, -24 - swi r5, r1, 0 - swi r6, r1, 4 - swi r7, r1, 8 - swi r8, r1, 12 - swi r9, r1, 16 - swi r10, r1, 20 - - /* setup args */ - addik r5, r1, 0 /* register_args */ - addik r6, r11, 0 /* stack_args */ - addik r7, r12, 0 /* closure object */ - addik r1, r1, -8 /* allocate return value */ - addik r8, r1, 0 /* void* rvalue */ - addik r1, r1, -8 /* allocate for return type/size values */ - addik r9, r1, 0 /* void* rtype */ - addik r10, r1, 4 /* void* rsize */ - - /* call the wrap_call function */ - addik r1, r1, -28 /* allocate args + link reg */ - swi r15, r1, 0 /* store the link register in the frame */ - brald r15, r3 - nop /* branch has delay slot */ - lwi r15, r1, 0 - addik r1, r1, 28 /* restore the link register from the frame */ - -ffi_closure_SYSV_prepare_return: - lwi r9, r1, 0 /* rtype */ - lwi r10, r1, 4 /* rsize */ - addik r1, r1, 8 /* de-allocate return info values */ - - /* Check if return type is actually a struct, store 4 bytes */ - rsubi r11, r9, FFI_TYPE_STRUCT - beqi r11, ffi_closure_SYSV_store32 - - /* Return 8bit */ - rsubi r11, r10, 1 - beqi r11, ffi_closure_SYSV_store8 - - /* Return 16bit */ - rsubi r11, r10, 2 - beqi r11, ffi_closure_SYSV_store16 - - /* Return 32bit */ - rsubi r11, r10, 4 - beqi r11, ffi_closure_SYSV_store32 - - /* Return 64bit */ - rsubi r11, r10, 8 - beqi r11, ffi_closure_SYSV_store64 - - /* Didn't match anything */ - bri ffi_closure_SYSV_end - -ffi_closure_SYSV_store64: - lwi r3, r1, 0 /* store word r3 into return value */ - lwi r4, r1, 4 /* store word r4 into return value */ - /* 64 bits == 2 words, no sign extend occurs */ - bri ffi_closure_SYSV_end - -ffi_closure_SYSV_store32: - lwi r3, r1, 0 /* store word r3 into return value */ - /* 32 bits == 1 word, no sign extend occurs */ - bri ffi_closure_SYSV_end - -ffi_closure_SYSV_store16: -#ifdef __BIG_ENDIAN__ - lhui r3, r1, 2 /* store half-word r3 into return value */ -#else - lhui r3, r1, 0 /* store half-word r3 into return value */ -#endif - rsubi r11, r9, FFI_TYPE_SINT16 - bnei r11, ffi_closure_SYSV_end - sext16 r3, r3 /* fix sign extend of sint8 */ - bri ffi_closure_SYSV_end - -ffi_closure_SYSV_store8: -#ifdef __BIG_ENDIAN__ - lbui r3, r1, 3 /* store byte r3 into return value */ -#else - lbui r3, r1, 0 /* store byte r3 into return value */ -#endif - rsubi r11, r9, FFI_TYPE_SINT8 - bnei r11, ffi_closure_SYSV_end - sext8 r3, r3 /* fix sign extend of sint8 */ - bri ffi_closure_SYSV_end - -ffi_closure_SYSV_end: - addik r1, r1, 8 /* de-allocate return value */ - - /* de-allocate stored args */ - addik r1, r1, 24 - - /* callee restores */ - lwi r19, r1, 0 /* frame pointer */ - lwi r20, r1, 4 /* PIC register */ - lwi r21, r1, 8 /* PIC register */ - addik r1, r1, 12 - - /* return from sub-routine (with delay slot) */ - rtsd r15, 8 - nop - - .size ffi_closure_SYSV, . - ffi_closure_SYSV |