diff options
author | Stefan Liebler <stli@linux.vnet.ibm.com> | 2016-05-25 17:18:05 +0200 |
---|---|---|
committer | Stefan Liebler <stli@linux.vnet.ibm.com> | 2016-05-25 17:18:05 +0200 |
commit | ee518b7070b1bcb41382b6db10f513e071b2c20e (patch) | |
tree | ceb9b067700ae10c747ae8e6ccbc241f43a8eb0b | |
parent | 6896776c3c9c32fd22324e6de6737dd69ae73213 (diff) | |
download | glibc-ee518b7070b1bcb41382b6db10f513e071b2c20e.tar.gz glibc-ee518b7070b1bcb41382b6db10f513e071b2c20e.tar.xz glibc-ee518b7070b1bcb41382b6db10f513e071b2c20e.zip |
S390: Use s390-64 specific ionv-modules on s390-32, too.
This patch reworks the existing s390 64bit specific iconv modules in order to use them on s390 31bit, too. Thus the parts for subdirectory iconvdata in sysdeps/s390/s390-64/Makefile were moved to sysdeps/s390/Makefile so that they apply on 31bit, too. All those modules are moved from sysdeps/s390/s390-64 directory to sysdeps/s390. The iso-8859-1 to/from cp037 module was adjusted, to use brct (branch relative on count) instruction on 31bit s390 instead of brctg, because the brctg is a zarch instruction and is not available on a 31bit kernel. The utf modules are using zarch instructions, thus the directive machinemode zarch_nohighgprs was added to the inline assemblies to omit the high-gprs flag in the shared libraries. Otherwise they can't be loaded on a 31bit kernel. The ifunc resolvers were adjusted in order to call the etf3eh or vector variants only if zarch instructions are available (64bit kernel in 31bit compat-mode). Furthermore some variable types were changed. E.g. unsigned long long would be a register pair on s390 31bit, but we want only one single register. For variables of type size_t the register contents have to be enlarged from a 32bit to a 64bit value on 31bit, because the inline assemblies uses 64bit values in such cases. ChangeLog: * sysdeps/s390/s390-64/Makefile (iconvdata-subdirectory): Move to ... * sysdeps/s390/Makefile: ... here. * sysdeps/s390/s390-64/iso-8859-1_cp037_z900.c: Move to ... * sysdeps/s390/iso-8859-1_cp037_z900.c: ... here. (BRANCH_ON_COUNT): New define. (TR_LOOP): Use BRANCH_ON_COUNT instead of brctg. * sysdeps/s390/s390-64/utf16-utf32-z9.c: Move to ... * sysdeps/s390/utf16-utf32-z9.c: ... here and adjust to run on s390-32, too. * sysdeps/s390/s390-64/utf8-utf16-z9.c: Move to ... * sysdeps/s390/utf8-utf16-z9.c: ... here and adjust to run on s390-32, too. * sysdeps/s390/s390-64/utf8-utf32-z9.c: Move to ... * sysdeps/s390/utf8-utf32-z9.c: ... here and adjust to run on s390-32, too.
-rw-r--r-- | ChangeLog | 19 | ||||
-rw-r--r-- | sysdeps/s390/Makefile | 31 | ||||
-rw-r--r-- | sysdeps/s390/iso-8859-1_cp037_z900.c (renamed from sysdeps/s390/s390-64/iso-8859-1_cp037_z900.c) | 8 | ||||
-rw-r--r-- | sysdeps/s390/s390-64/Makefile | 32 | ||||
-rw-r--r-- | sysdeps/s390/utf16-utf32-z9.c (renamed from sysdeps/s390/s390-64/utf16-utf32-z9.c) | 20 | ||||
-rw-r--r-- | sysdeps/s390/utf8-utf16-z9.c (renamed from sysdeps/s390/s390-64/utf8-utf16-z9.c) | 20 | ||||
-rw-r--r-- | sysdeps/s390/utf8-utf32-z9.c (renamed from sysdeps/s390/s390-64/utf8-utf32-z9.c) | 23 |
7 files changed, 107 insertions, 46 deletions
diff --git a/ChangeLog b/ChangeLog index 306c616020..78afe17d2d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,24 @@ 2016-05-25 Stefan Liebler <stli@linux.vnet.ibm.com> + * sysdeps/s390/s390-64/Makefile (iconvdata-subdirectory): + Move to ... + * sysdeps/s390/Makefile: ... here. + * sysdeps/s390/s390-64/iso-8859-1_cp037_z900.c: Move to ... + * sysdeps/s390/iso-8859-1_cp037_z900.c: ... here. + (BRANCH_ON_COUNT): New define. + (TR_LOOP): Use BRANCH_ON_COUNT instead of brctg. + * sysdeps/s390/s390-64/utf16-utf32-z9.c: Move to ... + * sysdeps/s390/utf16-utf32-z9.c: ... here and adjust to + run on s390-32, too. + * sysdeps/s390/s390-64/utf8-utf16-z9.c: Move to ... + * sysdeps/s390/utf8-utf16-z9.c: ... here and adjust to + run on s390-32, too. + * sysdeps/s390/s390-64/utf8-utf32-z9.c: Move to ... + * sysdeps/s390/utf8-utf32-z9.c: ... here and adjust to + run on s390-32, too. + +2016-05-25 Stefan Liebler <stli@linux.vnet.ibm.com> + * sysdeps/s390/s390-64/utf16-utf32-z9.c: Use ifunc to select c, etf3eh or new vector loop-variant. diff --git a/sysdeps/s390/Makefile b/sysdeps/s390/Makefile new file mode 100644 index 0000000000..d50836579f --- /dev/null +++ b/sysdeps/s390/Makefile @@ -0,0 +1,31 @@ +ifeq ($(subdir),iconvdata) +ISO-8859-1_CP037_Z900-routines := iso-8859-1_cp037_z900 +ISO-8859-1_CP037_Z900-map := gconv.map + +UTF8_UTF32_Z9-routines := utf8-utf32-z9 +UTF8_UTF32_Z9-map := gconv.map + +UTF16_UTF32_Z9-routines := utf16-utf32-z9 +UTF16_UTF32_Z9-map := gconv.map + +UTF8_UTF16_Z9-routines := utf8-utf16-z9 +UTF8_UTF16_Z9-map := gconv.map + +s390x-iconv-modules = ISO-8859-1_CP037_Z900 UTF8_UTF16_Z9 UTF16_UTF32_Z9 UTF8_UTF32_Z9 + +extra-modules-left += $(s390x-iconv-modules) +include extra-module.mk + +cpp-srcs-left := $(foreach mod,$(s390x-iconv-modules),$($(mod)-routines)) +lib := iconvdata +include $(patsubst %,$(..)cppflags-iterator.mk,$(cpp-srcs-left)) + +extra-objs += $(addsuffix .so, $(s390x-iconv-modules)) +install-others += $(patsubst %, $(inst_gconvdir)/%.so, $(s390x-iconv-modules)) + +$(patsubst %, $(inst_gconvdir)/%.so, $(s390x-iconv-modules)) : \ +$(inst_gconvdir)/%.so: $(objpfx)%.so $(+force) + $(do-install-program) + +sysdeps-gconv-modules = ../sysdeps/s390/gconv-modules +endif diff --git a/sysdeps/s390/s390-64/iso-8859-1_cp037_z900.c b/sysdeps/s390/iso-8859-1_cp037_z900.c index 3b63e6a94f..fc25dff387 100644 --- a/sysdeps/s390/s390-64/iso-8859-1_cp037_z900.c +++ b/sysdeps/s390/iso-8859-1_cp037_z900.c @@ -175,6 +175,12 @@ __attribute__ ((aligned (8))) = #define MIN_NEEDED_FROM 1 #define MIN_NEEDED_TO 1 +# if defined __s390x__ +# define BRANCH_ON_COUNT(REG,LBL) "brctg %" #REG "," #LBL "\n\t" +# else +# define BRANCH_ON_COUNT(REG,LBL) "brct %" #REG "," #LBL "\n\t" +# endif + #define TR_LOOP(TABLE) \ { \ size_t length = (inend - inptr < outend - outptr \ @@ -188,7 +194,7 @@ __attribute__ ((aligned (8))) = " tr 0(256,%[R_OUT]),0(%[R_TBL])\n\t" \ " la %[R_IN],256(%[R_IN])\n\t" \ " la %[R_OUT],256(%[R_OUT])\n\t" \ - " brctg %[R_LI],0b\n\t" \ + BRANCH_ON_COUNT ([R_LI], 0b) \ : /* outputs */ [R_IN] "+a" (inptr) \ , [R_OUT] "+a" (outptr), [R_LI] "+d" (blocks) \ : /* inputs */ [R_TBL] "a" (TABLE) \ diff --git a/sysdeps/s390/s390-64/Makefile b/sysdeps/s390/s390-64/Makefile index ce4aa3b58d..b4d793bb3d 100644 --- a/sysdeps/s390/s390-64/Makefile +++ b/sysdeps/s390/s390-64/Makefile @@ -7,35 +7,3 @@ CFLAGS-rtld.c += -Wno-uninitialized -Wno-unused CFLAGS-dl-load.c += -Wno-unused CFLAGS-dl-reloc.c += -Wno-unused endif - -ifeq ($(subdir),iconvdata) -ISO-8859-1_CP037_Z900-routines := iso-8859-1_cp037_z900 -ISO-8859-1_CP037_Z900-map := gconv.map - -UTF8_UTF32_Z9-routines := utf8-utf32-z9 -UTF8_UTF32_Z9-map := gconv.map - -UTF16_UTF32_Z9-routines := utf16-utf32-z9 -UTF16_UTF32_Z9-map := gconv.map - -UTF8_UTF16_Z9-routines := utf8-utf16-z9 -UTF8_UTF16_Z9-map := gconv.map - -s390x-iconv-modules = ISO-8859-1_CP037_Z900 UTF8_UTF16_Z9 UTF16_UTF32_Z9 UTF8_UTF32_Z9 - -extra-modules-left += $(s390x-iconv-modules) -include extra-module.mk - -cpp-srcs-left := $(foreach mod,$(s390x-iconv-modules),$($(mod)-routines)) -lib := iconvdata -include $(patsubst %,$(..)cppflags-iterator.mk,$(cpp-srcs-left)) - -extra-objs += $(addsuffix .so, $(s390x-iconv-modules)) -install-others += $(patsubst %, $(inst_gconvdir)/%.so, $(s390x-iconv-modules)) - -$(patsubst %, $(inst_gconvdir)/%.so, $(s390x-iconv-modules)) : \ -$(inst_gconvdir)/%.so: $(objpfx)%.so $(+force) - $(do-install-program) - -sysdeps-gconv-modules = ../sysdeps/s390/gconv-modules -endif diff --git a/sysdeps/s390/s390-64/utf16-utf32-z9.c b/sysdeps/s390/utf16-utf32-z9.c index 61d0a94939..8d42ab8b0e 100644 --- a/sysdeps/s390/s390-64/utf16-utf32-z9.c +++ b/sysdeps/s390/utf16-utf32-z9.c @@ -36,6 +36,12 @@ # define ASM_CLOBBER_VR(NR) #endif +#if defined __s390x__ +# define CONVERT_32BIT_SIZE_T(REG) +#else +# define CONVERT_32BIT_SIZE_T(REG) "llgfr %" #REG ",%" #REG "\n\t" +#endif + /* UTF-32 big endian byte order mark. */ #define BOM_UTF32 0x0000feffu @@ -144,13 +150,14 @@ gconv_end (struct __gconv_step *data) #define HARDWARE_CONVERT(INSTRUCTION) \ { \ register const unsigned char* pInput __asm__ ("8") = inptr; \ - register unsigned long long inlen __asm__ ("9") = inend - inptr; \ + register size_t inlen __asm__ ("9") = inend - inptr; \ register unsigned char* pOutput __asm__ ("10") = outptr; \ - register unsigned long long outlen __asm__("11") = outend - outptr; \ - uint64_t cc = 0; \ + register size_t outlen __asm__("11") = outend - outptr; \ + unsigned long cc = 0; \ \ __asm__ __volatile__ (".machine push \n\t" \ ".machine \"z9-109\" \n\t" \ + ".machinemode \"zarch_nohighgprs\"\n\t" \ "0: " INSTRUCTION " \n\t" \ ".machine pop \n\t" \ " jo 0b \n\t" \ @@ -260,6 +267,8 @@ gconv_end (struct __gconv_step *data) /* Setup to check for surrogates. */ \ " larl %[R_TMP],9f\n\t" \ " vlm %%v30,%%v31,0(%[R_TMP])\n\t" \ + CONVERT_32BIT_SIZE_T ([R_INLEN]) \ + CONVERT_32BIT_SIZE_T ([R_OUTLEN]) \ /* Loop which handles UTF-16 chars <0xd800, >0xdfff. */ \ "0: clgijl %[R_INLEN],16,2f\n\t" \ " clgijl %[R_OUTLEN],32,2f\n\t" \ @@ -496,6 +505,8 @@ strong_alias (__from_utf16_loop_c_single, __from_utf16_loop_single) /* Setup to check for surrogates. */ \ " larl %[R_TMP],9f\n\t" \ " vlm %%v30,%%v31,0(%[R_TMP])\n\t" \ + CONVERT_32BIT_SIZE_T ([R_INLEN]) \ + CONVERT_32BIT_SIZE_T ([R_OUTLEN]) \ /* Loop which handles UTF-16 chars \ ch < 0xd800 || (ch > 0xdfff && ch < 0x10000). */ \ "0: clgijl %[R_INLEN],32,20f\n\t" \ @@ -612,7 +623,8 @@ __to_utf16_loop_resolver (unsigned long int dl_hwcap) return __to_utf16_loop_vx; else #endif - if (dl_hwcap & HWCAP_S390_ETF3EH) + if (dl_hwcap & HWCAP_S390_ZARCH && dl_hwcap & HWCAP_S390_HIGH_GPRS + && dl_hwcap & HWCAP_S390_ETF3EH) return __to_utf16_loop_etf3eh; else return __to_utf16_loop_c; diff --git a/sysdeps/s390/s390-64/utf8-utf16-z9.c b/sysdeps/s390/utf8-utf16-z9.c index 7520ef2cc4..d3dc9bd97e 100644 --- a/sysdeps/s390/s390-64/utf8-utf16-z9.c +++ b/sysdeps/s390/utf8-utf16-z9.c @@ -36,6 +36,12 @@ # define ASM_CLOBBER_VR(NR) #endif +#if defined __s390x__ +# define CONVERT_32BIT_SIZE_T(REG) +#else +# define CONVERT_32BIT_SIZE_T(REG) "llgfr %" #REG ",%" #REG "\n\t" +#endif + /* Defines for skeleton.c. */ #define DEFINE_INIT 0 #define DEFINE_FINI 0 @@ -140,13 +146,14 @@ gconv_end (struct __gconv_step *data) #define HARDWARE_CONVERT(INSTRUCTION) \ { \ register const unsigned char* pInput __asm__ ("8") = inptr; \ - register unsigned long long inlen __asm__ ("9") = inend - inptr; \ + register size_t inlen __asm__ ("9") = inend - inptr; \ register unsigned char* pOutput __asm__ ("10") = outptr; \ - register unsigned long long outlen __asm__("11") = outend - outptr; \ - uint64_t cc = 0; \ + register size_t outlen __asm__("11") = outend - outptr; \ + unsigned long cc = 0; \ \ __asm__ __volatile__ (".machine push \n\t" \ ".machine \"z9-109\" \n\t" \ + ".machinemode \"zarch_nohighgprs\"\n\t" \ "0: " INSTRUCTION " \n\t" \ ".machine pop \n\t" \ " jo 0b \n\t" \ @@ -221,6 +228,8 @@ gconv_end (struct __gconv_step *data) ".machinemode \"zarch_nohighgprs\"\n\t" \ " vrepib %%v30,0x7f\n\t" /* For compare > 0x7f. */ \ " vrepib %%v31,0x20\n\t" \ + CONVERT_32BIT_SIZE_T ([R_INLEN]) \ + CONVERT_32BIT_SIZE_T ([R_OUTLEN]) \ /* Loop which handles UTF-8 chars <=0x7f. */ \ "0: clgijl %[R_INLEN],16,20f\n\t" \ " clgijl %[R_OUTLEN],32,20f\n\t" \ @@ -479,7 +488,8 @@ __from_utf8_loop_resolver (unsigned long int dl_hwcap) return __from_utf8_loop_vx; else #endif - if (dl_hwcap & HWCAP_S390_ETF3EH) + if (dl_hwcap & HWCAP_S390_ZARCH && dl_hwcap & HWCAP_S390_HIGH_GPRS + && dl_hwcap & HWCAP_S390_ETF3EH) return __from_utf8_loop_etf3eh; else return __from_utf8_loop_c; @@ -602,6 +612,8 @@ strong_alias (__from_utf8_loop_c_single, __from_utf8_loop_single) /* Setup to check for values <= 0x7f. */ \ " larl %[R_TMP],9f\n\t" \ " vlm %%v30,%%v31,0(%[R_TMP])\n\t" \ + CONVERT_32BIT_SIZE_T ([R_INLEN]) \ + CONVERT_32BIT_SIZE_T ([R_OUTLEN]) \ /* Loop which handles UTF-16 chars <=0x7f. */ \ "0: clgijl %[R_INLEN],32,2f\n\t" \ " clgijl %[R_OUTLEN],16,2f\n\t" \ diff --git a/sysdeps/s390/s390-64/utf8-utf32-z9.c b/sysdeps/s390/utf8-utf32-z9.c index f9c9199ab4..e39e0a73d9 100644 --- a/sysdeps/s390/s390-64/utf8-utf32-z9.c +++ b/sysdeps/s390/utf8-utf32-z9.c @@ -36,6 +36,12 @@ # define ASM_CLOBBER_VR(NR) #endif +#if defined __s390x__ +# define CONVERT_32BIT_SIZE_T(REG) +#else +# define CONVERT_32BIT_SIZE_T(REG) "llgfr %" #REG ",%" #REG "\n\t" +#endif + /* Defines for skeleton.c. */ #define DEFINE_INIT 0 #define DEFINE_FINI 0 @@ -140,13 +146,14 @@ gconv_end (struct __gconv_step *data) #define HARDWARE_CONVERT(INSTRUCTION) \ { \ register const unsigned char* pInput __asm__ ("8") = inptr; \ - register unsigned long long inlen __asm__ ("9") = inend - inptr; \ + register size_t inlen __asm__ ("9") = inend - inptr; \ register unsigned char* pOutput __asm__ ("10") = outptr; \ - register unsigned long long outlen __asm__("11") = outend - outptr; \ - uint64_t cc = 0; \ + register size_t outlen __asm__("11") = outend - outptr; \ + unsigned long cc = 0; \ \ __asm__ __volatile__ (".machine push \n\t" \ ".machine \"z9-109\" \n\t" \ + ".machinemode \"zarch_nohighgprs\"\n\t" \ "0: " INSTRUCTION " \n\t" \ ".machine pop \n\t" \ " jo 0b \n\t" \ @@ -413,6 +420,8 @@ gconv_end (struct __gconv_step *data) ".machinemode \"zarch_nohighgprs\"\n\t" \ " vrepib %%v30,0x7f\n\t" /* For compare > 0x7f. */ \ " vrepib %%v31,0x20\n\t" \ + CONVERT_32BIT_SIZE_T ([R_INLEN]) \ + CONVERT_32BIT_SIZE_T ([R_OUTLEN]) \ /* Loop which handles UTF-8 chars <=0x7f. */ \ "0: clgijl %[R_INLEN],16,20f\n\t" \ " clgijl %[R_OUTLEN],64,20f\n\t" \ @@ -554,7 +563,8 @@ __from_utf8_loop_resolver (unsigned long int dl_hwcap) return __from_utf8_loop_vx; else #endif - if (dl_hwcap & HWCAP_S390_ETF3EH) + if (dl_hwcap & HWCAP_S390_ZARCH && dl_hwcap & HWCAP_S390_HIGH_GPRS + && dl_hwcap & HWCAP_S390_ETF3EH) return __from_utf8_loop_etf3eh; else return __from_utf8_loop_c; @@ -683,6 +693,8 @@ strong_alias (__from_utf8_loop_c_single, __from_utf8_loop_single) " vzero %%v21\n\t" \ " vleih %%v21,8192,0\n\t" /* element 0: > */ \ " vleih %%v21,-8192,2\n\t" /* element 1: =<> */ \ + CONVERT_32BIT_SIZE_T ([R_INLEN]) \ + CONVERT_32BIT_SIZE_T ([R_OUTLEN]) \ /* Loop which handles UTF-32 chars <=0x7f. */ \ "0: clgijl %[R_INLEN],64,20f\n\t" \ " clgijl %[R_OUTLEN],16,20f\n\t" \ @@ -795,7 +807,8 @@ __to_utf8_loop_resolver (unsigned long int dl_hwcap) return __to_utf8_loop_vx; else #endif - if (dl_hwcap & HWCAP_S390_ETF3EH) + if (dl_hwcap & HWCAP_S390_ZARCH && dl_hwcap & HWCAP_S390_HIGH_GPRS + && dl_hwcap & HWCAP_S390_ETF3EH) return __to_utf8_loop_etf3eh; else return __to_utf8_loop_c; |