diff --git a/Modules/_ctypes/libffi_osx/powerpc/ppc-ffi_darwin.c b/Modules/_ctypes/libffi_osx/powerpc/ppc-ffi_darwin.c --- a/Modules/_ctypes/libffi_osx/powerpc/ppc-ffi_darwin.c +++ b/Modules/_ctypes/libffi_osx/powerpc/ppc-ffi_darwin.c @@ -37,19 +37,10 @@ #include #include -#if 0 #if defined(POWERPC_DARWIN) #include // for sys_icache_invalidate() #endif -#else - -#pragma weak sys_icache_invalidate -extern void sys_icache_invalidate(void *start, size_t len); - -#endif - - extern void ffi_closure_ASM(void); // The layout of a function descriptor. A C function pointer really @@ -1773,4 +1764,4 @@ } #endif /* defined(__ppc64__) */ -#endif /* __ppc__ || __ppc64__ */ +#endif /* __ppc__ || __ppc64__ */ \ No newline at end of file diff --git a/Modules/_ctypes/libffi_osx/x86/darwin64.S b/Modules/_ctypes/libffi_osx/x86/darwin64.S --- a/Modules/_ctypes/libffi_osx/x86/darwin64.S +++ b/Modules/_ctypes/libffi_osx/x86/darwin64.S @@ -45,6 +45,7 @@ _ffi_call_unix64: LUW0: movq (%rsp), %r10 /* Load return address. */ + movq %rdi, %r12 /* Save a copy of the register area. */ leaq (%rdi, %rsi), %rax /* Find local stack base. */ movq %rdx, (%rax) /* Save flags. */ movq %rcx, 8(%rax) /* Save raddr. */ @@ -52,7 +53,8 @@ movq %r10, 24(%rax) /* Relocate return address. */ movq %rax, %rbp /* Finalize local stack frame. */ LUW1: - movq %rdi, %r10 /* Save a copy of the register area. */ + /* movq %rdi, %r10 // Save a copy of the register area. */ + movq %r12, %r10 movq %r8, %r11 /* Save a copy of the target fn. */ movl %r9d, %eax /* Set number of SSE registers. */ @@ -255,7 +257,7 @@ ret .align 3 Lld_int8: - movzbl -24(%rsp), %eax + movzbl -24(%rsp), %eax ret .align 3 Lld_int16: diff --git a/Modules/_ctypes/libffi_osx/x86/x86-darwin.S b/Modules/_ctypes/libffi_osx/x86/x86-darwin.S --- a/Modules/_ctypes/libffi_osx/x86/x86-darwin.S +++ b/Modules/_ctypes/libffi_osx/x86/x86-darwin.S @@ -198,8 +198,12 @@ je Lcls_retldouble cmpl $FFI_TYPE_SINT64, %eax je Lcls_retllong + cmpl $FFI_TYPE_UINT8, %eax + je Lcls_retstruct1 cmpl $FFI_TYPE_SINT8, %eax je Lcls_retstruct1 + cmpl $FFI_TYPE_UINT16, %eax + je Lcls_retstruct2 cmpl $FFI_TYPE_SINT16, %eax je Lcls_retstruct2 cmpl $FFI_TYPE_STRUCT, %eax diff --git a/Modules/_ctypes/libffi_osx/x86/x86-ffi64.c b/Modules/_ctypes/libffi_osx/x86/x86-ffi64.c --- a/Modules/_ctypes/libffi_osx/x86/x86-ffi64.c +++ b/Modules/_ctypes/libffi_osx/x86/x86-ffi64.c @@ -152,12 +152,42 @@ case FFI_TYPE_UINT64: case FFI_TYPE_SINT64: case FFI_TYPE_POINTER: +#if 0 if (byte_offset + type->size <= 4) classes[0] = X86_64_INTEGERSI_CLASS; else classes[0] = X86_64_INTEGER_CLASS; return 1; +#else + { + int size = byte_offset + type->size; + + if (size <= 4) + { + classes[0] = X86_64_INTEGERSI_CLASS; + return 1; + } + else if (size <= 8) + { + classes[0] = X86_64_INTEGER_CLASS; + return 1; + } + else if (size <= 12) + { + classes[0] = X86_64_INTEGER_CLASS; + classes[1] = X86_64_INTEGERSI_CLASS; + return 2; + } + else if (size <= 16) + { + classes[0] = classes[1] = X86_64_INTEGERSI_CLASS; + return 2; + } + else + FFI_ASSERT (0); + } +#endif case FFI_TYPE_FLOAT: if (byte_offset == 0) @@ -213,6 +243,21 @@ byte_offset += (*ptr)->size; } + if (words > 2) + { + /* When size > 16 bytes, if the first one isn't + X86_64_SSE_CLASS or any other ones aren't + X86_64_SSEUP_CLASS, everything should be passed in + memory. */ + if (classes[0] != X86_64_SSE_CLASS) + return 0; + + for (i = 1; i < words; i++) + if (classes[i] != X86_64_SSEUP_CLASS) + return 0; + } + + /* Final merger cleanup. */ for (i = 0; i < words; i++) { @@ -224,13 +269,20 @@ /* The X86_64_SSEUP_CLASS should be always preceded by X86_64_SSE_CLASS. */ if (classes[i] == X86_64_SSEUP_CLASS - && (i == 0 || classes[i - 1] != X86_64_SSE_CLASS)) + && classes[i - 1] != X86_64_SSE_CLASS + && classes[i - 1] != X86_64_SSEUP_CLASS) + { + FFI_ASSERT(i != 0); classes[i] = X86_64_SSE_CLASS; + } /* X86_64_X87UP_CLASS should be preceded by X86_64_X87_CLASS. */ if (classes[i] == X86_64_X87UP_CLASS - && (i == 0 || classes[i - 1] != X86_64_X87_CLASS)) + && classes[i - 1] != X86_64_X87_CLASS) + { + FFI_ASSERT(i != 0); classes[i] = X86_64_SSE_CLASS; + } } return words; @@ -369,6 +421,7 @@ cif->flags = flags; cif->bytes = bytes; + cif->bytes = ALIGN(bytes,8); return FFI_OK; } @@ -449,7 +502,61 @@ case X86_64_INTEGER_CLASS: case X86_64_INTEGERSI_CLASS: reg_args->gpr[gprcount] = 0; - memcpy (®_args->gpr[gprcount], a, size < 8 ? size : 8); + switch (arg_types[i]->type) { + case FFI_TYPE_SINT8: + { + int8_t shortval = *(int8_t*)a; + int64_t actval = (int64_t)shortval; + reg_args->gpr[gprcount] = actval; + /*memcpy (®_args->gpr[gprcount], &actval, 8);*/ + break; + } + + case FFI_TYPE_SINT16: + { + int16_t shortval = *(int16_t*)a; + int64_t actval = (int64_t)shortval; + memcpy (®_args->gpr[gprcount], &actval, 8); + break; + } + + case FFI_TYPE_SINT32: + { + int32_t shortval = *(int32_t*)a; + int64_t actval = (int64_t)shortval; + memcpy (®_args->gpr[gprcount], &actval, 8); + break; + } + + case FFI_TYPE_UINT8: + { + u_int8_t shortval = *(u_int8_t*)a; + u_int64_t actval = (u_int64_t)shortval; + /*memcpy (®_args->gpr[gprcount], &actval, 8);*/ + reg_args->gpr[gprcount] = actval; + break; + } + + case FFI_TYPE_UINT16: + { + u_int16_t shortval = *(u_int16_t*)a; + u_int64_t actval = (u_int64_t)shortval; + memcpy (®_args->gpr[gprcount], &actval, 8); + break; + } + + case FFI_TYPE_UINT32: + { + u_int32_t shortval = *(u_int32_t*)a; + u_int64_t actval = (u_int64_t)shortval; + memcpy (®_args->gpr[gprcount], &actval, 8); + break; + } + + default: + //memcpy (®_args->gpr[gprcount], a, size < 8 ? size : 8); + reg_args->gpr[gprcount] = *(int64_t*)a; + } gprcount++; break; @@ -505,12 +612,15 @@ return FFI_OK; } +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wmissing-prototypes" int ffi_closure_unix64_inner( ffi_closure* closure, void* rvalue, RegisterArgs* reg_args, char* argp) +#pragma clang diagnostic pop { ffi_cif* cif = closure->cif; void** avalue = alloca(cif->nargs * sizeof(void *)); @@ -621,4 +731,4 @@ return ret; } -#endif /* __x86_64__ */ \ No newline at end of file +#endif /* __x86_64__ */ diff --git a/Modules/_ctypes/libffi_osx/x86/x86-ffi_darwin.c b/Modules/_ctypes/libffi_osx/x86/x86-ffi_darwin.c --- a/Modules/_ctypes/libffi_osx/x86/x86-ffi_darwin.c +++ b/Modules/_ctypes/libffi_osx/x86/x86-ffi_darwin.c @@ -35,6 +35,8 @@ /* ffi_prep_args is called by the assembly routine once stack space has been allocated for the function's arguments */ +void ffi_prep_args(char *stack, extended_cif *ecif); + void ffi_prep_args(char *stack, extended_cif *ecif) { register unsigned int i; @@ -433,4 +435,4 @@ } #endif -#endif // __i386__ \ No newline at end of file +#endif // __i386__