From 3d6b6fbc1f374f55fdb9e277d7e851fe112d68ff Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Fri, 15 Sep 2006 14:40:38 +0000 Subject: power-cpu add-on, 2.05 ISA optimized libs --- fedora/Makefile | 2 +- fedora/glibc.spec.in | 75 +++++++++++++++- fedora/makepatch.awk | 1 + fedora/power6emul.c | 242 +++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 317 insertions(+), 3 deletions(-) create mode 100644 fedora/power6emul.c (limited to 'fedora') diff --git a/fedora/Makefile b/fedora/Makefile index e2d037341b..73a6fd2287 100644 --- a/fedora/Makefile +++ b/fedora/Makefile @@ -114,7 +114,7 @@ $(tar-name)-$(branch-name).patch: makepatch.awk glibc.spec \ mv -f patch.tmp $@ # makepatch.awk omits these files from the patch; we put them in a tar file. -outside-patch = fedora c_stubs rtkaio \ +outside-patch = fedora c_stubs rtkaio powerpc-cpu \ localedata/charmaps/GB18030 iconvdata/gb18030.c $(tar-name)-$(branch-name)-$(snapshot-name).tar.bz2: Makefile branch.mk \ diff --git a/fedora/glibc.spec.in b/fedora/glibc.spec.in index 9b338cb3dc..ab0007ca20 100644 --- a/fedora/glibc.spec.in +++ b/fedora/glibc.spec.in @@ -8,6 +8,11 @@ %define buildxen 0 %define xenpackage 0 %endif +%ifarch ppc ppc64 +%define buildpower6 1 +%else +%define buildpower6 0 +%endif %define rtkaioarches %{ix86} x86_64 ia64 ppc ppc64 s390 s390x %define debuginfocommonarches %{ix86} alpha alphaev6 sparc sparcv9 %define _unpackaged_files_terminate_build 0 @@ -821,7 +826,7 @@ GXX="g++ -m64" BuildFlags="$BuildFlags -DNDEBUG=1" EnableKernel="--enable-kernel=%{enablekernel}" echo "$GCC" > Gcc -AddOns=`echo */configure | sed -e 's!/configure!!g;s!\(linuxthreads\|nptl\|rtkaio\)\( \|$\)!!g;s! \+$!!;s! !,!g;s!^!,!;/^,\*$/d'` +AddOns=`echo */configure | sed -e 's!/configure!!g;s!\(linuxthreads\|nptl\|rtkaio\|powerpc-cpu\)\( \|$\)!!g;s! \+$!!;s! !,!g;s!^!,!;/^,\*$/d'` %ifarch %{rtkaioarches} AddOns=,rtkaio$AddOns %endif @@ -850,6 +855,27 @@ build_nptl linuxnptl build_nptl linuxnptl-nosegneg -mno-tls-direct-seg-refs %endif +%if %{buildpower6} +( +platform=`LD_SHOW_AUXV=1 /bin/true | sed -n 's/^AT_PLATFORM:[[:blank:]]*//p'` +if [ "$platform" != power6 ]; then + mkdir -p power6emul/{lib,lib64} + $GCC -shared -O2 -fpic -o power6emul/%{_lib}/power6emul.so fedora/power6emul.c -Wl,-z,initfirst +%ifarch ppc + echo '' | gcc -shared -nostdlib -O2 -fpic -m64 -o power6emul/lib64/power6emul.so -xc - +%endif +%ifarch ppc64 + echo '' | gcc -shared -nostdlib -O2 -fpic -m32 -o power6emul/lib/power6emul.so -xc - +%endif + export LD_PRELOAD=`pwd`/power6emul/\$LIB/power6emul.so +fi +AddOns=",powerpc-cpu$AddOns --with-cpu=power6" +GCC="$GCC -mcpu=power6" +GXX="$GXX -mcpu=power6" +build_nptl linuxnptl-power6 +) +%endif + cd build-%{nptl_target_cpu}-linuxnptl $GCC -static -L. -Os ../fedora/glibc_post_upgrade.c -o glibc_post_upgrade.%{_target_cpu} \ -DNO_SIZE_OPTIMIZATION \ @@ -907,6 +933,29 @@ ln -sf `basename $RPM_BUILD_ROOT/%{_lib}/rtkaio/$SubDir/librtkaio-*.so` $RPM_BUI cd .. %endif +%if %{buildpower6} +cd build-%{nptl_target_cpu}-linuxnptl-power6 +mkdir -p $RPM_BUILD_ROOT/%{_lib}/power6/ +cp -a libc.so $RPM_BUILD_ROOT/%{_lib}/power6/`basename $RPM_BUILD_ROOT/%{_lib}/libc-*.so` +ln -sf `basename $RPM_BUILD_ROOT/%{_lib}/libc-*.so` $RPM_BUILD_ROOT/%{_lib}/power6/`basename $RPM_BUILD_ROOT/%{_lib}/libc.so.*` +cp -a math/libm.so $RPM_BUILD_ROOT/%{_lib}/power6/`basename $RPM_BUILD_ROOT/%{_lib}/libm-*.so` +ln -sf `basename $RPM_BUILD_ROOT/%{_lib}/libm-*.so` $RPM_BUILD_ROOT/%{_lib}/power6/`basename $RPM_BUILD_ROOT/%{_lib}/libm.so.*` +cp -a nptl/libpthread.so $RPM_BUILD_ROOT/%{_lib}/power6/libpthread-%{version}.so +pushd $RPM_BUILD_ROOT/%{_lib}/power6 +ln -sf libpthread-*.so `basename $RPM_BUILD_ROOT/%{_lib}/libpthread.so.*` +popd +cp -a rt/librt.so $RPM_BUILD_ROOT/%{_lib}/power6/`basename $RPM_BUILD_ROOT/%{_lib}/librt-*.so` +ln -sf `basename $RPM_BUILD_ROOT/%{_lib}/librt-*.so` $RPM_BUILD_ROOT/%{_lib}/power6/`basename $RPM_BUILD_ROOT/%{_lib}/librt.so.*` +cp -a nptl_db/libthread_db.so $RPM_BUILD_ROOT/%{_lib}/power6/`basename $RPM_BUILD_ROOT/%{_lib}/libthread_db-*.so` +ln -sf `basename $RPM_BUILD_ROOT/%{_lib}/libthread_db-*.so` $RPM_BUILD_ROOT/%{_lib}/power6/`basename $RPM_BUILD_ROOT/%{_lib}/libthread_db.so.*` +%ifarch %{rtkaioarches} +mkdir -p $RPM_BUILD_ROOT/%{_lib}/rtkaio/power6 +cp -a rtkaio/librtkaio.so $RPM_BUILD_ROOT/%{_lib}/rtkaio/power6/`basename $RPM_BUILD_ROOT/%{_lib}/librt-*.so | sed s/librt-/librtkaio-/` +ln -sf `basename $RPM_BUILD_ROOT/%{_lib}/rtkaio/power6/librtkaio-*.so` $RPM_BUILD_ROOT/%{_lib}/rtkaio/power6/`basename $RPM_BUILD_ROOT/%{_lib}/librt.so.*` +%endif +cd .. +%endif + # compatibility hack: this locale has vanished from glibc, but some other # programs are still using it. Normally we would handle it in the %pre # section but with glibc that is simply not an option @@ -1156,6 +1205,19 @@ cd build-%{nptl_target_cpu}-linuxnptl-nosegneg ) | tee check.log || : cd .. %endif +%if %{buildpower6} +echo ====================TESTING -mcpu=power6============= +cd build-%{nptl_target_cpu}-linuxnptl-power6 +( if [ -d ../power6emul ]; then + export LD_PRELOAD=`cd ../power6emul; pwd`/\$LIB/power6emul.so + fi + make -j$numprocs -k check PARALLELMFLAGS=-s 2>&1 + sleep 10s + teepid="`ps -eo ppid,pid,command | awk '($1 == '${parent}' && $3 ~ /^tee/) { print $2 }'`" + [ -n "$teepid" ] && kill $teepid +) | tee check.log || : +cd .. +%endif echo ====================TESTING DETAILS================= for i in `sed -n 's|^.*\*\*\* \[\([^]]*\.out\)\].*$|\1|p' build-*-linux*/check.log`; do echo =====$i===== @@ -1373,6 +1435,12 @@ rm -f *.filelist* %dir /%{_lib}/rtkaio/%{nosegneg_subdir} %endif %endif +%if %{buildpower6} +%dir /%{_lib}/power6 +%ifarch %{rtkaioarches} +%dir /%{_lib}/rtkaio/power6 +%endif +%endif %ifarch s390x %dir /lib /lib/ld64.so.1 @@ -1397,6 +1465,7 @@ rm -f *.filelist* %if %{xenpackage} %files -f nosegneg.filelist xen %defattr(-,root,root) +%dir /%{_lib}/%{nosegneg_subdir_base} %dir /%{_lib}/%{nosegneg_subdir} %endif @@ -1456,7 +1525,9 @@ rm -f *.filelist* %changelog * Fri Sep 15 2006 Jakub Jelinek 2.4.90-32 -- use just AT_PLATFORM and altivec AT_HWCAP bit for library selection +- on ppc* use just AT_PLATFORM and altivec AT_HWCAP bit for library selection +- fix lrintl and lroundl on ppc{,64} +- use hidden visibility on fstatat{,64} and mknodat in libc_nonshared.a * Sun Sep 10 2006 Jakub Jelinek 2.4.90-31 - fix pthread_cond_{,timed}wait cancellation (BZ#3123) diff --git a/fedora/makepatch.awk b/fedora/makepatch.awk index fba827de4b..fadf1c7e56 100644 --- a/fedora/makepatch.awk +++ b/fedora/makepatch.awk @@ -32,6 +32,7 @@ if ($2 ~ /.cvsignore$/ || $2 ~ /^c_stubs/ || $2 ~ /^rtkaio/ || + $2 ~ /^powerpc-cpu/ || $2 ~ /^fedora/ || $2 ~ /^localedata\/charmaps\/GB18030/ || $2 ~ /^iconvdata\/gb18030\.c/) { diff --git a/fedora/power6emul.c b/fedora/power6emul.c new file mode 100644 index 0000000000..f1d0d20e0f --- /dev/null +++ b/fedora/power6emul.c @@ -0,0 +1,242 @@ +/* Emulate power6 mf[tf]gpr and fri[zpmn] instructions. + Copyright (C) 2006 Red Hat, Inc. + Contributed by Jakub Jelinek , 2006. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + It is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include +#include + +extern double frip (double), friz (double), frin (double), frim (double); +asm (".globl frip, friz, frin, frim\n.hidden frip, friz, frin, frim\n\t" +#ifdef __powerpc64__ + ".section \".toc\",\"aw\"\n" +"8:" ".tc FD_43300000_0[TC],0x4330000000000000\n" +"9:" ".tc FD_3fe00000_0[TC],0x3fe0000000000000\n\t" + ".previous\n\t" +#else + ".rodata\n\t" + ".align 2\n" +"8:" ".long 0x59800000\n" +"9:" ".long 0x3f000000\n\t" + ".previous\n\t" +#endif + "# frip == ceil\n" +"frip:" "mffs 11\n\t" +#ifdef __powerpc64__ + "lfd 13,8b@toc(2)\n\t" +#else + "mflr 11\n\t" + "bcl 20,31,1f\n" +"1:" "mflr 9\n\t" + "addis 9,9,8b-1b@ha\n\t" + "lfs 13,8b-1b@l(9)\n\t" + "mtlr 11\n\t" +#endif + "fabs 0,1\n\t" + "fsub 12,13,13\n\t" + "fcmpu 7,0,13\n\t" + "fcmpu 6,1,12\n\t" + "bnllr- 7\n\t" + "mtfsfi 7,2\n\t" + "ble- 6,2f\n\t" + "fadd 1,1,13\n\t" + "fsub 1,1,13\n\t" + "fabs 1,1\n\t" + "mtfsf 0x01,11\n\t" + "blr\n" +"2:" "bge- 6,3f\n\t" + "fsub 1,1,13\n\t" + "fadd 1,1,13\n\t" + "fnabs 1,1\n" +"3:" "mtfsf 0x01,11\n\t" + "blr\n\t" + "# friz == trunc\n" +"friz:" "mffs 11\n\t" +#ifdef __powerpc64__ + "lfd 13,8b@toc(2)\n\t" +#else + "mflr 11\n\t" + "bcl 20,31,1f\n" +"1:" "mflr 9\n\t" + "addis 9,9,8b-1b@ha\n\t" + "lfs 13,8b-1b@l(9)\n\t" + "mtlr 11\n\t" +#endif + "fabs 0,1\n\t" + "fsub 12,13,13\n\t" + "fcmpu 7,0,13\n\t" + "fcmpu 6,1,12\n\t" + "bnllr- 7\n\t" + "mtfsfi 7,1\n\t" + "ble- 6,2f\n\t" + "fadd 1,1,13\n\t" + "fsub 1,1,13\n\t" + "fabs 1,1\n\t" + "mtfsf 0x01,11\n\t" + "blr\n" +"2:" "bge- 6,3f\n\t" + "fsub 1,1,13\n\t" + "fadd 1,1,13\n\t" + "fnabs 1,1\n" +"3:" "mtfsf 0x01,11\n\t" + "blr\n\t" + "# frin == round\n" +"frin:" "mffs 11\n\t" +#ifdef __powerpc64__ + "lfd 13,8b@toc(2)\n\t" +#else + "mflr 11\n\t" + "bcl 20,31,1f\n" +"1:" "mflr 9\n\t" + "addis 9,9,8b-1b@ha\n\t" + "addi 9,9,8b-1b@l\n\t" + "mtlr 11\n\t" + "lfs 13,0(9)\n\t" +#endif + "fabs 0,1\n\t" + "fsub 12,13,13\n\t" + "fcmpu 7,0,13\n\t" + "fcmpu 6,1,12\n\t" + "bnllr- 7\n\t" + "mtfsfi 7,1\n\t" +#ifdef __powerpc64__ + "lfd 10,9b@toc(2)\n\t" +#else + "lfs 10,9b-8b(9)\n\t" +#endif + "ble- 6,2f\n\t" + "fadd 1,1,10\n\t" + "fadd 1,1,13\n\t" + "fsub 1,1,13\n\t" + "fabs 1,1\n\t" + "mtfsf 0x01,11\n\t" + "blr\n" +"2:" "fsub 9,1,10\n\t" + "bge- 6,3f\n\t" + "fsub 1,9,13\n\t" + "fadd 1,1,13\n\t" + "fnabs 1,1\n" +"3:" "mtfsf 0x01,11\n\t" + "blr\n\t" + "# frim == floor\n" +"frim:" "mffs 11\n\t" +#ifdef __powerpc64__ + "lfd 13,8b@toc(2)\n\t" +#else + "mflr 11\n\t" + "bcl 20,31,1f\n" +"1:" "mflr 9\n\t" + "addis 9,9,8b-1b@ha\n\t" + "lfs 13,8b-1b@l(9)\n\t" + "mtlr 11\n\t" +#endif + "fabs 0,1\n\t" + "fsub 12,13,13\n\t" + "fcmpu 7,0,13\n\t" + "fcmpu 6,1,12\n\t" + "bnllr- 7\n\t" + "mtfsfi 7,3\n\t" + "ble- 6,2f\n\t" + "fadd 1,1,13\n\t" + "fsub 1,1,13\n\t" + "fabs 1,1\n\t" + "mtfsf 0x01,11\n\t" + "blr\n" +"2:" "bge- 6,3f\n\t" + "fsub 1,1,13\n\t" + "fadd 1,1,13\n\t" + "fnabs 1,1\n" +"3:" "mtfsf 0x01,11\n\t" + "blr\n"); + +static void +catch_sigill (int signal, struct sigcontext *ctx) +{ + unsigned int insn = *(unsigned int *) (ctx->regs->nip); +#ifdef __powerpc64__ + if ((insn & 0xfc1f07ff) == 0x7c0005be) /* mftgpr */ + { + unsigned long *regs = (unsigned long *) ctx->regs; + unsigned fpr = (insn >> 11) & 0x1f; + unsigned gpr = (insn >> 21) & 0x1f; + regs[gpr] = regs[fpr + 0x30]; + ctx->regs->nip += 4; + return; + } + if ((insn & 0xfc1f07ff) == 0x7c0004be) /*mffgpr */ + { + unsigned long *regs = (unsigned long *) ctx->regs; + unsigned fpr = (insn >> 21) & 0x1f; + unsigned gpr = (insn >> 11) & 0x1f; + regs[fpr + 0x30] = regs[gpr]; + ctx->regs->nip += 4; + return; + } +#endif + if ((insn & 0xfc1f073f) == 0xfc000310) /* fri[pznm] */ + { +#ifdef __powerpc64__ + double *regs = (double *) (((char *) ctx->regs) + 0x30 * 8); + unsigned int *fpscr = (unsigned int *) (((char *) ctx->regs) + 0x50 * 8 + 4); +#else + double *regs = (double *) (((char *) ctx->regs) + 0x30 * 4); + unsigned int *fpscr = (unsigned int *) (((char *) ctx->regs) + 0x30 * 4 + 0x20 * 8 + 4); +#endif + unsigned dest = (insn >> 21) & 0x1f; + unsigned src = (insn >> 11) & 0x1f; + switch (insn & 0xc0) + { + case 0: + regs[dest] = frin (regs[src]); + break; + case 0x40: + regs[dest] = friz (regs[src]); + break; + case 0x80: + regs[dest] = frip (regs[src]); + break; + case 0xc0: + regs[dest] = frim (regs[src]); + break; + } + /* Update raised exceptions. */ + union { unsigned int i[2]; double d; } u; + asm volatile ("mffs %0" : "=f" (u.d)); + u.i[1] &= 0xfffe0000; /* Is this correct? */ + *fpscr |= u.i[1]; + ctx->regs->nip += 4; + return; + } + + struct sigaction sa; + sa.sa_handler = SIG_DFL; + sigemptyset (&sa.sa_mask); + sa.sa_flags = 0; + sigaction (signal, &sa, NULL); + raise (signal); +} + +static void +__attribute__ ((constructor)) +install_handler (void) +{ + struct sigaction sa; + sa.sa_handler = (void *) catch_sigill; + sigemptyset (&sa.sa_mask); + sa.sa_flags = SA_RESTART; + sigaction (SIGILL, &sa, NULL); +} -- cgit v1.2.3