This is the mail archive of the
libc-alpha@sourceware.org
mailing list for the glibc project.
[Committed] S/390: Fix optimized mem* routines on 31 bit kernels
- From: "Andreas Krebbel" <andreas at de dot ibm dot com>
- To: libc-alpha at sourceware dot org
- Date: Thu, 6 Sep 2012 10:45:37 +0200
- Subject: [Committed] S/390: Fix optimized mem* routines on 31 bit kernels
Hi,
the attached patch fixes two problems with the optimized mem*
functions on 31 bit kernels.
- The optimized routines contain zarch mode instructions and therefore
are supposed to be used only for 31 bit code running on a 64 bit
kernel. However, assembling these files using the -mzarch option
makes them depend unconditionally on the highgprs kernel feature.
So the whole Glibc and everything using its crt files would be
prevented from being run on a 31 bit kernel although the IFUNC
resolver at runtime would make sure that the ESA mode variant would
be used in that case.
In order to fix this I've added a new s390 dependent pseudo
(.machinemode) to GAS which allows to enable zarch mode instructions
without setting the highgprs flag:
http://sourceware.org/ml/binutils/2012-09/msg00071.html
The attached patch makes use of this new pseudo. So building 31 bit
glibc for S/390 currently depends on upstream Binutils.
- Currently the Linux kernel reports having the highgprs feature even
for 31 bit kernels. This is a bug which will be fixed soon. So far
the Glibc IFUNC resolver on 31 bit (correctly) relies on the fact
that highgprs is only possible in zarch mode. With the patch the
zarch mode flag is checked explicitly as well in order to deal with
the currently broken kernels.
Bye,
-Andreas-
2012-09-06 Andreas Krebbel <Andreas.Krebbel@de.ibm.com>
* sysdeps/s390/s390-32/multiarch/Makefile: Remove -mzarch
assembler flag.
* sysdeps/s390/s390-32/multiarch/memcmp.S: Use .machinemode
zarch_nohighgprs around the zarch optimized routines.
* sysdeps/s390/s390-32/multiarch/memcpy.S: Likewise.
* sysdeps/s390/s390-32/multiarch/memset.S: Likewise.
* sysdeps/s390/s390-32/multiarch/ifunc-resolve.c: Explicitly check
for zarch.
---
sysdeps/s390/s390-32/multiarch/Makefile | 6 ------
sysdeps/s390/s390-32/multiarch/ifunc-resolve.c | 3 ++-
sysdeps/s390/s390-32/multiarch/memcmp.S | 2 ++
sysdeps/s390/s390-32/multiarch/memcpy.S | 2 ++
sysdeps/s390/s390-32/multiarch/memset.S | 2 ++
5 files changed, 8 insertions(+), 7 deletions(-)
Index: glibc/sysdeps/s390/s390-32/multiarch/Makefile
===================================================================
--- glibc.orig/sysdeps/s390/s390-32/multiarch/Makefile
+++ glibc/sysdeps/s390/s390-32/multiarch/Makefile
@@ -1,9 +1,3 @@
-ASFLAGS-.o += -Wa,-mzarch
-ASFLAGS-.os += -Wa,-mzarch
-ASFLAGS-.op += -Wa,-mzarch
-ASFLAGS-.og += -Wa,-mzarch
-ASFLAGS-.ob += -Wa,-mzarch
-ASFLAGS-.oS += -Wa,-mzarch
ifeq ($(subdir),string)
sysdep_routines += ifunc-resolve memset memcpy memcmp
endif
Index: glibc/sysdeps/s390/s390-32/multiarch/memcmp.S
===================================================================
--- glibc.orig/sysdeps/s390/s390-32/multiarch/memcmp.S
+++ glibc/sysdeps/s390/s390-32/multiarch/memcmp.S
@@ -31,6 +31,7 @@
ENTRY(memcmp_z196)
.machine "z196"
+ .machinemode "zarch_nohighgprs"
ltr %r4,%r4
je .L_Z196_4
ahi %r4,-1
@@ -64,6 +65,7 @@ END(memcmp_z196)
ENTRY(memcmp_z10)
.machine "z10"
+ .machinemode "zarch_nohighgprs"
ltr %r4,%r4
je .L_Z10_4
ahi %r4,-1
Index: glibc/sysdeps/s390/s390-32/multiarch/memcpy.S
===================================================================
--- glibc.orig/sysdeps/s390/s390-32/multiarch/memcpy.S
+++ glibc/sysdeps/s390/s390-32/multiarch/memcpy.S
@@ -31,6 +31,7 @@
ENTRY(memcpy_z196)
.machine "z196"
+ .machinemode "zarch_nohighgprs"
llgfr %r4,%r4
ltgr %r4,%r4
je .L_Z196_4
@@ -61,6 +62,7 @@ END(memcpy_z196)
ENTRY(memcpy_z10)
.machine "z10"
+ .machinemode "zarch_nohighgprs"
llgfr %r4,%r4
cgije %r4,0,.L_Z10_4
aghi %r4,-1
Index: glibc/sysdeps/s390/s390-32/multiarch/memset.S
===================================================================
--- glibc.orig/sysdeps/s390/s390-32/multiarch/memset.S
+++ glibc/sysdeps/s390/s390-32/multiarch/memset.S
@@ -31,6 +31,7 @@
ENTRY(memset_z196)
.machine "z196"
+ .machinemode "zarch_nohighgprs"
llgfr %r4,%r4
ltgr %r4,%r4
je .L_Z196_4
@@ -62,6 +63,7 @@ END(memset_z196)
ENTRY(memset_z10)
.machine "z10"
+ .machinemode "zarch_nohighgprs"
llgfr %r4,%r4
cgije %r4,0,.L_Z10_4
stc %r3,0(%r2)
Index: glibc/sysdeps/s390/s390-32/multiarch/ifunc-resolve.c
===================================================================
--- glibc.orig/sysdeps/s390/s390-32/multiarch/ifunc-resolve.c
+++ glibc/sysdeps/s390/s390-32/multiarch/ifunc-resolve.c
@@ -41,7 +41,8 @@
void *resolve_##FUNC (unsigned long int dl_hwcap) \
{ \
if ((dl_hwcap & HWCAP_S390_STFLE) \
- && (dl_hwcap & HWCAP_S390_HIGH_GPRS)) /* Implies zarch */ \
+ && (dl_hwcap & HWCAP_S390_ZARCH) \
+ && (dl_hwcap & HWCAP_S390_HIGH_GPRS)) \
{ \
/* We want just 1 double word to be returned. */ \
register unsigned long reg0 asm("0") = 0; \