mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 976648 - Backport of libffi powerpc64le-linux support. r=bsmedberg
This commit is contained in:
parent
aba64ccfe0
commit
9ef1683f17
12
js/src/ctypes/libffi/aclocal.m4
vendored
12
js/src/ctypes/libffi/aclocal.m4
vendored
@ -1282,7 +1282,7 @@ ia64-*-hpux*)
|
||||
rm -rf conftest*
|
||||
;;
|
||||
|
||||
x86_64-*kfreebsd*-gnu|x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*| \
|
||||
x86_64-*kfreebsd*-gnu|x86_64-*linux*|powerpc*-*linux*| \
|
||||
s390*-*linux*|s390*-*tpf*|sparc*-*linux*)
|
||||
# Find out which ABI we are using.
|
||||
echo 'int i;' > conftest.$ac_ext
|
||||
@ -1296,7 +1296,10 @@ s390*-*linux*|s390*-*tpf*|sparc*-*linux*)
|
||||
x86_64-*linux*)
|
||||
LD="${LD-ld} -m elf_i386"
|
||||
;;
|
||||
ppc64-*linux*|powerpc64-*linux*)
|
||||
powerpc64le-*linux*)
|
||||
LD="${LD-ld} -m elf32lppclinux"
|
||||
;;
|
||||
powerpc64-*linux*)
|
||||
LD="${LD-ld} -m elf32ppclinux"
|
||||
;;
|
||||
s390x-*linux*)
|
||||
@ -1315,7 +1318,10 @@ s390*-*linux*|s390*-*tpf*|sparc*-*linux*)
|
||||
x86_64-*linux*)
|
||||
LD="${LD-ld} -m elf_x86_64"
|
||||
;;
|
||||
ppc*-*linux*|powerpc*-*linux*)
|
||||
powerpcle-*linux*)
|
||||
LD="${LD-ld} -m elf64lppc"
|
||||
;;
|
||||
powerpc-*linux*)
|
||||
LD="${LD-ld} -m elf64ppc"
|
||||
;;
|
||||
s390*-*linux*|s390*-*tpf*)
|
||||
|
12
js/src/ctypes/libffi/configure
vendored
12
js/src/ctypes/libffi/configure
vendored
@ -6298,7 +6298,7 @@ ia64-*-hpux*)
|
||||
rm -rf conftest*
|
||||
;;
|
||||
|
||||
x86_64-*kfreebsd*-gnu|x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*| \
|
||||
x86_64-*kfreebsd*-gnu|x86_64-*linux*|powerpc*-*linux*| \
|
||||
s390*-*linux*|s390*-*tpf*|sparc*-*linux*)
|
||||
# Find out which ABI we are using.
|
||||
echo 'int i;' > conftest.$ac_ext
|
||||
@ -6316,7 +6316,10 @@ s390*-*linux*|s390*-*tpf*|sparc*-*linux*)
|
||||
x86_64-*linux*)
|
||||
LD="${LD-ld} -m elf_i386"
|
||||
;;
|
||||
ppc64-*linux*|powerpc64-*linux*)
|
||||
powerpc64le-*linux*)
|
||||
LD="${LD-ld} -m elf32lppclinux"
|
||||
;;
|
||||
powerpc64-*linux*)
|
||||
LD="${LD-ld} -m elf32ppclinux"
|
||||
;;
|
||||
s390x-*linux*)
|
||||
@ -6335,7 +6338,10 @@ s390*-*linux*|s390*-*tpf*|sparc*-*linux*)
|
||||
x86_64-*linux*)
|
||||
LD="${LD-ld} -m elf_x86_64"
|
||||
;;
|
||||
ppc*-*linux*|powerpc*-*linux*)
|
||||
powerpcle-*linux*)
|
||||
LD="${LD-ld} -m elf64lppc"
|
||||
;;
|
||||
powerpc-*linux*)
|
||||
LD="${LD-ld} -m elf64ppc"
|
||||
;;
|
||||
s390*-*linux*|s390*-*tpf*)
|
||||
|
12
js/src/ctypes/libffi/m4/libtool.m4
vendored
12
js/src/ctypes/libffi/m4/libtool.m4
vendored
@ -1267,7 +1267,7 @@ ia64-*-hpux*)
|
||||
rm -rf conftest*
|
||||
;;
|
||||
|
||||
x86_64-*kfreebsd*-gnu|x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*| \
|
||||
x86_64-*kfreebsd*-gnu|x86_64-*linux*|powerpc*-*linux*| \
|
||||
s390*-*linux*|s390*-*tpf*|sparc*-*linux*)
|
||||
# Find out which ABI we are using.
|
||||
echo 'int i;' > conftest.$ac_ext
|
||||
@ -1281,7 +1281,10 @@ s390*-*linux*|s390*-*tpf*|sparc*-*linux*)
|
||||
x86_64-*linux*)
|
||||
LD="${LD-ld} -m elf_i386"
|
||||
;;
|
||||
ppc64-*linux*|powerpc64-*linux*)
|
||||
powerpc64le-*linux*)
|
||||
LD="${LD-ld} -m elf32lppclinux"
|
||||
;;
|
||||
powerpc64-*linux*)
|
||||
LD="${LD-ld} -m elf32ppclinux"
|
||||
;;
|
||||
s390x-*linux*)
|
||||
@ -1300,7 +1303,10 @@ s390*-*linux*|s390*-*tpf*|sparc*-*linux*)
|
||||
x86_64-*linux*)
|
||||
LD="${LD-ld} -m elf_x86_64"
|
||||
;;
|
||||
ppc*-*linux*|powerpc*-*linux*)
|
||||
powerpcle-*linux*)
|
||||
LD="${LD-ld} -m elf64lppc"
|
||||
;;
|
||||
powerpc-*linux*)
|
||||
LD="${LD-ld} -m elf64ppc"
|
||||
;;
|
||||
s390*-*linux*|s390*-*tpf*)
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,6 +1,8 @@
|
||||
/* -----------------------------------------------------------------*-C-*-
|
||||
ffitarget.h - Copyright (c) 1996-2003 Red Hat, Inc.
|
||||
Copyright (C) 2007, 2008 Free Software Foundation, Inc
|
||||
ffitarget.h - Copyright (c) 2012 Anthony Green
|
||||
Copyright (C) 2007, 2008, 2010 Free Software Foundation, Inc
|
||||
Copyright (c) 1996-2003 Red Hat, Inc.
|
||||
|
||||
Target configuration macros for PowerPC.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
@ -28,6 +30,10 @@
|
||||
#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
|
||||
|
||||
/* ---- System specific configurations ----------------------------------- */
|
||||
|
||||
#if defined (POWERPC) && defined (__powerpc64__) /* linux64 */
|
||||
@ -57,18 +63,14 @@ typedef enum ffi_abi {
|
||||
FFI_LINUX64,
|
||||
FFI_LINUX,
|
||||
FFI_LINUX_SOFT_FLOAT,
|
||||
# ifdef POWERPC64
|
||||
# if defined(POWERPC64)
|
||||
FFI_DEFAULT_ABI = FFI_LINUX64,
|
||||
# else
|
||||
# if (!defined(__NO_FPRS__) && (__LDBL_MANT_DIG__ == 106))
|
||||
FFI_DEFAULT_ABI = FFI_LINUX,
|
||||
# else
|
||||
# ifdef __NO_FPRS__
|
||||
# elif defined(__NO_FPRS__)
|
||||
FFI_DEFAULT_ABI = FFI_LINUX_SOFT_FLOAT,
|
||||
# else
|
||||
# elif (__LDBL_MANT_DIG__ == 106)
|
||||
FFI_DEFAULT_ABI = FFI_LINUX,
|
||||
# else
|
||||
FFI_DEFAULT_ABI = FFI_GCC_SYSV,
|
||||
# endif
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
@ -101,6 +103,10 @@ typedef enum ffi_abi {
|
||||
|
||||
#define FFI_CLOSURES 1
|
||||
#define FFI_NATIVE_RAW_API 0
|
||||
#if defined (POWERPC) || defined (POWERPC_FREEBSD)
|
||||
# define FFI_TARGET_SPECIFIC_VARIADIC 1
|
||||
# define FFI_EXTRA_CIF_FIELDS unsigned nfixedargs
|
||||
#endif
|
||||
|
||||
/* For additional types like the below, take care about the order in
|
||||
ppc_closures.S. They must follow after the FFI_TYPE_LAST. */
|
||||
@ -113,10 +119,19 @@ typedef enum ffi_abi {
|
||||
defined in ffi.c, to determine the exact return type and its size. */
|
||||
#define FFI_SYSV_TYPE_SMALL_STRUCT (FFI_TYPE_LAST + 2)
|
||||
|
||||
#if defined(POWERPC64) || defined(POWERPC_AIX)
|
||||
#define FFI_TRAMPOLINE_SIZE 24
|
||||
#else /* POWERPC || POWERPC_AIX */
|
||||
#define FFI_TRAMPOLINE_SIZE 40
|
||||
/* Used by ELFv2 for homogenous structure returns. */
|
||||
#define FFI_V2_TYPE_FLOAT_HOMOG (FFI_TYPE_LAST + 1)
|
||||
#define FFI_V2_TYPE_DOUBLE_HOMOG (FFI_TYPE_LAST + 2)
|
||||
#define FFI_V2_TYPE_SMALL_STRUCT (FFI_TYPE_LAST + 3)
|
||||
|
||||
#if _CALL_ELF == 2
|
||||
# define FFI_TRAMPOLINE_SIZE 32
|
||||
#else
|
||||
# if defined(POWERPC64) || defined(POWERPC_AIX)
|
||||
# define FFI_TRAMPOLINE_SIZE 24
|
||||
# else /* POWERPC || POWERPC_AIX */
|
||||
# define FFI_TRAMPOLINE_SIZE 40
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef LIBFFI_ASM
|
||||
|
@ -30,16 +30,33 @@
|
||||
#include <ffi.h>
|
||||
|
||||
#ifdef __powerpc64__
|
||||
.hidden ffi_call_LINUX64, .ffi_call_LINUX64
|
||||
.globl ffi_call_LINUX64, .ffi_call_LINUX64
|
||||
.hidden ffi_call_LINUX64
|
||||
.globl ffi_call_LINUX64
|
||||
# if _CALL_ELF == 2
|
||||
.text
|
||||
ffi_call_LINUX64:
|
||||
addis %r2, %r12, .TOC.-ffi_call_LINUX64@ha
|
||||
addi %r2, %r2, .TOC.-ffi_call_LINUX64@l
|
||||
.localentry ffi_call_LINUX64, . - ffi_call_LINUX64
|
||||
# else
|
||||
.section ".opd","aw"
|
||||
.align 3
|
||||
ffi_call_LINUX64:
|
||||
# ifdef _CALL_LINUX
|
||||
.quad .L.ffi_call_LINUX64,.TOC.@tocbase,0
|
||||
.type ffi_call_LINUX64,@function
|
||||
.text
|
||||
.L.ffi_call_LINUX64:
|
||||
# else
|
||||
.hidden .ffi_call_LINUX64
|
||||
.globl .ffi_call_LINUX64
|
||||
.quad .ffi_call_LINUX64,.TOC.@tocbase,0
|
||||
.size ffi_call_LINUX64,24
|
||||
.type .ffi_call_LINUX64,@function
|
||||
.text
|
||||
.ffi_call_LINUX64:
|
||||
# endif
|
||||
# endif
|
||||
.LFB1:
|
||||
mflr %r0
|
||||
std %r28, -32(%r1)
|
||||
@ -54,22 +71,35 @@ ffi_call_LINUX64:
|
||||
mr %r31, %r5 /* flags, */
|
||||
mr %r30, %r6 /* rvalue, */
|
||||
mr %r29, %r7 /* function address. */
|
||||
/* Save toc pointer, not for the ffi_prep_args64 call, but for the later
|
||||
bctrl function call. */
|
||||
# if _CALL_ELF == 2
|
||||
std %r2, 24(%r1)
|
||||
# else
|
||||
std %r2, 40(%r1)
|
||||
# endif
|
||||
|
||||
/* Call ffi_prep_args64. */
|
||||
mr %r4, %r1
|
||||
# if defined _CALL_LINUX || _CALL_ELF == 2
|
||||
bl ffi_prep_args64
|
||||
# else
|
||||
bl .ffi_prep_args64
|
||||
# endif
|
||||
|
||||
ld %r0, 0(%r29)
|
||||
# if _CALL_ELF == 2
|
||||
mr %r12, %r29
|
||||
# else
|
||||
ld %r12, 0(%r29)
|
||||
ld %r2, 8(%r29)
|
||||
ld %r11, 16(%r29)
|
||||
|
||||
# endif
|
||||
/* Now do the call. */
|
||||
/* Set up cr1 with bits 4-7 of the flags. */
|
||||
mtcrf 0x40, %r31
|
||||
|
||||
/* Get the address to call into CTR. */
|
||||
mtctr %r0
|
||||
mtctr %r12
|
||||
/* Load all those argument registers. */
|
||||
ld %r3, -32-(8*8)(%r28)
|
||||
ld %r4, -32-(7*8)(%r28)
|
||||
@ -104,12 +134,17 @@ ffi_call_LINUX64:
|
||||
|
||||
/* This must follow the call immediately, the unwinder
|
||||
uses this to find out if r2 has been saved or not. */
|
||||
# if _CALL_ELF == 2
|
||||
ld %r2, 24(%r1)
|
||||
# else
|
||||
ld %r2, 40(%r1)
|
||||
# endif
|
||||
|
||||
/* Now, deal with the return value. */
|
||||
mtcrf 0x01, %r31
|
||||
bt- 30, .Ldone_return_value
|
||||
bt- 29, .Lfp_return_value
|
||||
bt 31, .Lstruct_return_value
|
||||
bt 30, .Ldone_return_value
|
||||
bt 29, .Lfp_return_value
|
||||
std %r3, 0(%r30)
|
||||
/* Fall through... */
|
||||
|
||||
@ -117,7 +152,7 @@ ffi_call_LINUX64:
|
||||
/* Restore the registers we used and return. */
|
||||
mr %r1, %r28
|
||||
ld %r0, 16(%r28)
|
||||
ld %r28, -32(%r1)
|
||||
ld %r28, -32(%r28)
|
||||
mtlr %r0
|
||||
ld %r29, -24(%r1)
|
||||
ld %r30, -16(%r1)
|
||||
@ -134,10 +169,48 @@ ffi_call_LINUX64:
|
||||
.Lfloat_return_value:
|
||||
stfs %f1, 0(%r30)
|
||||
b .Ldone_return_value
|
||||
|
||||
.Lstruct_return_value:
|
||||
bf 29, .Lsmall_struct
|
||||
bf 28, .Lfloat_homog_return_value
|
||||
stfd %f1, 0(%r30)
|
||||
stfd %f2, 8(%r30)
|
||||
stfd %f3, 16(%r30)
|
||||
stfd %f4, 24(%r30)
|
||||
stfd %f5, 32(%r30)
|
||||
stfd %f6, 40(%r30)
|
||||
stfd %f7, 48(%r30)
|
||||
stfd %f8, 56(%r30)
|
||||
b .Ldone_return_value
|
||||
|
||||
.Lfloat_homog_return_value:
|
||||
stfs %f1, 0(%r30)
|
||||
stfs %f2, 4(%r30)
|
||||
stfs %f3, 8(%r30)
|
||||
stfs %f4, 12(%r30)
|
||||
stfs %f5, 16(%r30)
|
||||
stfs %f6, 20(%r30)
|
||||
stfs %f7, 24(%r30)
|
||||
stfs %f8, 28(%r30)
|
||||
b .Ldone_return_value
|
||||
|
||||
.Lsmall_struct:
|
||||
std %r3, 0(%r30)
|
||||
std %r4, 8(%r30)
|
||||
b .Ldone_return_value
|
||||
|
||||
.LFE1:
|
||||
.long 0
|
||||
.byte 0,12,0,1,128,4,0,0
|
||||
# if _CALL_ELF == 2
|
||||
.size ffi_call_LINUX64,.-ffi_call_LINUX64
|
||||
# else
|
||||
# ifdef _CALL_LINUX
|
||||
.size ffi_call_LINUX64,.-.L.ffi_call_LINUX64
|
||||
# else
|
||||
.size .ffi_call_LINUX64,.-.ffi_call_LINUX64
|
||||
# endif
|
||||
# endif
|
||||
|
||||
.section .eh_frame,EH_FRAME_FLAGS,@progbits
|
||||
.Lframe1:
|
||||
@ -180,8 +253,8 @@ ffi_call_LINUX64:
|
||||
.uleb128 0x4
|
||||
.align 3
|
||||
.LEFDE1:
|
||||
#endif
|
||||
|
||||
#if defined __ELF__ && defined __linux__
|
||||
# if (defined __ELF__ && defined __linux__) || _CALL_ELF == 2
|
||||
.section .note.GNU-stack,"",@progbits
|
||||
# endif
|
||||
#endif
|
||||
|
@ -32,66 +32,125 @@
|
||||
|
||||
#ifdef __powerpc64__
|
||||
FFI_HIDDEN (ffi_closure_LINUX64)
|
||||
FFI_HIDDEN (.ffi_closure_LINUX64)
|
||||
.globl ffi_closure_LINUX64, .ffi_closure_LINUX64
|
||||
.globl ffi_closure_LINUX64
|
||||
# if _CALL_ELF == 2
|
||||
.text
|
||||
ffi_closure_LINUX64:
|
||||
addis %r2, %r12, .TOC.-ffi_closure_LINUX64@ha
|
||||
addi %r2, %r2, .TOC.-ffi_closure_LINUX64@l
|
||||
.localentry ffi_closure_LINUX64, . - ffi_closure_LINUX64
|
||||
# else
|
||||
.section ".opd","aw"
|
||||
.align 3
|
||||
ffi_closure_LINUX64:
|
||||
# ifdef _CALL_LINUX
|
||||
.quad .L.ffi_closure_LINUX64,.TOC.@tocbase,0
|
||||
.type ffi_closure_LINUX64,@function
|
||||
.text
|
||||
.L.ffi_closure_LINUX64:
|
||||
# else
|
||||
FFI_HIDDEN (.ffi_closure_LINUX64)
|
||||
.globl .ffi_closure_LINUX64
|
||||
.quad .ffi_closure_LINUX64,.TOC.@tocbase,0
|
||||
.size ffi_closure_LINUX64,24
|
||||
.type .ffi_closure_LINUX64,@function
|
||||
.text
|
||||
.ffi_closure_LINUX64:
|
||||
.LFB1:
|
||||
# save general regs into parm save area
|
||||
std %r3, 48(%r1)
|
||||
std %r4, 56(%r1)
|
||||
std %r5, 64(%r1)
|
||||
std %r6, 72(%r1)
|
||||
mflr %r0
|
||||
# endif
|
||||
# endif
|
||||
|
||||
# if _CALL_ELF == 2
|
||||
# 32 byte special reg save area + 64 byte parm save area
|
||||
# + 64 byte retval area + 13*8 fpr save area + round to 16
|
||||
# define STACKFRAME 272
|
||||
# define PARMSAVE 32
|
||||
# define RETVAL PARMSAVE+64
|
||||
# else
|
||||
# 48 bytes special reg save area + 64 bytes parm save area
|
||||
# + 16 bytes retval area + 13*8 bytes fpr save area + round to 16
|
||||
# define STACKFRAME 240
|
||||
# define PARMSAVE 48
|
||||
# define RETVAL PARMSAVE+64
|
||||
# endif
|
||||
|
||||
.LFB1:
|
||||
# if _CALL_ELF == 2
|
||||
ld %r12, FFI_TRAMPOLINE_SIZE(%r11) # closure->cif
|
||||
mflr %r0
|
||||
lwz %r12, 28(%r12) # cif->flags
|
||||
mtcrf 0x40, %r12
|
||||
addi %r12, %r1, PARMSAVE
|
||||
bt 7, .Lparmsave
|
||||
# Our caller has not allocated a parameter save area.
|
||||
# We need to allocate one here and use it to pass gprs to
|
||||
# ffi_closure_helper_LINUX64.
|
||||
addi %r12, %r1, -STACKFRAME+PARMSAVE
|
||||
.Lparmsave:
|
||||
std %r0, 16(%r1)
|
||||
# Save general regs into parm save area
|
||||
std %r3, 0(%r12)
|
||||
std %r4, 8(%r12)
|
||||
std %r5, 16(%r12)
|
||||
std %r6, 24(%r12)
|
||||
std %r7, 32(%r12)
|
||||
std %r8, 40(%r12)
|
||||
std %r9, 48(%r12)
|
||||
std %r10, 56(%r12)
|
||||
|
||||
# load up the pointer to the parm save area
|
||||
mr %r5, %r12
|
||||
# else
|
||||
mflr %r0
|
||||
# Save general regs into parm save area
|
||||
# This is the parameter save area set up by our caller.
|
||||
std %r3, PARMSAVE+0(%r1)
|
||||
std %r4, PARMSAVE+8(%r1)
|
||||
std %r5, PARMSAVE+16(%r1)
|
||||
std %r6, PARMSAVE+24(%r1)
|
||||
std %r7, PARMSAVE+32(%r1)
|
||||
std %r8, PARMSAVE+40(%r1)
|
||||
std %r9, PARMSAVE+48(%r1)
|
||||
std %r10, PARMSAVE+56(%r1)
|
||||
|
||||
std %r7, 80(%r1)
|
||||
std %r8, 88(%r1)
|
||||
std %r9, 96(%r1)
|
||||
std %r10, 104(%r1)
|
||||
std %r0, 16(%r1)
|
||||
|
||||
# mandatory 48 bytes special reg save area + 64 bytes parm save area
|
||||
# + 16 bytes retval area + 13*8 bytes fpr save area + round to 16
|
||||
stdu %r1, -240(%r1)
|
||||
.LCFI0:
|
||||
# load up the pointer to the parm save area
|
||||
addi %r5, %r1, PARMSAVE
|
||||
# endif
|
||||
|
||||
# next save fpr 1 to fpr 13
|
||||
stfd %f1, 128+(0*8)(%r1)
|
||||
stfd %f2, 128+(1*8)(%r1)
|
||||
stfd %f3, 128+(2*8)(%r1)
|
||||
stfd %f4, 128+(3*8)(%r1)
|
||||
stfd %f5, 128+(4*8)(%r1)
|
||||
stfd %f6, 128+(5*8)(%r1)
|
||||
stfd %f7, 128+(6*8)(%r1)
|
||||
stfd %f8, 128+(7*8)(%r1)
|
||||
stfd %f9, 128+(8*8)(%r1)
|
||||
stfd %f10, 128+(9*8)(%r1)
|
||||
stfd %f11, 128+(10*8)(%r1)
|
||||
stfd %f12, 128+(11*8)(%r1)
|
||||
stfd %f13, 128+(12*8)(%r1)
|
||||
stfd %f1, -104+(0*8)(%r1)
|
||||
stfd %f2, -104+(1*8)(%r1)
|
||||
stfd %f3, -104+(2*8)(%r1)
|
||||
stfd %f4, -104+(3*8)(%r1)
|
||||
stfd %f5, -104+(4*8)(%r1)
|
||||
stfd %f6, -104+(5*8)(%r1)
|
||||
stfd %f7, -104+(6*8)(%r1)
|
||||
stfd %f8, -104+(7*8)(%r1)
|
||||
stfd %f9, -104+(8*8)(%r1)
|
||||
stfd %f10, -104+(9*8)(%r1)
|
||||
stfd %f11, -104+(10*8)(%r1)
|
||||
stfd %f12, -104+(11*8)(%r1)
|
||||
stfd %f13, -104+(12*8)(%r1)
|
||||
|
||||
# load up the pointer to the saved fpr registers */
|
||||
addi %r6, %r1, -104
|
||||
|
||||
# load up the pointer to the result storage
|
||||
addi %r4, %r1, -STACKFRAME+RETVAL
|
||||
|
||||
stdu %r1, -STACKFRAME(%r1)
|
||||
.LCFI0:
|
||||
|
||||
# set up registers for the routine that actually does the work
|
||||
# get the context pointer from the trampoline
|
||||
mr %r3, %r11
|
||||
|
||||
# now load up the pointer to the result storage
|
||||
addi %r4, %r1, 112
|
||||
|
||||
# now load up the pointer to the parameter save area
|
||||
# in the previous frame
|
||||
addi %r5, %r1, 240 + 48
|
||||
|
||||
# now load up the pointer to the saved fpr registers */
|
||||
addi %r6, %r1, 128
|
||||
mr %r3, %r11
|
||||
|
||||
# make the call
|
||||
# if defined _CALL_LINUX || _CALL_ELF == 2
|
||||
bl ffi_closure_helper_LINUX64
|
||||
# else
|
||||
bl .ffi_closure_helper_LINUX64
|
||||
# endif
|
||||
.Lret:
|
||||
|
||||
# now r3 contains the return type
|
||||
@ -100,10 +159,12 @@ ffi_closure_LINUX64:
|
||||
|
||||
# look up the proper starting point in table
|
||||
# by using return type as offset
|
||||
ld %r0, STACKFRAME+16(%r1)
|
||||
cmpldi %r3, FFI_V2_TYPE_SMALL_STRUCT
|
||||
bge .Lsmall
|
||||
mflr %r4 # move address of .Lret to r4
|
||||
sldi %r3, %r3, 4 # now multiply return type by 16
|
||||
addi %r4, %r4, .Lret_type0 - .Lret
|
||||
ld %r0, 240+16(%r1)
|
||||
add %r3, %r3, %r4 # add contents of table to table address
|
||||
mtctr %r3
|
||||
bctr # jump to it
|
||||
@ -116,85 +177,175 @@ ffi_closure_LINUX64:
|
||||
.Lret_type0:
|
||||
# case FFI_TYPE_VOID
|
||||
mtlr %r0
|
||||
addi %r1, %r1, 240
|
||||
addi %r1, %r1, STACKFRAME
|
||||
blr
|
||||
nop
|
||||
# case FFI_TYPE_INT
|
||||
lwa %r3, 112+4(%r1)
|
||||
# ifdef __LITTLE_ENDIAN__
|
||||
lwa %r3, RETVAL+0(%r1)
|
||||
# else
|
||||
lwa %r3, RETVAL+4(%r1)
|
||||
# endif
|
||||
mtlr %r0
|
||||
addi %r1, %r1, 240
|
||||
addi %r1, %r1, STACKFRAME
|
||||
blr
|
||||
# case FFI_TYPE_FLOAT
|
||||
lfs %f1, 112+0(%r1)
|
||||
lfs %f1, RETVAL+0(%r1)
|
||||
mtlr %r0
|
||||
addi %r1, %r1, 240
|
||||
addi %r1, %r1, STACKFRAME
|
||||
blr
|
||||
# case FFI_TYPE_DOUBLE
|
||||
lfd %f1, 112+0(%r1)
|
||||
lfd %f1, RETVAL+0(%r1)
|
||||
mtlr %r0
|
||||
addi %r1, %r1, 240
|
||||
addi %r1, %r1, STACKFRAME
|
||||
blr
|
||||
# case FFI_TYPE_LONGDOUBLE
|
||||
lfd %f1, 112+0(%r1)
|
||||
lfd %f1, RETVAL+0(%r1)
|
||||
mtlr %r0
|
||||
lfd %f2, 112+8(%r1)
|
||||
lfd %f2, RETVAL+8(%r1)
|
||||
b .Lfinish
|
||||
# case FFI_TYPE_UINT8
|
||||
lbz %r3, 112+7(%r1)
|
||||
# ifdef __LITTLE_ENDIAN__
|
||||
lbz %r3, RETVAL+0(%r1)
|
||||
# else
|
||||
lbz %r3, RETVAL+7(%r1)
|
||||
# endif
|
||||
mtlr %r0
|
||||
addi %r1, %r1, 240
|
||||
addi %r1, %r1, STACKFRAME
|
||||
blr
|
||||
# case FFI_TYPE_SINT8
|
||||
lbz %r3, 112+7(%r1)
|
||||
# ifdef __LITTLE_ENDIAN__
|
||||
lbz %r3, RETVAL+0(%r1)
|
||||
# else
|
||||
lbz %r3, RETVAL+7(%r1)
|
||||
# endif
|
||||
extsb %r3,%r3
|
||||
mtlr %r0
|
||||
b .Lfinish
|
||||
# case FFI_TYPE_UINT16
|
||||
lhz %r3, 112+6(%r1)
|
||||
# ifdef __LITTLE_ENDIAN__
|
||||
lhz %r3, RETVAL+0(%r1)
|
||||
# else
|
||||
lhz %r3, RETVAL+6(%r1)
|
||||
# endif
|
||||
mtlr %r0
|
||||
.Lfinish:
|
||||
addi %r1, %r1, 240
|
||||
addi %r1, %r1, STACKFRAME
|
||||
blr
|
||||
# case FFI_TYPE_SINT16
|
||||
lha %r3, 112+6(%r1)
|
||||
# ifdef __LITTLE_ENDIAN__
|
||||
lha %r3, RETVAL+0(%r1)
|
||||
# else
|
||||
lha %r3, RETVAL+6(%r1)
|
||||
# endif
|
||||
mtlr %r0
|
||||
addi %r1, %r1, 240
|
||||
addi %r1, %r1, STACKFRAME
|
||||
blr
|
||||
# case FFI_TYPE_UINT32
|
||||
lwz %r3, 112+4(%r1)
|
||||
# ifdef __LITTLE_ENDIAN__
|
||||
lwz %r3, RETVAL+0(%r1)
|
||||
# else
|
||||
lwz %r3, RETVAL+4(%r1)
|
||||
# endif
|
||||
mtlr %r0
|
||||
addi %r1, %r1, 240
|
||||
addi %r1, %r1, STACKFRAME
|
||||
blr
|
||||
# case FFI_TYPE_SINT32
|
||||
lwa %r3, 112+4(%r1)
|
||||
# ifdef __LITTLE_ENDIAN__
|
||||
lwa %r3, RETVAL+0(%r1)
|
||||
# else
|
||||
lwa %r3, RETVAL+4(%r1)
|
||||
# endif
|
||||
mtlr %r0
|
||||
addi %r1, %r1, 240
|
||||
addi %r1, %r1, STACKFRAME
|
||||
blr
|
||||
# case FFI_TYPE_UINT64
|
||||
ld %r3, 112+0(%r1)
|
||||
ld %r3, RETVAL+0(%r1)
|
||||
mtlr %r0
|
||||
addi %r1, %r1, 240
|
||||
addi %r1, %r1, STACKFRAME
|
||||
blr
|
||||
# case FFI_TYPE_SINT64
|
||||
ld %r3, 112+0(%r1)
|
||||
ld %r3, RETVAL+0(%r1)
|
||||
mtlr %r0
|
||||
addi %r1, %r1, 240
|
||||
addi %r1, %r1, STACKFRAME
|
||||
blr
|
||||
# case FFI_TYPE_STRUCT
|
||||
mtlr %r0
|
||||
addi %r1, %r1, 240
|
||||
addi %r1, %r1, STACKFRAME
|
||||
blr
|
||||
nop
|
||||
# case FFI_TYPE_POINTER
|
||||
ld %r3, 112+0(%r1)
|
||||
ld %r3, RETVAL+0(%r1)
|
||||
mtlr %r0
|
||||
addi %r1, %r1, 240
|
||||
addi %r1, %r1, STACKFRAME
|
||||
blr
|
||||
# esac
|
||||
# case FFI_V2_TYPE_FLOAT_HOMOG
|
||||
lfs %f1, RETVAL+0(%r1)
|
||||
lfs %f2, RETVAL+4(%r1)
|
||||
lfs %f3, RETVAL+8(%r1)
|
||||
b .Lmorefloat
|
||||
# case FFI_V2_TYPE_DOUBLE_HOMOG
|
||||
lfd %f1, RETVAL+0(%r1)
|
||||
lfd %f2, RETVAL+8(%r1)
|
||||
lfd %f3, RETVAL+16(%r1)
|
||||
lfd %f4, RETVAL+24(%r1)
|
||||
mtlr %r0
|
||||
lfd %f5, RETVAL+32(%r1)
|
||||
lfd %f6, RETVAL+40(%r1)
|
||||
lfd %f7, RETVAL+48(%r1)
|
||||
lfd %f8, RETVAL+56(%r1)
|
||||
addi %r1, %r1, STACKFRAME
|
||||
blr
|
||||
.Lmorefloat:
|
||||
lfs %f4, RETVAL+12(%r1)
|
||||
mtlr %r0
|
||||
lfs %f5, RETVAL+16(%r1)
|
||||
lfs %f6, RETVAL+20(%r1)
|
||||
lfs %f7, RETVAL+24(%r1)
|
||||
lfs %f8, RETVAL+28(%r1)
|
||||
addi %r1, %r1, STACKFRAME
|
||||
blr
|
||||
.Lsmall:
|
||||
# ifdef __LITTLE_ENDIAN__
|
||||
ld %r3,RETVAL+0(%r1)
|
||||
mtlr %r0
|
||||
ld %r4,RETVAL+8(%r1)
|
||||
addi %r1, %r1, STACKFRAME
|
||||
blr
|
||||
# else
|
||||
# A struct smaller than a dword is returned in the low bits of r3
|
||||
# ie. right justified. Larger structs are passed left justified
|
||||
# in r3 and r4. The return value area on the stack will have
|
||||
# the structs as they are usually stored in memory.
|
||||
cmpldi %r3, FFI_V2_TYPE_SMALL_STRUCT + 7 # size 8 bytes?
|
||||
neg %r5, %r3
|
||||
ld %r3,RETVAL+0(%r1)
|
||||
blt .Lsmalldown
|
||||
mtlr %r0
|
||||
ld %r4,RETVAL+8(%r1)
|
||||
addi %r1, %r1, STACKFRAME
|
||||
blr
|
||||
.Lsmalldown:
|
||||
addi %r5, %r5, FFI_V2_TYPE_SMALL_STRUCT + 7
|
||||
mtlr %r0
|
||||
sldi %r5, %r5, 3
|
||||
addi %r1, %r1, STACKFRAME
|
||||
srd %r3, %r3, %r5
|
||||
blr
|
||||
# endif
|
||||
|
||||
.LFE1:
|
||||
.long 0
|
||||
.byte 0,12,0,1,128,0,0,0
|
||||
# if _CALL_ELF == 2
|
||||
.size ffi_closure_LINUX64,.-ffi_closure_LINUX64
|
||||
# else
|
||||
# ifdef _CALL_LINUX
|
||||
.size ffi_closure_LINUX64,.-.L.ffi_closure_LINUX64
|
||||
# else
|
||||
.size .ffi_closure_LINUX64,.-.ffi_closure_LINUX64
|
||||
# endif
|
||||
# endif
|
||||
|
||||
.section .eh_frame,EH_FRAME_FLAGS,@progbits
|
||||
.Lframe1:
|
||||
@ -223,14 +374,14 @@ ffi_closure_LINUX64:
|
||||
.byte 0x2 # DW_CFA_advance_loc1
|
||||
.byte .LCFI0-.LFB1
|
||||
.byte 0xe # DW_CFA_def_cfa_offset
|
||||
.uleb128 240
|
||||
.uleb128 STACKFRAME
|
||||
.byte 0x11 # DW_CFA_offset_extended_sf
|
||||
.uleb128 0x41
|
||||
.sleb128 -2
|
||||
.align 3
|
||||
.LEFDE1:
|
||||
#endif
|
||||
|
||||
#if defined __ELF__ && defined __linux__
|
||||
# if defined __ELF__ && defined __linux__
|
||||
.section .note.GNU-stack,"",@progbits
|
||||
# endif
|
||||
#endif
|
||||
|
@ -122,43 +122,78 @@ ENTRY(ffi_closure_SYSV)
|
||||
blr
|
||||
|
||||
# case FFI_TYPE_FLOAT
|
||||
#ifndef __NO_FPRS__
|
||||
lfs %f1,112+0(%r1)
|
||||
mtlr %r0
|
||||
addi %r1,%r1,144
|
||||
#else
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
#endif
|
||||
blr
|
||||
|
||||
# case FFI_TYPE_DOUBLE
|
||||
#ifndef __NO_FPRS__
|
||||
lfd %f1,112+0(%r1)
|
||||
mtlr %r0
|
||||
addi %r1,%r1,144
|
||||
#else
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
#endif
|
||||
blr
|
||||
|
||||
# case FFI_TYPE_LONGDOUBLE
|
||||
#ifndef __NO_FPRS__
|
||||
lfd %f1,112+0(%r1)
|
||||
lfd %f2,112+8(%r1)
|
||||
mtlr %r0
|
||||
b .Lfinish
|
||||
#else
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
blr
|
||||
#endif
|
||||
|
||||
# case FFI_TYPE_UINT8
|
||||
#ifdef __LITTLE_ENDIAN__
|
||||
lbz %r3,112+0(%r1)
|
||||
#else
|
||||
lbz %r3,112+3(%r1)
|
||||
#endif
|
||||
mtlr %r0
|
||||
addi %r1,%r1,144
|
||||
blr
|
||||
|
||||
# case FFI_TYPE_SINT8
|
||||
#ifdef __LITTLE_ENDIAN__
|
||||
lbz %r3,112+0(%r1)
|
||||
#else
|
||||
lbz %r3,112+3(%r1)
|
||||
#endif
|
||||
extsb %r3,%r3
|
||||
mtlr %r0
|
||||
b .Lfinish
|
||||
|
||||
# case FFI_TYPE_UINT16
|
||||
#ifdef __LITTLE_ENDIAN__
|
||||
lhz %r3,112+0(%r1)
|
||||
#else
|
||||
lhz %r3,112+2(%r1)
|
||||
#endif
|
||||
mtlr %r0
|
||||
addi %r1,%r1,144
|
||||
blr
|
||||
|
||||
# case FFI_TYPE_SINT16
|
||||
#ifdef __LITTLE_ENDIAN__
|
||||
lha %r3,112+0(%r1)
|
||||
#else
|
||||
lha %r3,112+2(%r1)
|
||||
#endif
|
||||
mtlr %r0
|
||||
addi %r1,%r1,144
|
||||
blr
|
||||
@ -203,7 +238,7 @@ ENTRY(ffi_closure_SYSV)
|
||||
lwz %r3,112+0(%r1)
|
||||
lwz %r4,112+4(%r1)
|
||||
lwz %r5,112+8(%r1)
|
||||
bl .Luint128
|
||||
b .Luint128
|
||||
|
||||
# The return types below are only used when the ABI type is FFI_SYSV.
|
||||
# case FFI_SYSV_TYPE_SMALL_STRUCT + 1. One byte struct.
|
||||
@ -220,9 +255,15 @@ ENTRY(ffi_closure_SYSV)
|
||||
|
||||
# case FFI_SYSV_TYPE_SMALL_STRUCT + 3. Three byte struct.
|
||||
lwz %r3,112+0(%r1)
|
||||
#ifdef __LITTLE_ENDIAN__
|
||||
mtlr %r0
|
||||
addi %r1,%r1,144
|
||||
blr
|
||||
#else
|
||||
srwi %r3,%r3,8
|
||||
mtlr %r0
|
||||
b .Lfinish
|
||||
#endif
|
||||
|
||||
# case FFI_SYSV_TYPE_SMALL_STRUCT + 4. Four byte struct.
|
||||
lwz %r3,112+0(%r1)
|
||||
@ -233,20 +274,35 @@ ENTRY(ffi_closure_SYSV)
|
||||
# case FFI_SYSV_TYPE_SMALL_STRUCT + 5. Five byte struct.
|
||||
lwz %r3,112+0(%r1)
|
||||
lwz %r4,112+4(%r1)
|
||||
#ifdef __LITTLE_ENDIAN__
|
||||
mtlr %r0
|
||||
b .Lfinish
|
||||
#else
|
||||
li %r5,24
|
||||
b .Lstruct567
|
||||
#endif
|
||||
|
||||
# case FFI_SYSV_TYPE_SMALL_STRUCT + 6. Six byte struct.
|
||||
lwz %r3,112+0(%r1)
|
||||
lwz %r4,112+4(%r1)
|
||||
#ifdef __LITTLE_ENDIAN__
|
||||
mtlr %r0
|
||||
b .Lfinish
|
||||
#else
|
||||
li %r5,16
|
||||
b .Lstruct567
|
||||
#endif
|
||||
|
||||
# case FFI_SYSV_TYPE_SMALL_STRUCT + 7. Seven byte struct.
|
||||
lwz %r3,112+0(%r1)
|
||||
lwz %r4,112+4(%r1)
|
||||
#ifdef __LITTLE_ENDIAN__
|
||||
mtlr %r0
|
||||
b .Lfinish
|
||||
#else
|
||||
li %r5,8
|
||||
b .Lstruct567
|
||||
#endif
|
||||
|
||||
# case FFI_SYSV_TYPE_SMALL_STRUCT + 8. Eight byte struct.
|
||||
lwz %r3,112+0(%r1)
|
||||
@ -254,6 +310,7 @@ ENTRY(ffi_closure_SYSV)
|
||||
mtlr %r0
|
||||
b .Lfinish
|
||||
|
||||
#ifndef __LITTLE_ENDIAN__
|
||||
.Lstruct567:
|
||||
subfic %r6,%r5,32
|
||||
srw %r4,%r4,%r5
|
||||
@ -263,6 +320,7 @@ ENTRY(ffi_closure_SYSV)
|
||||
mtlr %r0
|
||||
addi %r1,%r1,144
|
||||
blr
|
||||
#endif
|
||||
|
||||
.Luint128:
|
||||
lwz %r6,112+12(%r1)
|
||||
|
@ -83,6 +83,7 @@ ENTRY(ffi_call_SYSV)
|
||||
nop
|
||||
1:
|
||||
|
||||
#ifndef __NO_FPRS__
|
||||
/* Load all the FP registers. */
|
||||
bf- 6,2f
|
||||
lfd %f1,-16-(8*4)-(8*8)(%r28)
|
||||
@ -94,6 +95,7 @@ ENTRY(ffi_call_SYSV)
|
||||
lfd %f6,-16-(8*4)-(3*8)(%r28)
|
||||
lfd %f7,-16-(8*4)-(2*8)(%r28)
|
||||
lfd %f8,-16-(8*4)-(1*8)(%r28)
|
||||
#endif
|
||||
2:
|
||||
|
||||
/* Make the call. */
|
||||
@ -103,7 +105,9 @@ ENTRY(ffi_call_SYSV)
|
||||
mtcrf 0x01,%r31 /* cr7 */
|
||||
bt- 31,L(small_struct_return_value)
|
||||
bt- 30,L(done_return_value)
|
||||
#ifndef __NO_FPRS__
|
||||
bt- 29,L(fp_return_value)
|
||||
#endif
|
||||
stw %r3,0(%r30)
|
||||
bf+ 28,L(done_return_value)
|
||||
stw %r4,4(%r30)
|
||||
@ -124,6 +128,7 @@ L(done_return_value):
|
||||
lwz %r1,0(%r1)
|
||||
blr
|
||||
|
||||
#ifndef __NO_FPRS__
|
||||
L(fp_return_value):
|
||||
bf 28,L(float_return_value)
|
||||
stfd %f1,0(%r30)
|
||||
@ -134,21 +139,17 @@ L(fp_return_value):
|
||||
L(float_return_value):
|
||||
stfs %f1,0(%r30)
|
||||
b L(done_return_value)
|
||||
#endif
|
||||
|
||||
L(small_struct_return_value):
|
||||
extrwi %r6,%r31,2,19 /* number of bytes padding = shift/8 */
|
||||
mtcrf 0x02,%r31 /* copy flags to cr[24:27] (cr6) */
|
||||
extrwi %r5,%r31,5,19 /* r5 <- number of bits of padding */
|
||||
subfic %r6,%r6,4 /* r6 <- number of useful bytes in r3 */
|
||||
bf- 25,L(done_return_value) /* struct in r3 ? if not, done. */
|
||||
/* smst_one_register: */
|
||||
slw %r3,%r3,%r5 /* Left-justify value in r3 */
|
||||
mtxer %r6 /* move byte count to XER ... */
|
||||
stswx %r3,0,%r30 /* ... and store that many bytes */
|
||||
bf+ 26,L(done_return_value) /* struct in r3:r4 ? */
|
||||
add %r6,%r6,%r30 /* adjust pointer */
|
||||
stswi %r4,%r6,4 /* store last four bytes */
|
||||
b L(done_return_value)
|
||||
/*
|
||||
* The C code always allocates a properly-aligned 8-byte bounce
|
||||
* buffer to make this assembly code very simple. Just write out
|
||||
* r3 and r4 to the buffer to allow the C code to handle the rest.
|
||||
*/
|
||||
stw %r3, 0(%r30)
|
||||
stw %r4, 4(%r30)
|
||||
b L(done_return_value)
|
||||
|
||||
.LFE1:
|
||||
END(ffi_call_SYSV)
|
||||
|
Loading…
Reference in New Issue
Block a user