]> git.ipfire.org Git - thirdparty/glibc.git/commitdiff
S390: Use s390-64 specific ionv-modules on s390-32, too.
authorStefan Liebler <stli@linux.vnet.ibm.com>
Wed, 25 May 2016 15:18:05 +0000 (17:18 +0200)
committerStefan Liebler <stli@linux.vnet.ibm.com>
Wed, 25 May 2016 15:18:05 +0000 (17:18 +0200)
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.

ChangeLog
sysdeps/s390/Makefile [new file with mode: 0644]
sysdeps/s390/iso-8859-1_cp037_z900.c [moved from sysdeps/s390/s390-64/iso-8859-1_cp037_z900.c with 98% similarity]
sysdeps/s390/s390-64/Makefile
sysdeps/s390/utf16-utf32-z9.c [moved from sysdeps/s390/s390-64/utf16-utf32-z9.c with 97% similarity]
sysdeps/s390/utf8-utf16-z9.c [moved from sysdeps/s390/s390-64/utf8-utf16-z9.c with 97% similarity]
sysdeps/s390/utf8-utf32-z9.c [moved from sysdeps/s390/s390-64/utf8-utf32-z9.c with 97% similarity]

index 306c6160209d575753c9fd4cf8e256cba549c54d..78afe17d2d5922ec899d0988e5691fc11b2abc50 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,22 @@
+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,
diff --git a/sysdeps/s390/Makefile b/sysdeps/s390/Makefile
new file mode 100644 (file)
index 0000000..d508365
--- /dev/null
@@ -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
similarity index 98%
rename from sysdeps/s390/s390-64/iso-8859-1_cp037_z900.c
rename to sysdeps/s390/iso-8859-1_cp037_z900.c
index 3b63e6a94f1b9bafd848375f29b8606f4fbd3ee9..fc25dff3871512f25e044ae6c3ef46686693f1a9 100644 (file)
@@ -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)         \
index ce4aa3b58d804b973693b8f3bbce062a3178e006..b4d793bb3dd1f703c71be0c62d8dba6175ca7b1d 100644 (file)
@@ -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
similarity index 97%
rename from sysdeps/s390/s390-64/utf16-utf32-z9.c
rename to sysdeps/s390/utf16-utf32-z9.c
index 61d0a94939e6d9a66cd6bfa5c673c802719097c8..8d42ab8b0e4b6b74eb53c8c3dd5311affba34d4a 100644 (file)
 # 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;
similarity index 97%
rename from sysdeps/s390/s390-64/utf8-utf16-z9.c
rename to sysdeps/s390/utf8-utf16-z9.c
index 7520ef2cc4e264dd413998d620c34588ba1b13d1..d3dc9bd97e072902b9b983fadccf51088b91aea2 100644 (file)
 # 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"                    \
similarity index 97%
rename from sysdeps/s390/s390-64/utf8-utf32-z9.c
rename to sysdeps/s390/utf8-utf32-z9.c
index f9c9199ab4f143257b09b1dc4e0d83dd115b6a87..e39e0a73d9f32ddbcbbec622688beaa52eccbea9 100644 (file)
 # 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;