# HG changeset patch # Parent 007cf000fdf7c5048939a87f63165a67fd9db5f6 # User Ulrich Weigand Bug 976648 - powerpc64le-linux support - toplevel build/config Index: mozilla-release/build/autoconf/config.guess =================================================================== --- mozilla-release.orig/build/autoconf/config.guess +++ mozilla-release/build/autoconf/config.guess @@ -1,14 +1,12 @@ #! /bin/sh # Attempt to guess a canonical system name. -# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, -# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 -# Free Software Foundation, Inc. +# Copyright 1992-2014 Free Software Foundation, Inc. -timestamp='2009-08-19' +timestamp='2014-02-12' # This file is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or +# the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, but @@ -17,26 +15,22 @@ timestamp='2009-08-19' # General Public License for more details. # # You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA -# 02110-1301, USA. +# along with this program; if not, see . # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under -# the same distribution terms that you use for the rest of that program. - - -# Originally written by Per Bothner. Please send patches (context -# diff format) to and include a ChangeLog -# entry. +# the same distribution terms that you use for the rest of that +# program. This Exception is an additional permission under section 7 +# of the GNU General Public License, version 3 ("GPLv3"). # -# This script attempts to guess a canonical system name similar to -# config.sub. If it succeeds, it prints the system name on stdout, and -# exits with 0. Otherwise, it exits with 1. +# Originally written by Per Bothner. # # You can get the latest version of this script from: # http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD +# +# Please send patches with a ChangeLog entry to config-patches@gnu.org. + me=`echo "$0" | sed -e 's,.*/,,'` @@ -56,8 +50,7 @@ version="\ GNU config.guess ($timestamp) Originally written by Per Bothner. -Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, -2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. +Copyright 1992-2014 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." @@ -139,12 +132,33 @@ UNAME_RELEASE=`(uname -r) 2>/dev/null` | UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown +case "${UNAME_SYSTEM}" in +Linux|GNU|GNU/*) + # If the system lacks a compiler, then just pick glibc. + # We could probably try harder. + LIBC=gnu + + eval $set_cc_for_build + cat <<-EOF > $dummy.c + #include + #if defined(__UCLIBC__) + LIBC=uclibc + #elif defined(__dietlibc__) + LIBC=dietlibc + #else + LIBC=gnu + #endif + EOF + eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC' | sed 's, ,,g'` + ;; +esac + # Note: order is significant - the case branches are not exclusive. case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in *:NetBSD:*:*) # NetBSD (nbsd) targets should (where applicable) match one or - # more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*, + # more of the tuples: *-*-netbsdelf*, *-*-netbsdaout*, # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently # switched to ELF, *-*-netbsd* would select the old # object file format. This provides both forward @@ -180,7 +194,7 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:$ fi ;; *) - os=netbsd + os=netbsd ;; esac # The OS release @@ -201,6 +215,10 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:$ # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. echo "${machine}-${os}${release}" exit ;; + *:Bitrig:*:*) + UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'` + echo ${UNAME_MACHINE_ARCH}-unknown-bitrig${UNAME_RELEASE} + exit ;; *:OpenBSD:*:*) UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'` echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE} @@ -223,7 +241,7 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:$ UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` ;; *5.*) - UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'` + UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'` ;; esac # According to Compaq, /usr/sbin/psrinfo has been available on @@ -269,7 +287,10 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:$ # A Xn.n version is an unreleased experimental baselevel. # 1.2 uses "1.2" for uname -r. echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` - exit ;; + # Reset EXIT trap before exiting to avoid spurious non-zero exit code. + exitcode=$? + trap '' 0 + exit $exitcode ;; Alpha\ *:Windows_NT*:*) # How do we know it's Interix rather than the generic POSIX subsystem? # Should we change UNAME_MACHINE based on the output of uname instead @@ -295,12 +316,12 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:$ echo s390-ibm-zvmoe exit ;; *:OS400:*:*) - echo powerpc-ibm-os400 + echo powerpc-ibm-os400 exit ;; arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) echo arm-acorn-riscix${UNAME_RELEASE} exit ;; - arm:riscos:*:*|arm:RISCOS:*:*) + arm*:riscos:*:*|arm*:RISCOS:*:*) echo arm-unknown-riscos exit ;; SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) @@ -333,6 +354,9 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:$ sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; + i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*) + echo i386-pc-auroraux${UNAME_RELEASE} + exit ;; i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*) eval $set_cc_for_build SUN_ARCH="i386" @@ -391,23 +415,23 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:$ # MiNT. But MiNT is downward compatible to TOS, so this should # be no problem. atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) - echo m68k-atari-mint${UNAME_RELEASE} + echo m68k-atari-mint${UNAME_RELEASE} exit ;; atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) echo m68k-atari-mint${UNAME_RELEASE} - exit ;; + exit ;; *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) - echo m68k-atari-mint${UNAME_RELEASE} + echo m68k-atari-mint${UNAME_RELEASE} exit ;; milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) - echo m68k-milan-mint${UNAME_RELEASE} - exit ;; + echo m68k-milan-mint${UNAME_RELEASE} + exit ;; hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) - echo m68k-hades-mint${UNAME_RELEASE} - exit ;; + echo m68k-hades-mint${UNAME_RELEASE} + exit ;; *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) - echo m68k-unknown-mint${UNAME_RELEASE} - exit ;; + echo m68k-unknown-mint${UNAME_RELEASE} + exit ;; m68k:machten:*:*) echo m68k-apple-machten${UNAME_RELEASE} exit ;; @@ -477,8 +501,8 @@ EOF echo m88k-motorola-sysv3 exit ;; AViiON:dgux:*:*) - # DG/UX returns AViiON for all architectures - UNAME_PROCESSOR=`/usr/bin/uname -p` + # DG/UX returns AViiON for all architectures + UNAME_PROCESSOR=`/usr/bin/uname -p` if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ] then if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \ @@ -491,7 +515,7 @@ EOF else echo i586-dg-dgux${UNAME_RELEASE} fi - exit ;; + exit ;; M88*:DolphinOS:*:*) # DolphinOS (SVR3) echo m88k-dolphin-sysv3 exit ;; @@ -548,7 +572,7 @@ EOF echo rs6000-ibm-aix3.2 fi exit ;; - *:AIX:*:[456]) + *:AIX:*:[4567]) IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then IBM_ARCH=rs6000 @@ -591,52 +615,52 @@ EOF 9000/[678][0-9][0-9]) if [ -x /usr/bin/getconf ]; then sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` - sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` - case "${sc_cpu_version}" in - 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0 - 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1 - 532) # CPU_PA_RISC2_0 - case "${sc_kernel_bits}" in - 32) HP_ARCH="hppa2.0n" ;; - 64) HP_ARCH="hppa2.0w" ;; + sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` + case "${sc_cpu_version}" in + 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0 + 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1 + 532) # CPU_PA_RISC2_0 + case "${sc_kernel_bits}" in + 32) HP_ARCH="hppa2.0n" ;; + 64) HP_ARCH="hppa2.0w" ;; '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20 - esac ;; - esac + esac ;; + esac fi if [ "${HP_ARCH}" = "" ]; then eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c + sed 's/^ //' << EOF >$dummy.c + + #define _HPUX_SOURCE + #include + #include + + int main () + { + #if defined(_SC_KERNEL_BITS) + long bits = sysconf(_SC_KERNEL_BITS); + #endif + long cpu = sysconf (_SC_CPU_VERSION); - #define _HPUX_SOURCE - #include - #include - - int main () - { - #if defined(_SC_KERNEL_BITS) - long bits = sysconf(_SC_KERNEL_BITS); - #endif - long cpu = sysconf (_SC_CPU_VERSION); - - switch (cpu) - { - case CPU_PA_RISC1_0: puts ("hppa1.0"); break; - case CPU_PA_RISC1_1: puts ("hppa1.1"); break; - case CPU_PA_RISC2_0: - #if defined(_SC_KERNEL_BITS) - switch (bits) - { - case 64: puts ("hppa2.0w"); break; - case 32: puts ("hppa2.0n"); break; - default: puts ("hppa2.0"); break; - } break; - #else /* !defined(_SC_KERNEL_BITS) */ - puts ("hppa2.0"); break; - #endif - default: puts ("hppa1.0"); break; - } - exit (0); - } + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1"); break; + case CPU_PA_RISC2_0: + #if defined(_SC_KERNEL_BITS) + switch (bits) + { + case 64: puts ("hppa2.0w"); break; + case 32: puts ("hppa2.0n"); break; + default: puts ("hppa2.0"); break; + } break; + #else /* !defined(_SC_KERNEL_BITS) */ + puts ("hppa2.0"); break; + #endif + default: puts ("hppa1.0"); break; + } + exit (0); + } EOF (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy` test -z "$HP_ARCH" && HP_ARCH=hppa @@ -727,22 +751,22 @@ EOF exit ;; C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) echo c1-convex-bsd - exit ;; + exit ;; C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) if getsysinfo -f scalar_acc then echo c32-convex-bsd else echo c2-convex-bsd fi - exit ;; + exit ;; C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) echo c34-convex-bsd - exit ;; + exit ;; C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) echo c38-convex-bsd - exit ;; + exit ;; C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) echo c4-convex-bsd - exit ;; + exit ;; CRAY*Y-MP:*:*:*) echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; @@ -766,14 +790,14 @@ EOF exit ;; F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` - FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` - FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` - echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" - exit ;; + FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` + FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` + echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" + exit ;; 5000:UNIX_System_V:4.*:*) - FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` - FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'` - echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" + FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` + FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'` + echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" exit ;; i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} @@ -785,34 +809,39 @@ EOF echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} exit ;; *:FreeBSD:*:*) - case ${UNAME_MACHINE} in - pc98) - echo i386-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; + UNAME_PROCESSOR=`/usr/bin/uname -p` + case ${UNAME_PROCESSOR} in amd64) echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; *) - echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; + echo ${UNAME_PROCESSOR}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; esac exit ;; i*:CYGWIN*:*) echo ${UNAME_MACHINE}-pc-cygwin exit ;; + *:MINGW64*:*) + echo ${UNAME_MACHINE}-pc-mingw64 + exit ;; *:MINGW*:*) echo ${UNAME_MACHINE}-pc-mingw32 exit ;; + i*:MSYS*:*) + echo ${UNAME_MACHINE}-pc-msys + exit ;; i*:windows32*:*) - # uname -m includes "-pc" on this system. - echo ${UNAME_MACHINE}-mingw32 + # uname -m includes "-pc" on this system. + echo ${UNAME_MACHINE}-mingw32 exit ;; i*:PW*:*) echo ${UNAME_MACHINE}-pc-pw32 exit ;; - *:Interix*:[3456]*) - case ${UNAME_MACHINE} in + *:Interix*:*) + case ${UNAME_MACHINE} in x86) echo i586-pc-interix${UNAME_RELEASE} exit ;; - EM64T | authenticamd | genuineintel) + authenticamd | genuineintel | EM64T) echo x86_64-unknown-interix${UNAME_RELEASE} exit ;; IA64) @@ -845,45 +874,81 @@ EOF exit ;; *:GNU:*:*) # the GNU system - echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` + echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-${LIBC}`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` exit ;; *:GNU/*:*:*) # other systems with GNU libc and userland - echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-gnu + echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-${LIBC} exit ;; i*86:Minix:*:*) echo ${UNAME_MACHINE}-pc-minix exit ;; + aarch64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + aarch64_be:Linux:*:*) + UNAME_MACHINE=aarch64_be + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + alpha:Linux:*:*) + case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in + EV5) UNAME_MACHINE=alphaev5 ;; + EV56) UNAME_MACHINE=alphaev56 ;; + PCA56) UNAME_MACHINE=alphapca56 ;; + PCA57) UNAME_MACHINE=alphapca56 ;; + EV6) UNAME_MACHINE=alphaev6 ;; + EV67) UNAME_MACHINE=alphaev67 ;; + EV68*) UNAME_MACHINE=alphaev68 ;; + esac + objdump --private-headers /bin/sh | grep -q ld.so.1 + if test "$?" = 0 ; then LIBC="gnulibc1" ; fi + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + arc:Linux:*:* | arceb:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; arm*:Linux:*:*) eval $set_cc_for_build if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ARM_EABI__ then - echo ${UNAME_MACHINE}-unknown-linux-gnu + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} else - echo ${UNAME_MACHINE}-unknown-linux-gnueabi + if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep -q __ARM_PCS_VFP + then + echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabi + else + echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabihf + fi fi exit ;; avr32*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; cris:Linux:*:*) - echo cris-axis-linux-gnu + echo ${UNAME_MACHINE}-axis-linux-${LIBC} exit ;; crisv32:Linux:*:*) - echo crisv32-axis-linux-gnu + echo ${UNAME_MACHINE}-axis-linux-${LIBC} exit ;; frv:Linux:*:*) - echo frv-unknown-linux-gnu + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + hexagon:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + i*86:Linux:*:*) + echo ${UNAME_MACHINE}-pc-linux-${LIBC} exit ;; ia64:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; m32r*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; m68*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; mips:Linux:*:* | mips64:Linux:*:*) eval $set_cc_for_build @@ -901,123 +966,65 @@ EOF #endif #endif EOF - eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n ' - /^CPU/{ - s: ::g - p - }'`" - test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; } + eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'` + test x"${CPU}" != x && { echo "${CPU}-unknown-linux-${LIBC}"; exit; } ;; - or32:Linux:*:*) - echo or32-unknown-linux-gnu - exit ;; - ppc:Linux:*:*) - echo powerpc-unknown-linux-gnu - exit ;; - ppc64:Linux:*:*) - echo powerpc64-unknown-linux-gnu + or1k:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; - alpha:Linux:*:*) - case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in - EV5) UNAME_MACHINE=alphaev5 ;; - EV56) UNAME_MACHINE=alphaev56 ;; - PCA56) UNAME_MACHINE=alphapca56 ;; - PCA57) UNAME_MACHINE=alphapca56 ;; - EV6) UNAME_MACHINE=alphaev6 ;; - EV67) UNAME_MACHINE=alphaev67 ;; - EV68*) UNAME_MACHINE=alphaev68 ;; - esac - objdump --private-headers /bin/sh | grep -q ld.so.1 - if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi - echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} + or32:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; padre:Linux:*:*) - echo sparc-unknown-linux-gnu + echo sparc-unknown-linux-${LIBC} + exit ;; + parisc64:Linux:*:* | hppa64:Linux:*:*) + echo hppa64-unknown-linux-${LIBC} exit ;; parisc:Linux:*:* | hppa:Linux:*:*) # Look for CPU level case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in - PA7*) echo hppa1.1-unknown-linux-gnu ;; - PA8*) echo hppa2.0-unknown-linux-gnu ;; - *) echo hppa-unknown-linux-gnu ;; + PA7*) echo hppa1.1-unknown-linux-${LIBC} ;; + PA8*) echo hppa2.0-unknown-linux-${LIBC} ;; + *) echo hppa-unknown-linux-${LIBC} ;; esac exit ;; - parisc64:Linux:*:* | hppa64:Linux:*:*) - echo hppa64-unknown-linux-gnu + ppc64:Linux:*:*) + echo powerpc64-unknown-linux-${LIBC} + exit ;; + ppc:Linux:*:*) + echo powerpc-unknown-linux-${LIBC} + exit ;; + ppc64le:Linux:*:*) + echo powerpc64le-unknown-linux-${LIBC} + exit ;; + ppcle:Linux:*:*) + echo powerpcle-unknown-linux-${LIBC} exit ;; s390:Linux:*:* | s390x:Linux:*:*) - echo ${UNAME_MACHINE}-ibm-linux + echo ${UNAME_MACHINE}-ibm-linux-${LIBC} exit ;; sh64*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; sh*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; sparc:Linux:*:* | sparc64:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + tile*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; vax:Linux:*:*) - echo ${UNAME_MACHINE}-dec-linux-gnu + echo ${UNAME_MACHINE}-dec-linux-${LIBC} exit ;; x86_64:Linux:*:*) - echo x86_64-unknown-linux-gnu + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; xtensa*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; - i*86:Linux:*:*) - # The BFD linker knows what the default object file format is, so - # first see if it will tell us. cd to the root directory to prevent - # problems with other programs or directories called `ld' in the path. - # Set LC_ALL=C to ensure ld outputs messages in English. - ld_supported_targets=`cd /; LC_ALL=C ld --help 2>&1 \ - | sed -ne '/supported targets:/!d - s/[ ][ ]*/ /g - s/.*supported targets: *// - s/ .*// - p'` - case "$ld_supported_targets" in - elf32-i386) - TENTATIVE="${UNAME_MACHINE}-pc-linux-gnu" - ;; - esac - # Determine whether the default compiler is a.out or elf - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c - #include - #ifdef __ELF__ - # ifdef __GLIBC__ - # if __GLIBC__ >= 2 - LIBC=gnu - # else - LIBC=gnulibc1 - # endif - # else - LIBC=gnulibc1 - # endif - #else - #if defined(__INTEL_COMPILER) || defined(__PGI) || defined(__SUNPRO_C) || defined(__SUNPRO_CC) - LIBC=gnu - #else - LIBC=gnuaout - #endif - #endif - #ifdef __dietlibc__ - LIBC=dietlibc - #endif -EOF - eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n ' - /^LIBC/{ - s: ::g - p - }'`" - test x"${LIBC}" != x && { - echo "${UNAME_MACHINE}-pc-linux-${LIBC}" - exit - } - test x"${TENTATIVE}" != x && { echo "${TENTATIVE}"; exit; } - ;; i*86:DYNIX/ptx:4*:*) # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. # earlier versions are messed up and put the nodename in both @@ -1025,11 +1032,11 @@ EOF echo i386-sequent-sysv4 exit ;; i*86:UNIX_SV:4.2MP:2.*) - # Unixware is an offshoot of SVR4, but it has its own version - # number series starting with 2... - # I am not positive that other SVR4 systems won't match this, + # Unixware is an offshoot of SVR4, but it has its own version + # number series starting with 2... + # I am not positive that other SVR4 systems won't match this, # I just have to hope. -- rms. - # Use sysv4.2uw... so that sysv4* matches it. + # Use sysv4.2uw... so that sysv4* matches it. echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} exit ;; i*86:OS/2:*:*) @@ -1061,7 +1068,7 @@ EOF fi exit ;; i*86:*:5:[678]*) - # UnixWare 7.x, OpenUNIX and OpenServer 6. + # UnixWare 7.x, OpenUNIX and OpenServer 6. case `/bin/uname -X | grep "^Machine"` in *486*) UNAME_MACHINE=i486 ;; *Pentium) UNAME_MACHINE=i586 ;; @@ -1089,13 +1096,13 @@ EOF exit ;; pc:*:*:*) # Left here for compatibility: - # uname -m prints for DJGPP always 'pc', but it prints nothing about - # the processor, so we play safe by assuming i586. + # uname -m prints for DJGPP always 'pc', but it prints nothing about + # the processor, so we play safe by assuming i586. # Note: whatever this is, it MUST be the same as what config.sub # prints for the "djgpp" host, or else GDB configury will decide that # this is a cross-build. echo i586-pc-msdosdjgpp - exit ;; + exit ;; Intel:Mach:3*:*) echo i386-pc-mach3 exit ;; @@ -1130,8 +1137,8 @@ EOF /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) - /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ - && { echo i486-ncr-sysv4; exit; } ;; + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && { echo i486-ncr-sysv4; exit; } ;; NCR*:*:4.2:* | MPRAS*:*:4.2:*) OS_REL='.3' test -r /etc/.relid \ @@ -1174,10 +1181,10 @@ EOF echo ns32k-sni-sysv fi exit ;; - PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort - # says - echo i586-unisys-sysv4 - exit ;; + PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort + # says + echo i586-unisys-sysv4 + exit ;; *:UNIX_System_V:4*:FTX*) # From Gerald Hewes . # How about differentiating between stratus architectures? -djm @@ -1203,11 +1210,11 @@ EOF exit ;; R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) if [ -d /usr/nec ]; then - echo mips-nec-sysv${UNAME_RELEASE} + echo mips-nec-sysv${UNAME_RELEASE} else - echo mips-unknown-sysv${UNAME_RELEASE} + echo mips-unknown-sysv${UNAME_RELEASE} fi - exit ;; + exit ;; BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. echo powerpc-be-beos exit ;; @@ -1220,6 +1227,9 @@ EOF BePC:Haiku:*:*) # Haiku running on Intel PC compatible. echo i586-pc-haiku exit ;; + x86_64:Haiku:*:*) + echo x86_64-unknown-haiku + exit ;; SX-4:SUPER-UX:*:*) echo sx4-nec-superux${UNAME_RELEASE} exit ;; @@ -1246,13 +1256,31 @@ EOF exit ;; *:Darwin:*:*) UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown - case $UNAME_PROCESSOR in - i386) eval $set_cc_for_build - if $CC_FOR_BUILD -E -dM -x c /dev/null | grep __LP64__>/dev/null 2>&1 ; then - UNAME_PROCESSOR=x86_64 - fi ;; - unknown) UNAME_PROCESSOR=powerpc ;; - esac + eval $set_cc_for_build + if test "$UNAME_PROCESSOR" = unknown ; then + UNAME_PROCESSOR=powerpc + fi + if test `echo "$UNAME_RELEASE" | sed -e 's/\..*//'` -le 10 ; then + if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then + if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \ + (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ + grep IS_64BIT_ARCH >/dev/null + then + case $UNAME_PROCESSOR in + i386) UNAME_PROCESSOR=x86_64 ;; + powerpc) UNAME_PROCESSOR=powerpc64 ;; + esac + fi + fi + elif test "$UNAME_PROCESSOR" = i386 ; then + # Avoid executing cc on OS X 10.9, as it ships with a stub + # that puts up a graphical alert prompting to install + # developer tools. Any system running Mac OS X 10.7 or + # later (Darwin 11 and later) is required to have a 64-bit + # processor. This is not true of the ARM version of Darwin + # that Apple uses in portable devices. + UNAME_PROCESSOR=x86_64 + fi echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE} exit ;; *:procnto*:*:* | *:QNX:[0123456789]*:*) @@ -1266,7 +1294,10 @@ EOF *:QNX:*:4*) echo i386-pc-qnx exit ;; - NSE-?:NONSTOP_KERNEL:*:*) + NEO-?:NONSTOP_KERNEL:*:*) + echo neo-tandem-nsk${UNAME_RELEASE} + exit ;; + NSE-*:NONSTOP_KERNEL:*:*) echo nse-tandem-nsk${UNAME_RELEASE} exit ;; NSR-?:NONSTOP_KERNEL:*:*) @@ -1311,13 +1342,13 @@ EOF echo pdp10-unknown-its exit ;; SEI:*:*:SEIUX) - echo mips-sei-seiux${UNAME_RELEASE} + echo mips-sei-seiux${UNAME_RELEASE} exit ;; *:DragonFly:*:*) echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` exit ;; *:*VMS:*:*) - UNAME_MACHINE=`(uname -p) 2>/dev/null` + UNAME_MACHINE=`(uname -p) 2>/dev/null` case "${UNAME_MACHINE}" in A*) echo alpha-dec-vms ; exit ;; I*) echo ia64-dec-vms ; exit ;; @@ -1335,158 +1366,10 @@ EOF i*86:AROS:*:*) echo ${UNAME_MACHINE}-pc-aros exit ;; -esac - -#echo '(No uname command or uname output not recognized.)' 1>&2 -#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2 - -eval $set_cc_for_build -cat >$dummy.c < -# include -#endif -main () -{ -#if defined (sony) -#if defined (MIPSEB) - /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed, - I don't know.... */ - printf ("mips-sony-bsd\n"); exit (0); -#else -#include - printf ("m68k-sony-newsos%s\n", -#ifdef NEWSOS4 - "4" -#else - "" -#endif - ); exit (0); -#endif -#endif - -#if defined (__arm) && defined (__acorn) && defined (__unix) - printf ("arm-acorn-riscix\n"); exit (0); -#endif - -#if defined (hp300) && !defined (hpux) - printf ("m68k-hp-bsd\n"); exit (0); -#endif - -#if defined (NeXT) -#if !defined (__ARCHITECTURE__) -#define __ARCHITECTURE__ "m68k" -#endif - int version; - version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`; - if (version < 4) - printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); - else - printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version); - exit (0); -#endif - -#if defined (MULTIMAX) || defined (n16) -#if defined (UMAXV) - printf ("ns32k-encore-sysv\n"); exit (0); -#else -#if defined (CMU) - printf ("ns32k-encore-mach\n"); exit (0); -#else - printf ("ns32k-encore-bsd\n"); exit (0); -#endif -#endif -#endif - -#if defined (__386BSD__) - printf ("i386-pc-bsd\n"); exit (0); -#endif - -#if defined (sequent) -#if defined (i386) - printf ("i386-sequent-dynix\n"); exit (0); -#endif -#if defined (ns32000) - printf ("ns32k-sequent-dynix\n"); exit (0); -#endif -#endif - -#if defined (_SEQUENT_) - struct utsname un; - - uname(&un); - - if (strncmp(un.version, "V2", 2) == 0) { - printf ("i386-sequent-ptx2\n"); exit (0); - } - if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */ - printf ("i386-sequent-ptx1\n"); exit (0); - } - printf ("i386-sequent-ptx\n"); exit (0); - -#endif - -#if defined (vax) -# if !defined (ultrix) -# include -# if defined (BSD) -# if BSD == 43 - printf ("vax-dec-bsd4.3\n"); exit (0); -# else -# if BSD == 199006 - printf ("vax-dec-bsd4.3reno\n"); exit (0); -# else - printf ("vax-dec-bsd\n"); exit (0); -# endif -# endif -# else - printf ("vax-dec-bsd\n"); exit (0); -# endif -# else - printf ("vax-dec-ultrix\n"); exit (0); -# endif -#endif - -#if defined (alliant) && defined (i860) - printf ("i860-alliant-bsd\n"); exit (0); -#endif - - exit (1); -} -EOF - -$CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && SYSTEM_NAME=`$dummy` && - { echo "$SYSTEM_NAME"; exit; } - -# Apollos put the system type in the environment. - -test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit; } - -# Convex versions that predate uname can use getsysinfo(1) - -if [ -x /usr/convex/getsysinfo ] -then - case `getsysinfo -f cpu_type` in - c1*) - echo c1-convex-bsd + x86_64:VMkernel:*:*) + echo ${UNAME_MACHINE}-unknown-esx exit ;; - c2*) - if getsysinfo -f scalar_acc - then echo c32-convex-bsd - else echo c2-convex-bsd - fi - exit ;; - c34*) - echo c34-convex-bsd - exit ;; - c38*) - echo c38-convex-bsd - exit ;; - c4*) - echo c4-convex-bsd - exit ;; - esac -fi +esac cat >&2 <. # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under -# the same distribution terms that you use for the rest of that program. +# the same distribution terms that you use for the rest of that +# program. This Exception is an additional permission under section 7 +# of the GNU General Public License, version 3 ("GPLv3"). -# Please send patches to . Submit a context -# diff and a properly formatted GNU ChangeLog entry. +# Please send patches with a ChangeLog entry to config-patches@gnu.org. # # Configuration subroutine to validate and canonicalize a configuration type. # Supply the specified configuration type as an argument. @@ -75,8 +68,7 @@ Report bugs and patches to 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*) Index: mozilla-release/js/src/ctypes/libffi/configure =================================================================== --- mozilla-release.orig/js/src/ctypes/libffi/configure +++ mozilla-release/js/src/ctypes/libffi/configure @@ -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*) Index: mozilla-release/js/src/ctypes/libffi/m4/libtool.m4 =================================================================== --- mozilla-release.orig/js/src/ctypes/libffi/m4/libtool.m4 +++ mozilla-release/js/src/ctypes/libffi/m4/libtool.m4 @@ -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*) Index: mozilla-release/js/src/ctypes/libffi/src/powerpc/ffi.c =================================================================== --- mozilla-release.orig/js/src/ctypes/libffi/src/powerpc/ffi.c +++ mozilla-release/js/src/ctypes/libffi/src/powerpc/ffi.c @@ -1,7 +1,9 @@ /* ----------------------------------------------------------------------- - ffi.c - Copyright (c) 1998 Geoffrey Keating - Copyright (C) 2007, 2008 Free Software Foundation, Inc - Copyright (C) 2008 Red Hat, Inc + ffi.c - Copyright (C) 2011 Anthony Green + Copyright (C) 2011 Kyle Moffett + Copyright (C) 2008 Red Hat, Inc + Copyright (C) 2007, 2008 Free Software Foundation, Inc + Copyright (c) 1998 Geoffrey Keating PowerPC Foreign Function Interface @@ -39,32 +41,29 @@ enum { /* The assembly depends on these exact flags. */ FLAG_RETURNS_SMST = 1 << (31-31), /* Used for FFI_SYSV small structs. */ FLAG_RETURNS_NOTHING = 1 << (31-30), /* These go in cr7 */ +#ifndef __NO_FPRS__ FLAG_RETURNS_FP = 1 << (31-29), +#endif FLAG_RETURNS_64BITS = 1 << (31-28), FLAG_RETURNS_128BITS = 1 << (31-27), /* cr6 */ - FLAG_SYSV_SMST_R4 = 1 << (31-26), /* use r4 for FFI_SYSV 8 byte - structs. */ - FLAG_SYSV_SMST_R3 = 1 << (31-25), /* use r3 for FFI_SYSV 4 byte - structs. */ - /* Bits (31-24) through (31-19) store shift value for SMST */ FLAG_ARG_NEEDS_COPY = 1 << (31- 7), + FLAG_ARG_NEEDS_PSAVE = FLAG_ARG_NEEDS_COPY, /* Used by ELFv2 */ +#ifndef __NO_FPRS__ FLAG_FP_ARGUMENTS = 1 << (31- 6), /* cr1.eq; specified by ABI */ +#endif FLAG_4_GPR_ARGUMENTS = 1 << (31- 5), FLAG_RETVAL_REFERENCE = 1 << (31- 4) }; /* About the SYSV ABI. */ -unsigned int NUM_GPR_ARG_REGISTERS = 8; +#define ASM_NEEDS_REGISTERS 4 +#define NUM_GPR_ARG_REGISTERS 8 #ifndef __NO_FPRS__ -unsigned int NUM_FPR_ARG_REGISTERS = 8; -#else -unsigned int NUM_FPR_ARG_REGISTERS = 0; +# define NUM_FPR_ARG_REGISTERS 8 #endif -enum { ASM_NEEDS_REGISTERS = 4 }; - /* ffi_prep_args_SYSV is called by the assembly routine once stack space has been allocated for the function's arguments. @@ -113,10 +112,12 @@ ffi_prep_args_SYSV (extended_cif *ecif, valp gpr_base; int intarg_count; +#ifndef __NO_FPRS__ /* 'fpr_base' points at the space for fpr1, and grows upwards as we use FPR registers. */ valp fpr_base; int fparg_count; +#endif /* 'copy_space' grows down as we put structures in it. It should stay 16-byte aligned. */ @@ -125,9 +126,11 @@ ffi_prep_args_SYSV (extended_cif *ecif, /* 'next_arg' grows up as we put parameters in it. */ valp next_arg; - int i, ii MAYBE_UNUSED; + int i; ffi_type **ptr; +#ifndef __NO_FPRS__ double double_tmp; +#endif union { void **v; char **c; @@ -143,21 +146,22 @@ ffi_prep_args_SYSV (extended_cif *ecif, size_t struct_copy_size; unsigned gprvalue; - if (ecif->cif->abi == FFI_LINUX_SOFT_FLOAT) - NUM_FPR_ARG_REGISTERS = 0; - stacktop.c = (char *) stack + bytes; gpr_base.u = stacktop.u - ASM_NEEDS_REGISTERS - NUM_GPR_ARG_REGISTERS; intarg_count = 0; +#ifndef __NO_FPRS__ fpr_base.d = gpr_base.d - NUM_FPR_ARG_REGISTERS; fparg_count = 0; copy_space.c = ((flags & FLAG_FP_ARGUMENTS) ? fpr_base.c : gpr_base.c); +#else + copy_space.c = gpr_base.c; +#endif next_arg.u = stack + 2; /* Check that everything starts aligned properly. */ - FFI_ASSERT (((unsigned) (char *) stack & 0xF) == 0); - FFI_ASSERT (((unsigned) copy_space.c & 0xF) == 0); - FFI_ASSERT (((unsigned) stacktop.c & 0xF) == 0); + FFI_ASSERT (((unsigned long) (char *) stack & 0xF) == 0); + FFI_ASSERT (((unsigned long) copy_space.c & 0xF) == 0); + FFI_ASSERT (((unsigned long) stacktop.c & 0xF) == 0); FFI_ASSERT ((bytes & 0xF) == 0); FFI_ASSERT (copy_space.c >= next_arg.c); @@ -174,12 +178,28 @@ ffi_prep_args_SYSV (extended_cif *ecif, i > 0; i--, ptr++, p_argv.v++) { - switch ((*ptr)->type) - { + unsigned short typenum = (*ptr)->type; + + /* We may need to handle some values depending on ABI */ + if (ecif->cif->abi == FFI_LINUX_SOFT_FLOAT) { + if (typenum == FFI_TYPE_FLOAT) + typenum = FFI_TYPE_UINT32; + if (typenum == FFI_TYPE_DOUBLE) + typenum = FFI_TYPE_UINT64; + if (typenum == FFI_TYPE_LONGDOUBLE) + typenum = FFI_TYPE_UINT128; + } else if (ecif->cif->abi != FFI_LINUX) { +#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE + if (typenum == FFI_TYPE_LONGDOUBLE) + typenum = FFI_TYPE_STRUCT; +#endif + } + + /* Now test the translated value */ + switch (typenum) { +#ifndef __NO_FPRS__ case FFI_TYPE_FLOAT: /* With FFI_LINUX_SOFT_FLOAT floats are handled like UINT32. */ - if (ecif->cif->abi == FFI_LINUX_SOFT_FLOAT) - goto soft_float_prep; double_tmp = **p_argv.f; if (fparg_count >= NUM_FPR_ARG_REGISTERS) { @@ -195,8 +215,6 @@ ffi_prep_args_SYSV (extended_cif *ecif, case FFI_TYPE_DOUBLE: /* With FFI_LINUX_SOFT_FLOAT doubles are handled like UINT64. */ - if (ecif->cif->abi == FFI_LINUX_SOFT_FLOAT) - goto soft_double_prep; double_tmp = **p_argv.d; if (fparg_count >= NUM_FPR_ARG_REGISTERS) @@ -218,43 +236,6 @@ ffi_prep_args_SYSV (extended_cif *ecif, #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE case FFI_TYPE_LONGDOUBLE: - if ((ecif->cif->abi != FFI_LINUX) - && (ecif->cif->abi != FFI_LINUX_SOFT_FLOAT)) - goto do_struct; - /* The soft float ABI for long doubles works like this, - a long double is passed in four consecutive gprs if available. - A maximum of 2 long doubles can be passed in gprs. - If we do not have 4 gprs left, the long double is passed on the - stack, 4-byte aligned. */ - if (ecif->cif->abi == FFI_LINUX_SOFT_FLOAT) - { - unsigned int int_tmp = (*p_argv.ui)[0]; - if (intarg_count >= NUM_GPR_ARG_REGISTERS - 3) - { - if (intarg_count < NUM_GPR_ARG_REGISTERS) - intarg_count += NUM_GPR_ARG_REGISTERS - intarg_count; - *next_arg.u = int_tmp; - next_arg.u++; - for (ii = 1; ii < 4; ii++) - { - int_tmp = (*p_argv.ui)[ii]; - *next_arg.u = int_tmp; - next_arg.u++; - } - } - else - { - *gpr_base.u++ = int_tmp; - for (ii = 1; ii < 4; ii++) - { - int_tmp = (*p_argv.ui)[ii]; - *gpr_base.u++ = int_tmp; - } - } - intarg_count +=4; - } - else - { double_tmp = (*p_argv.d)[0]; if (fparg_count >= NUM_FPR_ARG_REGISTERS - 1) @@ -280,13 +261,40 @@ ffi_prep_args_SYSV (extended_cif *ecif, fparg_count += 2; FFI_ASSERT (flags & FLAG_FP_ARGUMENTS); - } break; #endif +#endif /* have FPRs */ + + /* + * The soft float ABI for long doubles works like this, a long double + * is passed in four consecutive GPRs if available. A maximum of 2 + * long doubles can be passed in gprs. If we do not have 4 GPRs + * left, the long double is passed on the stack, 4-byte aligned. + */ + case FFI_TYPE_UINT128: { + unsigned int int_tmp = (*p_argv.ui)[0]; + unsigned int ii; + if (intarg_count >= NUM_GPR_ARG_REGISTERS - 3) { + if (intarg_count < NUM_GPR_ARG_REGISTERS) + intarg_count += NUM_GPR_ARG_REGISTERS - intarg_count; + *(next_arg.u++) = int_tmp; + for (ii = 1; ii < 4; ii++) { + int_tmp = (*p_argv.ui)[ii]; + *(next_arg.u++) = int_tmp; + } + } else { + *(gpr_base.u++) = int_tmp; + for (ii = 1; ii < 4; ii++) { + int_tmp = (*p_argv.ui)[ii]; + *(gpr_base.u++) = int_tmp; + } + } + intarg_count += 4; + break; + } case FFI_TYPE_UINT64: case FFI_TYPE_SINT64: - soft_double_prep: if (intarg_count == NUM_GPR_ARG_REGISTERS-1) intarg_count++; if (intarg_count >= NUM_GPR_ARG_REGISTERS) @@ -319,9 +327,6 @@ ffi_prep_args_SYSV (extended_cif *ecif, break; case FFI_TYPE_STRUCT: -#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE - do_struct: -#endif struct_copy_size = ((*ptr)->size + 15) & ~0xF; copy_space.c -= struct_copy_size; memcpy (copy_space.c, *p_argv.c, (*ptr)->size); @@ -349,7 +354,6 @@ ffi_prep_args_SYSV (extended_cif *ecif, case FFI_TYPE_UINT32: case FFI_TYPE_SINT32: case FFI_TYPE_POINTER: - soft_float_prep: gprvalue = **p_argv.ui; @@ -366,8 +370,16 @@ ffi_prep_args_SYSV (extended_cif *ecif, /* Check that we didn't overrun the stack... */ FFI_ASSERT (copy_space.c >= next_arg.c); FFI_ASSERT (gpr_base.u <= stacktop.u - ASM_NEEDS_REGISTERS); + /* The assert below is testing that the number of integer arguments agrees + with the number found in ffi_prep_cif_machdep(). However, intarg_count + is incremented whenever we place an FP arg on the stack, so account for + that before our assert test. */ +#ifndef __NO_FPRS__ + if (fparg_count > NUM_FPR_ARG_REGISTERS) + intarg_count -= fparg_count - NUM_FPR_ARG_REGISTERS; FFI_ASSERT (fpr_base.u <= stacktop.u - ASM_NEEDS_REGISTERS - NUM_GPR_ARG_REGISTERS); +#endif FFI_ASSERT (flags & FLAG_4_GPR_ARGUMENTS || intarg_count <= 4); } @@ -378,6 +390,45 @@ enum { }; enum { ASM_NEEDS_REGISTERS64 = 4 }; +#if _CALL_ELF == 2 +static unsigned int +discover_homogeneous_aggregate (const ffi_type *t, unsigned int *elnum) +{ + switch (t->type) + { + case FFI_TYPE_FLOAT: + case FFI_TYPE_DOUBLE: + *elnum = 1; + return (int) t->type; + + case FFI_TYPE_STRUCT:; + { + unsigned int base_elt = 0, total_elnum = 0; + ffi_type **el = t->elements; + while (*el) + { + unsigned int el_elt, el_elnum = 0; + el_elt = discover_homogeneous_aggregate (*el, &el_elnum); + if (el_elt == 0 + || (base_elt && base_elt != el_elt)) + return 0; + base_elt = el_elt; + total_elnum += el_elnum; + if (total_elnum > 8) + return 0; + el++; + } + *elnum = total_elnum; + return base_elt; + } + + default: + return 0; + } +} +#endif + + /* ffi_prep_args64 is called by the assembly routine once stack space has been allocated for the function's arguments. @@ -423,6 +474,7 @@ ffi_prep_args64 (extended_cif *ecif, uns unsigned long *ul; float *f; double *d; + size_t p; } valp; /* 'stacktop' points at the previous backchain pointer. */ @@ -438,9 +490,9 @@ ffi_prep_args64 (extended_cif *ecif, uns /* 'fpr_base' points at the space for fpr3, and grows upwards as we use FPR registers. */ valp fpr_base; - int fparg_count; + unsigned int fparg_count; - int i, words; + unsigned int i, words, nargs, nfixedargs; ffi_type **ptr; double double_tmp; union { @@ -457,11 +509,18 @@ ffi_prep_args64 (extended_cif *ecif, uns double **d; } p_argv; unsigned long gprvalue; +#ifdef __STRUCT_PARM_ALIGN__ + unsigned long align; +#endif stacktop.c = (char *) stack + bytes; gpr_base.ul = stacktop.ul - ASM_NEEDS_REGISTERS64 - NUM_GPR_ARG_REGISTERS64; gpr_end.ul = gpr_base.ul + NUM_GPR_ARG_REGISTERS64; +#if _CALL_ELF == 2 + rest.ul = stack + 4 + NUM_GPR_ARG_REGISTERS64; +#else rest.ul = stack + 6 + NUM_GPR_ARG_REGISTERS64; +#endif fpr_base.d = gpr_base.d - NUM_FPR_ARG_REGISTERS64; fparg_count = 0; next_arg.ul = gpr_base.ul; @@ -477,30 +536,36 @@ ffi_prep_args64 (extended_cif *ecif, uns /* Now for the arguments. */ p_argv.v = ecif->avalue; - for (ptr = ecif->cif->arg_types, i = ecif->cif->nargs; - i > 0; - i--, ptr++, p_argv.v++) + nargs = ecif->cif->nargs; + nfixedargs = ecif->cif->nfixedargs; + for (ptr = ecif->cif->arg_types, i = 0; + i < nargs; + i++, ptr++, p_argv.v++) { + unsigned int elt, elnum; + switch ((*ptr)->type) { case FFI_TYPE_FLOAT: double_tmp = **p_argv.f; - *next_arg.f = (float) double_tmp; + if (fparg_count < NUM_FPR_ARG_REGISTERS64 && i < nfixedargs) + *fpr_base.d++ = double_tmp; + else + *next_arg.f = (float) double_tmp; if (++next_arg.ul == gpr_end.ul) next_arg.ul = rest.ul; - if (fparg_count < NUM_FPR_ARG_REGISTERS64) - *fpr_base.d++ = double_tmp; fparg_count++; FFI_ASSERT (flags & FLAG_FP_ARGUMENTS); break; case FFI_TYPE_DOUBLE: double_tmp = **p_argv.d; - *next_arg.d = double_tmp; + if (fparg_count < NUM_FPR_ARG_REGISTERS64 && i < nfixedargs) + *fpr_base.d++ = double_tmp; + else + *next_arg.d = double_tmp; if (++next_arg.ul == gpr_end.ul) next_arg.ul = rest.ul; - if (fparg_count < NUM_FPR_ARG_REGISTERS64) - *fpr_base.d++ = double_tmp; fparg_count++; FFI_ASSERT (flags & FLAG_FP_ARGUMENTS); break; @@ -508,18 +573,20 @@ ffi_prep_args64 (extended_cif *ecif, uns #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE case FFI_TYPE_LONGDOUBLE: double_tmp = (*p_argv.d)[0]; - *next_arg.d = double_tmp; + if (fparg_count < NUM_FPR_ARG_REGISTERS64 && i < nfixedargs) + *fpr_base.d++ = double_tmp; + else + *next_arg.d = double_tmp; if (++next_arg.ul == gpr_end.ul) next_arg.ul = rest.ul; - if (fparg_count < NUM_FPR_ARG_REGISTERS64) - *fpr_base.d++ = double_tmp; fparg_count++; double_tmp = (*p_argv.d)[1]; - *next_arg.d = double_tmp; + if (fparg_count < NUM_FPR_ARG_REGISTERS64 && i < nfixedargs) + *fpr_base.d++ = double_tmp; + else + *next_arg.d = double_tmp; if (++next_arg.ul == gpr_end.ul) next_arg.ul = rest.ul; - if (fparg_count < NUM_FPR_ARG_REGISTERS64) - *fpr_base.d++ = double_tmp; fparg_count++; FFI_ASSERT (__LDBL_MANT_DIG__ == 106); FFI_ASSERT (flags & FLAG_FP_ARGUMENTS); @@ -527,27 +594,86 @@ ffi_prep_args64 (extended_cif *ecif, uns #endif case FFI_TYPE_STRUCT: - words = ((*ptr)->size + 7) / 8; - if (next_arg.ul >= gpr_base.ul && next_arg.ul + words > gpr_end.ul) +#ifdef __STRUCT_PARM_ALIGN__ + align = (*ptr)->alignment; + if (align > __STRUCT_PARM_ALIGN__) + align = __STRUCT_PARM_ALIGN__; + if (align > 1) + next_arg.p = ALIGN (next_arg.p, align); +#endif + elt = 0; +#if _CALL_ELF == 2 + elt = discover_homogeneous_aggregate (*ptr, &elnum); +#endif + if (elt) { - size_t first = gpr_end.c - next_arg.c; - memcpy (next_arg.c, *p_argv.c, first); - memcpy (rest.c, *p_argv.c + first, (*ptr)->size - first); - next_arg.c = rest.c + words * 8 - first; + union { + void *v; + float *f; + double *d; + } arg; + + arg.v = *p_argv.v; + if (elt == FFI_TYPE_FLOAT) + { + do + { + double_tmp = *arg.f++; + if (fparg_count < NUM_FPR_ARG_REGISTERS64 + && i < nfixedargs) + *fpr_base.d++ = double_tmp; + else + *next_arg.f = (float) double_tmp; + if (++next_arg.f == gpr_end.f) + next_arg.f = rest.f; + fparg_count++; + } + while (--elnum != 0); + if ((next_arg.p & 3) != 0) + { + if (++next_arg.f == gpr_end.f) + next_arg.f = rest.f; + } + } + else + do + { + double_tmp = *arg.d++; + if (fparg_count < NUM_FPR_ARG_REGISTERS64 && i < nfixedargs) + *fpr_base.d++ = double_tmp; + else + *next_arg.d = double_tmp; + if (++next_arg.d == gpr_end.d) + next_arg.d = rest.d; + fparg_count++; + } + while (--elnum != 0); } else { - char *where = next_arg.c; - - /* Structures with size less than eight bytes are passed - left-padded. */ - if ((*ptr)->size < 8) - where += 8 - (*ptr)->size; + words = ((*ptr)->size + 7) / 8; + if (next_arg.ul >= gpr_base.ul && next_arg.ul + words > gpr_end.ul) + { + size_t first = gpr_end.c - next_arg.c; + memcpy (next_arg.c, *p_argv.c, first); + memcpy (rest.c, *p_argv.c + first, (*ptr)->size - first); + next_arg.c = rest.c + words * 8 - first; + } + else + { + char *where = next_arg.c; - memcpy (where, *p_argv.c, (*ptr)->size); - next_arg.ul += words; - if (next_arg.ul == gpr_end.ul) - next_arg.ul = rest.ul; +#ifndef __LITTLE_ENDIAN__ + /* Structures with size less than eight bytes are passed + left-padded. */ + if ((*ptr)->size < 8) + where += 8 - (*ptr)->size; +#endif + memcpy (where, *p_argv.c, (*ptr)->size); + next_arg.ul += words; + if (next_arg.ul == gpr_end.ul) + next_arg.ul = rest.ul; + } } break; @@ -591,27 +717,22 @@ ffi_prep_args64 (extended_cif *ecif, uns /* Perform machine dependent cif processing */ -ffi_status -ffi_prep_cif_machdep (ffi_cif *cif) +static ffi_status +ffi_prep_cif_machdep_core (ffi_cif *cif) { /* All this is for the SYSV and LINUX64 ABI. */ - int i; ffi_type **ptr; unsigned bytes; - int fparg_count = 0, intarg_count = 0; - unsigned flags = 0; + unsigned i, fparg_count = 0, intarg_count = 0; + unsigned flags = cif->flags; unsigned struct_copy_size = 0; unsigned type = cif->rtype->type; unsigned size = cif->rtype->size; - if (cif->abi == FFI_LINUX_SOFT_FLOAT) - NUM_FPR_ARG_REGISTERS = 0; - + /* The machine-independent calculation of cif->bytes doesn't work + for us. Redo the calculation. */ if (cif->abi != FFI_LINUX64) { - /* All the machine-independent calculation of cif->bytes will be wrong. - Redo the calculation for SYSV. */ - /* Space for the frame pointer, callee's LR, and the asm's temp regs. */ bytes = (2 + ASM_NEEDS_REGISTERS) * sizeof (int); @@ -621,13 +742,20 @@ ffi_prep_cif_machdep (ffi_cif *cif) else { /* 64-bit ABI. */ +#if _CALL_ELF == 2 + /* Space for backchain, CR, LR, TOC and the asm's temp regs. */ + bytes = (4 + ASM_NEEDS_REGISTERS64) * sizeof (long); + /* Space for the general registers. */ + bytes += NUM_GPR_ARG_REGISTERS64 * sizeof (long); +#else /* Space for backchain, CR, LR, cc/ld doubleword, TOC and the asm's temp regs. */ bytes = (6 + ASM_NEEDS_REGISTERS64) * sizeof (long); /* Space for the mandatory parm save area and general registers. */ bytes += 2 * NUM_GPR_ARG_REGISTERS64 * sizeof (long); +#endif } /* Return value handling. The rules for SYSV are as follows: @@ -646,13 +774,30 @@ ffi_prep_cif_machdep (ffi_cif *cif) - Single/double FP values in fpr1, long double in fpr1,fpr2. - soft-float float/doubles are treated as UINT32/UINT64 respectivley. - soft-float long doubles are returned in gpr3-gpr6. */ + /* First translate for softfloat/nonlinux */ + if (cif->abi == FFI_LINUX_SOFT_FLOAT) + { + if (type == FFI_TYPE_FLOAT) + type = FFI_TYPE_UINT32; + if (type == FFI_TYPE_DOUBLE) + type = FFI_TYPE_UINT64; + if (type == FFI_TYPE_LONGDOUBLE) + type = FFI_TYPE_UINT128; + } + else if (cif->abi != FFI_LINUX + && cif->abi != FFI_LINUX64) + { +#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE + if (type == FFI_TYPE_LONGDOUBLE) + type = FFI_TYPE_STRUCT; +#endif + } + switch (type) { +#ifndef __NO_FPRS__ #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE case FFI_TYPE_LONGDOUBLE: - if (cif->abi != FFI_LINUX && cif->abi != FFI_LINUX64 - && cif->abi != FFI_LINUX_SOFT_FLOAT) - goto byref; flags |= FLAG_RETURNS_128BITS; /* Fall through. */ #endif @@ -660,47 +805,52 @@ ffi_prep_cif_machdep (ffi_cif *cif) flags |= FLAG_RETURNS_64BITS; /* Fall through. */ case FFI_TYPE_FLOAT: - /* With FFI_LINUX_SOFT_FLOAT no fp registers are used. */ - if (cif->abi != FFI_LINUX_SOFT_FLOAT) - flags |= FLAG_RETURNS_FP; + flags |= FLAG_RETURNS_FP; break; +#endif + case FFI_TYPE_UINT128: + flags |= FLAG_RETURNS_128BITS; + /* Fall through. */ case FFI_TYPE_UINT64: case FFI_TYPE_SINT64: flags |= FLAG_RETURNS_64BITS; break; case FFI_TYPE_STRUCT: - if (cif->abi == FFI_SYSV) + /* + * The final SYSV ABI says that structures smaller or equal 8 bytes + * are returned in r3/r4. The FFI_GCC_SYSV ABI instead returns them + * in memory. + * + * NOTE: The assembly code can safely assume that it just needs to + * store both r3 and r4 into a 8-byte word-aligned buffer, as + * we allocate a temporary buffer in ffi_call() if this flag is + * set. + */ + if (cif->abi == FFI_SYSV && size <= 8) { - /* The final SYSV ABI says that structures smaller or equal 8 bytes - are returned in r3/r4. The FFI_GCC_SYSV ABI instead returns them - in memory. */ - - /* Treat structs with size <= 8 bytes. */ - if (size <= 8) + flags |= FLAG_RETURNS_SMST; + break; + } +#if _CALL_ELF == 2 + if (cif->abi == FFI_LINUX64) + { + unsigned int elt, elnum; + elt = discover_homogeneous_aggregate (cif->rtype, &elnum); + if (elt) + { + if (elt == FFI_TYPE_DOUBLE) + flags |= FLAG_RETURNS_64BITS; + flags |= FLAG_RETURNS_FP | FLAG_RETURNS_SMST; + break; + } + if (size <= 16) { flags |= FLAG_RETURNS_SMST; - /* These structs are returned in r3. We pack the type and the - precalculated shift value (needed in the sysv.S) into flags. - The same applies for the structs returned in r3/r4. */ - if (size <= 4) - { - flags |= FLAG_SYSV_SMST_R3; - flags |= 8 * (4 - size) << 8; - break; - } - /* These structs are returned in r3 and r4. See above. */ - if (size <= 8) - { - flags |= FLAG_SYSV_SMST_R3 | FLAG_SYSV_SMST_R4; - flags |= 8 * (8 - size) << 8; - break; - } + break; } } -#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE - byref: #endif intarg_count++; flags |= FLAG_RETVAL_REFERENCE; @@ -722,39 +872,36 @@ ffi_prep_cif_machdep (ffi_cif *cif) Stuff on the stack needs to keep proper alignment. */ for (ptr = cif->arg_types, i = cif->nargs; i > 0; i--, ptr++) { - switch ((*ptr)->type) - { + unsigned short typenum = (*ptr)->type; + + /* We may need to handle some values depending on ABI */ + if (cif->abi == FFI_LINUX_SOFT_FLOAT) { + if (typenum == FFI_TYPE_FLOAT) + typenum = FFI_TYPE_UINT32; + if (typenum == FFI_TYPE_DOUBLE) + typenum = FFI_TYPE_UINT64; + if (typenum == FFI_TYPE_LONGDOUBLE) + typenum = FFI_TYPE_UINT128; + } else if (cif->abi != FFI_LINUX && cif->abi != FFI_LINUX64) { +#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE + if (typenum == FFI_TYPE_LONGDOUBLE) + typenum = FFI_TYPE_STRUCT; +#endif + } + + switch (typenum) { +#ifndef __NO_FPRS__ case FFI_TYPE_FLOAT: - /* With FFI_LINUX_SOFT_FLOAT floats are handled like UINT32. */ - if (cif->abi == FFI_LINUX_SOFT_FLOAT) - goto soft_float_cif; fparg_count++; /* floating singles are not 8-aligned on stack */ break; #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE case FFI_TYPE_LONGDOUBLE: - if (cif->abi != FFI_LINUX && cif->abi != FFI_LINUX_SOFT_FLOAT) - goto do_struct; - if (cif->abi == FFI_LINUX_SOFT_FLOAT) - { - if (intarg_count >= NUM_GPR_ARG_REGISTERS - 3 - || intarg_count < NUM_GPR_ARG_REGISTERS) - /* A long double in FFI_LINUX_SOFT_FLOAT can use only - a set of four consecutive gprs. If we have not enough, - we have to adjust the intarg_count value. */ - intarg_count += NUM_GPR_ARG_REGISTERS - intarg_count; - intarg_count += 4; - break; - } - else - fparg_count++; + fparg_count++; /* Fall thru */ #endif case FFI_TYPE_DOUBLE: - /* With FFI_LINUX_SOFT_FLOAT doubles are handled like UINT64. */ - if (cif->abi == FFI_LINUX_SOFT_FLOAT) - goto soft_double_cif; fparg_count++; /* If this FP arg is going on the stack, it must be 8-byte-aligned. */ @@ -763,10 +910,21 @@ ffi_prep_cif_machdep (ffi_cif *cif) && intarg_count % 2 != 0) intarg_count++; break; +#endif + case FFI_TYPE_UINT128: + /* + * A long double in FFI_LINUX_SOFT_FLOAT can use only a set + * of four consecutive gprs. If we do not have enough, we + * have to adjust the intarg_count value. + */ + if (intarg_count >= NUM_GPR_ARG_REGISTERS - 3 + && intarg_count < NUM_GPR_ARG_REGISTERS) + intarg_count = NUM_GPR_ARG_REGISTERS; + intarg_count += 4; + break; case FFI_TYPE_UINT64: case FFI_TYPE_SINT64: - soft_double_cif: /* 'long long' arguments are passed as two words, but either both words must fit in registers or both go on the stack. If they go on the stack, they must @@ -783,9 +941,6 @@ ffi_prep_cif_machdep (ffi_cif *cif) break; case FFI_TYPE_STRUCT: -#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE - do_struct: -#endif /* We must allocate space for a copy of these to enforce pass-by-value. Pad the space up to a multiple of 16 bytes (the maximum alignment required for anything under @@ -793,50 +948,100 @@ ffi_prep_cif_machdep (ffi_cif *cif) struct_copy_size += ((*ptr)->size + 15) & ~0xF; /* Fall through (allocate space for the pointer). */ - default: - soft_float_cif: + case FFI_TYPE_POINTER: + case FFI_TYPE_INT: + case FFI_TYPE_UINT32: + case FFI_TYPE_SINT32: + case FFI_TYPE_UINT16: + case FFI_TYPE_SINT16: + case FFI_TYPE_UINT8: + case FFI_TYPE_SINT8: /* Everything else is passed as a 4-byte word in a GPR, either the object itself or a pointer to it. */ intarg_count++; break; + default: + FFI_ASSERT (0); } } else for (ptr = cif->arg_types, i = cif->nargs; i > 0; i--, ptr++) { + unsigned int elt, elnum; +#ifdef __STRUCT_PARM_ALIGN__ + unsigned int align; +#endif + switch ((*ptr)->type) { #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE case FFI_TYPE_LONGDOUBLE: - if (cif->abi == FFI_LINUX_SOFT_FLOAT) - intarg_count += 4; - else - { - fparg_count += 2; - intarg_count += 2; - } + fparg_count += 2; + intarg_count += 2; + if (fparg_count > NUM_FPR_ARG_REGISTERS64) + flags |= FLAG_ARG_NEEDS_PSAVE; break; #endif case FFI_TYPE_FLOAT: case FFI_TYPE_DOUBLE: fparg_count++; intarg_count++; + if (fparg_count > NUM_FPR_ARG_REGISTERS64) + flags |= FLAG_ARG_NEEDS_PSAVE; break; case FFI_TYPE_STRUCT: +#ifdef __STRUCT_PARM_ALIGN__ + align = (*ptr)->alignment; + if (align > __STRUCT_PARM_ALIGN__) + align = __STRUCT_PARM_ALIGN__; + align = align / 8; + if (align > 1) + intarg_count = ALIGN (intarg_count, align); +#endif intarg_count += ((*ptr)->size + 7) / 8; + elt = 0; +#if _CALL_ELF == 2 + elt = discover_homogeneous_aggregate (*ptr, &elnum); +#endif + if (elt) + { + fparg_count += elnum; + if (fparg_count > NUM_FPR_ARG_REGISTERS64) + flags |= FLAG_ARG_NEEDS_PSAVE; + } + else + { + if (intarg_count > NUM_GPR_ARG_REGISTERS64) + flags |= FLAG_ARG_NEEDS_PSAVE; + } break; - default: + case FFI_TYPE_POINTER: + case FFI_TYPE_UINT64: + case FFI_TYPE_SINT64: + case FFI_TYPE_INT: + case FFI_TYPE_UINT32: + case FFI_TYPE_SINT32: + case FFI_TYPE_UINT16: + case FFI_TYPE_SINT16: + case FFI_TYPE_UINT8: + case FFI_TYPE_SINT8: /* Everything else is passed as a 8-byte word in a GPR, either the object itself or a pointer to it. */ intarg_count++; + if (intarg_count > NUM_GPR_ARG_REGISTERS64) + flags |= FLAG_ARG_NEEDS_PSAVE; break; + default: + FFI_ASSERT (0); } } +#ifndef __NO_FPRS__ if (fparg_count != 0) flags |= FLAG_FP_ARGUMENTS; +#endif if (intarg_count > 4) flags |= FLAG_4_GPR_ARGUMENTS; if (struct_copy_size != 0) @@ -844,25 +1049,36 @@ ffi_prep_cif_machdep (ffi_cif *cif) if (cif->abi != FFI_LINUX64) { +#ifndef __NO_FPRS__ /* Space for the FPR registers, if needed. */ if (fparg_count != 0) bytes += NUM_FPR_ARG_REGISTERS * sizeof (double); +#endif /* Stack space. */ if (intarg_count > NUM_GPR_ARG_REGISTERS) bytes += (intarg_count - NUM_GPR_ARG_REGISTERS) * sizeof (int); +#ifndef __NO_FPRS__ if (fparg_count > NUM_FPR_ARG_REGISTERS) bytes += (fparg_count - NUM_FPR_ARG_REGISTERS) * sizeof (double); +#endif } else { +#ifndef __NO_FPRS__ /* Space for the FPR registers, if needed. */ if (fparg_count != 0) bytes += NUM_FPR_ARG_REGISTERS64 * sizeof (double); +#endif /* Stack space. */ +#if _CALL_ELF == 2 + if ((flags & FLAG_ARG_NEEDS_PSAVE) != 0) + bytes += intarg_count * sizeof (long); +#else if (intarg_count > NUM_GPR_ARG_REGISTERS64) bytes += (intarg_count - NUM_GPR_ARG_REGISTERS64) * sizeof (long); +#endif } /* The stack space allocated needs to be a multiple of 16 bytes. */ @@ -877,6 +1093,26 @@ ffi_prep_cif_machdep (ffi_cif *cif) return FFI_OK; } +ffi_status +ffi_prep_cif_machdep (ffi_cif *cif) +{ + cif->nfixedargs = cif->nargs; + return ffi_prep_cif_machdep_core (cif); +} + +ffi_status +ffi_prep_cif_machdep_var (ffi_cif *cif, + unsigned int nfixedargs, + unsigned int ntotalargs MAYBE_UNUSED) +{ + cif->nfixedargs = nfixedargs; +#if _CALL_ELF == 2 + if (cif->abi == FFI_LINUX64) + cif->flags |= FLAG_ARG_NEEDS_PSAVE; +#endif + return ffi_prep_cif_machdep_core (cif); +} + extern void ffi_call_SYSV(extended_cif *, unsigned, unsigned, unsigned *, void (*fn)(void)); extern void FFI_HIDDEN ffi_call_LINUX64(extended_cif *, unsigned long, @@ -886,28 +1122,39 @@ extern void FFI_HIDDEN ffi_call_LINUX64( void ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue) { + /* + * The final SYSV ABI says that structures smaller or equal 8 bytes + * are returned in r3/r4. The FFI_GCC_SYSV ABI instead returns them + * in memory. + * + * We bounce-buffer SYSV small struct return values so that sysv.S + * can write r3 and r4 to memory without worrying about struct size. + * + * For ELFv2 ABI, use a bounce buffer for homogeneous structs too, + * for similar reasons. + */ + unsigned long smst_buffer[8]; 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; - + ecif.rvalue = rvalue; + if ((cif->flags & FLAG_RETURNS_SMST) != 0) + ecif.rvalue = smst_buffer; + /* Ensure that we have a valid struct return value. + FIXME: Isn't this just papering over a user problem? */ + else if (!rvalue && cif->rtype->type == FFI_TYPE_STRUCT) + ecif.rvalue = alloca (cif->rtype->size); switch (cif->abi) { #ifndef POWERPC64 +# ifndef __NO_FPRS__ case FFI_SYSV: case FFI_GCC_SYSV: case FFI_LINUX: +# endif case FFI_LINUX_SOFT_FLOAT: ffi_call_SYSV (&ecif, -cif->bytes, cif->flags, ecif.rvalue, fn); break; @@ -920,10 +1167,29 @@ ffi_call(ffi_cif *cif, void (*fn)(void), FFI_ASSERT (0); break; } + + /* Check for a bounce-buffered return value */ + if (rvalue && ecif.rvalue == smst_buffer) + { + unsigned int rsize = cif->rtype->size; +#ifndef __LITTLE_ENDIAN__ + /* The SYSV ABI returns a structure of up to 4 bytes in size + left-padded in r3. */ + if (cif->abi == FFI_SYSV && rsize <= 4) + memcpy (rvalue, (char *) smst_buffer + 4 - rsize, rsize); + /* The SYSV ABI returns a structure of up to 8 bytes in size + left-padded in r3/r4, and the ELFv2 ABI similarly returns a + structure of up to 8 bytes in size left-padded in r3. */ + else if (rsize <= 8) + memcpy (rvalue, (char *) smst_buffer + 8 - rsize, rsize); + else +#endif + memcpy (rvalue, smst_buffer, rsize); + } } -#ifndef POWERPC64 +#if !defined POWERPC64 || _CALL_ELF == 2 #define MIN_CACHE_LINE_SIZE 8 static void @@ -947,16 +1213,38 @@ ffi_prep_closure_loc (ffi_closure *closu void *codeloc) { #ifdef POWERPC64 +# if _CALL_ELF == 2 + unsigned int *tramp = (unsigned int *) &closure->tramp[0]; + + if (cif->abi != FFI_LINUX64) + return FFI_BAD_ABI; + + tramp[0] = 0xe96c0018; /* 0: ld 11,2f-0b(12) */ + tramp[1] = 0xe98c0010; /* ld 12,1f-0b(12) */ + tramp[2] = 0x7d8903a6; /* mtctr 12 */ + tramp[3] = 0x4e800420; /* bctr */ + /* 1: .quad function_addr */ + /* 2: .quad context */ + *(void **) &tramp[4] = (void *) ffi_closure_LINUX64; + *(void **) &tramp[6] = codeloc; + flush_icache ((char *)tramp, (char *)codeloc, FFI_TRAMPOLINE_SIZE); +# else void **tramp = (void **) &closure->tramp[0]; - FFI_ASSERT (cif->abi == FFI_LINUX64); + if (cif->abi != FFI_LINUX64) + return FFI_BAD_ABI; /* Copy function address and TOC from ffi_closure_LINUX64. */ memcpy (tramp, (char *) ffi_closure_LINUX64, 16); tramp[2] = codeloc; +# endif #else unsigned int *tramp; - FFI_ASSERT (cif->abi == FFI_GCC_SYSV || cif->abi == FFI_SYSV); + if (! (cif->abi == FFI_GCC_SYSV + || cif->abi == FFI_SYSV + || cif->abi == FFI_LINUX + || cif->abi == FFI_LINUX_SOFT_FLOAT)) + return FFI_BAD_ABI; tramp = (unsigned int *) &closure->tramp[0]; tramp[0] = 0x7c0802a6; /* mflr r0 */ @@ -1011,32 +1299,38 @@ ffi_closure_helper_SYSV (ffi_closure *cl void ** avalue; ffi_type ** arg_types; long i, avn; - long nf; /* number of floating registers already used */ - long ng; /* number of general registers already used */ - ffi_cif * cif; - double temp; - unsigned size; +#ifndef __NO_FPRS__ + long nf = 0; /* number of floating registers already used */ +#endif + long ng = 0; /* number of general registers already used */ + + ffi_cif *cif = closure->cif; + unsigned size = cif->rtype->size; + unsigned short rtypenum = cif->rtype->type; - cif = closure->cif; avalue = alloca (cif->nargs * sizeof (void *)); - size = cif->rtype->size; - nf = 0; - ng = 0; + /* First translate for softfloat/nonlinux */ + if (cif->abi == FFI_LINUX_SOFT_FLOAT) { + if (rtypenum == FFI_TYPE_FLOAT) + rtypenum = FFI_TYPE_UINT32; + if (rtypenum == FFI_TYPE_DOUBLE) + rtypenum = FFI_TYPE_UINT64; + if (rtypenum == FFI_TYPE_LONGDOUBLE) + rtypenum = FFI_TYPE_UINT128; + } else if (cif->abi != FFI_LINUX && cif->abi != FFI_LINUX64) { +#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE + if (rtypenum == FFI_TYPE_LONGDOUBLE) + rtypenum = FFI_TYPE_STRUCT; +#endif + } + /* Copy the caller's structure return value address so that the closure returns the data directly to the caller. For FFI_SYSV the result is passed in r3/r4 if the struct size is less or equal 8 bytes. */ - - if ((cif->rtype->type == FFI_TYPE_STRUCT - && !((cif->abi == FFI_SYSV) && (size <= 8))) -#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE - || (cif->rtype->type == FFI_TYPE_LONGDOUBLE - && cif->abi != FFI_LINUX && cif->abi != FFI_LINUX_SOFT_FLOAT) -#endif - ) - { + if (rtypenum == FFI_TYPE_STRUCT && ((cif->abi != FFI_SYSV) || (size > 8))) { rvalue = (void *) *pgr; ng++; pgr++; @@ -1047,12 +1341,112 @@ ffi_closure_helper_SYSV (ffi_closure *cl arg_types = cif->arg_types; /* Grab the addresses of the arguments from the stack frame. */ - while (i < avn) - { - switch (arg_types[i]->type) - { + while (i < avn) { + unsigned short typenum = arg_types[i]->type; + + /* We may need to handle some values depending on ABI */ + if (cif->abi == FFI_LINUX_SOFT_FLOAT) { + if (typenum == FFI_TYPE_FLOAT) + typenum = FFI_TYPE_UINT32; + if (typenum == FFI_TYPE_DOUBLE) + typenum = FFI_TYPE_UINT64; + if (typenum == FFI_TYPE_LONGDOUBLE) + typenum = FFI_TYPE_UINT128; + } else if (cif->abi != FFI_LINUX && cif->abi != FFI_LINUX64) { +#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE + if (typenum == FFI_TYPE_LONGDOUBLE) + typenum = FFI_TYPE_STRUCT; +#endif + } + + switch (typenum) { +#ifndef __NO_FPRS__ + case FFI_TYPE_FLOAT: + /* unfortunately float values are stored as doubles + * in the ffi_closure_SYSV code (since we don't check + * the type in that routine). + */ + + /* there are 8 64bit floating point registers */ + + if (nf < 8) + { + double temp = pfr->d; + pfr->f = (float) temp; + avalue[i] = pfr; + nf++; + pfr++; + } + else + { + /* FIXME? here we are really changing the values + * stored in the original calling routines outgoing + * parameter stack. This is probably a really + * naughty thing to do but... + */ + avalue[i] = pst; + pst += 1; + } + break; + + case FFI_TYPE_DOUBLE: + /* On the outgoing stack all values are aligned to 8 */ + /* there are 8 64bit floating point registers */ + + if (nf < 8) + { + avalue[i] = pfr; + nf++; + pfr++; + } + else + { + if (((long) pst) & 4) + pst++; + avalue[i] = pst; + pst += 2; + } + break; + +#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE + case FFI_TYPE_LONGDOUBLE: + if (nf < 7) + { + avalue[i] = pfr; + pfr += 2; + nf += 2; + } + else + { + if (((long) pst) & 4) + pst++; + avalue[i] = pst; + pst += 4; + nf = 8; + } + break; +#endif +#endif /* have FPRS */ + + case FFI_TYPE_UINT128: + /* + * Test if for the whole long double, 4 gprs are available. + * otherwise the stuff ends up on the stack. + */ + if (ng < 5) { + avalue[i] = pgr; + pgr += 4; + ng += 4; + } else { + avalue[i] = pst; + pst += 4; + ng = 8+4; + } + break; + case FFI_TYPE_SINT8: case FFI_TYPE_UINT8: +#ifndef __LITTLE_ENDIAN__ /* there are 8 gpr registers used to pass values */ if (ng < 8) { @@ -1066,9 +1460,11 @@ ffi_closure_helper_SYSV (ffi_closure *cl pst++; } break; +#endif case FFI_TYPE_SINT16: case FFI_TYPE_UINT16: +#ifndef __LITTLE_ENDIAN__ /* there are 8 gpr registers used to pass values */ if (ng < 8) { @@ -1082,11 +1478,11 @@ ffi_closure_helper_SYSV (ffi_closure *cl pst++; } break; +#endif case FFI_TYPE_SINT32: case FFI_TYPE_UINT32: case FFI_TYPE_POINTER: - soft_float_closure: /* there are 8 gpr registers used to pass values */ if (ng < 8) { @@ -1102,9 +1498,6 @@ ffi_closure_helper_SYSV (ffi_closure *cl break; case FFI_TYPE_STRUCT: -#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE - do_struct: -#endif /* Structs are passed by reference. The address will appear in a gpr if it is one of the first 8 arguments. */ if (ng < 8) @@ -1122,7 +1515,6 @@ ffi_closure_helper_SYSV (ffi_closure *cl case FFI_TYPE_SINT64: case FFI_TYPE_UINT64: - soft_double_closure: /* passing long long ints are complex, they must * be passed in suitable register pairs such as * (r3,r4) or (r5,r6) or (r6,r7), or (r7,r8) or (r9,r10) @@ -1154,99 +1546,8 @@ ffi_closure_helper_SYSV (ffi_closure *cl } break; - case FFI_TYPE_FLOAT: - /* With FFI_LINUX_SOFT_FLOAT floats are handled like UINT32. */ - if (cif->abi == FFI_LINUX_SOFT_FLOAT) - goto soft_float_closure; - /* unfortunately float values are stored as doubles - * in the ffi_closure_SYSV code (since we don't check - * the type in that routine). - */ - - /* there are 8 64bit floating point registers */ - - if (nf < 8) - { - temp = pfr->d; - pfr->f = (float) temp; - avalue[i] = pfr; - nf++; - pfr++; - } - else - { - /* FIXME? here we are really changing the values - * stored in the original calling routines outgoing - * parameter stack. This is probably a really - * naughty thing to do but... - */ - avalue[i] = pst; - pst += 1; - } - break; - - case FFI_TYPE_DOUBLE: - /* With FFI_LINUX_SOFT_FLOAT doubles are handled like UINT64. */ - if (cif->abi == FFI_LINUX_SOFT_FLOAT) - goto soft_double_closure; - /* On the outgoing stack all values are aligned to 8 */ - /* there are 8 64bit floating point registers */ - - if (nf < 8) - { - avalue[i] = pfr; - nf++; - pfr++; - } - else - { - if (((long) pst) & 4) - pst++; - avalue[i] = pst; - pst += 2; - } - break; - -#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE - case FFI_TYPE_LONGDOUBLE: - if (cif->abi != FFI_LINUX && cif->abi != FFI_LINUX_SOFT_FLOAT) - goto do_struct; - if (cif->abi == FFI_LINUX_SOFT_FLOAT) - { /* Test if for the whole long double, 4 gprs are available. - otherwise the stuff ends up on the stack. */ - if (ng < 5) - { - avalue[i] = pgr; - pgr += 4; - ng += 4; - } - else - { - avalue[i] = pst; - pst += 4; - ng = 8; - } - break; - } - if (nf < 7) - { - avalue[i] = pfr; - pfr += 2; - nf += 2; - } - else - { - if (((long) pst) & 4) - pst++; - avalue[i] = pst; - pst += 4; - nf = 8; - } - break; -#endif - default: - FFI_ASSERT (0); + FFI_ASSERT (0); } i++; @@ -1263,39 +1564,9 @@ ffi_closure_helper_SYSV (ffi_closure *cl already used and we never have a struct with size zero. That is the reason for the subtraction of 1. See the comment in ffitarget.h about ordering. */ - if (cif->abi == FFI_SYSV && cif->rtype->type == FFI_TYPE_STRUCT - && size <= 8) + if (cif->abi == FFI_SYSV && rtypenum == FFI_TYPE_STRUCT && size <= 8) return (FFI_SYSV_TYPE_SMALL_STRUCT - 1) + size; -#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE - else if (cif->rtype->type == FFI_TYPE_LONGDOUBLE - && cif->abi != FFI_LINUX && cif->abi != FFI_LINUX_SOFT_FLOAT) - return FFI_TYPE_STRUCT; -#endif - /* With FFI_LINUX_SOFT_FLOAT floats and doubles are handled like UINT32 - respectivley UINT64. */ - if (cif->abi == FFI_LINUX_SOFT_FLOAT) - { - switch (cif->rtype->type) - { - case FFI_TYPE_FLOAT: - return FFI_TYPE_UINT32; - break; - case FFI_TYPE_DOUBLE: - return FFI_TYPE_UINT64; - break; -#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE - case FFI_TYPE_LONGDOUBLE: - return FFI_TYPE_UINT128; - break; -#endif - default: - return cif->rtype->type; - } - } - else - { - return cif->rtype->type; - } + return rtypenum; } int FFI_HIDDEN ffi_closure_helper_LINUX64 (ffi_closure *, void *, @@ -1312,16 +1583,20 @@ ffi_closure_helper_LINUX64 (ffi_closure void **avalue; ffi_type **arg_types; - long i, avn; + unsigned long i, avn, nfixedargs; ffi_cif *cif; ffi_dblfl *end_pfr = pfr + NUM_FPR_ARG_REGISTERS64; +#ifdef __STRUCT_PARM_ALIGN__ + unsigned long align; +#endif cif = closure->cif; avalue = alloca (cif->nargs * sizeof (void *)); - /* Copy the caller's structure return value address so that the closure - returns the data directly to the caller. */ - if (cif->rtype->type == FFI_TYPE_STRUCT) + /* Copy the caller's structure return value address so that the + closure returns the data directly to the caller. */ + if (cif->rtype->type == FFI_TYPE_STRUCT + && (cif->flags & FLAG_RETURNS_SMST) == 0) { rvalue = (void *) *pst; pst++; @@ -1329,30 +1604,39 @@ ffi_closure_helper_LINUX64 (ffi_closure i = 0; avn = cif->nargs; + nfixedargs = cif->nfixedargs; arg_types = cif->arg_types; /* Grab the addresses of the arguments from the stack frame. */ while (i < avn) { + unsigned int elt, elnum; + switch (arg_types[i]->type) { case FFI_TYPE_SINT8: case FFI_TYPE_UINT8: +#ifndef __LITTLE_ENDIAN__ avalue[i] = (char *) pst + 7; pst++; break; +#endif case FFI_TYPE_SINT16: case FFI_TYPE_UINT16: +#ifndef __LITTLE_ENDIAN__ avalue[i] = (char *) pst + 6; pst++; break; +#endif case FFI_TYPE_SINT32: case FFI_TYPE_UINT32: +#ifndef __LITTLE_ENDIAN__ avalue[i] = (char *) pst + 4; pst++; break; +#endif case FFI_TYPE_SINT64: case FFI_TYPE_UINT64: @@ -1362,12 +1646,82 @@ ffi_closure_helper_LINUX64 (ffi_closure break; case FFI_TYPE_STRUCT: - /* Structures with size less than eight bytes are passed - left-padded. */ - if (arg_types[i]->size < 8) - avalue[i] = (char *) pst + 8 - arg_types[i]->size; +#ifdef __STRUCT_PARM_ALIGN__ + align = arg_types[i]->alignment; + if (align > __STRUCT_PARM_ALIGN__) + align = __STRUCT_PARM_ALIGN__; + if (align > 1) + pst = (unsigned long *) ALIGN ((size_t) pst, align); +#endif + elt = 0; +#if _CALL_ELF == 2 + elt = discover_homogeneous_aggregate (arg_types[i], &elnum); +#endif + if (elt) + { + union { + void *v; + unsigned long *ul; + float *f; + double *d; + size_t p; + } to, from; + + /* Repackage the aggregate from its parts. The + aggregate size is not greater than the space taken by + the registers so store back to the register/parameter + save arrays. */ + if (pfr + elnum <= end_pfr) + to.v = pfr; + else + to.v = pst; + + avalue[i] = to.v; + from.ul = pst; + if (elt == FFI_TYPE_FLOAT) + { + do + { + if (pfr < end_pfr && i < nfixedargs) + { + *to.f = (float) pfr->d; + pfr++; + } + else + *to.f = *from.f; + to.f++; + from.f++; + } + while (--elnum != 0); + } + else + { + do + { + if (pfr < end_pfr && i < nfixedargs) + { + *to.d = pfr->d; + pfr++; + } + else + *to.d = *from.d; + to.d++; + from.d++; + } + while (--elnum != 0); + } + } else - avalue[i] = pst; + { +#ifndef __LITTLE_ENDIAN__ + /* Structures with size less than eight bytes are passed + left-padded. */ + if (arg_types[i]->size < 8) + avalue[i] = (char *) pst + 8 - arg_types[i]->size; + else +#endif + avalue[i] = pst; + } pst += (arg_types[i]->size + 7) / 8; break; @@ -1379,7 +1733,7 @@ ffi_closure_helper_LINUX64 (ffi_closure /* there are 13 64bit floating point registers */ - if (pfr < end_pfr) + if (pfr < end_pfr && i < nfixedargs) { double temp = pfr->d; pfr->f = (float) temp; @@ -1395,7 +1749,7 @@ ffi_closure_helper_LINUX64 (ffi_closure /* On the outgoing stack all values are aligned to 8 */ /* there are 13 64bit floating point registers */ - if (pfr < end_pfr) + if (pfr < end_pfr && i < nfixedargs) { avalue[i] = pfr; pfr++; @@ -1407,14 +1761,14 @@ ffi_closure_helper_LINUX64 (ffi_closure #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE case FFI_TYPE_LONGDOUBLE: - if (pfr + 1 < end_pfr) + if (pfr + 1 < end_pfr && i + 1 < nfixedargs) { avalue[i] = pfr; pfr += 2; } else { - if (pfr < end_pfr) + if (pfr < end_pfr && i < nfixedargs) { /* Passed partly in f13 and partly on the stack. Move it all to the stack. */ @@ -1438,5 +1792,14 @@ ffi_closure_helper_LINUX64 (ffi_closure (closure->fun) (cif, rvalue, avalue, closure->user_data); /* Tell ffi_closure_LINUX64 how to perform return type promotions. */ + if ((cif->flags & FLAG_RETURNS_SMST) != 0) + { + if ((cif->flags & FLAG_RETURNS_FP) == 0) + return FFI_V2_TYPE_SMALL_STRUCT + cif->rtype->size - 1; + else if ((cif->flags & FLAG_RETURNS_64BITS) != 0) + return FFI_V2_TYPE_DOUBLE_HOMOG; + else + return FFI_V2_TYPE_FLOAT_HOMOG; + } return cif->rtype->type; } Index: mozilla-release/js/src/ctypes/libffi/src/powerpc/ffitarget.h =================================================================== --- mozilla-release.orig/js/src/ctypes/libffi/src/powerpc/ffitarget.h +++ mozilla-release/js/src/ctypes/libffi/src/powerpc/ffitarget.h @@ -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 Index: mozilla-release/js/src/ctypes/libffi/src/powerpc/linux64.S =================================================================== --- mozilla-release.orig/js/src/ctypes/libffi/src/powerpc/linux64.S +++ mozilla-release/js/src/ctypes/libffi/src/powerpc/linux64.S @@ -30,16 +30,33 @@ #include #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 Index: mozilla-release/js/src/ctypes/libffi/src/powerpc/linux64_closure.S =================================================================== --- mozilla-release.orig/js/src/ctypes/libffi/src/powerpc/linux64_closure.S +++ mozilla-release/js/src/ctypes/libffi/src/powerpc/linux64_closure.S @@ -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: +# 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: - # save general regs into parm save area - std %r3, 48(%r1) - std %r4, 56(%r1) - std %r5, 64(%r1) - std %r6, 72(%r1) +# 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) - # set up registers for the routine that actually does the work - # get the context pointer from the trampoline - mr %r3, %r11 + # load up the pointer to the saved fpr registers */ + addi %r6, %r1, -104 - # now load up the pointer to the result storage - addi %r4, %r1, 112 + # load up the pointer to the result storage + addi %r4, %r1, -STACKFRAME+RETVAL - # now load up the pointer to the parameter save area - # in the previous frame - addi %r5, %r1, 240 + 48 + stdu %r1, -STACKFRAME(%r1) +.LCFI0: - # now load up the pointer to the saved fpr registers */ - addi %r6, %r1, 128 + # get the context pointer from the trampoline + 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 +# 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 -# esac +# 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 Index: mozilla-release/js/src/ctypes/libffi/src/powerpc/ppc_closure.S =================================================================== --- mozilla-release.orig/js/src/ctypes/libffi/src/powerpc/ppc_closure.S +++ mozilla-release/js/src/ctypes/libffi/src/powerpc/ppc_closure.S @@ -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) Index: mozilla-release/js/src/ctypes/libffi/src/powerpc/sysv.S =================================================================== --- mozilla-release.orig/js/src/ctypes/libffi/src/powerpc/sysv.S +++ mozilla-release/js/src/ctypes/libffi/src/powerpc/sysv.S @@ -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) Index: mozilla-release/mfbt/Endian.h =================================================================== --- mozilla-release.orig/mfbt/Endian.h +++ mozilla-release/mfbt/Endian.h @@ -91,7 +91,7 @@ # else # error "CPU type is unknown" # endif -#elif defined(__APPLE__) +#elif defined(__APPLE__) || defined(__powerpc__) || defined(__ppc__) # if __LITTLE_ENDIAN__ # define MOZ_LITTLE_ENDIAN 1 # elif __BIG_ENDIAN__ @@ -119,8 +119,7 @@ * cases. */ #elif defined(__sparc) || defined(__sparc__) || \ - defined(_POWER) || defined(__powerpc__) || \ - defined(__ppc__) || defined(__hppa) || \ + defined(_POWER) || defined(__hppa) || \ defined(_MIPSEB) || defined(__ARMEB__) || \ defined(__s390__) || defined(__AARCH64EB__) || \ (defined(__sh__) && defined(__LITTLE_ENDIAN__)) || \ Index: mozilla-release/media/webrtc/trunk/webrtc/typedefs.h =================================================================== --- mozilla-release.orig/media/webrtc/trunk/webrtc/typedefs.h +++ mozilla-release/media/webrtc/trunk/webrtc/typedefs.h @@ -52,13 +52,23 @@ #elif defined(__powerpc64__) #define WEBRTC_ARCH_PPC64 1 #define WEBRTC_ARCH_64_BITS 1 +#ifdef __LITTLE_ENDIAN__ +#define WEBRTC_ARCH_LITTLE_ENDIAN +#define WEBRTC_LITTLE_ENDIAN +#else #define WEBRTC_ARCH_BIG_ENDIAN #define WEBRTC_BIG_ENDIAN +#endif #elif defined(__ppc__) || defined(__powerpc__) #define WEBRTC_ARCH_PPC 1 #define WEBRTC_ARCH_32_BITS 1 +#ifdef __LITTLE_ENDIAN__ +#define WEBRTC_ARCH_LITTLE_ENDIAN +#define WEBRTC_LITTLE_ENDIAN +#else #define WEBRTC_ARCH_BIG_ENDIAN #define WEBRTC_BIG_ENDIAN +#endif #elif defined(__sparc64__) #define WEBRTC_ARCH_SPARC 1 #define WEBRTC_ARCH_64_BITS 1 Index: mozilla-release/xpcom/reflect/xptcall/src/md/unix/moz.build =================================================================== --- mozilla-release.orig/xpcom/reflect/xptcall/src/md/unix/moz.build +++ mozilla-release/xpcom/reflect/xptcall/src/md/unix/moz.build @@ -206,12 +206,12 @@ if CONFIG['OS_TEST'] == 'powerpc': 'xptcstubs_ppc_linux.cpp', ] -if CONFIG['OS_TEST'] == 'powerpc64': +if CONFIG['OS_TEST'] in ('powerpc64', 'powerpc64le'): if CONFIG['OS_ARCH'] in ('Linux', 'FreeBSD'): SOURCES += [ - 'xptcinvoke_asm_ppc64_linux.s', + 'xptcinvoke_asm_ppc64_linux.S', 'xptcinvoke_ppc64_linux.cpp', - 'xptcstubs_asm_ppc64_linux.s', + 'xptcstubs_asm_ppc64_linux.S', 'xptcstubs_ppc64_linux.cpp', ] Index: mozilla-release/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_asm_ppc64_linux.s =================================================================== --- mozilla-release.orig/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_asm_ppc64_linux.s +++ /dev/null @@ -1,132 +0,0 @@ -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -.set r0,0; .set r1,1; .set r2,2; .set r3,3; .set r4,4 -.set r5,5; .set r6,6; .set r7,7; .set r8,8; .set r9,9 -.set r10,10; .set r11,11; .set r12,12; .set r13,13; .set r14,14 -.set r15,15; .set r16,16; .set r17,17; .set r18,18; .set r19,19 -.set r20,20; .set r21,21; .set r22,22; .set r23,23; .set r24,24 -.set r25,25; .set r26,26; .set r27,27; .set r28,28; .set r29,29 -.set r30,30; .set r31,31 -.set f0,0; .set f1,1; .set f2,2; .set f3,3; .set f4,4 -.set f5,5; .set f6,6; .set f7,7; .set f8,8; .set f9,9 -.set f10,10; .set f11,11; .set f12,12; .set f13,13; .set f14,14 -.set f15,15; .set f16,16; .set f17,17; .set f18,18; .set f19,19 -.set f20,20; .set f21,21; .set f22,22; .set f23,23; .set f24,24 -.set f25,25; .set f26,26; .set f27,27; .set f28,28; .set f29,29 -.set f30,30; .set f31,31 - - -# -# NS_InvokeByIndex(nsISupports* that, uint32_t methodIndex, -# uint32_t paramCount, nsXPTCVariant* params) -# - - .section ".toc","aw" - .section ".text" - .align 2 - .globl NS_InvokeByIndex - .section ".opd","aw" - .align 3 -NS_InvokeByIndex: - .quad .NS_InvokeByIndex,.TOC.@tocbase - .previous - .type NS_InvokeByIndex,@function -.NS_InvokeByIndex: - mflr 0 - std 0,16(r1) - - std r29,-24(r1) - std r30,-16(r1) - std r31,-8(r1) - - mr r29,r3 # Save 'that' in r29 - mr r30,r4 # Save 'methodIndex' in r30 - mr r31,r1 # Save old frame - - # Allocate stack frame with space for params. Since at least the - # first 7 parameters (not including 'that') will be in registers, - # we don't actually need stack space for those. We must ensure - # that the stack remains 16-byte aligned. - # - # | ..128-byte stack frame.. | | 7 GP | 13 FP | 3 NV | - # | |(params)........| regs | regs | regs | - # (r1)...........(+112)....(+128) - # (-23*8).(-16*8).(-3*8)..(r31) - - # +stack frame, -unused stack params, +regs storage, +1 for alignment - addi r7,r5,((112/8)-7+7+13+3+1) - rldicr r7,r7,3,59 # multiply by 8 and mask with ~15 - neg r7,r7 - stdux r1,r1,r7 - - - # Call invoke_copy_to_stack(uint64_t* gpregs, double* fpregs, - # uint32_t paramCount, nsXPTCVariant* s, - # uint64_t* d)) - - # r5, r6 are passed through intact (paramCount, params) - # r7 (d) has to be r1+112 -- where parameters are passed on the stack. - # r3, r4 are above that, easier to address from r31 than from r1 - - subi r3,r31,(23*8) # r3 --> GPRS - subi r4,r31,(16*8) # r4 --> FPRS - addi r7,r1,112 # r7 --> params - bl invoke_copy_to_stack - nop - - # Set up to invoke function - - ld r9,0(r29) # vtable (r29 is 'that') - mr r3,r29 # self is first arg, obviously - - sldi r30,r30,3 # Find function descriptor - add r9,r9,r30 - ld r9,0(r9) - - ld r0,0(r9) # Actual address from fd. - std r2,40(r1) # Save r2 (TOC pointer) - - mtctr 0 - ld r11,16(r9) # Environment pointer from fd. - ld r2,8(r9) # TOC pointer from fd. - - # Load FP and GP registers as required - ld r4, -(23*8)(r31) - ld r5, -(22*8)(r31) - ld r6, -(21*8)(r31) - ld r7, -(20*8)(r31) - ld r8, -(19*8)(r31) - ld r9, -(18*8)(r31) - ld r10, -(17*8)(r31) - - lfd f1, -(16*8)(r31) - lfd f2, -(15*8)(r31) - lfd f3, -(14*8)(r31) - lfd f4, -(13*8)(r31) - lfd f5, -(12*8)(r31) - lfd f6, -(11*8)(r31) - lfd f7, -(10*8)(r31) - lfd f8, -(9*8)(r31) - lfd f9, -(8*8)(r31) - lfd f10, -(7*8)(r31) - lfd f11, -(6*8)(r31) - lfd f12, -(5*8)(r31) - lfd f13, -(4*8)(r31) - - bctrl # Do it - - ld r2,40(r1) # Load our own TOC pointer - ld r1,0(r1) # Revert stack frame - ld 0,16(r1) # Reload lr - ld 29,-24(r1) # Restore NVGPRS - ld 30,-16(r1) - ld 31,-8(r1) - mtlr 0 - blr - - .size NS_InvokeByIndex,.-.NS_InvokeByIndex - - # Magic indicating no need for an executable stack - .section .note.GNU-stack, "", @progbits ; .previous Index: mozilla-release/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_asm_ppc64_linux.S =================================================================== --- /dev/null +++ mozilla-release/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_asm_ppc64_linux.S @@ -0,0 +1,167 @@ +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +.set r0,0; .set r1,1; .set r2,2; .set r3,3; .set r4,4 +.set r5,5; .set r6,6; .set r7,7; .set r8,8; .set r9,9 +.set r10,10; .set r11,11; .set r12,12; .set r13,13; .set r14,14 +.set r15,15; .set r16,16; .set r17,17; .set r18,18; .set r19,19 +.set r20,20; .set r21,21; .set r22,22; .set r23,23; .set r24,24 +.set r25,25; .set r26,26; .set r27,27; .set r28,28; .set r29,29 +.set r30,30; .set r31,31 +.set f0,0; .set f1,1; .set f2,2; .set f3,3; .set f4,4 +.set f5,5; .set f6,6; .set f7,7; .set f8,8; .set f9,9 +.set f10,10; .set f11,11; .set f12,12; .set f13,13; .set f14,14 +.set f15,15; .set f16,16; .set f17,17; .set f18,18; .set f19,19 +.set f20,20; .set f21,21; .set f22,22; .set f23,23; .set f24,24 +.set f25,25; .set f26,26; .set f27,27; .set f28,28; .set f29,29 +.set f30,30; .set f31,31 + +# The ABI defines a fixed stack frame area of 4 doublewords (ELFv2) +# or 6 doublewords (ELFv1); the last of these doublewords is used +# as TOC pointer save area. The fixed area is followed by a parameter +# save area of 8 doublewords (used for vararg routines), followed +# by space for parameters passed on the stack. +# +# We set STACK_TOC to the offset of the TOC pointer save area, and +# STACK_PARAMS to the offset of the first on-stack parameter. + +#if _CALL_ELF == 2 +#define STACK_TOC 24 +#define STACK_PARAMS 96 +#else +#define STACK_TOC 40 +#define STACK_PARAMS 112 +#endif + +# +# NS_InvokeByIndex(nsISupports* that, uint32_t methodIndex, +# uint32_t paramCount, nsXPTCVariant* params) +# + +#if _CALL_ELF == 2 + .section ".text" + .type NS_InvokeByIndex,@function + .globl NS_InvokeByIndex + .align 2 +NS_InvokeByIndex: +0: addis 2,12,(.TOC.-0b)@ha + addi 2,2,(.TOC.-0b)@l + .localentry NS_InvokeByIndex,.-NS_InvokeByIndex +#else + .section ".toc","aw" + .section ".text" + .align 2 + .globl NS_InvokeByIndex + .section ".opd","aw" + .align 3 +NS_InvokeByIndex: + .quad .NS_InvokeByIndex,.TOC.@tocbase + .previous + .type NS_InvokeByIndex,@function +.NS_InvokeByIndex: +#endif + mflr 0 + std 0,16(r1) + + std r29,-24(r1) + std r30,-16(r1) + std r31,-8(r1) + + mr r29,r3 # Save 'that' in r29 + mr r30,r4 # Save 'methodIndex' in r30 + mr r31,r1 # Save old frame + + # Allocate stack frame with space for params. Since at least the + # first 7 parameters (not including 'that') will be in registers, + # we don't actually need stack space for those. We must ensure + # that the stack remains 16-byte aligned. + # + # | (fixed area + | | 7 GP | 13 FP | 3 NV | + # | param. save) |(params)........| regs | regs | regs | + # (r1)......(+STACK_PARAMS)... (-23*8).(-16*8).(-3*8)..(r31) + + # +stack frame, -unused stack params, +regs storage, +1 for alignment + addi r7,r5,((STACK_PARAMS/8)-7+7+13+3+1) + rldicr r7,r7,3,59 # multiply by 8 and mask with ~15 + neg r7,r7 + stdux r1,r1,r7 + + + # Call invoke_copy_to_stack(uint64_t* gpregs, double* fpregs, + # uint32_t paramCount, nsXPTCVariant* s, + # uint64_t* d)) + + # r5, r6 are passed through intact (paramCount, params) + # r7 (d) has to be r1+STACK_PARAMS + # -- where parameters are passed on the stack. + # r3, r4 are above that, easier to address from r31 than from r1 + + subi r3,r31,(23*8) # r3 --> GPRS + subi r4,r31,(16*8) # r4 --> FPRS + addi r7,r1,STACK_PARAMS # r7 --> params + bl invoke_copy_to_stack + nop + + # Set up to invoke function + + ld r9,0(r29) # vtable (r29 is 'that') + mr r3,r29 # self is first arg, obviously + + sldi r30,r30,3 # Find function descriptor + add r9,r9,r30 + ld r12,0(r9) + + std r2,STACK_TOC(r1) # Save r2 (TOC pointer) + +#if _CALL_ELF == 2 + mtctr r12 +#else + ld r0,0(r12) # Actual address from fd. + mtctr 0 + ld r11,16(r12) # Environment pointer from fd. + ld r2,8(r12) # TOC pointer from fd. +#endif + + # Load FP and GP registers as required + ld r4, -(23*8)(r31) + ld r5, -(22*8)(r31) + ld r6, -(21*8)(r31) + ld r7, -(20*8)(r31) + ld r8, -(19*8)(r31) + ld r9, -(18*8)(r31) + ld r10, -(17*8)(r31) + + lfd f1, -(16*8)(r31) + lfd f2, -(15*8)(r31) + lfd f3, -(14*8)(r31) + lfd f4, -(13*8)(r31) + lfd f5, -(12*8)(r31) + lfd f6, -(11*8)(r31) + lfd f7, -(10*8)(r31) + lfd f8, -(9*8)(r31) + lfd f9, -(8*8)(r31) + lfd f10, -(7*8)(r31) + lfd f11, -(6*8)(r31) + lfd f12, -(5*8)(r31) + lfd f13, -(4*8)(r31) + + bctrl # Do it + + ld r2,STACK_TOC(r1) # Load our own TOC pointer + ld r1,0(r1) # Revert stack frame + ld 0,16(r1) # Reload lr + ld 29,-24(r1) # Restore NVGPRS + ld 30,-16(r1) + ld 31,-8(r1) + mtlr 0 + blr + +#if _CALL_ELF == 2 + .size NS_InvokeByIndex,.-NS_InvokeByIndex +#else + .size NS_InvokeByIndex,.-.NS_InvokeByIndex +#endif + + # Magic indicating no need for an executable stack + .section .note.GNU-stack, "", @progbits ; .previous Index: mozilla-release/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_ppc64_linux.cpp =================================================================== --- mozilla-release.orig/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_ppc64_linux.cpp +++ mozilla-release/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_ppc64_linux.cpp @@ -74,7 +74,9 @@ invoke_copy_to_stack(uint64_t* gpregs, fpregs[i] = s->val.f; // if passed in registers, floats are promoted to doubles } else { float *p = (float *)d; +#ifndef __LITTLE_ENDIAN__ p++; +#endif *p = s->val.f; } } Index: mozilla-release/xpcom/reflect/xptcall/src/md/unix/xptcstubs_asm_ppc64_linux.s =================================================================== --- mozilla-release.orig/xpcom/reflect/xptcall/src/md/unix/xptcstubs_asm_ppc64_linux.s +++ /dev/null @@ -1,81 +0,0 @@ -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -.set r0,0; .set r1,1; .set RTOC,2; .set r3,3; .set r4,4 -.set r5,5; .set r6,6; .set r7,7; .set r8,8; .set r9,9 -.set r10,10; .set r11,11; .set r12,12; .set r13,13; .set r14,14 -.set r15,15; .set r16,16; .set r17,17; .set r18,18; .set r19,19 -.set r20,20; .set r21,21; .set r22,22; .set r23,23; .set r24,24 -.set r25,25; .set r26,26; .set r27,27; .set r28,28; .set r29,29 -.set r30,30; .set r31,31 -.set f0,0; .set f1,1; .set f2,2; .set f3,3; .set f4,4 -.set f5,5; .set f6,6; .set f7,7; .set f8,8; .set f9,9 -.set f10,10; .set f11,11; .set f12,12; .set f13,13; .set f14,14 -.set f15,15; .set f16,16; .set f17,17; .set f18,18; .set f19,19 -.set f20,20; .set f21,21; .set f22,22; .set f23,23; .set f24,24 -.set f25,25; .set f26,26; .set f27,27; .set f28,28; .set f29,29 -.set f30,30; .set f31,31 - - .section ".text" - .align 2 - .globl SharedStub - .section ".opd","aw" - .align 3 - -SharedStub: - .quad .SharedStub,.TOC.@tocbase - .previous - .type SharedStub,@function - -.SharedStub: - mflr r0 - - std r4, -56(r1) # Save all GPRS - std r5, -48(r1) - std r6, -40(r1) - std r7, -32(r1) - std r8, -24(r1) - std r9, -16(r1) - std r10, -8(r1) - - stfd f13, -64(r1) # ... and FPRS - stfd f12, -72(r1) - stfd f11, -80(r1) - stfd f10, -88(r1) - stfd f9, -96(r1) - stfd f8, -104(r1) - stfd f7, -112(r1) - stfd f6, -120(r1) - stfd f5, -128(r1) - stfd f4, -136(r1) - stfd f3, -144(r1) - stfd f2, -152(r1) - stfd f1, -160(r1) - - subi r6,r1,56 # r6 --> gprData - subi r7,r1,160 # r7 --> fprData - addi r5,r1,112 # r5 --> extra stack args - - std r0, 16(r1) - - stdu r1,-288(r1) - # r3 has the 'self' pointer - # already - - mr r4,r11 # r4 is methodIndex selector, - # passed via r11 in the - # nsNSStubBase::StubXX() call - - bl PrepareAndDispatch - nop - - ld 1,0(r1) # restore stack - ld r0,16(r1) # restore LR - mtlr r0 - blr - - .size SharedStub,.-.SharedStub - - # Magic indicating no need for an executable stack - .section .note.GNU-stack, "", @progbits ; .previous Index: mozilla-release/xpcom/reflect/xptcall/src/md/unix/xptcstubs_asm_ppc64_linux.S =================================================================== --- /dev/null +++ mozilla-release/xpcom/reflect/xptcall/src/md/unix/xptcstubs_asm_ppc64_linux.S @@ -0,0 +1,107 @@ +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +.set r0,0; .set r1,1; .set RTOC,2; .set r3,3; .set r4,4 +.set r5,5; .set r6,6; .set r7,7; .set r8,8; .set r9,9 +.set r10,10; .set r11,11; .set r12,12; .set r13,13; .set r14,14 +.set r15,15; .set r16,16; .set r17,17; .set r18,18; .set r19,19 +.set r20,20; .set r21,21; .set r22,22; .set r23,23; .set r24,24 +.set r25,25; .set r26,26; .set r27,27; .set r28,28; .set r29,29 +.set r30,30; .set r31,31 +.set f0,0; .set f1,1; .set f2,2; .set f3,3; .set f4,4 +.set f5,5; .set f6,6; .set f7,7; .set f8,8; .set f9,9 +.set f10,10; .set f11,11; .set f12,12; .set f13,13; .set f14,14 +.set f15,15; .set f16,16; .set f17,17; .set f18,18; .set f19,19 +.set f20,20; .set f21,21; .set f22,22; .set f23,23; .set f24,24 +.set f25,25; .set f26,26; .set f27,27; .set f28,28; .set f29,29 +.set f30,30; .set f31,31 + +#if _CALL_ELF == 2 +#define STACK_PARAMS 96 +#else +#define STACK_PARAMS 112 +#endif + +#if _CALL_ELF == 2 + .section ".text" + .type SharedStub,@function + .globl SharedStub + # Make the symbol hidden so that the branch from the stub does + # not go via a PLT. This is not only better for performance, + # but may be necessary to avoid linker errors since there is + # no place to restore the TOC register in a sibling call. + .hidden SharedStub + .align 2 +SharedStub: +0: addis 2,12,(.TOC.-0b)@ha + addi 2,2,(.TOC.-0b)@l + .localentry SharedStub,.-SharedStub +#else + .section ".text" + .align 2 + .globl SharedStub + .section ".opd","aw" + .align 3 + +SharedStub: + .quad .SharedStub,.TOC.@tocbase + .previous + .type SharedStub,@function + +.SharedStub: +#endif + mflr r0 + + std r4, -56(r1) # Save all GPRS + std r5, -48(r1) + std r6, -40(r1) + std r7, -32(r1) + std r8, -24(r1) + std r9, -16(r1) + std r10, -8(r1) + + stfd f13, -64(r1) # ... and FPRS + stfd f12, -72(r1) + stfd f11, -80(r1) + stfd f10, -88(r1) + stfd f9, -96(r1) + stfd f8, -104(r1) + stfd f7, -112(r1) + stfd f6, -120(r1) + stfd f5, -128(r1) + stfd f4, -136(r1) + stfd f3, -144(r1) + stfd f2, -152(r1) + stfd f1, -160(r1) + + subi r6,r1,56 # r6 --> gprData + subi r7,r1,160 # r7 --> fprData + addi r5,r1,STACK_PARAMS # r5 --> extra stack args + + std r0, 16(r1) + + stdu r1,-288(r1) + # r3 has the 'self' pointer + # already + + mr r4,r11 # r4 is methodIndex selector, + # passed via r11 in the + # nsNSStubBase::StubXX() call + + bl PrepareAndDispatch + nop + + ld 1,0(r1) # restore stack + ld r0,16(r1) # restore LR + mtlr r0 + blr + +#if _CALL_ELF == 2 + .size SharedStub,.-SharedStub +#else + .size SharedStub,.-.SharedStub +#endif + + # Magic indicating no need for an executable stack + .section .note.GNU-stack, "", @progbits ; .previous Index: mozilla-release/xpcom/reflect/xptcall/src/md/unix/xptcstubs_ppc64_linux.cpp =================================================================== --- mozilla-release.orig/xpcom/reflect/xptcall/src/md/unix/xptcstubs_ppc64_linux.cpp +++ mozilla-release/xpcom/reflect/xptcall/src/md/unix/xptcstubs_ppc64_linux.cpp @@ -83,7 +83,9 @@ PrepareAndDispatch(nsXPTCStubBase* self, dp->val.f = (float) fprData[i]; // in registers floats are passed as doubles else { float *p = (float *)ap; +#ifndef __LITTLE_ENDIAN__ p++; +#endif dp->val.f = *p; } } else { /* integer type or pointer */ @@ -153,6 +155,43 @@ PrepareAndDispatch(nsXPTCStubBase* self, // etc. // Use assembler directives to get the names right... +#if _CALL_ELF == 2 +# define STUB_ENTRY(n) \ +__asm__ ( \ + ".section \".text\" \n\t" \ + ".align 2 \n\t" \ + ".if "#n" < 10 \n\t" \ + ".globl _ZN14nsXPTCStubBase5Stub"#n"Ev \n\t" \ + ".type _ZN14nsXPTCStubBase5Stub"#n"Ev,@function \n\n" \ +"_ZN14nsXPTCStubBase5Stub"#n"Ev: \n\t" \ + "0: addis 2,12,.TOC.-0b@ha \n\t" \ + "addi 2,2,.TOC.-0b@l \n\t" \ + ".localentry _ZN14nsXPTCStubBase5Stub"#n"Ev,.-_ZN14nsXPTCStubBase5Stub"#n"Ev \n\t" \ + \ + ".elseif "#n" < 100 \n\t" \ + ".globl _ZN14nsXPTCStubBase6Stub"#n"Ev \n\t" \ + ".type _ZN14nsXPTCStubBase6Stub"#n"Ev,@function \n\n" \ +"_ZN14nsXPTCStubBase6Stub"#n"Ev: \n\t" \ + "0: addis 2,12,.TOC.-0b@ha \n\t" \ + "addi 2,2,.TOC.-0b@l \n\t" \ + ".localentry _ZN14nsXPTCStubBase6Stub"#n"Ev,.-_ZN14nsXPTCStubBase6Stub"#n"Ev \n\t" \ + \ + ".elseif "#n" < 1000 \n\t" \ + ".globl _ZN14nsXPTCStubBase7Stub"#n"Ev \n\t" \ + ".type _ZN14nsXPTCStubBase7Stub"#n"Ev,@function \n\n" \ +"_ZN14nsXPTCStubBase7Stub"#n"Ev: \n\t" \ + "0: addis 2,12,.TOC.-0b@ha \n\t" \ + "addi 2,2,.TOC.-0b@l \n\t" \ + ".localentry _ZN14nsXPTCStubBase7Stub"#n"Ev,.-_ZN14nsXPTCStubBase7Stub"#n"Ev \n\t" \ + \ + ".else \n\t" \ + ".err \"stub number "#n" >= 1000 not yet supported\"\n" \ + ".endif \n\t" \ + \ + "li 11,"#n" \n\t" \ + "b SharedStub \n" \ +); +#else # define STUB_ENTRY(n) \ __asm__ ( \ ".section \".toc\",\"aw\" \n\t" \ @@ -195,6 +234,7 @@ __asm__ ( "li 11,"#n" \n\t" \ "b SharedStub \n" \ ); +#endif #define SENTINEL_ENTRY(n) \ nsresult nsXPTCStubBase::Sentinel##n() \