From b6e3c51a12ec0d1d94def62283b2e780a4ec0c63 Mon Sep 17 00:00:00 2001 From: Hongchen Zhang Date: Tue, 18 Feb 2025 02:24:45 +0000 Subject: [PATCH] LoongArch: add loongarch support Co-developed-by: Jialing Zhang Signed-off-by: Hongchen Zhang --- BUILD.gn | 26 + install.py | 4 + patch/0001-Support-loongarch64-678.patch | 3226 +++++++++++++++++ ...-static-trampoline-for-LoongArch-723.patch | 139 + ...ch-Fix-a-build-error-with-GCC-14-825.patch | 29 + ...loongarch64-soft-float-build-816-817.patch | 27 + 6 files changed, 3451 insertions(+) create mode 100644 patch/0001-Support-loongarch64-678.patch create mode 100644 patch/0002-static-trampoline-for-LoongArch-723.patch create mode 100644 patch/0003-LoongArch-Fix-a-build-error-with-GCC-14-825.patch create mode 100644 patch/0004-Fix-loongarch64-soft-float-build-816-817.patch diff --git a/BUILD.gn b/BUILD.gn index ac5a68f..564c87d 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -42,6 +42,8 @@ action("libffi_action") { "$libffi_dir/src/alpha/osf.S", "$libffi_dir/src/csky/sysv.S", "$libffi_dir/src/csky/ffi.c", + "$libffi_dir/src/loongarch64/ffi.c", + "$libffi_dir/src/loongarch64/sysv.S", "$libffi_dir/src/bfin/sysv.S", "$libffi_dir/src/bfin/ffi.c", "$libffi_dir/src/sh/sysv.S", @@ -184,6 +186,30 @@ ohos_shared_library("ffi") { "$libffi_dir/src/x86/unix64.S", "$libffi_dir/src/x86/win64.S", ] + } else if (target_cpu == "loongarch64") { + include_dirs = [ + "$libffi_dir", + "$libffi_dir/include", + "$libffi_dir/src/loongarch64", + ] + + cflags = [ + "-DTARGET=LOONGARCH64", + "-Wno-sign-compare", + "-Wno-implicit-function-declaration", + "-Wno-extern-initializer", + ] + + sources = [ + "$libffi_dir/src/closures.c", + "$libffi_dir/src/java_raw_api.c", + "$libffi_dir/src/prep_cif.c", + "$libffi_dir/src/raw_api.c", + "$libffi_dir/src/tramp.c", + "$libffi_dir/src/types.c", + "$libffi_dir/src/loongarch64/ffi.c", + "$libffi_dir/src/loongarch64/sysv.S", + ] } else { include_dirs = [ "$libffi_dir", diff --git a/install.py b/install.py index 9380a09..c40de7b 100755 --- a/install.py +++ b/install.py @@ -27,6 +27,10 @@ patch_files = [ "backport-Fix-signed-vs-unsigned-comparison.patch", "riscv-extend-return-types-smaller-than-ffi_arg-680.patch", "fix-AARCH64EB-support.patch", + "0001-Support-loongarch64-678.patch", + "0002-static-trampoline-for-LoongArch-723.patch", + "0003-LoongArch-Fix-a-build-error-with-GCC-14-825.patch", + "0004-Fix-loongarch64-soft-float-build-816-817.patch", "backport-openharmony-adapt.patch", "backport-openharmony-dummy.patch" ] diff --git a/patch/0001-Support-loongarch64-678.patch b/patch/0001-Support-loongarch64-678.patch new file mode 100644 index 0000000..8946883 --- /dev/null +++ b/patch/0001-Support-loongarch64-678.patch @@ -0,0 +1,3226 @@ +From b2913db7b1cf7d64f0591e4d832ffb5c281aeead Mon Sep 17 00:00:00 2001 +From: zhangwenlong +Date: Wed, 25 May 2022 09:31:08 +0800 +Subject: [PATCH 1/4] Support loongarch64 (#678) + +* update config.{guess,sub} + +* Support loongarch64 + +Co-Authored-By: Cheng Lulu +Co-Authored-By: Xi Ruoyao +Co-Authored-By: Xu Hao +Co-Authored-By: Zhang Wenlong +Co-Authored-By: Pan Xuefeng + +Co-authored-by: panxuefeng +Co-authored-by: Cheng Lulu +Co-authored-by: Xi Ruoyao +--- + Makefile.am | 5 +- + config.guess | 1183 ++++++++++++++++++----------------- + config.sub | 105 +++- + configure.host | 5 + + src/loongarch64/ffi.c | 595 ++++++++++++++++++ + src/loongarch64/ffitarget.h | 82 +++ + src/loongarch64/sysv.S | 296 +++++++++ + 7 files changed, 1678 insertions(+), 593 deletions(-) + create mode 100644 src/loongarch64/ffi.c + create mode 100644 src/loongarch64/ffitarget.h + create mode 100644 src/loongarch64/sysv.S + +diff --git a/Makefile.am b/Makefile.am +index e29722f03839..0b56e60f8ce8 100644 +--- a/Makefile.am ++++ b/Makefile.am +@@ -64,7 +64,8 @@ noinst_HEADERS = src/aarch64/ffitarget.h src/aarch64/internal.h \ + src/sparc/internal.h src/tile/ffitarget.h src/vax/ffitarget.h \ + src/x86/ffitarget.h src/x86/internal.h src/x86/internal64.h \ + src/x86/asmnames.h src/xtensa/ffitarget.h src/dlmalloc.c \ +- src/kvx/ffitarget.h ++ src/kvx/ffitarget.h \ ++ src/loongarch64/ffitarget.h + + EXTRA_libffi_la_SOURCES = src/aarch64/ffi.c src/aarch64/sysv.S \ + src/aarch64/win64_armasm.S src/alpha/ffi.c src/alpha/osf.S \ +@@ -95,7 +96,7 @@ EXTRA_libffi_la_SOURCES = src/aarch64/ffi.c src/aarch64/sysv.S \ + src/x86/ffiw64.c src/x86/win64.S src/x86/ffi64.c \ + src/x86/unix64.S src/x86/sysv_intel.S src/x86/win64_intel.S \ + src/xtensa/ffi.c src/xtensa/sysv.S src/kvx/ffi.c \ +- src/kvx/sysv.S ++ src/kvx/sysv.S src/loongarch64/ffi.c src/loongarch64/sysv.S + + TARGET_OBJ = @TARGET_OBJ@ + libffi_la_LIBADD = $(TARGET_OBJ) +diff --git a/config.guess b/config.guess +index 01a1ef32b0aa..55f27ce019ad 100644 +--- a/config.guess ++++ b/config.guess +@@ -1,12 +1,14 @@ + #! /bin/sh + # Attempt to guess a canonical system name. +-# Copyright 1992-2020 Free Software Foundation, Inc. ++# Copyright 1992-2022 Free Software Foundation, Inc. + +-timestamp='2020-07-12' ++# shellcheck disable=SC2006,SC2268 # see below for rationale ++ ++timestamp='2022-01-09' + + # 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 3 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 +@@ -27,11 +29,19 @@ timestamp='2020-07-12' + # Originally written by Per Bothner; maintained since 2000 by Ben Elliston. + # + # You can get the latest version of this script from: +-# https://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess ++# https://git.savannah.gnu.org/cgit/config.git/plain/config.guess + # + # Please send patches to . + + ++# The "shellcheck disable" line above the timestamp inhibits complaints ++# about features and limitations of the classic Bourne shell that were ++# superseded or lifted in POSIX. However, this script identifies a wide ++# variety of pre-POSIX systems that do not have POSIX shells at all, and ++# even some reasonably current systems (Solaris 10 as case-in-point) still ++# have a pre-POSIX /bin/sh. ++ ++ + me=`echo "$0" | sed -e 's,.*/,,'` + + usage="\ +@@ -50,7 +60,7 @@ version="\ + GNU config.guess ($timestamp) + + Originally written by Per Bothner. +-Copyright 1992-2020 Free Software Foundation, Inc. ++Copyright 1992-2022 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." +@@ -84,6 +94,9 @@ if test $# != 0; then + exit 1 + fi + ++# Just in case it came from the environment. ++GUESS= ++ + # CC_FOR_BUILD -- compiler used by this script. Note that the use of a + # compiler to aid in system detection is discouraged as it requires + # temporary files to be created and, as you can see below, it is a +@@ -102,7 +115,7 @@ set_cc_for_build() { + # prevent multiple calls if $tmp is already set + test "$tmp" && return 0 + : "${TMPDIR=/tmp}" +- # shellcheck disable=SC2039 ++ # shellcheck disable=SC2039,SC3028 + { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || + { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir "$tmp" 2>/dev/null) ; } || + { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir "$tmp" 2>/dev/null) && echo "Warning: creating insecure temp directory" >&2 ; } || +@@ -112,7 +125,7 @@ set_cc_for_build() { + ,,) echo "int x;" > "$dummy.c" + for driver in cc gcc c89 c99 ; do + if ($driver -c -o "$dummy.o" "$dummy.c") >/dev/null 2>&1 ; then +- CC_FOR_BUILD="$driver" ++ CC_FOR_BUILD=$driver + break + fi + done +@@ -133,14 +146,12 @@ fi + + UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown + UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown +-UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown ++UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown + UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown + +-case "$UNAME_SYSTEM" in ++case $UNAME_SYSTEM in + Linux|GNU|GNU/*) +- # If the system lacks a compiler, then just pick glibc. +- # We could probably try harder. +- LIBC=gnu ++ LIBC=unknown + + set_cc_for_build + cat <<-EOF > "$dummy.c" +@@ -149,24 +160,37 @@ Linux|GNU|GNU/*) + LIBC=uclibc + #elif defined(__dietlibc__) + LIBC=dietlibc +- #else ++ #elif defined(__GLIBC__) + LIBC=gnu ++ #else ++ #include ++ /* First heuristic to detect musl libc. */ ++ #ifdef __DEFINED_va_list ++ LIBC=musl ++ #endif + #endif + EOF +- eval "`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^LIBC' | sed 's, ,,g'`" ++ cc_set_libc=`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^LIBC' | sed 's, ,,g'` ++ eval "$cc_set_libc" + +- # If ldd exists, use it to detect musl libc. +- if command -v ldd >/dev/null && \ +- ldd --version 2>&1 | grep -q ^musl +- then +- LIBC=musl ++ # Second heuristic to detect musl libc. ++ if [ "$LIBC" = unknown ] && ++ command -v ldd >/dev/null && ++ ldd --version 2>&1 | grep -q ^musl; then ++ LIBC=musl ++ fi ++ ++ # If the system lacks a compiler, then just pick glibc. ++ # We could probably try harder. ++ if [ "$LIBC" = unknown ]; then ++ LIBC=gnu + fi + ;; + esac + + # Note: order is significant - the case branches are not exclusive. + +-case "$UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION" in ++case $UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION in + *:NetBSD:*:*) + # NetBSD (nbsd) targets should (where applicable) match one or + # more of the tuples: *-*-netbsdelf*, *-*-netbsdaout*, +@@ -178,12 +202,12 @@ case "$UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION" in + # + # Note: NetBSD doesn't particularly care about the vendor + # portion of the name. We always set it to "unknown". +- sysctl="sysctl -n hw.machine_arch" + UNAME_MACHINE_ARCH=`(uname -p 2>/dev/null || \ +- "/sbin/$sysctl" 2>/dev/null || \ +- "/usr/sbin/$sysctl" 2>/dev/null || \ ++ /sbin/sysctl -n hw.machine_arch 2>/dev/null || \ ++ /usr/sbin/sysctl -n hw.machine_arch 2>/dev/null || \ + echo unknown)` +- case "$UNAME_MACHINE_ARCH" in ++ case $UNAME_MACHINE_ARCH in ++ aarch64eb) machine=aarch64_be-unknown ;; + armeb) machine=armeb-unknown ;; + arm*) machine=arm-unknown ;; + sh3el) machine=shl-unknown ;; +@@ -192,13 +216,13 @@ case "$UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION" in + earmv*) + arch=`echo "$UNAME_MACHINE_ARCH" | sed -e 's,^e\(armv[0-9]\).*$,\1,'` + endian=`echo "$UNAME_MACHINE_ARCH" | sed -ne 's,^.*\(eb\)$,\1,p'` +- machine="${arch}${endian}"-unknown ++ machine=${arch}${endian}-unknown + ;; +- *) machine="$UNAME_MACHINE_ARCH"-unknown ;; ++ *) machine=$UNAME_MACHINE_ARCH-unknown ;; + esac + # The Operating System including object format, if it has switched + # to ELF recently (or will in the future) and ABI. +- case "$UNAME_MACHINE_ARCH" in ++ case $UNAME_MACHINE_ARCH in + earm*) + os=netbsdelf + ;; +@@ -219,7 +243,7 @@ case "$UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION" in + ;; + esac + # Determine ABI tags. +- case "$UNAME_MACHINE_ARCH" in ++ case $UNAME_MACHINE_ARCH in + earm*) + expr='s/^earmv[0-9]/-eabi/;s/eb$//' + abi=`echo "$UNAME_MACHINE_ARCH" | sed -e "$expr"` +@@ -230,7 +254,7 @@ case "$UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION" in + # thus, need a distinct triplet. However, they do not need + # kernel version information, so it can be replaced with a + # suitable tag, in the style of linux-gnu. +- case "$UNAME_VERSION" in ++ case $UNAME_VERSION in + Debian*) + release='-gnu' + ;; +@@ -241,51 +265,57 @@ case "$UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION" in + # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: + # contains redundant information, the shorter form: + # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. +- echo "$machine-${os}${release}${abi-}" +- exit ;; ++ GUESS=$machine-${os}${release}${abi-} ++ ;; + *:Bitrig:*:*) + UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'` +- echo "$UNAME_MACHINE_ARCH"-unknown-bitrig"$UNAME_RELEASE" +- exit ;; ++ GUESS=$UNAME_MACHINE_ARCH-unknown-bitrig$UNAME_RELEASE ++ ;; + *:OpenBSD:*:*) + UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'` +- echo "$UNAME_MACHINE_ARCH"-unknown-openbsd"$UNAME_RELEASE" +- exit ;; ++ GUESS=$UNAME_MACHINE_ARCH-unknown-openbsd$UNAME_RELEASE ++ ;; ++ *:SecBSD:*:*) ++ UNAME_MACHINE_ARCH=`arch | sed 's/SecBSD.//'` ++ GUESS=$UNAME_MACHINE_ARCH-unknown-secbsd$UNAME_RELEASE ++ ;; + *:LibertyBSD:*:*) + UNAME_MACHINE_ARCH=`arch | sed 's/^.*BSD\.//'` +- echo "$UNAME_MACHINE_ARCH"-unknown-libertybsd"$UNAME_RELEASE" +- exit ;; ++ GUESS=$UNAME_MACHINE_ARCH-unknown-libertybsd$UNAME_RELEASE ++ ;; + *:MidnightBSD:*:*) +- echo "$UNAME_MACHINE"-unknown-midnightbsd"$UNAME_RELEASE" +- exit ;; ++ GUESS=$UNAME_MACHINE-unknown-midnightbsd$UNAME_RELEASE ++ ;; + *:ekkoBSD:*:*) +- echo "$UNAME_MACHINE"-unknown-ekkobsd"$UNAME_RELEASE" +- exit ;; ++ GUESS=$UNAME_MACHINE-unknown-ekkobsd$UNAME_RELEASE ++ ;; + *:SolidBSD:*:*) +- echo "$UNAME_MACHINE"-unknown-solidbsd"$UNAME_RELEASE" +- exit ;; ++ GUESS=$UNAME_MACHINE-unknown-solidbsd$UNAME_RELEASE ++ ;; + *:OS108:*:*) +- echo "$UNAME_MACHINE"-unknown-os108_"$UNAME_RELEASE" +- exit ;; ++ GUESS=$UNAME_MACHINE-unknown-os108_$UNAME_RELEASE ++ ;; + macppc:MirBSD:*:*) +- echo powerpc-unknown-mirbsd"$UNAME_RELEASE" +- exit ;; ++ GUESS=powerpc-unknown-mirbsd$UNAME_RELEASE ++ ;; + *:MirBSD:*:*) +- echo "$UNAME_MACHINE"-unknown-mirbsd"$UNAME_RELEASE" +- exit ;; ++ GUESS=$UNAME_MACHINE-unknown-mirbsd$UNAME_RELEASE ++ ;; + *:Sortix:*:*) +- echo "$UNAME_MACHINE"-unknown-sortix +- exit ;; ++ GUESS=$UNAME_MACHINE-unknown-sortix ++ ;; + *:Twizzler:*:*) +- echo "$UNAME_MACHINE"-unknown-twizzler +- exit ;; ++ GUESS=$UNAME_MACHINE-unknown-twizzler ++ ;; + *:Redox:*:*) +- echo "$UNAME_MACHINE"-unknown-redox +- exit ;; ++ GUESS=$UNAME_MACHINE-unknown-redox ++ ;; + mips:OSF1:*.*) +- echo mips-dec-osf1 +- exit ;; ++ GUESS=mips-dec-osf1 ++ ;; + alpha:OSF1:*:*) ++ # Reset EXIT trap before exiting to avoid spurious non-zero exit code. ++ trap '' 0 + case $UNAME_RELEASE in + *4.0) + UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` +@@ -299,7 +329,7 @@ case "$UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION" in + # covers most systems running today. This code pipes the CPU + # types through head -n 1, so we only detect the type of CPU 0. + ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1` +- case "$ALPHA_CPU_TYPE" in ++ case $ALPHA_CPU_TYPE in + "EV4 (21064)") + UNAME_MACHINE=alpha ;; + "EV4.5 (21064)") +@@ -336,117 +366,121 @@ case "$UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION" in + # A Tn.n version is a released field test version. + # 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`" +- # Reset EXIT trap before exiting to avoid spurious non-zero exit code. +- exitcode=$? +- trap '' 0 +- exit $exitcode ;; ++ OSF_REL=`echo "$UNAME_RELEASE" | sed -e 's/^[PVTX]//' | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz` ++ GUESS=$UNAME_MACHINE-dec-osf$OSF_REL ++ ;; + Amiga*:UNIX_System_V:4.0:*) +- echo m68k-unknown-sysv4 +- exit ;; ++ GUESS=m68k-unknown-sysv4 ++ ;; + *:[Aa]miga[Oo][Ss]:*:*) +- echo "$UNAME_MACHINE"-unknown-amigaos +- exit ;; ++ GUESS=$UNAME_MACHINE-unknown-amigaos ++ ;; + *:[Mm]orph[Oo][Ss]:*:*) +- echo "$UNAME_MACHINE"-unknown-morphos +- exit ;; ++ GUESS=$UNAME_MACHINE-unknown-morphos ++ ;; + *:OS/390:*:*) +- echo i370-ibm-openedition +- exit ;; ++ GUESS=i370-ibm-openedition ++ ;; + *:z/VM:*:*) +- echo s390-ibm-zvmoe +- exit ;; ++ GUESS=s390-ibm-zvmoe ++ ;; + *:OS400:*:*) +- echo powerpc-ibm-os400 +- exit ;; ++ GUESS=powerpc-ibm-os400 ++ ;; + arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) +- echo arm-acorn-riscix"$UNAME_RELEASE" +- exit ;; ++ GUESS=arm-acorn-riscix$UNAME_RELEASE ++ ;; + arm*:riscos:*:*|arm*:RISCOS:*:*) +- echo arm-unknown-riscos +- exit ;; ++ GUESS=arm-unknown-riscos ++ ;; + SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) +- echo hppa1.1-hitachi-hiuxmpp +- exit ;; ++ GUESS=hppa1.1-hitachi-hiuxmpp ++ ;; + Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) + # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. +- if test "`(/bin/universe) 2>/dev/null`" = att ; then +- echo pyramid-pyramid-sysv3 +- else +- echo pyramid-pyramid-bsd +- fi +- exit ;; ++ case `(/bin/universe) 2>/dev/null` in ++ att) GUESS=pyramid-pyramid-sysv3 ;; ++ *) GUESS=pyramid-pyramid-bsd ;; ++ esac ++ ;; + NILE*:*:*:dcosx) +- echo pyramid-pyramid-svr4 +- exit ;; ++ GUESS=pyramid-pyramid-svr4 ++ ;; + DRS?6000:unix:4.0:6*) +- echo sparc-icl-nx6 +- exit ;; ++ GUESS=sparc-icl-nx6 ++ ;; + DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*) + case `/usr/bin/uname -p` in +- sparc) echo sparc-icl-nx7; exit ;; +- esac ;; ++ sparc) GUESS=sparc-icl-nx7 ;; ++ esac ++ ;; + s390x:SunOS:*:*) +- echo "$UNAME_MACHINE"-ibm-solaris2"`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'`" +- exit ;; ++ SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'` ++ GUESS=$UNAME_MACHINE-ibm-solaris2$SUN_REL ++ ;; + sun4H:SunOS:5.*:*) +- echo sparc-hal-solaris2"`echo "$UNAME_RELEASE"|sed -e 's/[^.]*//'`" +- exit ;; ++ SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'` ++ GUESS=sparc-hal-solaris2$SUN_REL ++ ;; + sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) +- echo sparc-sun-solaris2"`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'`" +- exit ;; ++ SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'` ++ GUESS=sparc-sun-solaris2$SUN_REL ++ ;; + i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*) +- echo i386-pc-auroraux"$UNAME_RELEASE" +- exit ;; ++ GUESS=i386-pc-auroraux$UNAME_RELEASE ++ ;; + i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*) + set_cc_for_build + SUN_ARCH=i386 + # If there is a compiler, see if it is configured for 64-bit objects. + # Note that the Sun cc does not turn __LP64__ into 1 like gcc does. + # This test works for both compilers. +- if [ "$CC_FOR_BUILD" != no_compiler_found ]; then ++ if test "$CC_FOR_BUILD" != no_compiler_found; then + if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \ +- (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \ ++ (CCOPTS="" $CC_FOR_BUILD -m64 -E - 2>/dev/null) | \ + grep IS_64BIT_ARCH >/dev/null + then + SUN_ARCH=x86_64 + fi + fi +- echo "$SUN_ARCH"-pc-solaris2"`echo "$UNAME_RELEASE"|sed -e 's/[^.]*//'`" +- exit ;; ++ SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'` ++ GUESS=$SUN_ARCH-pc-solaris2$SUN_REL ++ ;; + sun4*:SunOS:6*:*) + # According to config.sub, this is the proper way to canonicalize + # SunOS6. Hard to guess exactly what SunOS6 will be like, but + # it's likely to be more like Solaris than SunOS4. +- echo sparc-sun-solaris3"`echo "$UNAME_RELEASE"|sed -e 's/[^.]*//'`" +- exit ;; ++ SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'` ++ GUESS=sparc-sun-solaris3$SUN_REL ++ ;; + sun4*:SunOS:*:*) +- case "`/usr/bin/arch -k`" in ++ case `/usr/bin/arch -k` in + Series*|S4*) + UNAME_RELEASE=`uname -v` + ;; + esac + # Japanese Language versions have a version number like `4.1.3-JL'. +- echo sparc-sun-sunos"`echo "$UNAME_RELEASE"|sed -e 's/-/_/'`" +- exit ;; ++ SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/-/_/'` ++ GUESS=sparc-sun-sunos$SUN_REL ++ ;; + sun3*:SunOS:*:*) +- echo m68k-sun-sunos"$UNAME_RELEASE" +- exit ;; ++ GUESS=m68k-sun-sunos$UNAME_RELEASE ++ ;; + sun*:*:4.2BSD:*) + UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` + test "x$UNAME_RELEASE" = x && UNAME_RELEASE=3 +- case "`/bin/arch`" in ++ case `/bin/arch` in + sun3) +- echo m68k-sun-sunos"$UNAME_RELEASE" ++ GUESS=m68k-sun-sunos$UNAME_RELEASE + ;; + sun4) +- echo sparc-sun-sunos"$UNAME_RELEASE" ++ GUESS=sparc-sun-sunos$UNAME_RELEASE + ;; + esac +- exit ;; ++ ;; + aushp:SunOS:*:*) +- echo sparc-auspex-sunos"$UNAME_RELEASE" +- exit ;; ++ GUESS=sparc-auspex-sunos$UNAME_RELEASE ++ ;; + # The situation for MiNT is a little confusing. The machine name + # can be virtually everything (everything which is not + # "atarist" or "atariste" at least should have a processor +@@ -456,41 +490,41 @@ case "$UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION" in + # 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" +- exit ;; ++ GUESS=m68k-atari-mint$UNAME_RELEASE ++ ;; + atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) +- echo m68k-atari-mint"$UNAME_RELEASE" +- exit ;; ++ GUESS=m68k-atari-mint$UNAME_RELEASE ++ ;; + *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) +- echo m68k-atari-mint"$UNAME_RELEASE" +- exit ;; ++ GUESS=m68k-atari-mint$UNAME_RELEASE ++ ;; + milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) +- echo m68k-milan-mint"$UNAME_RELEASE" +- exit ;; ++ GUESS=m68k-milan-mint$UNAME_RELEASE ++ ;; + hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) +- echo m68k-hades-mint"$UNAME_RELEASE" +- exit ;; ++ GUESS=m68k-hades-mint$UNAME_RELEASE ++ ;; + *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) +- echo m68k-unknown-mint"$UNAME_RELEASE" +- exit ;; ++ GUESS=m68k-unknown-mint$UNAME_RELEASE ++ ;; + m68k:machten:*:*) +- echo m68k-apple-machten"$UNAME_RELEASE" +- exit ;; ++ GUESS=m68k-apple-machten$UNAME_RELEASE ++ ;; + powerpc:machten:*:*) +- echo powerpc-apple-machten"$UNAME_RELEASE" +- exit ;; ++ GUESS=powerpc-apple-machten$UNAME_RELEASE ++ ;; + RISC*:Mach:*:*) +- echo mips-dec-mach_bsd4.3 +- exit ;; ++ GUESS=mips-dec-mach_bsd4.3 ++ ;; + RISC*:ULTRIX:*:*) +- echo mips-dec-ultrix"$UNAME_RELEASE" +- exit ;; ++ GUESS=mips-dec-ultrix$UNAME_RELEASE ++ ;; + VAX*:ULTRIX*:*:*) +- echo vax-dec-ultrix"$UNAME_RELEASE" +- exit ;; ++ GUESS=vax-dec-ultrix$UNAME_RELEASE ++ ;; + 2020:CLIX:*:* | 2430:CLIX:*:*) +- echo clipper-intergraph-clix"$UNAME_RELEASE" +- exit ;; ++ GUESS=clipper-intergraph-clix$UNAME_RELEASE ++ ;; + mips:*:*:UMIPS | mips:*:*:RISCos) + set_cc_for_build + sed 's/^ //' << EOF > "$dummy.c" +@@ -518,75 +552,76 @@ EOF + dummyarg=`echo "$UNAME_RELEASE" | sed -n 's/\([0-9]*\).*/\1/p'` && + SYSTEM_NAME=`"$dummy" "$dummyarg"` && + { echo "$SYSTEM_NAME"; exit; } +- echo mips-mips-riscos"$UNAME_RELEASE" +- exit ;; ++ GUESS=mips-mips-riscos$UNAME_RELEASE ++ ;; + Motorola:PowerMAX_OS:*:*) +- echo powerpc-motorola-powermax +- exit ;; ++ GUESS=powerpc-motorola-powermax ++ ;; + Motorola:*:4.3:PL8-*) +- echo powerpc-harris-powermax +- exit ;; ++ GUESS=powerpc-harris-powermax ++ ;; + Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*) +- echo powerpc-harris-powermax +- exit ;; ++ GUESS=powerpc-harris-powermax ++ ;; + Night_Hawk:Power_UNIX:*:*) +- echo powerpc-harris-powerunix +- exit ;; ++ GUESS=powerpc-harris-powerunix ++ ;; + m88k:CX/UX:7*:*) +- echo m88k-harris-cxux7 +- exit ;; ++ GUESS=m88k-harris-cxux7 ++ ;; + m88k:*:4*:R4*) +- echo m88k-motorola-sysv4 +- exit ;; ++ GUESS=m88k-motorola-sysv4 ++ ;; + m88k:*:3*:R3*) +- echo m88k-motorola-sysv3 +- exit ;; ++ GUESS=m88k-motorola-sysv3 ++ ;; + AViiON:dgux:*:*) + # DG/UX returns AViiON for all architectures + UNAME_PROCESSOR=`/usr/bin/uname -p` +- if [ "$UNAME_PROCESSOR" = mc88100 ] || [ "$UNAME_PROCESSOR" = mc88110 ] ++ if test "$UNAME_PROCESSOR" = mc88100 || test "$UNAME_PROCESSOR" = mc88110 + then +- if [ "$TARGET_BINARY_INTERFACE"x = m88kdguxelfx ] || \ +- [ "$TARGET_BINARY_INTERFACE"x = x ] ++ if test "$TARGET_BINARY_INTERFACE"x = m88kdguxelfx || \ ++ test "$TARGET_BINARY_INTERFACE"x = x + then +- echo m88k-dg-dgux"$UNAME_RELEASE" ++ GUESS=m88k-dg-dgux$UNAME_RELEASE + else +- echo m88k-dg-dguxbcs"$UNAME_RELEASE" ++ GUESS=m88k-dg-dguxbcs$UNAME_RELEASE + fi + else +- echo i586-dg-dgux"$UNAME_RELEASE" ++ GUESS=i586-dg-dgux$UNAME_RELEASE + fi +- exit ;; ++ ;; + M88*:DolphinOS:*:*) # DolphinOS (SVR3) +- echo m88k-dolphin-sysv3 +- exit ;; ++ GUESS=m88k-dolphin-sysv3 ++ ;; + M88*:*:R3*:*) + # Delta 88k system running SVR3 +- echo m88k-motorola-sysv3 +- exit ;; ++ GUESS=m88k-motorola-sysv3 ++ ;; + XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) +- echo m88k-tektronix-sysv3 +- exit ;; ++ GUESS=m88k-tektronix-sysv3 ++ ;; + Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) +- echo m68k-tektronix-bsd +- exit ;; ++ GUESS=m68k-tektronix-bsd ++ ;; + *:IRIX*:*:*) +- echo mips-sgi-irix"`echo "$UNAME_RELEASE"|sed -e 's/-/_/g'`" +- exit ;; ++ IRIX_REL=`echo "$UNAME_RELEASE" | sed -e 's/-/_/g'` ++ GUESS=mips-sgi-irix$IRIX_REL ++ ;; + ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. +- echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id +- exit ;; # Note that: echo "'`uname -s`'" gives 'AIX ' ++ GUESS=romp-ibm-aix # uname -m gives an 8 hex-code CPU id ++ ;; # Note that: echo "'`uname -s`'" gives 'AIX ' + i*86:AIX:*:*) +- echo i386-ibm-aix +- exit ;; ++ GUESS=i386-ibm-aix ++ ;; + ia64:AIX:*:*) +- if [ -x /usr/bin/oslevel ] ; then ++ if test -x /usr/bin/oslevel ; then + IBM_REV=`/usr/bin/oslevel` + else +- IBM_REV="$UNAME_VERSION.$UNAME_RELEASE" ++ IBM_REV=$UNAME_VERSION.$UNAME_RELEASE + fi +- echo "$UNAME_MACHINE"-ibm-aix"$IBM_REV" +- exit ;; ++ GUESS=$UNAME_MACHINE-ibm-aix$IBM_REV ++ ;; + *:AIX:2:3) + if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then + set_cc_for_build +@@ -603,16 +638,16 @@ EOF + EOF + if $CC_FOR_BUILD -o "$dummy" "$dummy.c" && SYSTEM_NAME=`"$dummy"` + then +- echo "$SYSTEM_NAME" ++ GUESS=$SYSTEM_NAME + else +- echo rs6000-ibm-aix3.2.5 ++ GUESS=rs6000-ibm-aix3.2.5 + fi + elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then +- echo rs6000-ibm-aix3.2.4 ++ GUESS=rs6000-ibm-aix3.2.4 + else +- echo rs6000-ibm-aix3.2 ++ GUESS=rs6000-ibm-aix3.2 + fi +- exit ;; ++ ;; + *: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 +@@ -620,56 +655,56 @@ EOF + else + IBM_ARCH=powerpc + fi +- if [ -x /usr/bin/lslpp ] ; then +- IBM_REV=`/usr/bin/lslpp -Lqc bos.rte.libc | ++ if test -x /usr/bin/lslpp ; then ++ IBM_REV=`/usr/bin/lslpp -Lqc bos.rte.libc | \ + awk -F: '{ print $3 }' | sed s/[0-9]*$/0/` + else +- IBM_REV="$UNAME_VERSION.$UNAME_RELEASE" ++ IBM_REV=$UNAME_VERSION.$UNAME_RELEASE + fi +- echo "$IBM_ARCH"-ibm-aix"$IBM_REV" +- exit ;; ++ GUESS=$IBM_ARCH-ibm-aix$IBM_REV ++ ;; + *:AIX:*:*) +- echo rs6000-ibm-aix +- exit ;; ++ GUESS=rs6000-ibm-aix ++ ;; + ibmrt:4.4BSD:*|romp-ibm:4.4BSD:*) +- echo romp-ibm-bsd4.4 +- exit ;; ++ GUESS=romp-ibm-bsd4.4 ++ ;; + ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and +- echo romp-ibm-bsd"$UNAME_RELEASE" # 4.3 with uname added to +- exit ;; # report: romp-ibm BSD 4.3 ++ GUESS=romp-ibm-bsd$UNAME_RELEASE # 4.3 with uname added to ++ ;; # report: romp-ibm BSD 4.3 + *:BOSX:*:*) +- echo rs6000-bull-bosx +- exit ;; ++ GUESS=rs6000-bull-bosx ++ ;; + DPX/2?00:B.O.S.:*:*) +- echo m68k-bull-sysv3 +- exit ;; ++ GUESS=m68k-bull-sysv3 ++ ;; + 9000/[34]??:4.3bsd:1.*:*) +- echo m68k-hp-bsd +- exit ;; ++ GUESS=m68k-hp-bsd ++ ;; + hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) +- echo m68k-hp-bsd4.4 +- exit ;; ++ GUESS=m68k-hp-bsd4.4 ++ ;; + 9000/[34678]??:HP-UX:*:*) +- HPUX_REV=`echo "$UNAME_RELEASE"|sed -e 's/[^.]*.[0B]*//'` +- case "$UNAME_MACHINE" in ++ HPUX_REV=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*.[0B]*//'` ++ case $UNAME_MACHINE in + 9000/31?) HP_ARCH=m68000 ;; + 9000/[34]??) HP_ARCH=m68k ;; + 9000/[678][0-9][0-9]) +- if [ -x /usr/bin/getconf ]; then ++ if test -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 ++ 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 ++ 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 + fi +- if [ "$HP_ARCH" = "" ]; then ++ if test "$HP_ARCH" = ""; then + set_cc_for_build + sed 's/^ //' << EOF > "$dummy.c" + +@@ -708,7 +743,7 @@ EOF + test -z "$HP_ARCH" && HP_ARCH=hppa + fi ;; + esac +- if [ "$HP_ARCH" = hppa2.0w ] ++ if test "$HP_ARCH" = hppa2.0w + then + set_cc_for_build + +@@ -729,12 +764,12 @@ EOF + HP_ARCH=hppa64 + fi + fi +- echo "$HP_ARCH"-hp-hpux"$HPUX_REV" +- exit ;; ++ GUESS=$HP_ARCH-hp-hpux$HPUX_REV ++ ;; + ia64:HP-UX:*:*) +- HPUX_REV=`echo "$UNAME_RELEASE"|sed -e 's/[^.]*.[0B]*//'` +- echo ia64-hp-hpux"$HPUX_REV" +- exit ;; ++ HPUX_REV=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*.[0B]*//'` ++ GUESS=ia64-hp-hpux$HPUX_REV ++ ;; + 3050*:HI-UX:*:*) + set_cc_for_build + sed 's/^ //' << EOF > "$dummy.c" +@@ -764,36 +799,36 @@ EOF + EOF + $CC_FOR_BUILD -o "$dummy" "$dummy.c" && SYSTEM_NAME=`"$dummy"` && + { echo "$SYSTEM_NAME"; exit; } +- echo unknown-hitachi-hiuxwe2 +- exit ;; ++ GUESS=unknown-hitachi-hiuxwe2 ++ ;; + 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:*) +- echo hppa1.1-hp-bsd +- exit ;; ++ GUESS=hppa1.1-hp-bsd ++ ;; + 9000/8??:4.3bsd:*:*) +- echo hppa1.0-hp-bsd +- exit ;; ++ GUESS=hppa1.0-hp-bsd ++ ;; + *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) +- echo hppa1.0-hp-mpeix +- exit ;; ++ GUESS=hppa1.0-hp-mpeix ++ ;; + hp7??:OSF1:*:* | hp8?[79]:OSF1:*:*) +- echo hppa1.1-hp-osf +- exit ;; ++ GUESS=hppa1.1-hp-osf ++ ;; + hp8??:OSF1:*:*) +- echo hppa1.0-hp-osf +- exit ;; ++ GUESS=hppa1.0-hp-osf ++ ;; + i*86:OSF1:*:*) +- if [ -x /usr/sbin/sysversion ] ; then +- echo "$UNAME_MACHINE"-unknown-osf1mk ++ if test -x /usr/sbin/sysversion ; then ++ GUESS=$UNAME_MACHINE-unknown-osf1mk + else +- echo "$UNAME_MACHINE"-unknown-osf1 ++ GUESS=$UNAME_MACHINE-unknown-osf1 + fi +- exit ;; ++ ;; + parisc*:Lites*:*:*) +- echo hppa1.1-hp-lites +- exit ;; ++ GUESS=hppa1.1-hp-lites ++ ;; + C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) +- echo c1-convex-bsd +- exit ;; ++ GUESS=c1-convex-bsd ++ ;; + C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd +@@ -801,17 +836,18 @@ EOF + fi + exit ;; + C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) +- echo c34-convex-bsd +- exit ;; ++ GUESS=c34-convex-bsd ++ ;; + C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) +- echo c38-convex-bsd +- exit ;; ++ GUESS=c38-convex-bsd ++ ;; + C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) +- echo c4-convex-bsd +- exit ;; ++ GUESS=c4-convex-bsd ++ ;; + CRAY*Y-MP:*:*:*) +- echo ymp-cray-unicos"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/' +- exit ;; ++ CRAY_REL=`echo "$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'` ++ GUESS=ymp-cray-unicos$CRAY_REL ++ ;; + CRAY*[A-Z]90:*:*:*) + echo "$UNAME_MACHINE"-cray-unicos"$UNAME_RELEASE" \ + | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ +@@ -819,120 +855,135 @@ EOF + -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*TS:*:*:*) +- echo t90-cray-unicos"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/' +- exit ;; ++ CRAY_REL=`echo "$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'` ++ GUESS=t90-cray-unicos$CRAY_REL ++ ;; + CRAY*T3E:*:*:*) +- echo alphaev5-cray-unicosmk"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/' +- exit ;; ++ CRAY_REL=`echo "$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'` ++ GUESS=alphaev5-cray-unicosmk$CRAY_REL ++ ;; + CRAY*SV1:*:*:*) +- echo sv1-cray-unicos"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/' +- exit ;; ++ CRAY_REL=`echo "$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'` ++ GUESS=sv1-cray-unicos$CRAY_REL ++ ;; + *:UNICOS/mp:*:*) +- echo craynv-cray-unicosmp"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/' +- exit ;; ++ CRAY_REL=`echo "$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'` ++ GUESS=craynv-cray-unicosmp$CRAY_REL ++ ;; + 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 ;; ++ GUESS=${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL} ++ ;; + 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}" +- exit ;; ++ GUESS=sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL} ++ ;; + i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) +- echo "$UNAME_MACHINE"-pc-bsdi"$UNAME_RELEASE" +- exit ;; ++ GUESS=$UNAME_MACHINE-pc-bsdi$UNAME_RELEASE ++ ;; + sparc*:BSD/OS:*:*) +- echo sparc-unknown-bsdi"$UNAME_RELEASE" +- exit ;; ++ GUESS=sparc-unknown-bsdi$UNAME_RELEASE ++ ;; + *:BSD/OS:*:*) +- echo "$UNAME_MACHINE"-unknown-bsdi"$UNAME_RELEASE" +- exit ;; ++ GUESS=$UNAME_MACHINE-unknown-bsdi$UNAME_RELEASE ++ ;; + arm:FreeBSD:*:*) + UNAME_PROCESSOR=`uname -p` + set_cc_for_build + if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep -q __ARM_PCS_VFP + then +- echo "${UNAME_PROCESSOR}"-unknown-freebsd"`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`"-gnueabi ++ FREEBSD_REL=`echo "$UNAME_RELEASE" | sed -e 's/[-(].*//'` ++ GUESS=$UNAME_PROCESSOR-unknown-freebsd$FREEBSD_REL-gnueabi + else +- echo "${UNAME_PROCESSOR}"-unknown-freebsd"`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`"-gnueabihf ++ FREEBSD_REL=`echo "$UNAME_RELEASE" | sed -e 's/[-(].*//'` ++ GUESS=$UNAME_PROCESSOR-unknown-freebsd$FREEBSD_REL-gnueabihf + fi +- exit ;; ++ ;; + *:FreeBSD:*:*) + UNAME_PROCESSOR=`/usr/bin/uname -p` +- case "$UNAME_PROCESSOR" in ++ case $UNAME_PROCESSOR in + amd64) + UNAME_PROCESSOR=x86_64 ;; + i386) + UNAME_PROCESSOR=i586 ;; + esac +- echo "$UNAME_PROCESSOR"-unknown-freebsd"`echo "$UNAME_RELEASE"|sed -e 's/[-(].*//'`" +- exit ;; ++ FREEBSD_REL=`echo "$UNAME_RELEASE" | sed -e 's/[-(].*//'` ++ GUESS=$UNAME_PROCESSOR-unknown-freebsd$FREEBSD_REL ++ ;; + i*:CYGWIN*:*) +- echo "$UNAME_MACHINE"-pc-cygwin +- exit ;; ++ GUESS=$UNAME_MACHINE-pc-cygwin ++ ;; + *:MINGW64*:*) +- echo "$UNAME_MACHINE"-pc-mingw64 +- exit ;; ++ GUESS=$UNAME_MACHINE-pc-mingw64 ++ ;; + *:MINGW*:*) +- echo "$UNAME_MACHINE"-pc-mingw32 +- exit ;; ++ GUESS=$UNAME_MACHINE-pc-mingw32 ++ ;; + *:MSYS*:*) +- echo "$UNAME_MACHINE"-pc-msys +- exit ;; ++ GUESS=$UNAME_MACHINE-pc-msys ++ ;; + i*:PW*:*) +- echo "$UNAME_MACHINE"-pc-pw32 +- exit ;; ++ GUESS=$UNAME_MACHINE-pc-pw32 ++ ;; ++ *:SerenityOS:*:*) ++ GUESS=$UNAME_MACHINE-pc-serenity ++ ;; + *:Interix*:*) +- case "$UNAME_MACHINE" in ++ case $UNAME_MACHINE in + x86) +- echo i586-pc-interix"$UNAME_RELEASE" +- exit ;; ++ GUESS=i586-pc-interix$UNAME_RELEASE ++ ;; + authenticamd | genuineintel | EM64T) +- echo x86_64-unknown-interix"$UNAME_RELEASE" +- exit ;; ++ GUESS=x86_64-unknown-interix$UNAME_RELEASE ++ ;; + IA64) +- echo ia64-unknown-interix"$UNAME_RELEASE" +- exit ;; ++ GUESS=ia64-unknown-interix$UNAME_RELEASE ++ ;; + esac ;; + i*:UWIN*:*) +- echo "$UNAME_MACHINE"-pc-uwin +- exit ;; ++ GUESS=$UNAME_MACHINE-pc-uwin ++ ;; + amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*) +- echo x86_64-pc-cygwin +- exit ;; ++ GUESS=x86_64-pc-cygwin ++ ;; + prep*:SunOS:5.*:*) +- echo powerpcle-unknown-solaris2"`echo "$UNAME_RELEASE"|sed -e 's/[^.]*//'`" +- exit ;; ++ SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'` ++ GUESS=powerpcle-unknown-solaris2$SUN_REL ++ ;; + *:GNU:*:*) + # the GNU system +- echo "`echo "$UNAME_MACHINE"|sed -e 's,[-/].*$,,'`-unknown-$LIBC`echo "$UNAME_RELEASE"|sed -e 's,/.*$,,'`" +- exit ;; ++ GNU_ARCH=`echo "$UNAME_MACHINE" | sed -e 's,[-/].*$,,'` ++ GNU_REL=`echo "$UNAME_RELEASE" | sed -e 's,/.*$,,'` ++ GUESS=$GNU_ARCH-unknown-$LIBC$GNU_REL ++ ;; + *:GNU/*:*:*) + # other systems with GNU libc and userland +- echo "$UNAME_MACHINE-unknown-`echo "$UNAME_SYSTEM" | sed 's,^[^/]*/,,' | tr "[:upper:]" "[:lower:]"``echo "$UNAME_RELEASE"|sed -e 's/[-(].*//'`-$LIBC" +- exit ;; ++ GNU_SYS=`echo "$UNAME_SYSTEM" | sed 's,^[^/]*/,,' | tr "[:upper:]" "[:lower:]"` ++ GNU_REL=`echo "$UNAME_RELEASE" | sed -e 's/[-(].*//'` ++ GUESS=$UNAME_MACHINE-unknown-$GNU_SYS$GNU_REL-$LIBC ++ ;; + *:Minix:*:*) +- echo "$UNAME_MACHINE"-unknown-minix +- exit ;; ++ GUESS=$UNAME_MACHINE-unknown-minix ++ ;; + aarch64:Linux:*:*) +- echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" +- exit ;; ++ GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ++ ;; + aarch64_be:Linux:*:*) + UNAME_MACHINE=aarch64_be +- echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" +- exit ;; ++ GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ++ ;; + sw_64:Linux:*:*) + case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in + sw) UNAME_MACHINE=sw_64 ;; + esac + objdump --private-headers /bin/sh | grep -q ld.so.1 + if test "$?" = 0 ; then LIBC=gnulibc1 ; fi +- echo ${UNAME_MACHINE}-sunway-linux-${LIBC} +- exit ;; ++ GUESS=$UNAME_MACHINE-sunway-linux-$LIBC ++ ;; + + alpha:Linux:*:*) + case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' /proc/cpuinfo 2>/dev/null` in +@@ -946,60 +997,63 @@ EOF + 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 ;; ++ GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ++ ;; ++ arc:Linux:*:* | arceb:Linux:*:* | arc32:Linux:*:* | arc64:Linux:*:*) ++ GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ++ ;; + arm*:Linux:*:*) + 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-"$LIBC" ++ GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + else + 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 ++ GUESS=$UNAME_MACHINE-unknown-linux-${LIBC}eabi + else +- echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"eabihf ++ GUESS=$UNAME_MACHINE-unknown-linux-${LIBC}eabihf + fi + fi +- exit ;; ++ ;; + avr32*:Linux:*:*) +- echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" +- exit ;; ++ GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ++ ;; + cris:Linux:*:*) +- echo "$UNAME_MACHINE"-axis-linux-"$LIBC" +- exit ;; ++ GUESS=$UNAME_MACHINE-axis-linux-$LIBC ++ ;; + crisv32:Linux:*:*) +- echo "$UNAME_MACHINE"-axis-linux-"$LIBC" +- exit ;; ++ GUESS=$UNAME_MACHINE-axis-linux-$LIBC ++ ;; + e2k:Linux:*:*) +- echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" +- exit ;; ++ GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ++ ;; + frv:Linux:*:*) +- echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" +- exit ;; ++ GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ++ ;; + hexagon:Linux:*:*) +- echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" +- exit ;; ++ GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ++ ;; + i*86:Linux:*:*) +- echo "$UNAME_MACHINE"-pc-linux-"$LIBC" +- exit ;; ++ GUESS=$UNAME_MACHINE-pc-linux-$LIBC ++ ;; + ia64:Linux:*:*) +- echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" +- exit ;; ++ GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ++ ;; + k1om:Linux:*:*) +- echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" +- exit ;; ++ GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ++ ;; ++ loongarch32:Linux:*:* | loongarch64:Linux:*:* | loongarchx32:Linux:*:*) ++ GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ++ ;; + m32r*:Linux:*:*) +- echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" +- exit ;; ++ GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ++ ;; + m68*:Linux:*:*) +- echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" +- exit ;; ++ GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ++ ;; + mips:Linux:*:* | mips64:Linux:*:*) + set_cc_for_build + IS_GLIBC=0 +@@ -1044,123 +1098,124 @@ EOF + #endif + #endif + EOF +- eval "`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^CPU\|^MIPS_ENDIAN\|^LIBCABI'`" ++ cc_set_vars=`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^CPU\|^MIPS_ENDIAN\|^LIBCABI'` ++ eval "$cc_set_vars" + test "x$CPU" != x && { echo "$CPU${MIPS_ENDIAN}-unknown-linux-$LIBCABI"; exit; } + ;; + mips64el:Linux:*:*) +- echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" +- exit ;; ++ GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ++ ;; + openrisc*:Linux:*:*) +- echo or1k-unknown-linux-"$LIBC" +- exit ;; ++ GUESS=or1k-unknown-linux-$LIBC ++ ;; + or32:Linux:*:* | or1k*:Linux:*:*) +- echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" +- exit ;; ++ GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ++ ;; + padre:Linux:*:*) +- echo sparc-unknown-linux-"$LIBC" +- exit ;; ++ GUESS=sparc-unknown-linux-$LIBC ++ ;; + parisc64:Linux:*:* | hppa64:Linux:*:*) +- echo hppa64-unknown-linux-"$LIBC" +- exit ;; ++ GUESS=hppa64-unknown-linux-$LIBC ++ ;; + 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-"$LIBC" ;; +- PA8*) echo hppa2.0-unknown-linux-"$LIBC" ;; +- *) echo hppa-unknown-linux-"$LIBC" ;; ++ PA7*) GUESS=hppa1.1-unknown-linux-$LIBC ;; ++ PA8*) GUESS=hppa2.0-unknown-linux-$LIBC ;; ++ *) GUESS=hppa-unknown-linux-$LIBC ;; + esac +- exit ;; ++ ;; + ppc64:Linux:*:*) +- echo powerpc64-unknown-linux-"$LIBC" +- exit ;; ++ GUESS=powerpc64-unknown-linux-$LIBC ++ ;; + ppc:Linux:*:*) +- echo powerpc-unknown-linux-"$LIBC" +- exit ;; ++ GUESS=powerpc-unknown-linux-$LIBC ++ ;; + ppc64le:Linux:*:*) +- echo powerpc64le-unknown-linux-"$LIBC" +- exit ;; ++ GUESS=powerpc64le-unknown-linux-$LIBC ++ ;; + ppcle:Linux:*:*) +- echo powerpcle-unknown-linux-"$LIBC" +- exit ;; +- riscv32:Linux:*:* | riscv64:Linux:*:*) +- echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" +- exit ;; ++ GUESS=powerpcle-unknown-linux-$LIBC ++ ;; ++ riscv32:Linux:*:* | riscv32be:Linux:*:* | riscv64:Linux:*:* | riscv64be:Linux:*:*) ++ GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ++ ;; + s390:Linux:*:* | s390x:Linux:*:*) +- echo "$UNAME_MACHINE"-ibm-linux-"$LIBC" +- exit ;; ++ GUESS=$UNAME_MACHINE-ibm-linux-$LIBC ++ ;; + sh64*:Linux:*:*) +- echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" +- exit ;; ++ GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ++ ;; + sh*:Linux:*:*) +- echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" +- exit ;; ++ GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ++ ;; + sparc:Linux:*:* | sparc64:Linux:*:*) +- echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" +- exit ;; ++ GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ++ ;; + tile*:Linux:*:*) +- echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" +- exit ;; ++ GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ++ ;; + vax:Linux:*:*) +- echo "$UNAME_MACHINE"-dec-linux-"$LIBC" +- exit ;; ++ GUESS=$UNAME_MACHINE-dec-linux-$LIBC ++ ;; + x86_64:Linux:*:*) + set_cc_for_build + LIBCABI=$LIBC +- if [ "$CC_FOR_BUILD" != no_compiler_found ]; then ++ if test "$CC_FOR_BUILD" != no_compiler_found; then + if (echo '#ifdef __ILP32__'; echo IS_X32; echo '#endif') | \ + (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \ + grep IS_X32 >/dev/null + then +- LIBCABI="$LIBC"x32 ++ LIBCABI=${LIBC}x32 + fi + fi +- echo "$UNAME_MACHINE"-pc-linux-"$LIBCABI" +- exit ;; ++ GUESS=$UNAME_MACHINE-pc-linux-$LIBCABI ++ ;; + xtensa*:Linux:*:*) +- echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" +- exit ;; ++ GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ++ ;; + 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 + # sysname and nodename. +- echo i386-sequent-sysv4 +- exit ;; ++ GUESS=i386-sequent-sysv4 ++ ;; + 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, + # I just have to hope. -- rms. + # Use sysv4.2uw... so that sysv4* matches it. +- echo "$UNAME_MACHINE"-pc-sysv4.2uw"$UNAME_VERSION" +- exit ;; ++ GUESS=$UNAME_MACHINE-pc-sysv4.2uw$UNAME_VERSION ++ ;; + i*86:OS/2:*:*) + # If we were able to find `uname', then EMX Unix compatibility + # is probably installed. +- echo "$UNAME_MACHINE"-pc-os2-emx +- exit ;; ++ GUESS=$UNAME_MACHINE-pc-os2-emx ++ ;; + i*86:XTS-300:*:STOP) +- echo "$UNAME_MACHINE"-unknown-stop +- exit ;; ++ GUESS=$UNAME_MACHINE-unknown-stop ++ ;; + i*86:atheos:*:*) +- echo "$UNAME_MACHINE"-unknown-atheos +- exit ;; ++ GUESS=$UNAME_MACHINE-unknown-atheos ++ ;; + i*86:syllable:*:*) +- echo "$UNAME_MACHINE"-pc-syllable +- exit ;; ++ GUESS=$UNAME_MACHINE-pc-syllable ++ ;; + i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*) +- echo i386-unknown-lynxos"$UNAME_RELEASE" +- exit ;; ++ GUESS=i386-unknown-lynxos$UNAME_RELEASE ++ ;; + i*86:*DOS:*:*) +- echo "$UNAME_MACHINE"-pc-msdosdjgpp +- exit ;; ++ GUESS=$UNAME_MACHINE-pc-msdosdjgpp ++ ;; + i*86:*:4.*:*) + UNAME_REL=`echo "$UNAME_RELEASE" | sed 's/\/MP$//'` + if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then +- echo "$UNAME_MACHINE"-univel-sysv"$UNAME_REL" ++ GUESS=$UNAME_MACHINE-univel-sysv$UNAME_REL + else +- echo "$UNAME_MACHINE"-pc-sysv"$UNAME_REL" ++ GUESS=$UNAME_MACHINE-pc-sysv$UNAME_REL + fi +- exit ;; ++ ;; + i*86:*:5:[678]*) + # UnixWare 7.x, OpenUNIX and OpenServer 6. + case `/bin/uname -X | grep "^Machine"` in +@@ -1168,12 +1223,12 @@ EOF + *Pentium) UNAME_MACHINE=i586 ;; + *Pent*|*Celeron) UNAME_MACHINE=i686 ;; + esac +- echo "$UNAME_MACHINE-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION}" +- exit ;; ++ GUESS=$UNAME_MACHINE-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION} ++ ;; + i*86:*:3.2:*) + if test -f /usr/options/cb.name; then + UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then + UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')` + (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486 +@@ -1183,11 +1238,11 @@ EOF + && UNAME_MACHINE=i686 + (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \ + && UNAME_MACHINE=i686 +- echo "$UNAME_MACHINE"-pc-sco"$UNAME_REL" ++ GUESS=$UNAME_MACHINE-pc-sco$UNAME_REL + else +- echo "$UNAME_MACHINE"-pc-sysv32 ++ GUESS=$UNAME_MACHINE-pc-sysv32 + fi +- exit ;; ++ ;; + pc:*:*:*) + # Left here for compatibility: + # uname -m prints for DJGPP always 'pc', but it prints nothing about +@@ -1195,31 +1250,31 @@ EOF + # Note: whatever this is, it MUST be the same as what config.sub + # prints for the "djgpp" host, or else GDB configure will decide that + # this is a cross-build. +- echo i586-pc-msdosdjgpp +- exit ;; ++ GUESS=i586-pc-msdosdjgpp ++ ;; + Intel:Mach:3*:*) +- echo i386-pc-mach3 +- exit ;; ++ GUESS=i386-pc-mach3 ++ ;; + paragon:*:*:*) +- echo i860-intel-osf1 +- exit ;; ++ GUESS=i860-intel-osf1 ++ ;; + i860:*:4.*:*) # i860-SVR4 + if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then +- echo i860-stardent-sysv"$UNAME_RELEASE" # Stardent Vistra i860-SVR4 ++ GUESS=i860-stardent-sysv$UNAME_RELEASE # Stardent Vistra i860-SVR4 + else # Add other i860-SVR4 vendors below as they are discovered. +- echo i860-unknown-sysv"$UNAME_RELEASE" # Unknown i860-SVR4 ++ GUESS=i860-unknown-sysv$UNAME_RELEASE # Unknown i860-SVR4 + fi +- exit ;; ++ ;; + mini*:CTIX:SYS*5:*) + # "miniframe" +- echo m68010-convergent-sysv +- exit ;; ++ GUESS=m68010-convergent-sysv ++ ;; + mc68k:UNIX:SYSTEM5:3.51m) +- echo m68k-convergent-sysv +- exit ;; ++ GUESS=m68k-convergent-sysv ++ ;; + M680?0:D-NIX:5.3:*) +- echo m68k-diab-dnix +- exit ;; ++ GUESS=m68k-diab-dnix ++ ;; + M68*:*:R3V[5678]*:*) + test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;; + 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0) +@@ -1244,116 +1299,116 @@ EOF + /bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \ + && { echo i586-ncr-sysv4.3"$OS_REL"; exit; } ;; + m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) +- echo m68k-unknown-lynxos"$UNAME_RELEASE" +- exit ;; ++ GUESS=m68k-unknown-lynxos$UNAME_RELEASE ++ ;; + mc68030:UNIX_System_V:4.*:*) +- echo m68k-atari-sysv4 +- exit ;; ++ GUESS=m68k-atari-sysv4 ++ ;; + TSUNAMI:LynxOS:2.*:*) +- echo sparc-unknown-lynxos"$UNAME_RELEASE" +- exit ;; ++ GUESS=sparc-unknown-lynxos$UNAME_RELEASE ++ ;; + rs6000:LynxOS:2.*:*) +- echo rs6000-unknown-lynxos"$UNAME_RELEASE" +- exit ;; ++ GUESS=rs6000-unknown-lynxos$UNAME_RELEASE ++ ;; + PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*) +- echo powerpc-unknown-lynxos"$UNAME_RELEASE" +- exit ;; ++ GUESS=powerpc-unknown-lynxos$UNAME_RELEASE ++ ;; + SM[BE]S:UNIX_SV:*:*) +- echo mips-dde-sysv"$UNAME_RELEASE" +- exit ;; ++ GUESS=mips-dde-sysv$UNAME_RELEASE ++ ;; + RM*:ReliantUNIX-*:*:*) +- echo mips-sni-sysv4 +- exit ;; ++ GUESS=mips-sni-sysv4 ++ ;; + RM*:SINIX-*:*:*) +- echo mips-sni-sysv4 +- exit ;; ++ GUESS=mips-sni-sysv4 ++ ;; + *:SINIX-*:*:*) + if uname -p 2>/dev/null >/dev/null ; then + UNAME_MACHINE=`(uname -p) 2>/dev/null` +- echo "$UNAME_MACHINE"-sni-sysv4 ++ GUESS=$UNAME_MACHINE-sni-sysv4 + else +- echo ns32k-sni-sysv ++ GUESS=ns32k-sni-sysv + fi +- exit ;; ++ ;; + PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort + # says +- echo i586-unisys-sysv4 +- exit ;; ++ GUESS=i586-unisys-sysv4 ++ ;; + *:UNIX_System_V:4*:FTX*) + # From Gerald Hewes . + # How about differentiating between stratus architectures? -djm +- echo hppa1.1-stratus-sysv4 +- exit ;; ++ GUESS=hppa1.1-stratus-sysv4 ++ ;; + *:*:*:FTX*) + # From seanf@swdc.stratus.com. +- echo i860-stratus-sysv4 +- exit ;; ++ GUESS=i860-stratus-sysv4 ++ ;; + i*86:VOS:*:*) + # From Paul.Green@stratus.com. +- echo "$UNAME_MACHINE"-stratus-vos +- exit ;; ++ GUESS=$UNAME_MACHINE-stratus-vos ++ ;; + *:VOS:*:*) + # From Paul.Green@stratus.com. +- echo hppa1.1-stratus-vos +- exit ;; ++ GUESS=hppa1.1-stratus-vos ++ ;; + mc68*:A/UX:*:*) +- echo m68k-apple-aux"$UNAME_RELEASE" +- exit ;; ++ GUESS=m68k-apple-aux$UNAME_RELEASE ++ ;; + news*:NEWS-OS:6*:*) +- echo mips-sony-newsos6 +- exit ;; ++ GUESS=mips-sony-newsos6 ++ ;; + R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) +- if [ -d /usr/nec ]; then +- echo mips-nec-sysv"$UNAME_RELEASE" ++ if test -d /usr/nec; then ++ GUESS=mips-nec-sysv$UNAME_RELEASE + else +- echo mips-unknown-sysv"$UNAME_RELEASE" ++ GUESS=mips-unknown-sysv$UNAME_RELEASE + fi +- exit ;; ++ ;; + BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. +- echo powerpc-be-beos +- exit ;; ++ GUESS=powerpc-be-beos ++ ;; + BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. +- echo powerpc-apple-beos +- exit ;; ++ GUESS=powerpc-apple-beos ++ ;; + BePC:BeOS:*:*) # BeOS running on Intel PC compatible. +- echo i586-pc-beos +- exit ;; ++ GUESS=i586-pc-beos ++ ;; + BePC:Haiku:*:*) # Haiku running on Intel PC compatible. +- echo i586-pc-haiku +- exit ;; ++ GUESS=i586-pc-haiku ++ ;; + x86_64:Haiku:*:*) +- echo x86_64-unknown-haiku +- exit ;; ++ GUESS=x86_64-unknown-haiku ++ ;; + SX-4:SUPER-UX:*:*) +- echo sx4-nec-superux"$UNAME_RELEASE" +- exit ;; ++ GUESS=sx4-nec-superux$UNAME_RELEASE ++ ;; + SX-5:SUPER-UX:*:*) +- echo sx5-nec-superux"$UNAME_RELEASE" +- exit ;; ++ GUESS=sx5-nec-superux$UNAME_RELEASE ++ ;; + SX-6:SUPER-UX:*:*) +- echo sx6-nec-superux"$UNAME_RELEASE" +- exit ;; ++ GUESS=sx6-nec-superux$UNAME_RELEASE ++ ;; + SX-7:SUPER-UX:*:*) +- echo sx7-nec-superux"$UNAME_RELEASE" +- exit ;; ++ GUESS=sx7-nec-superux$UNAME_RELEASE ++ ;; + SX-8:SUPER-UX:*:*) +- echo sx8-nec-superux"$UNAME_RELEASE" +- exit ;; ++ GUESS=sx8-nec-superux$UNAME_RELEASE ++ ;; + SX-8R:SUPER-UX:*:*) +- echo sx8r-nec-superux"$UNAME_RELEASE" +- exit ;; ++ GUESS=sx8r-nec-superux$UNAME_RELEASE ++ ;; + SX-ACE:SUPER-UX:*:*) +- echo sxace-nec-superux"$UNAME_RELEASE" +- exit ;; ++ GUESS=sxace-nec-superux$UNAME_RELEASE ++ ;; + Power*:Rhapsody:*:*) +- echo powerpc-apple-rhapsody"$UNAME_RELEASE" +- exit ;; ++ GUESS=powerpc-apple-rhapsody$UNAME_RELEASE ++ ;; + *:Rhapsody:*:*) +- echo "$UNAME_MACHINE"-apple-rhapsody"$UNAME_RELEASE" +- exit ;; ++ GUESS=$UNAME_MACHINE-apple-rhapsody$UNAME_RELEASE ++ ;; + arm64:Darwin:*:*) +- echo aarch64-apple-darwin"$UNAME_RELEASE" +- exit ;; ++ GUESS=aarch64-apple-darwin$UNAME_RELEASE ++ ;; + *:Darwin:*:*) + UNAME_PROCESSOR=`uname -p` + case $UNAME_PROCESSOR in +@@ -1368,7 +1423,7 @@ EOF + else + set_cc_for_build + fi +- if [ "$CC_FOR_BUILD" != no_compiler_found ]; then ++ if test "$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 +@@ -1389,109 +1444,119 @@ EOF + # uname -m returns i386 or x86_64 + UNAME_PROCESSOR=$UNAME_MACHINE + fi +- echo "$UNAME_PROCESSOR"-apple-darwin"$UNAME_RELEASE" +- exit ;; ++ GUESS=$UNAME_PROCESSOR-apple-darwin$UNAME_RELEASE ++ ;; + *:procnto*:*:* | *:QNX:[0123456789]*:*) + UNAME_PROCESSOR=`uname -p` + if test "$UNAME_PROCESSOR" = x86; then + UNAME_PROCESSOR=i386 + UNAME_MACHINE=pc + fi +- echo "$UNAME_PROCESSOR"-"$UNAME_MACHINE"-nto-qnx"$UNAME_RELEASE" +- exit ;; ++ GUESS=$UNAME_PROCESSOR-$UNAME_MACHINE-nto-qnx$UNAME_RELEASE ++ ;; + *:QNX:*:4*) +- echo i386-pc-qnx +- exit ;; ++ GUESS=i386-pc-qnx ++ ;; + NEO-*:NONSTOP_KERNEL:*:*) +- echo neo-tandem-nsk"$UNAME_RELEASE" +- exit ;; ++ GUESS=neo-tandem-nsk$UNAME_RELEASE ++ ;; + NSE-*:NONSTOP_KERNEL:*:*) +- echo nse-tandem-nsk"$UNAME_RELEASE" +- exit ;; ++ GUESS=nse-tandem-nsk$UNAME_RELEASE ++ ;; + NSR-*:NONSTOP_KERNEL:*:*) +- echo nsr-tandem-nsk"$UNAME_RELEASE" +- exit ;; ++ GUESS=nsr-tandem-nsk$UNAME_RELEASE ++ ;; + NSV-*:NONSTOP_KERNEL:*:*) +- echo nsv-tandem-nsk"$UNAME_RELEASE" +- exit ;; ++ GUESS=nsv-tandem-nsk$UNAME_RELEASE ++ ;; + NSX-*:NONSTOP_KERNEL:*:*) +- echo nsx-tandem-nsk"$UNAME_RELEASE" +- exit ;; ++ GUESS=nsx-tandem-nsk$UNAME_RELEASE ++ ;; + *:NonStop-UX:*:*) +- echo mips-compaq-nonstopux +- exit ;; ++ GUESS=mips-compaq-nonstopux ++ ;; + BS2000:POSIX*:*:*) +- echo bs2000-siemens-sysv +- exit ;; ++ GUESS=bs2000-siemens-sysv ++ ;; + DS/*:UNIX_System_V:*:*) +- echo "$UNAME_MACHINE"-"$UNAME_SYSTEM"-"$UNAME_RELEASE" +- exit ;; ++ GUESS=$UNAME_MACHINE-$UNAME_SYSTEM-$UNAME_RELEASE ++ ;; + *:Plan9:*:*) + # "uname -m" is not consistent, so use $cputype instead. 386 + # is converted to i386 for consistency with other x86 + # operating systems. +- # shellcheck disable=SC2154 +- if test "$cputype" = 386; then ++ if test "${cputype-}" = 386; then + UNAME_MACHINE=i386 +- else +- UNAME_MACHINE="$cputype" ++ elif test "x${cputype-}" != x; then ++ UNAME_MACHINE=$cputype + fi +- echo "$UNAME_MACHINE"-unknown-plan9 +- exit ;; ++ GUESS=$UNAME_MACHINE-unknown-plan9 ++ ;; + *:TOPS-10:*:*) +- echo pdp10-unknown-tops10 +- exit ;; ++ GUESS=pdp10-unknown-tops10 ++ ;; + *:TENEX:*:*) +- echo pdp10-unknown-tenex +- exit ;; ++ GUESS=pdp10-unknown-tenex ++ ;; + KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) +- echo pdp10-dec-tops20 +- exit ;; ++ GUESS=pdp10-dec-tops20 ++ ;; + XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) +- echo pdp10-xkl-tops20 +- exit ;; ++ GUESS=pdp10-xkl-tops20 ++ ;; + *:TOPS-20:*:*) +- echo pdp10-unknown-tops20 +- exit ;; ++ GUESS=pdp10-unknown-tops20 ++ ;; + *:ITS:*:*) +- echo pdp10-unknown-its +- exit ;; ++ GUESS=pdp10-unknown-its ++ ;; + SEI:*:*:SEIUX) +- echo mips-sei-seiux"$UNAME_RELEASE" +- exit ;; ++ GUESS=mips-sei-seiux$UNAME_RELEASE ++ ;; + *:DragonFly:*:*) +- echo "$UNAME_MACHINE"-unknown-dragonfly"`echo "$UNAME_RELEASE"|sed -e 's/[-(].*//'`" +- exit ;; ++ DRAGONFLY_REL=`echo "$UNAME_RELEASE" | sed -e 's/[-(].*//'` ++ GUESS=$UNAME_MACHINE-unknown-dragonfly$DRAGONFLY_REL ++ ;; + *:*VMS:*:*) + UNAME_MACHINE=`(uname -p) 2>/dev/null` +- case "$UNAME_MACHINE" in +- A*) echo alpha-dec-vms ; exit ;; +- I*) echo ia64-dec-vms ; exit ;; +- V*) echo vax-dec-vms ; exit ;; ++ case $UNAME_MACHINE in ++ A*) GUESS=alpha-dec-vms ;; ++ I*) GUESS=ia64-dec-vms ;; ++ V*) GUESS=vax-dec-vms ;; + esac ;; + *:XENIX:*:SysV) +- echo i386-pc-xenix +- exit ;; ++ GUESS=i386-pc-xenix ++ ;; + i*86:skyos:*:*) +- echo "$UNAME_MACHINE"-pc-skyos"`echo "$UNAME_RELEASE" | sed -e 's/ .*$//'`" +- exit ;; ++ SKYOS_REL=`echo "$UNAME_RELEASE" | sed -e 's/ .*$//'` ++ GUESS=$UNAME_MACHINE-pc-skyos$SKYOS_REL ++ ;; + i*86:rdos:*:*) +- echo "$UNAME_MACHINE"-pc-rdos +- exit ;; +- i*86:AROS:*:*) +- echo "$UNAME_MACHINE"-pc-aros +- exit ;; ++ GUESS=$UNAME_MACHINE-pc-rdos ++ ;; ++ i*86:Fiwix:*:*) ++ GUESS=$UNAME_MACHINE-pc-fiwix ++ ;; ++ *:AROS:*:*) ++ GUESS=$UNAME_MACHINE-unknown-aros ++ ;; + x86_64:VMkernel:*:*) +- echo "$UNAME_MACHINE"-unknown-esx +- exit ;; ++ GUESS=$UNAME_MACHINE-unknown-esx ++ ;; + amd64:Isilon\ OneFS:*:*) +- echo x86_64-unknown-onefs +- exit ;; ++ GUESS=x86_64-unknown-onefs ++ ;; + *:Unleashed:*:*) +- echo "$UNAME_MACHINE"-unknown-unleashed"$UNAME_RELEASE" +- exit ;; ++ GUESS=$UNAME_MACHINE-unknown-unleashed$UNAME_RELEASE ++ ;; + esac + ++# Do we have a guess based on uname results? ++if test "x$GUESS" != x; then ++ echo "$GUESS" ++ exit ++fi ++ + # No uname command or uname output not recognized. + set_cc_for_build + cat > "$dummy.c" </dev/null && SYSTEM_NAME=`$dummy` && ++$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. +@@ -1631,7 +1696,7 @@ test -d /usr/apollo && { echo "$ISP-apollo-$SYSTYPE"; exit; } + + echo "$0: unable to guess system type" >&2 + +-case "$UNAME_MACHINE:$UNAME_SYSTEM" in ++case $UNAME_MACHINE:$UNAME_SYSTEM in + mips:Linux | mips64:Linux) + # If we got here on MIPS GNU/Linux, output extra information. + cat >&2 <&2 <&2 +@@ -1750,8 +1785,12 @@ case $kernel-$os in + ;; + kfreebsd*-gnu* | kopensolaris*-gnu*) + ;; ++ vxworks-simlinux | vxworks-simwindows | vxworks-spe) ++ ;; + nto-qnx*) + ;; ++ os2-emx) ++ ;; + *-eabi* | *-gnueabi*) + ;; + -*) +diff --git a/configure.host b/configure.host +index 372e20bb11b0..ad3f8707689f 100644 +--- a/configure.host ++++ b/configure.host +@@ -146,6 +146,11 @@ case "${host}" in + SOURCES="ffi.c sysv.S" + ;; + ++ loongarch64-*-*) ++ TARGET=LOONGARCH64; TARGETDIR=loongarch64 ++ SOURCES="ffi.c sysv.S" ++ ;; ++ + m32r*-*-*) + TARGET=M32R; TARGETDIR=m32r + SOURCES="ffi.c sysv.S" +diff --git a/src/loongarch64/ffi.c b/src/loongarch64/ffi.c +new file mode 100644 +index 000000000000..7a2889281891 +--- /dev/null ++++ b/src/loongarch64/ffi.c +@@ -0,0 +1,595 @@ ++/* ----------------------------------------------------------------------- ++ ffi.c - Copyright (c) 2022 Xu Chenghua ++ 2022 Cheng Lulu ++ Based on RISC-V port ++ ++ LoongArch Foreign Function Interface ++ ++ Permission is hereby granted, free of charge, to any person obtaining ++ a copy of this software and associated documentation files (the ++ ``Software''), to deal in the Software without restriction, including ++ without limitation the rights to use, copy, modify, merge, publish, ++ distribute, sublicense, and/or sell copies of the Software, and to ++ permit persons to whom the Software is furnished to do so, subject to ++ the following conditions: ++ ++ The above copyright notice and this permission notice shall be included ++ in all copies or substantial portions of the Software. ++ ++ THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, ++ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF ++ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND ++ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT ++ HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, ++ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, ++ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER ++ DEALINGS IN THE SOFTWARE. ++ ----------------------------------------------------------------------- */ ++ ++#include ++#include ++ ++#include ++#include ++ ++#if defined(__loongarch_soft_float) ++# define ABI_FRLEN 0 ++#elif defined(__loongarch_single_float) ++# define ABI_FRLEN 32 ++# define ABI_FLOAT float ++#elif defined(__loongarch_double_float) ++# define ABI_FRLEN 64 ++# define ABI_FLOAT double ++#else ++#error unsupported LoongArch floating-point ABI ++#endif ++ ++#define NARGREG 8 ++#define STKALIGN 16 ++#define MAXCOPYARG (2 * sizeof (double)) ++ ++/* call_context registers ++ - 8 floating point parameter/result registers. ++ - 8 integer parameter/result registers. ++ - 2 registers used by the assembly code to in-place construct its own ++ stack frame ++ - frame register ++ - return register ++*/ ++typedef struct call_context ++{ ++ ABI_FLOAT fa[8]; ++ size_t a[10]; ++} call_context; ++ ++typedef struct call_builder ++{ ++ call_context *aregs; ++ int used_integer; ++ int used_float; ++ size_t *used_stack; ++ size_t *stack; ++ size_t next_struct_area; ++} call_builder; ++ ++/* Integer (not pointer) less than ABI GRLEN. */ ++/* FFI_TYPE_INT does not appear to be used. */ ++#if __SIZEOF_POINTER__ == 8 ++# define IS_INT(type) ((type) >= FFI_TYPE_UINT8 && (type) <= FFI_TYPE_SINT64) ++#else ++# define IS_INT(type) ((type) >= FFI_TYPE_UINT8 && (type) <= FFI_TYPE_SINT32) ++#endif ++ ++#if ABI_FRLEN ++typedef struct float_struct_info ++{ ++ char as_elements; ++ char type1; ++ char offset2; ++ char type2; ++} float_struct_info; ++ ++#if ABI_FRLEN >= 64 ++# define IS_FLOAT(type) ((type) >= FFI_TYPE_FLOAT && (type) <= FFI_TYPE_DOUBLE) ++#else ++# define IS_FLOAT(type) ((type) == FFI_TYPE_FLOAT) ++#endif ++ ++static ffi_type ** ++flatten_struct (ffi_type *in, ffi_type **out, ffi_type **out_end) ++{ ++ int i; ++ ++ if (out == out_end) ++ return out; ++ if (in->type != FFI_TYPE_STRUCT) ++ *(out++) = in; ++ else ++ for (i = 0; in->elements[i]; i++) ++ out = flatten_struct (in->elements[i], out, out_end); ++ return out; ++} ++ ++/* Structs with at most two fields after flattening, one of which is of ++ floating point type, are passed in multiple registers if sufficient ++ registers are available. */ ++static float_struct_info ++struct_passed_as_elements (call_builder *cb, ffi_type *top) ++{ ++ float_struct_info ret = {0, 0, 0, 0}; ++ ffi_type *fields[3]; ++ int num_floats, num_ints; ++ int num_fields = flatten_struct (top, fields, fields + 3) - fields; ++ ++ if (num_fields == 1) ++ { ++ if (IS_FLOAT (fields[0]->type)) ++ { ++ ret.as_elements = 1; ++ ret.type1 = fields[0]->type; ++ } ++ } ++ else if (num_fields == 2) ++ { ++ num_floats = IS_FLOAT (fields[0]->type) + IS_FLOAT (fields[1]->type); ++ num_ints = IS_INT (fields[0]->type) + IS_INT (fields[1]->type); ++ if (num_floats == 0 || num_floats + num_ints != 2) ++ return ret; ++ if (cb->used_float + num_floats > NARGREG ++ || cb->used_integer + (2 - num_floats) > NARGREG) ++ return ret; ++ if (!IS_FLOAT (fields[0]->type) && !IS_FLOAT (fields[1]->type)) ++ return ret; ++ ++ ret.type1 = fields[0]->type; ++ ret.type2 = fields[1]->type; ++ ret.offset2 = FFI_ALIGN (fields[0]->size, fields[1]->alignment); ++ ret.as_elements = 1; ++ } ++ return ret; ++} ++#endif ++ ++/* Allocates a single register, float register, or GRLEN-sized stack slot to a ++ datum. */ ++static void ++marshal_atom (call_builder *cb, int type, void *data) ++{ ++ size_t value = 0; ++ switch (type) ++ { ++ case FFI_TYPE_UINT8: ++ value = *(uint8_t *) data; ++ break; ++ case FFI_TYPE_SINT8: ++ value = *(int8_t *) data; ++ break; ++ case FFI_TYPE_UINT16: ++ value = *(uint16_t *) data; ++ break; ++ case FFI_TYPE_SINT16: ++ value = *(int16_t *) data; ++ break; ++ /* 32-bit quantities are always sign-extended in the ABI. */ ++ case FFI_TYPE_UINT32: ++ value = *(int32_t *) data; ++ break; ++ case FFI_TYPE_SINT32: ++ value = *(int32_t *) data; ++ break; ++#if __SIZEOF_POINTER__ == 8 ++ case FFI_TYPE_UINT64: ++ value = *(uint64_t *) data; ++ break; ++ case FFI_TYPE_SINT64: ++ value = *(int64_t *) data; ++ break; ++#endif ++ case FFI_TYPE_POINTER: ++ value = *(size_t *) data; ++ break; ++ ++#if ABI_FRLEN >= 32 ++ case FFI_TYPE_FLOAT: ++ *(float *)(cb->aregs->fa + cb->used_float++) = *(float *) data; ++ return; ++#endif ++#if ABI_FRLEN >= 64 ++ case FFI_TYPE_DOUBLE: ++ (cb->aregs->fa[cb->used_float++]) = *(double *) data; ++ return; ++#endif ++ default: ++ FFI_ASSERT (0); ++ break; ++ } ++ ++ if (cb->used_integer == NARGREG) ++ *cb->used_stack++ = value; ++ else ++ cb->aregs->a[cb->used_integer++] = value; ++} ++ ++static void ++unmarshal_atom (call_builder *cb, int type, void *data) ++{ ++ size_t value; ++ switch (type) ++ { ++#if ABI_FRLEN >= 32 ++ case FFI_TYPE_FLOAT: ++ *(float *) data = *(float *)(cb->aregs->fa + cb->used_float++); ++ return; ++#endif ++#if ABI_FRLEN >= 64 ++ case FFI_TYPE_DOUBLE: ++ *(double *) data = cb->aregs->fa[cb->used_float++]; ++ return; ++#endif ++ } ++ ++ if (cb->used_integer == NARGREG) ++ value = *cb->used_stack++; ++ else ++ value = cb->aregs->a[cb->used_integer++]; ++ ++ switch (type) ++ { ++ case FFI_TYPE_UINT8: ++ case FFI_TYPE_SINT8: ++ case FFI_TYPE_UINT16: ++ case FFI_TYPE_SINT16: ++ case FFI_TYPE_UINT32: ++ case FFI_TYPE_SINT32: ++#if __SIZEOF_POINTER__ == 8 ++ case FFI_TYPE_UINT64: ++ case FFI_TYPE_SINT64: ++#endif ++ case FFI_TYPE_POINTER: ++ *(ffi_arg *)data = value; ++ break; ++ default: ++ FFI_ASSERT (0); ++ break; ++ } ++} ++ ++/* Allocate and copy a structure that is passed by value on the stack and ++ return a pointer to it. */ ++static void * ++allocate_and_copy_struct_to_stack (call_builder *cb, void *data, ++ ffi_type *type) ++{ ++ size_t dest = cb->next_struct_area - type->size; ++ ++ dest = FFI_ALIGN_DOWN (dest, type->alignment); ++ cb->next_struct_area = dest; ++ ++ return memcpy ((char *)cb->stack + dest, data, type->size); ++} ++ ++/* Adds an argument to a call, or a not by reference return value. */ ++static void ++marshal (call_builder *cb, ffi_type *type, int var, void *data) ++{ ++ size_t realign[2]; ++ ++#if ABI_FRLEN ++ if (!var && type->type == FFI_TYPE_STRUCT) ++ { ++ float_struct_info fsi = struct_passed_as_elements (cb, type); ++ if (fsi.as_elements) ++ { ++ marshal_atom (cb, fsi.type1, data); ++ if (fsi.offset2) ++ marshal_atom (cb, fsi.type2, ((char *) data) + fsi.offset2); ++ return; ++ } ++ } ++ ++ if (!var && cb->used_float < NARGREG ++ && IS_FLOAT (type->type)) ++ { ++ marshal_atom (cb, type->type, data); ++ return; ++ } ++ ++ double promoted; ++ if (var && type->type == FFI_TYPE_FLOAT) ++ { ++ /* C standard requires promoting float -> double for variable arg. */ ++ promoted = *(float *) data; ++ type = &ffi_type_double; ++ data = &promoted; ++ } ++#endif ++ ++ if (type->size > 2 * __SIZEOF_POINTER__) ++ /* Pass by reference. */ ++ { ++ allocate_and_copy_struct_to_stack (cb, data, type); ++ data = (char *)cb->stack + cb->next_struct_area; ++ marshal_atom (cb, FFI_TYPE_POINTER, &data); ++ } ++ else if (IS_INT (type->type) || type->type == FFI_TYPE_POINTER) ++ marshal_atom (cb, type->type, data); ++ else ++ { ++ /* Overlong integers, soft-float floats, and structs without special ++ float handling are treated identically from this point on. */ ++ ++ /* Variadics are aligned even in registers. */ ++ if (type->alignment > __SIZEOF_POINTER__) ++ { ++ if (var) ++ cb->used_integer = FFI_ALIGN (cb->used_integer, 2); ++ cb->used_stack ++ = (size_t *) FFI_ALIGN (cb->used_stack, 2 * __SIZEOF_POINTER__); ++ } ++ ++ memcpy (realign, data, type->size); ++ if (type->size > 0) ++ marshal_atom (cb, FFI_TYPE_POINTER, realign); ++ if (type->size > __SIZEOF_POINTER__) ++ marshal_atom (cb, FFI_TYPE_POINTER, realign + 1); ++ } ++} ++ ++/* For arguments passed by reference returns the pointer, otherwise the arg ++ is copied (up to MAXCOPYARG bytes). */ ++static void * ++unmarshal (call_builder *cb, ffi_type *type, int var, void *data) ++{ ++ size_t realign[2]; ++ void *pointer; ++ ++#if ABI_FRLEN ++ if (!var && type->type == FFI_TYPE_STRUCT) ++ { ++ float_struct_info fsi = struct_passed_as_elements (cb, type); ++ if (fsi.as_elements) ++ { ++ unmarshal_atom (cb, fsi.type1, data); ++ if (fsi.offset2) ++ unmarshal_atom (cb, fsi.type2, ((char *) data) + fsi.offset2); ++ return data; ++ } ++ } ++ ++ if (!var && cb->used_float < NARGREG ++ && IS_FLOAT (type->type)) ++ { ++ unmarshal_atom (cb, type->type, data); ++ return data; ++ } ++ ++ if (var && type->type == FFI_TYPE_FLOAT) ++ { ++ int m = cb->used_integer; ++ void *promoted ++ = m < NARGREG ? cb->aregs->a + m : cb->used_stack + m - NARGREG + 1; ++ *(float *) promoted = *(double *) promoted; ++ } ++#endif ++ ++ if (type->size > 2 * __SIZEOF_POINTER__) ++ { ++ /* Pass by reference. */ ++ unmarshal_atom (cb, FFI_TYPE_POINTER, (char *) &pointer); ++ return pointer; ++ } ++ else if (IS_INT (type->type) || type->type == FFI_TYPE_POINTER) ++ { ++ unmarshal_atom (cb, type->type, data); ++ return data; ++ } ++ else ++ { ++ /* Overlong integers, soft-float floats, and structs without special ++ float handling are treated identically from this point on. */ ++ ++ /* Variadics are aligned even in registers. */ ++ if (type->alignment > __SIZEOF_POINTER__) ++ { ++ if (var) ++ cb->used_integer = FFI_ALIGN (cb->used_integer, 2); ++ cb->used_stack ++ = (size_t *) FFI_ALIGN (cb->used_stack, 2 * __SIZEOF_POINTER__); ++ } ++ ++ if (type->size > 0) ++ unmarshal_atom (cb, FFI_TYPE_POINTER, realign); ++ if (type->size > __SIZEOF_POINTER__) ++ unmarshal_atom (cb, FFI_TYPE_POINTER, realign + 1); ++ memcpy (data, realign, type->size); ++ return data; ++ } ++} ++ ++static int ++passed_by_ref (call_builder *cb, ffi_type *type, int var) ++{ ++#if ABI_FRLEN ++ if (!var && type->type == FFI_TYPE_STRUCT) ++ { ++ float_struct_info fsi = struct_passed_as_elements (cb, type); ++ if (fsi.as_elements) ++ return 0; ++ } ++#endif ++ ++ return type->size > 2 * __SIZEOF_POINTER__; ++} ++ ++/* Perform machine dependent cif processing. */ ++ffi_status ++ffi_prep_cif_machdep (ffi_cif *cif) ++{ ++ cif->loongarch_nfixedargs = cif->nargs; ++ return FFI_OK; ++} ++ ++/* Perform machine dependent cif processing when we have a variadic ++ function. */ ++ffi_status ++ffi_prep_cif_machdep_var (ffi_cif *cif, unsigned int nfixedargs, ++ unsigned int ntotalargs) ++{ ++ cif->loongarch_nfixedargs = nfixedargs; ++ return FFI_OK; ++} ++ ++/* Low level routine for calling functions. */ ++extern void ffi_call_asm (void *stack, struct call_context *regs, ++ void (*fn) (void), void *closure) FFI_HIDDEN; ++ ++static void ++ffi_call_int (ffi_cif *cif, void (*fn) (void), void *rvalue, void **avalue, ++ void *closure) ++{ ++ /* This is a conservative estimate, assuming a complex return value and ++ that all remaining arguments are long long / __int128 */ ++ size_t arg_bytes = cif->bytes; ++ size_t rval_bytes = 0; ++ if (rvalue == NULL && cif->rtype->size > 2 * __SIZEOF_POINTER__) ++ rval_bytes = FFI_ALIGN (cif->rtype->size, STKALIGN); ++ size_t alloc_size = arg_bytes + rval_bytes + sizeof (call_context); ++ ++ /* The assembly code will deallocate all stack data at lower addresses ++ than the argument region, so we need to allocate the frame and the ++ return value after the arguments in a single allocation. */ ++ size_t alloc_base; ++ /* Argument region must be 16-byte aligned in LP64 ABIs. */ ++ if (_Alignof(max_align_t) >= STKALIGN) ++ /* Since sizeof long double is normally 16, the compiler will ++ guarantee alloca alignment to at least that much. */ ++ alloc_base = (size_t) alloca (alloc_size); ++ else ++ alloc_base = FFI_ALIGN (alloca (alloc_size + STKALIGN - 1), STKALIGN); ++ ++ if (rval_bytes) ++ rvalue = (void *) (alloc_base + arg_bytes); ++ ++ call_builder cb; ++ cb.used_float = cb.used_integer = 0; ++ cb.aregs = (call_context *) (alloc_base + arg_bytes + rval_bytes); ++ cb.used_stack = (void *) alloc_base; ++ cb.stack = (void *) alloc_base; ++ cb.next_struct_area = arg_bytes; ++ ++ int return_by_ref = passed_by_ref (&cb, cif->rtype, 0); ++ if (return_by_ref) ++ cb.aregs->a[cb.used_integer++] = (size_t)rvalue; ++ ++ int i; ++ for (i = 0; i < cif->nargs; i++) ++ marshal (&cb, cif->arg_types[i], i >= cif->loongarch_nfixedargs, ++ avalue[i]); ++ ++ ffi_call_asm ((void *) alloc_base, cb.aregs, fn, closure); ++ ++ cb.used_float = cb.used_integer = 0; ++ if (!return_by_ref && rvalue) ++ unmarshal (&cb, cif->rtype, 0, rvalue); ++} ++ ++void ++ffi_call (ffi_cif *cif, void (*fn) (void), void *rvalue, void **avalue) ++{ ++ ffi_call_int (cif, fn, rvalue, avalue, NULL); ++} ++ ++void ++ffi_call_go (ffi_cif *cif, void (*fn) (void), void *rvalue, void **avalue, ++ void *closure) ++{ ++ ffi_call_int (cif, fn, rvalue, avalue, closure); ++} ++ ++extern void ffi_closure_asm (void) FFI_HIDDEN; ++ ++ffi_status ++ffi_prep_closure_loc (ffi_closure *closure, ffi_cif *cif, ++ void (*fun) (ffi_cif *, void *, void **, void *), ++ void *user_data, void *codeloc) ++{ ++ uint32_t *tramp = (uint32_t *) &closure->tramp[0]; ++ uint64_t fn = (uint64_t) (uintptr_t) ffi_closure_asm; ++ ++ if (cif->abi <= FFI_FIRST_ABI || cif->abi >= FFI_LAST_ABI) ++ return FFI_BAD_ABI; ++ ++ /* We will call ffi_closure_inner with codeloc, not closure, but as long ++ as the memory is readable it should work. */ ++ tramp[0] = 0x1800000c; /* pcaddi $t0, 0 (i.e. $t0 <- tramp) */ ++ tramp[1] = 0x28c0418d; /* ld.d $t1, $t0, 16 */ ++ tramp[2] = 0x4c0001a0; /* jirl $zero, $t1, 0 */ ++ tramp[3] = 0x03400000; /* nop */ ++ tramp[4] = fn; ++ tramp[5] = fn >> 32; ++ ++ closure->cif = cif; ++ closure->fun = fun; ++ closure->user_data = user_data; ++ ++ __builtin___clear_cache (codeloc, codeloc + FFI_TRAMPOLINE_SIZE); ++ return FFI_OK; ++} ++ ++extern void ffi_go_closure_asm (void) FFI_HIDDEN; ++ ++ffi_status ++ffi_prep_go_closure (ffi_go_closure *closure, ffi_cif *cif, ++ void (*fun) (ffi_cif *, void *, void **, void *)) ++{ ++ if (cif->abi <= FFI_FIRST_ABI || cif->abi >= FFI_LAST_ABI) ++ return FFI_BAD_ABI; ++ ++ closure->tramp = (void *) ffi_go_closure_asm; ++ closure->cif = cif; ++ closure->fun = fun; ++ return FFI_OK; ++} ++ ++/* Called by the assembly code with aregs pointing to saved argument registers ++ and stack pointing to the stacked arguments. Return values passed in ++ registers will be reloaded from aregs. */ ++void FFI_HIDDEN ++ffi_closure_inner (ffi_cif *cif, ++ void (*fun) (ffi_cif *, void *, void **, void *), ++ void *user_data, size_t *stack, call_context *aregs) ++{ ++ void **avalue = alloca (cif->nargs * sizeof (void *)); ++ /* Storage for arguments which will be copied by unmarshal(). We could ++ theoretically avoid the copies in many cases and use at most 128 bytes ++ of memory, but allocating disjoint storage for each argument is ++ simpler. */ ++ char *astorage = alloca (cif->nargs * MAXCOPYARG); ++ void *rvalue; ++ call_builder cb; ++ int return_by_ref; ++ int i; ++ ++ cb.aregs = aregs; ++ cb.used_integer = cb.used_float = 0; ++ cb.used_stack = stack; ++ ++ return_by_ref = passed_by_ref (&cb, cif->rtype, 0); ++ if (return_by_ref) ++ unmarshal (&cb, &ffi_type_pointer, 0, &rvalue); ++ else ++ rvalue = alloca (cif->rtype->size); ++ ++ for (i = 0; i < cif->nargs; i++) ++ avalue[i] ++ = unmarshal (&cb, cif->arg_types[i], i >= cif->loongarch_nfixedargs, ++ astorage + i * MAXCOPYARG); ++ ++ fun (cif, rvalue, avalue, user_data); ++ ++ if (!return_by_ref && cif->rtype->type != FFI_TYPE_VOID) ++ { ++ cb.used_integer = cb.used_float = 0; ++ marshal (&cb, cif->rtype, 0, rvalue); ++ } ++} +diff --git a/src/loongarch64/ffitarget.h b/src/loongarch64/ffitarget.h +new file mode 100644 +index 000000000000..5a4698af308d +--- /dev/null ++++ b/src/loongarch64/ffitarget.h +@@ -0,0 +1,82 @@ ++/* -----------------------------------------------------------------*-C-*- ++ ffitarget.h - Copyright (c) 2022 Xu Chenghua ++ 2022 Cheng Lulu ++ ++ Target configuration macros for LoongArch. ++ ++ Permission is hereby granted, free of charge, to any person obtaining ++ a copy of this software and associated documentation files (the ++ ``Software''), to deal in the Software without restriction, including ++ without limitation the rights to use, copy, modify, merge, publish, ++ distribute, sublicense, and/or sell copies of the Software, and to ++ permit persons to whom the Software is furnished to do so, subject to ++ the following conditions: ++ ++ The above copyright notice and this permission notice shall be included ++ in all copies or substantial portions of the Software. ++ ++ THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, ++ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF ++ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND ++ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT ++ HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, ++ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, ++ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER ++ DEALINGS IN THE SOFTWARE. ++ ++ ----------------------------------------------------------------------- */ ++ ++#ifndef LIBFFI_TARGET_H ++#define LIBFFI_TARGET_H ++ ++#ifndef LIBFFI_H ++#error \ ++ "Please do not include ffitarget.h directly into your source. Use ffi.h instead." ++#endif ++ ++#ifndef __loongarch__ ++#error \ ++ "libffi was configured for a LoongArch target but this does not appear to be a LoongArch compiler." ++#endif ++ ++#ifndef LIBFFI_ASM ++ ++typedef unsigned long ffi_arg; ++typedef signed long ffi_sarg; ++ ++typedef enum ffi_abi ++{ ++ FFI_FIRST_ABI = 0, ++ FFI_LP64S, ++ FFI_LP64F, ++ FFI_LP64D, ++ FFI_LAST_ABI, ++ ++#if defined(__loongarch64) ++#if defined(__loongarch_soft_float) ++ FFI_DEFAULT_ABI = FFI_LP64S ++#elif defined(__loongarch_single_float) ++ FFI_DEFAULT_ABI = FFI_LP64F ++#elif defined(__loongarch_double_float) ++ FFI_DEFAULT_ABI = FFI_LP64D ++#else ++#error unsupported LoongArch floating-point ABI ++#endif ++#else ++#error unsupported LoongArch base architecture ++#endif ++} ffi_abi; ++ ++#endif /* LIBFFI_ASM */ ++ ++/* ---- Definitions for closures ----------------------------------------- */ ++ ++#define FFI_CLOSURES 1 ++#define FFI_GO_CLOSURES 1 ++#define FFI_TRAMPOLINE_SIZE 24 ++#define FFI_NATIVE_RAW_API 0 ++#define FFI_EXTRA_CIF_FIELDS \ ++ unsigned loongarch_nfixedargs; \ ++ unsigned loongarch_unused; ++#define FFI_TARGET_SPECIFIC_VARIADIC ++#endif +diff --git a/src/loongarch64/sysv.S b/src/loongarch64/sysv.S +new file mode 100644 +index 000000000000..9e0da1125301 +--- /dev/null ++++ b/src/loongarch64/sysv.S +@@ -0,0 +1,296 @@ ++/* ----------------------------------------------------------------------- ++ sysv.S - Copyright (c) 2022 Xu Chenghua ++ 2022 Cheng Lulu ++ ++ LoongArch Foreign Function Interface ++ ++ Permission is hereby granted, free of charge, to any person obtaining ++ a copy of this software and associated documentation files (the ++ ``Software''), to deal in the Software without restriction, including ++ without limitation the rights to use, copy, modify, merge, publish, ++ distribute, sublicense, and/or sell copies of the Software, and to ++ permit persons to whom the Software is furnished to do so, subject to ++ the following conditions: ++ ++ The above copyright notice and this permission notice shall be included ++ in all copies or substantial portions of the Software. ++ ++ THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, ++ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF ++ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND ++ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT ++ HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, ++ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, ++ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER ++ DEALINGS IN THE SOFTWARE. ++ ----------------------------------------------------------------------- */ ++ ++#define LIBFFI_ASM ++#include ++#include ++ ++/* Define aliases so that we can handle all ABIs uniformly. */ ++ ++#if __SIZEOF_POINTER__ == 8 ++# define PTRS 8 ++# define LARG ld.d ++# define SARG st.d ++#else ++# define PTRS 4 ++# define LARG ld.w ++# define SARG st.w ++#endif ++ ++#if defined(__loongarch_single_float) ++# define FLTS 4 ++# define FLD fld.w ++# define FST fst.w ++#elif defined(__loongarch_double_float) ++# define FLTS 8 ++# define FLARG fld.d ++# define FSARG fst.d ++#elif defined(__loongarch_soft_float) ++# define FLTS 0 ++#else ++#error unsupported LoongArch floating-point ABI ++#endif ++ ++ .text ++ .globl ffi_call_asm ++ .type ffi_call_asm, @function ++ .hidden ffi_call_asm ++/* struct call_context ++ { ++ ABI_FLOAT fa[8]; ++ size_t a[10]; ++ } ++ ++ - 8 floating point parameter/result registers (fa[0] - fa[7]) ++ - 8 integer parameter/result registers (a[0] - a[7]) ++ - 2 registers used by the assembly code to in-place construct its own stack ++ frame. ++ - frame pointer (a[8]) ++ - return address (a[9]) ++ ++ void ffi_call_asm (size_t *stackargs, struct call_context *regargs, ++ void (*fn)(void), void *closure); */ ++ ++#define FRAME_LEN (8 * FLTS + 10 * PTRS) ++ ++ffi_call_asm: ++ .cfi_startproc ++ ++ /* We are NOT going to set up an ordinary stack frame. In order to pass ++ the stacked args to the called function, we adjust our stack pointer ++ to a0, which is in the _caller's_ alloca area. We establish our own ++ stack frame at the end of the call_context. ++ ++ Anything below the arguments will be freed at this point, although ++ we preserve the call_context so that it can be read back in the ++ caller. */ ++ ++ .cfi_def_cfa 5, FRAME_LEN # Interim CFA based on a1. ++ SARG $fp, $a1, FRAME_LEN - 2*PTRS ++ .cfi_offset 22, -2*PTRS ++ SARG $ra, $a1, FRAME_LEN - 1*PTRS ++ .cfi_offset 1, -1*PTRS ++ ++ addi.d $fp, $a1, FRAME_LEN ++ move $sp, $a0 ++ .cfi_def_cfa 22, 0 # Our frame is fully set up. ++ ++ # Load arguments. ++ move $t1, $a2 ++ move $t2, $a3 ++ ++#if FLTS ++ FLARG $fa0, $fp, -FRAME_LEN+0*FLTS ++ FLARG $fa1, $fp, -FRAME_LEN+1*FLTS ++ FLARG $fa2, $fp, -FRAME_LEN+2*FLTS ++ FLARG $fa3, $fp, -FRAME_LEN+3*FLTS ++ FLARG $fa4, $fp, -FRAME_LEN+4*FLTS ++ FLARG $fa5, $fp, -FRAME_LEN+5*FLTS ++ FLARG $fa6, $fp, -FRAME_LEN+6*FLTS ++ FLARG $fa7, $fp, -FRAME_LEN+7*FLTS ++#endif ++ ++ LARG $a0, $fp, -FRAME_LEN+8*FLTS+0*PTRS ++ LARG $a1, $fp, -FRAME_LEN+8*FLTS+1*PTRS ++ LARG $a2, $fp, -FRAME_LEN+8*FLTS+2*PTRS ++ LARG $a3, $fp, -FRAME_LEN+8*FLTS+3*PTRS ++ LARG $a4, $fp, -FRAME_LEN+8*FLTS+4*PTRS ++ LARG $a5, $fp, -FRAME_LEN+8*FLTS+5*PTRS ++ LARG $a6, $fp, -FRAME_LEN+8*FLTS+6*PTRS ++ LARG $a7, $fp, -FRAME_LEN+8*FLTS+7*PTRS ++ ++ /* Call */ ++ jirl $ra, $t1, 0 ++ ++#if FLTS ++ /* Save return values - only a0/a1 (fa0/fa1) are used. */ ++ FSARG $fa0, $fp, -FRAME_LEN+0*FLTS ++ FSARG $fa1, $fp, -FRAME_LEN+1*FLTS ++#endif ++ ++ SARG $a0, $fp, -FRAME_LEN+8*FLTS+0*PTRS ++ SARG $a1, $fp, -FRAME_LEN+8*FLTS+1*PTRS ++ ++ /* Restore and return. */ ++ addi.d $sp, $fp, -FRAME_LEN ++ .cfi_def_cfa 3, FRAME_LEN ++ LARG $ra, $fp, -1*PTRS ++ .cfi_restore 1 ++ LARG $fp, $fp, -2*PTRS ++ .cfi_restore 22 ++ jr $ra ++ .cfi_endproc ++ .size ffi_call_asm, .-ffi_call_asm ++ ++ ++/* ffi_closure_asm. Expects address of the passed-in ffi_closure in t1. ++ void ffi_closure_inner (ffi_cif *cif, ++ void (*fun)(ffi_cif *, void *, void **, void *), ++ void *user_data, ++ size_t *stackargs, struct call_context *regargs) */ ++ ++ .globl ffi_closure_asm ++ .hidden ffi_closure_asm ++ .type ffi_closure_asm, @function ++ ++ffi_closure_asm: ++ .cfi_startproc ++ addi.d $sp, $sp, -FRAME_LEN ++ .cfi_def_cfa_offset FRAME_LEN ++ ++ /* Make a frame. */ ++ SARG $fp, $sp, FRAME_LEN - 2*PTRS ++ .cfi_offset 22, -2*PTRS ++ SARG $ra, $sp, FRAME_LEN - 1*PTRS ++ .cfi_offset 1, -1*PTRS ++ addi.d $fp, $sp, FRAME_LEN ++ ++ /* Save arguments. */ ++#if FLTS ++ FSARG $fa0, $sp, 0*FLTS ++ FSARG $fa1, $sp, 1*FLTS ++ FSARG $fa2, $sp, 2*FLTS ++ FSARG $fa3, $sp, 3*FLTS ++ FSARG $fa4, $sp, 4*FLTS ++ FSARG $fa5, $sp, 5*FLTS ++ FSARG $fa6, $sp, 6*FLTS ++ FSARG $fa7, $sp, 7*FLTS ++#endif ++ ++ SARG $a0, $sp, 8*FLTS+0*PTRS ++ SARG $a1, $sp, 8*FLTS+1*PTRS ++ SARG $a2, $sp, 8*FLTS+2*PTRS ++ SARG $a3, $sp, 8*FLTS+3*PTRS ++ SARG $a4, $sp, 8*FLTS+4*PTRS ++ SARG $a5, $sp, 8*FLTS+5*PTRS ++ SARG $a6, $sp, 8*FLTS+6*PTRS ++ SARG $a7, $sp, 8*FLTS+7*PTRS ++ ++ /* Enter C */ ++ LARG $a0, $t0, FFI_TRAMPOLINE_SIZE+0*PTRS ++ LARG $a1, $t0, FFI_TRAMPOLINE_SIZE+1*PTRS ++ LARG $a2, $t0, FFI_TRAMPOLINE_SIZE+2*PTRS ++ addi.d $a3, $sp, FRAME_LEN ++ move $a4, $sp ++ ++ bl ffi_closure_inner ++ ++ /* Return values. */ ++#if FLTS ++ FLARG $fa0, $sp, 0*FLTS ++ FLARG $fa1, $sp, 1*FLTS ++#endif ++ ++ LARG $a0, $sp, 8*FLTS+0*PTRS ++ LARG $a1, $sp, 8*FLTS+1*PTRS ++ ++ /* Restore and return. */ ++ LARG $ra, $sp, FRAME_LEN-1*PTRS ++ .cfi_restore 1 ++ LARG $fp, $sp, FRAME_LEN-2*PTRS ++ .cfi_restore 22 ++ addi.d $sp, $sp, FRAME_LEN ++ .cfi_def_cfa_offset 0 ++ jr $ra ++ .cfi_endproc ++ .size ffi_closure_asm, .-ffi_closure_asm ++ ++/* ffi_go_closure_asm. Expects address of the passed-in ffi_go_closure in t2. ++ void ffi_closure_inner (ffi_cif *cif, ++ void (*fun)(ffi_cif *, void *, void **, void *), ++ void *user_data, ++ size_t *stackargs, struct call_context *regargs) */ ++ ++ .globl ffi_go_closure_asm ++ .hidden ffi_go_closure_asm ++ .type ffi_go_closure_asm, @function ++ ++ffi_go_closure_asm: ++ .cfi_startproc ++ addi.d $sp, $sp, -FRAME_LEN ++ .cfi_def_cfa_offset FRAME_LEN ++ ++ /* Make a frame. */ ++ SARG $fp, $sp, FRAME_LEN - 2*PTRS ++ .cfi_offset 22, -2*PTRS ++ SARG $ra, $sp, FRAME_LEN - 1*PTRS ++ .cfi_offset 1, -1*PTRS ++ addi.d $fp, $sp, FRAME_LEN ++ ++ /* Save arguments. */ ++#if FLTS ++ FSARG $fa0, $sp, 0*FLTS ++ FSARG $fa1, $sp, 1*FLTS ++ FSARG $fa2, $sp, 2*FLTS ++ FSARG $fa3, $sp, 3*FLTS ++ FSARG $fa4, $sp, 4*FLTS ++ FSARG $fa5, $sp, 5*FLTS ++ FSARG $fa6, $sp, 6*FLTS ++ FSARG $fa7, $sp, 7*FLTS ++#endif ++ ++ SARG $a0, $sp, 8*FLTS+0*PTRS ++ SARG $a1, $sp, 8*FLTS+1*PTRS ++ SARG $a2, $sp, 8*FLTS+2*PTRS ++ SARG $a3, $sp, 8*FLTS+3*PTRS ++ SARG $a4, $sp, 8*FLTS+4*PTRS ++ SARG $a5, $sp, 8*FLTS+5*PTRS ++ SARG $a6, $sp, 8*FLTS+6*PTRS ++ SARG $a7, $sp, 8*FLTS+7*PTRS ++ ++ /* Enter C */ ++ LARG $a0, $t2, 1*PTRS ++ LARG $a1, $t2, 2*PTRS ++ move $a2, $t2 ++ addi.d $a3, $sp, FRAME_LEN ++ move $a4, $sp ++ ++ bl ffi_closure_inner ++ ++ /* Return values. */ ++#if FLTS ++ FLARG $fa0, $sp, 0*FLTS ++ FLARG $fa1, $sp, 1*FLTS ++#endif ++ ++ LARG $a0, $sp, 8*FLTS+0*PTRS ++ LARG $a1, $sp, 8*FLTS+1*PTRS ++ ++ /* Restore and return. */ ++ LARG $ra, $sp, FRAME_LEN-1*PTRS ++ .cfi_restore 1 ++ LARG $fp, $sp, FRAME_LEN-2*PTRS ++ .cfi_restore 22 ++ addi.d $sp, $sp, FRAME_LEN ++ .cfi_def_cfa_offset 0 ++ jr $ra ++ .cfi_endproc ++ .size ffi_go_closure_asm, .-ffi_go_closure_asm ++ ++#if defined __ELF__ && defined __linux__ ++ .section .note.GNU-stack,"",%progbits ++#endif +-- +2.34.1 + diff --git a/patch/0002-static-trampoline-for-LoongArch-723.patch b/patch/0002-static-trampoline-for-LoongArch-723.patch new file mode 100644 index 0000000..6c479ca --- /dev/null +++ b/patch/0002-static-trampoline-for-LoongArch-723.patch @@ -0,0 +1,139 @@ +From 64bee76cb69dd1845bb4b13e25e6ef881837301e Mon Sep 17 00:00:00 2001 +From: Xi Ruoyao +Date: Fri, 22 Jul 2022 05:56:30 +0800 +Subject: [PATCH 2/4] static trampoline for LoongArch (#723) + +For the benefit and technical details of static trampoline, see +https://github.com/libffi/libffi/pull/624. As a new architecture, let's +be "safer" from the start. + +The change survived libffi testsuite on loongarch64-linux-gnu. +--- + configure.ac | 2 +- + src/loongarch64/ffi.c | 30 +++++++++++++++++++++++++++--- + src/loongarch64/sysv.S | 33 ++++++++++++++++++++++++++++++++- + 3 files changed, 60 insertions(+), 5 deletions(-) + +diff --git a/configure.ac b/configure.ac +index 70f6d2c2ea44..c70b23bf6add 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -373,7 +373,7 @@ if test "$enable_exec_static_tramp" != no; then + case "$target" in + *-cygwin*) + ;; +- *arm*-*-linux-* | aarch64*-*-linux-* | i*86-*-linux-* | x86_64-*-linux-*) ++ *arm*-*-linux-* | aarch64*-*-linux-* | i*86-*-linux-* | x86_64-*-linux-* | loongarch*-*-linux-*) + AC_DEFINE(FFI_EXEC_STATIC_TRAMP, 1, + [Define this if you want statically defined trampolines]) + ;; +diff --git a/src/loongarch64/ffi.c b/src/loongarch64/ffi.c +index 7a2889281891..ed9c15f3968d 100644 +--- a/src/loongarch64/ffi.c ++++ b/src/loongarch64/ffi.c +@@ -519,8 +519,16 @@ ffi_prep_closure_loc (ffi_closure *closure, ffi_cif *cif, + if (cif->abi <= FFI_FIRST_ABI || cif->abi >= FFI_LAST_ABI) + return FFI_BAD_ABI; + +- /* We will call ffi_closure_inner with codeloc, not closure, but as long +- as the memory is readable it should work. */ ++#if defined(FFI_EXEC_STATIC_TRAMP) ++ if (ffi_tramp_is_present(closure)) ++ { ++ ffi_tramp_set_parms (closure->ftramp, ffi_closure_asm, closure); ++ goto out; ++ } ++#endif ++ ++ /* Fill the dynamic trampoline. We will call ffi_closure_inner with codeloc, ++ not closure, but as long as the memory is readable it should work. */ + tramp[0] = 0x1800000c; /* pcaddi $t0, 0 (i.e. $t0 <- tramp) */ + tramp[1] = 0x28c0418d; /* ld.d $t1, $t0, 16 */ + tramp[2] = 0x4c0001a0; /* jirl $zero, $t1, 0 */ +@@ -528,11 +536,13 @@ ffi_prep_closure_loc (ffi_closure *closure, ffi_cif *cif, + tramp[4] = fn; + tramp[5] = fn >> 32; + ++ __builtin___clear_cache (codeloc, codeloc + FFI_TRAMPOLINE_SIZE); ++ ++out: + closure->cif = cif; + closure->fun = fun; + closure->user_data = user_data; + +- __builtin___clear_cache (codeloc, codeloc + FFI_TRAMPOLINE_SIZE); + return FFI_OK; + } + +@@ -593,3 +603,17 @@ ffi_closure_inner (ffi_cif *cif, + marshal (&cb, cif->rtype, 0, rvalue); + } + } ++ ++#if defined(FFI_EXEC_STATIC_TRAMP) ++void * ++ffi_tramp_arch (size_t *tramp_size, size_t *map_size) ++{ ++ extern void *trampoline_code_table; ++ ++ *tramp_size = 16; ++ /* A mapping size of 64K is chosen to cover the page sizes of 4K, 16K, and ++ 64K. */ ++ *map_size = 1 << 16; ++ return &trampoline_code_table; ++} ++#endif +diff --git a/src/loongarch64/sysv.S b/src/loongarch64/sysv.S +index 9e0da1125301..aa7bde2c1efc 100644 +--- a/src/loongarch64/sysv.S ++++ b/src/loongarch64/sysv.S +@@ -147,7 +147,7 @@ ffi_call_asm: + .size ffi_call_asm, .-ffi_call_asm + + +-/* ffi_closure_asm. Expects address of the passed-in ffi_closure in t1. ++/* ffi_closure_asm. Expects address of the passed-in ffi_closure in t0. + void ffi_closure_inner (ffi_cif *cif, + void (*fun)(ffi_cif *, void *, void **, void *), + void *user_data, +@@ -219,6 +219,37 @@ ffi_closure_asm: + .cfi_endproc + .size ffi_closure_asm, .-ffi_closure_asm + ++/* Static trampoline code table, in which each element is a trampoline. ++ ++ The trampoline clobbers t0 and t1, but we don't save them on the stack ++ because our psABI explicitly says they are scratch registers, at least for ++ ELF. Our dynamic trampoline is already clobbering them anyway. ++ ++ The trampoline has two parameters - target code to jump to and data for ++ the target code. The trampoline extracts the parameters from its parameter ++ block (see tramp_table_map()). The trampoline saves the data address in ++ t0 and jumps to the target code. As ffi_closure_asm() already expects the ++ data address to be in t0, we don't need a "ffi_closure_asm_alt". */ ++ ++#if defined(FFI_EXEC_STATIC_TRAMP) ++ .align 16 ++ .globl trampoline_code_table ++ .hidden trampoline_code_table ++ .type trampoline_code_table, @function ++ ++trampoline_code_table: ++ ++ .rept 65536 / 16 ++ pcaddu12i $t1, 16 # 65536 >> 12 ++ ld.d $t0, $t1, 0 ++ ld.d $t1, $t1, 8 ++ jirl $zero, $t1, 0 ++ .endr ++ .size trampoline_code_table, .-trampoline_code_table ++ ++ .align 2 ++#endif ++ + /* ffi_go_closure_asm. Expects address of the passed-in ffi_go_closure in t2. + void ffi_closure_inner (ffi_cif *cif, + void (*fun)(ffi_cif *, void *, void **, void *), +-- +2.34.1 + diff --git a/patch/0003-LoongArch-Fix-a-build-error-with-GCC-14-825.patch b/patch/0003-LoongArch-Fix-a-build-error-with-GCC-14-825.patch new file mode 100644 index 0000000..2d72b59 --- /dev/null +++ b/patch/0003-LoongArch-Fix-a-build-error-with-GCC-14-825.patch @@ -0,0 +1,29 @@ +From e4ff891fe26a414c8eb820b78b1ca1dcf9404ce6 Mon Sep 17 00:00:00 2001 +From: Xi Ruoyao +Date: Thu, 15 Feb 2024 20:49:27 +0800 +Subject: [PATCH 3/4] LoongArch: Fix a build error with GCC 14 (#825) + +Fix the build error with GCC 14: + + ../src/loongarch64/ffi.c: In function 'ffi_prep_closure_loc': + ../src/loongarch64/ffi.c:525:7: error: implicit declaration of + function 'ffi_tramp_set_parms' [-Wimplicit-function-declaration] +--- + src/loongarch64/ffi.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/src/loongarch64/ffi.c b/src/loongarch64/ffi.c +index ed9c15f3968d..eed3e1e8f5e2 100644 +--- a/src/loongarch64/ffi.c ++++ b/src/loongarch64/ffi.c +@@ -28,6 +28,7 @@ + + #include + #include ++#include + + #include + #include +-- +2.34.1 + diff --git a/patch/0004-Fix-loongarch64-soft-float-build-816-817.patch b/patch/0004-Fix-loongarch64-soft-float-build-816-817.patch new file mode 100644 index 0000000..5d37624 --- /dev/null +++ b/patch/0004-Fix-loongarch64-soft-float-build-816-817.patch @@ -0,0 +1,27 @@ +From 9b834fe7a339ba28d1b29517e82a582cdea31f6d Mon Sep 17 00:00:00 2001 +From: =?utf-8?q?=E6=9D=A8=E5=B1=BF=E6=9D=B0?= + <30362409+scylaac@users.noreply.github.com> +Date: Thu, 15 Feb 2024 20:51:40 +0800 +Subject: [PATCH 4/4] Fix loongarch64 soft-float build (#816) (#817) + +--- + src/loongarch64/ffi.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/src/loongarch64/ffi.c b/src/loongarch64/ffi.c +index eed3e1e8f5e2..8754c3730394 100644 +--- a/src/loongarch64/ffi.c ++++ b/src/loongarch64/ffi.c +@@ -59,7 +59,9 @@ + */ + typedef struct call_context + { ++#if !defined(__loongarch_soft_float) + ABI_FLOAT fa[8]; ++#endif + size_t a[10]; + } call_context; + +-- +2.34.1 + -- Gitee