summaryrefslogtreecommitdiff
path: root/sysdeps/s390
diff options
context:
space:
mode:
authorSamuel Thibault <samuel.thibault@ens-lyon.org>2018-12-27 19:01:57 +0000
committerSamuel Thibault <samuel.thibault@ens-lyon.org>2018-12-27 19:01:57 +0000
commitcab56836b146bc129f1ad43f0393d95a9deca63a (patch)
tree4f4e655319bbac78fca170da05275c127429b460 /sysdeps/s390
parent04ac1241a4cd004872282c2c82ec37fa33925292 (diff)
parent82dd75a7f436a19047325d62182590c9f9e23a78 (diff)
Merge branch 't/tls' into refs/top-bases/t/tls-threadvar
Diffstat (limited to 'sysdeps/s390')
-rw-r--r--sysdeps/s390/Makefile31
-rw-r--r--sysdeps/s390/asm-syntax.h2
-rw-r--r--sysdeps/s390/atomic-machine.h171
-rw-r--r--sysdeps/s390/bits/byteswap-16.h65
-rw-r--r--sysdeps/s390/bits/byteswap.h134
-rw-r--r--sysdeps/s390/bits/flt-eval-method.h24
-rw-r--r--sysdeps/s390/bits/link.h31
-rw-r--r--sysdeps/s390/bits/mathdef.h36
-rw-r--r--sysdeps/s390/bits/setjmp.h2
-rw-r--r--sysdeps/s390/bits/string.h252
-rw-r--r--sysdeps/s390/bits/xtitypes.h2
-rw-r--r--sysdeps/s390/configure135
-rw-r--r--sysdeps/s390/configure.ac55
-rw-r--r--sysdeps/s390/dl-irel.h2
-rw-r--r--sysdeps/s390/dl-procinfo.c11
-rw-r--r--sysdeps/s390/dl-procinfo.h16
-rw-r--r--sysdeps/s390/dl-tls.h5
-rw-r--r--sysdeps/s390/ffs.c2
-rw-r--r--sysdeps/s390/fix-fp-int-convert-overflow.h2
-rw-r--r--sysdeps/s390/fpu/bits/fenv.h10
-rw-r--r--sysdeps/s390/fpu/bits/mathinline.h100
-rw-r--r--sysdeps/s390/fpu/e_sqrt.c2
-rw-r--r--sysdeps/s390/fpu/e_sqrtf.c2
-rw-r--r--sysdeps/s390/fpu/e_sqrtl.c2
-rw-r--r--sysdeps/s390/fpu/fclrexcpt.c2
-rw-r--r--sysdeps/s390/fpu/fedisblxcpt.c2
-rw-r--r--sysdeps/s390/fpu/feenablxcpt.c2
-rw-r--r--sysdeps/s390/fpu/fegetenv.c2
-rw-r--r--sysdeps/s390/fpu/fegetexcept.c2
-rw-r--r--sysdeps/s390/fpu/fegetmode.c (renamed from sysdeps/s390/nptl/pthread_spin_trylock.c)19
-rw-r--r--sysdeps/s390/fpu/fegetround.c2
-rw-r--r--sysdeps/s390/fpu/feholdexcpt.c4
-rw-r--r--sysdeps/s390/fpu/fenv_libc.h2
-rw-r--r--sysdeps/s390/fpu/fesetenv.c4
-rw-r--r--sysdeps/s390/fpu/fesetexcept.c (renamed from sysdeps/s390/nptl/pthread_spin_lock.c)21
-rw-r--r--sysdeps/s390/fpu/fesetmode.c (renamed from sysdeps/s390/nptl/pthread_spin_unlock.c)29
-rw-r--r--sysdeps/s390/fpu/fesetround.c2
-rw-r--r--sysdeps/s390/fpu/fetestexceptflag.c31
-rw-r--r--sysdeps/s390/fpu/feupdateenv.c2
-rw-r--r--sysdeps/s390/fpu/fgetexcptflg.c2
-rw-r--r--sysdeps/s390/fpu/fix-fp-int-compare-invalid.h36
-rw-r--r--sysdeps/s390/fpu/fpu_control.h2
-rw-r--r--sysdeps/s390/fpu/fraiseexcpt.c43
-rw-r--r--sysdeps/s390/fpu/fsetexcptflg.c5
-rw-r--r--sysdeps/s390/fpu/ftestexcept.c2
-rw-r--r--sysdeps/s390/fpu/get-rounding-mode.h2
-rw-r--r--sysdeps/s390/fpu/libm-test-ulps416
-rw-r--r--sysdeps/s390/fpu/libm-test-ulps-name1
-rw-r--r--sysdeps/s390/fpu/s_fma.c10
-rw-r--r--sysdeps/s390/fpu/s_fmaf.c5
-rw-r--r--sysdeps/s390/gccframe.h2
-rw-r--r--sysdeps/s390/gconv-modules50
-rw-r--r--sysdeps/s390/gmp-mparam.h2
-rw-r--r--sysdeps/s390/iso-8859-1_cp037_z900.c (renamed from sysdeps/s390/s390-64/iso-8859-1_cp037_z900.c)99
-rw-r--r--sysdeps/s390/jmpbuf-offsets.h2
-rw-r--r--sysdeps/s390/jmpbuf-unwind.h2
-rw-r--r--sysdeps/s390/ldsodefs.h2
-rw-r--r--sysdeps/s390/libc-tls.c2
-rw-r--r--sysdeps/s390/linkmap.h4
-rw-r--r--sysdeps/s390/longjmp.c3
-rw-r--r--sysdeps/s390/machine-gmon.h2
-rw-r--r--sysdeps/s390/mempcpy.S (renamed from sysdeps/s390/nptl/pthread_spin_init.c)6
-rw-r--r--sysdeps/s390/memusage.h2
-rw-r--r--sysdeps/s390/multiarch/8bit-generic.c402
-rw-r--r--sysdeps/s390/multiarch/Makefile17
-rw-r--r--sysdeps/s390/multiarch/gconv_simple.c1266
-rw-r--r--sysdeps/s390/multiarch/gen-8bit.sh6
-rw-r--r--sysdeps/s390/multiarch/iconv/skeleton.c21
-rw-r--r--sysdeps/s390/multiarch/ifunc-impl-list.c9
-rw-r--r--sysdeps/s390/multiarch/ifunc-resolve.h86
-rw-r--r--sysdeps/s390/multiarch/memccpy-c.c2
-rw-r--r--sysdeps/s390/multiarch/memccpy-vx.S2
-rw-r--r--sysdeps/s390/multiarch/memccpy.c2
-rw-r--r--sysdeps/s390/multiarch/memchr-vx.S2
-rw-r--r--sysdeps/s390/multiarch/memchr.c7
-rw-r--r--sysdeps/s390/multiarch/mempcpy.c32
-rw-r--r--sysdeps/s390/multiarch/memrchr-c.c2
-rw-r--r--sysdeps/s390/multiarch/memrchr-vx.S2
-rw-r--r--sysdeps/s390/multiarch/memrchr.c2
-rw-r--r--sysdeps/s390/multiarch/rawmemchr-c.c2
-rw-r--r--sysdeps/s390/multiarch/rawmemchr-vx.S2
-rw-r--r--sysdeps/s390/multiarch/rawmemchr.c7
-rw-r--r--sysdeps/s390/multiarch/stpcpy-c.c2
-rw-r--r--sysdeps/s390/multiarch/stpcpy-vx.S2
-rw-r--r--sysdeps/s390/multiarch/stpcpy.c11
-rw-r--r--sysdeps/s390/multiarch/stpncpy-c.c2
-rw-r--r--sysdeps/s390/multiarch/stpncpy-vx.S2
-rw-r--r--sysdeps/s390/multiarch/stpncpy.c8
-rw-r--r--sysdeps/s390/multiarch/strcat-c.c2
-rw-r--r--sysdeps/s390/multiarch/strcat-vx.S2
-rw-r--r--sysdeps/s390/multiarch/strcat.c6
-rw-r--r--sysdeps/s390/multiarch/strchr-c.c2
-rw-r--r--sysdeps/s390/multiarch/strchr-vx.S2
-rw-r--r--sysdeps/s390/multiarch/strchr.c8
-rw-r--r--sysdeps/s390/multiarch/strchrnul-c.c2
-rw-r--r--sysdeps/s390/multiarch/strchrnul-vx.S2
-rw-r--r--sysdeps/s390/multiarch/strchrnul.c2
-rw-r--r--sysdeps/s390/multiarch/strcmp-vx.S2
-rw-r--r--sysdeps/s390/multiarch/strcmp.c9
-rw-r--r--sysdeps/s390/multiarch/strcpy-vx.S2
-rw-r--r--sysdeps/s390/multiarch/strcpy.c7
-rw-r--r--sysdeps/s390/multiarch/strcspn-c.c2
-rw-r--r--sysdeps/s390/multiarch/strcspn-vx.S2
-rw-r--r--sysdeps/s390/multiarch/strcspn.c8
-rw-r--r--sysdeps/s390/multiarch/strlen-c.c2
-rw-r--r--sysdeps/s390/multiarch/strlen-vx.S2
-rw-r--r--sysdeps/s390/multiarch/strlen.c6
-rw-r--r--sysdeps/s390/multiarch/strncat-c.c4
-rw-r--r--sysdeps/s390/multiarch/strncat-vx.S2
-rw-r--r--sysdeps/s390/multiarch/strncat.c2
-rw-r--r--sysdeps/s390/multiarch/strncmp-c.c2
-rw-r--r--sysdeps/s390/multiarch/strncmp-vx.S2
-rw-r--r--sysdeps/s390/multiarch/strncmp.c11
-rw-r--r--sysdeps/s390/multiarch/strncpy-vx.S2
-rw-r--r--sysdeps/s390/multiarch/strncpy.c9
-rw-r--r--sysdeps/s390/multiarch/strnlen-c.c2
-rw-r--r--sysdeps/s390/multiarch/strnlen-vx.S2
-rw-r--r--sysdeps/s390/multiarch/strnlen.c9
-rw-r--r--sysdeps/s390/multiarch/strpbrk-c.c2
-rw-r--r--sysdeps/s390/multiarch/strpbrk-vx.S2
-rw-r--r--sysdeps/s390/multiarch/strpbrk.c8
-rw-r--r--sysdeps/s390/multiarch/strrchr-c.c2
-rw-r--r--sysdeps/s390/multiarch/strrchr-vx.S2
-rw-r--r--sysdeps/s390/multiarch/strrchr.c8
-rw-r--r--sysdeps/s390/multiarch/strspn-c.c2
-rw-r--r--sysdeps/s390/multiarch/strspn-vx.S2
-rw-r--r--sysdeps/s390/multiarch/strspn.c8
-rw-r--r--sysdeps/s390/multiarch/utf16-utf32-z9.c48
-rw-r--r--sysdeps/s390/multiarch/utf8-utf16-z9.c50
-rw-r--r--sysdeps/s390/multiarch/utf8-utf32-z9.c50
-rw-r--r--sysdeps/s390/multiarch/wcpcpy-c.c2
-rw-r--r--sysdeps/s390/multiarch/wcpcpy-vx.S2
-rw-r--r--sysdeps/s390/multiarch/wcpcpy.c2
-rw-r--r--sysdeps/s390/multiarch/wcpncpy-c.c2
-rw-r--r--sysdeps/s390/multiarch/wcpncpy-vx.S2
-rw-r--r--sysdeps/s390/multiarch/wcpncpy.c2
-rw-r--r--sysdeps/s390/multiarch/wcscat-c.c2
-rw-r--r--sysdeps/s390/multiarch/wcscat-vx.S2
-rw-r--r--sysdeps/s390/multiarch/wcscat.c2
-rw-r--r--sysdeps/s390/multiarch/wcschr-c.c2
-rw-r--r--sysdeps/s390/multiarch/wcschr-vx.S2
-rw-r--r--sysdeps/s390/multiarch/wcschr.c9
-rw-r--r--sysdeps/s390/multiarch/wcschrnul-c.c2
-rw-r--r--sysdeps/s390/multiarch/wcschrnul-vx.S2
-rw-r--r--sysdeps/s390/multiarch/wcschrnul.c2
-rw-r--r--sysdeps/s390/multiarch/wcscmp-c.c2
-rw-r--r--sysdeps/s390/multiarch/wcscmp-vx.S2
-rw-r--r--sysdeps/s390/multiarch/wcscmp.c6
-rw-r--r--sysdeps/s390/multiarch/wcscpy-c.c2
-rw-r--r--sysdeps/s390/multiarch/wcscpy-vx.S2
-rw-r--r--sysdeps/s390/multiarch/wcscpy.c2
-rw-r--r--sysdeps/s390/multiarch/wcscspn-c.c2
-rw-r--r--sysdeps/s390/multiarch/wcscspn-vx.S2
-rw-r--r--sysdeps/s390/multiarch/wcscspn.c2
-rw-r--r--sysdeps/s390/multiarch/wcslen-c.c2
-rw-r--r--sysdeps/s390/multiarch/wcslen-vx.S2
-rw-r--r--sysdeps/s390/multiarch/wcslen.c2
-rw-r--r--sysdeps/s390/multiarch/wcsncat-c.c2
-rw-r--r--sysdeps/s390/multiarch/wcsncat-vx.S2
-rw-r--r--sysdeps/s390/multiarch/wcsncat.c2
-rw-r--r--sysdeps/s390/multiarch/wcsncmp-c.c2
-rw-r--r--sysdeps/s390/multiarch/wcsncmp-vx.S2
-rw-r--r--sysdeps/s390/multiarch/wcsncmp.c2
-rw-r--r--sysdeps/s390/multiarch/wcsncpy-c.c2
-rw-r--r--sysdeps/s390/multiarch/wcsncpy-vx.S2
-rw-r--r--sysdeps/s390/multiarch/wcsncpy.c2
-rw-r--r--sysdeps/s390/multiarch/wcsnlen-c.c2
-rw-r--r--sysdeps/s390/multiarch/wcsnlen-vx.S2
-rw-r--r--sysdeps/s390/multiarch/wcsnlen.c2
-rw-r--r--sysdeps/s390/multiarch/wcspbrk-c.c2
-rw-r--r--sysdeps/s390/multiarch/wcspbrk-vx.S2
-rw-r--r--sysdeps/s390/multiarch/wcspbrk.c6
-rw-r--r--sysdeps/s390/multiarch/wcsrchr-c.c2
-rw-r--r--sysdeps/s390/multiarch/wcsrchr-vx.S2
-rw-r--r--sysdeps/s390/multiarch/wcsrchr.c2
-rw-r--r--sysdeps/s390/multiarch/wcsspn-c.c2
-rw-r--r--sysdeps/s390/multiarch/wcsspn-vx.S2
-rw-r--r--sysdeps/s390/multiarch/wcsspn.c6
-rw-r--r--sysdeps/s390/multiarch/wmemchr-c.c2
-rw-r--r--sysdeps/s390/multiarch/wmemchr-vx.S2
-rw-r--r--sysdeps/s390/multiarch/wmemchr.c9
-rw-r--r--sysdeps/s390/multiarch/wmemcmp-c.c2
-rw-r--r--sysdeps/s390/multiarch/wmemcmp-vx.S2
-rw-r--r--sysdeps/s390/multiarch/wmemcmp.c2
-rw-r--r--sysdeps/s390/multiarch/wmemset-c.c2
-rw-r--r--sysdeps/s390/multiarch/wmemset-vx.S2
-rw-r--r--sysdeps/s390/multiarch/wmemset.c9
-rw-r--r--sysdeps/s390/nptl/Makefile5
-rw-r--r--sysdeps/s390/nptl/bits/pthreadtypes-arch.h79
-rw-r--r--sysdeps/s390/nptl/bits/pthreadtypes.h248
-rw-r--r--sysdeps/s390/nptl/bits/semaphore.h2
-rw-r--r--sysdeps/s390/nptl/pthread-offsets.h15
-rw-r--r--sysdeps/s390/nptl/pthreaddef.h2
-rw-r--r--sysdeps/s390/nptl/tcb-offsets.sym1
-rw-r--r--sysdeps/s390/nptl/tls.h21
-rw-r--r--sysdeps/s390/s390-32/Makefile2
-rw-r--r--sysdeps/s390/s390-32/__longjmp.c2
-rw-r--r--sysdeps/s390/s390-32/add_n.S2
-rw-r--r--sysdeps/s390/s390-32/addmul_1.S2
-rw-r--r--sysdeps/s390/s390-32/backtrace.c2
-rw-r--r--sysdeps/s390/s390-32/bcopy.S2
-rw-r--r--sysdeps/s390/s390-32/bits/wordsize.h12
-rw-r--r--sysdeps/s390/s390-32/bzero.S2
-rw-r--r--sysdeps/s390/s390-32/crti.S4
-rw-r--r--sysdeps/s390/s390-32/crtn.S2
-rw-r--r--sysdeps/s390/s390-32/dl-machine.h38
-rw-r--r--sysdeps/s390/s390-32/dl-sysdep.h2
-rw-r--r--sysdeps/s390/s390-32/dl-trampoline.S136
-rw-r--r--sysdeps/s390/s390-32/dl-trampoline.h230
-rw-r--r--sysdeps/s390/s390-32/memchr.S2
-rw-r--r--sysdeps/s390/s390-32/memcmp.S2
-rw-r--r--sysdeps/s390/s390-32/memcpy.S67
-rw-r--r--sysdeps/s390/s390-32/memset.S2
-rw-r--r--sysdeps/s390/s390-32/mul_1.S2
-rw-r--r--sysdeps/s390/s390-32/multiarch/memchr.c2
-rw-r--r--sysdeps/s390/s390-32/multiarch/memcmp-s390.S5
-rw-r--r--sysdeps/s390/s390-32/multiarch/memcmp.c9
-rw-r--r--sysdeps/s390/s390-32/multiarch/memcpy-s390.S38
-rw-r--r--sysdeps/s390/s390-32/multiarch/memcpy.c7
-rw-r--r--sysdeps/s390/s390-32/multiarch/memset-s390.S5
-rw-r--r--sysdeps/s390/s390-32/multiarch/memset.c7
-rw-r--r--sysdeps/s390/s390-32/multiarch/strcmp.c2
-rw-r--r--sysdeps/s390/s390-32/multiarch/strcpy.c2
-rw-r--r--sysdeps/s390/s390-32/multiarch/strncpy.c2
-rw-r--r--sysdeps/s390/s390-32/s390-mcount.S4
-rw-r--r--sysdeps/s390/s390-32/setjmp.S44
-rw-r--r--sysdeps/s390/s390-32/start.S9
-rw-r--r--sysdeps/s390/s390-32/strcmp.S2
-rw-r--r--sysdeps/s390/s390-32/strcpy.S2
-rw-r--r--sysdeps/s390/s390-32/strncpy.S2
-rw-r--r--sysdeps/s390/s390-32/sub_n.S2
-rw-r--r--sysdeps/s390/s390-32/symbol-hacks.h21
-rw-r--r--sysdeps/s390/s390-32/sysdep.h10
-rw-r--r--sysdeps/s390/s390-32/tls-macros.h22
-rw-r--r--sysdeps/s390/s390-32/tst-audit.h2
-rw-r--r--sysdeps/s390/s390-64/Makefile83
-rw-r--r--sysdeps/s390/s390-64/__longjmp.c2
-rw-r--r--sysdeps/s390/s390-64/add_n.S2
-rw-r--r--sysdeps/s390/s390-64/backtrace.c2
-rw-r--r--sysdeps/s390/s390-64/bcopy.S2
-rw-r--r--sysdeps/s390/s390-64/bits/wordsize.h12
-rw-r--r--sysdeps/s390/s390-64/bzero.S2
-rw-r--r--sysdeps/s390/s390-64/crti.S4
-rw-r--r--sysdeps/s390/s390-64/crtn.S2
-rw-r--r--sysdeps/s390/s390-64/dl-machine.h38
-rw-r--r--sysdeps/s390/s390-64/dl-trampoline.S132
-rw-r--r--sysdeps/s390/s390-64/dl-trampoline.h224
-rw-r--r--sysdeps/s390/s390-64/memchr.S2
-rw-r--r--sysdeps/s390/s390-64/memcmp.S2
-rw-r--r--sysdeps/s390/s390-64/memcpy.S51
-rw-r--r--sysdeps/s390/s390-64/memset.S2
-rw-r--r--sysdeps/s390/s390-64/multiarch/memchr.c2
-rw-r--r--sysdeps/s390/s390-64/multiarch/memcmp-s390x.S5
-rw-r--r--sysdeps/s390/s390-64/multiarch/memcmp.c9
-rw-r--r--sysdeps/s390/s390-64/multiarch/memcpy-s390x.S36
-rw-r--r--sysdeps/s390/s390-64/multiarch/memcpy.c7
-rw-r--r--sysdeps/s390/s390-64/multiarch/memset-s390x.S5
-rw-r--r--sysdeps/s390/s390-64/multiarch/memset.c7
-rw-r--r--sysdeps/s390/s390-64/multiarch/strcmp.c2
-rw-r--r--sysdeps/s390/s390-64/multiarch/strcpy.c2
-rw-r--r--sysdeps/s390/s390-64/multiarch/strncpy.c2
-rw-r--r--sysdeps/s390/s390-64/s390x-mcount.S4
-rw-r--r--sysdeps/s390/s390-64/setjmp.S44
-rw-r--r--sysdeps/s390/s390-64/start.S9
-rw-r--r--sysdeps/s390/s390-64/strcmp.S2
-rw-r--r--sysdeps/s390/s390-64/strcpy.S2
-rw-r--r--sysdeps/s390/s390-64/strncpy.S2
-rw-r--r--sysdeps/s390/s390-64/sub_n.S2
-rw-r--r--sysdeps/s390/s390-64/sysdep.h4
-rw-r--r--sysdeps/s390/s390-64/tls-macros.h10
-rw-r--r--sysdeps/s390/s390-64/tst-audit.h2
-rw-r--r--sysdeps/s390/s390-64/utf16-utf32-z9.c337
-rw-r--r--sysdeps/s390/s390-64/utf8-utf16-z9.c471
-rw-r--r--sysdeps/s390/s390-64/utf8-utf32-z9.c511
-rw-r--r--sysdeps/s390/sotruss-lib.c2
-rw-r--r--sysdeps/s390/stackinfo.h2
-rw-r--r--sysdeps/s390/string_private.h2
-rw-r--r--sysdeps/s390/utf16-utf32-z9.c819
-rw-r--r--sysdeps/s390/utf8-utf16-z9.c942
-rw-r--r--sysdeps/s390/utf8-utf32-z9.c983
280 files changed, 6691 insertions, 3451 deletions
diff --git a/sysdeps/s390/Makefile b/sysdeps/s390/Makefile
new file mode 100644
index 0000000000..8a54f88cd7
--- /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 %,$(..)libof-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/asm-syntax.h b/sysdeps/s390/asm-syntax.h
index 64a03b7419..2c37abf483 100644
--- a/sysdeps/s390/asm-syntax.h
+++ b/sysdeps/s390/asm-syntax.h
@@ -1,5 +1,5 @@
/* Definitions for S/390 syntax variations.
- Copyright (C) 1992-2016 Free Software Foundation, Inc.
+ Copyright (C) 1992-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library. Its master source is NOT part of
the C library, however. The master source lives in the GNU MP Library.
diff --git a/sysdeps/s390/atomic-machine.h b/sysdeps/s390/atomic-machine.h
index 4ba41077e4..b80b55ecd2 100644
--- a/sysdeps/s390/atomic-machine.h
+++ b/sysdeps/s390/atomic-machine.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2003-2016 Free Software Foundation, Inc.
+/* Copyright (C) 2003-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Martin Schwidefsky <schwidefsky@de.ibm.com>, 2003.
@@ -43,78 +43,119 @@ typedef uintptr_t uatomicptr_t;
typedef intmax_t atomic_max_t;
typedef uintmax_t uatomic_max_t;
-#define USE_ATOMIC_COMPILER_BUILTINS 0
+/* Activate all C11 atomic builtins.
+ Note:
+ E.g. in nptl/pthread_key_delete.c if compiled with GCCs 6 and before,
+ an extra stack-frame is generated and the old value is stored on stack
+ before cs instruction but it never loads this value from stack.
+ An unreleased GCC 7 omit those stack operations.
-#define __arch_compare_and_exchange_val_8_acq(mem, newval, oldval) \
- (abort (), (__typeof (*mem)) 0)
+ E.g. in nptl/pthread_once.c the condition code of cs instruction is
+ evaluated by a sequence of ipm, sra, compare and jump instructions instead
+ of one conditional jump instruction. This also occurs with an unreleased
+ GCC 7.
-#define __arch_compare_and_exchange_val_16_acq(mem, newval, oldval) \
- (abort (), (__typeof (*mem)) 0)
-
-#define __arch_compare_and_exchange_val_32_acq(mem, newval, oldval) \
- ({ __typeof (mem) __archmem = (mem); \
- __typeof (*mem) __archold = (oldval); \
- __asm__ __volatile__ ("cs %0,%2,%1" \
- : "+d" (__archold), "=Q" (*__archmem) \
- : "d" (newval), "m" (*__archmem) : "cc", "memory" ); \
- __archold; })
+ The atomic_fetch_abc_def C11 builtins are now using load-and-abc instructions
+ on z196 zarch and higher cpus instead of a loop with compare-and-swap
+ instruction. */
+#define USE_ATOMIC_COMPILER_BUILTINS 1
#ifdef __s390x__
# define __HAVE_64B_ATOMICS 1
-# define __arch_compare_and_exchange_val_64_acq(mem, newval, oldval) \
- ({ __typeof (mem) __archmem = (mem); \
- __typeof (*mem) __archold = (oldval); \
- __asm__ __volatile__ ("csg %0,%2,%1" \
- : "+d" (__archold), "=Q" (*__archmem) \
- : "d" ((long) (newval)), "m" (*__archmem) : "cc", "memory" ); \
- __archold; })
#else
# define __HAVE_64B_ATOMICS 0
-/* For 31 bit we do not really need 64-bit compare-and-exchange. We can
- implement them by use of the csd instruction. The straightforward
- implementation causes warnings so we skip the definition for now. */
-# define __arch_compare_and_exchange_val_64_acq(mem, newval, oldval) \
- (abort (), (__typeof (*mem)) 0)
#endif
+#define ATOMIC_EXCHANGE_USES_CAS 1
+
+/* Implement some of the non-C11 atomic macros from include/atomic.h
+ with help of the C11 atomic builtins. The other non-C11 atomic macros
+ are using the macros defined here. */
+
+/* Atomically store NEWVAL in *MEM if *MEM is equal to OLDVAL.
+ Return the old *MEM value. */
+#define atomic_compare_and_exchange_val_acq(mem, newval, oldval) \
+ ({ __atomic_check_size((mem)); \
+ typeof ((__typeof (*(mem))) *(mem)) __atg1_oldval = (oldval); \
+ __atomic_compare_exchange_n (mem, (void *) &__atg1_oldval, \
+ newval, 1, __ATOMIC_ACQUIRE, \
+ __ATOMIC_RELAXED); \
+ __atg1_oldval; })
+#define atomic_compare_and_exchange_val_rel(mem, newval, oldval) \
+ ({ __atomic_check_size((mem)); \
+ typeof ((__typeof (*(mem))) *(mem)) __atg1_2_oldval = (oldval); \
+ __atomic_compare_exchange_n (mem, (void *) &__atg1_2_oldval, \
+ newval, 1, __ATOMIC_RELEASE, \
+ __ATOMIC_RELAXED); \
+ __atg1_2_oldval; })
+
+/* Atomically store NEWVAL in *MEM if *MEM is equal to OLDVAL.
+ Return zero if *MEM was changed or non-zero if no exchange happened. */
+#define atomic_compare_and_exchange_bool_acq(mem, newval, oldval) \
+ ({ __atomic_check_size((mem)); \
+ typeof ((__typeof (*(mem))) *(mem)) __atg2_oldval = (oldval); \
+ !__atomic_compare_exchange_n (mem, (void *) &__atg2_oldval, newval, \
+ 1, __ATOMIC_ACQUIRE, \
+ __ATOMIC_RELAXED); })
+#define catomic_compare_and_exchange_bool_acq(mem, newval, oldval) \
+ atomic_compare_and_exchange_bool_acq (mem, newval, oldval)
+
/* Store NEWVALUE in *MEM and return the old value. */
-/* On s390, the atomic_exchange_acq is different from generic implementation,
- because the generic one does not use the condition-code of cs-instruction
- to determine if looping is needed. Instead it saves the old-value and
- compares it against old-value returned by cs-instruction. */
-#ifdef __s390x__
-# define atomic_exchange_acq(mem, newvalue) \
- ({ __typeof (mem) __atg5_memp = (mem); \
- __typeof (*(mem)) __atg5_oldval = *__atg5_memp; \
- __typeof (*(mem)) __atg5_value = (newvalue); \
- if (sizeof (*mem) == 4) \
- __asm__ __volatile__ ("0: cs %0,%2,%1\n" \
- " jl 0b" \
- : "+d" (__atg5_oldval), "=Q" (*__atg5_memp) \
- : "d" (__atg5_value), "m" (*__atg5_memp) \
- : "cc", "memory" ); \
- else if (sizeof (*mem) == 8) \
- __asm__ __volatile__ ("0: csg %0,%2,%1\n" \
- " jl 0b" \
- : "+d" ( __atg5_oldval), "=Q" (*__atg5_memp) \
- : "d" ((long) __atg5_value), "m" (*__atg5_memp) \
- : "cc", "memory" ); \
- else \
- abort (); \
- __atg5_oldval; })
-#else
-# define atomic_exchange_acq(mem, newvalue) \
- ({ __typeof (mem) __atg5_memp = (mem); \
- __typeof (*(mem)) __atg5_oldval = *__atg5_memp; \
- __typeof (*(mem)) __atg5_value = (newvalue); \
- if (sizeof (*mem) == 4) \
- __asm__ __volatile__ ("0: cs %0,%2,%1\n" \
- " jl 0b" \
- : "+d" (__atg5_oldval), "=Q" (*__atg5_memp) \
- : "d" (__atg5_value), "m" (*__atg5_memp) \
- : "cc", "memory" ); \
- else \
- abort (); \
- __atg5_oldval; })
-#endif
+#define atomic_exchange_acq(mem, newvalue) \
+ ({ __atomic_check_size((mem)); \
+ __atomic_exchange_n (mem, newvalue, __ATOMIC_ACQUIRE); })
+#define atomic_exchange_rel(mem, newvalue) \
+ ({ __atomic_check_size((mem)); \
+ __atomic_exchange_n (mem, newvalue, __ATOMIC_RELEASE); })
+
+/* Add VALUE to *MEM and return the old value of *MEM. */
+/* The gcc builtin uses load-and-add instruction on z196 zarch and higher cpus
+ instead of a loop with compare-and-swap instruction. */
+# define atomic_exchange_and_add_acq(mem, operand) \
+ ({ __atomic_check_size((mem)); \
+ __atomic_fetch_add ((mem), (operand), __ATOMIC_ACQUIRE); })
+# define atomic_exchange_and_add_rel(mem, operand) \
+ ({ __atomic_check_size((mem)); \
+ __atomic_fetch_add ((mem), (operand), __ATOMIC_RELEASE); })
+#define catomic_exchange_and_add(mem, value) \
+ atomic_exchange_and_add (mem, value)
+
+/* Atomically *mem |= mask and return the old value of *mem. */
+/* The gcc builtin uses load-and-or instruction on z196 zarch and higher cpus
+ instead of a loop with compare-and-swap instruction. */
+#define atomic_or_val(mem, operand) \
+ ({ __atomic_check_size((mem)); \
+ __atomic_fetch_or ((mem), (operand), __ATOMIC_ACQUIRE); })
+/* Atomically *mem |= mask. */
+#define atomic_or(mem, mask) \
+ do { \
+ atomic_or_val (mem, mask); \
+ } while (0)
+#define catomic_or(mem, mask) \
+ atomic_or (mem, mask)
+
+/* Atomically *mem |= 1 << bit and return true if the bit was set in old value
+ of *mem. */
+/* The load-and-or instruction is used on z196 zarch and higher cpus
+ instead of a loop with compare-and-swap instruction. */
+#define atomic_bit_test_set(mem, bit) \
+ ({ __typeof (*(mem)) __atg14_old; \
+ __typeof (mem) __atg14_memp = (mem); \
+ __typeof (*(mem)) __atg14_mask = ((__typeof (*(mem))) 1 << (bit)); \
+ __atg14_old = atomic_or_val (__atg14_memp, __atg14_mask); \
+ __atg14_old & __atg14_mask; })
+
+/* Atomically *mem &= mask and return the old value of *mem. */
+/* The gcc builtin uses load-and-and instruction on z196 zarch and higher cpus
+ instead of a loop with compare-and-swap instruction. */
+#define atomic_and_val(mem, operand) \
+ ({ __atomic_check_size((mem)); \
+ __atomic_fetch_and ((mem), (operand), __ATOMIC_ACQUIRE); })
+/* Atomically *mem &= mask. */
+#define atomic_and(mem, mask) \
+ do { \
+ atomic_and_val (mem, mask); \
+ } while (0)
+#define catomic_and(mem, mask) \
+ atomic_and(mem, mask)
diff --git a/sysdeps/s390/bits/byteswap-16.h b/sysdeps/s390/bits/byteswap-16.h
deleted file mode 100644
index 87514d1b92..0000000000
--- a/sysdeps/s390/bits/byteswap-16.h
+++ /dev/null
@@ -1,65 +0,0 @@
-/* Macros to swap the order of bytes in 16-bit integer values. s390 version
- Copyright (C) 2012-2016 Free Software Foundation, Inc.
- Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com).
- This file is part of the GNU C Library.
-
- The GNU C 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.
-
- The GNU C Library 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, see
- <http://www.gnu.org/licenses/>. */
-
-#ifndef _BITS_BYTESWAP_H
-# error "Never use <bits/byteswap-16.h> directly; include <byteswap.h> instead."
-#endif
-
-#include <bits/wordsize.h>
-
-/* Swap bytes in 16 bit value. */
-#if defined __GNUC__ && __GNUC__ >= 2
-# if __WORDSIZE == 64
-# define __bswap_16(x) \
- (__extension__ \
- ({ unsigned short int __v, __x = (unsigned short int) (x); \
- if (__builtin_constant_p (x)) \
- __v = __bswap_constant_16 (__x); \
- else { \
- unsigned short int __tmp = (unsigned short int) (__x); \
- __asm__ __volatile__ ( \
- "lrvh %0,%1" \
- : "=&d" (__v) : "m" (__tmp) ); \
- } \
- __v; }))
-# else
-# define __bswap_16(x) \
- (__extension__ \
- ({ unsigned short int __v, __x = (unsigned short int) (x); \
- if (__builtin_constant_p (x)) \
- __v = __bswap_constant_16 (__x); \
- else { \
- unsigned short int __tmp = (unsigned short int) (__x); \
- __asm__ __volatile__ ( \
- "sr %0,%0\n" \
- "la 1,%1\n" \
- "icm %0,2,1(1)\n" \
- "ic %0,0(1)" \
- : "=&d" (__v) : "m" (__tmp) : "1"); \
- } \
- __v; }))
-# endif
-#else
-/* This is better than nothing. */
-static __inline unsigned short int
-__bswap_16 (unsigned short int __bsx)
-{
- return __bswap_constant_16 (__bsx);
-}
-#endif
diff --git a/sysdeps/s390/bits/byteswap.h b/sysdeps/s390/bits/byteswap.h
deleted file mode 100644
index 6a8cb9d82b..0000000000
--- a/sysdeps/s390/bits/byteswap.h
+++ /dev/null
@@ -1,134 +0,0 @@
-/* Macros to swap the order of bytes in integer values. s390 version.
- Copyright (C) 2000-2016 Free Software Foundation, Inc.
- Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com).
- This file is part of the GNU C Library.
-
- The GNU C 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.
-
- The GNU C Library 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, see
- <http://www.gnu.org/licenses/>. */
-
-#if !defined _BYTESWAP_H && !defined _NETINET_IN_H && !defined _ENDIAN_H
-# error "Never use <bits/byteswap.h> directly; include <byteswap.h> instead."
-#endif
-
-#include <bits/wordsize.h>
-
-#ifndef _BITS_BYTESWAP_H
-#define _BITS_BYTESWAP_H 1
-
-#define __bswap_constant_16(x) \
- ((unsigned short int) ((((x) >> 8) & 0xff) | (((x) & 0xff) << 8)))
-
-/* Get __bswap_16. */
-#include <bits/byteswap-16.h>
-
-/* Swap bytes in 32 bit value. */
-#define __bswap_constant_32(x) \
- ((((x) & 0xff000000) >> 24) | (((x) & 0x00ff0000) >> 8) | \
- (((x) & 0x0000ff00) << 8) | (((x) & 0x000000ff) << 24))
-
-#if defined __GNUC__ && __GNUC__ >= 2
-# if __WORDSIZE == 64
-# define __bswap_32(x) \
- (__extension__ \
- ({ unsigned int __v, __x = (x); \
- if (__builtin_constant_p (x)) \
- __v = __bswap_constant_32 (__x); \
- else { \
- unsigned int __tmp = (unsigned int) (__x); \
- __asm__ __volatile__ ( \
- "lrv %0,%1" \
- : "=&d" (__v) : "m" (__tmp)); \
- } \
- __v; }))
-# else
-# define __bswap_32(x) \
- (__extension__ \
- ({ unsigned int __v, __x = (x); \
- if (__builtin_constant_p (x)) \
- __v = __bswap_constant_32 (__x); \
- else { \
- unsigned int __tmp = (unsigned int) (__x); \
- __asm__ __volatile__ ( \
- "la 1,%1\n" \
- "icm %0,8,3(1)\n" \
- "icm %0,4,2(1)\n" \
- "icm %0,2,1(1)\n" \
- "ic %0,0(1)" \
- : "=&d" (__v) : "m" (__tmp) : "1"); \
- } \
- __v; }))
-# endif
-#else
-static __inline unsigned int
-__bswap_32 (unsigned int __bsx)
-{
- return __bswap_constant_32 (__bsx);
-}
-#endif
-
-/* Swap bytes in 64 bit value. */
-#if defined __GNUC__ && __GNUC__ >= 2
-# define __bswap_constant_64(x) \
- (__extension__ ((((x) & 0xff00000000000000ul) >> 56) \
- | (((x) & 0x00ff000000000000ul) >> 40) \
- | (((x) & 0x0000ff0000000000ul) >> 24) \
- | (((x) & 0x000000ff00000000ul) >> 8) \
- | (((x) & 0x00000000ff000000ul) << 8) \
- | (((x) & 0x0000000000ff0000ul) << 24) \
- | (((x) & 0x000000000000ff00ul) << 40) \
- | (((x) & 0x00000000000000fful) << 56)))
-
-# if __WORDSIZE == 64
-# define __bswap_64(x) \
- (__extension__ \
- ({ unsigned long __w, __x = (x); \
- if (__builtin_constant_p (x)) \
- __w = __bswap_constant_64 (__x); \
- else { \
- unsigned long __tmp = (unsigned long) (__x); \
- __asm__ __volatile__ ( \
- "lrvg %0,%1" \
- : "=&d" (__w) : "m" (__tmp)); \
- } \
- __w; }))
-# else
-# define __bswap_64(x) \
- __extension__ \
- ({ union { unsigned long long int __ll; \
- unsigned long int __l[2]; } __w, __r; \
- __w.__ll = (x); \
- __r.__l[0] = __bswap_32 (__w.__l[1]); \
- __r.__l[1] = __bswap_32 (__w.__l[0]); \
- __r.__ll; })
-# endif
-#else
-# define __bswap_constant_64(x) \
- ((((x) & 0xff00000000000000ull) >> 56) \
- | (((x) & 0x00ff000000000000ull) >> 40) \
- | (((x) & 0x0000ff0000000000ull) >> 24) \
- | (((x) & 0x000000ff00000000ull) >> 8) \
- | (((x) & 0x00000000ff000000ull) << 8) \
- | (((x) & 0x0000000000ff0000ull) << 24) \
- | (((x) & 0x000000000000ff00ull) << 40) \
- | (((x) & 0x00000000000000ffull) << 56))
-
-__extension__
-static __inline unsigned long long int
-__bswap_64 (unsigned long long int __bsx)
-{
- return __bswap_constant_64 (__bsx);
-}
-#endif
-
-#endif /* _BITS_BYTESWAP_H */
diff --git a/sysdeps/s390/bits/flt-eval-method.h b/sysdeps/s390/bits/flt-eval-method.h
new file mode 100644
index 0000000000..b0663e80cc
--- /dev/null
+++ b/sysdeps/s390/bits/flt-eval-method.h
@@ -0,0 +1,24 @@
+/* Define __GLIBC_FLT_EVAL_METHOD. S/390 version.
+ Copyright (C) 2016-2018 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C 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.
+
+ The GNU C Library 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, see
+ <http://www.gnu.org/licenses/>. */
+
+#ifndef _MATH_H
+# error "Never use <bits/flt-eval-method.h> directly; include <math.h> instead."
+#endif
+
+/* This value is used because of a historical mistake. */
+#define __GLIBC_FLT_EVAL_METHOD 1
diff --git a/sysdeps/s390/bits/link.h b/sysdeps/s390/bits/link.h
index 2ef7f44225..8d17e9245b 100644
--- a/sysdeps/s390/bits/link.h
+++ b/sysdeps/s390/bits/link.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2005-2016 Free Software Foundation, Inc.
+/* Copyright (C) 2005-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -19,6 +19,9 @@
# error "Never include <bits/link.h> directly; use <link.h> instead."
#endif
+#if defined HAVE_S390_VX_ASM_SUPPORT
+typedef char La_s390_vr[16];
+#endif
#if __ELF_NATIVE_CLASS == 32
@@ -32,6 +35,16 @@ typedef struct La_s390_32_regs
uint32_t lr_r6;
double lr_fp0;
double lr_fp2;
+# if defined HAVE_S390_VX_ASM_SUPPORT
+ La_s390_vr lr_v24;
+ La_s390_vr lr_v25;
+ La_s390_vr lr_v26;
+ La_s390_vr lr_v27;
+ La_s390_vr lr_v28;
+ La_s390_vr lr_v29;
+ La_s390_vr lr_v30;
+ La_s390_vr lr_v31;
+# endif
} La_s390_32_regs;
/* Return values for calls from PLT on s390-32. */
@@ -40,6 +53,9 @@ typedef struct La_s390_32_retval
uint32_t lrv_r2;
uint32_t lrv_r3;
double lrv_fp0;
+# if defined HAVE_S390_VX_ASM_SUPPORT
+ La_s390_vr lrv_v24;
+# endif
} La_s390_32_retval;
@@ -77,6 +93,16 @@ typedef struct La_s390_64_regs
double lr_fp2;
double lr_fp4;
double lr_fp6;
+# if defined HAVE_S390_VX_ASM_SUPPORT
+ La_s390_vr lr_v24;
+ La_s390_vr lr_v25;
+ La_s390_vr lr_v26;
+ La_s390_vr lr_v27;
+ La_s390_vr lr_v28;
+ La_s390_vr lr_v29;
+ La_s390_vr lr_v30;
+ La_s390_vr lr_v31;
+# endif
} La_s390_64_regs;
/* Return values for calls from PLT on s390-64. */
@@ -84,6 +110,9 @@ typedef struct La_s390_64_retval
{
uint64_t lrv_r2;
double lrv_fp0;
+# if defined HAVE_S390_VX_ASM_SUPPORT
+ La_s390_vr lrv_v24;
+# endif
} La_s390_64_retval;
diff --git a/sysdeps/s390/bits/mathdef.h b/sysdeps/s390/bits/mathdef.h
deleted file mode 100644
index 8c47ade208..0000000000
--- a/sysdeps/s390/bits/mathdef.h
+++ /dev/null
@@ -1,36 +0,0 @@
-/* Copyright (C) 1997-2016 Free Software Foundation, Inc.
- This file is part of the GNU C Library.
-
- The GNU C 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.
-
- The GNU C Library 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, see
- <http://www.gnu.org/licenses/>. */
-
-#if !defined _MATH_H && !defined _COMPLEX_H
-# error "Never use <bits/mathdef.h> directly; include <math.h> instead"
-#endif
-
-#if defined __USE_ISOC99 && defined _MATH_H && !defined _MATH_H_MATHDEF
-# define _MATH_H_MATHDEF 1
-
-/* Normally, there is no long double type and the `float' and `double'
- expressions are evaluated as `double'. */
-typedef double float_t; /* `float' expressions are evaluated as
- `double'. */
-typedef double double_t; /* `double' expressions are evaluated as
- `double'. */
-
-/* The values returned by `ilogb' for 0 and NaN respectively. */
-# define FP_ILOGB0 (-2147483647)
-# define FP_ILOGBNAN 2147483647
-
-#endif /* ISO C99 */
diff --git a/sysdeps/s390/bits/setjmp.h b/sysdeps/s390/bits/setjmp.h
index 8d29e8dbd8..07229c292f 100644
--- a/sysdeps/s390/bits/setjmp.h
+++ b/sysdeps/s390/bits/setjmp.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000-2016 Free Software Foundation, Inc.
+/* Copyright (C) 2000-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
diff --git a/sysdeps/s390/bits/string.h b/sysdeps/s390/bits/string.h
deleted file mode 100644
index 39e0b7fe7c..0000000000
--- a/sysdeps/s390/bits/string.h
+++ /dev/null
@@ -1,252 +0,0 @@
-/* Optimized, inlined string functions. S/390 version.
- Copyright (C) 2000-2016 Free Software Foundation, Inc.
- Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com).
- This file is part of the GNU C Library.
-
- The GNU C 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.
-
- The GNU C Library 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, see
- <http://www.gnu.org/licenses/>. */
-
-#ifndef _STRING_H
-# error "Never use <bits/string.h> directly; include <string.h> instead."
-#endif
-
-/* Use the unaligned string inline ABI. */
-#define _STRING_INLINE_unaligned 1
-
-/* We only provide optimizations if the user selects them and if
- GNU CC is used. */
-#if !defined __NO_STRING_INLINES && defined __USE_STRING_INLINES \
- && defined __GNUC__ && __GNUC__ >= 2
-
-#ifndef __STRING_INLINE
-# ifndef __extern_inline
-# define __STRING_INLINE inline
-# else
-# define __STRING_INLINE __extern_inline
-# endif
-#endif
-
-#define _HAVE_STRING_ARCH_strlen 1
-#ifndef _FORCE_INLINES
-#define strlen(str) __strlen_g ((str))
-
-__STRING_INLINE size_t __strlen_g (const char *) __asm__ ("strlen");
-
-__STRING_INLINE size_t
-__strlen_g (const char *__str)
-{
- char *__ptr, *__tmp;
-
- __ptr = (char *) 0;
- __tmp = (char *) __str;
- __asm__ __volatile__ (" la 0,0\n"
- "0: srst %0,%1\n"
- " jo 0b\n"
- : "+&a" (__ptr), "+&a" (__tmp) :
- : "cc", "memory", "0" );
- return (size_t) (__ptr - __str);
-}
-#endif
-
-/* Copy SRC to DEST. */
-#define _HAVE_STRING_ARCH_strcpy 1
-#ifndef _FORCE_INLINES
-#define strcpy(dest, src) __strcpy_g ((dest), (src))
-
-__STRING_INLINE char *__strcpy_g (char *, const char *) __asm__ ("strcpy");
-
-__STRING_INLINE char *
-__strcpy_g (char *__dest, const char *__src)
-{
- char *tmp = __dest;
-
- __asm__ __volatile__ (" la 0,0\n"
- "0: mvst %0,%1\n"
- " jo 0b"
- : "+&a" (__dest), "+&a" (__src) :
- : "cc", "memory", "0" );
- return tmp;
-}
-#endif
-
-#define _HAVE_STRING_ARCH_strncpy 1
-#ifndef _FORCE_INLINES
-#define strncpy(dest, src, n) __strncpy_g ((dest), (src), (n))
-
-__STRING_INLINE char *__strncpy_g (char *, const char *, size_t)
- __asm__ ("strncpy");
-
-__STRING_INLINE char *
-__strncpy_g (char *__dest, const char *__src, size_t __n)
-{
- char *__ret = __dest;
- char *__ptr;
- size_t __diff;
-
- if (__n > 0) {
- __diff = (size_t) (__dest - __src);
- __ptr = (char *) __src;
- __asm__ __volatile__ (" j 1f\n"
- "0: la %0,1(%0)\n"
- "1: icm 0,1,0(%0)\n"
- " stc 0,0(%2,%0)\n"
- " jz 3f\n"
-#if defined(__s390x__)
- " brctg %1,0b\n"
-#else
- " brct %1,0b\n"
-#endif
- " j 4f\n"
- "2: la %0,1(%0)\n"
- " stc 0,0(%2,%0)\n"
-#if defined(__s390x__)
- "3: brctg %1,2b\n"
-#else
- "3: brct %1,2b\n"
-#endif
- "4:"
- : "+&a" (__ptr), "+&a" (__n) : "a" (__diff)
- : "cc", "memory", "0" );
- }
- return __ret;
-}
-#endif
-
-/* Append SRC onto DEST. */
-#define _HAVE_STRING_ARCH_strcat 1
-#ifndef _FORCE_INLINES
-#define strcat(dest, src) __strcat_g ((dest), (src))
-
-__STRING_INLINE char *__strcat_g (char *, const char *) __asm__ ("strcat");
-
-__STRING_INLINE char *
-__strcat_g (char *__dest, const char *__src)
-{
- char *__ret = __dest;
- char *__ptr, *__tmp;
-
- /* Move __ptr to the end of __dest. */
- __ptr = (char *) 0;
- __tmp = __dest;
- __asm__ __volatile__ (" la 0,0\n"
- "0: srst %0,%1\n"
- " jo 0b\n"
- : "+&a" (__ptr), "+&a" (__tmp) :
- : "cc", "0" );
-
- /* Now do the copy. */
- __asm__ __volatile__ (" la 0,0\n"
- "0: mvst %0,%1\n"
- " jo 0b"
- : "+&a" (__ptr), "+&a" (__src) :
- : "cc", "memory", "0" );
- return __ret;
-}
-#endif
-
-/* Append no more than N characters from SRC onto DEST. */
-#define _HAVE_STRING_ARCH_strncat 1
-#ifndef _FORCE_INLINES
-#define strncat(dest, src, n) __strncat_g ((dest), (src), (n))
-
-__STRING_INLINE char *__strncat_g (char *, const char *, size_t)
- __asm__ ("strncat");
-
-__STRING_INLINE char *
-__strncat_g (char *__dest, const char *__src, size_t __n)
-{
- char *__ret = __dest;
- char *__ptr, *__tmp;
- size_t __diff;
-
- if (__n > 0) {
- /* Move __ptr to the end of __dest. */
- __ptr = (char *) 0;
- __tmp = __dest;
- __asm__ __volatile__ (" la 0,0\n"
- "0: srst %0,%1\n"
- " jo 0b\n"
- : "+&a" (__ptr), "+&a" (__tmp) :
- : "cc", "memory", "0" );
-
- __diff = (size_t) (__ptr - __src);
- __tmp = (char *) __src;
- __asm__ __volatile__ (" j 1f\n"
- "0: la %0,1(%0)\n"
- "1: icm 0,1,0(%0)\n"
- " stc 0,0(%2,%0)\n"
- " jz 2f\n"
-#if defined(__s390x__)
- " brctg %1,0b\n"
-#else
- " brct %1,0b\n"
-#endif
- " slr 0,0\n"
- " stc 0,1(%2,%0)\n"
- "2:"
- : "+&a" (__tmp), "+&a" (__n) : "a" (__diff)
- : "cc", "memory", "0" );
-
- }
- return __ret;
-}
-#endif
-
-/* Search N bytes of S for C. */
-#define _HAVE_STRING_ARCH_memchr 1
-#ifndef _FORCE_INLINES
-__STRING_INLINE void *
-memchr (const void *__str, int __c, size_t __n)
-{
- char *__ptr, *__tmp;
-
- __tmp = (char *) __str;
- __ptr = (char *) __tmp + __n;
- __asm__ __volatile__ (" lhi 0,0xff\n"
- " nr 0,%2\n"
- "0: srst %0,%1\n"
- " jo 0b\n"
- " brc 13,1f\n"
- " la %0,0\n"
- "1:"
- : "+&a" (__ptr), "+&a" (__tmp) : "d" (__c)
- : "cc", "memory", "0" );
- return __ptr;
-}
-#endif
-
-/* Compare S1 and S2. */
-#define _HAVE_STRING_ARCH_strcmp 1
-#ifndef _FORCE_INLINES
-__STRING_INLINE int
-strcmp (const char *__s1, const char *__s2)
-{
- char *__p1, *__p2;
- int __ret;
-
- __p1 = (char *) __s1;
- __p2 = (char *) __s2;
- __asm__ __volatile__ (" slr 0,0\n"
- "0: clst %1,%2\n"
- " jo 0b\n"
- " ipm %0\n"
- " srl %0,28"
- : "=d" (__ret), "+&a" (__p1), "+&a" (__p2) :
- : "cc", "memory", "0" );
- __ret = (__ret == 0) ? 0 : (__ret == 1) ? -1 : 1;
- return __ret;
-}
-#endif
-
-#endif /* Use string inlines && GNU CC. */
diff --git a/sysdeps/s390/bits/xtitypes.h b/sysdeps/s390/bits/xtitypes.h
index 3c9606a636..462b126d11 100644
--- a/sysdeps/s390/bits/xtitypes.h
+++ b/sysdeps/s390/bits/xtitypes.h
@@ -1,5 +1,5 @@
/* bits/xtitypes.h -- Define some types used by <bits/stropts.h>. S390/S390x
- Copyright (C) 2002-2016 Free Software Foundation, Inc.
+ Copyright (C) 2002-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
diff --git a/sysdeps/s390/configure b/sysdeps/s390/configure
index 0fa54c3061..74b415f2ab 100644
--- a/sysdeps/s390/configure
+++ b/sysdeps/s390/configure
@@ -4,71 +4,6 @@
$as_echo "#define PI_STATIC_AND_HIDDEN 1" >>confdefs.h
-for ac_prog in $AS
-do
- # Extract the first word of "$ac_prog", so it can be a program name with args.
-set dummy $ac_prog; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_prog_AS+:} false; then :
- $as_echo_n "(cached) " >&6
-else
- if test -n "$AS"; then
- ac_cv_prog_AS="$AS" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
- ac_cv_prog_AS="$ac_prog"
- $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
- done
-IFS=$as_save_IFS
-
-fi
-fi
-AS=$ac_cv_prog_AS
-if test -n "$AS"; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AS" >&5
-$as_echo "$AS" >&6; }
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
-
- test -n "$AS" && break
-done
-
-if test -z "$AS"; then
- ac_verc_fail=yes
-else
- # Found it, now check the version.
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking version of $AS" >&5
-$as_echo_n "checking version of $AS... " >&6; }
- ac_prog_version=`$AS --version 2>&1 | sed -n 's/^.*GNU assembler.* \([0-9]*\.[0-9.]*\).*$/\1/p'`
- case $ac_prog_version in
- '') ac_prog_version="v. ?.??, bad"; ac_verc_fail=yes;;
- 2.2[4-9]*|2.[3-9][0-9]*|[3-9].*|[1-9][0-9]*)
- ac_prog_version="$ac_prog_version, ok"; ac_verc_fail=no;;
- *) ac_prog_version="$ac_prog_version, bad"; ac_verc_fail=yes;;
-
- esac
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_prog_version" >&5
-$as_echo "$ac_prog_version" >&6; }
-fi
-if test $ac_verc_fail = yes; then
- critic_missing="$critic_missing The program AS is required in version >= 2.24 for target S390."
-fi
-
-
-
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for __builtin_tbegin" >&5
$as_echo_n "checking for __builtin_tbegin... " >&6; }
if ${libc_cv_gcc_builtin_tbegin+:} false; then :
@@ -100,7 +35,7 @@ fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libc_cv_gcc_builtin_tbegin" >&5
$as_echo "$libc_cv_gcc_builtin_tbegin" >&6; }
-if test "$enable_lock_elision" = yes && test "$libc_cv_gcc_builtin_tbegin" = no ; then
+if test "$libc_cv_gcc_builtin_tbegin" = no ; then
critic_missing="$critic_missing The used GCC has no support for __builtin_tbegin, which is needed for lock-elision on target S390."
fi
@@ -144,6 +79,74 @@ else
$as_echo "$as_me: WARNING: Use binutils with vector-support in order to use optimized implementations." >&2;}
fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for S390 vector support in gcc" >&5
+$as_echo_n "checking for S390 vector support in gcc... " >&6; }
+if ${libc_cv_gcc_s390_vx+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat > conftest.c <<\EOF
+void testvecclobber ()
+{
+ __asm__ ("" : : : "v16");
+}
+EOF
+if { ac_try='${CC-cc} --shared conftest.c -o conftest.o &> /dev/null'
+ { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; } ;
+then
+ libc_cv_gcc_s390_vx=yes
+else
+ libc_cv_gcc_s390_vx=no
+fi
+rm -f conftest*
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libc_cv_gcc_s390_vx" >&5
+$as_echo "$libc_cv_gcc_s390_vx" >&6; }
+
+if test "$libc_cv_gcc_s390_vx" = yes ;
+then
+ $as_echo "#define HAVE_S390_VX_GCC_SUPPORT 1" >>confdefs.h
+
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for S390 z196 zarch instruction support as default" >&5
+$as_echo_n "checking for S390 z196 zarch instruction support as default... " >&6; }
+if ${libc_cv_asm_s390_min_z196_zarch+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat > conftest.c <<\EOF
+float testinsn (double e)
+{
+ float d;
+ __asm__ ("ledbra %0,5,%1,4" : "=f" (d) : "f" (e) );
+ return d;
+}
+EOF
+if { ac_try='${CC-cc} $CFLAGS $CPPFLAGS $LDFLAGS --shared conftest.c
+ -o conftest.o &> /dev/null'
+ { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; } ;
+then
+ libc_cv_asm_s390_min_z196_zarch=yes
+else
+ libc_cv_asm_s390_min_z196_zarch=no
+fi
+rm -f conftest*
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libc_cv_asm_s390_min_z196_zarch" >&5
+$as_echo "$libc_cv_asm_s390_min_z196_zarch" >&6; }
+
+if test "$libc_cv_asm_s390_min_z196_zarch" = yes ;
+then
+ $as_echo "#define HAVE_S390_MIN_Z196_ZARCH_ASM_SUPPORT 1" >>confdefs.h
+
+fi
test -n "$critic_missing" && as_fn_error $? "
*** $critic_missing" "$LINENO" 5
diff --git a/sysdeps/s390/configure.ac b/sysdeps/s390/configure.ac
index 4da134e9a0..1cdb021282 100644
--- a/sysdeps/s390/configure.ac
+++ b/sysdeps/s390/configure.ac
@@ -5,12 +5,6 @@ dnl It is always possible to access static and hidden symbols in an
dnl position independent way.
AC_DEFINE(PI_STATIC_AND_HIDDEN)
-dnl Accept as 2.24 or newer.
-AC_CHECK_PROG_VER(AS, $AS, --version,
- [GNU assembler.* \([0-9]*\.[0-9.]*\)],
- [2.2[4-9]*|2.[3-9][0-9]*|[3-9].*|[1-9][0-9]*], critic_missing="$critic_missing The program AS is required in version >= 2.24 for target S390.")
-
-
AC_CACHE_CHECK(for __builtin_tbegin, libc_cv_gcc_builtin_tbegin, [dnl
cat > conftest.c <<\EOF
#include <htmintrin.h>
@@ -32,7 +26,7 @@ else
fi
rm -f conftest* ])
-if test "$enable_lock_elision" = yes && test "$libc_cv_gcc_builtin_tbegin" = no ; then
+if test "$libc_cv_gcc_builtin_tbegin" = no ; then
critic_missing="$critic_missing The used GCC has no support for __builtin_tbegin, which is needed for lock-elision on target S390."
fi
@@ -64,6 +58,53 @@ else
AC_MSG_WARN([Use binutils with vector-support in order to use optimized implementations.])
fi
+AC_CACHE_CHECK(for S390 vector support in gcc, libc_cv_gcc_s390_vx, [dnl
+cat > conftest.c <<\EOF
+void testvecclobber ()
+{
+ __asm__ ("" : : : "v16");
+}
+EOF
+dnl
+dnl test, if gcc supports S390 vector registers as clobber in inline assembly
+if AC_TRY_COMMAND([${CC-cc} --shared conftest.c -o conftest.o &> /dev/null]) ;
+then
+ libc_cv_gcc_s390_vx=yes
+else
+ libc_cv_gcc_s390_vx=no
+fi
+rm -f conftest* ])
+
+if test "$libc_cv_gcc_s390_vx" = yes ;
+then
+ AC_DEFINE(HAVE_S390_VX_GCC_SUPPORT)
+fi
+
+AC_CACHE_CHECK(for S390 z196 zarch instruction support as default,
+ libc_cv_asm_s390_min_z196_zarch, [dnl
+cat > conftest.c <<\EOF
+float testinsn (double e)
+{
+ float d;
+ __asm__ ("ledbra %0,5,%1,4" : "=f" (d) : "f" (e) );
+ return d;
+}
+EOF
+dnl
+dnl test, if assembler supports S390 z196 zarch instructions as default
+if AC_TRY_COMMAND([${CC-cc} $CFLAGS $CPPFLAGS $LDFLAGS --shared conftest.c
+ -o conftest.o &> /dev/null]) ;
+then
+ libc_cv_asm_s390_min_z196_zarch=yes
+else
+ libc_cv_asm_s390_min_z196_zarch=no
+fi
+rm -f conftest* ])
+
+if test "$libc_cv_asm_s390_min_z196_zarch" = yes ;
+then
+ AC_DEFINE(HAVE_S390_MIN_Z196_ZARCH_ASM_SUPPORT)
+fi
test -n "$critic_missing" && AC_MSG_ERROR([
*** $critic_missing])
diff --git a/sysdeps/s390/dl-irel.h b/sysdeps/s390/dl-irel.h
index 38c5761a6e..d8ba7ba427 100644
--- a/sysdeps/s390/dl-irel.h
+++ b/sysdeps/s390/dl-irel.h
@@ -1,6 +1,6 @@
/* Machine-dependent ELF indirect relocation inline functions.
Version for S/390 32 and 64 bit.
- Copyright (C) 2012-2016 Free Software Foundation, Inc.
+ Copyright (C) 2012-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
diff --git a/sysdeps/s390/dl-procinfo.c b/sysdeps/s390/dl-procinfo.c
index 22c4cf7a01..86c964caff 100644
--- a/sysdeps/s390/dl-procinfo.c
+++ b/sysdeps/s390/dl-procinfo.c
@@ -1,5 +1,5 @@
/* Data for s390 version of processor capability information.
- Copyright (C) 2006-2016 Free Software Foundation, Inc.
+ Copyright (C) 2006-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Martin Schwidefsky <schwidefsky@de.ibm.com>, 2006.
@@ -46,11 +46,12 @@
#if !defined PROCINFO_DECL && defined SHARED
._dl_s390_cap_flags
#else
-PROCINFO_CLASS const char _dl_s390_cap_flags[12][9]
+PROCINFO_CLASS const char _dl_s390_cap_flags[15][9]
#endif
#ifndef PROCINFO_DECL
= {
- "esan3", "zarch", "stfle", "msa", "ldisp", "eimm", "dfp", "edat", "etf3eh", "highgprs", "te", "vx"
+ "esan3", "zarch", "stfle", "msa", "ldisp", "eimm", "dfp", "edat", "etf3eh",
+ "highgprs", "te", "vx", "vxd", "vxe", "gs"
}
#endif
#if !defined SHARED || defined PROCINFO_DECL
@@ -62,11 +63,11 @@ PROCINFO_CLASS const char _dl_s390_cap_flags[12][9]
#if !defined PROCINFO_DECL && defined SHARED
._dl_s390_platforms
#else
-PROCINFO_CLASS const char _dl_s390_platforms[8][7]
+PROCINFO_CLASS const char _dl_s390_platforms[9][7]
#endif
#ifndef PROCINFO_DECL
= {
- "g5", "z900", "z990", "z9-109", "z10", "z196", "zEC12", "z13"
+ "g5", "z900", "z990", "z9-109", "z10", "z196", "zEC12", "z13", "z14"
}
#endif
#if !defined SHARED || defined PROCINFO_DECL
diff --git a/sysdeps/s390/dl-procinfo.h b/sysdeps/s390/dl-procinfo.h
index 4ae276e4ed..b0383bfb4c 100644
--- a/sysdeps/s390/dl-procinfo.h
+++ b/sysdeps/s390/dl-procinfo.h
@@ -1,5 +1,5 @@
/* s390 version of processor capability information handling macros.
- Copyright (C) 2006-2016 Free Software Foundation, Inc.
+ Copyright (C) 2006-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Martin Schwidefsky <schwidefsky@de.ibm.com>, 2006.
@@ -21,9 +21,9 @@
#define _DL_PROCINFO_H 1
#include <ldsodefs.h>
-#define _DL_HWCAP_COUNT 12
+#define _DL_HWCAP_COUNT 15
-#define _DL_PLATFORMS_COUNT 8
+#define _DL_PLATFORMS_COUNT 9
/* The kernel provides up to 32 capability bits with elf_hwcap. */
#define _DL_FIRST_PLATFORM 32
@@ -51,6 +51,9 @@ enum
HWCAP_S390_HIGH_GPRS = 1 << 9,
HWCAP_S390_TE = 1 << 10,
HWCAP_S390_VX = 1 << 11,
+ HWCAP_S390_VXD = 1 << 12,
+ HWCAP_S390_VXE = 1 << 13,
+ HWCAP_S390_GS = 1 << 14,
};
#define HWCAP_IMPORTANT (HWCAP_S390_ZARCH | HWCAP_S390_LDISP \
@@ -66,13 +69,6 @@ _dl_hwcap_string (int idx)
return GLRO(dl_s390_cap_flags)[idx];
};
-static inline const char *
-__attribute__ ((unused))
-_dl_platform_string (int idx)
-{
- return GLRO(dl_s390_platforms)[idx - _DL_FIRST_PLATFORM];
-};
-
static inline int
__attribute__ ((unused, always_inline))
_dl_string_hwcap (const char *str)
diff --git a/sysdeps/s390/dl-tls.h b/sysdeps/s390/dl-tls.h
index 503048a622..7a843f29ad 100644
--- a/sysdeps/s390/dl-tls.h
+++ b/sysdeps/s390/dl-tls.h
@@ -1,5 +1,5 @@
/* Thread-local storage handling in the ELF dynamic linker. s390 version.
- Copyright (C) 2003-2016 Free Software Foundation, Inc.
+ Copyright (C) 2003-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -102,6 +102,3 @@ extern void *__tls_get_addr_internal (tls_index *ti);
+ (unsigned long) __builtin_thread_pointer (); })
#endif
-
-/* Value used for dtv entries for which the allocation is delayed. */
-#define TLS_DTV_UNALLOCATED ((void *) -1l)
diff --git a/sysdeps/s390/ffs.c b/sysdeps/s390/ffs.c
index 7808185569..d46eec8e48 100644
--- a/sysdeps/s390/ffs.c
+++ b/sysdeps/s390/ffs.c
@@ -1,6 +1,6 @@
/* ffs -- find first set bit in a word, counted from least significant end.
S/390 version.
- Copyright (C) 2000-2016 Free Software Foundation, Inc.
+ Copyright (C) 2000-2018 Free Software Foundation, Inc.
Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com).
This file is part of the GNU C Library.
diff --git a/sysdeps/s390/fix-fp-int-convert-overflow.h b/sysdeps/s390/fix-fp-int-convert-overflow.h
index 61279edc19..b60d4c54ac 100644
--- a/sysdeps/s390/fix-fp-int-convert-overflow.h
+++ b/sysdeps/s390/fix-fp-int-convert-overflow.h
@@ -1,5 +1,5 @@
/* Fix for conversion of floating point to integer overflow. S390 version.
- Copyright (C) 2016 Free Software Foundation, Inc.
+ Copyright (C) 2016-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
diff --git a/sysdeps/s390/fpu/bits/fenv.h b/sysdeps/s390/fpu/bits/fenv.h
index 6de74b9939..079e71f3a5 100644
--- a/sysdeps/s390/fpu/bits/fenv.h
+++ b/sysdeps/s390/fpu/bits/fenv.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000-2016 Free Software Foundation, Inc.
+/* Copyright (C) 2000-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Denis Joseph Barrow <djbarrow@de.ibm.com>.
@@ -90,3 +90,11 @@ typedef struct
/* Floating-point environment where none of the exceptions are masked. */
# define FE_NOMASK_ENV ((const fenv_t *) -2)
#endif
+
+#if __GLIBC_USE (IEC_60559_BFP_EXT)
+/* Type representing floating-point control modes. */
+typedef unsigned int femode_t;
+
+/* Default floating-point control modes. */
+# define FE_DFL_MODE ((const femode_t *) -1L)
+#endif
diff --git a/sysdeps/s390/fpu/bits/mathinline.h b/sysdeps/s390/fpu/bits/mathinline.h
deleted file mode 100644
index 7c09a5c7da..0000000000
--- a/sysdeps/s390/fpu/bits/mathinline.h
+++ /dev/null
@@ -1,100 +0,0 @@
-/* Inline math functions for s390.
- Copyright (C) 2004-2016 Free Software Foundation, Inc.
- This file is part of the GNU C Library.
-
- The GNU C 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.
-
- The GNU C Library 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, see
- <http://www.gnu.org/licenses/>. */
-
-#ifndef _MATH_H
-# error "Never use <bits/mathinline.h> directly; include <math.h> instead."
-#endif
-
-#ifndef __extern_inline
-# define __MATH_INLINE __inline
-#else
-# define __MATH_INLINE __extern_inline
-#endif
-
-#if (!defined __NO_MATH_INLINES || defined __LIBC_INTERNAL_MATH_INLINES) \
- && defined __OPTIMIZE__
-
-#ifdef __USE_ISOC99
-
-/* Test for negative number. Used in the signbit() macro. */
-__MATH_INLINE int
-__NTH (__signbitf (float __x))
-{
- __extension__ union { float __f; int __i; } __u = { __f: __x };
- return __u.__i < 0;
-}
-
-__MATH_INLINE int
-__NTH (__signbit (double __x))
-{
- __extension__ union { double __d; long __i; } __u = { __d: __x };
- return __u.__i < 0;
-}
-
-# ifndef __NO_LONG_DOUBLE_MATH
-__MATH_INLINE int
-__NTH (__signbitl (long double __x))
-{
- __extension__ union { long double __l; int __i[4]; } __u = { __l: __x };
- return __u.__i[0] < 0;
-}
-# else
-__MATH_INLINE int
-__NTH (__signbitl (long double __x))
-{
- return __signbit ((double) __x);
-}
-# endif
-
-#endif /* C99 */
-
-/* This code is used internally in the GNU libc. */
-#ifdef __LIBC_INTERNAL_MATH_INLINES
-
-__MATH_INLINE double
-__NTH (__ieee754_sqrt (double x))
-{
- double res;
-
- __asm__ ( "sqdbr %0,%1" : "=f" (res) : "f" (x) );
- return res;
-}
-
-__MATH_INLINE float
-__NTH (__ieee754_sqrtf (float x))
-{
- float res;
-
- __asm__ ( "sqebr %0,%1" : "=f" (res) : "f" (x) );
- return res;
-}
-
-# if !defined __NO_LONG_DOUBLE_MATH
-__MATH_INLINE long double
-__NTH (sqrtl (long double __x))
-{
- long double res;
-
- __asm__ ( "sqxbr %0,%1" : "=f" (res) : "f" (__x) );
- return res;
-}
-# endif /* !__NO_LONG_DOUBLE_MATH */
-
-#endif /* __LIBC_INTERNAL_MATH_INLINES */
-
-#endif /* __NO_MATH_INLINES */
diff --git a/sysdeps/s390/fpu/e_sqrt.c b/sysdeps/s390/fpu/e_sqrt.c
index efdb2865b9..b8b362a6bb 100644
--- a/sysdeps/s390/fpu/e_sqrt.c
+++ b/sysdeps/s390/fpu/e_sqrt.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2004-2016 Free Software Foundation, Inc.
+/* Copyright (C) 2004-2018 Free Software Foundation, Inc.
Contributed by Martin Schwidefsky <schwidefsky@de.ibm.com>.
This file is part of the GNU C Library.
diff --git a/sysdeps/s390/fpu/e_sqrtf.c b/sysdeps/s390/fpu/e_sqrtf.c
index 38160acc12..2c67e3e656 100644
--- a/sysdeps/s390/fpu/e_sqrtf.c
+++ b/sysdeps/s390/fpu/e_sqrtf.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2004-2016 Free Software Foundation, Inc.
+/* Copyright (C) 2004-2018 Free Software Foundation, Inc.
Contributed by Martin Schwidefsky <schwidefsky@de.ibm.com>.
This file is part of the GNU C Library.
diff --git a/sysdeps/s390/fpu/e_sqrtl.c b/sysdeps/s390/fpu/e_sqrtl.c
index add859a3a8..209242b516 100644
--- a/sysdeps/s390/fpu/e_sqrtl.c
+++ b/sysdeps/s390/fpu/e_sqrtl.c
@@ -1,5 +1,5 @@
/* Square root. S/390 FPU version.
- Copyright (C) 2004-2016 Free Software Foundation, Inc.
+ Copyright (C) 2004-2018 Free Software Foundation, Inc.
Contributed by Martin Schwidefsky <schwidefsky@de.ibm.com>.
This file is part of the GNU C Library.
diff --git a/sysdeps/s390/fpu/fclrexcpt.c b/sysdeps/s390/fpu/fclrexcpt.c
index b19899a2eb..27b7255a79 100644
--- a/sysdeps/s390/fpu/fclrexcpt.c
+++ b/sysdeps/s390/fpu/fclrexcpt.c
@@ -1,5 +1,5 @@
/* Clear given exceptions in current floating-point environment.
- Copyright (C) 2000-2016 Free Software Foundation, Inc.
+ Copyright (C) 2000-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
diff --git a/sysdeps/s390/fpu/fedisblxcpt.c b/sysdeps/s390/fpu/fedisblxcpt.c
index d3b49789b9..fc0ac27cc3 100644
--- a/sysdeps/s390/fpu/fedisblxcpt.c
+++ b/sysdeps/s390/fpu/fedisblxcpt.c
@@ -1,5 +1,5 @@
/* Disable floating-point exceptions.
- Copyright (C) 2000-2016 Free Software Foundation, Inc.
+ Copyright (C) 2000-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Denis Joseph Barrow (djbarrow@de.ibm.com).
diff --git a/sysdeps/s390/fpu/feenablxcpt.c b/sysdeps/s390/fpu/feenablxcpt.c
index b9aab5976a..067d8e9fa3 100644
--- a/sysdeps/s390/fpu/feenablxcpt.c
+++ b/sysdeps/s390/fpu/feenablxcpt.c
@@ -1,5 +1,5 @@
/* Enable floating-point exceptions.
- Copyright (C) 2000-2016 Free Software Foundation, Inc.
+ Copyright (C) 2000-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Denis Joseph Barrow (djbarrow@de.ibm.com).
diff --git a/sysdeps/s390/fpu/fegetenv.c b/sysdeps/s390/fpu/fegetenv.c
index 3b912b66cf..709fbd9c19 100644
--- a/sysdeps/s390/fpu/fegetenv.c
+++ b/sysdeps/s390/fpu/fegetenv.c
@@ -1,5 +1,5 @@
/* Store current floating-point environment.
- Copyright (C) 2000-2016 Free Software Foundation, Inc.
+ Copyright (C) 2000-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Denis Joseph Barrow (djbarrow@de.ibm.com).
diff --git a/sysdeps/s390/fpu/fegetexcept.c b/sysdeps/s390/fpu/fegetexcept.c
index dc5033c550..0fd39f14e4 100644
--- a/sysdeps/s390/fpu/fegetexcept.c
+++ b/sysdeps/s390/fpu/fegetexcept.c
@@ -1,5 +1,5 @@
/* Get enabled floating-point exceptions.
- Copyright (C) 2000-2016 Free Software Foundation, Inc.
+ Copyright (C) 2000-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Denis Joseph Barrow (djbarrow@de.ibm.com).
diff --git a/sysdeps/s390/nptl/pthread_spin_trylock.c b/sysdeps/s390/fpu/fegetmode.c
index 4c00e0833f..d6a5feff3d 100644
--- a/sysdeps/s390/nptl/pthread_spin_trylock.c
+++ b/sysdeps/s390/fpu/fegetmode.c
@@ -1,6 +1,6 @@
-/* Copyright (C) 2003-2016 Free Software Foundation, Inc.
+/* Store current floating-point control modes. S/390 version.
+ Copyright (C) 2016-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
- Contributed by Martin Schwidefsky <schwidefsky@de.ibm.com>, 2003.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -16,17 +16,12 @@
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
-#include <errno.h>
-#include "pthreadP.h"
+#include <fenv.h>
+#include <fpu_control.h>
int
-pthread_spin_trylock (pthread_spinlock_t *lock)
+fegetmode (femode_t *modep)
{
- int old;
-
- __asm__ __volatile__ ("cs %0,%3,%1"
- : "=d" (old), "=Q" (*lock)
- : "0" (0), "d" (1), "m" (*lock) : "cc" );
-
- return old != 0 ? EBUSY : 0;
+ _FPU_GETCW (*modep);
+ return 0;
}
diff --git a/sysdeps/s390/fpu/fegetround.c b/sysdeps/s390/fpu/fegetround.c
index bca8517577..3c38bc9189 100644
--- a/sysdeps/s390/fpu/fegetround.c
+++ b/sysdeps/s390/fpu/fegetround.c
@@ -1,5 +1,5 @@
/* Return current rounding direction.
- Copyright (C) 2000-2016 Free Software Foundation, Inc.
+ Copyright (C) 2000-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Denis Joseph Barrow (djbarrow@de.ibm.com).
diff --git a/sysdeps/s390/fpu/feholdexcpt.c b/sysdeps/s390/fpu/feholdexcpt.c
index 2700028016..5daee5675d 100644
--- a/sysdeps/s390/fpu/feholdexcpt.c
+++ b/sysdeps/s390/fpu/feholdexcpt.c
@@ -1,5 +1,5 @@
/* Store current floating-point environment and clear exceptions.
- Copyright (C) 2000-2016 Free Software Foundation, Inc.
+ Copyright (C) 2000-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Denis Joseph Barrow (djbarrow@de.ibm.com).
@@ -24,7 +24,7 @@ int __feholdexcept (fenv_t *envp)
{
fexcept_t fpc;
/* Store the environment. */
- fegetenv (envp);
+ __fegetenv (envp);
/* Clear the current sticky bits as more than one exception
may be generated. */
fpc = envp->__fpc & ~(FPC_FLAGS_MASK | FPC_DXC_MASK);
diff --git a/sysdeps/s390/fpu/fenv_libc.h b/sysdeps/s390/fpu/fenv_libc.h
index dff8fd92e5..0b4b7aad99 100644
--- a/sysdeps/s390/fpu/fenv_libc.h
+++ b/sysdeps/s390/fpu/fenv_libc.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000-2016 Free Software Foundation, Inc.
+/* Copyright (C) 2000-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Denis Joseph Barrow (djbarrow@de.ibm.com).
diff --git a/sysdeps/s390/fpu/fesetenv.c b/sysdeps/s390/fpu/fesetenv.c
index 694a538c1e..c6c275d79d 100644
--- a/sysdeps/s390/fpu/fesetenv.c
+++ b/sysdeps/s390/fpu/fesetenv.c
@@ -1,5 +1,5 @@
/* Install given floating-point environment.
- Copyright (C) 2000-2016 Free Software Foundation, Inc.
+ Copyright (C) 2000-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Denis Joseph Barrow (djbarrow@de.ibm.com).
@@ -20,8 +20,6 @@
#include <fenv_libc.h>
#include <fpu_control.h>
#include <stddef.h>
-#include <asm/ptrace.h>
-#include <sys/ptrace.h>
#include <unistd.h>
int
diff --git a/sysdeps/s390/nptl/pthread_spin_lock.c b/sysdeps/s390/fpu/fesetexcept.c
index def6a24275..e41853e25e 100644
--- a/sysdeps/s390/nptl/pthread_spin_lock.c
+++ b/sysdeps/s390/fpu/fesetexcept.c
@@ -1,6 +1,6 @@
-/* Copyright (C) 2003-2016 Free Software Foundation, Inc.
+/* Set given exception flags. S/390 version.
+ Copyright (C) 2016-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
- Contributed by Martin Schwidefsky <schwidefsky@de.ibm.com>, 2003.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -16,17 +16,18 @@
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
-#include "pthreadP.h"
+#include <fenv.h>
+#include <fpu_control.h>
+#include <fenv_libc.h>
int
-pthread_spin_lock (pthread_spinlock_t *lock)
+fesetexcept (int excepts)
{
- int oldval;
+ fexcept_t temp;
+
+ _FPU_GETCW (temp);
+ temp |= (excepts & FE_ALL_EXCEPT) << FPC_FLAGS_SHIFT;
+ _FPU_SETCW (temp);
- __asm__ __volatile__ ("0: lhi %0,0\n"
- " cs %0,%2,%1\n"
- " jl 0b"
- : "=&d" (oldval), "=Q" (*lock)
- : "d" (1), "m" (*lock) : "cc" );
return 0;
}
diff --git a/sysdeps/s390/nptl/pthread_spin_unlock.c b/sysdeps/s390/fpu/fesetmode.c
index 0dcc2d0cb5..37ede8f115 100644
--- a/sysdeps/s390/nptl/pthread_spin_unlock.c
+++ b/sysdeps/s390/fpu/fesetmode.c
@@ -1,6 +1,6 @@
-/* Copyright (C) 2003-2016 Free Software Foundation, Inc.
+/* Install given floating-point control modes. S/390 version.
+ Copyright (C) 2016-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
- Contributed by Martin Schwidefsky <schwidefsky@de.ibm.com>, 2003.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -16,17 +16,24 @@
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
-/* Ugly hack to avoid the declaration of pthread_spin_init. */
-#define pthread_spin_init pthread_spin_init_XXX
-#include "pthreadP.h"
-#undef pthread_spin_init
+#include <fenv.h>
+#include <fpu_control.h>
+#include <fenv_libc.h>
+
+#define FPC_STATUS (FPC_FLAGS_MASK | FPC_DXC_MASK)
int
-pthread_spin_unlock (pthread_spinlock_t *lock)
+fesetmode (const femode_t *modep)
{
- __asm__ __volatile__ (" xc %O0(4,%R0),%0\n"
- " bcr 15,0"
- : "=Q" (*lock) : "m" (*lock) : "cc" );
+ fpu_control_t fpc;
+
+ _FPU_GETCW (fpc);
+ fpc &= FPC_STATUS;
+ if (modep == FE_DFL_MODE)
+ fpc |= _FPU_DEFAULT;
+ else
+ fpc |= *modep & ~FPC_STATUS;
+ _FPU_SETCW (fpc);
+
return 0;
}
-strong_alias (pthread_spin_unlock, pthread_spin_init)
diff --git a/sysdeps/s390/fpu/fesetround.c b/sysdeps/s390/fpu/fesetround.c
index 5b15a1973d..d8a84d2c96 100644
--- a/sysdeps/s390/fpu/fesetround.c
+++ b/sysdeps/s390/fpu/fesetround.c
@@ -1,5 +1,5 @@
/* Set current rounding direction.
- Copyright (C) 2000-2016 Free Software Foundation, Inc.
+ Copyright (C) 2000-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Denis Joseph Barrow (djbarrow@de.ibm.com).
diff --git a/sysdeps/s390/fpu/fetestexceptflag.c b/sysdeps/s390/fpu/fetestexceptflag.c
new file mode 100644
index 0000000000..784d356f7b
--- /dev/null
+++ b/sysdeps/s390/fpu/fetestexceptflag.c
@@ -0,0 +1,31 @@
+/* Test exception in saved exception state. S/390 version.
+ Copyright (C) 2016-2018 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C 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.
+
+ The GNU C Library 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, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <fenv.h>
+#include <fenv_libc.h>
+
+int
+fetestexceptflag (const fexcept_t *flagp, int excepts)
+{
+ /* As *flagp is obtained by an earlier call of fegetexceptflag the
+ bits 0-5 of dxc-byte are either zero or correspond to the
+ flag-bits. Evaluate flags and last dxc-exception-code. */
+ return (((*flagp >> FPC_FLAGS_SHIFT) | (*flagp >> FPC_DXC_SHIFT))
+ & excepts
+ & FE_ALL_EXCEPT);
+}
diff --git a/sysdeps/s390/fpu/feupdateenv.c b/sysdeps/s390/fpu/feupdateenv.c
index 1aad35ec13..4888e1a864 100644
--- a/sysdeps/s390/fpu/feupdateenv.c
+++ b/sysdeps/s390/fpu/feupdateenv.c
@@ -1,5 +1,5 @@
/* Install given floating-point environment and raise exceptions.
- Copyright (C) 2000-2016 Free Software Foundation, Inc.
+ Copyright (C) 2000-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Denis Joseph Barrow (djbarrow@de.ibm.com).
diff --git a/sysdeps/s390/fpu/fgetexcptflg.c b/sysdeps/s390/fpu/fgetexcptflg.c
index 09b7cfd99c..2a0f6dc77c 100644
--- a/sysdeps/s390/fpu/fgetexcptflg.c
+++ b/sysdeps/s390/fpu/fgetexcptflg.c
@@ -1,5 +1,5 @@
/* Store current representation for exceptions.
- Copyright (C) 2000-2016 Free Software Foundation, Inc.
+ Copyright (C) 2000-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Denis Joseph Barrow (djbarrow@de.ibm.com).
diff --git a/sysdeps/s390/fpu/fix-fp-int-compare-invalid.h b/sysdeps/s390/fpu/fix-fp-int-compare-invalid.h
new file mode 100644
index 0000000000..2ad36817c7
--- /dev/null
+++ b/sysdeps/s390/fpu/fix-fp-int-compare-invalid.h
@@ -0,0 +1,36 @@
+/* Fix for missing "invalid" exceptions from floating-point
+ comparisons. s390 version.
+ Copyright (C) 2016-2018 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C 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.
+
+ The GNU C Library 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, see
+ <http://www.gnu.org/licenses/>. */
+
+#ifndef FIX_FP_INT_COMPARE_INVALID_H
+#define FIX_FP_INT_COMPARE_INVALID_H 1
+
+/* GCC uses unordered comparison instructions like cebr (Short BFP COMPARE)
+ when it should use ordered comparison instructions like kebr
+ (Short BFP COMPARE AND SIGNAL) in order to raise invalid exceptions if
+ any operand is quiet (or signaling) NAN. See gcc bugzilla:
+ <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77918>.
+ There exists an equivalent gcc bugzilla for Intel:
+ <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=52451>.
+ Once the s390 gcc bug is fixed, the definition of FIX_COMPARE_INVALID
+ should have a __GNUC_PREREQ conditional added so that e.g. the workaround
+ to call feraiseexcept (FE_INVALID) in math/s_iseqsig_template.c can be
+ avoided. */
+#define FIX_COMPARE_INVALID 1
+
+#endif /* fix-fp-int-compare-invalid.h */
diff --git a/sysdeps/s390/fpu/fpu_control.h b/sysdeps/s390/fpu/fpu_control.h
index e0266a703e..cb8bca2c56 100644
--- a/sysdeps/s390/fpu/fpu_control.h
+++ b/sysdeps/s390/fpu/fpu_control.h
@@ -1,5 +1,5 @@
/* FPU control word definitions. Stub version.
- Copyright (C) 2000-2016 Free Software Foundation, Inc.
+ Copyright (C) 2000-2018 Free Software Foundation, Inc.
Contributed by Denis Joseph Barrow (djbarrow@de.ibm.com) and
Martin Schwidefsky (schwidefsky@de.ibm.com).
This file is part of the GNU C Library.
diff --git a/sysdeps/s390/fpu/fraiseexcpt.c b/sysdeps/s390/fpu/fraiseexcpt.c
index 92a1a7db68..c1edf7a732 100644
--- a/sysdeps/s390/fpu/fraiseexcpt.c
+++ b/sysdeps/s390/fpu/fraiseexcpt.c
@@ -1,5 +1,5 @@
/* Raise given exceptions.
- Copyright (C) 2000-2016 Free Software Foundation, Inc.
+ Copyright (C) 2000-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Denis Joseph Barrow (djbarrow@de.ibm.com) and
Martin Schwidefsky (schwidefsky@de.ibm.com).
@@ -35,6 +35,23 @@ fexceptadd (float d, float e)
__asm__ __volatile__ ("aebr %0,%1" : : "f" (d), "f" (e) );
}
+#ifdef HAVE_S390_MIN_Z196_ZARCH_ASM_SUPPORT
+static __inline__ void
+fexceptround (double e)
+{
+ float d;
+ /* Load rounded from double to float with M3 = round toward 0, M4 = Suppress
+ IEEE-inexact exception.
+ In case of e=0x1p128 and the overflow-mask bit is zero, only the
+ IEEE-overflow flag is set. If overflow-mask bit is one, DXC field is set to
+ 0x20 "IEEE overflow, exact".
+ In case of e=0x1p-150 and the underflow-mask bit is zero, only the
+ IEEE-underflow flag is set. If underflow-mask bit is one, DXC field is set
+ to 0x10 "IEEE underflow, exact".
+ This instruction is available with a zarch machine >= z196. */
+ __asm__ __volatile__ ("ledbra %0,5,%1,4" : "=f" (d) : "f" (e) );
+}
+#endif
int
__feraiseexcept (int excepts)
@@ -54,13 +71,29 @@ __feraiseexcept (int excepts)
/* Next: overflow. */
if (FE_OVERFLOW & excepts)
- /* I don't think we can do the same trick as intel so we will have
- to live with inexact coming also. */
- fexceptadd (FLT_MAX, 1.0e32);
+ {
+#ifdef HAVE_S390_MIN_Z196_ZARCH_ASM_SUPPORT
+ fexceptround (0x1p128);
+#else
+ /* If overflow-mask bit is zero, both IEEE-overflow and IEEE-inexact flags
+ are set. If overflow-mask bit is one, DXC field is set to 0x2C "IEEE
+ overflow, inexact and incremented". */
+ fexceptadd (FLT_MAX, 1.0e32);
+#endif
+ }
/* Next: underflow. */
if (FE_UNDERFLOW & excepts)
- fexceptdiv (FLT_MIN, 3.0);
+ {
+#ifdef HAVE_S390_MIN_Z196_ZARCH_ASM_SUPPORT
+ fexceptround (0x1p-150);
+#else
+ /* If underflow-mask bit is zero, both IEEE-underflow and IEEE-inexact
+ flags are set. If underflow-mask bit is one, DXC field is set to 0x1C
+ "IEEE underflow, inexact and incremented". */
+ fexceptdiv (FLT_MIN, 3.0);
+#endif
+ }
/* Last: inexact. */
if (FE_INEXACT & excepts)
diff --git a/sysdeps/s390/fpu/fsetexcptflg.c b/sysdeps/s390/fpu/fsetexcptflg.c
index 25ade854bd..e50684c574 100644
--- a/sysdeps/s390/fpu/fsetexcptflg.c
+++ b/sysdeps/s390/fpu/fsetexcptflg.c
@@ -1,5 +1,5 @@
/* Set floating-point environment exception handling.
- Copyright (C) 2000-2016 Free Software Foundation, Inc.
+ Copyright (C) 2000-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Denis Joseph Barrow (djbarrow@de.ibm.com).
@@ -45,8 +45,7 @@ fesetexceptflag (const fexcept_t *flagp, int excepts)
& newexcepts;
/* Store the new status word (along with the rest of the environment.
- Possibly new exceptions are set but they won't get executed unless
- the next floating-point instruction. */
+ Possibly new exceptions are set but they won't get executed. */
_FPU_SETCW (temp);
/* Success. */
diff --git a/sysdeps/s390/fpu/ftestexcept.c b/sysdeps/s390/fpu/ftestexcept.c
index 45cfcb52d0..727b9b342d 100644
--- a/sysdeps/s390/fpu/ftestexcept.c
+++ b/sysdeps/s390/fpu/ftestexcept.c
@@ -1,5 +1,5 @@
/* Test exception in current environment.
- Copyright (C) 2000-2016 Free Software Foundation, Inc.
+ Copyright (C) 2000-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Denis Joseph Barrow (djbarrow@de.ibm.com).
diff --git a/sysdeps/s390/fpu/get-rounding-mode.h b/sysdeps/s390/fpu/get-rounding-mode.h
index 5150b0ab25..ae40791af6 100644
--- a/sysdeps/s390/fpu/get-rounding-mode.h
+++ b/sysdeps/s390/fpu/get-rounding-mode.h
@@ -1,5 +1,5 @@
/* Determine floating-point rounding mode within libc. S/390 version.
- Copyright (C) 2012-2016 Free Software Foundation, Inc.
+ Copyright (C) 2012-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
diff --git a/sysdeps/s390/fpu/libm-test-ulps b/sysdeps/s390/fpu/libm-test-ulps
index bc5795b361..fec59c7d60 100644
--- a/sysdeps/s390/fpu/libm-test-ulps
+++ b/sysdeps/s390/fpu/libm-test-ulps
@@ -40,9 +40,9 @@ ildouble: 2
ldouble: 2
Function: "acosh_downward":
-double: 1
+double: 2
float: 2
-idouble: 1
+idouble: 2
ifloat: 2
ildouble: 3
ldouble: 3
@@ -126,9 +126,7 @@ ildouble: 4
ldouble: 4
Function: "atan":
-double: 1
float: 1
-idouble: 1
ifloat: 1
ildouble: 1
ldouble: 1
@@ -252,42 +250,42 @@ ildouble: 2
ldouble: 2
Function: Imaginary part of "cacos":
-double: 1
+double: 2
float: 2
-idouble: 1
+idouble: 2
ifloat: 2
ildouble: 2
ldouble: 2
Function: Real part of "cacos_downward":
-double: 2
+double: 3
float: 2
-idouble: 2
+idouble: 3
ifloat: 2
-ildouble: 2
-ldouble: 2
+ildouble: 3
+ldouble: 3
Function: Imaginary part of "cacos_downward":
double: 5
float: 3
idouble: 5
ifloat: 3
-ildouble: 5
-ldouble: 5
+ildouble: 6
+ldouble: 6
Function: Real part of "cacos_towardzero":
-double: 2
+double: 3
float: 2
-idouble: 2
+idouble: 3
ifloat: 2
-ildouble: 2
-ldouble: 2
+ildouble: 3
+ldouble: 3
Function: Imaginary part of "cacos_towardzero":
-double: 5
-float: 3
-idouble: 5
-ifloat: 3
+double: 4
+float: 2
+idouble: 4
+ifloat: 2
ildouble: 5
ldouble: 5
@@ -300,17 +298,17 @@ ildouble: 3
ldouble: 3
Function: Imaginary part of "cacos_upward":
-double: 4
-float: 4
-idouble: 4
-ifloat: 4
-ildouble: 5
-ldouble: 5
+double: 5
+float: 5
+idouble: 5
+ifloat: 5
+ildouble: 7
+ldouble: 7
Function: Real part of "cacosh":
-double: 1
+double: 2
float: 2
-idouble: 1
+idouble: 2
ifloat: 2
ildouble: 2
ldouble: 2
@@ -324,57 +322,55 @@ ildouble: 2
ldouble: 2
Function: Real part of "cacosh_downward":
-double: 5
-float: 3
-idouble: 5
-ifloat: 3
+double: 4
+float: 2
+idouble: 4
+ifloat: 2
ildouble: 5
ldouble: 5
Function: Imaginary part of "cacosh_downward":
-double: 2
-float: 2
-idouble: 2
-ifloat: 2
-ildouble: 2
-ldouble: 2
-
-Function: Real part of "cacosh_towardzero":
-double: 5
+double: 3
float: 3
-idouble: 5
+idouble: 3
ifloat: 3
+ildouble: 4
+ldouble: 4
+
+Function: Real part of "cacosh_towardzero":
+double: 4
+float: 2
+idouble: 4
+ifloat: 2
ildouble: 5
ldouble: 5
Function: Imaginary part of "cacosh_towardzero":
-double: 2
+double: 3
float: 2
-idouble: 2
+idouble: 3
ifloat: 2
-ildouble: 2
-ldouble: 2
+ildouble: 3
+ldouble: 3
Function: Real part of "cacosh_upward":
double: 4
-float: 4
+float: 3
idouble: 4
-ifloat: 4
-ildouble: 5
-ldouble: 5
+ifloat: 3
+ildouble: 6
+ldouble: 6
Function: Imaginary part of "cacosh_upward":
-double: 2
+double: 3
float: 2
-idouble: 2
+idouble: 3
ifloat: 2
-ildouble: 3
-ldouble: 3
+ildouble: 4
+ldouble: 4
Function: "carg":
-double: 1
float: 1
-idouble: 1
ifloat: 1
ildouble: 2
ldouble: 2
@@ -412,18 +408,18 @@ ildouble: 2
ldouble: 2
Function: Imaginary part of "casin":
-double: 1
+double: 2
float: 2
-idouble: 1
+idouble: 2
ifloat: 2
ildouble: 2
ldouble: 2
Function: Real part of "casin_downward":
double: 3
-float: 1
+float: 2
idouble: 3
-ifloat: 1
+ifloat: 2
ildouble: 3
ldouble: 3
@@ -432,8 +428,8 @@ double: 5
float: 3
idouble: 5
ifloat: 3
-ildouble: 5
-ldouble: 5
+ildouble: 6
+ldouble: 6
Function: Real part of "casin_towardzero":
double: 3
@@ -444,33 +440,33 @@ ildouble: 3
ldouble: 3
Function: Imaginary part of "casin_towardzero":
-double: 5
-float: 3
-idouble: 5
-ifloat: 3
+double: 4
+float: 2
+idouble: 4
+ifloat: 2
ildouble: 5
ldouble: 5
Function: Real part of "casin_upward":
-double: 2
-float: 1
-idouble: 2
-ifloat: 1
+double: 3
+float: 2
+idouble: 3
+ifloat: 2
ildouble: 3
ldouble: 3
Function: Imaginary part of "casin_upward":
-double: 4
-float: 4
-idouble: 4
-ifloat: 4
-ildouble: 5
-ldouble: 5
+double: 5
+float: 5
+idouble: 5
+ifloat: 5
+ildouble: 7
+ldouble: 7
Function: Real part of "casinh":
-double: 1
+double: 2
float: 2
-idouble: 1
+idouble: 2
ifloat: 2
ildouble: 2
ldouble: 2
@@ -488,22 +484,22 @@ double: 5
float: 3
idouble: 5
ifloat: 3
-ildouble: 5
-ldouble: 5
+ildouble: 6
+ldouble: 6
Function: Imaginary part of "casinh_downward":
double: 3
-float: 1
+float: 2
idouble: 3
-ifloat: 1
+ifloat: 2
ildouble: 3
ldouble: 3
Function: Real part of "casinh_towardzero":
-double: 5
-float: 3
-idouble: 5
-ifloat: 3
+double: 4
+float: 2
+idouble: 4
+ifloat: 2
ildouble: 5
ldouble: 5
@@ -516,23 +512,25 @@ ildouble: 3
ldouble: 3
Function: Real part of "casinh_upward":
-double: 4
-float: 4
-idouble: 4
-ifloat: 4
-ildouble: 5
-ldouble: 5
+double: 5
+float: 5
+idouble: 5
+ifloat: 5
+ildouble: 7
+ldouble: 7
Function: Imaginary part of "casinh_upward":
-double: 2
+double: 3
float: 2
-idouble: 2
+idouble: 3
ifloat: 2
ildouble: 3
ldouble: 3
Function: Real part of "catan":
+double: 1
float: 1
+idouble: 1
ifloat: 1
ildouble: 1
ldouble: 1
@@ -547,9 +545,9 @@ ldouble: 1
Function: Real part of "catan_downward":
double: 1
-float: 1
+float: 2
idouble: 1
-ifloat: 1
+ifloat: 2
ildouble: 2
ldouble: 2
@@ -558,36 +556,38 @@ double: 2
float: 2
idouble: 2
ifloat: 2
-ildouble: 3
-ldouble: 3
+ildouble: 2
+ldouble: 2
Function: Real part of "catan_towardzero":
double: 1
-float: 1
+float: 2
idouble: 1
-ifloat: 1
+ifloat: 2
ildouble: 2
ldouble: 2
Function: Imaginary part of "catan_towardzero":
double: 2
-float: 1
+float: 2
idouble: 2
-ifloat: 1
-ildouble: 3
-ldouble: 3
+ifloat: 2
+ildouble: 2
+ldouble: 2
Function: Real part of "catan_upward":
+double: 1
float: 1
+idouble: 1
ifloat: 1
-ildouble: 1
-ldouble: 1
+ildouble: 2
+ldouble: 2
Function: Imaginary part of "catan_upward":
-double: 3
-float: 3
-idouble: 3
-ifloat: 3
+double: 2
+float: 2
+idouble: 2
+ifloat: 2
ildouble: 3
ldouble: 3
@@ -600,7 +600,9 @@ ildouble: 1
ldouble: 1
Function: Imaginary part of "catanh":
+double: 1
float: 1
+idouble: 1
ifloat: 1
ildouble: 1
ldouble: 1
@@ -610,8 +612,8 @@ double: 2
float: 2
idouble: 2
ifloat: 2
-ildouble: 3
-ldouble: 3
+ildouble: 2
+ldouble: 2
Function: Imaginary part of "catanh_downward":
double: 1
@@ -623,11 +625,11 @@ ldouble: 2
Function: Real part of "catanh_towardzero":
double: 2
-float: 1
+float: 2
idouble: 2
-ifloat: 1
-ildouble: 3
-ldouble: 3
+ifloat: 2
+ildouble: 2
+ldouble: 2
Function: Imaginary part of "catanh_towardzero":
double: 1
@@ -639,17 +641,19 @@ ldouble: 2
Function: Real part of "catanh_upward":
double: 4
-float: 3
+float: 4
idouble: 4
-ifloat: 3
+ifloat: 4
ildouble: 4
ldouble: 4
Function: Imaginary part of "catanh_upward":
+double: 1
float: 1
+idouble: 1
ifloat: 1
-ildouble: 1
-ldouble: 1
+ildouble: 2
+ldouble: 2
Function: "cbrt":
double: 3
@@ -765,9 +769,9 @@ ldouble: 1
Function: Real part of "ccosh_downward":
double: 1
-float: 3
+float: 2
idouble: 1
-ifloat: 3
+ifloat: 2
ildouble: 2
ldouble: 2
@@ -884,9 +888,7 @@ ildouble: 2
ldouble: 2
Function: Imaginary part of "clog":
-double: 1
float: 1
-idouble: 1
ifloat: 1
ildouble: 1
ldouble: 1
@@ -900,18 +902,18 @@ ildouble: 2
ldouble: 2
Function: Imaginary part of "clog10":
-double: 1
+double: 2
float: 2
-idouble: 1
+idouble: 2
ifloat: 2
ildouble: 2
ldouble: 2
Function: Real part of "clog10_downward":
double: 5
-float: 4
+float: 5
idouble: 5
-ifloat: 4
+ifloat: 5
ildouble: 3
ldouble: 3
@@ -1004,32 +1006,26 @@ ildouble: 2
ldouble: 2
Function: "cos":
-float: 1
-ifloat: 1
+double: 1
+idouble: 1
ildouble: 1
ldouble: 1
Function: "cos_downward":
double: 1
-float: 2
idouble: 1
-ifloat: 2
ildouble: 3
ldouble: 3
Function: "cos_towardzero":
double: 1
-float: 1
idouble: 1
-ifloat: 1
ildouble: 1
ldouble: 1
Function: "cos_upward":
double: 1
-float: 2
idouble: 1
-ifloat: 2
ildouble: 2
ldouble: 2
@@ -1203,9 +1199,9 @@ ldouble: 1
Function: Real part of "csinh_downward":
double: 2
-float: 2
+float: 1
idouble: 2
-ifloat: 2
+ifloat: 1
ildouble: 2
ldouble: 2
@@ -1323,9 +1319,9 @@ ldouble: 3
Function: Imaginary part of "ctan":
double: 2
-float: 1
+float: 2
idouble: 2
-ifloat: 1
+ifloat: 2
ildouble: 3
ldouble: 3
@@ -1339,9 +1335,9 @@ ldouble: 4
Function: Imaginary part of "ctan_downward":
double: 2
-float: 1
+float: 2
idouble: 2
-ifloat: 1
+ifloat: 2
ildouble: 5
ldouble: 5
@@ -1363,17 +1359,17 @@ ldouble: 5
Function: Real part of "ctan_upward":
double: 2
-float: 3
+float: 4
idouble: 2
-ifloat: 3
+ifloat: 4
ildouble: 5
ldouble: 5
Function: Imaginary part of "ctan_upward":
double: 2
-float: 3
+float: 2
idouble: 2
-ifloat: 3
+ifloat: 2
ildouble: 5
ldouble: 5
@@ -1395,9 +1391,9 @@ ldouble: 3
Function: Real part of "ctanh_downward":
double: 4
-float: 1
+float: 2
idouble: 4
-ifloat: 1
+ifloat: 2
ildouble: 5
ldouble: 5
@@ -1427,9 +1423,9 @@ ldouble: 3
Function: Real part of "ctanh_upward":
double: 2
-float: 3
+float: 2
idouble: 2
-ifloat: 3
+ifloat: 2
ildouble: 5
ldouble: 5
@@ -1506,8 +1502,6 @@ ildouble: 5
ldouble: 5
Function: "exp":
-float: 1
-ifloat: 1
ildouble: 1
ldouble: 1
@@ -1543,25 +1537,19 @@ ldouble: 3
Function: "exp2":
double: 1
-float: 1
idouble: 1
-ifloat: 1
ildouble: 1
ldouble: 1
Function: "exp2_downward":
double: 1
-float: 1
idouble: 1
-ifloat: 1
ildouble: 1
ldouble: 1
Function: "exp2_towardzero":
double: 1
-float: 1
idouble: 1
-ifloat: 1
ildouble: 1
ldouble: 1
@@ -1575,15 +1563,21 @@ ldouble: 2
Function: "exp_downward":
double: 1
+float: 1
idouble: 1
+ifloat: 1
Function: "exp_towardzero":
double: 1
+float: 1
idouble: 1
+ifloat: 1
Function: "exp_upward":
double: 1
+float: 1
idouble: 1
+ifloat: 1
Function: "expm1":
double: 1
@@ -1619,9 +1613,9 @@ ldouble: 3
Function: "gamma":
double: 3
-float: 4
+float: 3
idouble: 3
-ifloat: 4
+ifloat: 3
ildouble: 5
ldouble: 5
@@ -1683,9 +1677,9 @@ ldouble: 2
Function: "j0_downward":
double: 2
-float: 3
+float: 4
idouble: 2
-ifloat: 3
+ifloat: 4
ildouble: 4
ldouble: 4
@@ -1771,9 +1765,9 @@ ldouble: 7
Function: "lgamma":
double: 3
-float: 4
+float: 3
idouble: 3
-ifloat: 4
+ifloat: 3
ildouble: 5
ldouble: 5
@@ -1802,8 +1796,6 @@ ildouble: 8
ldouble: 8
Function: "log":
-float: 1
-ifloat: 1
ildouble: 1
ldouble: 1
@@ -1825,9 +1817,9 @@ ldouble: 1
Function: "log10_towardzero":
double: 2
-float: 2
+float: 1
idouble: 2
-ifloat: 2
+ifloat: 1
ildouble: 1
ldouble: 1
@@ -1881,84 +1873,40 @@ ldouble: 2
Function: "log2_downward":
double: 3
-float: 3
idouble: 3
-ifloat: 3
ildouble: 3
ldouble: 3
Function: "log2_towardzero":
double: 2
-float: 2
idouble: 2
-ifloat: 2
ildouble: 1
ldouble: 1
Function: "log2_upward":
double: 3
-float: 3
idouble: 3
-ifloat: 3
ildouble: 1
ldouble: 1
Function: "log_downward":
-float: 2
-ifloat: 2
ildouble: 1
ldouble: 1
Function: "log_towardzero":
-float: 1
-ifloat: 1
ildouble: 2
ldouble: 2
Function: "log_upward":
-double: 1
-float: 1
-idouble: 1
-ifloat: 1
ildouble: 1
ldouble: 1
Function: "pow":
-float: 1
-ifloat: 1
-ildouble: 2
-ldouble: 2
-
-Function: "pow10":
-double: 2
-idouble: 2
+double: 1
+idouble: 1
ildouble: 2
ldouble: 2
-Function: "pow10_downward":
-double: 2
-float: 1
-idouble: 2
-ifloat: 1
-ildouble: 3
-ldouble: 3
-
-Function: "pow10_towardzero":
-double: 2
-float: 1
-idouble: 2
-ifloat: 1
-ildouble: 3
-ldouble: 3
-
-Function: "pow10_upward":
-double: 2
-float: 1
-idouble: 2
-ifloat: 1
-ildouble: 3
-ldouble: 3
-
Function: "pow_downward":
double: 1
float: 1
@@ -1984,62 +1932,50 @@ ildouble: 2
ldouble: 2
Function: "sin":
-float: 1
-ifloat: 1
+double: 1
+idouble: 1
ildouble: 1
ldouble: 1
Function: "sin_downward":
double: 1
-float: 2
idouble: 1
-ifloat: 2
ildouble: 3
ldouble: 3
Function: "sin_towardzero":
double: 1
-float: 1
idouble: 1
-ifloat: 1
ildouble: 2
ldouble: 2
Function: "sin_upward":
double: 1
-float: 2
idouble: 1
-ifloat: 2
ildouble: 3
ldouble: 3
Function: "sincos":
-float: 1
-ifloat: 1
+double: 1
+idouble: 1
ildouble: 1
ldouble: 1
Function: "sincos_downward":
double: 1
-float: 2
idouble: 1
-ifloat: 2
ildouble: 3
ldouble: 3
Function: "sincos_towardzero":
double: 1
-float: 1
idouble: 1
-ifloat: 1
ildouble: 2
ldouble: 2
Function: "sincos_upward":
double: 1
-float: 2
idouble: 1
-ifloat: 2
ildouble: 3
ldouble: 3
@@ -2179,9 +2115,9 @@ ldouble: 3
Function: "y0_downward":
double: 3
-float: 2
+float: 4
idouble: 3
-ifloat: 2
+ifloat: 4
ildouble: 4
ldouble: 4
@@ -2195,9 +2131,9 @@ ldouble: 3
Function: "y0_upward":
double: 2
-float: 3
+float: 5
idouble: 2
-ifloat: 3
+ifloat: 5
ildouble: 3
ldouble: 3
@@ -2235,17 +2171,17 @@ ldouble: 5
Function: "yn":
double: 3
-float: 2
+float: 3
idouble: 3
-ifloat: 2
+ifloat: 3
ildouble: 5
ldouble: 5
Function: "yn_downward":
double: 3
-float: 2
+float: 4
idouble: 3
-ifloat: 2
+ifloat: 4
ildouble: 5
ldouble: 5
@@ -2259,9 +2195,9 @@ ldouble: 5
Function: "yn_upward":
double: 4
-float: 3
+float: 5
idouble: 4
-ifloat: 3
+ifloat: 5
ildouble: 5
ldouble: 5
diff --git a/sysdeps/s390/fpu/libm-test-ulps-name b/sysdeps/s390/fpu/libm-test-ulps-name
new file mode 100644
index 0000000000..4a55100a0e
--- /dev/null
+++ b/sysdeps/s390/fpu/libm-test-ulps-name
@@ -0,0 +1 @@
+S/390
diff --git a/sysdeps/s390/fpu/s_fma.c b/sysdeps/s390/fpu/s_fma.c
index 7d7e563b7e..93405d0662 100644
--- a/sysdeps/s390/fpu/s_fma.c
+++ b/sysdeps/s390/fpu/s_fma.c
@@ -1,5 +1,5 @@
/* Compute x * y + z as ternary operation. S/390 version.
- Copyright (C) 2010-2016 Free Software Foundation, Inc.
+ Copyright (C) 2010-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Jakub Jelinek <jakub@redhat.com>, 2010.
@@ -18,6 +18,7 @@
<http://www.gnu.org/licenses/>. */
#include <math.h>
+#include <libm-alias-double.h>
double
__fma (double x, double y, double z)
@@ -27,10 +28,5 @@ __fma (double x, double y, double z)
return r;
}
#ifndef __fma
-weak_alias (__fma, fma)
-#endif
-
-#ifdef NO_LONG_DOUBLE
-strong_alias (__fma, __fmal)
-weak_alias (__fmal, fmal)
+libm_alias_double (__fma, fma)
#endif
diff --git a/sysdeps/s390/fpu/s_fmaf.c b/sysdeps/s390/fpu/s_fmaf.c
index 50af2bbc5b..0768495f16 100644
--- a/sysdeps/s390/fpu/s_fmaf.c
+++ b/sysdeps/s390/fpu/s_fmaf.c
@@ -1,5 +1,5 @@
/* Compute x * y + z as ternary operation. S/390 version.
- Copyright (C) 2010-2016 Free Software Foundation, Inc.
+ Copyright (C) 2010-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Jakub Jelinek <jakub@redhat.com>, 2010.
@@ -18,6 +18,7 @@
<http://www.gnu.org/licenses/>. */
#include <math.h>
+#include <libm-alias-float.h>
float
__fmaf (float x, float y, float z)
@@ -27,5 +28,5 @@ __fmaf (float x, float y, float z)
return r;
}
#ifndef __fmaf
-weak_alias (__fmaf, fmaf)
+libm_alias_float (__fma, fma)
#endif
diff --git a/sysdeps/s390/gccframe.h b/sysdeps/s390/gccframe.h
index ac0b6b9c4b..ad41f1f0ab 100644
--- a/sysdeps/s390/gccframe.h
+++ b/sysdeps/s390/gccframe.h
@@ -1,5 +1,5 @@
/* Definition of object in frame unwind info. s390 version.
- Copyright (C) 2001-2016 Free Software Foundation, Inc.
+ Copyright (C) 2001-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
diff --git a/sysdeps/s390/gconv-modules b/sysdeps/s390/gconv-modules
new file mode 100644
index 0000000000..c24b4571f5
--- /dev/null
+++ b/sysdeps/s390/gconv-modules
@@ -0,0 +1,50 @@
+# GNU libc iconv configuration.
+# Copyright (C) 1997-2018 Free Software Foundation, Inc.
+# This file is part of the GNU C Library.
+
+# The GNU C 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.
+
+# The GNU C Library 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, see
+# <http://www.gnu.org/licenses/>.
+
+# All lines contain the following information:
+
+# If the lines start with `module'
+# fromset: either a name triple or a regular expression triple.
+# toset: a name triple or an expression with \N to get regular
+# expression matching results.
+# filename: filename of the module implementing the transformation.
+# If it is not absolute the path is made absolute by prepending
+# the directory the configuration file is found in.
+# cost: optional cost of the transformation. Default is 1.
+
+# If the lines start with `alias'
+# alias: alias name which is not really recognized.
+# name: the real name of the character set
+
+# S/390 hardware accelerated modules
+# from to module cost
+module ISO-8859-1// IBM037// ISO-8859-1_CP037_Z900 1
+module IBM037// ISO-8859-1// ISO-8859-1_CP037_Z900 1
+module ISO-10646/UTF8/ UTF-32// UTF8_UTF32_Z9 1
+module UTF-32BE// ISO-10646/UTF8/ UTF8_UTF32_Z9 1
+module ISO-10646/UTF8/ UTF-32BE// UTF8_UTF32_Z9 1
+module UTF-16BE// UTF-32// UTF16_UTF32_Z9 1
+module UTF-32BE// UTF-16// UTF16_UTF32_Z9 1
+module INTERNAL UTF-16// UTF16_UTF32_Z9 1
+module UTF-32BE// UTF-16BE// UTF16_UTF32_Z9 1
+module INTERNAL UTF-16BE// UTF16_UTF32_Z9 1
+module UTF-16BE// UTF-32BE// UTF16_UTF32_Z9 1
+module UTF-16BE// INTERNAL UTF16_UTF32_Z9 1
+module UTF-16BE// ISO-10646/UTF8/ UTF8_UTF16_Z9 1
+module ISO-10646/UTF8/ UTF-16// UTF8_UTF16_Z9 1
+module ISO-10646/UTF8/ UTF-16BE// UTF8_UTF16_Z9 1
diff --git a/sysdeps/s390/gmp-mparam.h b/sysdeps/s390/gmp-mparam.h
index 0f7ec7af0c..fe7d708b78 100644
--- a/sysdeps/s390/gmp-mparam.h
+++ b/sysdeps/s390/gmp-mparam.h
@@ -1,5 +1,5 @@
/* gmp-mparam.h -- Compiler/machine parameter header file.
- Copyright (C) 2000-2016 Free Software Foundation, Inc.
+ Copyright (C) 2000-2018 Free Software Foundation, Inc.
Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com).
This file is part of the GNU MP Library.
diff --git a/sysdeps/s390/s390-64/iso-8859-1_cp037_z900.c b/sysdeps/s390/iso-8859-1_cp037_z900.c
index c59f87f18d..8428d77e57 100644
--- a/sysdeps/s390/s390-64/iso-8859-1_cp037_z900.c
+++ b/sysdeps/s390/iso-8859-1_cp037_z900.c
@@ -1,8 +1,7 @@
/* Conversion between ISO 8859-1 and IBM037.
- This module uses the Z900 variant of the Translate One To One
- instruction.
- Copyright (C) 1997-2016 Free Software Foundation, Inc.
+ This module uses the translate instruction.
+ Copyright (C) 1997-2018 Free Software Foundation, Inc.
Author: Andreas Krebbel <Andreas.Krebbel@de.ibm.com>
Based on the work by Ulrich Drepper <drepper@cygnus.com>, 1997.
@@ -176,50 +175,76 @@ __attribute__ ((aligned (8))) =
#define MIN_NEEDED_FROM 1
#define MIN_NEEDED_TO 1
-/* The Z900 variant of troo forces us to always specify a test
- character which ends the translation. So if we run into the
- situation where the translation has been interrupted due to the
- test character we translate the character by hand and jump back
- into the instruction. */
+# 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 TROO_LOOP(TABLE) \
+#define TR_LOOP(TABLE) \
{ \
- register const unsigned char test __asm__ ("0") = 0; \
- register const unsigned char *pTable __asm__ ("1") = TABLE; \
- register unsigned char *pOutput __asm__ ("2") = outptr; \
- register uint64_t length __asm__ ("3"); \
- const unsigned char* pInput = inptr; \
- uint64_t tmp; \
+ size_t length = (inend - inptr < outend - outptr \
+ ? inend - inptr : outend - outptr); \
\
- length = (inend - inptr < outend - outptr \
- ? inend - inptr : outend - outptr); \
+ /* Process in 256 byte blocks. */ \
+ if (__builtin_expect (length >= 256, 0)) \
+ { \
+ size_t blocks = length / 256; \
+ __asm__ __volatile__("0: mvc 0(256,%[R_OUT]),0(%[R_IN])\n\t" \
+ " 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" \
+ BRANCH_ON_COUNT ([R_LI], 0b) \
+ : /* outputs */ [R_IN] "+a" (inptr) \
+ , [R_OUT] "+a" (outptr), [R_LI] "+d" (blocks) \
+ : /* inputs */ [R_TBL] "a" (TABLE) \
+ : /* clobber list */ "memory" \
+ ); \
+ length = length % 256; \
+ } \
\
- __asm__ volatile ("0: \n\t" \
- " troo %0,%1 \n\t" \
- " jz 1f \n\t" \
- " jo 0b \n\t" \
- " llgc %3,0(%1) \n\t" \
- " la %3,0(%3,%4) \n\t" \
- " mvc 0(1,%0),0(%3) \n\t" \
- " aghi %1,1 \n\t" \
- " aghi %0,1 \n\t" \
- " aghi %2,-1 \n\t" \
- " j 0b \n\t" \
- "1: \n" \
+ /* Process remaining 0...248 bytes in 8byte blocks. */ \
+ if (length >= 8) \
+ { \
+ size_t blocks = length / 8; \
+ for (int i = 0; i < blocks; i++) \
+ { \
+ outptr[0] = TABLE[inptr[0]]; \
+ outptr[1] = TABLE[inptr[1]]; \
+ outptr[2] = TABLE[inptr[2]]; \
+ outptr[3] = TABLE[inptr[3]]; \
+ outptr[4] = TABLE[inptr[4]]; \
+ outptr[5] = TABLE[inptr[5]]; \
+ outptr[6] = TABLE[inptr[6]]; \
+ outptr[7] = TABLE[inptr[7]]; \
+ inptr += 8; \
+ outptr += 8; \
+ } \
+ length = length % 8; \
+ } \
\
- : "+a" (pOutput), "+a" (pInput), "+d" (length), "=&a" (tmp) \
- : "a" (pTable), "d" (test) \
- : "cc"); \
- \
- inptr = pInput; \
- outptr = pOutput; \
+ /* Process remaining 0...7 bytes. */ \
+ switch (length) \
+ { \
+ case 7: outptr[6] = TABLE[inptr[6]]; \
+ case 6: outptr[5] = TABLE[inptr[5]]; \
+ case 5: outptr[4] = TABLE[inptr[4]]; \
+ case 4: outptr[3] = TABLE[inptr[3]]; \
+ case 3: outptr[2] = TABLE[inptr[2]]; \
+ case 2: outptr[1] = TABLE[inptr[1]]; \
+ case 1: outptr[0] = TABLE[inptr[0]]; \
+ case 0: break; \
+ } \
+ inptr += length; \
+ outptr += length; \
}
+
/* First define the conversion function from ISO 8859-1 to CP037. */
#define MIN_NEEDED_INPUT MIN_NEEDED_FROM
#define MIN_NEEDED_OUTPUT MIN_NEEDED_TO
#define LOOPFCT FROM_LOOP
-#define BODY TROO_LOOP (table_iso8859_1_to_cp037)
+#define BODY TR_LOOP (table_iso8859_1_to_cp037)
#include <iconv/loop.c>
@@ -228,7 +253,7 @@ __attribute__ ((aligned (8))) =
#define MIN_NEEDED_INPUT MIN_NEEDED_TO
#define MIN_NEEDED_OUTPUT MIN_NEEDED_FROM
#define LOOPFCT TO_LOOP
-#define BODY TROO_LOOP (table_cp037_iso8859_1);
+#define BODY TR_LOOP (table_cp037_iso8859_1);
#include <iconv/loop.c>
diff --git a/sysdeps/s390/jmpbuf-offsets.h b/sysdeps/s390/jmpbuf-offsets.h
index bf23695cd2..7c6aafd8fa 100644
--- a/sysdeps/s390/jmpbuf-offsets.h
+++ b/sysdeps/s390/jmpbuf-offsets.h
@@ -1,5 +1,5 @@
/* Private macros for accessing __jmp_buf contents. S/390 version.
- Copyright (C) 2006-2016 Free Software Foundation, Inc.
+ Copyright (C) 2006-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
diff --git a/sysdeps/s390/jmpbuf-unwind.h b/sysdeps/s390/jmpbuf-unwind.h
index 1e1b4a8b6d..9d42f3056b 100644
--- a/sysdeps/s390/jmpbuf-unwind.h
+++ b/sysdeps/s390/jmpbuf-unwind.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2003-2016 Free Software Foundation, Inc.
+/* Copyright (C) 2003-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Jakub Jelinek <jakub@redhat.com>, 2003.
diff --git a/sysdeps/s390/ldsodefs.h b/sysdeps/s390/ldsodefs.h
index b22d364be4..e545d953fb 100644
--- a/sysdeps/s390/ldsodefs.h
+++ b/sysdeps/s390/ldsodefs.h
@@ -1,5 +1,5 @@
/* Run-time dynamic linker data structures for loaded ELF shared objects.
- Copyright (C) 1995-2016 Free Software Foundation, Inc.
+ Copyright (C) 1995-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
diff --git a/sysdeps/s390/libc-tls.c b/sysdeps/s390/libc-tls.c
index 1df435c1f4..85ede75275 100644
--- a/sysdeps/s390/libc-tls.c
+++ b/sysdeps/s390/libc-tls.c
@@ -1,5 +1,5 @@
/* Thread-local storage handling in the ELF dynamic linker. S390 version.
- Copyright (C) 2003-2016 Free Software Foundation, Inc.
+ Copyright (C) 2003-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
diff --git a/sysdeps/s390/linkmap.h b/sysdeps/s390/linkmap.h
index fc1fba363a..283615b99a 100644
--- a/sysdeps/s390/linkmap.h
+++ b/sysdeps/s390/linkmap.h
@@ -2,12 +2,12 @@
struct link_map_machine
{
Elf64_Addr plt; /* Address of .plt + 0x2e */
- Elf64_Addr gotplt; /* Address of .got + 0x18 */
+ const Elf64_Rela *jmprel; /* Address of first JMP_SLOT reloc */
};
#else
struct link_map_machine
{
Elf32_Addr plt; /* Address of .plt + 0x2c */
- Elf32_Addr gotplt; /* Address of .got + 0x0c */
+ const Elf32_Rela *jmprel; /* Address of first JMP_SLOT reloc */
};
#endif
diff --git a/sysdeps/s390/longjmp.c b/sysdeps/s390/longjmp.c
index 25b0145933..e61cdba2a3 100644
--- a/sysdeps/s390/longjmp.c
+++ b/sysdeps/s390/longjmp.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2014-2016 Free Software Foundation, Inc.
+/* Copyright (C) 2014-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -33,7 +33,6 @@
but were reverted before 2.20. Thus both versions are the same function. */
strong_alias (__libc_siglongjmp, __libc_longjmp)
-libc_hidden_def (__libc_longjmp)
weak_alias (__libc_siglongjmp, __v1_longjmp)
weak_alias (__libc_siglongjmp, __v2_longjmp)
diff --git a/sysdeps/s390/machine-gmon.h b/sysdeps/s390/machine-gmon.h
index 0c978754f6..a7b77c41ca 100644
--- a/sysdeps/s390/machine-gmon.h
+++ b/sysdeps/s390/machine-gmon.h
@@ -1,5 +1,5 @@
/* s390-specific implementation of profiling support.
- Copyright (C) 2000-2016 Free Software Foundation, Inc.
+ Copyright (C) 2000-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
diff --git a/sysdeps/s390/nptl/pthread_spin_init.c b/sysdeps/s390/mempcpy.S
index 7d3568fd6f..18ef29213e 100644
--- a/sysdeps/s390/nptl/pthread_spin_init.c
+++ b/sysdeps/s390/mempcpy.S
@@ -1,6 +1,6 @@
-/* Copyright (C) 2003-2016 Free Software Foundation, Inc.
+/* CPU specific mempcpy without multiarch - 32/64 bit S/390 version.
+ Copyright (C) 2016-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
- Contributed by Martin Schwidefsky <schwidefsky@de.ibm.com>, 2003.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -16,4 +16,4 @@
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
-/* Not needed. pthread_spin_init is an alias for pthread_spin_unlock. */
+/* mempcpy is implemented in memcpy.S. */
diff --git a/sysdeps/s390/memusage.h b/sysdeps/s390/memusage.h
index 888d708b29..c408acd416 100644
--- a/sysdeps/s390/memusage.h
+++ b/sysdeps/s390/memusage.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000-2016 Free Software Foundation, Inc.
+/* Copyright (C) 2000-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
diff --git a/sysdeps/s390/multiarch/8bit-generic.c b/sysdeps/s390/multiarch/8bit-generic.c
new file mode 100644
index 0000000000..d608beaa62
--- /dev/null
+++ b/sysdeps/s390/multiarch/8bit-generic.c
@@ -0,0 +1,402 @@
+/* Generic conversion to and from 8bit charsets - S390 version.
+ Copyright (C) 2016-2018 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C 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.
+
+ The GNU C Library 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, see
+ <http://www.gnu.org/licenses/>. */
+
+#if defined HAVE_S390_VX_ASM_SUPPORT
+
+# if defined HAVE_S390_VX_GCC_SUPPORT
+# define ASM_CLOBBER_VR(NR) , NR
+# else
+# define ASM_CLOBBER_VR(NR)
+# endif
+
+/* Generate the conversion loop routines without vector instructions as
+ fallback, if vector instructions aren't available at runtime. */
+# define IGNORE_ICONV_SKELETON
+# define from_generic __from_generic_c
+# define to_generic __to_generic_c
+# include "iconvdata/8bit-generic.c"
+# undef IGNORE_ICONV_SKELETON
+# undef from_generic
+# undef to_generic
+
+/* Generate the converion routines with vector instructions. The vector
+ routines can only be used with charsets where the maximum UCS4 value
+ fits in 1 byte size. Then the hardware translate-instruction is used
+ to translate between multiple generic characters and "1 byte UCS4"
+ characters at once. The vector instructions are used to convert between
+ the "1 byte UCS4" and UCS4. */
+# include <ifunc-resolve.h>
+
+# undef FROM_LOOP
+# undef TO_LOOP
+# define FROM_LOOP __from_generic_vx
+# define TO_LOOP __to_generic_vx
+
+# define MIN_NEEDED_FROM 1
+# define MIN_NEEDED_TO 4
+# define ONE_DIRECTION 0
+
+/* First define the conversion function from the 8bit charset to UCS4. */
+# define MIN_NEEDED_INPUT MIN_NEEDED_FROM
+# define MIN_NEEDED_OUTPUT MIN_NEEDED_TO
+# define LOOPFCT FROM_LOOP
+# define BODY_FROM_ORIG \
+ { \
+ uint32_t ch = to_ucs4[*inptr]; \
+ \
+ if (HAS_HOLES && __builtin_expect (ch == L'\0', 0) && *inptr != '\0') \
+ { \
+ /* This is an illegal character. */ \
+ STANDARD_FROM_LOOP_ERR_HANDLER (1); \
+ } \
+ \
+ put32 (outptr, ch); \
+ outptr += 4; \
+ ++inptr; \
+ }
+
+# define BODY \
+ { \
+ if (__builtin_expect (inend - inptr < 16, 1) \
+ || outend - outptr < 64) \
+ /* Convert remaining bytes with c code. */ \
+ BODY_FROM_ORIG \
+ else \
+ { \
+ /* Convert 16 ... 256 bytes at once with tr-instruction. */ \
+ size_t index; \
+ char buf[256]; \
+ size_t loop_count = (inend - inptr) / 16; \
+ if (loop_count > (outend - outptr) / 64) \
+ loop_count = (outend - outptr) / 64; \
+ if (loop_count > 16) \
+ loop_count = 16; \
+ __asm__ volatile (".machine push\n\t" \
+ ".machine \"z13\"\n\t" \
+ ".machinemode \"zarch_nohighgprs\"\n\t" \
+ " sllk %[R_I],%[R_LI],4\n\t" \
+ " ahi %[R_I],-1\n\t" \
+ /* Execute mvc and tr with correct len. */ \
+ " exrl %[R_I],21f\n\t" \
+ " exrl %[R_I],22f\n\t" \
+ /* Post-processing. */ \
+ " lghi %[R_I],0\n\t" \
+ " vzero %%v0\n\t" \
+ "0: \n\t" \
+ /* Find invalid character - value is zero. */ \
+ " vl %%v16,0(%[R_I],%[R_BUF])\n\t" \
+ " vceqbs %%v23,%%v0,%%v16\n\t" \
+ " jle 10f\n\t" \
+ "1: \n\t" \
+ /* Enlarge to UCS4. */ \
+ " vuplhb %%v17,%%v16\n\t" \
+ " vupllb %%v18,%%v16\n\t" \
+ " vuplhh %%v19,%%v17\n\t" \
+ " vupllh %%v20,%%v17\n\t" \
+ " vuplhh %%v21,%%v18\n\t" \
+ " vupllh %%v22,%%v18\n\t" \
+ /* Store 64bytes to buf_out. */ \
+ " vstm %%v19,%%v22,0(%[R_OUT])\n\t" \
+ " aghi %[R_I],16\n\t" \
+ " la %[R_OUT],64(%[R_OUT])\n\t" \
+ " brct %[R_LI],0b\n\t" \
+ " la %[R_IN],0(%[R_I],%[R_IN])\n\t" \
+ " j 20f\n\t" \
+ "21: mvc 0(1,%[R_BUF]),0(%[R_IN])\n\t" \
+ "22: tr 0(1,%[R_BUF]),0(%[R_TBL])\n\t" \
+ /* Possibly invalid character found. */ \
+ "10: \n\t" \
+ /* Test if input was zero, too. */ \
+ " vl %%v24,0(%[R_I],%[R_IN])\n\t" \
+ " vceqb %%v24,%%v0,%%v24\n\t" \
+ /* Zeros in buf (v23) and inptr (v24) are marked \
+ with one bits. After xor, invalid characters \
+ are marked as one bits. Proceed, if no \
+ invalid characters are found. */ \
+ " vx %%v24,%%v23,%%v24\n\t" \
+ " vfenebs %%v24,%%v24,%%v0\n\t" \
+ " jo 1b\n\t" \
+ /* Found an invalid translation. \
+ Store the preceding chars. */ \
+ " la %[R_IN],0(%[R_I],%[R_IN])\n\t" \
+ " vlgvb %[R_I],%%v24,7\n\t" \
+ " la %[R_IN],0(%[R_I],%[R_IN])\n\t" \
+ " sll %[R_I],2\n\t" \
+ " ahi %[R_I],-1\n\t" \
+ " jl 20f\n\t" \
+ " lgr %[R_LI],%[R_I]\n\t" \
+ " vuplhb %%v17,%%v16\n\t" \
+ " vuplhh %%v19,%%v17\n\t" \
+ " vstl %%v19,%[R_I],0(%[R_OUT])\n\t" \
+ " ahi %[R_I],-16\n\t" \
+ " jl 11f\n\t" \
+ " vupllh %%v20,%%v17\n\t" \
+ " vstl %%v20,%[R_I],16(%[R_OUT])\n\t" \
+ " ahi %[R_I],-16\n\t" \
+ " jl 11f\n\t" \
+ " vupllb %%v18,%%v16\n\t" \
+ " vuplhh %%v21,%%v18\n\t" \
+ " vstl %%v21,%[R_I],32(%[R_OUT])\n\t" \
+ " ahi %[R_I],-16\n\t" \
+ " jl 11f\n\t" \
+ " vupllh %%v22,%%v18\n\t" \
+ " vstl %%v22,%[R_I],48(%[R_OUT])\n\t" \
+ "11: \n\t" \
+ " la %[R_OUT],1(%[R_LI],%[R_OUT])\n\t" \
+ "20: \n\t" \
+ ".machine pop" \
+ : /* outputs */ [R_IN] "+a" (inptr) \
+ , [R_OUT] "+a" (outptr), [R_I] "=&a" (index) \
+ , [R_LI] "+a" (loop_count) \
+ : /* inputs */ [R_BUF] "a" (buf) \
+ , [R_TBL] "a" (to_ucs1) \
+ : /* clobber list*/ "memory", "cc" \
+ ASM_CLOBBER_VR ("v0") ASM_CLOBBER_VR ("v16") \
+ ASM_CLOBBER_VR ("v17") ASM_CLOBBER_VR ("v18") \
+ ASM_CLOBBER_VR ("v19") ASM_CLOBBER_VR ("v20") \
+ ASM_CLOBBER_VR ("v21") ASM_CLOBBER_VR ("v22") \
+ ASM_CLOBBER_VR ("v23") ASM_CLOBBER_VR ("v24") \
+ ); \
+ /* Error occured? */ \
+ if (loop_count != 0) \
+ { \
+ /* Found an invalid character! */ \
+ STANDARD_FROM_LOOP_ERR_HANDLER (1); \
+ } \
+ } \
+ }
+
+# define LOOP_NEED_FLAGS
+# include <iconv/loop.c>
+
+/* Next, define the other direction - from UCS4 to 8bit charset. */
+# define MIN_NEEDED_INPUT MIN_NEEDED_TO
+# define MIN_NEEDED_OUTPUT MIN_NEEDED_FROM
+# define LOOPFCT TO_LOOP
+# define BODY_TO_ORIG \
+ { \
+ uint32_t ch = get32 (inptr); \
+ \
+ if (__builtin_expect (ch >= sizeof (from_ucs4) / sizeof (from_ucs4[0]), 0)\
+ || (__builtin_expect (from_ucs4[ch], '\1') == '\0' && ch != 0)) \
+ { \
+ UNICODE_TAG_HANDLER (ch, 4); \
+ \
+ /* This is an illegal character. */ \
+ STANDARD_TO_LOOP_ERR_HANDLER (4); \
+ } \
+ \
+ *outptr++ = from_ucs4[ch]; \
+ inptr += 4; \
+ }
+# define BODY \
+ { \
+ if (__builtin_expect (inend - inptr < 64, 1) \
+ || outend - outptr < 16) \
+ /* Convert remaining bytes with c code. */ \
+ BODY_TO_ORIG \
+ else \
+ { \
+ /* Convert 64 ... 1024 bytes at once with tr-instruction. */ \
+ size_t index, tmp; \
+ char buf[256]; \
+ size_t loop_count = (inend - inptr) / 64; \
+ uint32_t max = sizeof (from_ucs4) / sizeof (from_ucs4[0]); \
+ if (loop_count > (outend - outptr) / 16) \
+ loop_count = (outend - outptr) / 16; \
+ if (loop_count > 16) \
+ loop_count = 16; \
+ size_t remaining_loop_count = loop_count; \
+ /* Step 1: Check for ch>=max, ch == 0 and shorten to bytes. \
+ (ch == 0 is no error, but is handled differently) */ \
+ __asm__ volatile (".machine push\n\t" \
+ ".machine \"z13\"\n\t" \
+ ".machinemode \"zarch_nohighgprs\"\n\t" \
+ /* Setup to check for ch >= max. */ \
+ " vzero %%v21\n\t" \
+ " vleih %%v21,-24576,0\n\t" /* element 0: > */ \
+ " vleih %%v21,-8192,2\n\t" /* element 1: =<> */ \
+ " vlvgf %%v20,%[R_MAX],0\n\t" /* element 0: val */ \
+ /* Process in 64byte - 16 characters blocks. */ \
+ " lghi %[R_I],0\n\t" \
+ " lghi %[R_TMP],0\n\t" \
+ "0: \n\t" \
+ " vlm %%v16,%%v19,0(%[R_IN])\n\t" \
+ /* Test for ch >= max and ch == 0. */ \
+ " vstrczfs %%v22,%%v16,%%v20,%%v21\n\t" \
+ " jno 10f\n\t" \
+ " vstrczfs %%v22,%%v17,%%v20,%%v21\n\t" \
+ " jno 11f\n\t" \
+ " vstrczfs %%v22,%%v18,%%v20,%%v21\n\t" \
+ " jno 12f\n\t" \
+ " vstrczfs %%v22,%%v19,%%v20,%%v21\n\t" \
+ " jno 13f\n\t" \
+ /* Shorten to byte values. */ \
+ " vpkf %%v16,%%v16,%%v17\n\t" \
+ " vpkf %%v18,%%v18,%%v19\n\t" \
+ " vpkh %%v16,%%v16,%%v18\n\t" \
+ /* Store 16bytes to buf. */ \
+ " vst %%v16,0(%[R_I],%[R_BUF])\n\t" \
+ /* Loop until all blocks are processed. */ \
+ " la %[R_IN],64(%[R_IN])\n\t" \
+ " aghi %[R_I],16\n\t" \
+ " brct %[R_LI],0b\n\t" \
+ " j 20f\n\t" \
+ /* Found error ch >= max or ch == 0. */ \
+ "13: aghi %[R_TMP],4\n\t" \
+ "12: aghi %[R_TMP],4\n\t" \
+ "11: aghi %[R_TMP],4\n\t" \
+ "10: vlgvb %[R_I],%%v22,7\n\t" \
+ " srlg %[R_I],%[R_I],2\n\t" \
+ " agr %[R_I],%[R_TMP]\n\t" \
+ "20: \n\t" \
+ ".machine pop" \
+ : /* outputs */ [R_IN] "+a" (inptr) \
+ , [R_I] "=&a" (index) \
+ , [R_TMP] "=d" (tmp) \
+ , [R_LI] "+d" (remaining_loop_count) \
+ : /* inputs */ [R_BUF] "a" (buf) \
+ , [R_MAX] "d" (max) \
+ : /* clobber list*/ "memory", "cc" \
+ ASM_CLOBBER_VR ("v16") ASM_CLOBBER_VR ("v17") \
+ ASM_CLOBBER_VR ("v18") ASM_CLOBBER_VR ("v19") \
+ ASM_CLOBBER_VR ("v20") ASM_CLOBBER_VR ("v21") \
+ ASM_CLOBBER_VR ("v22") \
+ ); \
+ /* Error occured in step 1? An error (ch >= max || ch == 0) \
+ occured, if remaining_loop_count > 0. The error occured \
+ at character-index (index) after already processed blocks. */ \
+ loop_count -= remaining_loop_count; \
+ if (loop_count > 0) \
+ { \
+ /* Step 2: Translate already processed blocks in buf and \
+ check for errors (from_ucs4[ch] == 0). */ \
+ __asm__ volatile (".machine push\n\t" \
+ ".machine \"z13\"\n\t" \
+ ".machinemode \"zarch_nohighgprs\"\n\t" \
+ " sllk %[R_I],%[R_LI],4\n\t" \
+ " ahi %[R_I],-1\n\t" \
+ /* Execute tr with correct len. */ \
+ " exrl %[R_I],21f\n\t" \
+ /* Post-processing. */ \
+ " lghi %[R_I],0\n\t" \
+ "0: \n\t" \
+ /* Find invalid character - value == 0. */ \
+ " vl %%v16,0(%[R_I],%[R_BUF])\n\t" \
+ " vfenezbs %%v17,%%v16,%%v16\n\t" \
+ " je 10f\n\t" \
+ /* Store 16bytes to buf_out. */ \
+ " vst %%v16,0(%[R_I],%[R_OUT])\n\t" \
+ " aghi %[R_I],16\n\t" \
+ " brct %[R_LI],0b\n\t" \
+ " la %[R_OUT],0(%[R_I],%[R_OUT])\n\t" \
+ " j 20f\n\t" \
+ "21: tr 0(1,%[R_BUF]),0(%[R_TBL])\n\t" \
+ /* Found an error: from_ucs4[ch] == 0. */ \
+ "10: la %[R_OUT],0(%[R_I],%[R_OUT])\n\t" \
+ " vlgvb %[R_I],%%v17,7\n\t" \
+ "20: \n\t" \
+ ".machine pop" \
+ : /* outputs */ [R_OUT] "+a" (outptr) \
+ , [R_I] "=&a" (tmp) \
+ , [R_LI] "+d" (loop_count) \
+ : /* inputs */ [R_BUF] "a" (buf) \
+ , [R_TBL] "a" (from_ucs4) \
+ : /* clobber list*/ "memory", "cc" \
+ ASM_CLOBBER_VR ("v16") \
+ ASM_CLOBBER_VR ("v17") \
+ ); \
+ /* Error occured in processed bytes of step 2? \
+ Thus possible error in step 1 is obselete.*/ \
+ if (tmp < 16) \
+ { \
+ index = tmp; \
+ inptr -= loop_count * 64; \
+ } \
+ } \
+ /* Error occured in step 1/2? */ \
+ if (index < 16) \
+ { \
+ /* Found an invalid character (see step 2) or zero \
+ (see step 1) at index! Convert the chars before index \
+ manually. If there is a zero at index detected by step 1, \
+ there could be invalid characters before this zero. */ \
+ int i; \
+ uint32_t ch; \
+ for (i = 0; i < index; i++) \
+ { \
+ ch = get32 (inptr); \
+ if (__builtin_expect (from_ucs4[ch], '\1') == '\0') \
+ break; \
+ *outptr++ = from_ucs4[ch]; \
+ inptr += 4; \
+ } \
+ if (i == index) \
+ { \
+ ch = get32 (inptr); \
+ if (ch == 0) \
+ { \
+ /* This is no error, but handled differently. */ \
+ *outptr++ = from_ucs4[ch]; \
+ inptr += 4; \
+ continue; \
+ } \
+ } \
+ \
+ /* iconv/loop.c disables -Wmaybe-uninitialized for a false \
+ positive warning in this code with -Os and has a \
+ comment referencing this code accordingly. Updates in \
+ one place may require updates in the other. */ \
+ UNICODE_TAG_HANDLER (ch, 4); \
+ \
+ /* This is an illegal character. */ \
+ STANDARD_TO_LOOP_ERR_HANDLER (4); \
+ } \
+ } \
+ }
+
+# define LOOP_NEED_FLAGS
+# include <iconv/loop.c>
+
+
+/* Generate ifunc'ed loop function. */
+s390_libc_ifunc_expr (__from_generic_c, __from_generic,
+ (sizeof (from_ucs4) / sizeof (from_ucs4[0]) <= 256
+ && hwcap & HWCAP_S390_VX)
+ ? __from_generic_vx
+ : __from_generic_c);
+
+s390_libc_ifunc_expr (__to_generic_c, __to_generic,
+ (sizeof (from_ucs4) / sizeof (from_ucs4[0]) <= 256
+ && hwcap & HWCAP_S390_VX)
+ ? __to_generic_vx
+ : __to_generic_c);
+
+strong_alias (__to_generic_c_single, __to_generic_single)
+
+# undef FROM_LOOP
+# undef TO_LOOP
+# define FROM_LOOP __from_generic
+# define TO_LOOP __to_generic
+# include <iconv/skeleton.c>
+
+#else
+/* Generate this module without ifunc if build environment lacks vector
+ support. Instead the common 8bit-generic.c is used. */
+# include "iconvdata/8bit-generic.c"
+#endif /* !defined HAVE_S390_VX_ASM_SUPPORT */
diff --git a/sysdeps/s390/multiarch/Makefile b/sysdeps/s390/multiarch/Makefile
index 0805b07984..c893ebc565 100644
--- a/sysdeps/s390/multiarch/Makefile
+++ b/sysdeps/s390/multiarch/Makefile
@@ -18,7 +18,8 @@ sysdep_routines += strlen strlen-vx strlen-c \
memchr memchr-vx \
rawmemchr rawmemchr-vx rawmemchr-c \
memccpy memccpy-vx memccpy-c \
- memrchr memrchr-vx memrchr-c
+ memrchr memrchr-vx memrchr-c \
+ mempcpy
endif
ifeq ($(subdir),wcsmbs)
@@ -42,3 +43,17 @@ sysdep_routines += wcslen wcslen-vx wcslen-c \
wmemset wmemset-vx wmemset-c \
wmemcmp wmemcmp-vx wmemcmp-c
endif
+
+ifeq ($(subdir),iconvdata)
+override define generate-8bit-table
+$(make-target-directory)
+LC_ALL=C $(SHELL) ./gen-8bit.sh $< > $(@:stmp=T)
+LC_ALL=C $(SHELL) ../sysdeps/s390/multiarch/gen-8bit.sh $< >> $(@:stmp=T)
+$(move-if-change) $(@:stmp=T) $(@:stmp=h)
+touch $@
+endef
+endif
+
+ifeq ($(subdir),iconv)
+sysdep_routines += gconv_simple
+endif
diff --git a/sysdeps/s390/multiarch/gconv_simple.c b/sysdeps/s390/multiarch/gconv_simple.c
new file mode 100644
index 0000000000..aaa1ebf74a
--- /dev/null
+++ b/sysdeps/s390/multiarch/gconv_simple.c
@@ -0,0 +1,1266 @@
+/* Simple transformations functions - s390 version.
+ Copyright (C) 2016-2018 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C 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.
+
+ The GNU C Library 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, see
+ <http://www.gnu.org/licenses/>. */
+
+#if defined HAVE_S390_VX_ASM_SUPPORT
+# include <ifunc-resolve.h>
+
+# if defined HAVE_S390_VX_GCC_SUPPORT
+# define ASM_CLOBBER_VR(NR) , NR
+# else
+# define ASM_CLOBBER_VR(NR)
+# endif
+
+# define ICONV_C_NAME(NAME) __##NAME##_c
+# define ICONV_VX_NAME(NAME) __##NAME##_vx
+# define ICONV_VX_IFUNC(FUNC) \
+ extern __typeof (ICONV_C_NAME (FUNC)) __##FUNC; \
+ s390_vx_libc_ifunc (__##FUNC) \
+ int FUNC (struct __gconv_step *step, struct __gconv_step_data *data, \
+ const unsigned char **inptrp, const unsigned char *inend, \
+ unsigned char **outbufstart, size_t *irreversible, \
+ int do_flush, int consume_incomplete) \
+ { \
+ return __##FUNC (step, data, inptrp, inend,outbufstart, \
+ irreversible, do_flush, consume_incomplete); \
+ }
+# define ICONV_VX_SINGLE(NAME) \
+ static __typeof (NAME##_single) __##NAME##_vx_single __attribute__((alias(#NAME "_single")));
+
+/* Generate the transformations which are used, if the target machine does not
+ support vector instructions. */
+# define __gconv_transform_ascii_internal \
+ ICONV_C_NAME (__gconv_transform_ascii_internal)
+# define __gconv_transform_internal_ascii \
+ ICONV_C_NAME (__gconv_transform_internal_ascii)
+# define __gconv_transform_internal_ucs4le \
+ ICONV_C_NAME (__gconv_transform_internal_ucs4le)
+# define __gconv_transform_ucs4_internal \
+ ICONV_C_NAME (__gconv_transform_ucs4_internal)
+# define __gconv_transform_ucs4le_internal \
+ ICONV_C_NAME (__gconv_transform_ucs4le_internal)
+# define __gconv_transform_ucs2_internal \
+ ICONV_C_NAME (__gconv_transform_ucs2_internal)
+# define __gconv_transform_ucs2reverse_internal \
+ ICONV_C_NAME (__gconv_transform_ucs2reverse_internal)
+# define __gconv_transform_internal_ucs2 \
+ ICONV_C_NAME (__gconv_transform_internal_ucs2)
+# define __gconv_transform_internal_ucs2reverse \
+ ICONV_C_NAME (__gconv_transform_internal_ucs2reverse)
+
+
+# include <iconv/gconv_simple.c>
+
+# undef __gconv_transform_ascii_internal
+# undef __gconv_transform_internal_ascii
+# undef __gconv_transform_internal_ucs4le
+# undef __gconv_transform_ucs4_internal
+# undef __gconv_transform_ucs4le_internal
+# undef __gconv_transform_ucs2_internal
+# undef __gconv_transform_ucs2reverse_internal
+# undef __gconv_transform_internal_ucs2
+# undef __gconv_transform_internal_ucs2reverse
+
+/* Now define the functions with vector support. */
+# if defined __s390x__
+# define CONVERT_32BIT_SIZE_T(REG)
+# else
+# define CONVERT_32BIT_SIZE_T(REG) "llgfr %" #REG ",%" #REG "\n\t"
+# endif
+
+/* Convert from ISO 646-IRV to the internal (UCS4-like) format. */
+# define DEFINE_INIT 0
+# define DEFINE_FINI 0
+# define MIN_NEEDED_FROM 1
+# define MIN_NEEDED_TO 4
+# define FROM_DIRECTION 1
+# define FROM_LOOP ICONV_VX_NAME (ascii_internal_loop)
+# define TO_LOOP ICONV_VX_NAME (ascii_internal_loop) /* This is not used. */
+# define FUNCTION_NAME ICONV_VX_NAME (__gconv_transform_ascii_internal)
+# define ONE_DIRECTION 1
+
+# define MIN_NEEDED_INPUT MIN_NEEDED_FROM
+# define MIN_NEEDED_OUTPUT MIN_NEEDED_TO
+# define LOOPFCT FROM_LOOP
+# define BODY_ORIG_ERROR \
+ /* The value is too large. We don't try transliteration here since \
+ this is not an error because of the lack of possibilities to \
+ represent the result. This is a genuine bug in the input since \
+ ASCII does not allow such values. */ \
+ STANDARD_FROM_LOOP_ERR_HANDLER (1);
+
+# define BODY_ORIG \
+ { \
+ if (__glibc_unlikely (*inptr > '\x7f')) \
+ { \
+ BODY_ORIG_ERROR \
+ } \
+ else \
+ { \
+ /* It's an one byte sequence. */ \
+ *((uint32_t *) outptr) = *inptr++; \
+ outptr += sizeof (uint32_t); \
+ } \
+ }
+# define BODY \
+ { \
+ size_t len = inend - inptr; \
+ if (len > (outend - outptr) / 4) \
+ len = (outend - outptr) / 4; \
+ size_t loop_count, tmp; \
+ __asm__ volatile (".machine push\n\t" \
+ ".machine \"z13\"\n\t" \
+ ".machinemode \"zarch_nohighgprs\"\n\t" \
+ CONVERT_32BIT_SIZE_T ([R_LEN]) \
+ " vrepib %%v30,0x7f\n\t" /* For compare > 0x7f. */ \
+ " srlg %[R_LI],%[R_LEN],4\n\t" \
+ " vrepib %%v31,0x20\n\t" \
+ " clgije %[R_LI],0,1f\n\t" \
+ "0: \n\t" /* Handle 16-byte blocks. */ \
+ " vl %%v16,0(%[R_IN])\n\t" \
+ /* Checking for values > 0x7f. */ \
+ " vstrcbs %%v17,%%v16,%%v30,%%v31\n\t" \
+ " jno 10f\n\t" \
+ /* Enlarge to UCS4. */ \
+ " vuplhb %%v17,%%v16\n\t" \
+ " vupllb %%v18,%%v16\n\t" \
+ " vuplhh %%v19,%%v17\n\t" \
+ " vupllh %%v20,%%v17\n\t" \
+ " vuplhh %%v21,%%v18\n\t" \
+ " vupllh %%v22,%%v18\n\t" \
+ /* Store 64bytes to buf_out. */ \
+ " vstm %%v19,%%v22,0(%[R_OUT])\n\t" \
+ " la %[R_IN],16(%[R_IN])\n\t" \
+ " la %[R_OUT],64(%[R_OUT])\n\t" \
+ " brctg %[R_LI],0b\n\t" \
+ " lghi %[R_LI],15\n\t" \
+ " ngr %[R_LEN],%[R_LI]\n\t" \
+ " je 20f\n\t" /* Jump away if no remaining bytes. */ \
+ /* Handle remaining bytes. */ \
+ "1: aghik %[R_LI],%[R_LEN],-1\n\t" \
+ " jl 20f\n\t" /* Jump away if no remaining bytes. */ \
+ " vll %%v16,%[R_LI],0(%[R_IN])\n\t" \
+ /* Checking for values > 0x7f. */ \
+ " vstrcbs %%v17,%%v16,%%v30,%%v31\n\t" \
+ " vlgvb %[R_TMP],%%v17,7\n\t" \
+ " clr %[R_TMP],%[R_LI]\n\t" \
+ " locrh %[R_TMP],%[R_LEN]\n\t" \
+ " locghih %[R_LEN],0\n\t" \
+ " j 12f\n\t" \
+ "10:\n\t" \
+ /* Found a value > 0x7f. \
+ Store the preceding chars. */ \
+ " vlgvb %[R_TMP],%%v17,7\n\t" \
+ "12: la %[R_IN],0(%[R_TMP],%[R_IN])\n\t" \
+ " sllk %[R_TMP],%[R_TMP],2\n\t" \
+ " ahi %[R_TMP],-1\n\t" \
+ " jl 20f\n\t" \
+ " lgr %[R_LI],%[R_TMP]\n\t" \
+ " vuplhb %%v17,%%v16\n\t" \
+ " vuplhh %%v19,%%v17\n\t" \
+ " vstl %%v19,%[R_LI],0(%[R_OUT])\n\t" \
+ " ahi %[R_LI],-16\n\t" \
+ " jl 11f\n\t" \
+ " vupllh %%v20,%%v17\n\t" \
+ " vstl %%v20,%[R_LI],16(%[R_OUT])\n\t" \
+ " ahi %[R_LI],-16\n\t" \
+ " jl 11f\n\t" \
+ " vupllb %%v18,%%v16\n\t" \
+ " vuplhh %%v21,%%v18\n\t" \
+ " vstl %%v21,%[R_LI],32(%[R_OUT])\n\t" \
+ " ahi %[R_LI],-16\n\t" \
+ " jl 11f\n\t" \
+ " vupllh %%v22,%%v18\n\t" \
+ " vstl %%v22,%[R_LI],48(%[R_OUT])\n\t" \
+ "11:\n\t" \
+ " la %[R_OUT],1(%[R_TMP],%[R_OUT])\n\t" \
+ "20:\n\t" \
+ ".machine pop" \
+ : /* outputs */ [R_OUT] "+a" (outptr) \
+ , [R_IN] "+a" (inptr) \
+ , [R_LEN] "+d" (len) \
+ , [R_LI] "=d" (loop_count) \
+ , [R_TMP] "=a" (tmp) \
+ : /* inputs */ \
+ : /* clobber list*/ "memory", "cc" \
+ ASM_CLOBBER_VR ("v16") ASM_CLOBBER_VR ("v17") \
+ ASM_CLOBBER_VR ("v18") ASM_CLOBBER_VR ("v19") \
+ ASM_CLOBBER_VR ("v20") ASM_CLOBBER_VR ("v21") \
+ ASM_CLOBBER_VR ("v22") ASM_CLOBBER_VR ("v30") \
+ ASM_CLOBBER_VR ("v31") \
+ ); \
+ if (len > 0) \
+ { \
+ /* Found an invalid character at the next input byte. */ \
+ BODY_ORIG_ERROR \
+ } \
+ }
+
+# define LOOP_NEED_FLAGS
+# include <iconv/loop.c>
+# include <iconv/skeleton.c>
+# undef BODY_ORIG
+# undef BODY_ORIG_ERROR
+ICONV_VX_IFUNC (__gconv_transform_ascii_internal)
+
+/* Convert from the internal (UCS4-like) format to ISO 646-IRV. */
+# define DEFINE_INIT 0
+# define DEFINE_FINI 0
+# define MIN_NEEDED_FROM 4
+# define MIN_NEEDED_TO 1
+# define FROM_DIRECTION 1
+# define FROM_LOOP ICONV_VX_NAME (internal_ascii_loop)
+# define TO_LOOP ICONV_VX_NAME (internal_ascii_loop) /* This is not used. */
+# define FUNCTION_NAME ICONV_VX_NAME (__gconv_transform_internal_ascii)
+# define ONE_DIRECTION 1
+
+# define MIN_NEEDED_INPUT MIN_NEEDED_FROM
+# define MIN_NEEDED_OUTPUT MIN_NEEDED_TO
+# define LOOPFCT FROM_LOOP
+# define BODY_ORIG_ERROR \
+ UNICODE_TAG_HANDLER (*((const uint32_t *) inptr), 4); \
+ STANDARD_TO_LOOP_ERR_HANDLER (4);
+
+# define BODY_ORIG \
+ { \
+ if (__glibc_unlikely (*((const uint32_t *) inptr) > 0x7f)) \
+ { \
+ BODY_ORIG_ERROR \
+ } \
+ else \
+ { \
+ /* It's an one byte sequence. */ \
+ *outptr++ = *((const uint32_t *) inptr); \
+ inptr += sizeof (uint32_t); \
+ } \
+ }
+# define BODY \
+ { \
+ size_t len = (inend - inptr) / 4; \
+ if (len > outend - outptr) \
+ len = outend - outptr; \
+ size_t loop_count, tmp, tmp2; \
+ __asm__ volatile (".machine push\n\t" \
+ ".machine \"z13\"\n\t" \
+ ".machinemode \"zarch_nohighgprs\"\n\t" \
+ CONVERT_32BIT_SIZE_T ([R_LEN]) \
+ /* Setup to check for ch > 0x7f. */ \
+ " vzero %%v21\n\t" \
+ " srlg %[R_LI],%[R_LEN],4\n\t" \
+ " vleih %%v21,8192,0\n\t" /* element 0: > */ \
+ " vleih %%v21,-8192,2\n\t" /* element 1: =<> */ \
+ " vleif %%v20,127,0\n\t" /* element 0: 127 */ \
+ " lghi %[R_TMP],0\n\t" \
+ " clgije %[R_LI],0,1f\n\t" \
+ "0:\n\t" \
+ " vlm %%v16,%%v19,0(%[R_IN])\n\t" \
+ /* Shorten to byte values. */ \
+ " vpkf %%v23,%%v16,%%v17\n\t" \
+ " vpkf %%v24,%%v18,%%v19\n\t" \
+ " vpkh %%v23,%%v23,%%v24\n\t" \
+ /* Checking for values > 0x7f. */ \
+ " vstrcfs %%v22,%%v16,%%v20,%%v21\n\t" \
+ " jno 10f\n\t" \
+ " vstrcfs %%v22,%%v17,%%v20,%%v21\n\t" \
+ " jno 11f\n\t" \
+ " vstrcfs %%v22,%%v18,%%v20,%%v21\n\t" \
+ " jno 12f\n\t" \
+ " vstrcfs %%v22,%%v19,%%v20,%%v21\n\t" \
+ " jno 13f\n\t" \
+ /* Store 16bytes to outptr. */ \
+ " vst %%v23,0(%[R_OUT])\n\t" \
+ " la %[R_IN],64(%[R_IN])\n\t" \
+ " la %[R_OUT],16(%[R_OUT])\n\t" \
+ " brctg %[R_LI],0b\n\t" \
+ " lghi %[R_LI],15\n\t" \
+ " ngr %[R_LEN],%[R_LI]\n\t" \
+ " je 20f\n\t" /* Jump away if no remaining bytes. */ \
+ /* Handle remaining bytes. */ \
+ "1: sllg %[R_LI],%[R_LEN],2\n\t" \
+ " aghi %[R_LI],-1\n\t" \
+ " jl 20f\n\t" /* Jump away if no remaining bytes. */ \
+ /* Load remaining 1...63 bytes. */ \
+ " vll %%v16,%[R_LI],0(%[R_IN])\n\t" \
+ " ahi %[R_LI],-16\n\t" \
+ " jl 2f\n\t" \
+ " vll %%v17,%[R_LI],16(%[R_IN])\n\t" \
+ " ahi %[R_LI],-16\n\t" \
+ " jl 2f\n\t" \
+ " vll %%v18,%[R_LI],32(%[R_IN])\n\t" \
+ " ahi %[R_LI],-16\n\t" \
+ " jl 2f\n\t" \
+ " vll %%v19,%[R_LI],48(%[R_IN])\n\t" \
+ "2:\n\t" \
+ /* Shorten to byte values. */ \
+ " vpkf %%v23,%%v16,%%v17\n\t" \
+ " vpkf %%v24,%%v18,%%v19\n\t" \
+ " vpkh %%v23,%%v23,%%v24\n\t" \
+ " sllg %[R_LI],%[R_LEN],2\n\t" \
+ " aghi %[R_LI],-16\n\t" \
+ " jl 3f\n\t" /* v16 is not fully loaded. */ \
+ " vstrcfs %%v22,%%v16,%%v20,%%v21\n\t" \
+ " jno 10f\n\t" \
+ " aghi %[R_LI],-16\n\t" \
+ " jl 4f\n\t" /* v17 is not fully loaded. */ \
+ " vstrcfs %%v22,%%v17,%%v20,%%v21\n\t" \
+ " jno 11f\n\t" \
+ " aghi %[R_LI],-16\n\t" \
+ " jl 5f\n\t" /* v18 is not fully loaded. */ \
+ " vstrcfs %%v22,%%v18,%%v20,%%v21\n\t" \
+ " jno 12f\n\t" \
+ " aghi %[R_LI],-16\n\t" \
+ /* v19 is not fully loaded. */ \
+ " lghi %[R_TMP],12\n\t" \
+ " vstrcfs %%v22,%%v19,%%v20,%%v21\n\t" \
+ "6: vlgvb %[R_I],%%v22,7\n\t" \
+ " aghi %[R_LI],16\n\t" \
+ " clrjl %[R_I],%[R_LI],14f\n\t" \
+ " lgr %[R_I],%[R_LEN]\n\t" \
+ " lghi %[R_LEN],0\n\t" \
+ " j 15f\n\t" \
+ "3: vstrcfs %%v22,%%v16,%%v20,%%v21\n\t" \
+ " j 6b\n\t" \
+ "4: vstrcfs %%v22,%%v17,%%v20,%%v21\n\t" \
+ " lghi %[R_TMP],4\n\t" \
+ " j 6b\n\t" \
+ "5: vstrcfs %%v22,%%v17,%%v20,%%v21\n\t" \
+ " lghi %[R_TMP],8\n\t" \
+ " j 6b\n\t" \
+ /* Found a value > 0x7f. */ \
+ "13: ahi %[R_TMP],4\n\t" \
+ "12: ahi %[R_TMP],4\n\t" \
+ "11: ahi %[R_TMP],4\n\t" \
+ "10: vlgvb %[R_I],%%v22,7\n\t" \
+ "14: srlg %[R_I],%[R_I],2\n\t" \
+ " agr %[R_I],%[R_TMP]\n\t" \
+ " je 20f\n\t" \
+ /* Store characters before invalid one... */ \
+ "15: aghi %[R_I],-1\n\t" \
+ " vstl %%v23,%[R_I],0(%[R_OUT])\n\t" \
+ /* ... and update pointers. */ \
+ " la %[R_OUT],1(%[R_I],%[R_OUT])\n\t" \
+ " sllg %[R_I],%[R_I],2\n\t" \
+ " la %[R_IN],4(%[R_I],%[R_IN])\n\t" \
+ "20:\n\t" \
+ ".machine pop" \
+ : /* outputs */ [R_OUT] "+a" (outptr) \
+ , [R_IN] "+a" (inptr) \
+ , [R_LEN] "+d" (len) \
+ , [R_LI] "=d" (loop_count) \
+ , [R_I] "=a" (tmp2) \
+ , [R_TMP] "=d" (tmp) \
+ : /* inputs */ \
+ : /* clobber list*/ "memory", "cc" \
+ ASM_CLOBBER_VR ("v16") ASM_CLOBBER_VR ("v17") \
+ ASM_CLOBBER_VR ("v18") ASM_CLOBBER_VR ("v19") \
+ ASM_CLOBBER_VR ("v20") ASM_CLOBBER_VR ("v21") \
+ ASM_CLOBBER_VR ("v22") ASM_CLOBBER_VR ("v23") \
+ ASM_CLOBBER_VR ("v24") \
+ ); \
+ if (len > 0) \
+ { \
+ /* Found an invalid character > 0x7f at next character. */ \
+ BODY_ORIG_ERROR \
+ } \
+ }
+# define LOOP_NEED_FLAGS
+# include <iconv/loop.c>
+# include <iconv/skeleton.c>
+# undef BODY_ORIG
+# undef BODY_ORIG_ERROR
+ICONV_VX_IFUNC (__gconv_transform_internal_ascii)
+
+
+/* Convert from internal UCS4 to UCS4 little endian form. */
+# define DEFINE_INIT 0
+# define DEFINE_FINI 0
+# define MIN_NEEDED_FROM 4
+# define MIN_NEEDED_TO 4
+# define FROM_DIRECTION 1
+# define FROM_LOOP ICONV_VX_NAME (internal_ucs4le_loop)
+# define TO_LOOP ICONV_VX_NAME (internal_ucs4le_loop) /* This is not used. */
+# define FUNCTION_NAME ICONV_VX_NAME (__gconv_transform_internal_ucs4le)
+# define ONE_DIRECTION 0
+
+static inline int
+__attribute ((always_inline))
+ICONV_VX_NAME (internal_ucs4le_loop) (struct __gconv_step *step,
+ struct __gconv_step_data *step_data,
+ const unsigned char **inptrp,
+ const unsigned char *inend,
+ unsigned char **outptrp,
+ unsigned char *outend,
+ size_t *irreversible)
+{
+ const unsigned char *inptr = *inptrp;
+ unsigned char *outptr = *outptrp;
+ int result;
+ size_t len = MIN (inend - inptr, outend - outptr) / 4;
+ size_t loop_count;
+ __asm__ volatile (".machine push\n\t"
+ ".machine \"z13\"\n\t"
+ ".machinemode \"zarch_nohighgprs\"\n\t"
+ CONVERT_32BIT_SIZE_T ([R_LEN])
+ " bras %[R_LI],1f\n\t"
+ /* Vector permute mask: */
+ " .long 0x03020100,0x7060504,0x0B0A0908,0x0F0E0D0C\n\t"
+ "1: vl %%v20,0(%[R_LI])\n\t"
+ /* Process 64byte (16char) blocks. */
+ " srlg %[R_LI],%[R_LEN],4\n\t"
+ " clgije %[R_LI],0,10f\n\t"
+ "0: vlm %%v16,%%v19,0(%[R_IN])\n\t"
+ " vperm %%v16,%%v16,%%v16,%%v20\n\t"
+ " vperm %%v17,%%v17,%%v17,%%v20\n\t"
+ " vperm %%v18,%%v18,%%v18,%%v20\n\t"
+ " vperm %%v19,%%v19,%%v19,%%v20\n\t"
+ " vstm %%v16,%%v19,0(%[R_OUT])\n\t"
+ " la %[R_IN],64(%[R_IN])\n\t"
+ " la %[R_OUT],64(%[R_OUT])\n\t"
+ " brctg %[R_LI],0b\n\t"
+ " llgfr %[R_LEN],%[R_LEN]\n\t"
+ " nilf %[R_LEN],15\n\t"
+ /* Process 16byte (4char) blocks. */
+ "10: srlg %[R_LI],%[R_LEN],2\n\t"
+ " clgije %[R_LI],0,20f\n\t"
+ "11: vl %%v16,0(%[R_IN])\n\t"
+ " vperm %%v16,%%v16,%%v16,%%v20\n\t"
+ " vst %%v16,0(%[R_OUT])\n\t"
+ " la %[R_IN],16(%[R_IN])\n\t"
+ " la %[R_OUT],16(%[R_OUT])\n\t"
+ " brctg %[R_LI],11b\n\t"
+ " nill %[R_LEN],3\n\t"
+ /* Process <16bytes. */
+ "20: sll %[R_LEN],2\n\t"
+ " ahi %[R_LEN],-1\n\t"
+ " jl 30f\n\t"
+ " vll %%v16,%[R_LEN],0(%[R_IN])\n\t"
+ " vperm %%v16,%%v16,%%v16,%%v20\n\t"
+ " vstl %%v16,%[R_LEN],0(%[R_OUT])\n\t"
+ " la %[R_IN],1(%[R_LEN],%[R_IN])\n\t"
+ " la %[R_OUT],1(%[R_LEN],%[R_OUT])\n\t"
+ "30: \n\t"
+ ".machine pop"
+ : /* outputs */ [R_OUT] "+a" (outptr)
+ , [R_IN] "+a" (inptr)
+ , [R_LI] "=a" (loop_count)
+ , [R_LEN] "+a" (len)
+ : /* inputs */
+ : /* clobber list*/ "memory", "cc"
+ ASM_CLOBBER_VR ("v16") ASM_CLOBBER_VR ("v17")
+ ASM_CLOBBER_VR ("v18") ASM_CLOBBER_VR ("v19")
+ ASM_CLOBBER_VR ("v20")
+ );
+ *inptrp = inptr;
+ *outptrp = outptr;
+
+ /* Determine the status. */
+ if (*inptrp == inend)
+ result = __GCONV_EMPTY_INPUT;
+ else if (*outptrp + 4 > outend)
+ result = __GCONV_FULL_OUTPUT;
+ else
+ result = __GCONV_INCOMPLETE_INPUT;
+
+ return result;
+}
+
+ICONV_VX_SINGLE (internal_ucs4le_loop)
+# include <iconv/skeleton.c>
+ICONV_VX_IFUNC (__gconv_transform_internal_ucs4le)
+
+
+/* Transform from UCS4 to the internal, UCS4-like format. Unlike
+ for the other direction we have to check for correct values here. */
+# define DEFINE_INIT 0
+# define DEFINE_FINI 0
+# define MIN_NEEDED_FROM 4
+# define MIN_NEEDED_TO 4
+# define FROM_DIRECTION 1
+# define FROM_LOOP ICONV_VX_NAME (ucs4_internal_loop)
+# define TO_LOOP ICONV_VX_NAME (ucs4_internal_loop) /* This is not used. */
+# define FUNCTION_NAME ICONV_VX_NAME (__gconv_transform_ucs4_internal)
+# define ONE_DIRECTION 0
+
+
+static inline int
+__attribute ((always_inline))
+ICONV_VX_NAME (ucs4_internal_loop) (struct __gconv_step *step,
+ struct __gconv_step_data *step_data,
+ const unsigned char **inptrp,
+ const unsigned char *inend,
+ unsigned char **outptrp,
+ unsigned char *outend,
+ size_t *irreversible)
+{
+ int flags = step_data->__flags;
+ const unsigned char *inptr = *inptrp;
+ unsigned char *outptr = *outptrp;
+ int result;
+ size_t len, loop_count;
+ do
+ {
+ len = MIN (inend - inptr, outend - outptr) / 4;
+ __asm__ volatile (".machine push\n\t"
+ ".machine \"z13\"\n\t"
+ ".machinemode \"zarch_nohighgprs\"\n\t"
+ CONVERT_32BIT_SIZE_T ([R_LEN])
+ /* Setup to check for ch > 0x7fffffff. */
+ " larl %[R_LI],9f\n\t"
+ " vlm %%v20,%%v21,0(%[R_LI])\n\t"
+ " srlg %[R_LI],%[R_LEN],2\n\t"
+ " clgije %[R_LI],0,1f\n\t"
+ /* Process 16byte (4char) blocks. */
+ "0: vl %%v16,0(%[R_IN])\n\t"
+ " vstrcfs %%v22,%%v16,%%v20,%%v21\n\t"
+ " jno 10f\n\t"
+ " vst %%v16,0(%[R_OUT])\n\t"
+ " la %[R_IN],16(%[R_IN])\n\t"
+ " la %[R_OUT],16(%[R_OUT])\n\t"
+ " brctg %[R_LI],0b\n\t"
+ " llgfr %[R_LEN],%[R_LEN]\n\t"
+ " nilf %[R_LEN],3\n\t"
+ /* Process <16bytes. */
+ "1: sll %[R_LEN],2\n\t"
+ " ahik %[R_LI],%[R_LEN],-1\n\t"
+ " jl 20f\n\t" /* No further bytes available. */
+ " vll %%v16,%[R_LI],0(%[R_IN])\n\t"
+ " vstrcfs %%v22,%%v16,%%v20,%%v21\n\t"
+ " vlgvb %[R_LI],%%v22,7\n\t"
+ " clr %[R_LI],%[R_LEN]\n\t"
+ " locgrhe %[R_LI],%[R_LEN]\n\t"
+ " locghihe %[R_LEN],0\n\t"
+ " j 11f\n\t"
+ /* v20: Vector string range compare values. */
+ "9: .long 0x7fffffff,0x0,0x0,0x0\n\t"
+ /* v21: Vector string range compare control-bits.
+ element 0: >; element 1: =<> (always true) */
+ " .long 0x20000000,0xE0000000,0x0,0x0\n\t"
+ /* Found a value > 0x7fffffff. */
+ "10: vlgvb %[R_LI],%%v22,7\n\t"
+ /* Store characters before invalid one. */
+ "11: aghi %[R_LI],-1\n\t"
+ " jl 20f\n\t"
+ " vstl %%v16,%[R_LI],0(%[R_OUT])\n\t"
+ " la %[R_IN],1(%[R_LI],%[R_IN])\n\t"
+ " la %[R_OUT],1(%[R_LI],%[R_OUT])\n\t"
+ "20:\n\t"
+ ".machine pop"
+ : /* outputs */ [R_OUT] "+a" (outptr)
+ , [R_IN] "+a" (inptr)
+ , [R_LI] "=a" (loop_count)
+ , [R_LEN] "+d" (len)
+ : /* inputs */
+ : /* clobber list*/ "memory", "cc"
+ ASM_CLOBBER_VR ("v16") ASM_CLOBBER_VR ("v20")
+ ASM_CLOBBER_VR ("v21") ASM_CLOBBER_VR ("v22")
+ );
+ if (len > 0)
+ {
+ /* The value is too large. We don't try transliteration here since
+ this is not an error because of the lack of possibilities to
+ represent the result. This is a genuine bug in the input since
+ UCS4 does not allow such values. */
+ if (irreversible == NULL)
+ /* We are transliterating, don't try to correct anything. */
+ return __GCONV_ILLEGAL_INPUT;
+
+ if (flags & __GCONV_IGNORE_ERRORS)
+ {
+ /* Just ignore this character. */
+ ++*irreversible;
+ inptr += 4;
+ continue;
+ }
+
+ *inptrp = inptr;
+ *outptrp = outptr;
+ return __GCONV_ILLEGAL_INPUT;
+ }
+ }
+ while (len > 0);
+
+ *inptrp = inptr;
+ *outptrp = outptr;
+
+ /* Determine the status. */
+ if (*inptrp == inend)
+ result = __GCONV_EMPTY_INPUT;
+ else if (*outptrp + 4 > outend)
+ result = __GCONV_FULL_OUTPUT;
+ else
+ result = __GCONV_INCOMPLETE_INPUT;
+
+ return result;
+}
+
+ICONV_VX_SINGLE (ucs4_internal_loop)
+# include <iconv/skeleton.c>
+ICONV_VX_IFUNC (__gconv_transform_ucs4_internal)
+
+
+/* Transform from UCS4-LE to the internal encoding. */
+# define DEFINE_INIT 0
+# define DEFINE_FINI 0
+# define MIN_NEEDED_FROM 4
+# define MIN_NEEDED_TO 4
+# define FROM_DIRECTION 1
+# define FROM_LOOP ICONV_VX_NAME (ucs4le_internal_loop)
+# define TO_LOOP ICONV_VX_NAME (ucs4le_internal_loop) /* This is not used. */
+# define FUNCTION_NAME ICONV_VX_NAME (__gconv_transform_ucs4le_internal)
+# define ONE_DIRECTION 0
+
+static inline int
+__attribute ((always_inline))
+ICONV_VX_NAME (ucs4le_internal_loop) (struct __gconv_step *step,
+ struct __gconv_step_data *step_data,
+ const unsigned char **inptrp,
+ const unsigned char *inend,
+ unsigned char **outptrp,
+ unsigned char *outend,
+ size_t *irreversible)
+{
+ int flags = step_data->__flags;
+ const unsigned char *inptr = *inptrp;
+ unsigned char *outptr = *outptrp;
+ int result;
+ size_t len, loop_count;
+ do
+ {
+ len = MIN (inend - inptr, outend - outptr) / 4;
+ __asm__ volatile (".machine push\n\t"
+ ".machine \"z13\"\n\t"
+ ".machinemode \"zarch_nohighgprs\"\n\t"
+ CONVERT_32BIT_SIZE_T ([R_LEN])
+ /* Setup to check for ch > 0x7fffffff. */
+ " larl %[R_LI],9f\n\t"
+ " vlm %%v20,%%v22,0(%[R_LI])\n\t"
+ " srlg %[R_LI],%[R_LEN],2\n\t"
+ " clgije %[R_LI],0,1f\n\t"
+ /* Process 16byte (4char) blocks. */
+ "0: vl %%v16,0(%[R_IN])\n\t"
+ " vperm %%v16,%%v16,%%v16,%%v22\n\t"
+ " vstrcfs %%v23,%%v16,%%v20,%%v21\n\t"
+ " jno 10f\n\t"
+ " vst %%v16,0(%[R_OUT])\n\t"
+ " la %[R_IN],16(%[R_IN])\n\t"
+ " la %[R_OUT],16(%[R_OUT])\n\t"
+ " brctg %[R_LI],0b\n\t"
+ " llgfr %[R_LEN],%[R_LEN]\n\t"
+ " nilf %[R_LEN],3\n\t"
+ /* Process <16bytes. */
+ "1: sll %[R_LEN],2\n\t"
+ " ahik %[R_LI],%[R_LEN],-1\n\t"
+ " jl 20f\n\t" /* No further bytes available. */
+ " vll %%v16,%[R_LI],0(%[R_IN])\n\t"
+ " vperm %%v16,%%v16,%%v16,%%v22\n\t"
+ " vstrcfs %%v23,%%v16,%%v20,%%v21\n\t"
+ " vlgvb %[R_LI],%%v23,7\n\t"
+ " clr %[R_LI],%[R_LEN]\n\t"
+ " locgrhe %[R_LI],%[R_LEN]\n\t"
+ " locghihe %[R_LEN],0\n\t"
+ " j 11f\n\t"
+ /* v20: Vector string range compare values. */
+ "9: .long 0x7fffffff,0x0,0x0,0x0\n\t"
+ /* v21: Vector string range compare control-bits.
+ element 0: >; element 1: =<> (always true) */
+ " .long 0x20000000,0xE0000000,0x0,0x0\n\t"
+ /* v22: Vector permute mask. */
+ " .long 0x03020100,0x7060504,0x0B0A0908,0x0F0E0D0C\n\t"
+ /* Found a value > 0x7fffffff. */
+ "10: vlgvb %[R_LI],%%v23,7\n\t"
+ /* Store characters before invalid one. */
+ "11: aghi %[R_LI],-1\n\t"
+ " jl 20f\n\t"
+ " vstl %%v16,%[R_LI],0(%[R_OUT])\n\t"
+ " la %[R_IN],1(%[R_LI],%[R_IN])\n\t"
+ " la %[R_OUT],1(%[R_LI],%[R_OUT])\n\t"
+ "20:\n\t"
+ ".machine pop"
+ : /* outputs */ [R_OUT] "+a" (outptr)
+ , [R_IN] "+a" (inptr)
+ , [R_LI] "=a" (loop_count)
+ , [R_LEN] "+d" (len)
+ : /* inputs */
+ : /* clobber list*/ "memory", "cc"
+ ASM_CLOBBER_VR ("v16") ASM_CLOBBER_VR ("v20")
+ ASM_CLOBBER_VR ("v21") ASM_CLOBBER_VR ("v22")
+ ASM_CLOBBER_VR ("v23")
+ );
+ if (len > 0)
+ {
+ /* The value is too large. We don't try transliteration here since
+ this is not an error because of the lack of possibilities to
+ represent the result. This is a genuine bug in the input since
+ UCS4 does not allow such values. */
+ if (irreversible == NULL)
+ /* We are transliterating, don't try to correct anything. */
+ return __GCONV_ILLEGAL_INPUT;
+
+ if (flags & __GCONV_IGNORE_ERRORS)
+ {
+ /* Just ignore this character. */
+ ++*irreversible;
+ inptr += 4;
+ continue;
+ }
+
+ *inptrp = inptr;
+ *outptrp = outptr;
+ return __GCONV_ILLEGAL_INPUT;
+ }
+ }
+ while (len > 0);
+
+ *inptrp = inptr;
+ *outptrp = outptr;
+
+ /* Determine the status. */
+ if (*inptrp == inend)
+ result = __GCONV_EMPTY_INPUT;
+ else if (*inptrp + 4 > inend)
+ result = __GCONV_INCOMPLETE_INPUT;
+ else
+ {
+ assert (*outptrp + 4 > outend);
+ result = __GCONV_FULL_OUTPUT;
+ }
+
+ return result;
+}
+ICONV_VX_SINGLE (ucs4le_internal_loop)
+# include <iconv/skeleton.c>
+ICONV_VX_IFUNC (__gconv_transform_ucs4le_internal)
+
+/* Convert from UCS2 to the internal (UCS4-like) format. */
+# define DEFINE_INIT 0
+# define DEFINE_FINI 0
+# define MIN_NEEDED_FROM 2
+# define MIN_NEEDED_TO 4
+# define FROM_DIRECTION 1
+# define FROM_LOOP ICONV_VX_NAME (ucs2_internal_loop)
+# define TO_LOOP ICONV_VX_NAME (ucs2_internal_loop) /* This is not used. */
+# define FUNCTION_NAME ICONV_VX_NAME (__gconv_transform_ucs2_internal)
+# define ONE_DIRECTION 1
+
+# define MIN_NEEDED_INPUT MIN_NEEDED_FROM
+# define MIN_NEEDED_OUTPUT MIN_NEEDED_TO
+# define LOOPFCT FROM_LOOP
+# define BODY_ORIG_ERROR \
+ /* Surrogate characters in UCS-2 input are not valid. Reject \
+ them. (Catching this here is not security relevant.) */ \
+ STANDARD_FROM_LOOP_ERR_HANDLER (2);
+# define BODY_ORIG \
+ { \
+ uint16_t u1 = get16 (inptr); \
+ \
+ if (__glibc_unlikely (u1 >= 0xd800 && u1 < 0xe000)) \
+ { \
+ BODY_ORIG_ERROR \
+ } \
+ \
+ *((uint32_t *) outptr) = u1; \
+ outptr += sizeof (uint32_t); \
+ inptr += 2; \
+ }
+# define BODY \
+ { \
+ size_t len, tmp, tmp2; \
+ len = MIN ((inend - inptr) / 2, (outend - outptr) / 4); \
+ __asm__ volatile (".machine push\n\t" \
+ ".machine \"z13\"\n\t" \
+ ".machinemode \"zarch_nohighgprs\"\n\t" \
+ CONVERT_32BIT_SIZE_T ([R_LEN]) \
+ /* Setup to check for ch >= 0xd800 && ch < 0xe000. */ \
+ " larl %[R_TMP],9f\n\t" \
+ " vlm %%v20,%%v21,0(%[R_TMP])\n\t" \
+ " srlg %[R_TMP],%[R_LEN],3\n\t" \
+ " clgije %[R_TMP],0,1f\n\t" \
+ /* Process 16byte (8char) blocks. */ \
+ "0: vl %%v16,0(%[R_IN])\n\t" \
+ " vstrchs %%v19,%%v16,%%v20,%%v21\n\t" \
+ /* Enlarge UCS2 to UCS4. */ \
+ " vuplhh %%v17,%%v16\n\t" \
+ " vupllh %%v18,%%v16\n\t" \
+ " jno 10f\n\t" \
+ /* Store 32bytes to buf_out. */ \
+ " vstm %%v17,%%v18,0(%[R_OUT])\n\t" \
+ " la %[R_IN],16(%[R_IN])\n\t" \
+ " la %[R_OUT],32(%[R_OUT])\n\t" \
+ " brctg %[R_TMP],0b\n\t" \
+ " llgfr %[R_LEN],%[R_LEN]\n\t" \
+ " nilf %[R_LEN],7\n\t" \
+ /* Process <16bytes. */ \
+ "1: sll %[R_LEN],1\n\t" \
+ " ahik %[R_TMP],%[R_LEN],-1\n\t" \
+ " jl 20f\n\t" /* No further bytes available. */ \
+ " vll %%v16,%[R_TMP],0(%[R_IN])\n\t" \
+ " vstrchs %%v19,%%v16,%%v20,%%v21\n\t" \
+ /* Enlarge UCS2 to UCS4. */ \
+ " vuplhh %%v17,%%v16\n\t" \
+ " vupllh %%v18,%%v16\n\t" \
+ " vlgvb %[R_TMP],%%v19,7\n\t" \
+ " clr %[R_TMP],%[R_LEN]\n\t" \
+ " locgrhe %[R_TMP],%[R_LEN]\n\t" \
+ " locghihe %[R_LEN],0\n\t" \
+ " j 11f\n\t" \
+ /* v20: Vector string range compare values. */ \
+ "9: .short 0xd800,0xe000,0x0,0x0,0x0,0x0,0x0,0x0\n\t" \
+ /* v21: Vector string range compare control-bits. \
+ element 0: =>; element 1: < */ \
+ " .short 0xa000,0x4000,0x0,0x0,0x0,0x0,0x0,0x0\n\t" \
+ /* Found an element: ch >= 0xd800 && ch < 0xe000 */ \
+ "10: vlgvb %[R_TMP],%%v19,7\n\t" \
+ "11: la %[R_IN],0(%[R_TMP],%[R_IN])\n\t" \
+ " sll %[R_TMP],1\n\t" \
+ " lgr %[R_TMP2],%[R_TMP]\n\t" \
+ " ahi %[R_TMP],-1\n\t" \
+ " jl 20f\n\t" \
+ " vstl %%v17,%[R_TMP],0(%[R_OUT])\n\t" \
+ " ahi %[R_TMP],-16\n\t" \
+ " jl 19f\n\t" \
+ " vstl %%v18,%[R_TMP],16(%[R_OUT])\n\t" \
+ "19: la %[R_OUT],0(%[R_TMP2],%[R_OUT])\n\t" \
+ "20: \n\t" \
+ ".machine pop" \
+ : /* outputs */ [R_OUT] "+a" (outptr) \
+ , [R_IN] "+a" (inptr) \
+ , [R_TMP] "=a" (tmp) \
+ , [R_TMP2] "=a" (tmp2) \
+ , [R_LEN] "+d" (len) \
+ : /* inputs */ \
+ : /* clobber list*/ "memory", "cc" \
+ ASM_CLOBBER_VR ("v16") ASM_CLOBBER_VR ("v17") \
+ ASM_CLOBBER_VR ("v18") ASM_CLOBBER_VR ("v19") \
+ ASM_CLOBBER_VR ("v20") ASM_CLOBBER_VR ("v21") \
+ ); \
+ if (len > 0) \
+ { \
+ /* Found an invalid character at next input-char. */ \
+ BODY_ORIG_ERROR \
+ } \
+ }
+
+# define LOOP_NEED_FLAGS
+# include <iconv/loop.c>
+# include <iconv/skeleton.c>
+# undef BODY_ORIG
+# undef BODY_ORIG_ERROR
+ICONV_VX_IFUNC (__gconv_transform_ucs2_internal)
+
+/* Convert from UCS2 in other endianness to the internal (UCS4-like) format. */
+# define DEFINE_INIT 0
+# define DEFINE_FINI 0
+# define MIN_NEEDED_FROM 2
+# define MIN_NEEDED_TO 4
+# define FROM_DIRECTION 1
+# define FROM_LOOP ICONV_VX_NAME (ucs2reverse_internal_loop)
+# define TO_LOOP ICONV_VX_NAME (ucs2reverse_internal_loop) /* This is not used.*/
+# define FUNCTION_NAME ICONV_VX_NAME (__gconv_transform_ucs2reverse_internal)
+# define ONE_DIRECTION 1
+
+# define MIN_NEEDED_INPUT MIN_NEEDED_FROM
+# define MIN_NEEDED_OUTPUT MIN_NEEDED_TO
+# define LOOPFCT FROM_LOOP
+# define BODY_ORIG_ERROR \
+ /* Surrogate characters in UCS-2 input are not valid. Reject \
+ them. (Catching this here is not security relevant.) */ \
+ if (! ignore_errors_p ()) \
+ { \
+ result = __GCONV_ILLEGAL_INPUT; \
+ break; \
+ } \
+ inptr += 2; \
+ ++*irreversible; \
+ continue;
+
+# define BODY_ORIG \
+ { \
+ uint16_t u1 = bswap_16 (get16 (inptr)); \
+ \
+ if (__glibc_unlikely (u1 >= 0xd800 && u1 < 0xe000)) \
+ { \
+ BODY_ORIG_ERROR \
+ } \
+ \
+ *((uint32_t *) outptr) = u1; \
+ outptr += sizeof (uint32_t); \
+ inptr += 2; \
+ }
+# define BODY \
+ { \
+ size_t len, tmp, tmp2; \
+ len = MIN ((inend - inptr) / 2, (outend - outptr) / 4); \
+ __asm__ volatile (".machine push\n\t" \
+ ".machine \"z13\"\n\t" \
+ ".machinemode \"zarch_nohighgprs\"\n\t" \
+ CONVERT_32BIT_SIZE_T ([R_LEN]) \
+ /* Setup to check for ch >= 0xd800 && ch < 0xe000. */ \
+ " larl %[R_TMP],9f\n\t" \
+ " vlm %%v20,%%v22,0(%[R_TMP])\n\t" \
+ " srlg %[R_TMP],%[R_LEN],3\n\t" \
+ " clgije %[R_TMP],0,1f\n\t" \
+ /* Process 16byte (8char) blocks. */ \
+ "0: vl %%v16,0(%[R_IN])\n\t" \
+ " vperm %%v16,%%v16,%%v16,%%v22\n\t" \
+ " vstrchs %%v19,%%v16,%%v20,%%v21\n\t" \
+ /* Enlarge UCS2 to UCS4. */ \
+ " vuplhh %%v17,%%v16\n\t" \
+ " vupllh %%v18,%%v16\n\t" \
+ " jno 10f\n\t" \
+ /* Store 32bytes to buf_out. */ \
+ " vstm %%v17,%%v18,0(%[R_OUT])\n\t" \
+ " la %[R_IN],16(%[R_IN])\n\t" \
+ " la %[R_OUT],32(%[R_OUT])\n\t" \
+ " brctg %[R_TMP],0b\n\t" \
+ " llgfr %[R_LEN],%[R_LEN]\n\t" \
+ " nilf %[R_LEN],7\n\t" \
+ /* Process <16bytes. */ \
+ "1: sll %[R_LEN],1\n\t" \
+ " ahik %[R_TMP],%[R_LEN],-1\n\t" \
+ " jl 20f\n\t" /* No further bytes available. */ \
+ " vll %%v16,%[R_TMP],0(%[R_IN])\n\t" \
+ " vperm %%v16,%%v16,%%v16,%%v22\n\t" \
+ " vstrchs %%v19,%%v16,%%v20,%%v21\n\t" \
+ /* Enlarge UCS2 to UCS4. */ \
+ " vuplhh %%v17,%%v16\n\t" \
+ " vupllh %%v18,%%v16\n\t" \
+ " vlgvb %[R_TMP],%%v19,7\n\t" \
+ " clr %[R_TMP],%[R_LEN]\n\t" \
+ " locgrhe %[R_TMP],%[R_LEN]\n\t" \
+ " locghihe %[R_LEN],0\n\t" \
+ " j 11f\n\t" \
+ /* v20: Vector string range compare values. */ \
+ "9: .short 0xd800,0xe000,0x0,0x0,0x0,0x0,0x0,0x0\n\t" \
+ /* v21: Vector string range compare control-bits. \
+ element 0: =>; element 1: < */ \
+ " .short 0xa000,0x4000,0x0,0x0,0x0,0x0,0x0,0x0\n\t" \
+ /* v22: Vector permute mask. */ \
+ " .short 0x0100,0x0302,0x0504,0x0706\n\t" \
+ " .short 0x0908,0x0b0a,0x0d0c,0x0f0e\n\t" \
+ /* Found an element: ch >= 0xd800 && ch < 0xe000 */ \
+ "10: vlgvb %[R_TMP],%%v19,7\n\t" \
+ "11: la %[R_IN],0(%[R_TMP],%[R_IN])\n\t" \
+ " sll %[R_TMP],1\n\t" \
+ " lgr %[R_TMP2],%[R_TMP]\n\t" \
+ " ahi %[R_TMP],-1\n\t" \
+ " jl 20f\n\t" \
+ " vstl %%v17,%[R_TMP],0(%[R_OUT])\n\t" \
+ " ahi %[R_TMP],-16\n\t" \
+ " jl 19f\n\t" \
+ " vstl %%v18,%[R_TMP],16(%[R_OUT])\n\t" \
+ "19: la %[R_OUT],0(%[R_TMP2],%[R_OUT])\n\t" \
+ "20: \n\t" \
+ ".machine pop" \
+ : /* outputs */ [R_OUT] "+a" (outptr) \
+ , [R_IN] "+a" (inptr) \
+ , [R_TMP] "=a" (tmp) \
+ , [R_TMP2] "=a" (tmp2) \
+ , [R_LEN] "+d" (len) \
+ : /* inputs */ \
+ : /* clobber list*/ "memory", "cc" \
+ ASM_CLOBBER_VR ("v16") ASM_CLOBBER_VR ("v17") \
+ ASM_CLOBBER_VR ("v18") ASM_CLOBBER_VR ("v19") \
+ ASM_CLOBBER_VR ("v20") ASM_CLOBBER_VR ("v21") \
+ ASM_CLOBBER_VR ("v22") \
+ ); \
+ if (len > 0) \
+ { \
+ /* Found an invalid character at next input-char. */ \
+ BODY_ORIG_ERROR \
+ } \
+ }
+# define LOOP_NEED_FLAGS
+# include <iconv/loop.c>
+# include <iconv/skeleton.c>
+# undef BODY_ORIG
+# undef BODY_ORIG_ERROR
+ICONV_VX_IFUNC (__gconv_transform_ucs2reverse_internal)
+
+/* Convert from the internal (UCS4-like) format to UCS2. */
+#define DEFINE_INIT 0
+#define DEFINE_FINI 0
+#define MIN_NEEDED_FROM 4
+#define MIN_NEEDED_TO 2
+#define FROM_DIRECTION 1
+#define FROM_LOOP ICONV_VX_NAME (internal_ucs2_loop)
+#define TO_LOOP ICONV_VX_NAME (internal_ucs2_loop) /* This is not used. */
+#define FUNCTION_NAME ICONV_VX_NAME (__gconv_transform_internal_ucs2)
+#define ONE_DIRECTION 1
+
+#define MIN_NEEDED_INPUT MIN_NEEDED_FROM
+#define MIN_NEEDED_OUTPUT MIN_NEEDED_TO
+#define LOOPFCT FROM_LOOP
+#define BODY_ORIG \
+ { \
+ uint32_t val = *((const uint32_t *) inptr); \
+ \
+ if (__glibc_unlikely (val >= 0x10000)) \
+ { \
+ UNICODE_TAG_HANDLER (val, 4); \
+ STANDARD_TO_LOOP_ERR_HANDLER (4); \
+ } \
+ else if (__glibc_unlikely (val >= 0xd800 && val < 0xe000)) \
+ { \
+ /* Surrogate characters in UCS-4 input are not valid. \
+ We must catch this, because the UCS-2 output might be \
+ interpreted as UTF-16 by other programs. If we let \
+ surrogates pass through, attackers could make a security \
+ hole exploit by synthesizing any desired plane 1-16 \
+ character. */ \
+ result = __GCONV_ILLEGAL_INPUT; \
+ if (! ignore_errors_p ()) \
+ break; \
+ inptr += 4; \
+ ++*irreversible; \
+ continue; \
+ } \
+ else \
+ { \
+ put16 (outptr, val); \
+ outptr += sizeof (uint16_t); \
+ inptr += 4; \
+ } \
+ }
+# define BODY \
+ { \
+ if (__builtin_expect (inend - inptr < 32, 1) \
+ || outend - outptr < 16) \
+ /* Convert remaining bytes with c code. */ \
+ BODY_ORIG \
+ else \
+ { \
+ /* Convert in 32 byte blocks. */ \
+ size_t loop_count = (inend - inptr) / 32; \
+ size_t tmp, tmp2; \
+ if (loop_count > (outend - outptr) / 16) \
+ loop_count = (outend - outptr) / 16; \
+ __asm__ volatile (".machine push\n\t" \
+ ".machine \"z13\"\n\t" \
+ ".machinemode \"zarch_nohighgprs\"\n\t" \
+ CONVERT_32BIT_SIZE_T ([R_LI]) \
+ " larl %[R_I],3f\n\t" \
+ " vlm %%v20,%%v23,0(%[R_I])\n\t" \
+ "0: \n\t" \
+ " vlm %%v16,%%v17,0(%[R_IN])\n\t" \
+ /* Shorten UCS4 to UCS2. */ \
+ " vpkf %%v18,%%v16,%%v17\n\t" \
+ " vstrcfs %%v19,%%v16,%%v20,%%v21\n\t" \
+ " jno 11f\n\t" \
+ "1: vstrcfs %%v19,%%v17,%%v20,%%v21\n\t" \
+ " jno 10f\n\t" \
+ /* Store 16bytes to buf_out. */ \
+ "2: vst %%v18,0(%[R_OUT])\n\t" \
+ " la %[R_IN],32(%[R_IN])\n\t" \
+ " la %[R_OUT],16(%[R_OUT])\n\t" \
+ " brctg %[R_LI],0b\n\t" \
+ " j 20f\n\t" \
+ /* Setup to check for ch >= 0xd800. (v20, v21) */ \
+ "3: .long 0xd800,0xd800,0x0,0x0\n\t" \
+ " .long 0xa0000000,0xa0000000,0x0,0x0\n\t" \
+ /* Setup to check for ch >= 0xe000 \
+ && ch < 0x10000. (v22,v23) */ \
+ " .long 0xe000,0x10000,0x0,0x0\n\t" \
+ " .long 0xa0000000,0x40000000,0x0,0x0\n\t" \
+ /* v16 contains only valid chars. Check in v17: \
+ ch >= 0xe000 && ch <= 0xffff. */ \
+ "10: vstrcfs %%v19,%%v17,%%v22,%%v23,8\n\t" \
+ " jo 2b\n\t" /* All ch's in this range, proceed. */ \
+ " lghi %[R_TMP],16\n\t" \
+ " j 12f\n\t" \
+ /* Maybe v16 contains invalid chars. \
+ Check ch >= 0xe000 && ch <= 0xffff. */ \
+ "11: vstrcfs %%v19,%%v16,%%v22,%%v23,8\n\t" \
+ " jo 1b\n\t" /* All ch's in this range, proceed. */ \
+ " lghi %[R_TMP],0\n\t" \
+ "12: vlgvb %[R_I],%%v19,7\n\t" \
+ " agr %[R_I],%[R_TMP]\n\t" \
+ " la %[R_IN],0(%[R_I],%[R_IN])\n\t" \
+ " srl %[R_I],1\n\t" \
+ " ahi %[R_I],-1\n\t" \
+ " jl 20f\n\t" \
+ " vstl %%v18,%[R_I],0(%[R_OUT])\n\t" \
+ " la %[R_OUT],1(%[R_I],%[R_OUT])\n\t" \
+ "20:\n\t" \
+ ".machine pop" \
+ : /* outputs */ [R_OUT] "+a" (outptr) \
+ , [R_IN] "+a" (inptr) \
+ , [R_LI] "+d" (loop_count) \
+ , [R_I] "=a" (tmp2) \
+ , [R_TMP] "=d" (tmp) \
+ : /* inputs */ \
+ : /* clobber list*/ "memory", "cc" \
+ ASM_CLOBBER_VR ("v16") ASM_CLOBBER_VR ("v17") \
+ ASM_CLOBBER_VR ("v18") ASM_CLOBBER_VR ("v19") \
+ ASM_CLOBBER_VR ("v20") ASM_CLOBBER_VR ("v21") \
+ ASM_CLOBBER_VR ("v22") ASM_CLOBBER_VR ("v23") \
+ ); \
+ if (loop_count > 0) \
+ { \
+ /* Found an invalid character at next character. */ \
+ BODY_ORIG \
+ } \
+ } \
+ }
+#define LOOP_NEED_FLAGS
+#include <iconv/loop.c>
+#include <iconv/skeleton.c>
+# undef BODY_ORIG
+ICONV_VX_IFUNC (__gconv_transform_internal_ucs2)
+
+/* Convert from the internal (UCS4-like) format to UCS2 in other endianness. */
+#define DEFINE_INIT 0
+#define DEFINE_FINI 0
+#define MIN_NEEDED_FROM 4
+#define MIN_NEEDED_TO 2
+#define FROM_DIRECTION 1
+#define FROM_LOOP ICONV_VX_NAME (internal_ucs2reverse_loop)
+#define TO_LOOP ICONV_VX_NAME (internal_ucs2reverse_loop)/* This is not used.*/
+#define FUNCTION_NAME ICONV_VX_NAME (__gconv_transform_internal_ucs2reverse)
+#define ONE_DIRECTION 1
+
+#define MIN_NEEDED_INPUT MIN_NEEDED_FROM
+#define MIN_NEEDED_OUTPUT MIN_NEEDED_TO
+#define LOOPFCT FROM_LOOP
+#define BODY_ORIG \
+ { \
+ uint32_t val = *((const uint32_t *) inptr); \
+ if (__glibc_unlikely (val >= 0x10000)) \
+ { \
+ UNICODE_TAG_HANDLER (val, 4); \
+ STANDARD_TO_LOOP_ERR_HANDLER (4); \
+ } \
+ else if (__glibc_unlikely (val >= 0xd800 && val < 0xe000)) \
+ { \
+ /* Surrogate characters in UCS-4 input are not valid. \
+ We must catch this, because the UCS-2 output might be \
+ interpreted as UTF-16 by other programs. If we let \
+ surrogates pass through, attackers could make a security \
+ hole exploit by synthesizing any desired plane 1-16 \
+ character. */ \
+ if (! ignore_errors_p ()) \
+ { \
+ result = __GCONV_ILLEGAL_INPUT; \
+ break; \
+ } \
+ inptr += 4; \
+ ++*irreversible; \
+ continue; \
+ } \
+ else \
+ { \
+ put16 (outptr, bswap_16 (val)); \
+ outptr += sizeof (uint16_t); \
+ inptr += 4; \
+ } \
+ }
+# define BODY \
+ { \
+ if (__builtin_expect (inend - inptr < 32, 1) \
+ || outend - outptr < 16) \
+ /* Convert remaining bytes with c code. */ \
+ BODY_ORIG \
+ else \
+ { \
+ /* Convert in 32 byte blocks. */ \
+ size_t loop_count = (inend - inptr) / 32; \
+ size_t tmp, tmp2; \
+ if (loop_count > (outend - outptr) / 16) \
+ loop_count = (outend - outptr) / 16; \
+ __asm__ volatile (".machine push\n\t" \
+ ".machine \"z13\"\n\t" \
+ ".machinemode \"zarch_nohighgprs\"\n\t" \
+ CONVERT_32BIT_SIZE_T ([R_LI]) \
+ " larl %[R_I],3f\n\t" \
+ " vlm %%v20,%%v24,0(%[R_I])\n\t" \
+ "0: \n\t" \
+ " vlm %%v16,%%v17,0(%[R_IN])\n\t" \
+ /* Shorten UCS4 to UCS2 and byteswap. */ \
+ " vpkf %%v18,%%v16,%%v17\n\t" \
+ " vperm %%v18,%%v18,%%v18,%%v24\n\t" \
+ " vstrcfs %%v19,%%v16,%%v20,%%v21\n\t" \
+ " jno 11f\n\t" \
+ "1: vstrcfs %%v19,%%v17,%%v20,%%v21\n\t" \
+ " jno 10f\n\t" \
+ /* Store 16bytes to buf_out. */ \
+ "2: vst %%v18,0(%[R_OUT])\n\t" \
+ " la %[R_IN],32(%[R_IN])\n\t" \
+ " la %[R_OUT],16(%[R_OUT])\n\t" \
+ " brctg %[R_LI],0b\n\t" \
+ " j 20f\n\t" \
+ /* Setup to check for ch >= 0xd800. (v20, v21) */ \
+ "3: .long 0xd800,0xd800,0x0,0x0\n\t" \
+ " .long 0xa0000000,0xa0000000,0x0,0x0\n\t" \
+ /* Setup to check for ch >= 0xe000 \
+ && ch < 0x10000. (v22,v23) */ \
+ " .long 0xe000,0x10000,0x0,0x0\n\t" \
+ " .long 0xa0000000,0x40000000,0x0,0x0\n\t" \
+ /* Vector permute mask (v24) */ \
+ " .short 0x0100,0x0302,0x0504,0x0706\n\t" \
+ " .short 0x0908,0x0b0a,0x0d0c,0x0f0e\n\t" \
+ /* v16 contains only valid chars. Check in v17: \
+ ch >= 0xe000 && ch <= 0xffff. */ \
+ "10: vstrcfs %%v19,%%v17,%%v22,%%v23,8\n\t" \
+ " jo 2b\n\t" /* All ch's in this range, proceed. */ \
+ " lghi %[R_TMP],16\n\t" \
+ " j 12f\n\t" \
+ /* Maybe v16 contains invalid chars. \
+ Check ch >= 0xe000 && ch <= 0xffff. */ \
+ "11: vstrcfs %%v19,%%v16,%%v22,%%v23,8\n\t" \
+ " jo 1b\n\t" /* All ch's in this range, proceed. */ \
+ " lghi %[R_TMP],0\n\t" \
+ "12: vlgvb %[R_I],%%v19,7\n\t" \
+ " agr %[R_I],%[R_TMP]\n\t" \
+ " la %[R_IN],0(%[R_I],%[R_IN])\n\t" \
+ " srl %[R_I],1\n\t" \
+ " ahi %[R_I],-1\n\t" \
+ " jl 20f\n\t" \
+ " vstl %%v18,%[R_I],0(%[R_OUT])\n\t" \
+ " la %[R_OUT],1(%[R_I],%[R_OUT])\n\t" \
+ "20:\n\t" \
+ ".machine pop" \
+ : /* outputs */ [R_OUT] "+a" (outptr) \
+ , [R_IN] "+a" (inptr) \
+ , [R_LI] "+d" (loop_count) \
+ , [R_I] "=a" (tmp2) \
+ , [R_TMP] "=d" (tmp) \
+ : /* inputs */ \
+ : /* clobber list*/ "memory", "cc" \
+ ASM_CLOBBER_VR ("v16") ASM_CLOBBER_VR ("v17") \
+ ASM_CLOBBER_VR ("v18") ASM_CLOBBER_VR ("v19") \
+ ASM_CLOBBER_VR ("v20") ASM_CLOBBER_VR ("v21") \
+ ASM_CLOBBER_VR ("v22") ASM_CLOBBER_VR ("v23") \
+ ASM_CLOBBER_VR ("v24") \
+ ); \
+ if (loop_count > 0) \
+ { \
+ /* Found an invalid character at next character. */ \
+ BODY_ORIG \
+ } \
+ } \
+ }
+#define LOOP_NEED_FLAGS
+#include <iconv/loop.c>
+#include <iconv/skeleton.c>
+# undef BODY_ORIG
+ICONV_VX_IFUNC (__gconv_transform_internal_ucs2reverse)
+
+
+#else
+/* Generate the internal transformations without ifunc if build environment
+ lacks vector support. Instead simply include the common version. */
+# include <iconv/gconv_simple.c>
+#endif /* !defined HAVE_S390_VX_ASM_SUPPORT */
diff --git a/sysdeps/s390/multiarch/gen-8bit.sh b/sysdeps/s390/multiarch/gen-8bit.sh
new file mode 100644
index 0000000000..6f88c4bd9d
--- /dev/null
+++ b/sysdeps/s390/multiarch/gen-8bit.sh
@@ -0,0 +1,6 @@
+#!/bin/sh
+echo "static const uint8_t to_ucs1[256] = {"
+sed -ne '/^[^[:space:]]*[[:space:]]*.x00/d;/^END/q' \
+ -e 's/^<U00\(..\)>[[:space:]]*.x\(..\).*/ [0x\2] = 0x\1,/p' \
+ "$@" | sort -u
+echo "};"
diff --git a/sysdeps/s390/multiarch/iconv/skeleton.c b/sysdeps/s390/multiarch/iconv/skeleton.c
new file mode 100644
index 0000000000..8774a536ca
--- /dev/null
+++ b/sysdeps/s390/multiarch/iconv/skeleton.c
@@ -0,0 +1,21 @@
+/* Skeleton for a conversion module - S390 version.
+ Copyright (C) 2016-2018 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C 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.
+
+ The GNU C Library 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, see
+ <http://www.gnu.org/licenses/>. */
+
+#ifndef IGNORE_ICONV_SKELETON
+# include_next <iconv/skeleton.c>
+#endif
diff --git a/sysdeps/s390/multiarch/ifunc-impl-list.c b/sysdeps/s390/multiarch/ifunc-impl-list.c
index 62a435983c..ec3373ae26 100644
--- a/sysdeps/s390/multiarch/ifunc-impl-list.c
+++ b/sysdeps/s390/multiarch/ifunc-impl-list.c
@@ -1,5 +1,5 @@
/* Enumerate available IFUNC implementations of a function. s390/s390x version.
- Copyright (C) 2015-2016 Free Software Foundation, Inc.
+ Copyright (C) 2015-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -69,6 +69,13 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
S390_IS_Z10 (stfle_bits), __memcpy_z10)
IFUNC_IMPL_ADD (array, i, memcpy, 1, __memcpy_default))
+ IFUNC_IMPL (i, name, mempcpy,
+ IFUNC_IMPL_ADD (array, i, mempcpy,
+ S390_IS_Z196 (stfle_bits), ____mempcpy_z196)
+ IFUNC_IMPL_ADD (array, i, mempcpy,
+ S390_IS_Z10 (stfle_bits), ____mempcpy_z10)
+ IFUNC_IMPL_ADD (array, i, mempcpy, 1, ____mempcpy_default))
+
#endif /* SHARED */
#ifdef HAVE_S390_VX_ASM_SUPPORT
diff --git a/sysdeps/s390/multiarch/ifunc-resolve.h b/sysdeps/s390/multiarch/ifunc-resolve.h
index 744a0d8d6d..b42ed922fd 100644
--- a/sysdeps/s390/multiarch/ifunc-resolve.h
+++ b/sysdeps/s390/multiarch/ifunc-resolve.h
@@ -1,6 +1,6 @@
/* IFUNC resolver function for CPU specific functions.
32/64 bit S/390 version.
- Copyright (C) 2015-2016 Free Software Foundation, Inc.
+ Copyright (C) 2015-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -40,55 +40,51 @@
".machine pop" "\n" \
: "=QS" (STFLE_BITS), "+d" (reg0) \
: : "cc");
+#define s390_libc_ifunc_init() \
+ unsigned long long stfle_bits = 0ULL; \
+ if (__glibc_likely((dl_hwcap & HWCAP_S390_STFLE) \
+ && (dl_hwcap & HWCAP_S390_ZARCH) \
+ && (dl_hwcap & HWCAP_S390_HIGH_GPRS))) \
+ { \
+ S390_STORE_STFLE (stfle_bits); \
+ }
-#define s390_libc_ifunc(FUNC) \
- __asm__ (".globl " #FUNC "\n\t" \
- ".type " #FUNC ",@gnu_indirect_function\n\t" \
- ".set " #FUNC ",__resolve_" #FUNC "\n\t" \
- ".globl __GI_" #FUNC "\n\t" \
- ".set __GI_" #FUNC "," #FUNC "\n"); \
- \
+#define s390_libc_ifunc(TYPE_FUNC, RESOLVERFUNC, FUNC) \
/* Make the declarations of the optimized functions hidden in order
to prevent GOT slots being generated for them. */ \
- extern void *__##FUNC##_z196 attribute_hidden; \
- extern void *__##FUNC##_z10 attribute_hidden; \
- extern void *__##FUNC##_default attribute_hidden; \
- \
- void *__resolve_##FUNC (unsigned long int dl_hwcap) \
- { \
- if ((dl_hwcap & HWCAP_S390_STFLE) \
- && (dl_hwcap & HWCAP_S390_ZARCH) \
- && (dl_hwcap & HWCAP_S390_HIGH_GPRS)) \
- { \
- unsigned long long stfle_bits; \
- S390_STORE_STFLE (stfle_bits); \
- \
- if (S390_IS_Z196 (stfle_bits)) \
- return &__##FUNC##_z196; \
- else if (S390_IS_Z10 (stfle_bits)) \
- return &__##FUNC##_z10; \
- else \
- return &__##FUNC##_default; \
- } \
- else \
- return &__##FUNC##_default; \
- }
+ extern __typeof (TYPE_FUNC) RESOLVERFUNC##_z196 attribute_hidden; \
+ extern __typeof (TYPE_FUNC) RESOLVERFUNC##_z10 attribute_hidden; \
+ extern __typeof (TYPE_FUNC) RESOLVERFUNC##_default attribute_hidden; \
+ __ifunc (TYPE_FUNC, FUNC, \
+ __glibc_likely (S390_IS_Z196 (stfle_bits)) \
+ ? RESOLVERFUNC##_z196 \
+ : __glibc_likely (S390_IS_Z10 (stfle_bits)) \
+ ? RESOLVERFUNC##_z10 \
+ : RESOLVERFUNC##_default, \
+ unsigned long int dl_hwcap, s390_libc_ifunc_init);
#define s390_vx_libc_ifunc(FUNC) \
- s390_vx_libc_ifunc2(FUNC, FUNC)
+ s390_vx_libc_ifunc2_redirected(FUNC, FUNC, FUNC)
+
+#define s390_vx_libc_ifunc_redirected(TYPE_FUNC, FUNC) \
+ s390_vx_libc_ifunc2_redirected(TYPE_FUNC, FUNC, FUNC)
-#define s390_vx_libc_ifunc2(RESOLVERFUNC, FUNC) \
+#define s390_vx_libc_ifunc2(RESOLVERFUNC, FUNC) \
+ s390_vx_libc_ifunc2_redirected(FUNC, RESOLVERFUNC, FUNC)
+
+#define s390_vx_libc_ifunc_init()
+#define s390_vx_libc_ifunc2_redirected(TYPE_FUNC, RESOLVERFUNC, FUNC) \
/* Make the declarations of the optimized functions hidden in order
to prevent GOT slots being generated for them. */ \
- extern __typeof (FUNC) RESOLVERFUNC##_vx attribute_hidden; \
- extern __typeof (FUNC) RESOLVERFUNC##_c attribute_hidden; \
- extern void *__resolve_##RESOLVERFUNC (unsigned long int) __asm__ (#FUNC); \
- \
- void *__resolve_##RESOLVERFUNC (unsigned long int dl_hwcap) \
- { \
- if (dl_hwcap & HWCAP_S390_VX) \
- return &RESOLVERFUNC##_vx; \
- else \
- return &RESOLVERFUNC##_c; \
- } \
- __asm__ (".type " #FUNC ", %gnu_indirect_function");
+ extern __typeof (TYPE_FUNC) RESOLVERFUNC##_vx attribute_hidden; \
+ extern __typeof (TYPE_FUNC) RESOLVERFUNC##_c attribute_hidden; \
+ __ifunc (TYPE_FUNC, FUNC, \
+ (dl_hwcap & HWCAP_S390_VX) \
+ ? RESOLVERFUNC##_vx \
+ : RESOLVERFUNC##_c, \
+ unsigned long int dl_hwcap, s390_vx_libc_ifunc_init);
+
+#define s390_libc_ifunc_expr_init()
+#define s390_libc_ifunc_expr(TYPE_FUNC, FUNC, EXPR) \
+ __ifunc (TYPE_FUNC, FUNC, EXPR, unsigned long int hwcap, \
+ s390_libc_ifunc_expr_init);
diff --git a/sysdeps/s390/multiarch/memccpy-c.c b/sysdeps/s390/multiarch/memccpy-c.c
index 9309bd108b..1f4c548199 100644
--- a/sysdeps/s390/multiarch/memccpy-c.c
+++ b/sysdeps/s390/multiarch/memccpy-c.c
@@ -1,5 +1,5 @@
/* Default memccpy implementation for S/390.
- Copyright (C) 2015-2016 Free Software Foundation, Inc.
+ Copyright (C) 2015-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
diff --git a/sysdeps/s390/multiarch/memccpy-vx.S b/sysdeps/s390/multiarch/memccpy-vx.S
index 2db9b2cef4..150aa0e4a4 100644
--- a/sysdeps/s390/multiarch/memccpy-vx.S
+++ b/sysdeps/s390/multiarch/memccpy-vx.S
@@ -1,5 +1,5 @@
/* Vector optimized 32/64 bit S/390 version of memccpy.
- Copyright (C) 2015-2016 Free Software Foundation, Inc.
+ Copyright (C) 2015-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
diff --git a/sysdeps/s390/multiarch/memccpy.c b/sysdeps/s390/multiarch/memccpy.c
index 0a0936e340..30aae82321 100644
--- a/sysdeps/s390/multiarch/memccpy.c
+++ b/sysdeps/s390/multiarch/memccpy.c
@@ -1,5 +1,5 @@
/* Multiple versions of memccpy.
- Copyright (C) 2015-2016 Free Software Foundation, Inc.
+ Copyright (C) 2015-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
diff --git a/sysdeps/s390/multiarch/memchr-vx.S b/sysdeps/s390/multiarch/memchr-vx.S
index 875eee2b43..77d31e0036 100644
--- a/sysdeps/s390/multiarch/memchr-vx.S
+++ b/sysdeps/s390/multiarch/memchr-vx.S
@@ -1,5 +1,5 @@
/* Vector optimized 32/64 bit S/390 version of memchr.
- Copyright (C) 2015-2016 Free Software Foundation, Inc.
+ Copyright (C) 2015-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
diff --git a/sysdeps/s390/multiarch/memchr.c b/sysdeps/s390/multiarch/memchr.c
index f80de1cc1f..3885ebaa4d 100644
--- a/sysdeps/s390/multiarch/memchr.c
+++ b/sysdeps/s390/multiarch/memchr.c
@@ -1,5 +1,5 @@
/* Multiple versions of memchr.
- Copyright (C) 2015-2016 Free Software Foundation, Inc.
+ Copyright (C) 2015-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -17,8 +17,11 @@
<http://www.gnu.org/licenses/>. */
#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)
+# define memchr __redirect_memchr
# include <string.h>
+# undef memchr
# include <ifunc-resolve.h>
-s390_vx_libc_ifunc2 (__memchr, memchr)
+s390_vx_libc_ifunc2_redirected (__redirect_memchr, __memchr, memchr)
+
#endif
diff --git a/sysdeps/s390/multiarch/mempcpy.c b/sysdeps/s390/multiarch/mempcpy.c
new file mode 100644
index 0000000000..363fe47aef
--- /dev/null
+++ b/sysdeps/s390/multiarch/mempcpy.c
@@ -0,0 +1,32 @@
+/* Multiple versions of mempcpy.
+ Copyright (C) 2016-2018 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C 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.
+
+ The GNU C Library 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, see
+ <http://www.gnu.org/licenses/>. */
+
+
+#if defined SHARED && IS_IN (libc)
+# define mempcpy __redirect_mempcpy
+# define __mempcpy __redirect___mempcpy
+# define __NO_STRING_INLINES
+# define NO_MEMPCPY_STPCPY_REDIRECT
+# include <string.h>
+# undef mempcpy
+# undef __mempcpy
+# include <ifunc-resolve.h>
+
+s390_libc_ifunc (__redirect___mempcpy, ____mempcpy, __mempcpy)
+weak_alias (__mempcpy, mempcpy);
+#endif
diff --git a/sysdeps/s390/multiarch/memrchr-c.c b/sysdeps/s390/multiarch/memrchr-c.c
index af54097376..1e3c914a5d 100644
--- a/sysdeps/s390/multiarch/memrchr-c.c
+++ b/sysdeps/s390/multiarch/memrchr-c.c
@@ -1,5 +1,5 @@
/* Default memrchr implementation for S/390.
- Copyright (C) 2015-2016 Free Software Foundation, Inc.
+ Copyright (C) 2015-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
diff --git a/sysdeps/s390/multiarch/memrchr-vx.S b/sysdeps/s390/multiarch/memrchr-vx.S
index fdb8c30ebe..8e81f5ed75 100644
--- a/sysdeps/s390/multiarch/memrchr-vx.S
+++ b/sysdeps/s390/multiarch/memrchr-vx.S
@@ -1,5 +1,5 @@
/* Vector optimized 32/64 bit S/390 version of memrchr.
- Copyright (C) 2015-2016 Free Software Foundation, Inc.
+ Copyright (C) 2015-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
diff --git a/sysdeps/s390/multiarch/memrchr.c b/sysdeps/s390/multiarch/memrchr.c
index 7681890d01..43a44abcf6 100644
--- a/sysdeps/s390/multiarch/memrchr.c
+++ b/sysdeps/s390/multiarch/memrchr.c
@@ -1,5 +1,5 @@
/* Multiple versions of memrchr.
- Copyright (C) 2015-2016 Free Software Foundation, Inc.
+ Copyright (C) 2015-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
diff --git a/sysdeps/s390/multiarch/rawmemchr-c.c b/sysdeps/s390/multiarch/rawmemchr-c.c
index 20dcdb5a28..f43c883a76 100644
--- a/sysdeps/s390/multiarch/rawmemchr-c.c
+++ b/sysdeps/s390/multiarch/rawmemchr-c.c
@@ -1,5 +1,5 @@
/* Default rawmemchr implementation for S/390.
- Copyright (C) 2015-2016 Free Software Foundation, Inc.
+ Copyright (C) 2015-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
diff --git a/sysdeps/s390/multiarch/rawmemchr-vx.S b/sysdeps/s390/multiarch/rawmemchr-vx.S
index 5af2419e98..d5778be068 100644
--- a/sysdeps/s390/multiarch/rawmemchr-vx.S
+++ b/sysdeps/s390/multiarch/rawmemchr-vx.S
@@ -1,5 +1,5 @@
/* Vector optimized 32/64 bit S/390 version of rawmemchr.
- Copyright (C) 2015-2016 Free Software Foundation, Inc.
+ Copyright (C) 2015-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
diff --git a/sysdeps/s390/multiarch/rawmemchr.c b/sysdeps/s390/multiarch/rawmemchr.c
index 7186ccd9d4..5fdb2252df 100644
--- a/sysdeps/s390/multiarch/rawmemchr.c
+++ b/sysdeps/s390/multiarch/rawmemchr.c
@@ -1,5 +1,5 @@
/* Multiple versions of rawmemchr.
- Copyright (C) 2015-2016 Free Software Foundation, Inc.
+ Copyright (C) 2015-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -17,10 +17,13 @@
<http://www.gnu.org/licenses/>. */
#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)
+# define __rawmemchr __redirect___rawmemchr
# include <string.h>
+# undef __rawmemchr
# include <ifunc-resolve.h>
-s390_vx_libc_ifunc (__rawmemchr)
+s390_vx_libc_ifunc2_redirected (__redirect___rawmemchr, __rawmemchr
+ , __rawmemchr)
weak_alias (__rawmemchr, rawmemchr)
#else
diff --git a/sysdeps/s390/multiarch/stpcpy-c.c b/sysdeps/s390/multiarch/stpcpy-c.c
index 85a8a93c7f..4a1c3e5832 100644
--- a/sysdeps/s390/multiarch/stpcpy-c.c
+++ b/sysdeps/s390/multiarch/stpcpy-c.c
@@ -1,5 +1,5 @@
/* Default stpcpy implementation for S/390.
- Copyright (C) 2015-2016 Free Software Foundation, Inc.
+ Copyright (C) 2015-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
diff --git a/sysdeps/s390/multiarch/stpcpy-vx.S b/sysdeps/s390/multiarch/stpcpy-vx.S
index da9f2760de..6c17def0fc 100644
--- a/sysdeps/s390/multiarch/stpcpy-vx.S
+++ b/sysdeps/s390/multiarch/stpcpy-vx.S
@@ -1,5 +1,5 @@
/* Vector optimized 32/64 bit S/390 version of stpcpy.
- Copyright (C) 2015-2016 Free Software Foundation, Inc.
+ Copyright (C) 2015-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
diff --git a/sysdeps/s390/multiarch/stpcpy.c b/sysdeps/s390/multiarch/stpcpy.c
index dcde01278b..654f9dfbef 100644
--- a/sysdeps/s390/multiarch/stpcpy.c
+++ b/sysdeps/s390/multiarch/stpcpy.c
@@ -1,5 +1,5 @@
/* Multiple versions of stpcpy.
- Copyright (C) 2015-2016 Free Software Foundation, Inc.
+ Copyright (C) 2015-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -17,13 +17,18 @@
<http://www.gnu.org/licenses/>. */
#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)
+# define stpcpy __redirect_stpcpy
+# define __stpcpy __redirect___stpcpy
+/* Omit the stpcpy inline definitions because it would redefine stpcpy. */
+# define __NO_STRING_INLINES
# define NO_MEMPCPY_STPCPY_REDIRECT
# include <string.h>
+# undef stpcpy
+# undef __stpcpy
# include <ifunc-resolve.h>
-s390_vx_libc_ifunc (__stpcpy)
+s390_vx_libc_ifunc_redirected (__redirect___stpcpy, __stpcpy);
weak_alias (__stpcpy, stpcpy)
-libc_hidden_builtin_def (stpcpy)
#else
# include <string/stpcpy.c>
diff --git a/sysdeps/s390/multiarch/stpncpy-c.c b/sysdeps/s390/multiarch/stpncpy-c.c
index 32b61a8e3e..45e50aa9e7 100644
--- a/sysdeps/s390/multiarch/stpncpy-c.c
+++ b/sysdeps/s390/multiarch/stpncpy-c.c
@@ -1,5 +1,5 @@
/* Default stpncpy implementation for S/390.
- Copyright (C) 2015-2016 Free Software Foundation, Inc.
+ Copyright (C) 2015-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
diff --git a/sysdeps/s390/multiarch/stpncpy-vx.S b/sysdeps/s390/multiarch/stpncpy-vx.S
index 2e536d9e0f..922bd7a355 100644
--- a/sysdeps/s390/multiarch/stpncpy-vx.S
+++ b/sysdeps/s390/multiarch/stpncpy-vx.S
@@ -1,5 +1,5 @@
/* Vector optimized 32/64 bit S/390 version of stpncpy.
- Copyright (C) 2015-2016 Free Software Foundation, Inc.
+ Copyright (C) 2015-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
diff --git a/sysdeps/s390/multiarch/stpncpy.c b/sysdeps/s390/multiarch/stpncpy.c
index f5335b42ac..f7f9d51a50 100644
--- a/sysdeps/s390/multiarch/stpncpy.c
+++ b/sysdeps/s390/multiarch/stpncpy.c
@@ -1,5 +1,5 @@
/* Multiple versions of stpncpy.
- Copyright (C) 2015-2016 Free Software Foundation, Inc.
+ Copyright (C) 2015-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -17,10 +17,14 @@
<http://www.gnu.org/licenses/>. */
#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)
+# define stpncpy __redirect_stpncpy
+# define __stpncpy __redirect___stpncpy
# include <string.h>
+# undef stpncpy
+# undef __stpncpy
# include <ifunc-resolve.h>
-s390_vx_libc_ifunc (__stpncpy)
+s390_vx_libc_ifunc_redirected (__redirect___stpncpy, __stpncpy)
weak_alias (__stpncpy, stpncpy)
#else
diff --git a/sysdeps/s390/multiarch/strcat-c.c b/sysdeps/s390/multiarch/strcat-c.c
index ae7cc2149d..f871faa7b5 100644
--- a/sysdeps/s390/multiarch/strcat-c.c
+++ b/sysdeps/s390/multiarch/strcat-c.c
@@ -1,5 +1,5 @@
/* Default strcat implementation for S/390.
- Copyright (C) 2015-2016 Free Software Foundation, Inc.
+ Copyright (C) 2015-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
diff --git a/sysdeps/s390/multiarch/strcat-vx.S b/sysdeps/s390/multiarch/strcat-vx.S
index e77fc2aa2f..3abbbccced 100644
--- a/sysdeps/s390/multiarch/strcat-vx.S
+++ b/sysdeps/s390/multiarch/strcat-vx.S
@@ -1,5 +1,5 @@
/* Vector optimized 32/64 bit S/390 version of strcat.
- Copyright (C) 2015-2016 Free Software Foundation, Inc.
+ Copyright (C) 2015-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
diff --git a/sysdeps/s390/multiarch/strcat.c b/sysdeps/s390/multiarch/strcat.c
index c3b5e1c9d6..7d4126b44f 100644
--- a/sysdeps/s390/multiarch/strcat.c
+++ b/sysdeps/s390/multiarch/strcat.c
@@ -1,5 +1,5 @@
/* Multiple versions of strcat.
- Copyright (C) 2015-2016 Free Software Foundation, Inc.
+ Copyright (C) 2015-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -17,10 +17,12 @@
<http://www.gnu.org/licenses/>. */
#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)
+# define strcat __redirect_strcat
# include <string.h>
+# undef strcat
# include <ifunc-resolve.h>
-s390_vx_libc_ifunc2 (__strcat, strcat)
+s390_vx_libc_ifunc2_redirected (__redirect_strcat, __strcat, strcat)
#else
# include <string/strcat.c>
diff --git a/sysdeps/s390/multiarch/strchr-c.c b/sysdeps/s390/multiarch/strchr-c.c
index 2250dbbf5e..606cb56788 100644
--- a/sysdeps/s390/multiarch/strchr-c.c
+++ b/sysdeps/s390/multiarch/strchr-c.c
@@ -1,5 +1,5 @@
/* Default strchr implementation for S/390.
- Copyright (C) 2015-2016 Free Software Foundation, Inc.
+ Copyright (C) 2015-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
diff --git a/sysdeps/s390/multiarch/strchr-vx.S b/sysdeps/s390/multiarch/strchr-vx.S
index 4fe5dc0293..6e744fb82f 100644
--- a/sysdeps/s390/multiarch/strchr-vx.S
+++ b/sysdeps/s390/multiarch/strchr-vx.S
@@ -1,5 +1,5 @@
/* Vector optimized 32/64 bit S/390 version of strchr.
- Copyright (C) 2015-2016 Free Software Foundation, Inc.
+ Copyright (C) 2015-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
diff --git a/sysdeps/s390/multiarch/strchr.c b/sysdeps/s390/multiarch/strchr.c
index 3c8c7e4600..8aa33a51cc 100644
--- a/sysdeps/s390/multiarch/strchr.c
+++ b/sysdeps/s390/multiarch/strchr.c
@@ -1,5 +1,5 @@
/* Multiple versions of strchr.
- Copyright (C) 2015-2016 Free Software Foundation, Inc.
+ Copyright (C) 2015-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -17,10 +17,14 @@
<http://www.gnu.org/licenses/>. */
#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)
+# define strchr __redirect_strchr
+/* Omit the strchr inline definitions because it would redefine strchr. */
+# define __NO_STRING_INLINES
# include <string.h>
+# undef strchr
# include <ifunc-resolve.h>
-s390_vx_libc_ifunc2 (__strchr, strchr)
+s390_vx_libc_ifunc2_redirected (__redirect_strchr, __strchr, strchr)
weak_alias (strchr, index)
#else
diff --git a/sysdeps/s390/multiarch/strchrnul-c.c b/sysdeps/s390/multiarch/strchrnul-c.c
index 1f77c40cea..020cebcf3e 100644
--- a/sysdeps/s390/multiarch/strchrnul-c.c
+++ b/sysdeps/s390/multiarch/strchrnul-c.c
@@ -1,5 +1,5 @@
/* Default strchrnul implementation for S/390.
- Copyright (C) 2015-2016 Free Software Foundation, Inc.
+ Copyright (C) 2015-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
diff --git a/sysdeps/s390/multiarch/strchrnul-vx.S b/sysdeps/s390/multiarch/strchrnul-vx.S
index 43ca29ead0..d561825e04 100644
--- a/sysdeps/s390/multiarch/strchrnul-vx.S
+++ b/sysdeps/s390/multiarch/strchrnul-vx.S
@@ -1,5 +1,5 @@
/* Vector optimized 32/64 bit S/390 version of strchrnul.
- Copyright (C) 2015-2016 Free Software Foundation, Inc.
+ Copyright (C) 2015-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
diff --git a/sysdeps/s390/multiarch/strchrnul.c b/sysdeps/s390/multiarch/strchrnul.c
index 627c084521..62dfc6bd90 100644
--- a/sysdeps/s390/multiarch/strchrnul.c
+++ b/sysdeps/s390/multiarch/strchrnul.c
@@ -1,5 +1,5 @@
/* Multiple versions of strchrnul.
- Copyright (C) 2015-2016 Free Software Foundation, Inc.
+ Copyright (C) 2015-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
diff --git a/sysdeps/s390/multiarch/strcmp-vx.S b/sysdeps/s390/multiarch/strcmp-vx.S
index edf557b5eb..bcaeb564d4 100644
--- a/sysdeps/s390/multiarch/strcmp-vx.S
+++ b/sysdeps/s390/multiarch/strcmp-vx.S
@@ -1,5 +1,5 @@
/* Vector optimized 32/64 bit S/390 version of strcmp.
- Copyright (C) 2015-2016 Free Software Foundation, Inc.
+ Copyright (C) 2015-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
diff --git a/sysdeps/s390/multiarch/strcmp.c b/sysdeps/s390/multiarch/strcmp.c
index c4ccd34420..7c8b17b304 100644
--- a/sysdeps/s390/multiarch/strcmp.c
+++ b/sysdeps/s390/multiarch/strcmp.c
@@ -1,5 +1,5 @@
/* Multiple versions of strcmp.
- Copyright (C) 2015-2016 Free Software Foundation, Inc.
+ Copyright (C) 2015-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -17,10 +17,13 @@
<http://www.gnu.org/licenses/>. */
#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)
+# define strcmp __redirect_strcmp
+/* Omit the strcmp inline definitions because it would redefine strcmp. */
+# define __NO_STRING_INLINES
# include <string.h>
# include <ifunc-resolve.h>
+# undef strcmp
+s390_vx_libc_ifunc2_redirected (__redirect_strcmp, __strcmp, strcmp)
-# undef strcmp
-s390_vx_libc_ifunc2 (__strcmp, strcmp)
#endif
diff --git a/sysdeps/s390/multiarch/strcpy-vx.S b/sysdeps/s390/multiarch/strcpy-vx.S
index d3472b821d..52197f57f7 100644
--- a/sysdeps/s390/multiarch/strcpy-vx.S
+++ b/sysdeps/s390/multiarch/strcpy-vx.S
@@ -1,5 +1,5 @@
/* Vector optimized 32/64 bit S/390 version of strcpy.
- Copyright (C) 2015-2016 Free Software Foundation, Inc.
+ Copyright (C) 2015-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
diff --git a/sysdeps/s390/multiarch/strcpy.c b/sysdeps/s390/multiarch/strcpy.c
index f348199112..8f32a13f67 100644
--- a/sysdeps/s390/multiarch/strcpy.c
+++ b/sysdeps/s390/multiarch/strcpy.c
@@ -1,5 +1,5 @@
/* Multiple versions of strcpy.
- Copyright (C) 2015-2016 Free Software Foundation, Inc.
+ Copyright (C) 2015-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -17,8 +17,11 @@
<http://www.gnu.org/licenses/>. */
#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)
+# define strcpy __redirect_strcpy
# include <string.h>
+# undef strcpy
# include <ifunc-resolve.h>
-s390_vx_libc_ifunc2 (__strcpy, strcpy)
+s390_vx_libc_ifunc2_redirected (__redirect_strcpy, __strcpy, strcpy)
+
#endif
diff --git a/sysdeps/s390/multiarch/strcspn-c.c b/sysdeps/s390/multiarch/strcspn-c.c
index bc195b6625..7b454f5b56 100644
--- a/sysdeps/s390/multiarch/strcspn-c.c
+++ b/sysdeps/s390/multiarch/strcspn-c.c
@@ -1,5 +1,5 @@
/* Default strcspn implementation for S/390.
- Copyright (C) 2015-2016 Free Software Foundation, Inc.
+ Copyright (C) 2015-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
diff --git a/sysdeps/s390/multiarch/strcspn-vx.S b/sysdeps/s390/multiarch/strcspn-vx.S
index 1c6250661e..ea1668742b 100644
--- a/sysdeps/s390/multiarch/strcspn-vx.S
+++ b/sysdeps/s390/multiarch/strcspn-vx.S
@@ -1,5 +1,5 @@
/* Vector optimized 32/64 bit S/390 version of strcspn.
- Copyright (C) 2015-2016 Free Software Foundation, Inc.
+ Copyright (C) 2015-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
diff --git a/sysdeps/s390/multiarch/strcspn.c b/sysdeps/s390/multiarch/strcspn.c
index c23452a791..418ffcdded 100644
--- a/sysdeps/s390/multiarch/strcspn.c
+++ b/sysdeps/s390/multiarch/strcspn.c
@@ -1,5 +1,5 @@
/* Multiple versions of strcspn.
- Copyright (C) 2015-2016 Free Software Foundation, Inc.
+ Copyright (C) 2015-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -17,10 +17,14 @@
<http://www.gnu.org/licenses/>. */
#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)
+# define strcspn __redirect_strcspn
+/* Omit the strcspn inline definitions because it would redefine strcspn. */
+# define __NO_STRING_INLINES
# include <string.h>
+# undef strcspn
# include <ifunc-resolve.h>
-s390_vx_libc_ifunc2 (__strcspn, strcspn)
+s390_vx_libc_ifunc2_redirected (__redirect_strcspn, __strcspn, strcspn)
#else
# include <string/strcspn.c>
diff --git a/sysdeps/s390/multiarch/strlen-c.c b/sysdeps/s390/multiarch/strlen-c.c
index 63c0d9e3e6..a2c8e43624 100644
--- a/sysdeps/s390/multiarch/strlen-c.c
+++ b/sysdeps/s390/multiarch/strlen-c.c
@@ -1,5 +1,5 @@
/* Default strlen implementation for S/390.
- Copyright (C) 2015-2016 Free Software Foundation, Inc.
+ Copyright (C) 2015-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
diff --git a/sysdeps/s390/multiarch/strlen-vx.S b/sysdeps/s390/multiarch/strlen-vx.S
index 3fe834a0c7..9308b33237 100644
--- a/sysdeps/s390/multiarch/strlen-vx.S
+++ b/sysdeps/s390/multiarch/strlen-vx.S
@@ -1,5 +1,5 @@
/* Vector optimized 32/64 bit S/390 version of strlen.
- Copyright (C) 2015-2016 Free Software Foundation, Inc.
+ Copyright (C) 2015-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
diff --git a/sysdeps/s390/multiarch/strlen.c b/sysdeps/s390/multiarch/strlen.c
index 098d4e1e58..0edf8b7d02 100644
--- a/sysdeps/s390/multiarch/strlen.c
+++ b/sysdeps/s390/multiarch/strlen.c
@@ -1,5 +1,5 @@
/* Multiple versions of strlen.
- Copyright (C) 2015-2016 Free Software Foundation, Inc.
+ Copyright (C) 2015-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -17,10 +17,12 @@
<http://www.gnu.org/licenses/>. */
#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)
+# define strlen __redirect_strlen
# include <string.h>
# include <ifunc-resolve.h>
+# undef strlen
-s390_vx_libc_ifunc2 (__strlen, strlen)
+s390_vx_libc_ifunc2_redirected (__redirect_strlen, __strlen, strlen)
#else
# include <string/strlen.c>
diff --git a/sysdeps/s390/multiarch/strncat-c.c b/sysdeps/s390/multiarch/strncat-c.c
index 538b1fa51e..9e6c245ccb 100644
--- a/sysdeps/s390/multiarch/strncat-c.c
+++ b/sysdeps/s390/multiarch/strncat-c.c
@@ -1,5 +1,5 @@
/* Default strncat implementation for S/390.
- Copyright (C) 2015-2016 Free Software Foundation, Inc.
+ Copyright (C) 2015-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -18,6 +18,6 @@
#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)
# define STRNCAT __strncat_c
-
+# define STRNCAT_PRIMARY
# include <string/strncat.c>
#endif
diff --git a/sysdeps/s390/multiarch/strncat-vx.S b/sysdeps/s390/multiarch/strncat-vx.S
index b9857c1233..e6584d0f43 100644
--- a/sysdeps/s390/multiarch/strncat-vx.S
+++ b/sysdeps/s390/multiarch/strncat-vx.S
@@ -1,5 +1,5 @@
/* Vector optimized 32/64 bit S/390 version of strncat.
- Copyright (C) 2015-2016 Free Software Foundation, Inc.
+ Copyright (C) 2015-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
diff --git a/sysdeps/s390/multiarch/strncat.c b/sysdeps/s390/multiarch/strncat.c
index eb1410d5ac..94b8dffa85 100644
--- a/sysdeps/s390/multiarch/strncat.c
+++ b/sysdeps/s390/multiarch/strncat.c
@@ -1,5 +1,5 @@
/* Multiple versions of strncat.
- Copyright (C) 2015-2016 Free Software Foundation, Inc.
+ Copyright (C) 2015-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
diff --git a/sysdeps/s390/multiarch/strncmp-c.c b/sysdeps/s390/multiarch/strncmp-c.c
index e781aefbe3..e54277ec1b 100644
--- a/sysdeps/s390/multiarch/strncmp-c.c
+++ b/sysdeps/s390/multiarch/strncmp-c.c
@@ -1,5 +1,5 @@
/* Default strncmp implementation for S/390.
- Copyright (C) 2015-2016 Free Software Foundation, Inc.
+ Copyright (C) 2015-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
diff --git a/sysdeps/s390/multiarch/strncmp-vx.S b/sysdeps/s390/multiarch/strncmp-vx.S
index 9c4b207f41..168fd657da 100644
--- a/sysdeps/s390/multiarch/strncmp-vx.S
+++ b/sysdeps/s390/multiarch/strncmp-vx.S
@@ -1,5 +1,5 @@
/* Vector optimized 32/64 bit S/390 version of strncmp.
- Copyright (C) 2015-2016 Free Software Foundation, Inc.
+ Copyright (C) 2015-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
diff --git a/sysdeps/s390/multiarch/strncmp.c b/sysdeps/s390/multiarch/strncmp.c
index 9a72c79bfd..0ec472c3b0 100644
--- a/sysdeps/s390/multiarch/strncmp.c
+++ b/sysdeps/s390/multiarch/strncmp.c
@@ -1,5 +1,5 @@
/* Multiple versions of strncmp.
- Copyright (C) 2015-2016 Free Software Foundation, Inc.
+ Copyright (C) 2015-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -17,13 +17,14 @@
<http://www.gnu.org/licenses/>. */
#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)
+# define strncmp __redirect_strncmp
+/* Omit the strncmp inline definitions because it would redefine strncmp. */
+# define __NO_STRING_INLINES
# include <string.h>
+# undef strncmp
# include <ifunc-resolve.h>
-
-# undef strcmp
-extern __typeof (strncmp) __strncmp;
-s390_vx_libc_ifunc2 (__strncmp, strncmp)
+s390_vx_libc_ifunc2_redirected (__redirect_strncmp, __strncmp, strncmp)
#else
# include <string/strncmp.c>
diff --git a/sysdeps/s390/multiarch/strncpy-vx.S b/sysdeps/s390/multiarch/strncpy-vx.S
index 08a0b29e8b..2a37b7b84e 100644
--- a/sysdeps/s390/multiarch/strncpy-vx.S
+++ b/sysdeps/s390/multiarch/strncpy-vx.S
@@ -1,5 +1,5 @@
/* Vector optimized 32/64 bit S/390 version of strncpy.
- Copyright (C) 2015-2016 Free Software Foundation, Inc.
+ Copyright (C) 2015-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
diff --git a/sysdeps/s390/multiarch/strncpy.c b/sysdeps/s390/multiarch/strncpy.c
index 1464551875..2d4c456d96 100644
--- a/sysdeps/s390/multiarch/strncpy.c
+++ b/sysdeps/s390/multiarch/strncpy.c
@@ -1,5 +1,5 @@
/* Multiple versions of strncpy.
- Copyright (C) 2015-2016 Free Software Foundation, Inc.
+ Copyright (C) 2015-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -17,8 +17,13 @@
<http://www.gnu.org/licenses/>. */
#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)
+# define strncpy __redirect_strncpy
+/* Omit the strncpy inline definitions because it would redefine strncpy. */
+# define __NO_STRING_INLINES
# include <string.h>
+# undef strncpy
# include <ifunc-resolve.h>
-s390_vx_libc_ifunc2 (__strncpy, strncpy)
+s390_vx_libc_ifunc2_redirected (__redirect_strncpy, __strncpy, strncpy);
+
#endif
diff --git a/sysdeps/s390/multiarch/strnlen-c.c b/sysdeps/s390/multiarch/strnlen-c.c
index 99ad65a103..353e83ed35 100644
--- a/sysdeps/s390/multiarch/strnlen-c.c
+++ b/sysdeps/s390/multiarch/strnlen-c.c
@@ -1,5 +1,5 @@
/* Default strnlen implementation for S/390.
- Copyright (C) 2015-2016 Free Software Foundation, Inc.
+ Copyright (C) 2015-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
diff --git a/sysdeps/s390/multiarch/strnlen-vx.S b/sysdeps/s390/multiarch/strnlen-vx.S
index 3e3a31dd9c..fc659a956c 100644
--- a/sysdeps/s390/multiarch/strnlen-vx.S
+++ b/sysdeps/s390/multiarch/strnlen-vx.S
@@ -1,5 +1,5 @@
/* Vector optimized 32/64 bit S/390 version of strnlen.
- Copyright (C) 2015-2016 Free Software Foundation, Inc.
+ Copyright (C) 2015-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
diff --git a/sysdeps/s390/multiarch/strnlen.c b/sysdeps/s390/multiarch/strnlen.c
index 48c3bb73e6..0f9cff5d69 100644
--- a/sysdeps/s390/multiarch/strnlen.c
+++ b/sysdeps/s390/multiarch/strnlen.c
@@ -1,5 +1,5 @@
/* Multiple versions of strnlen.
- Copyright (C) 2015-2016 Free Software Foundation, Inc.
+ Copyright (C) 2015-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -17,12 +17,15 @@
<http://www.gnu.org/licenses/>. */
#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)
+# define strnlen __redirect_strnlen
+# define __strnlen __redirect___strnlen
# include <string.h>
+# undef strnlen
+# undef __strnlen
# include <ifunc-resolve.h>
-s390_vx_libc_ifunc (__strnlen)
+s390_vx_libc_ifunc_redirected (__redirect___strnlen, __strnlen)
weak_alias (__strnlen, strnlen)
-libc_hidden_def (strnlen)
#else
# include <string/strnlen.c>
diff --git a/sysdeps/s390/multiarch/strpbrk-c.c b/sysdeps/s390/multiarch/strpbrk-c.c
index 49c5e1258b..2c0517aeb5 100644
--- a/sysdeps/s390/multiarch/strpbrk-c.c
+++ b/sysdeps/s390/multiarch/strpbrk-c.c
@@ -1,5 +1,5 @@
/* Default strpbrk implementation for S/390.
- Copyright (C) 2015-2016 Free Software Foundation, Inc.
+ Copyright (C) 2015-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
diff --git a/sysdeps/s390/multiarch/strpbrk-vx.S b/sysdeps/s390/multiarch/strpbrk-vx.S
index 6a0bbd9d19..e19c550ed4 100644
--- a/sysdeps/s390/multiarch/strpbrk-vx.S
+++ b/sysdeps/s390/multiarch/strpbrk-vx.S
@@ -1,5 +1,5 @@
/* Vector optimized 32/64 bit S/390 version of strpbrk.
- Copyright (C) 2015-2016 Free Software Foundation, Inc.
+ Copyright (C) 2015-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
diff --git a/sysdeps/s390/multiarch/strpbrk.c b/sysdeps/s390/multiarch/strpbrk.c
index cdc139929f..11afc268f7 100644
--- a/sysdeps/s390/multiarch/strpbrk.c
+++ b/sysdeps/s390/multiarch/strpbrk.c
@@ -1,5 +1,5 @@
/* Multiple versions of strpbrk.
- Copyright (C) 2015-2016 Free Software Foundation, Inc.
+ Copyright (C) 2015-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -17,10 +17,14 @@
<http://www.gnu.org/licenses/>. */
#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)
+# define strpbrk __redirect_strpbrk
+/* Omit the strpbrk inline definitions because it would redefine strpbrk. */
+# define __NO_STRING_INLINES
# include <string.h>
+# undef strpbrk
# include <ifunc-resolve.h>
-s390_vx_libc_ifunc2 (__strpbrk, strpbrk)
+s390_vx_libc_ifunc2_redirected (__redirect_strpbrk, __strpbrk, strpbrk)
#else
# include <string/strpbrk.c>
diff --git a/sysdeps/s390/multiarch/strrchr-c.c b/sysdeps/s390/multiarch/strrchr-c.c
index 2513af956d..53ceb8086f 100644
--- a/sysdeps/s390/multiarch/strrchr-c.c
+++ b/sysdeps/s390/multiarch/strrchr-c.c
@@ -1,5 +1,5 @@
/* Default strrchr implementation for S/390.
- Copyright (C) 2015-2016 Free Software Foundation, Inc.
+ Copyright (C) 2015-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
diff --git a/sysdeps/s390/multiarch/strrchr-vx.S b/sysdeps/s390/multiarch/strrchr-vx.S
index 175d2cba3c..8b3b989631 100644
--- a/sysdeps/s390/multiarch/strrchr-vx.S
+++ b/sysdeps/s390/multiarch/strrchr-vx.S
@@ -1,5 +1,5 @@
/* Vector optimized 32/64 bit S/390 version of strrchr.
- Copyright (C) 2015-2016 Free Software Foundation, Inc.
+ Copyright (C) 2015-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
diff --git a/sysdeps/s390/multiarch/strrchr.c b/sysdeps/s390/multiarch/strrchr.c
index e515d6b6e6..e00e25a3a4 100644
--- a/sysdeps/s390/multiarch/strrchr.c
+++ b/sysdeps/s390/multiarch/strrchr.c
@@ -1,5 +1,5 @@
/* Multiple versions of strrchr.
- Copyright (C) 2015-2016 Free Software Foundation, Inc.
+ Copyright (C) 2015-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -17,11 +17,13 @@
<http://www.gnu.org/licenses/>. */
#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)
+# define strrchr __redirect_strrchr
# include <string.h>
+# undef strrchr
# include <ifunc-resolve.h>
-s390_vx_libc_ifunc2 (__strrchr, strrchr)
-weak_alias (strrchr, rindex)
+s390_vx_libc_ifunc2_redirected (__redirect_strrchr, __strrchr, strrchr)
+weak_alias (strrchr, rindex);
#else
# include <string/strrchr.c>
diff --git a/sysdeps/s390/multiarch/strspn-c.c b/sysdeps/s390/multiarch/strspn-c.c
index 8928d3cc24..0efe61bfb2 100644
--- a/sysdeps/s390/multiarch/strspn-c.c
+++ b/sysdeps/s390/multiarch/strspn-c.c
@@ -1,5 +1,5 @@
/* Default strspn implementation for S/390.
- Copyright (C) 2015-2016 Free Software Foundation, Inc.
+ Copyright (C) 2015-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
diff --git a/sysdeps/s390/multiarch/strspn-vx.S b/sysdeps/s390/multiarch/strspn-vx.S
index 65d295937a..6aa823e63b 100644
--- a/sysdeps/s390/multiarch/strspn-vx.S
+++ b/sysdeps/s390/multiarch/strspn-vx.S
@@ -1,5 +1,5 @@
/* Vector optimized 32/64 bit S/390 version of strspn.
- Copyright (C) 2015-2016 Free Software Foundation, Inc.
+ Copyright (C) 2015-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
diff --git a/sysdeps/s390/multiarch/strspn.c b/sysdeps/s390/multiarch/strspn.c
index 7c26af8ced..bedbe98cfc 100644
--- a/sysdeps/s390/multiarch/strspn.c
+++ b/sysdeps/s390/multiarch/strspn.c
@@ -1,5 +1,5 @@
/* Multiple versions of strspn.
- Copyright (C) 2015-2016 Free Software Foundation, Inc.
+ Copyright (C) 2015-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -17,10 +17,14 @@
<http://www.gnu.org/licenses/>. */
#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)
+# define strspn __redirect_strspn
+/* Omit the strspn inline definitions because it would redefine strspn. */
+# define __NO_STRING_INLINES
# include <string.h>
+# undef strspn
# include <ifunc-resolve.h>
-s390_vx_libc_ifunc2 (__strspn, strspn)
+s390_vx_libc_ifunc2_redirected (__redirect_strspn, __strspn, strspn)
#else
# include <string/strspn.c>
diff --git a/sysdeps/s390/multiarch/utf16-utf32-z9.c b/sysdeps/s390/multiarch/utf16-utf32-z9.c
new file mode 100644
index 0000000000..46a23b09bf
--- /dev/null
+++ b/sysdeps/s390/multiarch/utf16-utf32-z9.c
@@ -0,0 +1,48 @@
+/* Conversion between UTF-16 and UTF-32 BE/internal - multiarch s390 version.
+
+ Copyright (C) 2017-2018 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C 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.
+
+ The GNU C Library 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, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <sysdeps/s390/utf16-utf32-z9.c>
+#include <ifunc-resolve.h>
+
+#undef FROM_LOOP
+#define FROM_LOOP __from_utf16_loop
+#undef TO_LOOP
+#define TO_LOOP __to_utf16_loop
+
+#define _SINGLE_NAME(NAME) NAME##_single
+#define SINGLE_NAME(NAME) _SINGLE_NAME(NAME)
+strong_alias (SINGLE_NAME (FROM_LOOP_DEFAULT), SINGLE_NAME (FROM_LOOP))
+strong_alias (SINGLE_NAME (TO_LOOP_DEFAULT), SINGLE_NAME (TO_LOOP))
+
+/* Generate ifunc'ed loop functions for FROM/TO_LOOP. */
+s390_libc_ifunc_expr (FROM_LOOP_DEFAULT, FROM_LOOP,
+ (HAVE_FROM_VX_CU && (hwcap & HWCAP_S390_VXE))
+ ? FROM_LOOP_VX_CU
+ : (HAVE_FROM_VX && (hwcap & HWCAP_S390_VX))
+ ? FROM_LOOP_VX
+ : FROM_LOOP_DEFAULT);
+
+s390_libc_ifunc_expr (TO_LOOP_DEFAULT, TO_LOOP,
+ (HAVE_TO_VX_CU && (hwcap & HWCAP_S390_VXE))
+ ? TO_LOOP_VX_CU
+ : (HAVE_TO_VX && (hwcap & HWCAP_S390_VX))
+ ? TO_LOOP_VX
+ : TO_LOOP_DEFAULT);
+
+#include <iconv/skeleton.c>
diff --git a/sysdeps/s390/multiarch/utf8-utf16-z9.c b/sysdeps/s390/multiarch/utf8-utf16-z9.c
new file mode 100644
index 0000000000..ad9b3fbcea
--- /dev/null
+++ b/sysdeps/s390/multiarch/utf8-utf16-z9.c
@@ -0,0 +1,50 @@
+/* Conversion between UTF-8 and UTF-16 - multiarch s390 version.
+
+ Copyright (C) 2017-2018 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C 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.
+
+ The GNU C Library 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, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <sysdeps/s390/utf8-utf16-z9.c>
+#include <ifunc-resolve.h>
+
+#undef FROM_LOOP
+#define FROM_LOOP __from_utf8_loop
+#undef TO_LOOP
+#define TO_LOOP __to_utf8_loop
+
+#define _SINGLE_NAME(NAME) NAME##_single
+#define SINGLE_NAME(NAME) _SINGLE_NAME(NAME)
+strong_alias (SINGLE_NAME (FROM_LOOP_DEFAULT), SINGLE_NAME (FROM_LOOP))
+strong_alias (SINGLE_NAME (TO_LOOP_DEFAULT), SINGLE_NAME (TO_LOOP))
+
+/* Generate ifunc'ed loop functions for FROM/TO_LOOP. */
+s390_libc_ifunc_expr (FROM_LOOP_DEFAULT, FROM_LOOP,
+ (HAVE_FROM_VX && (hwcap & HWCAP_S390_VX))
+ ? FROM_LOOP_VX
+ : (HAVE_FROM_CU && (hwcap & HWCAP_S390_ZARCH
+ && hwcap & HWCAP_S390_HIGH_GPRS
+ && hwcap & HWCAP_S390_ETF3EH))
+ ? FROM_LOOP_CU
+ : FROM_LOOP_DEFAULT);
+
+s390_libc_ifunc_expr (TO_LOOP_DEFAULT, TO_LOOP,
+ (HAVE_TO_VX_CU && (hwcap & HWCAP_S390_VXE))
+ ? TO_LOOP_VX_CU
+ : (HAVE_TO_VX && (hwcap & HWCAP_S390_VX))
+ ? TO_LOOP_VX
+ : TO_LOOP_DEFAULT);
+
+#include <iconv/skeleton.c>
diff --git a/sysdeps/s390/multiarch/utf8-utf32-z9.c b/sysdeps/s390/multiarch/utf8-utf32-z9.c
new file mode 100644
index 0000000000..011feeeea8
--- /dev/null
+++ b/sysdeps/s390/multiarch/utf8-utf32-z9.c
@@ -0,0 +1,50 @@
+/* Conversion between UTF-8 and UTF-32 - multiarch s390 version.
+
+ Copyright (C) 2017-2018 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C 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.
+
+ The GNU C Library 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, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <sysdeps/s390/utf8-utf32-z9.c>
+#include <ifunc-resolve.h>
+
+#undef FROM_LOOP
+#define FROM_LOOP __from_utf8_loop
+#undef TO_LOOP
+#define TO_LOOP __to_utf8_loop
+
+#define _SINGLE_NAME(NAME) NAME##_single
+#define SINGLE_NAME(NAME) _SINGLE_NAME(NAME)
+strong_alias (SINGLE_NAME (FROM_LOOP_DEFAULT), SINGLE_NAME (FROM_LOOP))
+strong_alias (SINGLE_NAME (TO_LOOP_DEFAULT), SINGLE_NAME (TO_LOOP))
+
+/* Generate ifunc'ed loop functions for FROM/TO_LOOP. */
+s390_libc_ifunc_expr (FROM_LOOP_DEFAULT, FROM_LOOP,
+ (HAVE_FROM_VX && (hwcap & HWCAP_S390_VX))
+ ? FROM_LOOP_VX
+ : (HAVE_FROM_CU && (hwcap & HWCAP_S390_ZARCH
+ && hwcap & HWCAP_S390_HIGH_GPRS
+ && hwcap & HWCAP_S390_ETF3EH))
+ ? FROM_LOOP_CU
+ : FROM_LOOP_DEFAULT);
+
+s390_libc_ifunc_expr (TO_LOOP_DEFAULT, TO_LOOP,
+ (HAVE_TO_VX_CU && (hwcap & HWCAP_S390_VXE))
+ ? TO_LOOP_VX_CU
+ : (HAVE_TO_VX && (hwcap & HWCAP_S390_VX))
+ ? TO_LOOP_VX
+ : TO_LOOP_DEFAULT);
+
+#include <iconv/skeleton.c>
diff --git a/sysdeps/s390/multiarch/wcpcpy-c.c b/sysdeps/s390/multiarch/wcpcpy-c.c
index b4849a3321..e3282fde19 100644
--- a/sysdeps/s390/multiarch/wcpcpy-c.c
+++ b/sysdeps/s390/multiarch/wcpcpy-c.c
@@ -1,5 +1,5 @@
/* Default wcslen implementation for S/390.
- Copyright (C) 2015-2016 Free Software Foundation, Inc.
+ Copyright (C) 2015-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
diff --git a/sysdeps/s390/multiarch/wcpcpy-vx.S b/sysdeps/s390/multiarch/wcpcpy-vx.S
index 8a466c6a37..bff6e85628 100644
--- a/sysdeps/s390/multiarch/wcpcpy-vx.S
+++ b/sysdeps/s390/multiarch/wcpcpy-vx.S
@@ -1,5 +1,5 @@
/* Vector optimized 32/64 bit S/390 version of wcpcpy.
- Copyright (C) 2015-2016 Free Software Foundation, Inc.
+ Copyright (C) 2015-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
diff --git a/sysdeps/s390/multiarch/wcpcpy.c b/sysdeps/s390/multiarch/wcpcpy.c
index 8afd98d7d4..f19d376d85 100644
--- a/sysdeps/s390/multiarch/wcpcpy.c
+++ b/sysdeps/s390/multiarch/wcpcpy.c
@@ -1,5 +1,5 @@
/* Multiple versions of wcpcpy.
- Copyright (C) 2015-2016 Free Software Foundation, Inc.
+ Copyright (C) 2015-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
diff --git a/sysdeps/s390/multiarch/wcpncpy-c.c b/sysdeps/s390/multiarch/wcpncpy-c.c
index 86db27b525..1f44bacea9 100644
--- a/sysdeps/s390/multiarch/wcpncpy-c.c
+++ b/sysdeps/s390/multiarch/wcpncpy-c.c
@@ -1,5 +1,5 @@
/* Default wcsncpy implementation for S/390.
- Copyright (C) 2015-2016 Free Software Foundation, Inc.
+ Copyright (C) 2015-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
diff --git a/sysdeps/s390/multiarch/wcpncpy-vx.S b/sysdeps/s390/multiarch/wcpncpy-vx.S
index ca0203f451..004f512e1f 100644
--- a/sysdeps/s390/multiarch/wcpncpy-vx.S
+++ b/sysdeps/s390/multiarch/wcpncpy-vx.S
@@ -1,5 +1,5 @@
/* Vector optimized 32/64 bit S/390 version of wcpncpy.
- Copyright (C) 2015-2016 Free Software Foundation, Inc.
+ Copyright (C) 2015-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
diff --git a/sysdeps/s390/multiarch/wcpncpy.c b/sysdeps/s390/multiarch/wcpncpy.c
index 13bc543a8a..b72265fbe9 100644
--- a/sysdeps/s390/multiarch/wcpncpy.c
+++ b/sysdeps/s390/multiarch/wcpncpy.c
@@ -1,5 +1,5 @@
/* Multiple versions of wcpncpy.
- Copyright (C) 2015-2016 Free Software Foundation, Inc.
+ Copyright (C) 2015-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
diff --git a/sysdeps/s390/multiarch/wcscat-c.c b/sysdeps/s390/multiarch/wcscat-c.c
index bceec55408..9a31c65a0b 100644
--- a/sysdeps/s390/multiarch/wcscat-c.c
+++ b/sysdeps/s390/multiarch/wcscat-c.c
@@ -1,5 +1,5 @@
/* Default wcscat implementation for S/390.
- Copyright (C) 2015-2016 Free Software Foundation, Inc.
+ Copyright (C) 2015-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
diff --git a/sysdeps/s390/multiarch/wcscat-vx.S b/sysdeps/s390/multiarch/wcscat-vx.S
index 8353caafa9..2164a8da41 100644
--- a/sysdeps/s390/multiarch/wcscat-vx.S
+++ b/sysdeps/s390/multiarch/wcscat-vx.S
@@ -1,5 +1,5 @@
/* Vector optimized 32/64 bit S/390 version of wcscat.
- Copyright (C) 2015-2016 Free Software Foundation, Inc.
+ Copyright (C) 2015-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
diff --git a/sysdeps/s390/multiarch/wcscat.c b/sysdeps/s390/multiarch/wcscat.c
index 8d71c2f1b9..33e4f6da3f 100644
--- a/sysdeps/s390/multiarch/wcscat.c
+++ b/sysdeps/s390/multiarch/wcscat.c
@@ -1,5 +1,5 @@
/* Multiple versions of wcscat.
- Copyright (C) 2015-2016 Free Software Foundation, Inc.
+ Copyright (C) 2015-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
diff --git a/sysdeps/s390/multiarch/wcschr-c.c b/sysdeps/s390/multiarch/wcschr-c.c
index 9ba1d5f861..8d6679c7f2 100644
--- a/sysdeps/s390/multiarch/wcschr-c.c
+++ b/sysdeps/s390/multiarch/wcschr-c.c
@@ -1,5 +1,5 @@
/* Default wcschr implementation for S/390.
- Copyright (C) 2015-2016 Free Software Foundation, Inc.
+ Copyright (C) 2015-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
diff --git a/sysdeps/s390/multiarch/wcschr-vx.S b/sysdeps/s390/multiarch/wcschr-vx.S
index ff7d1c4b4e..94e5df7f36 100644
--- a/sysdeps/s390/multiarch/wcschr-vx.S
+++ b/sysdeps/s390/multiarch/wcschr-vx.S
@@ -1,5 +1,5 @@
/* Vector optimized 32/64 bit S/390 version of wcschr.
- Copyright (C) 2015-2016 Free Software Foundation, Inc.
+ Copyright (C) 2015-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
diff --git a/sysdeps/s390/multiarch/wcschr.c b/sysdeps/s390/multiarch/wcschr.c
index fb51097cd6..f44138f771 100644
--- a/sysdeps/s390/multiarch/wcschr.c
+++ b/sysdeps/s390/multiarch/wcschr.c
@@ -1,5 +1,5 @@
/* Multiple versions of wcschr.
- Copyright (C) 2015-2016 Free Software Foundation, Inc.
+ Copyright (C) 2015-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -17,12 +17,15 @@
<http://www.gnu.org/licenses/>. */
#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)
+# define wcschr __redirect_wcschr
+# define __wcschr __redirect___wcschr
# include <wchar.h>
+# undef wcschr
+# undef __wcschr
# include <ifunc-resolve.h>
-s390_vx_libc_ifunc (__wcschr)
+s390_vx_libc_ifunc_redirected (__redirect___wcschr, __wcschr)
weak_alias (__wcschr, wcschr)
-libc_hidden_weak (wcschr)
#else
# include <wcsmbs/wcschr.c>
diff --git a/sysdeps/s390/multiarch/wcschrnul-c.c b/sysdeps/s390/multiarch/wcschrnul-c.c
index bbee3288fe..00e776a3ad 100644
--- a/sysdeps/s390/multiarch/wcschrnul-c.c
+++ b/sysdeps/s390/multiarch/wcschrnul-c.c
@@ -1,5 +1,5 @@
/* Default wcschrnul implementation for S/390.
- Copyright (C) 2015-2016 Free Software Foundation, Inc.
+ Copyright (C) 2015-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
diff --git a/sysdeps/s390/multiarch/wcschrnul-vx.S b/sysdeps/s390/multiarch/wcschrnul-vx.S
index e54e48d894..ebcd32b870 100644
--- a/sysdeps/s390/multiarch/wcschrnul-vx.S
+++ b/sysdeps/s390/multiarch/wcschrnul-vx.S
@@ -1,5 +1,5 @@
/* Vector optimized 32/64 bit S/390 version of wcschrnul.
- Copyright (C) 2015-2016 Free Software Foundation, Inc.
+ Copyright (C) 2015-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
diff --git a/sysdeps/s390/multiarch/wcschrnul.c b/sysdeps/s390/multiarch/wcschrnul.c
index 7436a596bd..807d7ee089 100644
--- a/sysdeps/s390/multiarch/wcschrnul.c
+++ b/sysdeps/s390/multiarch/wcschrnul.c
@@ -1,5 +1,5 @@
/* Multiple versions of wcschrnul.
- Copyright (C) 2015-2016 Free Software Foundation, Inc.
+ Copyright (C) 2015-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
diff --git a/sysdeps/s390/multiarch/wcscmp-c.c b/sysdeps/s390/multiarch/wcscmp-c.c
index 3add8e4095..ce0817ae97 100644
--- a/sysdeps/s390/multiarch/wcscmp-c.c
+++ b/sysdeps/s390/multiarch/wcscmp-c.c
@@ -1,5 +1,5 @@
/* Default wcscmp implementation for S/390.
- Copyright (C) 2015-2016 Free Software Foundation, Inc.
+ Copyright (C) 2015-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
diff --git a/sysdeps/s390/multiarch/wcscmp-vx.S b/sysdeps/s390/multiarch/wcscmp-vx.S
index 549ae3c733..14267dbfc7 100644
--- a/sysdeps/s390/multiarch/wcscmp-vx.S
+++ b/sysdeps/s390/multiarch/wcscmp-vx.S
@@ -1,5 +1,5 @@
/* Vector optimized 32/64 bit S/390 version of wcscmp.
- Copyright (C) 2015-2016 Free Software Foundation, Inc.
+ Copyright (C) 2015-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
diff --git a/sysdeps/s390/multiarch/wcscmp.c b/sysdeps/s390/multiarch/wcscmp.c
index 705ef4596e..5ee0fd4d88 100644
--- a/sysdeps/s390/multiarch/wcscmp.c
+++ b/sysdeps/s390/multiarch/wcscmp.c
@@ -1,5 +1,5 @@
/* Multiple versions of wcscmp.
- Copyright (C) 2015-2016 Free Software Foundation, Inc.
+ Copyright (C) 2015-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -17,10 +17,12 @@
<http://www.gnu.org/licenses/>. */
#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)
+# define __wcscmp __redirect___wcscmp
# include <wchar.h>
+# undef __wcscmp
# include <ifunc-resolve.h>
-s390_vx_libc_ifunc (__wcscmp)
+s390_vx_libc_ifunc_redirected (__redirect___wcscmp, __wcscmp)
weak_alias (__wcscmp, wcscmp)
#else
diff --git a/sysdeps/s390/multiarch/wcscpy-c.c b/sysdeps/s390/multiarch/wcscpy-c.c
index 3450c00048..4a510f466b 100644
--- a/sysdeps/s390/multiarch/wcscpy-c.c
+++ b/sysdeps/s390/multiarch/wcscpy-c.c
@@ -1,5 +1,5 @@
/* Default wcscpy implementation for S/390.
- Copyright (C) 2015-2016 Free Software Foundation, Inc.
+ Copyright (C) 2015-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
diff --git a/sysdeps/s390/multiarch/wcscpy-vx.S b/sysdeps/s390/multiarch/wcscpy-vx.S
index 2077893130..c2e81055be 100644
--- a/sysdeps/s390/multiarch/wcscpy-vx.S
+++ b/sysdeps/s390/multiarch/wcscpy-vx.S
@@ -1,5 +1,5 @@
/* Vector optimized 32/64 bit S/390 version of wcscpy.
- Copyright (C) 2015-2016 Free Software Foundation, Inc.
+ Copyright (C) 2015-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
diff --git a/sysdeps/s390/multiarch/wcscpy.c b/sysdeps/s390/multiarch/wcscpy.c
index 8c5f54910b..e69baa6c59 100644
--- a/sysdeps/s390/multiarch/wcscpy.c
+++ b/sysdeps/s390/multiarch/wcscpy.c
@@ -1,5 +1,5 @@
/* Multiple versions of wcscpy.
- Copyright (C) 2015-2016 Free Software Foundation, Inc.
+ Copyright (C) 2015-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
diff --git a/sysdeps/s390/multiarch/wcscspn-c.c b/sysdeps/s390/multiarch/wcscspn-c.c
index e8fd2a53d9..161e52e686 100644
--- a/sysdeps/s390/multiarch/wcscspn-c.c
+++ b/sysdeps/s390/multiarch/wcscspn-c.c
@@ -1,5 +1,5 @@
/* Default wcscscpn implementation for S/390.
- Copyright (C) 2015-2016 Free Software Foundation, Inc.
+ Copyright (C) 2015-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
diff --git a/sysdeps/s390/multiarch/wcscspn-vx.S b/sysdeps/s390/multiarch/wcscspn-vx.S
index b0b1066658..06bc4e25d0 100644
--- a/sysdeps/s390/multiarch/wcscspn-vx.S
+++ b/sysdeps/s390/multiarch/wcscspn-vx.S
@@ -1,5 +1,5 @@
/* Vector optimized 32/64 bit S/390 version of wcscspn.
- Copyright (C) 2015-2016 Free Software Foundation, Inc.
+ Copyright (C) 2015-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
diff --git a/sysdeps/s390/multiarch/wcscspn.c b/sysdeps/s390/multiarch/wcscspn.c
index ebd77734ac..707327522a 100644
--- a/sysdeps/s390/multiarch/wcscspn.c
+++ b/sysdeps/s390/multiarch/wcscspn.c
@@ -1,5 +1,5 @@
/* Multiple versions of wcscspn.
- Copyright (C) 2015-2016 Free Software Foundation, Inc.
+ Copyright (C) 2015-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
diff --git a/sysdeps/s390/multiarch/wcslen-c.c b/sysdeps/s390/multiarch/wcslen-c.c
index dcbe3094d9..32a23e206d 100644
--- a/sysdeps/s390/multiarch/wcslen-c.c
+++ b/sysdeps/s390/multiarch/wcslen-c.c
@@ -1,5 +1,5 @@
/* Default wcslen implementation for S/390.
- Copyright (C) 2015-2016 Free Software Foundation, Inc.
+ Copyright (C) 2015-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
diff --git a/sysdeps/s390/multiarch/wcslen-vx.S b/sysdeps/s390/multiarch/wcslen-vx.S
index dafb7b799d..337cbed6ec 100644
--- a/sysdeps/s390/multiarch/wcslen-vx.S
+++ b/sysdeps/s390/multiarch/wcslen-vx.S
@@ -1,5 +1,5 @@
/* Vector optimized 32/64 bit S/390 version of wcslen.
- Copyright (C) 2015-2016 Free Software Foundation, Inc.
+ Copyright (C) 2015-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
diff --git a/sysdeps/s390/multiarch/wcslen.c b/sysdeps/s390/multiarch/wcslen.c
index 540845f70a..3a1d1a32c9 100644
--- a/sysdeps/s390/multiarch/wcslen.c
+++ b/sysdeps/s390/multiarch/wcslen.c
@@ -1,5 +1,5 @@
/* Multiple versions of wcslen.
- Copyright (C) 2015-2016 Free Software Foundation, Inc.
+ Copyright (C) 2015-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
diff --git a/sysdeps/s390/multiarch/wcsncat-c.c b/sysdeps/s390/multiarch/wcsncat-c.c
index e8cc219eac..2cf1a76385 100644
--- a/sysdeps/s390/multiarch/wcsncat-c.c
+++ b/sysdeps/s390/multiarch/wcsncat-c.c
@@ -1,5 +1,5 @@
/* Default wcsncat implementation for S/390.
- Copyright (C) 2015-2016 Free Software Foundation, Inc.
+ Copyright (C) 2015-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
diff --git a/sysdeps/s390/multiarch/wcsncat-vx.S b/sysdeps/s390/multiarch/wcsncat-vx.S
index 4264f6d21d..1d3935690d 100644
--- a/sysdeps/s390/multiarch/wcsncat-vx.S
+++ b/sysdeps/s390/multiarch/wcsncat-vx.S
@@ -1,5 +1,5 @@
/* Vector optimized 32/64 bit S/390 version of wcsncat.
- Copyright (C) 2015-2016 Free Software Foundation, Inc.
+ Copyright (C) 2015-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
diff --git a/sysdeps/s390/multiarch/wcsncat.c b/sysdeps/s390/multiarch/wcsncat.c
index 62073321e8..c49b8ff786 100644
--- a/sysdeps/s390/multiarch/wcsncat.c
+++ b/sysdeps/s390/multiarch/wcsncat.c
@@ -1,5 +1,5 @@
/* Multiple versions of wcsncat.
- Copyright (C) 2015-2016 Free Software Foundation, Inc.
+ Copyright (C) 2015-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
diff --git a/sysdeps/s390/multiarch/wcsncmp-c.c b/sysdeps/s390/multiarch/wcsncmp-c.c
index 8f2573810d..92ab5e8b50 100644
--- a/sysdeps/s390/multiarch/wcsncmp-c.c
+++ b/sysdeps/s390/multiarch/wcsncmp-c.c
@@ -1,5 +1,5 @@
/* Default wcsncmp implementation for S/390.
- Copyright (C) 2015-2016 Free Software Foundation, Inc.
+ Copyright (C) 2015-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
diff --git a/sysdeps/s390/multiarch/wcsncmp-vx.S b/sysdeps/s390/multiarch/wcsncmp-vx.S
index e77f17dcaf..34c203bc90 100644
--- a/sysdeps/s390/multiarch/wcsncmp-vx.S
+++ b/sysdeps/s390/multiarch/wcsncmp-vx.S
@@ -1,5 +1,5 @@
/* Vector optimized 32/64 bit S/390 version of wcsncmp.
- Copyright (C) 2015-2016 Free Software Foundation, Inc.
+ Copyright (C) 2015-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
diff --git a/sysdeps/s390/multiarch/wcsncmp.c b/sysdeps/s390/multiarch/wcsncmp.c
index 3482d90e4e..ee5f08c1e4 100644
--- a/sysdeps/s390/multiarch/wcsncmp.c
+++ b/sysdeps/s390/multiarch/wcsncmp.c
@@ -1,5 +1,5 @@
/* Multiple versions of wcsncmp.
- Copyright (C) 2015-2016 Free Software Foundation, Inc.
+ Copyright (C) 2015-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
diff --git a/sysdeps/s390/multiarch/wcsncpy-c.c b/sysdeps/s390/multiarch/wcsncpy-c.c
index b63d86ef5f..6b89b8c14b 100644
--- a/sysdeps/s390/multiarch/wcsncpy-c.c
+++ b/sysdeps/s390/multiarch/wcsncpy-c.c
@@ -1,5 +1,5 @@
/* Default wcsncpy implementation for S/390.
- Copyright (C) 2015-2016 Free Software Foundation, Inc.
+ Copyright (C) 2015-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
diff --git a/sysdeps/s390/multiarch/wcsncpy-vx.S b/sysdeps/s390/multiarch/wcsncpy-vx.S
index 33cc33f28b..b3400d50d9 100644
--- a/sysdeps/s390/multiarch/wcsncpy-vx.S
+++ b/sysdeps/s390/multiarch/wcsncpy-vx.S
@@ -1,5 +1,5 @@
/* Vector optimized 32/64 bit S/390 version of wcsncpy.
- Copyright (C) 2015-2016 Free Software Foundation, Inc.
+ Copyright (C) 2015-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
diff --git a/sysdeps/s390/multiarch/wcsncpy.c b/sysdeps/s390/multiarch/wcsncpy.c
index eb225a97b4..7209c7d431 100644
--- a/sysdeps/s390/multiarch/wcsncpy.c
+++ b/sysdeps/s390/multiarch/wcsncpy.c
@@ -1,5 +1,5 @@
/* Multiple versions of wcsncpy.
- Copyright (C) 2015-2016 Free Software Foundation, Inc.
+ Copyright (C) 2015-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
diff --git a/sysdeps/s390/multiarch/wcsnlen-c.c b/sysdeps/s390/multiarch/wcsnlen-c.c
index 89984e9f18..8f43f5104f 100644
--- a/sysdeps/s390/multiarch/wcsnlen-c.c
+++ b/sysdeps/s390/multiarch/wcsnlen-c.c
@@ -1,5 +1,5 @@
/* Default wcsnlen implementation for S/390.
- Copyright (C) 2015-2016 Free Software Foundation, Inc.
+ Copyright (C) 2015-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
diff --git a/sysdeps/s390/multiarch/wcsnlen-vx.S b/sysdeps/s390/multiarch/wcsnlen-vx.S
index 1ba00c3cae..420f29fbc0 100644
--- a/sysdeps/s390/multiarch/wcsnlen-vx.S
+++ b/sysdeps/s390/multiarch/wcsnlen-vx.S
@@ -1,5 +1,5 @@
/* Vector optimized 32/64 bit S/390 version of wcsnlen.
- Copyright (C) 2015-2016 Free Software Foundation, Inc.
+ Copyright (C) 2015-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
diff --git a/sysdeps/s390/multiarch/wcsnlen.c b/sysdeps/s390/multiarch/wcsnlen.c
index 4308472a81..5234074b1f 100644
--- a/sysdeps/s390/multiarch/wcsnlen.c
+++ b/sysdeps/s390/multiarch/wcsnlen.c
@@ -1,5 +1,5 @@
/* Multiple versions of wcsnlen.
- Copyright (C) 2015-2016 Free Software Foundation, Inc.
+ Copyright (C) 2015-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
diff --git a/sysdeps/s390/multiarch/wcspbrk-c.c b/sysdeps/s390/multiarch/wcspbrk-c.c
index 8b74eaf017..6b6e7aade4 100644
--- a/sysdeps/s390/multiarch/wcspbrk-c.c
+++ b/sysdeps/s390/multiarch/wcspbrk-c.c
@@ -1,5 +1,5 @@
/* Default wcspbrk implementation for S/390.
- Copyright (C) 2015-2016 Free Software Foundation, Inc.
+ Copyright (C) 2015-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
diff --git a/sysdeps/s390/multiarch/wcspbrk-vx.S b/sysdeps/s390/multiarch/wcspbrk-vx.S
index 3e28e9aa90..5c89ec5d33 100644
--- a/sysdeps/s390/multiarch/wcspbrk-vx.S
+++ b/sysdeps/s390/multiarch/wcspbrk-vx.S
@@ -1,5 +1,5 @@
/* Vector optimized 32/64 bit S/390 version of wcspbrk.
- Copyright (C) 2015-2016 Free Software Foundation, Inc.
+ Copyright (C) 2015-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
diff --git a/sysdeps/s390/multiarch/wcspbrk.c b/sysdeps/s390/multiarch/wcspbrk.c
index 198144d2c5..97876328b5 100644
--- a/sysdeps/s390/multiarch/wcspbrk.c
+++ b/sysdeps/s390/multiarch/wcspbrk.c
@@ -1,5 +1,5 @@
/* Multiple versions of wcspbrk.
- Copyright (C) 2015-2016 Free Software Foundation, Inc.
+ Copyright (C) 2015-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -17,10 +17,12 @@
<http://www.gnu.org/licenses/>. */
#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)
+# define wcspbrk __redirect_wcspbrk
# include <wchar.h>
+# undef wcspbrk
# include <ifunc-resolve.h>
-s390_vx_libc_ifunc2 (__wcspbrk, wcspbrk)
+s390_vx_libc_ifunc2_redirected (__redirect_wcspbrk, __wcspbrk, wcspbrk)
#else
# include <wcsmbs/wcspbrk.c>
diff --git a/sysdeps/s390/multiarch/wcsrchr-c.c b/sysdeps/s390/multiarch/wcsrchr-c.c
index eac588b79e..615250358b 100644
--- a/sysdeps/s390/multiarch/wcsrchr-c.c
+++ b/sysdeps/s390/multiarch/wcsrchr-c.c
@@ -1,5 +1,5 @@
/* Default wcsrchr implementation for S/390.
- Copyright (C) 2015-2016 Free Software Foundation, Inc.
+ Copyright (C) 2015-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
diff --git a/sysdeps/s390/multiarch/wcsrchr-vx.S b/sysdeps/s390/multiarch/wcsrchr-vx.S
index 0b99edc7a5..e40a554e5d 100644
--- a/sysdeps/s390/multiarch/wcsrchr-vx.S
+++ b/sysdeps/s390/multiarch/wcsrchr-vx.S
@@ -1,5 +1,5 @@
/* Vector optimized 32/64 bit S/390 version of wcsrchr.
- Copyright (C) 2015-2016 Free Software Foundation, Inc.
+ Copyright (C) 2015-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
diff --git a/sysdeps/s390/multiarch/wcsrchr.c b/sysdeps/s390/multiarch/wcsrchr.c
index 9281e12898..aa0b8a8f82 100644
--- a/sysdeps/s390/multiarch/wcsrchr.c
+++ b/sysdeps/s390/multiarch/wcsrchr.c
@@ -1,5 +1,5 @@
/* Multiple versions of wcsrchr.
- Copyright (C) 2015-2016 Free Software Foundation, Inc.
+ Copyright (C) 2015-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
diff --git a/sysdeps/s390/multiarch/wcsspn-c.c b/sysdeps/s390/multiarch/wcsspn-c.c
index 54c2698bd8..2c0bd0f4e6 100644
--- a/sysdeps/s390/multiarch/wcsspn-c.c
+++ b/sysdeps/s390/multiarch/wcsspn-c.c
@@ -1,5 +1,5 @@
/* Default wcsspn implementation for S/390.
- Copyright (C) 2015-2016 Free Software Foundation, Inc.
+ Copyright (C) 2015-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
diff --git a/sysdeps/s390/multiarch/wcsspn-vx.S b/sysdeps/s390/multiarch/wcsspn-vx.S
index e1785ea7cf..548f2ad164 100644
--- a/sysdeps/s390/multiarch/wcsspn-vx.S
+++ b/sysdeps/s390/multiarch/wcsspn-vx.S
@@ -1,5 +1,5 @@
/* Vector optimized 32/64 bit S/390 version of wcsspn.
- Copyright (C) 2015-2016 Free Software Foundation, Inc.
+ Copyright (C) 2015-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
diff --git a/sysdeps/s390/multiarch/wcsspn.c b/sysdeps/s390/multiarch/wcsspn.c
index 167a881d13..7743144a8c 100644
--- a/sysdeps/s390/multiarch/wcsspn.c
+++ b/sysdeps/s390/multiarch/wcsspn.c
@@ -1,5 +1,5 @@
/* Multiple versions of wcsspn.
- Copyright (C) 2015-2016 Free Software Foundation, Inc.
+ Copyright (C) 2015-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -17,10 +17,12 @@
<http://www.gnu.org/licenses/>. */
#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)
+# define wcsspn __redirect_wcsspn
# include <wchar.h>
+# undef wcsspn
# include <ifunc-resolve.h>
-s390_vx_libc_ifunc2 (__wcsspn, wcsspn)
+s390_vx_libc_ifunc2_redirected (__redirect_wcsspn, __wcsspn, wcsspn)
#else
# include <wcsmbs/wcsspn.c>
diff --git a/sysdeps/s390/multiarch/wmemchr-c.c b/sysdeps/s390/multiarch/wmemchr-c.c
index 32dddc6c3d..089392b512 100644
--- a/sysdeps/s390/multiarch/wmemchr-c.c
+++ b/sysdeps/s390/multiarch/wmemchr-c.c
@@ -1,5 +1,5 @@
/* Default wmemchr implementation for S/390.
- Copyright (C) 2015-2016 Free Software Foundation, Inc.
+ Copyright (C) 2015-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
diff --git a/sysdeps/s390/multiarch/wmemchr-vx.S b/sysdeps/s390/multiarch/wmemchr-vx.S
index a729681341..db057b579a 100644
--- a/sysdeps/s390/multiarch/wmemchr-vx.S
+++ b/sysdeps/s390/multiarch/wmemchr-vx.S
@@ -1,5 +1,5 @@
/* Vector optimized 32/64 bit S/390 version of wmemchr.
- Copyright (C) 2015-2016 Free Software Foundation, Inc.
+ Copyright (C) 2015-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
diff --git a/sysdeps/s390/multiarch/wmemchr.c b/sysdeps/s390/multiarch/wmemchr.c
index f2bfe3c7a5..6b55c1d7fa 100644
--- a/sysdeps/s390/multiarch/wmemchr.c
+++ b/sysdeps/s390/multiarch/wmemchr.c
@@ -1,5 +1,5 @@
/* Multiple versions of wmemchr.
- Copyright (C) 2015-2016 Free Software Foundation, Inc.
+ Copyright (C) 2015-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -17,12 +17,15 @@
<http://www.gnu.org/licenses/>. */
#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)
+# define wmemchr __redirect_wmemchr
+# define __wmemchr __redirect___wmemchr
# include <wchar.h>
+# undef wmemchr
+# undef __wmemchr
# include <ifunc-resolve.h>
-s390_vx_libc_ifunc (__wmemchr)
+s390_vx_libc_ifunc_redirected (__redirect___wmemchr, __wmemchr)
weak_alias (__wmemchr, wmemchr)
-libc_hidden_weak (wmemchr)
#else
# include <wcsmbs/wmemchr.c>
diff --git a/sysdeps/s390/multiarch/wmemcmp-c.c b/sysdeps/s390/multiarch/wmemcmp-c.c
index 683385431e..2fd39d5013 100644
--- a/sysdeps/s390/multiarch/wmemcmp-c.c
+++ b/sysdeps/s390/multiarch/wmemcmp-c.c
@@ -1,5 +1,5 @@
/* Default wmemcmp implementation for S/390.
- Copyright (C) 2015-2016 Free Software Foundation, Inc.
+ Copyright (C) 2015-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
diff --git a/sysdeps/s390/multiarch/wmemcmp-vx.S b/sysdeps/s390/multiarch/wmemcmp-vx.S
index 761cc17771..e2fc21e419 100644
--- a/sysdeps/s390/multiarch/wmemcmp-vx.S
+++ b/sysdeps/s390/multiarch/wmemcmp-vx.S
@@ -1,5 +1,5 @@
/* Vector Optimized 32/64 bit S/390 version of wmemcmp.
- Copyright (C) 2015-2016 Free Software Foundation, Inc.
+ Copyright (C) 2015-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
diff --git a/sysdeps/s390/multiarch/wmemcmp.c b/sysdeps/s390/multiarch/wmemcmp.c
index 95106fcaf9..a4cb440c45 100644
--- a/sysdeps/s390/multiarch/wmemcmp.c
+++ b/sysdeps/s390/multiarch/wmemcmp.c
@@ -1,5 +1,5 @@
/* Multiple versions of wmemcmp.
- Copyright (C) 2015-2016 Free Software Foundation, Inc.
+ Copyright (C) 2015-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
diff --git a/sysdeps/s390/multiarch/wmemset-c.c b/sysdeps/s390/multiarch/wmemset-c.c
index 61ccd8fc09..1969cf93dc 100644
--- a/sysdeps/s390/multiarch/wmemset-c.c
+++ b/sysdeps/s390/multiarch/wmemset-c.c
@@ -1,5 +1,5 @@
/* Default wmemset implementation for S/390.
- Copyright (C) 2015-2016 Free Software Foundation, Inc.
+ Copyright (C) 2015-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
diff --git a/sysdeps/s390/multiarch/wmemset-vx.S b/sysdeps/s390/multiarch/wmemset-vx.S
index 7a28bb4ca6..0c2f6337b0 100644
--- a/sysdeps/s390/multiarch/wmemset-vx.S
+++ b/sysdeps/s390/multiarch/wmemset-vx.S
@@ -1,5 +1,5 @@
/* Vector Optimized 32/64 bit S/390 version of wmemset.
- Copyright (C) 2015-2016 Free Software Foundation, Inc.
+ Copyright (C) 2015-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
diff --git a/sysdeps/s390/multiarch/wmemset.c b/sysdeps/s390/multiarch/wmemset.c
index e9e695fc0a..149b481470 100644
--- a/sysdeps/s390/multiarch/wmemset.c
+++ b/sysdeps/s390/multiarch/wmemset.c
@@ -1,5 +1,5 @@
/* Multiple versions of wmemset.
- Copyright (C) 2015-2016 Free Software Foundation, Inc.
+ Copyright (C) 2015-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -17,12 +17,15 @@
<http://www.gnu.org/licenses/>. */
#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)
+# define wmemset __redirect_wmemset
+# define __wmemset __redirect___wmemset
# include <wchar.h>
+# undef wmemset
+# undef __wmemset
# include <ifunc-resolve.h>
-s390_vx_libc_ifunc (__wmemset)
+s390_vx_libc_ifunc_redirected (__redirect___wmemset, __wmemset)
weak_alias (__wmemset, wmemset)
-libc_hidden_weak (wmemset)
#else
# include <wcsmbs/wmemset.c>
diff --git a/sysdeps/s390/nptl/Makefile b/sysdeps/s390/nptl/Makefile
index 5734b983b0..2b0d392c06 100644
--- a/sysdeps/s390/nptl/Makefile
+++ b/sysdeps/s390/nptl/Makefile
@@ -1,4 +1,4 @@
-# Copyright (C) 2003-2016 Free Software Foundation, Inc.
+# Copyright (C) 2003-2018 Free Software Foundation, Inc.
# This file is part of the GNU C Library.
# The GNU C Library is free software; you can redistribute it and/or
@@ -20,5 +20,6 @@ gen-as-const-headers += tcb-offsets.sym
endif
ifeq ($(subdir),nptl)
-libpthread-routines += ptw-sysdep
+libpthread-routines += sysdep
+libpthread-shared-only-routines += sysdep
endif
diff --git a/sysdeps/s390/nptl/bits/pthreadtypes-arch.h b/sysdeps/s390/nptl/bits/pthreadtypes-arch.h
new file mode 100644
index 0000000000..20db42c8a0
--- /dev/null
+++ b/sysdeps/s390/nptl/bits/pthreadtypes-arch.h
@@ -0,0 +1,79 @@
+/* Copyright (C) 2003-2018 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C 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.
+
+ The GNU C Library 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, see
+ <http://www.gnu.org/licenses/>. */
+
+#ifndef _BITS_PTHREADTYPES_ARCH_H
+#define _BITS_PTHREADTYPES_ARCH_H 1
+
+#include <bits/wordsize.h>
+
+#if __WORDSIZE == 64
+# define __SIZEOF_PTHREAD_ATTR_T 56
+# define __SIZEOF_PTHREAD_MUTEX_T 40
+# define __SIZEOF_PTHREAD_RWLOCK_T 56
+# define __SIZEOF_PTHREAD_BARRIER_T 32
+#else
+# define __SIZEOF_PTHREAD_ATTR_T 36
+# define __SIZEOF_PTHREAD_MUTEX_T 24
+# define __SIZEOF_PTHREAD_RWLOCK_T 32
+# define __SIZEOF_PTHREAD_BARRIER_T 20
+#endif
+#define __SIZEOF_PTHREAD_MUTEXATTR_T 4
+#define __SIZEOF_PTHREAD_CONDATTR_T 4
+#define __SIZEOF_PTHREAD_COND_T 48
+#define __SIZEOF_PTHREAD_RWLOCKATTR_T 8
+#define __SIZEOF_PTHREAD_BARRIERATTR_T 4
+
+/* Definitions for internal mutex struct. */
+#define __PTHREAD_COMPAT_PADDING_MID
+#define __PTHREAD_COMPAT_PADDING_END
+#define __PTHREAD_MUTEX_LOCK_ELISION 1
+#define __PTHREAD_MUTEX_NUSERS_AFTER_KIND (__WORDSIZE != 64)
+#define __PTHREAD_MUTEX_USE_UNION (__WORDSIZE != 64)
+
+#define __LOCK_ALIGNMENT
+#define __ONCE_ALIGNMENT
+
+struct __pthread_rwlock_arch_t
+{
+ unsigned int __readers;
+ unsigned int __writers;
+ unsigned int __wrphase_futex;
+ unsigned int __writers_futex;
+ unsigned int __pad3;
+ unsigned int __pad4;
+#if __WORDSIZE == 64
+ int __cur_writer;
+ int __shared;
+ unsigned long int __pad1;
+ unsigned long int __pad2;
+ /* FLAGS must stay at this position in the structure to maintain
+ binary compatibility. */
+ unsigned int __flags;
+# else
+ unsigned char __pad1;
+ unsigned char __pad2;
+ unsigned char __shared;
+ /* FLAGS must stay at this position in the structure to maintain
+ binary compatibility. */
+ unsigned char __flags;
+ int __cur_writer;
+#endif
+};
+
+#define __PTHREAD_RWLOCK_ELISION_EXTRA 0
+
+#endif /* bits/pthreadtypes.h */
diff --git a/sysdeps/s390/nptl/bits/pthreadtypes.h b/sysdeps/s390/nptl/bits/pthreadtypes.h
deleted file mode 100644
index 40d10fea59..0000000000
--- a/sysdeps/s390/nptl/bits/pthreadtypes.h
+++ /dev/null
@@ -1,248 +0,0 @@
-/* Copyright (C) 2003-2016 Free Software Foundation, Inc.
- This file is part of the GNU C Library.
-
- The GNU C 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.
-
- The GNU C Library 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, see
- <http://www.gnu.org/licenses/>. */
-
-#ifndef _BITS_PTHREADTYPES_H
-#define _BITS_PTHREADTYPES_H 1
-
-#include <bits/wordsize.h>
-
-#if __WORDSIZE == 64
-# define __SIZEOF_PTHREAD_ATTR_T 56
-# define __SIZEOF_PTHREAD_MUTEX_T 40
-# define __SIZEOF_PTHREAD_MUTEXATTR_T 4
-# define __SIZEOF_PTHREAD_COND_T 48
-# define __SIZEOF_PTHREAD_CONDATTR_T 4
-# define __SIZEOF_PTHREAD_RWLOCK_T 56
-# define __SIZEOF_PTHREAD_RWLOCKATTR_T 8
-# define __SIZEOF_PTHREAD_BARRIER_T 32
-# define __SIZEOF_PTHREAD_BARRIERATTR_T 4
-#else
-# define __SIZEOF_PTHREAD_ATTR_T 36
-# define __SIZEOF_PTHREAD_MUTEX_T 24
-# define __SIZEOF_PTHREAD_MUTEXATTR_T 4
-# define __SIZEOF_PTHREAD_COND_T 48
-# define __SIZEOF_PTHREAD_CONDATTR_T 4
-# define __SIZEOF_PTHREAD_RWLOCK_T 32
-# define __SIZEOF_PTHREAD_RWLOCKATTR_T 8
-# define __SIZEOF_PTHREAD_BARRIER_T 20
-# define __SIZEOF_PTHREAD_BARRIERATTR_T 4
-#endif
-
-
-/* Thread identifiers. The structure of the attribute type is not
- exposed on purpose. */
-typedef unsigned long int pthread_t;
-
-
-union pthread_attr_t
-{
- char __size[__SIZEOF_PTHREAD_ATTR_T];
- long int __align;
-};
-#ifndef __have_pthread_attr_t
-typedef union pthread_attr_t pthread_attr_t;
-# define __have_pthread_attr_t 1
-#endif
-
-
-#if __WORDSIZE == 64
-typedef struct __pthread_internal_list
-{
- struct __pthread_internal_list *__prev;
- struct __pthread_internal_list *__next;
-} __pthread_list_t;
-#else
-typedef struct __pthread_internal_slist
-{
- struct __pthread_internal_slist *__next;
-} __pthread_slist_t;
-#endif
-
-
-/* Data structures for mutex handling. The structure of the attribute
- type is not exposed on purpose. */
-typedef union
-{
- struct __pthread_mutex_s
- {
- int __lock;
- unsigned int __count;
- int __owner;
-#if __WORDSIZE == 64
- unsigned int __nusers;
-#endif
- /* KIND must stay at this position in the structure to maintain
- binary compatibility. */
- int __kind;
-#if __WORDSIZE == 64
-# ifdef ENABLE_LOCK_ELISION
- short __spins;
- short __elision;
- /* Mutex __spins initializer used by PTHREAD_MUTEX_INITIALIZER. */
-# define __PTHREAD_SPINS 0, 0
-# else
- int __spins;
- /* Mutex __spins initializer used by PTHREAD_MUTEX_INITIALIZER. */
-# define __PTHREAD_SPINS 0
-# endif
- __pthread_list_t __list;
-# define __PTHREAD_MUTEX_HAVE_PREV 1
-#else
- unsigned int __nusers;
- __extension__ union
- {
-# ifdef ENABLE_LOCK_ELISION
- struct
- {
- short __espins;
- short __elision;
- } _d;
-# define __spins _d.__espins
-# define __elision _d.__elision
- /* Mutex __spins initializer used by PTHREAD_MUTEX_INITIALIZER. */
-# define __PTHREAD_SPINS { 0, 0 }
-# else
- int __spins;
- /* Mutex __spins initializer used by PTHREAD_MUTEX_INITIALIZER. */
-# define __PTHREAD_SPINS 0
-# endif
- __pthread_slist_t __list;
- };
-#endif
- } __data;
- char __size[__SIZEOF_PTHREAD_MUTEX_T];
- long int __align;
-} pthread_mutex_t;
-
-
-typedef union
-{
- char __size[__SIZEOF_PTHREAD_MUTEXATTR_T];
- int __align;
-} pthread_mutexattr_t;
-
-
-/* Data structure for conditional variable handling. The structure of
- the attribute type is not exposed on purpose. */
-typedef union
-{
- struct
- {
- int __lock;
- unsigned int __futex;
- __extension__ unsigned long long int __total_seq;
- __extension__ unsigned long long int __wakeup_seq;
- __extension__ unsigned long long int __woken_seq;
- void *__mutex;
- unsigned int __nwaiters;
- unsigned int __broadcast_seq;
- } __data;
- char __size[__SIZEOF_PTHREAD_COND_T];
- __extension__ long long int __align;
-} pthread_cond_t;
-
-typedef union
-{
- char __size[__SIZEOF_PTHREAD_CONDATTR_T];
- int __align;
-} pthread_condattr_t;
-
-
-/* Keys for thread-specific data */
-typedef unsigned int pthread_key_t;
-
-
-/* Once-only execution */
-typedef int pthread_once_t;
-
-
-#if defined __USE_UNIX98 || defined __USE_XOPEN2K
-/* Data structure for read-write lock variable handling. The
- structure of the attribute type is not exposed on purpose. */
-typedef union
-{
-# if __WORDSIZE == 64
- struct
- {
- int __lock;
- unsigned int __nr_readers;
- unsigned int __readers_wakeup;
- unsigned int __writer_wakeup;
- unsigned int __nr_readers_queued;
- unsigned int __nr_writers_queued;
- int __writer;
- int __shared;
- unsigned long int __pad1;
- unsigned long int __pad2;
- /* FLAGS must stay at this position in the structure to maintain
- binary compatibility. */
- unsigned int __flags;
- } __data;
-# else
- struct
- {
- int __lock;
- unsigned int __nr_readers;
- unsigned int __readers_wakeup;
- unsigned int __writer_wakeup;
- unsigned int __nr_readers_queued;
- unsigned int __nr_writers_queued;
- unsigned char __pad1;
- unsigned char __pad2;
- unsigned char __shared;
- /* FLAGS must stay at this position in the structure to maintain
- binary compatibility. */
- unsigned char __flags;
- int __writer;
- } __data;
-# endif
- char __size[__SIZEOF_PTHREAD_RWLOCK_T];
- long int __align;
-} pthread_rwlock_t;
-
-#define __PTHREAD_RWLOCK_ELISION_EXTRA 0
-
-typedef union
-{
- char __size[__SIZEOF_PTHREAD_RWLOCKATTR_T];
- long int __align;
-} pthread_rwlockattr_t;
-#endif
-
-
-#ifdef __USE_XOPEN2K
-/* POSIX spinlock data type. */
-typedef volatile int pthread_spinlock_t;
-
-
-/* POSIX barriers data type. The structure of the type is
- deliberately not exposed. */
-typedef union
-{
- char __size[__SIZEOF_PTHREAD_BARRIER_T];
- long int __align;
-} pthread_barrier_t;
-
-typedef union
-{
- char __size[__SIZEOF_PTHREAD_BARRIERATTR_T];
- int __align;
-} pthread_barrierattr_t;
-#endif
-
-
-#endif /* bits/pthreadtypes.h */
diff --git a/sysdeps/s390/nptl/bits/semaphore.h b/sysdeps/s390/nptl/bits/semaphore.h
index 0d756abc42..cb1b294922 100644
--- a/sysdeps/s390/nptl/bits/semaphore.h
+++ b/sysdeps/s390/nptl/bits/semaphore.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2003-2016 Free Software Foundation, Inc.
+/* Copyright (C) 2003-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Martin Schwidefsky <schwidefsky@de.ibm.com>, 2003.
diff --git a/sysdeps/s390/nptl/pthread-offsets.h b/sysdeps/s390/nptl/pthread-offsets.h
new file mode 100644
index 0000000000..bdda1f197e
--- /dev/null
+++ b/sysdeps/s390/nptl/pthread-offsets.h
@@ -0,0 +1,15 @@
+#include <bits/wordsize.h>
+
+#if __WORDSIZE == 64
+# define __PTHREAD_MUTEX_NUSERS_OFFSET 12
+# define __PTHREAD_MUTEX_KIND_OFFSET 16
+# define __PTHREAD_MUTEX_SPINS_OFFSET 20
+# define __PTHREAD_MUTEX_ELISION_OFFSET 22
+# define __PTHREAD_MUTEX_LIST_OFFSET 24
+#else
+# define __PTHREAD_MUTEX_NUSERS_OFFSET 16
+# define __PTHREAD_MUTEX_KIND_OFFSET 12
+# define __PTHREAD_MUTEX_SPINS_OFFSET 20
+# define __PTHREAD_MUTEX_ELISION_OFFSET 22
+# define __PTHREAD_MUTEX_LIST_OFFSET 20
+#endif
diff --git a/sysdeps/s390/nptl/pthreaddef.h b/sysdeps/s390/nptl/pthreaddef.h
index d483f11103..410ae7b896 100644
--- a/sysdeps/s390/nptl/pthreaddef.h
+++ b/sysdeps/s390/nptl/pthreaddef.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2003-2016 Free Software Foundation, Inc.
+/* Copyright (C) 2003-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
diff --git a/sysdeps/s390/nptl/tcb-offsets.sym b/sysdeps/s390/nptl/tcb-offsets.sym
index 9cfae211e0..9c1c01f353 100644
--- a/sysdeps/s390/nptl/tcb-offsets.sym
+++ b/sysdeps/s390/nptl/tcb-offsets.sym
@@ -3,5 +3,4 @@
MULTIPLE_THREADS_OFFSET offsetof (tcbhead_t, multiple_threads)
STACK_GUARD offsetof (tcbhead_t, stack_guard)
-PID offsetof (struct pthread, pid)
TID offsetof (struct pthread, tid)
diff --git a/sysdeps/s390/nptl/tls.h b/sysdeps/s390/nptl/tls.h
index e4c3ec7830..220bdfffb3 100644
--- a/sysdeps/s390/nptl/tls.h
+++ b/sysdeps/s390/nptl/tls.h
@@ -1,5 +1,5 @@
/* Definition for thread-local data handling. NPTL/s390 version.
- Copyright (C) 2003-2016 Free Software Foundation, Inc.
+ Copyright (C) 2003-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -27,19 +27,7 @@
# include <stdlib.h>
# include <list.h>
# include <kernel-features.h>
-
-
-/* Type for the dtv. */
-typedef union dtv
-{
- size_t counter;
- struct
- {
- void *val;
- bool is_static;
- } pointer;
-} dtv_t;
-
+# include <dl-dtv.h>
typedef struct
{
@@ -51,11 +39,7 @@ typedef struct
uintptr_t sysinfo;
uintptr_t stack_guard;
int gscope_flag;
-#ifndef __ASSUME_PRIVATE_FUTEX
- int private_futex;
-#else
int __glibc_reserved1;
-#endif
/* GCC split stack support. */
void *__private_ss;
} tcbhead_t;
@@ -181,6 +165,7 @@ typedef struct
#define THREAD_COPY_POINTER_GUARD(descr)
/* Get and set the global scope generation counter in struct pthread. */
+#define THREAD_GSCOPE_IN_TCB 1
#define THREAD_GSCOPE_FLAG_UNUSED 0
#define THREAD_GSCOPE_FLAG_USED 1
#define THREAD_GSCOPE_FLAG_WAIT 2
diff --git a/sysdeps/s390/s390-32/Makefile b/sysdeps/s390/s390-32/Makefile
index 057862d91b..a07f2986ae 100644
--- a/sysdeps/s390/s390-32/Makefile
+++ b/sysdeps/s390/s390-32/Makefile
@@ -1,5 +1,3 @@
-pic-ccflag = -fpic
-
ifeq ($(subdir),gmon)
sysdep_routines += s390-mcount
endif
diff --git a/sysdeps/s390/s390-32/__longjmp.c b/sysdeps/s390/s390-32/__longjmp.c
index 2631cfd32f..eb3f78b383 100644
--- a/sysdeps/s390/s390-32/__longjmp.c
+++ b/sysdeps/s390/s390-32/__longjmp.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000-2016 Free Software Foundation, Inc.
+/* Copyright (C) 2000-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com).
diff --git a/sysdeps/s390/s390-32/add_n.S b/sysdeps/s390/s390-32/add_n.S
index b8e915712e..0232a1b31e 100644
--- a/sysdeps/s390/s390-32/add_n.S
+++ b/sysdeps/s390/s390-32/add_n.S
@@ -1,6 +1,6 @@
/* Add two limb vectors of the same length > 0 and store sum in a third
limb vector.
- Copyright (C) 2000-2016 Free Software Foundation, Inc.
+ Copyright (C) 2000-2018 Free Software Foundation, Inc.
Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com).
This file is part of the GNU MP Library.
diff --git a/sysdeps/s390/s390-32/addmul_1.S b/sysdeps/s390/s390-32/addmul_1.S
index 160c599d16..ff592cf34e 100644
--- a/sysdeps/s390/s390-32/addmul_1.S
+++ b/sysdeps/s390/s390-32/addmul_1.S
@@ -1,6 +1,6 @@
/* S390 __mpn_addmul_1 -- Multiply a limb vector with a limb and add
the result to a second limb vector.
- Copyright (C) 2000-2016 Free Software Foundation, Inc.
+ Copyright (C) 2000-2018 Free Software Foundation, Inc.
Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com).
This file is part of the GNU MP Library.
diff --git a/sysdeps/s390/s390-32/backtrace.c b/sysdeps/s390/s390-32/backtrace.c
index a8290ed86a..f9e85b26d9 100644
--- a/sysdeps/s390/s390-32/backtrace.c
+++ b/sysdeps/s390/s390-32/backtrace.c
@@ -1,5 +1,5 @@
/* Return backtrace of current program state.
- Copyright (C) 2000-2016 Free Software Foundation, Inc.
+ Copyright (C) 2000-2018 Free Software Foundation, Inc.
Contributed by Martin Schwidefsky <schwidefsky@de.ibm.com>.
This file is part of the GNU C Library.
diff --git a/sysdeps/s390/s390-32/bcopy.S b/sysdeps/s390/s390-32/bcopy.S
index cc64cb9aa7..560e04fdee 100644
--- a/sysdeps/s390/s390-32/bcopy.S
+++ b/sysdeps/s390/s390-32/bcopy.S
@@ -1,6 +1,6 @@
/* bcopy -- copy a block from source to destination. S/390 version.
This file is part of the GNU C Library.
- Copyright (C) 2000-2016 Free Software Foundation, Inc.
+ Copyright (C) 2000-2018 Free Software Foundation, Inc.
Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com).
The GNU C Library is free software; you can redistribute it and/or
diff --git a/sysdeps/s390/s390-32/bits/wordsize.h b/sysdeps/s390/s390-32/bits/wordsize.h
index da791fa28e..129e47182b 100644
--- a/sysdeps/s390/s390-32/bits/wordsize.h
+++ b/sysdeps/s390/s390-32/bits/wordsize.h
@@ -5,15 +5,7 @@
#else
# define __WORDSIZE 32
# define __WORDSIZE32_SIZE_ULONG 1
+# define __WORDSIZE32_PTRDIFF_LONG 0
#endif
-#if !defined __NO_LONG_DOUBLE_MATH && !defined __LONG_DOUBLE_MATH_OPTIONAL
-
-/* Signal that we didn't used to have a `long double'. The changes all
- the `long double' function variants to be redirects to the double
- functions. */
-# define __LONG_DOUBLE_MATH_OPTIONAL 1
-# ifndef __LONG_DOUBLE_128__
-# define __NO_LONG_DOUBLE_MATH 1
-# endif
-#endif
+#define __WORDSIZE_TIME64_COMPAT32 0
diff --git a/sysdeps/s390/s390-32/bzero.S b/sysdeps/s390/s390-32/bzero.S
index 4cbb62e06e..897aa2154a 100644
--- a/sysdeps/s390/s390-32/bzero.S
+++ b/sysdeps/s390/s390-32/bzero.S
@@ -1,6 +1,6 @@
/* bzero -- set a block of memory to zero. IBM S390 version
This file is part of the GNU C Library.
- Copyright (C) 2000-2016 Free Software Foundation, Inc.
+ Copyright (C) 2000-2018 Free Software Foundation, Inc.
Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com).
The GNU C Library is free software; you can redistribute it and/or
diff --git a/sysdeps/s390/s390-32/crti.S b/sysdeps/s390/s390-32/crti.S
index 5db5b1e900..44b1a704fd 100644
--- a/sysdeps/s390/s390-32/crti.S
+++ b/sysdeps/s390/s390-32/crti.S
@@ -1,5 +1,5 @@
/* Special .init and .fini section support for S/390.
- Copyright (C) 2000-2016 Free Software Foundation, Inc.
+ Copyright (C) 2000-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -57,6 +57,7 @@
.section .init,"ax",@progbits
.globl _init
+ .hidden _init
.type _init,@function
.align 4
_init:
@@ -88,6 +89,7 @@ _init:
.section .fini,"ax",@progbits
.globl _fini
+ .hidden _fini
.type _fini,@function
.align 4
_fini:
diff --git a/sysdeps/s390/s390-32/crtn.S b/sysdeps/s390/s390-32/crtn.S
index 73677917dc..6cc476ea43 100644
--- a/sysdeps/s390/s390-32/crtn.S
+++ b/sysdeps/s390/s390-32/crtn.S
@@ -1,5 +1,5 @@
/* Special .init and .fini section support for S/390.
- Copyright (C) 2000-2016 Free Software Foundation, Inc.
+ Copyright (C) 2000-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
diff --git a/sysdeps/s390/s390-32/dl-machine.h b/sysdeps/s390/s390-32/dl-machine.h
index 14bde3b58d..ded41adff8 100644
--- a/sysdeps/s390/s390-32/dl-machine.h
+++ b/sysdeps/s390/s390-32/dl-machine.h
@@ -1,5 +1,5 @@
/* Machine-dependent ELF dynamic relocation inline functions. S390 Version.
- Copyright (C) 2000-2016 Free Software Foundation, Inc.
+ Copyright (C) 2000-2018 Free Software Foundation, Inc.
Contributed by Carl Pederson & Martin Schwidefsky.
This file is part of the GNU C Library.
@@ -89,6 +89,11 @@ elf_machine_runtime_setup (struct link_map *l, int lazy, int profile)
{
extern void _dl_runtime_resolve (Elf32_Word);
extern void _dl_runtime_profile (Elf32_Word);
+#if defined HAVE_S390_VX_ASM_SUPPORT
+ extern void _dl_runtime_resolve_vx (Elf32_Word);
+ extern void _dl_runtime_profile_vx (Elf32_Word);
+#endif
+
if (l->l_info[DT_JMPREL] && lazy)
{
@@ -104,7 +109,7 @@ elf_machine_runtime_setup (struct link_map *l, int lazy, int profile)
if (got[1])
{
l->l_mach.plt = got[1] + l->l_addr;
- l->l_mach.gotplt = (Elf32_Addr) &got[3];
+ l->l_mach.jmprel = (const Elf32_Rela *) D_PTR (l, l_info[DT_JMPREL]);
}
got[1] = (Elf32_Addr) l; /* Identify this shared object. */
@@ -116,7 +121,14 @@ elf_machine_runtime_setup (struct link_map *l, int lazy, int profile)
end in this function. */
if (__glibc_unlikely (profile))
{
+#if defined HAVE_S390_VX_ASM_SUPPORT
+ if (GLRO(dl_hwcap) & HWCAP_S390_VX)
+ got[2] = (Elf32_Addr) &_dl_runtime_profile_vx;
+ else
+ got[2] = (Elf32_Addr) &_dl_runtime_profile;
+#else
got[2] = (Elf32_Addr) &_dl_runtime_profile;
+#endif
if (GLRO(dl_profile) != NULL
&& _dl_name_match_p (GLRO(dl_profile), l))
@@ -125,9 +137,18 @@ elf_machine_runtime_setup (struct link_map *l, int lazy, int profile)
GL(dl_profile_map) = l;
}
else
- /* This function will get called to fix up the GOT entry indicated by
- the offset on the stack, and then jump to the resolved address. */
- got[2] = (Elf32_Addr) &_dl_runtime_resolve;
+ {
+ /* This function will get called to fix up the GOT entry indicated by
+ the offset on the stack, and then jump to the resolved address. */
+#if defined HAVE_S390_VX_ASM_SUPPORT
+ if (GLRO(dl_hwcap) & HWCAP_S390_VX)
+ got[2] = (Elf32_Addr) &_dl_runtime_resolve_vx;
+ else
+ got[2] = (Elf32_Addr) &_dl_runtime_resolve;
+#else
+ got[2] = (Elf32_Addr) &_dl_runtime_resolve;
+#endif
+ }
}
return lazy;
@@ -273,6 +294,7 @@ dl_platform_init (void)
static inline Elf32_Addr
elf_machine_fixup_plt (struct link_map *map, lookup_t t,
+ const ElfW(Sym) *refsym, const ElfW(Sym) *sym,
const Elf32_Rela *reloc,
Elf32_Addr *reloc_addr, Elf32_Addr value)
{
@@ -336,7 +358,7 @@ elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc,
const Elf32_Sym *const refsym = sym;
#endif
struct link_map *sym_map = RESOLVE_MAP (&sym, version, r_type);
- Elf32_Addr value = sym == NULL ? 0 : sym_map->l_addr + sym->st_value;
+ Elf32_Addr value = SYMBOL_ADDRESS (sym_map, sym, true);
if (sym != NULL
&& __builtin_expect (ELFW(ST_TYPE) (sym->st_info) == STT_GNU_IFUNC, 0)
@@ -485,9 +507,7 @@ elf_machine_lazy_rel (struct link_map *map,
if (__builtin_expect (map->l_mach.plt, 0) == 0)
*reloc_addr += l_addr;
else
- *reloc_addr =
- map->l_mach.plt
- + (((Elf32_Addr) reloc_addr) - map->l_mach.gotplt) * 8;
+ *reloc_addr = map->l_mach.plt + (reloc - map->l_mach.jmprel) * 32;
}
else if (__glibc_likely (r_type == R_390_IRELATIVE))
{
diff --git a/sysdeps/s390/s390-32/dl-sysdep.h b/sysdeps/s390/s390-32/dl-sysdep.h
index d550d15985..b2e063ff09 100644
--- a/sysdeps/s390/s390-32/dl-sysdep.h
+++ b/sysdeps/s390/s390-32/dl-sysdep.h
@@ -1,5 +1,5 @@
/* System-specific settings for dynamic linker code. S/390 version.
- Copyright (C) 2014-2016 Free Software Foundation, Inc.
+ Copyright (C) 2014-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
diff --git a/sysdeps/s390/s390-32/dl-trampoline.S b/sysdeps/s390/s390-32/dl-trampoline.S
index 1645610383..1ec409bc56 100644
--- a/sysdeps/s390/s390-32/dl-trampoline.S
+++ b/sysdeps/s390/s390-32/dl-trampoline.S
@@ -1,5 +1,5 @@
/* PLT trampolines. s390 version.
- Copyright (C) 2005-2016 Free Software Foundation, Inc.
+ Copyright (C) 2005-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -16,130 +16,18 @@
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
-/* This code is used in dl-runtime.c to call the `fixup' function
- and then redirect to the address it returns. */
-
-/* The PLT stubs will call _dl_runtime_resolve/_dl_runtime_profile
- * with the following linkage:
- * r2 - r6 : parameter registers
- * f0, f2 : floating point parameter registers
- * 24(r15), 28(r15) : PLT arguments PLT1, PLT2
- * 96(r15) : additional stack parameters
- * The normal clobber rules for function calls apply:
- * r0 - r5 : call clobbered
- * r6 - r13 : call saved
- * r14 : return address (call clobbered)
- * r15 : stack pointer (call saved)
- * f4, f6 : call saved
- * f0 - f3, f5, f7 - f15 : call clobbered
- */
-
#include <sysdep.h>
.text
- .globl _dl_runtime_resolve
- .type _dl_runtime_resolve, @function
- cfi_startproc
- .align 16
-_dl_runtime_resolve:
- stm %r2,%r5,32(%r15) # save registers
- st %r14,8(%r15)
- cfi_offset (r14, -88)
- lr %r0,%r15 # create stack frame
- ahi %r15,-96
- cfi_adjust_cfa_offset (96)
- st 0,0(%r15)
- lm %r2,%r3,120(%r15) # load args saved by PLT
- basr %r1,0
-0: l %r14,1f-0b(%r1)
- bas %r14,0(%r14,%r1) # call resolver
- lr %r1,%r2 # function addr returned in r2
- ahi %r15,96 # remove stack frame
- cfi_adjust_cfa_offset (-96)
- l %r14,8(15) # restore registers
- lm %r2,%r5,32(%r15)
- br %r1
-1: .long _dl_fixup - 0b
- cfi_endproc
- .size _dl_runtime_resolve, .-_dl_runtime_resolve
-
-
-#ifndef PROF
- .globl _dl_runtime_profile
- .type _dl_runtime_profile, @function
- cfi_startproc
- .align 16
-_dl_runtime_profile:
- stm %r2,%r6,32(%r15) # save registers
- std %f0,56(%r15)
- std %f2,64(%r15)
- st %r6,8(%r15)
- st %r12,12(%r15)
- st %r14,16(%r15)
- cfi_offset (r6, -64)
- cfi_offset (f0, -40)
- cfi_offset (f2, -32)
- cfi_offset (r12, -84)
- cfi_offset (r14, -80)
- lr %r12,%r15 # create stack frame
- cfi_def_cfa_register (12)
- ahi %r15,-96
- st %r12,0(%r15)
- lm %r2,%r3,24(%r12) # load arguments saved by PLT
- lr %r4,%r14 # return address as third parameter
- basr %r1,0
-0: l %r14,6f-0b(%r1)
- la %r5,32(%r12) # pointer to struct La_s390_32_regs
- la %r6,20(%r12) # long int * framesize
- bas %r14,0(%r14,%r1) # call resolver
- lr %r1,%r2 # function addr returned in r2
- icm %r0,15,20(%r12) # load & test framesize
- jnm 2f
-
- lm %r2,%r6,32(%r12)
- ld %f0,56(%r12)
- ld %f2,64(%r12)
- lr %r15,%r12 # remove stack frame
- cfi_def_cfa_register (15)
- l %r14,16(%r15) # restore registers
- l %r12,12(%r15)
- br %r1 # tail-call to the resolved function
-
- cfi_def_cfa_register (12)
-2: jz 4f # framesize == 0 ?
- ahi %r0,7 # align framesize to 8
- lhi %r2,-8
- nr %r0,%r2
- slr %r15,%r0 # make room for framesize bytes
- st %r12,0(%r15)
- la %r2,96(%r15)
- la %r3,96(%r12)
- srl %r0,3
-3: mvc 0(8,%r2),0(%r3) # copy additional parameters
- la %r2,8(%r2)
- la %r3,8(%r3)
- brct %r0,3b
-4: lm %r2,%r6,32(%r12) # load register parameters
- ld %f0,56(%r12)
- ld %f2,64(%r12)
- basr %r14,%r1 # call resolved function
- stm %r2,%r3,72(%r12)
- std %f0,80(%r12)
- lm %r2,%r3,24(%r12) # load arguments saved by PLT
- basr %r1,0
-5: l %r14,7f-5b(%r1)
- la %r4,32(%r12) # pointer to struct La_s390_32_regs
- la %r5,72(%r12) # pointer to struct La_s390_32_retval
- basr %r14,%r1 # call _dl_call_pltexit
-
- lr %r15,%r12 # remove stack frame
- cfi_def_cfa_register (15)
- l %r14,16(%r15) # restore registers
- l %r12,12(%r15)
- br %r14
-
-6: .long _dl_profile_fixup - 0b
-7: .long _dl_call_pltexit - 5b
- cfi_endproc
- .size _dl_runtime_profile, .-_dl_runtime_profile
+/* Create variant of _dl_runtime_resolve/profile for machines before z13.
+ No vector registers are saved/restored. */
+#include <dl-trampoline.h>
+
+#if defined HAVE_S390_VX_ASM_SUPPORT
+/* Create variant of _dl_runtime_resolve/profile for z13 and newer.
+ The vector registers are saved/restored, too.*/
+# define _dl_runtime_resolve _dl_runtime_resolve_vx
+# define _dl_runtime_profile _dl_runtime_profile_vx
+# define RESTORE_VRS
+# include <dl-trampoline.h>
#endif
diff --git a/sysdeps/s390/s390-32/dl-trampoline.h b/sysdeps/s390/s390-32/dl-trampoline.h
new file mode 100644
index 0000000000..d36c002743
--- /dev/null
+++ b/sysdeps/s390/s390-32/dl-trampoline.h
@@ -0,0 +1,230 @@
+/* PLT trampolines. s390 version.
+ Copyright (C) 2016-2018 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C 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.
+
+ The GNU C Library 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, see
+ <http://www.gnu.org/licenses/>. */
+
+/* This code is used in dl-runtime.c to call the `fixup' function
+ and then redirect to the address it returns. */
+
+/* The PLT stubs will call _dl_runtime_resolve/_dl_runtime_profile
+ * with the following linkage:
+ * r2 - r6 : parameter registers
+ * f0, f2 : floating point parameter registers
+ * v24, v26, v28, v30, v25, v27, v29, v31 : vector parameter registers
+ * 24(r15), 28(r15) : PLT arguments PLT1, PLT2
+ * 96(r15) : additional stack parameters
+ * The normal clobber rules for function calls apply:
+ * r0 - r5 : call clobbered
+ * r6 - r13 : call saved
+ * r14 : return address (call clobbered)
+ * r15 : stack pointer (call saved)
+ * f4, f6 : call saved
+ * f0 - f3, f5, f7 - f15 : call clobbered
+ * v0 - v3, v5, v7 - v15 : bytes 0-7 overlap with fprs: call clobbered
+ bytes 8-15: call clobbered
+ * v4, v6 : bytes 0-7 overlap with f4, f6: call saved
+ bytes 8-15: call clobbered
+ * v16 - v31 : call clobbered
+ */
+
+
+ .globl _dl_runtime_resolve
+ .type _dl_runtime_resolve, @function
+ cfi_startproc
+ .align 16
+_dl_runtime_resolve:
+ stm %r2,%r5,32(%r15) # save registers
+ cfi_offset (r2, -64)
+ cfi_offset (r3, -60)
+ cfi_offset (r4, -56)
+ cfi_offset (r5, -52)
+ stm %r14,%r15,48(%r15)
+ cfi_offset (r14, -48)
+ cfi_offset (r15, -44)
+ std %f0,56(%r15)
+ cfi_offset (f0, -40)
+ std %f2,64(%r15)
+ cfi_offset (f2, -32)
+ lr %r0,%r15
+ lm %r2,%r3,24(%r15) # load args saved by PLT
+#ifdef RESTORE_VRS
+ ahi %r15,-224 # create stack frame
+ cfi_adjust_cfa_offset (224)
+ .machine push
+ .machine "z13"
+ .machinemode "zarch_nohighgprs"
+ vstm %v24,%v31,96(%r15) # store call-clobbered vr arguments
+ cfi_offset (v24, -224)
+ cfi_offset (v25, -208)
+ cfi_offset (v26, -192)
+ cfi_offset (v27, -176)
+ cfi_offset (v28, -160)
+ cfi_offset (v29, -144)
+ cfi_offset (v30, -128)
+ cfi_offset (v31, -112)
+ .machine pop
+#else
+ ahi %r15,-96 # create stack frame
+ cfi_adjust_cfa_offset (96)
+#endif
+ st %r0,0(%r15) # write backchain
+ basr %r1,0
+0: l %r14,1f-0b(%r1)
+ bas %r14,0(%r14,%r1) # call _dl_fixup
+ lr %r1,%r2 # function addr returned in r2
+#ifdef RESTORE_VRS
+ .machine push
+ .machine "z13"
+ .machinemode "zarch_nohighgprs"
+ vlm %v24,%v31,96(%r15) # restore vector registers
+ .machine pop
+ lm %r14,%r15,272(%r15)# remove stack frame and restore registers
+#else
+ lm %r14,%r15,144(%r15)# remove stack frame and restore registers
+#endif
+ cfi_def_cfa_offset (96)
+ ld %f0,56(%r15)
+ ld %f2,64(%r15)
+ lm %r2,%r5,32(%r15)
+ br %r1
+1: .long _dl_fixup - 0b
+ cfi_endproc
+ .size _dl_runtime_resolve, .-_dl_runtime_resolve
+
+
+#ifndef PROF
+ .globl _dl_runtime_profile
+ .type _dl_runtime_profile, @function
+ cfi_startproc
+ .align 16
+_dl_runtime_profile:
+ st %r12,12(%r15) # r12 is used as backup of r15
+ cfi_offset (r12, -84)
+ st %r14,16(%r15)
+ cfi_offset (r14, -80)
+ lr %r12,%r15 # backup stack pointer
+ cfi_def_cfa_register (12)
+ ahi %r15,-264 # create stack frame:
+ # 96 + sizeof(La_s390_32_regs)
+ st %r12,0(%r15) # save backchain
+
+ stm %r2,%r6,96(%r15) # save registers
+ cfi_offset (r2, -264) # + r6 needed as arg for
+ cfi_offset (r3, -260) # _dl_profile_fixup
+ cfi_offset (r4, -256)
+ cfi_offset (r5, -252)
+ cfi_offset (r6, -248)
+ std %f0,120(%r15)
+ cfi_offset (f0, -240)
+ std %f2,128(%r15)
+ cfi_offset (f2, -232)
+#ifdef RESTORE_VRS
+ .machine push
+ .machine "z13"
+ .machinemode "zarch_nohighgprs"
+ vstm %v24,%v31,136(%r15) # store call-clobbered vr arguments
+ cfi_offset (v24, -224)
+ cfi_offset (v25, -208)
+ cfi_offset (v26, -192)
+ cfi_offset (v27, -176)
+ cfi_offset (v28, -160)
+ cfi_offset (v29, -144)
+ cfi_offset (v30, -128)
+ cfi_offset (v31, -112)
+ .machine pop
+#endif
+
+ lm %r2,%r3,24(%r12) # load arguments saved by PLT
+ lr %r4,%r14 # return address as third parameter
+ basr %r1,0
+0: l %r14,6f-0b(%r1)
+ la %r5,96(%r15) # pointer to struct La_s390_32_regs
+ la %r6,20(%r12) # long int * framesize
+ bas %r14,0(%r14,%r1) # call resolver
+ lr %r1,%r2 # function addr returned in r2
+ ld %f0,120(%r15) # restore call-clobbered arg fprs
+ ld %f2,128(%r15)
+#ifdef RESTORE_VRS
+ .machine push
+ .machine "z13"
+ .machinemode "zarch_nohighgprs"
+ vlm %v24,%v31,136(%r15) # restore call-clobbered arg vrs
+ .machine pop
+#endif
+ icm %r0,15,20(%r12) # load & test framesize
+ jnm 2f
+
+ lm %r2,%r6,96(%r15) # framesize < 0 means no pltexit call
+ # so we can do a tail call without
+ # copying the arg overflow area
+ lr %r15,%r12 # remove stack frame
+ cfi_def_cfa_register (15)
+ l %r14,16(%r15) # restore registers
+ l %r12,12(%r15)
+ br %r1 # tail-call to the resolved function
+
+ cfi_def_cfa_register (12)
+2: la %r4,96(%r15) # pointer to struct La_s390_32_regs
+ st %r4,32(%r12)
+ jz 4f # framesize == 0 ?
+ ahi %r0,7 # align framesize to 8
+ lhi %r2,-8
+ nr %r0,%r2
+ slr %r15,%r0 # make room for framesize bytes
+ st %r12,0(%r15) # save backchain
+ la %r2,96(%r15)
+ la %r3,96(%r12)
+ srl %r0,3
+3: mvc 0(8,%r2),0(%r3) # copy additional parameters
+ la %r2,8(%r2)
+ la %r3,8(%r3)
+ brct %r0,3b
+4: lm %r2,%r6,0(%r4) # load register parameters
+ basr %r14,%r1 # call resolved function
+ stm %r2,%r3,40(%r12) # store return values r2, r3, f0
+ std %f0,48(%r12) # to struct La_s390_32_retval
+#ifdef RESTORE_VRS
+ .machine push
+ .machine "z13"
+ vst %v24,56(%r12) # store return value v24
+ .machine pop
+#endif
+ lm %r2,%r4,24(%r12) # r2, r3: load arguments saved by PLT
+ # r4: pointer to struct La_s390_32_regs
+ basr %r1,0
+5: l %r14,7f-5b(%r1)
+ la %r5,40(%r12) # pointer to struct La_s390_32_retval
+ bas %r14,0(%r14,%r1) # call _dl_call_pltexit
+
+ lr %r15,%r12 # remove stack frame
+ cfi_def_cfa_register (15)
+ l %r14,16(%r15) # restore registers
+ l %r12,12(%r15)
+ lm %r2,%r3,40(%r15) # restore return values
+ ld %f0,48(%r15)
+#ifdef RESTORE_VRS
+ .machine push
+ .machine "z13"
+ vl %v24,56(%r15) # restore return value v24
+ .machine pop
+#endif
+ br %r14
+
+6: .long _dl_profile_fixup - 0b
+7: .long _dl_call_pltexit - 5b
+ cfi_endproc
+ .size _dl_runtime_profile, .-_dl_runtime_profile
+#endif
diff --git a/sysdeps/s390/s390-32/memchr.S b/sysdeps/s390/s390-32/memchr.S
index 5c82af4b90..54f9b85f57 100644
--- a/sysdeps/s390/s390-32/memchr.S
+++ b/sysdeps/s390/s390-32/memchr.S
@@ -1,5 +1,5 @@
/* Search a character in a block of memory. For IBM S390
- Copyright (C) 2000-2016 Free Software Foundation, Inc.
+ Copyright (C) 2000-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com).
diff --git a/sysdeps/s390/s390-32/memcmp.S b/sysdeps/s390/s390-32/memcmp.S
index 50ab61c77f..f9ad0bc745 100644
--- a/sysdeps/s390/s390-32/memcmp.S
+++ b/sysdeps/s390/s390-32/memcmp.S
@@ -1,5 +1,5 @@
/* memcmp - compare two memory blocks. 32 bit S/390 version.
- Copyright (C) 2012-2016 Free Software Foundation, Inc.
+ Copyright (C) 2012-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
diff --git a/sysdeps/s390/s390-32/memcpy.S b/sysdeps/s390/s390-32/memcpy.S
index 62ecbbf619..493cc18aba 100644
--- a/sysdeps/s390/s390-32/memcpy.S
+++ b/sysdeps/s390/s390-32/memcpy.S
@@ -1,5 +1,5 @@
/* memcpy - copy a block from source to destination. S/390 version.
- Copyright (C) 2012-2016 Free Software Foundation, Inc.
+ Copyright (C) 2012-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -25,58 +25,65 @@
%r3 = address of source memory area
%r4 = number of bytes to copy. */
-#ifdef USE_MULTIARCH
-ENTRY(__memcpy_default)
-#else
-ENTRY(memcpy)
+ .text
+ENTRY(__mempcpy)
+ .machine "g5"
+ lr %r1,%r2 # Use as dest
+ la %r2,0(%r4,%r2) # Return dest + n
+ j .L_G5_start
+END(__mempcpy)
+#ifndef USE_MULTIARCH
+libc_hidden_def (__mempcpy)
+weak_alias (__mempcpy, mempcpy)
+libc_hidden_builtin_def (mempcpy)
#endif
+
+ENTRY(memcpy)
.machine "g5"
- st %r13,52(%r15)
- .cfi_offset 13, -44
- basr %r13,0
-.L_G5_16:
+ lr %r1,%r2 # r1: Use as dest ; r2: Return dest
+.L_G5_start:
ltr %r4,%r4
- je .L_G5_4
+ je .L_G5_99
ahi %r4,-1
lr %r5,%r4
srl %r5,8
ltr %r5,%r5
- lr %r1,%r2
- jne .L_G5_12
- ex %r4,.L_G5_17-.L_G5_16(%r13)
+ jne .L_G5_13
.L_G5_4:
- l %r13,52(%r15)
+ basr %r5,0
+.L_G5_16:
+ ex %r4,.L_G5_17-.L_G5_16(%r5)
+.L_G5_99:
br %r14
.L_G5_13:
- chi %r5,4096 # Switch to mvcle for copies >1MB
+ chi %r5,4096 # Switch to mvcle for copies >1MB
jh __memcpy_mvcle
.L_G5_12:
mvc 0(256,%r1),0(%r3)
la %r1,256(%r1)
la %r3,256(%r3)
brct %r5,.L_G5_12
- ex %r4,.L_G5_17-.L_G5_16(%r13)
j .L_G5_4
.L_G5_17:
mvc 0(1,%r1),0(%r3)
-#ifdef USE_MULTIARCH
-END(__memcpy_default)
-#else
END(memcpy)
+#ifndef USE_MULTIARCH
libc_hidden_builtin_def (memcpy)
#endif
ENTRY(__memcpy_mvcle)
- # Using as standalone function will result in unexpected
- # results since the length field is incremented by 1 in order to
- # compensate the changes already done in the functions above.
- ahi %r4,1 # length + 1
- lr %r5,%r4 # source length
- lr %r4,%r3 # source address
- lr %r3,%r5 # destination length = source length
+ # Using as standalone function will result in unexpected
+ # results since the length field is incremented by 1 in order to
+ # compensate the changes already done in the functions above.
+ lr %r0,%r2 # backup return dest [ + n ]
+ ahi %r4,1 # length + 1
+ lr %r5,%r4 # source length
+ lr %r4,%r3 # source address
+ lr %r2,%r1 # destination address
+ lr %r3,%r5 # destination length = source length
.L_MVCLE_1:
- mvcle %r2,%r4,0 # thats it, MVCLE is your friend
- jo .L_MVCLE_1
- lr %r2,%r1 # return destination address
- br %r14
+ mvcle %r2,%r4,0 # thats it, MVCLE is your friend
+ jo .L_MVCLE_1
+ lr %r2,%r0 # return destination address
+ br %r14
END(__memcpy_mvcle)
diff --git a/sysdeps/s390/s390-32/memset.S b/sysdeps/s390/s390-32/memset.S
index eca65d4a49..57f08e1cae 100644
--- a/sysdeps/s390/s390-32/memset.S
+++ b/sysdeps/s390/s390-32/memset.S
@@ -1,5 +1,5 @@
/* Set a block of memory to some byte value. For IBM S390
- Copyright (C) 2012-2016 Free Software Foundation, Inc.
+ Copyright (C) 2012-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
diff --git a/sysdeps/s390/s390-32/mul_1.S b/sysdeps/s390/s390-32/mul_1.S
index 50df39c17f..6fa4fae437 100644
--- a/sysdeps/s390/s390-32/mul_1.S
+++ b/sysdeps/s390/s390-32/mul_1.S
@@ -1,6 +1,6 @@
/* __mpn_mul_1 -- Multiply a limb vector with a limb and store
the result in a second limb vector.
- Copyright (C) 2000-2016 Free Software Foundation, Inc.
+ Copyright (C) 2000-2018 Free Software Foundation, Inc.
Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com).
This file is part of the GNU MP Library.
diff --git a/sysdeps/s390/s390-32/multiarch/memchr.c b/sysdeps/s390/s390-32/multiarch/memchr.c
index 2281e43056..5e1610afa4 100644
--- a/sysdeps/s390/s390-32/multiarch/memchr.c
+++ b/sysdeps/s390/s390-32/multiarch/memchr.c
@@ -1,5 +1,5 @@
/* Multiple versions of memchr.
- Copyright (C) 2015-2016 Free Software Foundation, Inc.
+ Copyright (C) 2015-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
diff --git a/sysdeps/s390/s390-32/multiarch/memcmp-s390.S b/sysdeps/s390/s390-32/multiarch/memcmp-s390.S
index e9ee6d2270..e53b508c98 100644
--- a/sysdeps/s390/s390-32/multiarch/memcmp-s390.S
+++ b/sysdeps/s390/s390-32/multiarch/memcmp-s390.S
@@ -1,5 +1,5 @@
/* CPU specific memcmp implementations. 32 bit S/390 version.
- Copyright (C) 2012-2016 Free Software Foundation, Inc.
+ Copyright (C) 2012-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -101,4 +101,7 @@ END(__memcmp_z10)
.set memcmp,__memcmp_default
.weak bcmp
.set bcmp,__memcmp_default
+#elif defined SHARED && IS_IN (libc)
+.globl __GI_memcmp
+.set __GI_memcmp,__memcmp_default
#endif
diff --git a/sysdeps/s390/s390-32/multiarch/memcmp.c b/sysdeps/s390/s390-32/multiarch/memcmp.c
index 44f72dc8ca..1e6f31806e 100644
--- a/sysdeps/s390/s390-32/multiarch/memcmp.c
+++ b/sysdeps/s390/s390-32/multiarch/memcmp.c
@@ -1,5 +1,5 @@
/* Multiple versions of memcmp.
- Copyright (C) 2015-2016 Free Software Foundation, Inc.
+ Copyright (C) 2015-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -17,8 +17,11 @@
<http://www.gnu.org/licenses/>. */
#if IS_IN (libc)
+# define memcmp __redirect_memcmp
+# include <string.h>
+# undef memcmp
# include <ifunc-resolve.h>
-s390_libc_ifunc (memcmp)
-__asm__(".weak bcmp ; bcmp = memcmp");
+s390_libc_ifunc (__redirect_memcmp, __memcmp, memcmp)
+weak_alias (memcmp, bcmp);
#endif
diff --git a/sysdeps/s390/s390-32/multiarch/memcpy-s390.S b/sysdeps/s390/s390-32/multiarch/memcpy-s390.S
index 4e30cdf6c6..aad13bd07c 100644
--- a/sysdeps/s390/s390-32/multiarch/memcpy-s390.S
+++ b/sysdeps/s390/s390-32/multiarch/memcpy-s390.S
@@ -1,5 +1,5 @@
/* CPU specific memcpy implementations. 32 bit S/390 version.
- Copyright (C) 2012-2016 Free Software Foundation, Inc.
+ Copyright (C) 2012-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -29,14 +29,23 @@
#if defined SHARED && IS_IN (libc)
+ENTRY(____mempcpy_z196)
+ .machine "z196"
+ .machinemode "zarch_nohighgprs"
+ lr %r1,%r2 # Use as dest
+ la %r2,0(%r4,%r2) # Return dest + n
+ j .L_Z196_start
+END(____mempcpy_z196)
+
ENTRY(__memcpy_z196)
.machine "z196"
.machinemode "zarch_nohighgprs"
+ lr %r1,%r2 # r1: Use as dest ; r2: Return dest
+.L_Z196_start:
llgfr %r4,%r4
ltgr %r4,%r4
je .L_Z196_4
aghi %r4,-1
- lr %r1,%r2
srlg %r5,%r4,8
ltgr %r5,%r5
jne .L_Z196_5
@@ -60,13 +69,22 @@ ENTRY(__memcpy_z196)
mvc 0(1,%r1),0(%r3)
END(__memcpy_z196)
+ENTRY(____mempcpy_z10)
+ .machine "z10"
+ .machinemode "zarch_nohighgprs"
+ lr %r1,%r2 # Use as dest
+ la %r2,0(%r4,%r2) # Return dest + n
+ j .L_Z10_start
+END(____mempcpy_z10)
+
ENTRY(__memcpy_z10)
.machine "z10"
.machinemode "zarch_nohighgprs"
+ lr %r1,%r2 # r1: Use as dest ; r2: Return dest
+.L_Z10_start:
llgfr %r4,%r4
cgije %r4,0,.L_Z10_4
aghi %r4,-1
- lr %r1,%r2
srlg %r5,%r4,8
cgijlh %r5,0,.L_Z10_13
.L_Z10_3:
@@ -88,11 +106,23 @@ ENTRY(__memcpy_z10)
mvc 0(1,%r1),0(%r3)
END(__memcpy_z10)
+# define __mempcpy ____mempcpy_default
#endif /* SHARED && IS_IN (libc) */
+#define memcpy __memcpy_default
#include "../memcpy.S"
+#undef memcpy
-#if !defined SHARED || !IS_IN (libc)
+#if defined SHARED && IS_IN (libc)
+.globl __GI_memcpy
+.set __GI_memcpy,__memcpy_default
+.globl __GI_mempcpy
+.set __GI_mempcpy,____mempcpy_default
+.globl __GI___mempcpy
+.set __GI___mempcpy,____mempcpy_default
+#else
.globl memcpy
.set memcpy,__memcpy_default
+.weak mempcpy
+.set mempcpy,__mempcpy
#endif
diff --git a/sysdeps/s390/s390-32/multiarch/memcpy.c b/sysdeps/s390/s390-32/multiarch/memcpy.c
index 2a98aa0b82..c9577a854a 100644
--- a/sysdeps/s390/s390-32/multiarch/memcpy.c
+++ b/sysdeps/s390/s390-32/multiarch/memcpy.c
@@ -1,5 +1,5 @@
/* Multiple versions of memcpy.
- Copyright (C) 2015-2016 Free Software Foundation, Inc.
+ Copyright (C) 2015-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -18,7 +18,10 @@
/* In the static lib memcpy is needed before the reloc is resolved. */
#if defined SHARED && IS_IN (libc)
+# define memcpy __redirect_memcpy
+# include <string.h>
+# undef memcpy
# include <ifunc-resolve.h>
-s390_libc_ifunc (memcpy)
+s390_libc_ifunc (__redirect_memcpy, __memcpy, memcpy)
#endif
diff --git a/sysdeps/s390/s390-32/multiarch/memset-s390.S b/sysdeps/s390/s390-32/multiarch/memset-s390.S
index 47277c13a6..b092073d6b 100644
--- a/sysdeps/s390/s390-32/multiarch/memset-s390.S
+++ b/sysdeps/s390/s390-32/multiarch/memset-s390.S
@@ -1,5 +1,5 @@
/* Set a block of memory to some byte value. 32 bit S/390 version.
- Copyright (C) 2012-2016 Free Software Foundation, Inc.
+ Copyright (C) 2012-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -110,4 +110,7 @@ END(__memset_mvcle)
#if !IS_IN (libc)
.globl memset
.set memset,__memset_default
+#elif defined SHARED && IS_IN (libc)
+.globl __GI_memset
+.set __GI_memset,__memset_default
#endif
diff --git a/sysdeps/s390/s390-32/multiarch/memset.c b/sysdeps/s390/s390-32/multiarch/memset.c
index 89b8102f2a..760b3e9df2 100644
--- a/sysdeps/s390/s390-32/multiarch/memset.c
+++ b/sysdeps/s390/s390-32/multiarch/memset.c
@@ -1,5 +1,5 @@
/* Multiple versions of memset.
- Copyright (C) 2015-2016 Free Software Foundation, Inc.
+ Copyright (C) 2015-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -17,7 +17,10 @@
<http://www.gnu.org/licenses/>. */
#if IS_IN (libc)
+# define memset __redirect_memset
+# include <string.h>
+# undef memset
# include <ifunc-resolve.h>
-s390_libc_ifunc (memset)
+s390_libc_ifunc (__redirect_memset, __memset, memset)
#endif
diff --git a/sysdeps/s390/s390-32/multiarch/strcmp.c b/sysdeps/s390/s390-32/multiarch/strcmp.c
index b7eebc017f..d06b0f3436 100644
--- a/sysdeps/s390/s390-32/multiarch/strcmp.c
+++ b/sysdeps/s390/s390-32/multiarch/strcmp.c
@@ -1,5 +1,5 @@
/* Multiple versions of strcmp.
- Copyright (C) 2015-2016 Free Software Foundation, Inc.
+ Copyright (C) 2015-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
diff --git a/sysdeps/s390/s390-32/multiarch/strcpy.c b/sysdeps/s390/s390-32/multiarch/strcpy.c
index ae140d22b7..6a22e31a03 100644
--- a/sysdeps/s390/s390-32/multiarch/strcpy.c
+++ b/sysdeps/s390/s390-32/multiarch/strcpy.c
@@ -1,5 +1,5 @@
/* Multiple versions of strcpy.
- Copyright (C) 2015-2016 Free Software Foundation, Inc.
+ Copyright (C) 2015-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
diff --git a/sysdeps/s390/s390-32/multiarch/strncpy.c b/sysdeps/s390/s390-32/multiarch/strncpy.c
index 28a2af72e4..57f9df18d1 100644
--- a/sysdeps/s390/s390-32/multiarch/strncpy.c
+++ b/sysdeps/s390/s390-32/multiarch/strncpy.c
@@ -1,5 +1,5 @@
/* Multiple versions of strncpy.
- Copyright (C) 2015-2016 Free Software Foundation, Inc.
+ Copyright (C) 2015-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
diff --git a/sysdeps/s390/s390-32/s390-mcount.S b/sysdeps/s390/s390-32/s390-mcount.S
index a27f434fbf..153777e1b8 100644
--- a/sysdeps/s390/s390-32/s390-mcount.S
+++ b/sysdeps/s390/s390-32/s390-mcount.S
@@ -1,5 +1,5 @@
-/* S/390-specific implemetation of profiling support.
- Copyright (C) 2000-2016 Free Software Foundation, Inc.
+/* S/390-specific implementation of profiling support.
+ Copyright (C) 2000-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com)
diff --git a/sysdeps/s390/s390-32/setjmp.S b/sysdeps/s390/s390-32/setjmp.S
index dbacb0fdf2..fd2f991682 100644
--- a/sysdeps/s390/s390-32/setjmp.S
+++ b/sysdeps/s390/s390-32/setjmp.S
@@ -1,5 +1,5 @@
/* setjmp for s390, ELF version.
- Copyright (C) 2000-2016 Free Software Foundation, Inc.
+ Copyright (C) 2000-2018 Free Software Foundation, Inc.
Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com).
This file is part of the GNU C Library.
@@ -24,17 +24,16 @@
#include <shlib-compat.h>
#include <stap-probe.h>
-#if !IS_IN (rtld)
-# if defined SHARED && SHLIB_COMPAT (libc, GLIBC_2_19, GLIBC_2_20)
- /* we need a unique name in case of symbol versioning. */
-# define setjmp __v1setjmp
-# define _setjmp __v1_setjmp
-# define __sigsetjmp __v1__sigsetjmp
-
-# undef libc_hidden_def
-# define libc_hidden_def(name) strong_alias(_setjmp, __GI__setjmp)
-# endif /* if defined SHARED && SHLIB_COMPAT (libc, GLIBC_2_19, GLIBC_2_20) */
-#endif /* !IS_IN (rtld) */
+#if !IS_IN (rtld) && defined SHARED \
+ && SHLIB_COMPAT (libc, GLIBC_2_19, GLIBC_2_20)
+# define NEED_COMPAT_SYMBOLS 1
+/* We need a unique name in case of symbol versioning. */
+# define setjmp __v1setjmp
+# define _setjmp __v1_setjmp
+# define __sigsetjmp __v1__sigsetjmp
+#else
+# define NEED_COMPAT_SYMBOLS 0
+#endif
/* We include the BSD entry points here as well. */
ENTRY (setjmp)
@@ -47,7 +46,11 @@ ENTRY(_setjmp)
lhi %r3,0 /* second argument of zero */
j .Linternal_sigsetjmp /* branch relativ to __sigsetjmp */
END (_setjmp)
+#if NEED_COMPAT_SYMBOLS
+strong_alias (_setjmp, __GI__setjmp)
+#else
libc_hidden_def (_setjmp)
+#endif
ENTRY(__setjmp)
lhi %r3,0 /* second argument of zero */
@@ -92,15 +95,19 @@ ENTRY(__sigsetjmp)
.L1: .long __sigjmp_save
#endif
END (__sigsetjmp)
+#if NEED_COMPAT_SYMBOLS
+strong_alias (__sigsetjmp, __GI___sigsetjmp)
+#else
+libc_hidden_def (__sigsetjmp)
+#endif
-#if !IS_IN (rtld)
-# if defined SHARED && SHLIB_COMPAT (libc, GLIBC_2_19, GLIBC_2_20)
+#if NEED_COMPAT_SYMBOLS
/* In glibc release 2.19 new versions of setjmp-functions were introduced,
but were reverted before 2.20. Thus both versions are the same function. */
-# undef setjmp
-# undef _setjmp
-# undef __sigsetjmp
+# undef setjmp
+# undef _setjmp
+# undef __sigsetjmp
strong_alias (__v1setjmp, __v2setjmp);
versioned_symbol (libc, __v1setjmp, setjmp, GLIBC_2_0);
@@ -113,5 +120,4 @@ compat_symbol (libc, __v2_setjmp, _setjmp, GLIBC_2_19);
strong_alias (__v1__sigsetjmp, __v2__sigsetjmp);
versioned_symbol (libc, __v1__sigsetjmp, __sigsetjmp, GLIBC_2_0);
compat_symbol (libc, __v2__sigsetjmp, __sigsetjmp, GLIBC_2_19);
-# endif /* if defined SHARED && SHLIB_COMPAT (libc, GLIBC_2_19, GLIBC_2_20) */
-#endif /* if !IS_IN (rtld) */
+#endif /* NEED_COMPAT_SYMBOLS */
diff --git a/sysdeps/s390/s390-32/start.S b/sysdeps/s390/s390-32/start.S
index 1fbc64d2e4..1483642985 100644
--- a/sysdeps/s390/s390-32/start.S
+++ b/sysdeps/s390/s390-32/start.S
@@ -1,5 +1,5 @@
/* Startup code compliant to the ELF s390 ABI.
- Copyright (C) 2000-2016 Free Software Foundation, Inc.
+ Copyright (C) 2000-2018 Free Software Foundation, Inc.
Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com).
This file is part of the GNU C Library.
@@ -34,6 +34,8 @@
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
+#include <sysdep.h>
+
/*
This is the canonical entry point, usually the first thing in the text
segment. Most registers' values are unspecified, except for:
@@ -57,6 +59,10 @@
.globl _start
.type _start,@function
_start:
+ cfi_startproc
+ /* Mark r14 as undefined in order to stop unwinding here! */
+ cfi_undefined (r14)
+
/* Check if the kernel provides highgprs facility if needed by
the binary. */
@@ -188,6 +194,7 @@ _start:
/* crash if __libc_start_main returns */
.word 0
+ cfi_endproc
.Llit:
#ifndef PIC
.L1: .long __libc_csu_init
diff --git a/sysdeps/s390/s390-32/strcmp.S b/sysdeps/s390/s390-32/strcmp.S
index 71f113ebab..3cf3f239fd 100644
--- a/sysdeps/s390/s390-32/strcmp.S
+++ b/sysdeps/s390/s390-32/strcmp.S
@@ -1,6 +1,6 @@
/* strcmp - compare two string. S/390 version.
This file is part of the GNU C Library.
- Copyright (C) 2001-2016 Free Software Foundation, Inc.
+ Copyright (C) 2001-2018 Free Software Foundation, Inc.
Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com).
The GNU C Library is free software; you can redistribute it and/or
diff --git a/sysdeps/s390/s390-32/strcpy.S b/sysdeps/s390/s390-32/strcpy.S
index 5cdc350f91..d49136ee92 100644
--- a/sysdeps/s390/s390-32/strcpy.S
+++ b/sysdeps/s390/s390-32/strcpy.S
@@ -1,6 +1,6 @@
/* strcpy - copy a string from source to destination. For IBM S390
This file is part of the GNU C Library.
- Copyright (C) 2000-2016 Free Software Foundation, Inc.
+ Copyright (C) 2000-2018 Free Software Foundation, Inc.
Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com).
The GNU C Library is free software; you can redistribute it and/or
diff --git a/sysdeps/s390/s390-32/strncpy.S b/sysdeps/s390/s390-32/strncpy.S
index 75800b3ee6..9086eb1c70 100644
--- a/sysdeps/s390/s390-32/strncpy.S
+++ b/sysdeps/s390/s390-32/strncpy.S
@@ -1,7 +1,7 @@
/* strncpy - copy at most n characters from a string from source to
destination. For IBM S390
This file is part of the GNU C Library.
- Copyright (C) 2000-2016 Free Software Foundation, Inc.
+ Copyright (C) 2000-2018 Free Software Foundation, Inc.
Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com).
The GNU C Library is free software; you can redistribute it and/or
diff --git a/sysdeps/s390/s390-32/sub_n.S b/sysdeps/s390/s390-32/sub_n.S
index f8de2c2a5e..e7fdb604ff 100644
--- a/sysdeps/s390/s390-32/sub_n.S
+++ b/sysdeps/s390/s390-32/sub_n.S
@@ -1,6 +1,6 @@
/* __mpn_sub_n -- Add two limb vectors of the same length > 0 and store
sum in a third limb vector.
- Copyright (C) 2000-2016 Free Software Foundation, Inc.
+ Copyright (C) 2000-2018 Free Software Foundation, Inc.
Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com).
This file is part of the GNU MP Library.
diff --git a/sysdeps/s390/s390-32/symbol-hacks.h b/sysdeps/s390/s390-32/symbol-hacks.h
new file mode 100644
index 0000000000..879ce2f517
--- /dev/null
+++ b/sysdeps/s390/s390-32/symbol-hacks.h
@@ -0,0 +1,21 @@
+/* Hacks needed for symbol manipulation. s390 version.
+ Copyright (C) 2017-2018 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C 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.
+
+ The GNU C Library 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, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <sysdeps/wordsize-32/divdi3-symbol-hacks.h>
+
+#include_next "symbol-hacks.h"
diff --git a/sysdeps/s390/s390-32/sysdep.h b/sysdeps/s390/s390-32/sysdep.h
index 26e9285dbd..7e2763fe92 100644
--- a/sysdeps/s390/s390-32/sysdep.h
+++ b/sysdeps/s390/s390-32/sysdep.h
@@ -1,5 +1,5 @@
/* Assembler macros for s390.
- Copyright (C) 2000-2016 Free Software Foundation, Inc.
+ Copyright (C) 2000-2018 Free Software Foundation, Inc.
Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com).
This file is part of the GNU C Library.
@@ -82,14 +82,14 @@ lose: SYSCALL_PIC_SETUP \
END (name)
#undef JUMPTARGET
-#ifdef PIC
+#ifdef SHARED
#define JUMPTARGET(name) name##@PLT
#define SYSCALL_PIC_SETUP \
- bras %r12,1f \
-0: .long _GLOBAL_OFFSET_TABLE_-0b \
+ bras %r12,1f; \
+0: .long _GLOBAL_OFFSET_TABLE_-0b; \
1: al %r12,0(%r12)
#else
-#define JUMPTARGET(name) name
+#define JUMPTARGET(name) name
#define SYSCALL_PIC_SETUP /* Nothing. */
#endif
diff --git a/sysdeps/s390/s390-32/tls-macros.h b/sysdeps/s390/s390-32/tls-macros.h
index 09b42aa37a..153523a4ae 100644
--- a/sysdeps/s390/s390-32/tls-macros.h
+++ b/sysdeps/s390/s390-32/tls-macros.h
@@ -8,15 +8,17 @@
#ifdef PIC
# define TLS_IE(x) \
- ({ unsigned long __offset, __got; \
+ ({ unsigned long __offset, __save12; \
__asm__ ("bras %0,1f\n" \
"0:\t.long _GLOBAL_OFFSET_TABLE_-0b\n\t" \
".long " #x "@gotntpoff\n" \
- "1:\tl %1,0(%0)\n\t" \
- "la %1,0(%1,%0)\n\t" \
+ "1:\tlr %1,%%r12\n\t" \
+ "l %%r12,0(%0)\n\t" \
+ "la %%r12,0(%0,%%r12)\n\t" \
"l %0,4(%0)\n\t" \
- "l %0,0(%0,%1):tls_load:" #x "\n" \
- : "=&a" (__offset), "=&a" (__got) : : "cc" ); \
+ "l %0,0(%0,%%r12):tls_load:" #x "\n\t" \
+ "lr %%r12,%1\n" \
+ : "=&a" (__offset), "=&a" (__save12) : : "cc" ); \
(int *) (__builtin_thread_pointer() + __offset); })
#else
# define TLS_IE(x) \
@@ -47,7 +49,7 @@
"alr %0,%%r2\n\t" \
"lr %%r12,%1" \
: "=&a" (__offset), "=&a" (__save12) \
- : : "cc", "0", "1", "2", "3", "4", "5" ); \
+ : : "cc", "0", "1", "2", "3", "4", "5", "14"); \
(int *) (__builtin_thread_pointer() + __offset); })
#else
# define TLS_LD(x) \
@@ -63,7 +65,8 @@
"bas %%r14,0(%%r1):tls_ldcall:" #x "\n\t" \
"l %0,12(%0)\n\t" \
"alr %0,%%r2" \
- : "=&a" (__offset) : : "cc", "0", "1", "2", "3", "4", "5", "12" ); \
+ : "=&a" (__offset) \
+ : : "cc", "0", "1", "2", "3", "4", "5", "12", "14"); \
(int *) (__builtin_thread_pointer() + __offset); })
#endif
@@ -83,7 +86,7 @@
"lr %0,%%r2\n\t" \
"lr %%r12,%1" \
: "=&a" (__offset), "=&a" (__save12) \
- : : "cc", "0", "1", "2", "3", "4", "5" ); \
+ : : "cc", "0", "1", "2", "3", "4", "5", "14"); \
(int *) (__builtin_thread_pointer() + __offset); })
#else
# define TLS_GD(x) \
@@ -97,6 +100,7 @@
"l %%r2,8(%0)\n\t" \
"bas %%r14,0(%%r1):tls_gdcall:" #x "\n\t" \
"lr %0,%%r2" \
- : "=&a" (__offset) : : "cc", "0", "1", "2", "3", "4", "5", "12" ); \
+ : "=&a" (__offset) \
+ : : "cc", "0", "1", "2", "3", "4", "5", "12", "14"); \
(int *) (__builtin_thread_pointer() + __offset); })
#endif
diff --git a/sysdeps/s390/s390-32/tst-audit.h b/sysdeps/s390/s390-32/tst-audit.h
index 8908602cff..173b1ec40c 100644
--- a/sysdeps/s390/s390-32/tst-audit.h
+++ b/sysdeps/s390/s390-32/tst-audit.h
@@ -1,6 +1,6 @@
/* Definitions for testing PLT entry/exit auditing. S/390 32-bit version.
- Copyright (C) 2012-2016 Free Software Foundation, Inc.
+ Copyright (C) 2012-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
diff --git a/sysdeps/s390/s390-64/Makefile b/sysdeps/s390/s390-64/Makefile
index ce4f0c5c88..b4d793bb3d 100644
--- a/sysdeps/s390/s390-64/Makefile
+++ b/sysdeps/s390/s390-64/Makefile
@@ -1,5 +1,3 @@
-pic-ccflag = -fpic
-
ifeq ($(subdir),gmon)
sysdep_routines += s390x-mcount
endif
@@ -9,84 +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)
-
-$(objpfx)gconv-modules-s390: gconv-modules $(+force)
- cp $< $@
- echo >> $@
- echo "# S/390 hardware accelerated modules" >> $@
- echo -n "module ISO-8859-1// IBM037// " >> $@
- echo " ISO-8859-1_CP037_Z900 1" >> $@
- echo -n "module IBM037// ISO-8859-1// " >> $@
- echo " ISO-8859-1_CP037_Z900 1" >> $@
- echo -n "module ISO-10646/UTF8/ UTF-32// " >> $@
- echo " UTF8_UTF32_Z9 1" >> $@
- echo -n "module UTF-32BE// ISO-10646/UTF8/ " >> $@
- echo " UTF8_UTF32_Z9 1" >> $@
- echo -n "module ISO-10646/UTF8/ UTF-32BE// " >> $@
- echo " UTF8_UTF32_Z9 1" >> $@
- echo -n "module UTF-16BE// UTF-32// " >> $@
- echo " UTF16_UTF32_Z9 1" >> $@
- echo -n "module UTF-32BE// UTF-16// " >> $@
- echo " UTF16_UTF32_Z9 1" >> $@
- echo -n "module INTERNAL UTF-16// " >> $@
- echo " UTF16_UTF32_Z9 1" >> $@
- echo -n "module UTF-32BE// UTF-16BE// " >> $@
- echo " UTF16_UTF32_Z9 1" >> $@
- echo -n "module INTERNAL UTF-16BE// " >> $@
- echo " UTF16_UTF32_Z9 1" >> $@
- echo -n "module UTF-16BE// UTF-32BE// " >> $@
- echo " UTF16_UTF32_Z9 1" >> $@
- echo -n "module UTF-16BE// INTERNAL " >> $@
- echo " UTF16_UTF32_Z9 1" >> $@
- echo -n "module UTF-16BE// ISO-10646/UTF8/ " >> $@
- echo " UTF8_UTF16_Z9 1" >> $@
- echo -n "module ISO-10646/UTF8/ UTF-16// " >> $@
- echo " UTF8_UTF16_Z9 1" >> $@
- echo -n "module ISO-10646/UTF8/ UTF-16BE// " >> $@
- echo " UTF8_UTF16_Z9 1" >> $@
-
-$(inst_gconvdir)/gconv-modules: $(objpfx)gconv-modules-s390 $(+force)
- $(do-install)
-ifeq (no,$(cross-compiling))
-# Update the $(prefix)/lib/gconv/gconv-modules.cache file. This is necessary
-# if this libc has more gconv modules than the previously installed one.
- if test -f "$(inst_gconvdir)/gconv-modules.cache"; then \
- LC_ALL=C \
- $(rtld-prefix) \
- $(common-objpfx)iconv/iconvconfig \
- $(addprefix --prefix=,$(install_root)); \
- fi
-else
- @echo '*@*@*@ You should recreate $(inst_gconvdir)/gconv-modules.cache'
-endif
-
-endif
diff --git a/sysdeps/s390/s390-64/__longjmp.c b/sysdeps/s390/s390-64/__longjmp.c
index 66005b82ac..17aa0810e6 100644
--- a/sysdeps/s390/s390-64/__longjmp.c
+++ b/sysdeps/s390/s390-64/__longjmp.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2016 Free Software Foundation, Inc.
+/* Copyright (C) 2001-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com).
diff --git a/sysdeps/s390/s390-64/add_n.S b/sysdeps/s390/s390-64/add_n.S
index 11bc60170b..5cbc6d0d8e 100644
--- a/sysdeps/s390/s390-64/add_n.S
+++ b/sysdeps/s390/s390-64/add_n.S
@@ -1,6 +1,6 @@
/* Add two limb vectors of the same length > 0 and store sum in a third
limb vector.
- Copyright (C) 2001-2016 Free Software Foundation, Inc.
+ Copyright (C) 2001-2018 Free Software Foundation, Inc.
Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com).
This file is part of the GNU MP Library.
diff --git a/sysdeps/s390/s390-64/backtrace.c b/sysdeps/s390/s390-64/backtrace.c
index 5f8b7f8fff..3efcbe4096 100644
--- a/sysdeps/s390/s390-64/backtrace.c
+++ b/sysdeps/s390/s390-64/backtrace.c
@@ -1,5 +1,5 @@
/* Return backtrace of current program state. 64 bit S/390 version.
- Copyright (C) 2001-2016 Free Software Foundation, Inc.
+ Copyright (C) 2001-2018 Free Software Foundation, Inc.
Contributed by Martin Schwidefsky <schwidefsky@de.ibm.com>.
This file is part of the GNU C Library.
diff --git a/sysdeps/s390/s390-64/bcopy.S b/sysdeps/s390/s390-64/bcopy.S
index 7eeeae499c..806dd15d02 100644
--- a/sysdeps/s390/s390-64/bcopy.S
+++ b/sysdeps/s390/s390-64/bcopy.S
@@ -1,6 +1,6 @@
/* bcopy -- copy a block from source to destination. 64 bit S/390 version.
This file is part of the GNU C Library.
- Copyright (C) 2000-2016 Free Software Foundation, Inc.
+ Copyright (C) 2000-2018 Free Software Foundation, Inc.
Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com).
The GNU C Library is free software; you can redistribute it and/or
diff --git a/sysdeps/s390/s390-64/bits/wordsize.h b/sysdeps/s390/s390-64/bits/wordsize.h
index da791fa28e..00e88b0628 100644
--- a/sysdeps/s390/s390-64/bits/wordsize.h
+++ b/sysdeps/s390/s390-64/bits/wordsize.h
@@ -5,15 +5,7 @@
#else
# define __WORDSIZE 32
# define __WORDSIZE32_SIZE_ULONG 1
+# define __WORDSIZE32_PTRDIFF_LONG 0
#endif
-#if !defined __NO_LONG_DOUBLE_MATH && !defined __LONG_DOUBLE_MATH_OPTIONAL
-
-/* Signal that we didn't used to have a `long double'. The changes all
- the `long double' function variants to be redirects to the double
- functions. */
-# define __LONG_DOUBLE_MATH_OPTIONAL 1
-# ifndef __LONG_DOUBLE_128__
-# define __NO_LONG_DOUBLE_MATH 1
-# endif
-#endif
+#define __WORDSIZE_TIME64_COMPAT32 0
diff --git a/sysdeps/s390/s390-64/bzero.S b/sysdeps/s390/s390-64/bzero.S
index 891efc2d6e..b321665298 100644
--- a/sysdeps/s390/s390-64/bzero.S
+++ b/sysdeps/s390/s390-64/bzero.S
@@ -1,6 +1,6 @@
/* bzero -- set a block of memory to zero. 64 bit S/390 version.
This file is part of the GNU C Library.
- Copyright (C) 2001-2016 Free Software Foundation, Inc.
+ Copyright (C) 2001-2018 Free Software Foundation, Inc.
Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com).
The GNU C Library is free software; you can redistribute it and/or
diff --git a/sysdeps/s390/s390-64/crti.S b/sysdeps/s390/s390-64/crti.S
index 248ef83dbe..f676eb5259 100644
--- a/sysdeps/s390/s390-64/crti.S
+++ b/sysdeps/s390/s390-64/crti.S
@@ -1,5 +1,5 @@
/* Special .init and .fini section support for 64 bit S/390.
- Copyright (C) 2001-2016 Free Software Foundation, Inc.
+ Copyright (C) 2001-2018 Free Software Foundation, Inc.
Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com).
This file is part of the GNU C Library.
@@ -59,6 +59,7 @@
.section .init,"ax",@progbits
.align 4
.globl _init
+ .hidden _init
.type _init,@function
_init:
stmg %r6,%r15,48(%r15)
@@ -81,6 +82,7 @@ _init:
.section .fini,"ax",@progbits
.align 4
.globl _fini
+ .hidden _fini
.type _fini,@function
_fini:
stmg %r6,%r15,48(%r15)
diff --git a/sysdeps/s390/s390-64/crtn.S b/sysdeps/s390/s390-64/crtn.S
index ce906acffc..8ae6394b72 100644
--- a/sysdeps/s390/s390-64/crtn.S
+++ b/sysdeps/s390/s390-64/crtn.S
@@ -1,5 +1,5 @@
/* Special .init and .fini section support for 64 bit S/390.
- Copyright (C) 2001-2016 Free Software Foundation, Inc.
+ Copyright (C) 2001-2018 Free Software Foundation, Inc.
Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com).
This file is part of the GNU C Library.
diff --git a/sysdeps/s390/s390-64/dl-machine.h b/sysdeps/s390/s390-64/dl-machine.h
index cb81aafc5d..f22db7860b 100644
--- a/sysdeps/s390/s390-64/dl-machine.h
+++ b/sysdeps/s390/s390-64/dl-machine.h
@@ -1,6 +1,6 @@
/* Machine-dependent ELF dynamic relocation inline functions.
64 bit S/390 Version.
- Copyright (C) 2001-2016 Free Software Foundation, Inc.
+ Copyright (C) 2001-2018 Free Software Foundation, Inc.
Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com).
This file is part of the GNU C Library.
@@ -26,6 +26,7 @@
#include <sys/param.h>
#include <string.h>
#include <link.h>
+#include <sysdeps/s390/dl-procinfo.h>
#include <dl-irel.h>
#define ELF_MACHINE_IRELATIVE R_390_IRELATIVE
@@ -78,6 +79,10 @@ elf_machine_runtime_setup (struct link_map *l, int lazy, int profile)
{
extern void _dl_runtime_resolve (Elf64_Word);
extern void _dl_runtime_profile (Elf64_Word);
+#if defined HAVE_S390_VX_ASM_SUPPORT
+ extern void _dl_runtime_resolve_vx (Elf64_Word);
+ extern void _dl_runtime_profile_vx (Elf64_Word);
+#endif
if (l->l_info[DT_JMPREL] && lazy)
{
@@ -93,7 +98,7 @@ elf_machine_runtime_setup (struct link_map *l, int lazy, int profile)
if (got[1])
{
l->l_mach.plt = got[1] + l->l_addr;
- l->l_mach.gotplt = (Elf64_Addr) &got[3];
+ l->l_mach.jmprel = (const Elf64_Rela *) D_PTR (l, l_info[DT_JMPREL]);
}
got[1] = (Elf64_Addr) l; /* Identify this shared object. */
@@ -105,7 +110,14 @@ elf_machine_runtime_setup (struct link_map *l, int lazy, int profile)
end in this function. */
if (__glibc_unlikely (profile))
{
+#if defined HAVE_S390_VX_ASM_SUPPORT
+ if (GLRO(dl_hwcap) & HWCAP_S390_VX)
+ got[2] = (Elf64_Addr) &_dl_runtime_profile_vx;
+ else
+ got[2] = (Elf64_Addr) &_dl_runtime_profile;
+#else
got[2] = (Elf64_Addr) &_dl_runtime_profile;
+#endif
if (GLRO(dl_profile) != NULL
&& _dl_name_match_p (GLRO(dl_profile), l))
@@ -114,9 +126,18 @@ elf_machine_runtime_setup (struct link_map *l, int lazy, int profile)
GL(dl_profile_map) = l;
}
else
- /* This function will get called to fix up the GOT entry indicated by
- the offset on the stack, and then jump to the resolved address. */
- got[2] = (Elf64_Addr) &_dl_runtime_resolve;
+ {
+ /* This function will get called to fix up the GOT entry indicated by
+ the offset on the stack, and then jump to the resolved address. */
+#if defined HAVE_S390_VX_ASM_SUPPORT
+ if (GLRO(dl_hwcap) & HWCAP_S390_VX)
+ got[2] = (Elf64_Addr) &_dl_runtime_resolve_vx;
+ else
+ got[2] = (Elf64_Addr) &_dl_runtime_resolve;
+#else
+ got[2] = (Elf64_Addr) &_dl_runtime_resolve;
+#endif
+ }
}
return lazy;
@@ -221,6 +242,7 @@ dl_platform_init (void)
static inline Elf64_Addr
elf_machine_fixup_plt (struct link_map *map, lookup_t t,
+ const ElfW(Sym) *refsym, const ElfW(Sym) *sym,
const Elf64_Rela *reloc,
Elf64_Addr *reloc_addr, Elf64_Addr value)
{
@@ -283,7 +305,7 @@ elf_machine_rela (struct link_map *map, const Elf64_Rela *reloc,
const Elf64_Sym *const refsym = sym;
#endif
struct link_map *sym_map = RESOLVE_MAP (&sym, version, r_type);
- Elf64_Addr value = sym == NULL ? 0 : sym_map->l_addr + sym->st_value;
+ Elf64_Addr value = SYMBOL_ADDRESS (sym_map, sym, true);
if (sym != NULL
&& __builtin_expect (ELFW(ST_TYPE) (sym->st_info) == STT_GNU_IFUNC,
@@ -439,9 +461,7 @@ elf_machine_lazy_rel (struct link_map *map,
if (__builtin_expect (map->l_mach.plt, 0) == 0)
*reloc_addr += l_addr;
else
- *reloc_addr =
- map->l_mach.plt
- + (((Elf64_Addr) reloc_addr) - map->l_mach.gotplt) * 4;
+ *reloc_addr = map->l_mach.plt + (reloc - map->l_mach.jmprel) * 32;
}
else if (__glibc_likely (r_type == R_390_IRELATIVE))
{
diff --git a/sysdeps/s390/s390-64/dl-trampoline.S b/sysdeps/s390/s390-64/dl-trampoline.S
index 6919ed0138..03c8f0415b 100644
--- a/sysdeps/s390/s390-64/dl-trampoline.S
+++ b/sysdeps/s390/s390-64/dl-trampoline.S
@@ -1,5 +1,5 @@
/* PLT trampolines. s390x version.
- Copyright (C) 2005-2016 Free Software Foundation, Inc.
+ Copyright (C) 2005-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -16,126 +16,18 @@
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
-/* The PLT stubs will call _dl_runtime_resolve/_dl_runtime_profile
- * with the following linkage:
- * r2 - r6 : parameter registers
- * f0, f2, f4, f6 : floating point parameter registers
- * 48(r15), 56(r15) : PLT arguments PLT1, PLT2
- * 160(r15) : additional stack parameters
- * The normal clobber rules for function calls apply:
- * r0 - r5 : call clobbered
- * r6 - r13 : call saved
- * r14 : return address (call clobbered)
- * r15 : stack pointer (call saved)
- * f1, f3, f5, f7 : call saved
- * f0 - f3, f5, f7 - f15 : call clobbered
- */
-
#include <sysdep.h>
.text
- .globl _dl_runtime_resolve
- .type _dl_runtime_resolve, @function
- cfi_startproc
- .align 16
-_dl_runtime_resolve:
- stmg %r2,%r5,64(15) # save call-clobbered argument registers
- stg %r14,96(15)
- cfi_offset (r14, -64)
- lgr %r0,%r15
- aghi %r15,-160 # create stack frame
- cfi_adjust_cfa_offset (160)
- stg %r0,0(%r15) # write backchain
- lmg %r2,%r3,208(%r15)# load args saved by PLT
- brasl %r14,_dl_fixup # call fixup
- lgr %r1,%r2 # function addr returned in r2
- aghi %r15,160 # remove stack frame
- cfi_adjust_cfa_offset (-160)
- lg %r14,96(15) # restore registers
- lmg %r2,%r5,64(15)
- br %r1
- cfi_endproc
- .size _dl_runtime_resolve, .-_dl_runtime_resolve
-
-
-#ifndef PROF
- .globl _dl_runtime_profile
- .type _dl_runtime_profile, @function
- cfi_startproc
- .align 16
-_dl_runtime_profile:
- stmg %r2,%r6,64(%r15) # save call-clobbered arg regs
- std %f0,104(%r15) # + r6 needed as arg for
- std %f2,112(%r15) # _dl_profile_fixup
- std %f4,120(%r15)
- std %f6,128(%r15)
- stg %r12,24(%r15) # r12 is used as backup of r15
- stg %r14,32(%r15)
- cfi_offset (r6, -96)
- cfi_offset (f0, -56)
- cfi_offset (f2, -48)
- cfi_offset (f4, -40)
- cfi_offset (f6, -32)
- cfi_offset (r12, -136)
- cfi_offset (r14, -128)
- lgr %r12,%r15 # backup stack pointer
- cfi_def_cfa_register (12)
- aghi %r15,-160 # create stack frame
- stg %r12,0(%r15) # save backchain
- lmg %r2,%r3,48(%r12) # load arguments saved by PLT
- lgr %r4,%r14 # return address as third parameter
- la %r5,64(%r12) # pointer to struct La_s390_32_regs
- la %r6,40(%r12) # long int * framesize
- brasl %r14,_dl_profile_fixup # call resolver
- lgr %r1,%r2 # function addr returned in r2
- lg %r0,40(%r12) # load framesize
- ltgr %r0,%r0
- jnm 1f
-
- lmg %r2,%r6,64(%r12) # framesize < 0 means no pltexit call
- ld %f0,104(%r12) # so we can do a tail call without
- ld %f2,112(%r12) # copying the arg overflow area
- ld %f4,120(%r12)
- ld %f6,128(%r12)
-
- lgr %r15,%r12 # remove stack frame
- cfi_def_cfa_register (15)
- lg %r14,32(%r15) # restore registers
- lg %r12,24(%r15)
- br %r1 # tail-call to resolved function
-
- cfi_def_cfa_register (12)
-1: jz 4f # framesize == 0 ?
- aghi %r0,7 # align framesize to 8
- nill %r0,0xfff8
- slgr %r15,%r0 # make room for framesize bytes
- stg %r12,0(%r15)
- la %r2,160(%r15)
- la %r3,160(%r12)
- srlg %r0,%r0,3
-3: mvc 0(8,%r2),0(%r3) # copy additional parameters
- la %r2,8(%r2)
- la %r3,8(%r3)
- brctg %r0,3b
-4: lmg %r2,%r6,64(%r12) # load register parameters
- ld %f0,104(%r12) # restore call-clobbered arg regs
- ld %f2,112(%r12)
- ld %f4,120(%r12)
- ld %f6,128(%r12)
- basr %r14,%r1 # call resolved function
- stg %r2,136(%r12)
- std %f0,144(%r12)
- lmg %r2,%r3,48(%r12) # load arguments saved by PLT
- la %r4,32(%r12) # pointer to struct La_s390_32_regs
- la %r5,72(%r12) # pointer to struct La_s390_32_retval
- brasl %r14,_dl_call_pltexit
-
- lgr %r15,%r12 # remove stack frame
- cfi_def_cfa_register (15)
- lg %r14,32(%r15) # restore registers
- lg %r12,24(%r15)
- br %r14
-
- cfi_endproc
- .size _dl_runtime_profile, .-_dl_runtime_profile
+/* Create variant of _dl_runtime_resolve/profile for machines before z13.
+ No vector registers are saved/restored. */
+#include <dl-trampoline.h>
+
+#if defined HAVE_S390_VX_ASM_SUPPORT
+/* Create variant of _dl_runtime_resolve/profile for z13 and newer.
+ The vector registers are saved/restored, too.*/
+# define _dl_runtime_resolve _dl_runtime_resolve_vx
+# define _dl_runtime_profile _dl_runtime_profile_vx
+# define RESTORE_VRS
+# include <dl-trampoline.h>
#endif
diff --git a/sysdeps/s390/s390-64/dl-trampoline.h b/sysdeps/s390/s390-64/dl-trampoline.h
new file mode 100644
index 0000000000..d313fd521d
--- /dev/null
+++ b/sysdeps/s390/s390-64/dl-trampoline.h
@@ -0,0 +1,224 @@
+/* PLT trampolines. s390x version.
+ Copyright (C) 2016-2018 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C 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.
+
+ The GNU C Library 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, see
+ <http://www.gnu.org/licenses/>. */
+
+/* The PLT stubs will call _dl_runtime_resolve/_dl_runtime_profile
+ * with the following linkage:
+ * r2 - r6 : parameter registers
+ * f0, f2, f4, f6 : floating point parameter registers
+ * v24, v26, v28, v30, v25, v27, v29, v31 : vector parameter registers
+ * 48(r15), 56(r15) : PLT arguments PLT1, PLT2
+ * 160(r15) : additional stack parameters
+ * The normal clobber rules for function calls apply:
+ * r0 - r5 : call clobbered
+ * r6 - r13 : call saved
+ * r14 : return address (call clobbered)
+ * r15 : stack pointer (call saved)
+ * f0 - f7 : call clobbered
+ * f8 - f15 : call saved
+ * v0 - v7 : bytes 0-7 overlap with f0-f7: call clobbered
+ bytes 8-15: call clobbered
+ * v8 - v15 : bytes 0-7 overlap with f8-f15: call saved
+ bytes 8-15: call clobbered
+ * v16 - v31 : call clobbered
+ */
+
+ .globl _dl_runtime_resolve
+ .type _dl_runtime_resolve, @function
+ cfi_startproc
+ .align 16
+_dl_runtime_resolve:
+ stmg %r2,%r5,64(%r15) # save call-clobbered argument registers
+ cfi_offset (r2, -96)
+ cfi_offset (r3, -88)
+ cfi_offset (r4, -80)
+ cfi_offset (r5, -72)
+ stmg %r14,%r15,96(%r15)
+ cfi_offset (r14, -64)
+ cfi_offset (r15, -56)
+ std %f0,112(%r15)
+ cfi_offset (f0, -48)
+ std %f2,120(%r15)
+ cfi_offset (f2, -40)
+ std %f4,128(%r15)
+ cfi_offset (f4, -32)
+ std %f6,136(%r15)
+ cfi_offset (f6, -24)
+ lmg %r2,%r3,48(%r15) # load args for fixup saved by PLT
+ lgr %r0,%r15
+#ifdef RESTORE_VRS
+ aghi %r15,-288 # create stack frame
+ cfi_adjust_cfa_offset (288)
+ .machine push
+ .machine "z13"
+ vstm %v24,%v31,160(%r15)# store call-clobbered vector argument registers
+ cfi_offset (v24, -288)
+ cfi_offset (v25, -272)
+ cfi_offset (v26, -256)
+ cfi_offset (v27, -240)
+ cfi_offset (v28, -224)
+ cfi_offset (v29, -208)
+ cfi_offset (v30, -192)
+ cfi_offset (v31, -176)
+ .machine pop
+#else
+ aghi %r15,-160 # create stack frame
+ cfi_adjust_cfa_offset (160)
+#endif
+ stg %r0,0(%r15) # write backchain
+ brasl %r14,_dl_fixup # call _dl_fixup
+ lgr %r1,%r2 # function addr returned in r2
+#ifdef RESTORE_VRS
+ .machine push
+ .machine "z13"
+ vlm %v24,%v31,160(%r15)# restore vector registers
+ .machine pop
+ lmg %r14,%r15,384(%r15)# remove stack frame and restore registers
+#else
+ lmg %r14,%r15,256(%r15)# remove stack frame and restore registers
+#endif
+ cfi_def_cfa_offset (160)
+ ld %f0,112(%r15)
+ ld %f2,120(%r15)
+ ld %f4,128(%r15)
+ ld %f6,136(%r15)
+ lmg %r2,%r5,64(%r15)
+ br %r1
+ cfi_endproc
+ .size _dl_runtime_resolve, .-_dl_runtime_resolve
+
+
+#ifndef PROF
+ .globl _dl_runtime_profile
+ .type _dl_runtime_profile, @function
+ cfi_startproc
+ .align 16
+_dl_runtime_profile:
+ stg %r12,24(%r15) # r12 is used as backup of r15
+ cfi_offset (r12, -136)
+ stg %r14,32(%r15)
+ cfi_offset (r14, -128)
+ lgr %r12,%r15 # backup stack pointer
+ cfi_def_cfa_register (12)
+ aghi %r15,-360 # create stack frame:
+ # 160 + sizeof(La_s390_64_regs)
+ stg %r12,0(%r15) # save backchain
+
+ stmg %r2,%r6,160(%r15) # save call-clobbered arg regs
+ cfi_offset (r2, -360) # + r6 needed as arg for
+ cfi_offset (r3, -352) # _dl_profile_fixup
+ cfi_offset (r4, -344)
+ cfi_offset (r5, -336)
+ cfi_offset (r6, -328)
+ std %f0,200(%r15)
+ cfi_offset (f0, -320)
+ std %f2,208(%r15)
+ cfi_offset (f2, -312)
+ std %f4,216(%r15)
+ cfi_offset (f4, -304)
+ std %f6,224(%r15)
+ cfi_offset (f6, -296)
+#ifdef RESTORE_VRS
+ .machine push
+ .machine "z13"
+ vstm %v24,%v31,232(%r15) # store call-clobbered vector arguments
+ cfi_offset (v24, -288)
+ cfi_offset (v25, -272)
+ cfi_offset (v26, -256)
+ cfi_offset (v27, -240)
+ cfi_offset (v28, -224)
+ cfi_offset (v29, -208)
+ cfi_offset (v30, -192)
+ cfi_offset (v31, -176)
+ .machine pop
+#endif
+ lmg %r2,%r3,48(%r12) # load arguments saved by PLT
+ lgr %r4,%r14 # return address as third parameter
+ la %r5,160(%r15) # pointer to struct La_s390_64_regs
+ la %r6,40(%r12) # long int * framesize
+ brasl %r14,_dl_profile_fixup # call resolver
+ lgr %r1,%r2 # function addr returned in r2
+ ld %f0,200(%r15) # restore call-clobbered arg fprs
+ ld %f2,208(%r15)
+ ld %f4,216(%r15)
+ ld %f6,224(%r15)
+#ifdef RESTORE_VRS
+ .machine push
+ .machine "z13"
+ vlm %v24,%v31,232(%r15) # restore call-clobbered arg vrs
+ .machine pop
+#endif
+ lg %r0,40(%r12) # load framesize
+ ltgr %r0,%r0
+ jnm 1f
+
+ lmg %r2,%r6,160(%r15) # framesize < 0 means no pltexit call
+ # so we can do a tail call without
+ # copying the arg overflow area
+ lgr %r15,%r12 # remove stack frame
+ cfi_def_cfa_register (15)
+ lg %r14,32(%r15) # restore registers
+ lg %r12,24(%r15)
+ br %r1 # tail-call to resolved function
+
+ cfi_def_cfa_register (12)
+1: la %r4,160(%r15) # pointer to struct La_s390_64_regs
+ stg %r4,64(%r12)
+ jz 4f # framesize == 0 ?
+ aghi %r0,7 # align framesize to 8
+ nill %r0,0xfff8
+ slgr %r15,%r0 # make room for framesize bytes
+ stg %r12,0(%r15) # save backchain
+ la %r2,160(%r15)
+ la %r3,160(%r12)
+ srlg %r0,%r0,3
+3: mvc 0(8,%r2),0(%r3) # copy additional parameters
+ la %r2,8(%r2) # depending on framesize
+ la %r3,8(%r3)
+ brctg %r0,3b
+4: lmg %r2,%r6,0(%r4) # restore call-clobbered arg gprs
+ basr %r14,%r1 # call resolved function
+ stg %r2,72(%r12) # store return values r2, f0
+ std %f0,80(%r12) # to struct La_s390_64_retval
+#ifdef RESTORE_VRS
+ .machine push
+ .machine "z13"
+ vst %v24,88(%r12) # store return value v24
+ .machine pop
+#endif
+ lmg %r2,%r4,48(%r12) # r2, r3: load arguments saved by PLT
+ # r4: pointer to struct La_s390_64_regs
+ la %r5,72(%r12) # pointer to struct La_s390_64_retval
+ brasl %r14,_dl_call_pltexit
+
+ lgr %r15,%r12 # remove stack frame
+ cfi_def_cfa_register (15)
+ lg %r14,32(%r15) # restore registers
+ lg %r12,24(%r15)
+ lg %r2,72(%r15) # restore return values
+ ld %f0,80(%r15)
+#ifdef RESTORE_VRS
+ .machine push
+ .machine "z13"
+ vl %v24,88(%r15) # restore return value v24
+ .machine pop
+#endif
+ br %r14 # Jump back to caller
+
+ cfi_endproc
+ .size _dl_runtime_profile, .-_dl_runtime_profile
+#endif
diff --git a/sysdeps/s390/s390-64/memchr.S b/sysdeps/s390/s390-64/memchr.S
index 8d50dcfe86..a19fcafa14 100644
--- a/sysdeps/s390/s390-64/memchr.S
+++ b/sysdeps/s390/s390-64/memchr.S
@@ -1,5 +1,5 @@
/* Search a character in a block of memory. 64 bit S/390 version.
- Copyright (C) 2001-2016 Free Software Foundation, Inc.
+ Copyright (C) 2001-2018 Free Software Foundation, Inc.
Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com).
This file is part of the GNU C Library.
diff --git a/sysdeps/s390/s390-64/memcmp.S b/sysdeps/s390/s390-64/memcmp.S
index 5e79d544bf..005b19de45 100644
--- a/sysdeps/s390/s390-64/memcmp.S
+++ b/sysdeps/s390/s390-64/memcmp.S
@@ -1,5 +1,5 @@
/* memcmp - compare two memory blocks. 64 bit S/390 version.
- Copyright (C) 2012-2016 Free Software Foundation, Inc.
+ Copyright (C) 2012-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
diff --git a/sysdeps/s390/s390-64/memcpy.S b/sysdeps/s390/s390-64/memcpy.S
index e84a3572cb..2e5490df23 100644
--- a/sysdeps/s390/s390-64/memcpy.S
+++ b/sysdeps/s390/s390-64/memcpy.S
@@ -1,5 +1,5 @@
/* memcpy - copy a block from source to destination. 64 bit S/390 version.
- Copyright (C) 2012-2016 Free Software Foundation, Inc.
+ Copyright (C) 2012-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -27,19 +27,27 @@
.text
+ENTRY(__mempcpy)
+ .machine "z900"
+ lgr %r1,%r2 # Use as dest
+ la %r2,0(%r4,%r2) # Return dest + n
+ j .L_Z900_start
+END(__mempcpy)
+#ifndef USE_MULTIARCH
+libc_hidden_def (__mempcpy)
+weak_alias (__mempcpy, mempcpy)
+libc_hidden_builtin_def (mempcpy)
+#endif
-#ifdef USE_MULTIARCH
-ENTRY(__memcpy_default)
-#else
ENTRY(memcpy)
-#endif
.machine "z900"
+ lgr %r1,%r2 # r1: Use as dest ; r2: Return dest
+.L_Z900_start:
ltgr %r4,%r4
je .L_Z900_4
aghi %r4,-1
srlg %r5,%r4,8
ltgr %r5,%r5
- lgr %r1,%r2
jne .L_Z900_13
.L_Z900_3:
larl %r5,.L_Z900_15
@@ -47,7 +55,7 @@ ENTRY(memcpy)
.L_Z900_4:
br %r14
.L_Z900_13:
- chi %r5,4096 # Switch to mvcle for copies >1MB
+ cghi %r5,4096 # Switch to mvcle for copies >1MB
jh __memcpy_mvcle
.L_Z900_12:
mvc 0(256,%r1),0(%r3)
@@ -57,25 +65,24 @@ ENTRY(memcpy)
j .L_Z900_3
.L_Z900_15:
mvc 0(1,%r1),0(%r3)
-
-#ifdef USE_MULTIARCH
-END(__memcpy_default)
-#else
END(memcpy)
+#ifndef USE_MULTIARCH
libc_hidden_builtin_def (memcpy)
#endif
ENTRY(__memcpy_mvcle)
- # Using as standalone function will result in unexpected
- # results since the length field is incremented by 1 in order to
- # compensate the changes already done in the functions above.
- aghi %r4,1 # length + 1
- lgr %r5,%r4 # source length
- lgr %r4,%r3 # source address
- lgr %r3,%r5 # destination length = source length
+ # Using as standalone function will result in unexpected
+ # results since the length field is incremented by 1 in order to
+ # compensate the changes already done in the functions above.
+ lgr %r0,%r2 # backup return dest [ + n ]
+ aghi %r4,1 # length + 1
+ lgr %r5,%r4 # source length
+ lgr %r4,%r3 # source address
+ lgr %r2,%r1 # destination address
+ lgr %r3,%r5 # destination length = source length
.L_MVCLE_1:
- mvcle %r2,%r4,0 # thats it, MVCLE is your friend
- jo .L_MVCLE_1
- lgr %r2,%r1 # return destination address
- br %r14
+ mvcle %r2,%r4,0 # thats it, MVCLE is your friend
+ jo .L_MVCLE_1
+ lgr %r2,%r0 # return destination address
+ br %r14
END(__memcpy_mvcle)
diff --git a/sysdeps/s390/s390-64/memset.S b/sysdeps/s390/s390-64/memset.S
index cab7855549..8799c6592c 100644
--- a/sysdeps/s390/s390-64/memset.S
+++ b/sysdeps/s390/s390-64/memset.S
@@ -1,5 +1,5 @@
/* Set a block of memory to some byte value. 64 bit S/390 version.
- Copyright (C) 2001-2016 Free Software Foundation, Inc.
+ Copyright (C) 2001-2018 Free Software Foundation, Inc.
Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com).
This file is part of the GNU C Library.
diff --git a/sysdeps/s390/s390-64/multiarch/memchr.c b/sysdeps/s390/s390-64/multiarch/memchr.c
index 2281e43056..5e1610afa4 100644
--- a/sysdeps/s390/s390-64/multiarch/memchr.c
+++ b/sysdeps/s390/s390-64/multiarch/memchr.c
@@ -1,5 +1,5 @@
/* Multiple versions of memchr.
- Copyright (C) 2015-2016 Free Software Foundation, Inc.
+ Copyright (C) 2015-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
diff --git a/sysdeps/s390/s390-64/multiarch/memcmp-s390x.S b/sysdeps/s390/s390-64/multiarch/memcmp-s390x.S
index 2a4c0ae9a6..35f9bf9cf7 100644
--- a/sysdeps/s390/s390-64/multiarch/memcmp-s390x.S
+++ b/sysdeps/s390/s390-64/multiarch/memcmp-s390x.S
@@ -1,5 +1,5 @@
/* CPU specific memcmp implementations. 64 bit S/390 version.
- Copyright (C) 2012-2016 Free Software Foundation, Inc.
+ Copyright (C) 2012-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -98,4 +98,7 @@ END(__memcmp_z10)
.set memcmp,__memcmp_default
.weak bcmp
.set bcmp,__memcmp_default
+#elif defined SHARED && IS_IN (libc)
+.globl __GI_memcmp
+.set __GI_memcmp,__memcmp_default
#endif
diff --git a/sysdeps/s390/s390-64/multiarch/memcmp.c b/sysdeps/s390/s390-64/multiarch/memcmp.c
index 44f72dc8ca..1e6f31806e 100644
--- a/sysdeps/s390/s390-64/multiarch/memcmp.c
+++ b/sysdeps/s390/s390-64/multiarch/memcmp.c
@@ -1,5 +1,5 @@
/* Multiple versions of memcmp.
- Copyright (C) 2015-2016 Free Software Foundation, Inc.
+ Copyright (C) 2015-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -17,8 +17,11 @@
<http://www.gnu.org/licenses/>. */
#if IS_IN (libc)
+# define memcmp __redirect_memcmp
+# include <string.h>
+# undef memcmp
# include <ifunc-resolve.h>
-s390_libc_ifunc (memcmp)
-__asm__(".weak bcmp ; bcmp = memcmp");
+s390_libc_ifunc (__redirect_memcmp, __memcmp, memcmp)
+weak_alias (memcmp, bcmp);
#endif
diff --git a/sysdeps/s390/s390-64/multiarch/memcpy-s390x.S b/sysdeps/s390/s390-64/multiarch/memcpy-s390x.S
index 69fa562060..6d60a70834 100644
--- a/sysdeps/s390/s390-64/multiarch/memcpy-s390x.S
+++ b/sysdeps/s390/s390-64/multiarch/memcpy-s390x.S
@@ -1,5 +1,5 @@
/* CPU specific memcpy implementations. 64 bit S/390 version.
- Copyright (C) 2012-2016 Free Software Foundation, Inc.
+ Copyright (C) 2012-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -29,12 +29,20 @@
#if defined SHARED && IS_IN (libc)
+ENTRY(____mempcpy_z196)
+ .machine "z196"
+ lgr %r1,%r2 # Use as dest
+ la %r2,0(%r4,%r2) # Return dest + n
+ j .L_Z196_start
+END(____mempcpy_z196)
+
ENTRY(__memcpy_z196)
.machine "z196"
+ lgr %r1,%r2 # r1: Use as dest ; r2: Return dest
+.L_Z196_start:
ltgr %r4,%r4
je .L_Z196_4
aghi %r4,-1
- lgr %r1,%r2
srlg %r5,%r4,8
ltgr %r5,%r5
jne .L_Z196_5
@@ -58,11 +66,19 @@ ENTRY(__memcpy_z196)
mvc 0(1,%r1),0(%r3)
END(__memcpy_z196)
+ENTRY(____mempcpy_z10)
+ .machine "z10"
+ lgr %r1,%r2 # Use as dest
+ la %r2,0(%r4,%r2) # Return dest + n
+ j .L_Z10_start
+END(____mempcpy_z10)
+
ENTRY(__memcpy_z10)
.machine "z10"
+ lgr %r1,%r2 # r1: Use as dest ; r2: Return dest
+.L_Z10_start:
cgije %r4,0,.L_Z10_4
aghi %r4,-1
- lgr %r1,%r2
srlg %r5,%r4,8
cgijlh %r5,0,.L_Z10_13
.L_Z10_3:
@@ -84,11 +100,23 @@ ENTRY(__memcpy_z10)
mvc 0(1,%r1),0(%r3)
END(__memcpy_z10)
+# define __mempcpy ____mempcpy_default
#endif /* SHARED && IS_IN (libc) */
+#define memcpy __memcpy_default
#include "../memcpy.S"
+#undef memcpy
-#if !defined SHARED || !IS_IN (libc)
+#if defined SHARED && IS_IN (libc)
+.globl __GI_memcpy
+.set __GI_memcpy,__memcpy_default
+.globl __GI_mempcpy
+.set __GI_mempcpy,____mempcpy_default
+.globl __GI___mempcpy
+.set __GI___mempcpy,____mempcpy_default
+#else
.globl memcpy
.set memcpy,__memcpy_default
+.weak mempcpy
+.set mempcpy,__mempcpy
#endif
diff --git a/sysdeps/s390/s390-64/multiarch/memcpy.c b/sysdeps/s390/s390-64/multiarch/memcpy.c
index 2a98aa0b82..c9577a854a 100644
--- a/sysdeps/s390/s390-64/multiarch/memcpy.c
+++ b/sysdeps/s390/s390-64/multiarch/memcpy.c
@@ -1,5 +1,5 @@
/* Multiple versions of memcpy.
- Copyright (C) 2015-2016 Free Software Foundation, Inc.
+ Copyright (C) 2015-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -18,7 +18,10 @@
/* In the static lib memcpy is needed before the reloc is resolved. */
#if defined SHARED && IS_IN (libc)
+# define memcpy __redirect_memcpy
+# include <string.h>
+# undef memcpy
# include <ifunc-resolve.h>
-s390_libc_ifunc (memcpy)
+s390_libc_ifunc (__redirect_memcpy, __memcpy, memcpy)
#endif
diff --git a/sysdeps/s390/s390-64/multiarch/memset-s390x.S b/sysdeps/s390/s390-64/multiarch/memset-s390x.S
index 05e068279d..0c5aaef34f 100644
--- a/sysdeps/s390/s390-64/multiarch/memset-s390x.S
+++ b/sysdeps/s390/s390-64/multiarch/memset-s390x.S
@@ -1,5 +1,5 @@
/* Set a block of memory to some byte value. 64 bit S/390 version.
- Copyright (C) 2012-2016 Free Software Foundation, Inc.
+ Copyright (C) 2012-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -106,4 +106,7 @@ END(__memset_mvcle)
#if !IS_IN (libc)
.globl memset
.set memset,__memset_default
+#elif defined SHARED && IS_IN (libc)
+.globl __GI_memset
+.set __GI_memset,__memset_default
#endif
diff --git a/sysdeps/s390/s390-64/multiarch/memset.c b/sysdeps/s390/s390-64/multiarch/memset.c
index 89b8102f2a..760b3e9df2 100644
--- a/sysdeps/s390/s390-64/multiarch/memset.c
+++ b/sysdeps/s390/s390-64/multiarch/memset.c
@@ -1,5 +1,5 @@
/* Multiple versions of memset.
- Copyright (C) 2015-2016 Free Software Foundation, Inc.
+ Copyright (C) 2015-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -17,7 +17,10 @@
<http://www.gnu.org/licenses/>. */
#if IS_IN (libc)
+# define memset __redirect_memset
+# include <string.h>
+# undef memset
# include <ifunc-resolve.h>
-s390_libc_ifunc (memset)
+s390_libc_ifunc (__redirect_memset, __memset, memset)
#endif
diff --git a/sysdeps/s390/s390-64/multiarch/strcmp.c b/sysdeps/s390/s390-64/multiarch/strcmp.c
index b7eebc017f..d06b0f3436 100644
--- a/sysdeps/s390/s390-64/multiarch/strcmp.c
+++ b/sysdeps/s390/s390-64/multiarch/strcmp.c
@@ -1,5 +1,5 @@
/* Multiple versions of strcmp.
- Copyright (C) 2015-2016 Free Software Foundation, Inc.
+ Copyright (C) 2015-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
diff --git a/sysdeps/s390/s390-64/multiarch/strcpy.c b/sysdeps/s390/s390-64/multiarch/strcpy.c
index ae140d22b7..6a22e31a03 100644
--- a/sysdeps/s390/s390-64/multiarch/strcpy.c
+++ b/sysdeps/s390/s390-64/multiarch/strcpy.c
@@ -1,5 +1,5 @@
/* Multiple versions of strcpy.
- Copyright (C) 2015-2016 Free Software Foundation, Inc.
+ Copyright (C) 2015-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
diff --git a/sysdeps/s390/s390-64/multiarch/strncpy.c b/sysdeps/s390/s390-64/multiarch/strncpy.c
index 28a2af72e4..57f9df18d1 100644
--- a/sysdeps/s390/s390-64/multiarch/strncpy.c
+++ b/sysdeps/s390/s390-64/multiarch/strncpy.c
@@ -1,5 +1,5 @@
/* Multiple versions of strncpy.
- Copyright (C) 2015-2016 Free Software Foundation, Inc.
+ Copyright (C) 2015-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
diff --git a/sysdeps/s390/s390-64/s390x-mcount.S b/sysdeps/s390/s390-64/s390x-mcount.S
index cb67ddb7ff..c6b5d65e17 100644
--- a/sysdeps/s390/s390-64/s390x-mcount.S
+++ b/sysdeps/s390/s390-64/s390x-mcount.S
@@ -1,5 +1,5 @@
-/* 64 bit S/390-specific implemetation of profiling support.
- Copyright (C) 2001-2016 Free Software Foundation, Inc.
+/* 64 bit S/390-specific implementation of profiling support.
+ Copyright (C) 2001-2018 Free Software Foundation, Inc.
Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com)
This file is part of the GNU C Library.
diff --git a/sysdeps/s390/s390-64/setjmp.S b/sysdeps/s390/s390-64/setjmp.S
index bbcb70db5f..f512589fb9 100644
--- a/sysdeps/s390/s390-64/setjmp.S
+++ b/sysdeps/s390/s390-64/setjmp.S
@@ -1,5 +1,5 @@
/* setjmp for 64 bit S/390, ELF version.
- Copyright (C) 2001-2016 Free Software Foundation, Inc.
+ Copyright (C) 2001-2018 Free Software Foundation, Inc.
Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com).
This file is part of the GNU C Library.
@@ -24,17 +24,16 @@
#include <shlib-compat.h>
#include <stap-probe.h>
-#if !IS_IN (rtld)
-# if defined SHARED && SHLIB_COMPAT (libc, GLIBC_2_19, GLIBC_2_20)
- /* we need a unique name in case of symbol versioning. */
-# define setjmp __v1setjmp
-# define _setjmp __v1_setjmp
-# define __sigsetjmp __v1__sigsetjmp
-
-# undef libc_hidden_def
-# define libc_hidden_def(name) strong_alias(_setjmp, __GI__setjmp)
-# endif /* if defined SHARED && SHLIB_COMPAT (libc, GLIBC_2_19, GLIBC_2_20) */
-#endif /* !IS_IN (rtld) */
+#if !IS_IN (rtld) && defined SHARED \
+ && SHLIB_COMPAT (libc, GLIBC_2_19, GLIBC_2_20)
+# define NEED_COMPAT_SYMBOLS 1
+/* We need a unique name in case of symbol versioning. */
+# define setjmp __v1setjmp
+# define _setjmp __v1_setjmp
+# define __sigsetjmp __v1__sigsetjmp
+#else
+# define NEED_COMPAT_SYMBOLS 0
+#endif
/* We include the BSD entry points here as well. */
ENTRY (setjmp)
@@ -47,7 +46,11 @@ ENTRY(_setjmp)
slgr %r3,%r3 /* Second argument of zero. */
j .Linternal_sigsetjmp /* Branch relativ to __sigsetjmp. */
END (_setjmp)
+#if NEED_COMPAT_SYMBOLS
+strong_alias (_setjmp, __GI__setjmp)
+#else
libc_hidden_def (_setjmp)
+#endif
ENTRY(__setjmp)
slgr %r3,%r3 /* Second argument of zero. */
@@ -87,15 +90,19 @@ ENTRY(__sigsetjmp)
jg __sigjmp_save
#endif
END (__sigsetjmp)
+#if NEED_COMPAT_SYMBOLS
+strong_alias (__sigsetjmp, __GI___sigsetjmp)
+#else
+libc_hidden_def (__sigsetjmp)
+#endif
-#if !IS_IN (rtld)
-# if defined SHARED && SHLIB_COMPAT (libc, GLIBC_2_19, GLIBC_2_20)
+#if NEED_COMPAT_SYMBOLS
/* In glibc release 2.19 new versions of setjmp-functions were introduced,
but were reverted before 2.20. Thus both versions are the same function. */
-# undef setjmp
-# undef _setjmp
-# undef __sigsetjmp
+# undef setjmp
+# undef _setjmp
+# undef __sigsetjmp
strong_alias (__v1setjmp, __v2setjmp);
versioned_symbol (libc, __v1setjmp, setjmp, GLIBC_2_0);
@@ -108,5 +115,4 @@ compat_symbol (libc, __v2_setjmp, _setjmp, GLIBC_2_19);
strong_alias (__v1__sigsetjmp, __v2__sigsetjmp);
versioned_symbol (libc, __v1__sigsetjmp, __sigsetjmp, GLIBC_2_0);
compat_symbol (libc, __v2__sigsetjmp, __sigsetjmp, GLIBC_2_19);
-# endif /* if defined SHARED && SHLIB_COMPAT (libc, GLIBC_2_19, GLIBC_2_20) */
-#endif /* if !IS_IN (rtld) */
+#endif /* NEED_COMPAT_SYMBOLS */
diff --git a/sysdeps/s390/s390-64/start.S b/sysdeps/s390/s390-64/start.S
index e261460dd5..79e7b69f1d 100644
--- a/sysdeps/s390/s390-64/start.S
+++ b/sysdeps/s390/s390-64/start.S
@@ -1,5 +1,5 @@
/* Startup code compliant to the 64 bit S/390 ELF ABI.
- Copyright (C) 2001-2016 Free Software Foundation, Inc.
+ Copyright (C) 2001-2018 Free Software Foundation, Inc.
Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com).
This file is part of the GNU C Library.
@@ -34,6 +34,8 @@
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
+#include <sysdep.h>
+
/*
This is the canonical entry point, usually the first thing in the text
segment. Most registers' values are unspecified, except for:
@@ -57,6 +59,9 @@
.globl _start
.type _start,@function
_start:
+ cfi_startproc
+ /* Mark r14 as undefined in order to stop unwinding here! */
+ cfi_undefined (r14)
/* Load argc and argv from stack. */
la %r4,8(%r15) # get argv
lg %r3,0(%r15) # get argc
@@ -91,6 +96,8 @@ _start:
/* Crash if __libc_start_main returns. */
.word 0
+ cfi_endproc
+
/* Define a symbol for the first piece of initialized data. */
.data
.globl __data_start
diff --git a/sysdeps/s390/s390-64/strcmp.S b/sysdeps/s390/s390-64/strcmp.S
index 245b54cc9d..6cf1addd8b 100644
--- a/sysdeps/s390/s390-64/strcmp.S
+++ b/sysdeps/s390/s390-64/strcmp.S
@@ -1,6 +1,6 @@
/* strcmp - compare two string. 64 bit S/390 version.
This file is part of the GNU C Library.
- Copyright (C) 2001-2016 Free Software Foundation, Inc.
+ Copyright (C) 2001-2018 Free Software Foundation, Inc.
Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com).
The GNU C Library is free software; you can redistribute it and/or
diff --git a/sysdeps/s390/s390-64/strcpy.S b/sysdeps/s390/s390-64/strcpy.S
index 9864e98b24..203c73c905 100644
--- a/sysdeps/s390/s390-64/strcpy.S
+++ b/sysdeps/s390/s390-64/strcpy.S
@@ -1,5 +1,5 @@
/* strcpy - copy a string from source to destination. 64 bit S/390 version.
- Copyright (C) 2001-2016 Free Software Foundation, Inc.
+ Copyright (C) 2001-2018 Free Software Foundation, Inc.
Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com).
This file is part of the GNU C Library.
diff --git a/sysdeps/s390/s390-64/strncpy.S b/sysdeps/s390/s390-64/strncpy.S
index 56c8a526ae..be40aa32d5 100644
--- a/sysdeps/s390/s390-64/strncpy.S
+++ b/sysdeps/s390/s390-64/strncpy.S
@@ -1,6 +1,6 @@
/* strncpy - copy at most n characters from a string from source to
destination. 64 bit S/390 version
- Copyright (C) 2001-2016 Free Software Foundation, Inc.
+ Copyright (C) 2001-2018 Free Software Foundation, Inc.
Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com).
This file is part of the GNU C Library.
diff --git a/sysdeps/s390/s390-64/sub_n.S b/sysdeps/s390/s390-64/sub_n.S
index 7318836db9..ad5c7fc9ca 100644
--- a/sysdeps/s390/s390-64/sub_n.S
+++ b/sysdeps/s390/s390-64/sub_n.S
@@ -1,6 +1,6 @@
/* __mpn_sub_n -- Add two limb vectors of the same length > 0 and store
sum in a third limb vector. 64 bit S/390 version.
- Copyright (C) 2001-2016 Free Software Foundation, Inc.
+ Copyright (C) 2001-2018 Free Software Foundation, Inc.
Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com).
This file is part of the GNU MP Library.
diff --git a/sysdeps/s390/s390-64/sysdep.h b/sysdeps/s390/s390-64/sysdep.h
index 7fac89da51..a573e08e92 100644
--- a/sysdeps/s390/s390-64/sysdep.h
+++ b/sysdeps/s390/s390-64/sysdep.h
@@ -1,5 +1,5 @@
/* Assembler macros for 64 bit S/390.
- Copyright (C) 2001-2016 Free Software Foundation, Inc.
+ Copyright (C) 2001-2018 Free Software Foundation, Inc.
Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com).
This file is part of the GNU C Library.
@@ -77,7 +77,7 @@ lose: SYSCALL_PIC_SETUP \
END (name)
#undef JUMPTARGET
-#ifdef PIC
+#ifdef SHARED
#define JUMPTARGET(name) name##@PLT
#define SYSCALL_PIC_SETUP \
larl %r12,_GLOBAL_OFFSET_TABLE_
diff --git a/sysdeps/s390/s390-64/tls-macros.h b/sysdeps/s390/s390-64/tls-macros.h
index d70ea6ce0c..449a843d69 100644
--- a/sysdeps/s390/s390-64/tls-macros.h
+++ b/sysdeps/s390/s390-64/tls-macros.h
@@ -8,13 +8,15 @@
#ifdef PIC
# define TLS_IE(x) \
- ({ unsigned long __offset, __got; \
+ ({ unsigned long __offset, __save12; \
__asm__ ("bras %0,0f\n\t" \
".quad " #x "@gotntpoff\n" \
- "0:\tlarl %1,_GLOBAL_OFFSET_TABLE_\n\t" \
+ "0:\tlgr %1,%%r12\n\t" \
+ "larl %%r12,_GLOBAL_OFFSET_TABLE_\n\t" \
"lg %0,0(%0)\n\t" \
- "lg %0,0(%0,%1):tls_load:" #x "\n" \
- : "=&a" (__offset), "=&a" (__got) : : "cc" ); \
+ "lg %0,0(%0,%%r12):tls_load:" #x "\n\t" \
+ "lgr %%r12,%1\n" \
+ : "=&a" (__offset), "=&a" (__save12) : : "cc" ); \
(int *) (__builtin_thread_pointer() + __offset); })
#else
# define TLS_IE(x) \
diff --git a/sysdeps/s390/s390-64/tst-audit.h b/sysdeps/s390/s390-64/tst-audit.h
index 3283e95037..954373e24f 100644
--- a/sysdeps/s390/s390-64/tst-audit.h
+++ b/sysdeps/s390/s390-64/tst-audit.h
@@ -1,6 +1,6 @@
/* Definitions for testing PLT entry/exit auditing. S/390 64-bit version.
- Copyright (C) 2012-2016 Free Software Foundation, Inc.
+ Copyright (C) 2012-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
diff --git a/sysdeps/s390/s390-64/utf16-utf32-z9.c b/sysdeps/s390/s390-64/utf16-utf32-z9.c
deleted file mode 100644
index a3863ee244..0000000000
--- a/sysdeps/s390/s390-64/utf16-utf32-z9.c
+++ /dev/null
@@ -1,337 +0,0 @@
-/* Conversion between UTF-16 and UTF-32 BE/internal.
-
- This module uses the Z9-109 variants of the Convert Unicode
- instructions.
- Copyright (C) 1997-2016 Free Software Foundation, Inc.
-
- Author: Andreas Krebbel <Andreas.Krebbel@de.ibm.com>
- Based on the work by Ulrich Drepper <drepper@cygnus.com>, 1997.
-
- Thanks to Daniel Appich who covered the relevant performance work
- in his diploma thesis.
-
- This 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.
-
- This 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, see
- <http://www.gnu.org/licenses/>. */
-
-#include <dlfcn.h>
-#include <stdint.h>
-#include <unistd.h>
-#include <dl-procinfo.h>
-#include <gconv.h>
-
-/* UTF-32 big endian byte order mark. */
-#define BOM_UTF32 0x0000feffu
-
-/* UTF-16 big endian byte order mark. */
-#define BOM_UTF16 0xfeff
-
-#define DEFINE_INIT 0
-#define DEFINE_FINI 0
-#define MIN_NEEDED_FROM 2
-#define MAX_NEEDED_FROM 4
-#define MIN_NEEDED_TO 4
-#define FROM_LOOP from_utf16_loop
-#define TO_LOOP to_utf16_loop
-#define FROM_DIRECTION (dir == from_utf16)
-#define ONE_DIRECTION 0
-#define PREPARE_LOOP \
- enum direction dir = ((struct utf16_data *) step->__data)->dir; \
- int emit_bom = ((struct utf16_data *) step->__data)->emit_bom; \
- \
- if (emit_bom && !data->__internal_use \
- && data->__invocation_counter == 0) \
- { \
- if (dir == to_utf16) \
- { \
- /* Emit the UTF-16 Byte Order Mark. */ \
- if (__glibc_unlikely (outbuf + 2 > outend)) \
- return __GCONV_FULL_OUTPUT; \
- \
- put16u (outbuf, BOM_UTF16); \
- outbuf += 2; \
- } \
- else \
- { \
- /* Emit the UTF-32 Byte Order Mark. */ \
- if (__glibc_unlikely (outbuf + 4 > outend)) \
- return __GCONV_FULL_OUTPUT; \
- \
- put32u (outbuf, BOM_UTF32); \
- outbuf += 4; \
- } \
- }
-
-/* Direction of the transformation. */
-enum direction
-{
- illegal_dir,
- to_utf16,
- from_utf16
-};
-
-struct utf16_data
-{
- enum direction dir;
- int emit_bom;
-};
-
-
-extern int gconv_init (struct __gconv_step *step);
-int
-gconv_init (struct __gconv_step *step)
-{
- /* Determine which direction. */
- struct utf16_data *new_data;
- enum direction dir = illegal_dir;
- int emit_bom;
- int result;
-
- emit_bom = (__strcasecmp (step->__to_name, "UTF-32//") == 0
- || __strcasecmp (step->__to_name, "UTF-16//") == 0);
-
- if (__strcasecmp (step->__from_name, "UTF-16BE//") == 0
- && (__strcasecmp (step->__to_name, "UTF-32//") == 0
- || __strcasecmp (step->__to_name, "UTF-32BE//") == 0
- || __strcasecmp (step->__to_name, "INTERNAL") == 0))
- {
- dir = from_utf16;
- }
- else if ((__strcasecmp (step->__to_name, "UTF-16//") == 0
- || __strcasecmp (step->__to_name, "UTF-16BE//") == 0)
- && (__strcasecmp (step->__from_name, "UTF-32BE//") == 0
- || __strcasecmp (step->__from_name, "INTERNAL") == 0))
- {
- dir = to_utf16;
- }
-
- result = __GCONV_NOCONV;
- if (dir != illegal_dir)
- {
- new_data = (struct utf16_data *) malloc (sizeof (struct utf16_data));
-
- result = __GCONV_NOMEM;
- if (new_data != NULL)
- {
- new_data->dir = dir;
- new_data->emit_bom = emit_bom;
- step->__data = new_data;
-
- if (dir == from_utf16)
- {
- step->__min_needed_from = MIN_NEEDED_FROM;
- step->__max_needed_from = MIN_NEEDED_FROM;
- step->__min_needed_to = MIN_NEEDED_TO;
- step->__max_needed_to = MIN_NEEDED_TO;
- }
- else
- {
- step->__min_needed_from = MIN_NEEDED_TO;
- step->__max_needed_from = MIN_NEEDED_TO;
- step->__min_needed_to = MIN_NEEDED_FROM;
- step->__max_needed_to = MIN_NEEDED_FROM;
- }
-
- step->__stateful = 0;
-
- result = __GCONV_OK;
- }
- }
-
- return result;
-}
-
-
-extern void gconv_end (struct __gconv_step *data);
-void
-gconv_end (struct __gconv_step *data)
-{
- free (data->__data);
-}
-
-/* The macro for the hardware loop. This is used for both
- directions. */
-#define HARDWARE_CONVERT(INSTRUCTION) \
- { \
- register const unsigned char* pInput __asm__ ("8") = inptr; \
- register unsigned long long 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; \
- \
- __asm__ volatile (".machine push \n\t" \
- ".machine \"z9-109\" \n\t" \
- "0: " INSTRUCTION " \n\t" \
- ".machine pop \n\t" \
- " jo 0b \n\t" \
- " ipm %2 \n" \
- : "+a" (pOutput), "+a" (pInput), "+d" (cc), \
- "+d" (outlen), "+d" (inlen) \
- : \
- : "cc", "memory"); \
- \
- inptr = pInput; \
- outptr = pOutput; \
- cc >>= 28; \
- \
- if (cc == 1) \
- { \
- result = __GCONV_FULL_OUTPUT; \
- break; \
- } \
- else if (cc == 2) \
- { \
- result = __GCONV_ILLEGAL_INPUT; \
- break; \
- } \
- }
-
-/* Conversion function from UTF-16 to UTF-32 internal/BE. */
-
-#define MIN_NEEDED_INPUT MIN_NEEDED_FROM
-#define MAX_NEEDED_INPUT MAX_NEEDED_FROM
-#define MIN_NEEDED_OUTPUT MIN_NEEDED_TO
-#define LOOPFCT FROM_LOOP
-/* The software routine is copied from utf-16.c (minus bytes
- swapping). */
-#define BODY \
- { \
- /* The hardware instruction currently fails to report an error for \
- isolated low surrogates so we have to disable the instruction \
- until this gets resolved. */ \
- if (0) /* (GLRO (dl_hwcap) & HWCAP_S390_ETF3EH) */ \
- { \
- HARDWARE_CONVERT ("cu24 %0, %1, 1"); \
- if (inptr != inend) \
- { \
- /* Check if the third byte is \
- a valid start of a UTF-16 surrogate. */ \
- if (inend - inptr == 3 && (inptr[3] & 0xfc) != 0xdc) \
- STANDARD_FROM_LOOP_ERR_HANDLER (3); \
- \
- result = __GCONV_INCOMPLETE_INPUT; \
- break; \
- } \
- continue; \
- } \
- \
- uint16_t u1 = get16 (inptr); \
- \
- if (__builtin_expect (u1 < 0xd800, 1) || u1 > 0xdfff) \
- { \
- /* No surrogate. */ \
- put32 (outptr, u1); \
- inptr += 2; \
- } \
- else \
- { \
- /* An isolated low-surrogate was found. This has to be \
- considered ill-formed. */ \
- if (__glibc_unlikely (u1 >= 0xdc00)) \
- { \
- STANDARD_FROM_LOOP_ERR_HANDLER (2); \
- } \
- /* It's a surrogate character. At least the first word says \
- it is. */ \
- if (__glibc_unlikely (inptr + 4 > inend)) \
- { \
- /* We don't have enough input for another complete input \
- character. */ \
- result = __GCONV_INCOMPLETE_INPUT; \
- break; \
- } \
- \
- inptr += 2; \
- uint16_t u2 = get16 (inptr); \
- if (__builtin_expect (u2 < 0xdc00, 0) \
- || __builtin_expect (u2 > 0xdfff, 0)) \
- { \
- /* This is no valid second word for a surrogate. */ \
- inptr -= 2; \
- STANDARD_FROM_LOOP_ERR_HANDLER (2); \
- } \
- \
- put32 (outptr, ((u1 - 0xd7c0) << 10) + (u2 - 0xdc00)); \
- inptr += 2; \
- } \
- outptr += 4; \
- }
-#define LOOP_NEED_FLAGS
-#include <iconv/loop.c>
-
-/* Conversion from UTF-32 internal/BE to UTF-16. */
-
-#define MIN_NEEDED_INPUT MIN_NEEDED_TO
-#define MIN_NEEDED_OUTPUT MIN_NEEDED_FROM
-#define MAX_NEEDED_OUTPUT MAX_NEEDED_FROM
-#define LOOPFCT TO_LOOP
-/* The software routine is copied from utf-16.c (minus bytes
- swapping). */
-#define BODY \
- { \
- if (GLRO (dl_hwcap) & HWCAP_S390_ETF3EH) \
- { \
- HARDWARE_CONVERT ("cu42 %0, %1"); \
- \
- if (inptr != inend) \
- { \
- result = __GCONV_INCOMPLETE_INPUT; \
- break; \
- } \
- continue; \
- } \
- \
- uint32_t c = get32 (inptr); \
- \
- if (__builtin_expect (c <= 0xd7ff, 1) \
- || (c >=0xdc00 && c <= 0xffff)) \
- { \
- /* Two UTF-16 chars. */ \
- put16 (outptr, c); \
- } \
- else if (__builtin_expect (c >= 0x10000, 1) \
- && __builtin_expect (c <= 0x10ffff, 1)) \
- { \
- /* Four UTF-16 chars. */ \
- uint16_t zabcd = ((c & 0x1f0000) >> 16) - 1; \
- uint16_t out; \
- \
- /* Generate a surrogate character. */ \
- if (__glibc_unlikely (outptr + 4 > outend)) \
- { \
- /* Overflow in the output buffer. */ \
- result = __GCONV_FULL_OUTPUT; \
- break; \
- } \
- \
- out = 0xd800; \
- out |= (zabcd & 0xff) << 6; \
- out |= (c >> 10) & 0x3f; \
- put16 (outptr, out); \
- outptr += 2; \
- \
- out = 0xdc00; \
- out |= c & 0x3ff; \
- put16 (outptr, out); \
- } \
- else \
- { \
- STANDARD_TO_LOOP_ERR_HANDLER (4); \
- } \
- outptr += 2; \
- inptr += 4; \
- }
-#define LOOP_NEED_FLAGS
-#include <iconv/loop.c>
-
-#include <iconv/skeleton.c>
diff --git a/sysdeps/s390/s390-64/utf8-utf16-z9.c b/sysdeps/s390/s390-64/utf8-utf16-z9.c
deleted file mode 100644
index 4148ed796b..0000000000
--- a/sysdeps/s390/s390-64/utf8-utf16-z9.c
+++ /dev/null
@@ -1,471 +0,0 @@
-/* Conversion between UTF-16 and UTF-32 BE/internal.
-
- This module uses the Z9-109 variants of the Convert Unicode
- instructions.
- Copyright (C) 1997-2016 Free Software Foundation, Inc.
-
- Author: Andreas Krebbel <Andreas.Krebbel@de.ibm.com>
- Based on the work by Ulrich Drepper <drepper@cygnus.com>, 1997.
-
- Thanks to Daniel Appich who covered the relevant performance work
- in his diploma thesis.
-
- This 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.
-
- This 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, see
- <http://www.gnu.org/licenses/>. */
-
-#include <dlfcn.h>
-#include <stdint.h>
-#include <unistd.h>
-#include <dl-procinfo.h>
-#include <gconv.h>
-
-/* UTF-16 big endian byte order mark. */
-#define BOM_UTF16 0xfeff
-
-#define DEFINE_INIT 0
-#define DEFINE_FINI 0
-#define MIN_NEEDED_FROM 1
-#define MAX_NEEDED_FROM 4
-#define MIN_NEEDED_TO 2
-#define MAX_NEEDED_TO 4
-#define FROM_LOOP from_utf8_loop
-#define TO_LOOP to_utf8_loop
-#define FROM_DIRECTION (dir == from_utf8)
-#define ONE_DIRECTION 0
-#define PREPARE_LOOP \
- enum direction dir = ((struct utf8_data *) step->__data)->dir; \
- int emit_bom = ((struct utf8_data *) step->__data)->emit_bom; \
- \
- if (emit_bom && !data->__internal_use \
- && data->__invocation_counter == 0) \
- { \
- /* Emit the UTF-16 Byte Order Mark. */ \
- if (__glibc_unlikely (outbuf + 2 > outend)) \
- return __GCONV_FULL_OUTPUT; \
- \
- put16u (outbuf, BOM_UTF16); \
- outbuf += 2; \
- }
-
-/* Direction of the transformation. */
-enum direction
-{
- illegal_dir,
- to_utf8,
- from_utf8
-};
-
-struct utf8_data
-{
- enum direction dir;
- int emit_bom;
-};
-
-
-extern int gconv_init (struct __gconv_step *step);
-int
-gconv_init (struct __gconv_step *step)
-{
- /* Determine which direction. */
- struct utf8_data *new_data;
- enum direction dir = illegal_dir;
- int emit_bom;
- int result;
-
- emit_bom = (__strcasecmp (step->__to_name, "UTF-16//") == 0);
-
- if (__strcasecmp (step->__from_name, "ISO-10646/UTF8/") == 0
- && (__strcasecmp (step->__to_name, "UTF-16//") == 0
- || __strcasecmp (step->__to_name, "UTF-16BE//") == 0))
- {
- dir = from_utf8;
- }
- else if (__strcasecmp (step->__from_name, "UTF-16BE//") == 0
- && __strcasecmp (step->__to_name, "ISO-10646/UTF8/") == 0)
- {
- dir = to_utf8;
- }
-
- result = __GCONV_NOCONV;
- if (dir != illegal_dir)
- {
- new_data = (struct utf8_data *) malloc (sizeof (struct utf8_data));
-
- result = __GCONV_NOMEM;
- if (new_data != NULL)
- {
- new_data->dir = dir;
- new_data->emit_bom = emit_bom;
- step->__data = new_data;
-
- if (dir == from_utf8)
- {
- step->__min_needed_from = MIN_NEEDED_FROM;
- step->__max_needed_from = MIN_NEEDED_FROM;
- step->__min_needed_to = MIN_NEEDED_TO;
- step->__max_needed_to = MIN_NEEDED_TO;
- }
- else
- {
- step->__min_needed_from = MIN_NEEDED_TO;
- step->__max_needed_from = MIN_NEEDED_TO;
- step->__min_needed_to = MIN_NEEDED_FROM;
- step->__max_needed_to = MIN_NEEDED_FROM;
- }
-
- step->__stateful = 0;
-
- result = __GCONV_OK;
- }
- }
-
- return result;
-}
-
-
-extern void gconv_end (struct __gconv_step *data);
-void
-gconv_end (struct __gconv_step *data)
-{
- free (data->__data);
-}
-
-/* The macro for the hardware loop. This is used for both
- directions. */
-#define HARDWARE_CONVERT(INSTRUCTION) \
- { \
- register const unsigned char* pInput __asm__ ("8") = inptr; \
- register unsigned long long 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; \
- \
- __asm__ volatile (".machine push \n\t" \
- ".machine \"z9-109\" \n\t" \
- "0: " INSTRUCTION " \n\t" \
- ".machine pop \n\t" \
- " jo 0b \n\t" \
- " ipm %2 \n" \
- : "+a" (pOutput), "+a" (pInput), "+d" (cc), \
- "+d" (outlen), "+d" (inlen) \
- : \
- : "cc", "memory"); \
- \
- inptr = pInput; \
- outptr = pOutput; \
- cc >>= 28; \
- \
- if (cc == 1) \
- { \
- result = __GCONV_FULL_OUTPUT; \
- break; \
- } \
- else if (cc == 2) \
- { \
- result = __GCONV_ILLEGAL_INPUT; \
- break; \
- } \
- }
-
-/* Conversion function from UTF-8 to UTF-16. */
-
-#define MIN_NEEDED_INPUT MIN_NEEDED_FROM
-#define MAX_NEEDED_INPUT MAX_NEEDED_FROM
-#define MIN_NEEDED_OUTPUT MIN_NEEDED_TO
-#define MAX_NEEDED_OUTPUT MAX_NEEDED_TO
-#define LOOPFCT FROM_LOOP
-/* The software implementation is based on the code in gconv_simple.c. */
-#define BODY \
- { \
- if (GLRO (dl_hwcap) & HWCAP_S390_ETF3EH) \
- { \
- HARDWARE_CONVERT ("cu12 %0, %1, 1"); \
- \
- if (inptr != inend) \
- { \
- int i; \
- for (i = 1; inptr + i < inend; ++i) \
- if ((inptr[i] & 0xc0) != 0x80) \
- break; \
- \
- if (__glibc_likely (inptr + i == inend)) \
- { \
- result = __GCONV_INCOMPLETE_INPUT; \
- break; \
- } \
- STANDARD_FROM_LOOP_ERR_HANDLER (i); \
- } \
- continue; \
- } \
- \
- /* Next input byte. */ \
- uint16_t ch = *inptr; \
- \
- if (__glibc_likely (ch < 0x80)) \
- { \
- /* One byte sequence. */ \
- ++inptr; \
- } \
- else \
- { \
- uint_fast32_t cnt; \
- uint_fast32_t i; \
- \
- if (ch >= 0xc2 && ch < 0xe0) \
- { \
- /* We expect two bytes. The first byte cannot be 0xc0 \
- or 0xc1, otherwise the wide character could have been \
- represented using a single byte. */ \
- cnt = 2; \
- ch &= 0x1f; \
- } \
- else if (__glibc_likely ((ch & 0xf0) == 0xe0)) \
- { \
- /* We expect three bytes. */ \
- cnt = 3; \
- ch &= 0x0f; \
- } \
- else if (__glibc_likely ((ch & 0xf8) == 0xf0)) \
- { \
- /* We expect four bytes. */ \
- cnt = 4; \
- ch &= 0x07; \
- } \
- else \
- { \
- /* Search the end of this ill-formed UTF-8 character. This \
- is the next byte with (x & 0xc0) != 0x80. */ \
- i = 0; \
- do \
- ++i; \
- while (inptr + i < inend \
- && (*(inptr + i) & 0xc0) == 0x80 \
- && i < 5); \
- \
- errout: \
- STANDARD_FROM_LOOP_ERR_HANDLER (i); \
- } \
- \
- if (__glibc_unlikely (inptr + cnt > inend)) \
- { \
- /* We don't have enough input. But before we report \
- that check that all the bytes are correct. */ \
- for (i = 1; inptr + i < inend; ++i) \
- if ((inptr[i] & 0xc0) != 0x80) \
- break; \
- \
- if (__glibc_likely (inptr + i == inend)) \
- { \
- result = __GCONV_INCOMPLETE_INPUT; \
- break; \
- } \
- \
- goto errout; \
- } \
- \
- if (cnt == 4) \
- { \
- /* For 4 byte UTF-8 chars two UTF-16 chars (high and \
- low) are needed. */ \
- uint16_t zabcd, high, low; \
- \
- if (__glibc_unlikely (outptr + 4 > outend)) \
- { \
- /* Overflow in the output buffer. */ \
- result = __GCONV_FULL_OUTPUT; \
- break; \
- } \
- \
- /* See Principles of Operations cu12. */ \
- zabcd = (((inptr[0] & 0x7) << 2) | \
- ((inptr[1] & 0x30) >> 4)) - 1; \
- \
- /* z-bit must be zero after subtracting 1. */ \
- if (zabcd & 0x10) \
- STANDARD_FROM_LOOP_ERR_HANDLER (4) \
- \
- high = (uint16_t)(0xd8 << 8); /* high surrogate id */ \
- high |= zabcd << 6; /* abcd bits */ \
- high |= (inptr[1] & 0xf) << 2; /* efgh bits */ \
- high |= (inptr[2] & 0x30) >> 4; /* ij bits */ \
- \
- low = (uint16_t)(0xdc << 8); /* low surrogate id */ \
- low |= ((uint16_t)inptr[2] & 0xc) << 6; /* kl bits */ \
- low |= (inptr[2] & 0x3) << 6; /* mn bits */ \
- low |= inptr[3] & 0x3f; /* opqrst bits */ \
- \
- put16 (outptr, high); \
- outptr += 2; \
- put16 (outptr, low); \
- outptr += 2; \
- inptr += 4; \
- continue; \
- } \
- else \
- { \
- /* Read the possible remaining bytes. */ \
- for (i = 1; i < cnt; ++i) \
- { \
- uint16_t byte = inptr[i]; \
- \
- if ((byte & 0xc0) != 0x80) \
- /* This is an illegal encoding. */ \
- break; \
- \
- ch <<= 6; \
- ch |= byte & 0x3f; \
- } \
- inptr += cnt; \
- \
- } \
- } \
- /* Now adjust the pointers and store the result. */ \
- *((uint16_t *) outptr) = ch; \
- outptr += sizeof (uint16_t); \
- }
-
-#define LOOP_NEED_FLAGS
-#include <iconv/loop.c>
-
-/* Conversion from UTF-16 to UTF-8. */
-
-#define MIN_NEEDED_INPUT MIN_NEEDED_TO
-#define MAX_NEEDED_INPUT MAX_NEEDED_TO
-#define MIN_NEEDED_OUTPUT MIN_NEEDED_FROM
-#define MAX_NEEDED_OUTPUT MAX_NEEDED_FROM
-#define LOOPFCT TO_LOOP
-/* The software routine is based on the functionality of the S/390
- hardware instruction (cu21) as described in the Principles of
- Operation. */
-#define BODY \
- { \
- /* The hardware instruction currently fails to report an error for \
- isolated low surrogates so we have to disable the instruction \
- until this gets resolved. */ \
- if (0) /* (GLRO (dl_hwcap) & HWCAP_S390_ETF3EH) */ \
- { \
- HARDWARE_CONVERT ("cu21 %0, %1, 1"); \
- if (inptr != inend) \
- { \
- /* Check if the third byte is \
- a valid start of a UTF-16 surrogate. */ \
- if (inend - inptr == 3 && (inptr[3] & 0xfc) != 0xdc) \
- STANDARD_TO_LOOP_ERR_HANDLER (3); \
- \
- result = __GCONV_INCOMPLETE_INPUT; \
- break; \
- } \
- continue; \
- } \
- \
- uint16_t c = get16 (inptr); \
- \
- if (__glibc_likely (c <= 0x007f)) \
- { \
- /* Single byte UTF-8 char. */ \
- *outptr = c & 0xff; \
- outptr++; \
- } \
- else if (c >= 0x0080 && c <= 0x07ff) \
- { \
- /* Two byte UTF-8 char. */ \
- \
- if (__glibc_unlikely (outptr + 2 > outend)) \
- { \
- /* Overflow in the output buffer. */ \
- result = __GCONV_FULL_OUTPUT; \
- break; \
- } \
- \
- outptr[0] = 0xc0; \
- outptr[0] |= c >> 6; \
- \
- outptr[1] = 0x80; \
- outptr[1] |= c & 0x3f; \
- \
- outptr += 2; \
- } \
- else if ((c >= 0x0800 && c <= 0xd7ff) || c > 0xdfff) \
- { \
- /* Three byte UTF-8 char. */ \
- \
- if (__glibc_unlikely (outptr + 3 > outend)) \
- { \
- /* Overflow in the output buffer. */ \
- result = __GCONV_FULL_OUTPUT; \
- break; \
- } \
- outptr[0] = 0xe0; \
- outptr[0] |= c >> 12; \
- \
- outptr[1] = 0x80; \
- outptr[1] |= (c >> 6) & 0x3f; \
- \
- outptr[2] = 0x80; \
- outptr[2] |= c & 0x3f; \
- \
- outptr += 3; \
- } \
- else if (c >= 0xd800 && c <= 0xdbff) \
- { \
- /* Four byte UTF-8 char. */ \
- uint16_t low, uvwxy; \
- \
- if (__glibc_unlikely (outptr + 4 > outend)) \
- { \
- /* Overflow in the output buffer. */ \
- result = __GCONV_FULL_OUTPUT; \
- break; \
- } \
- inptr += 2; \
- if (__glibc_unlikely (inptr + 2 > inend)) \
- { \
- result = __GCONV_INCOMPLETE_INPUT; \
- break; \
- } \
- \
- low = get16 (inptr); \
- \
- if ((low & 0xfc00) != 0xdc00) \
- { \
- inptr -= 2; \
- STANDARD_TO_LOOP_ERR_HANDLER (2); \
- } \
- uvwxy = ((c >> 6) & 0xf) + 1; \
- outptr[0] = 0xf0; \
- outptr[0] |= uvwxy >> 2; \
- \
- outptr[1] = 0x80; \
- outptr[1] |= (uvwxy << 4) & 0x30; \
- outptr[1] |= (c >> 2) & 0x0f; \
- \
- outptr[2] = 0x80; \
- outptr[2] |= (c & 0x03) << 4; \
- outptr[2] |= (low >> 6) & 0x0f; \
- \
- outptr[3] = 0x80; \
- outptr[3] |= low & 0x3f; \
- \
- outptr += 4; \
- } \
- else \
- { \
- STANDARD_TO_LOOP_ERR_HANDLER (2); \
- } \
- inptr += 2; \
- }
-#define LOOP_NEED_FLAGS
-#include <iconv/loop.c>
-
-#include <iconv/skeleton.c>
diff --git a/sysdeps/s390/s390-64/utf8-utf32-z9.c b/sysdeps/s390/s390-64/utf8-utf32-z9.c
deleted file mode 100644
index defd47d251..0000000000
--- a/sysdeps/s390/s390-64/utf8-utf32-z9.c
+++ /dev/null
@@ -1,511 +0,0 @@
-/* Conversion between UTF-8 and UTF-32 BE/internal.
-
- This module uses the Z9-109 variants of the Convert Unicode
- instructions.
- Copyright (C) 1997-2016 Free Software Foundation, Inc.
-
- Author: Andreas Krebbel <Andreas.Krebbel@de.ibm.com>
- Based on the work by Ulrich Drepper <drepper@cygnus.com>, 1997.
-
- Thanks to Daniel Appich who covered the relevant performance work
- in his diploma thesis.
-
- This 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.
-
- This 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, see
- <http://www.gnu.org/licenses/>. */
-
-#include <dlfcn.h>
-#include <stdint.h>
-#include <unistd.h>
-#include <dl-procinfo.h>
-#include <gconv.h>
-
-/* UTF-32 big endian byte order mark. */
-#define BOM 0x0000feffu
-
-#define DEFINE_INIT 0
-#define DEFINE_FINI 0
-/* These definitions apply to the UTF-8 to UTF-32 direction. The
- software implementation for UTF-8 still supports multibyte
- characters up to 6 bytes whereas the hardware variant does not. */
-#define MIN_NEEDED_FROM 1
-#define MAX_NEEDED_FROM 6
-#define MIN_NEEDED_TO 4
-#define FROM_LOOP from_utf8_loop
-#define TO_LOOP to_utf8_loop
-#define FROM_DIRECTION (dir == from_utf8)
-#define ONE_DIRECTION 0
-#define PREPARE_LOOP \
- enum direction dir = ((struct utf8_data *) step->__data)->dir; \
- int emit_bom = ((struct utf8_data *) step->__data)->emit_bom; \
- \
- if (emit_bom && !data->__internal_use \
- && data->__invocation_counter == 0) \
- { \
- /* Emit the Byte Order Mark. */ \
- if (__glibc_unlikely (outbuf + 4 > outend)) \
- return __GCONV_FULL_OUTPUT; \
- \
- put32u (outbuf, BOM); \
- outbuf += 4; \
- }
-
-/* Direction of the transformation. */
-enum direction
-{
- illegal_dir,
- to_utf8,
- from_utf8
-};
-
-struct utf8_data
-{
- enum direction dir;
- int emit_bom;
-};
-
-
-extern int gconv_init (struct __gconv_step *step);
-int
-gconv_init (struct __gconv_step *step)
-{
- /* Determine which direction. */
- struct utf8_data *new_data;
- enum direction dir = illegal_dir;
- int emit_bom;
- int result;
-
- emit_bom = (__strcasecmp (step->__to_name, "UTF-32//") == 0);
-
- if (__strcasecmp (step->__from_name, "ISO-10646/UTF8/") == 0
- && (__strcasecmp (step->__to_name, "UTF-32//") == 0
- || __strcasecmp (step->__to_name, "UTF-32BE//") == 0
- || __strcasecmp (step->__to_name, "INTERNAL") == 0))
- {
- dir = from_utf8;
- }
- else if (__strcasecmp (step->__to_name, "ISO-10646/UTF8/") == 0
- && (__strcasecmp (step->__from_name, "UTF-32BE//") == 0
- || __strcasecmp (step->__from_name, "INTERNAL") == 0))
- {
- dir = to_utf8;
- }
-
- result = __GCONV_NOCONV;
- if (dir != illegal_dir)
- {
- new_data = (struct utf8_data *) malloc (sizeof (struct utf8_data));
-
- result = __GCONV_NOMEM;
- if (new_data != NULL)
- {
- new_data->dir = dir;
- new_data->emit_bom = emit_bom;
- step->__data = new_data;
-
- if (dir == from_utf8)
- {
- step->__min_needed_from = MIN_NEEDED_FROM;
- step->__max_needed_from = MIN_NEEDED_FROM;
- step->__min_needed_to = MIN_NEEDED_TO;
- step->__max_needed_to = MIN_NEEDED_TO;
- }
- else
- {
- step->__min_needed_from = MIN_NEEDED_TO;
- step->__max_needed_from = MIN_NEEDED_TO;
- step->__min_needed_to = MIN_NEEDED_FROM;
- step->__max_needed_to = MIN_NEEDED_FROM;
- }
-
- step->__stateful = 0;
-
- result = __GCONV_OK;
- }
- }
-
- return result;
-}
-
-
-extern void gconv_end (struct __gconv_step *data);
-void
-gconv_end (struct __gconv_step *data)
-{
- free (data->__data);
-}
-
-/* The macro for the hardware loop. This is used for both
- directions. */
-#define HARDWARE_CONVERT(INSTRUCTION) \
- { \
- register const unsigned char* pInput __asm__ ("8") = inptr; \
- register unsigned long long 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; \
- \
- __asm__ volatile (".machine push \n\t" \
- ".machine \"z9-109\" \n\t" \
- "0: " INSTRUCTION " \n\t" \
- ".machine pop \n\t" \
- " jo 0b \n\t" \
- " ipm %2 \n" \
- : "+a" (pOutput), "+a" (pInput), "+d" (cc), \
- "+d" (outlen), "+d" (inlen) \
- : \
- : "cc", "memory"); \
- \
- inptr = pInput; \
- outptr = pOutput; \
- cc >>= 28; \
- \
- if (cc == 1) \
- { \
- result = __GCONV_FULL_OUTPUT; \
- break; \
- } \
- else if (cc == 2) \
- { \
- result = __GCONV_ILLEGAL_INPUT; \
- break; \
- } \
- }
-
-/* Conversion function from UTF-8 to UTF-32 internal/BE. */
-
-#define MIN_NEEDED_INPUT MIN_NEEDED_FROM
-#define MAX_NEEDED_INPUT MAX_NEEDED_FROM
-#define MIN_NEEDED_OUTPUT MIN_NEEDED_TO
-#define LOOPFCT FROM_LOOP
-/* The software routine is copied from gconv_simple.c. */
-#define BODY \
- { \
- if (GLRO (dl_hwcap) & HWCAP_S390_ETF3EH) \
- { \
- HARDWARE_CONVERT ("cu14 %0, %1, 1"); \
- \
- if (inptr != inend) \
- { \
- int i; \
- for (i = 1; inptr + i < inend; ++i) \
- if ((inptr[i] & 0xc0) != 0x80) \
- break; \
- \
- if (__glibc_likely (inptr + i == inend)) \
- { \
- result = __GCONV_INCOMPLETE_INPUT; \
- break; \
- } \
- STANDARD_FROM_LOOP_ERR_HANDLER (i); \
- } \
- continue; \
- } \
- \
- /* Next input byte. */ \
- uint32_t ch = *inptr; \
- \
- if (__glibc_likely (ch < 0x80)) \
- { \
- /* One byte sequence. */ \
- ++inptr; \
- } \
- else \
- { \
- uint_fast32_t cnt; \
- uint_fast32_t i; \
- \
- if (ch >= 0xc2 && ch < 0xe0) \
- { \
- /* We expect two bytes. The first byte cannot be 0xc0 or \
- 0xc1, otherwise the wide character could have been \
- represented using a single byte. */ \
- cnt = 2; \
- ch &= 0x1f; \
- } \
- else if (__glibc_likely ((ch & 0xf0) == 0xe0)) \
- { \
- /* We expect three bytes. */ \
- cnt = 3; \
- ch &= 0x0f; \
- } \
- else if (__glibc_likely ((ch & 0xf8) == 0xf0)) \
- { \
- /* We expect four bytes. */ \
- cnt = 4; \
- ch &= 0x07; \
- } \
- else if (__glibc_likely ((ch & 0xfc) == 0xf8)) \
- { \
- /* We expect five bytes. */ \
- cnt = 5; \
- ch &= 0x03; \
- } \
- else if (__glibc_likely ((ch & 0xfe) == 0xfc)) \
- { \
- /* We expect six bytes. */ \
- cnt = 6; \
- ch &= 0x01; \
- } \
- else \
- { \
- /* Search the end of this ill-formed UTF-8 character. This \
- is the next byte with (x & 0xc0) != 0x80. */ \
- i = 0; \
- do \
- ++i; \
- while (inptr + i < inend \
- && (*(inptr + i) & 0xc0) == 0x80 \
- && i < 5); \
- \
- errout: \
- STANDARD_FROM_LOOP_ERR_HANDLER (i); \
- } \
- \
- if (__glibc_unlikely (inptr + cnt > inend)) \
- { \
- /* We don't have enough input. But before we report \
- that check that all the bytes are correct. */ \
- for (i = 1; inptr + i < inend; ++i) \
- if ((inptr[i] & 0xc0) != 0x80) \
- break; \
- \
- if (__glibc_likely (inptr + i == inend)) \
- { \
- result = __GCONV_INCOMPLETE_INPUT; \
- break; \
- } \
- \
- goto errout; \
- } \
- \
- /* Read the possible remaining bytes. */ \
- for (i = 1; i < cnt; ++i) \
- { \
- uint32_t byte = inptr[i]; \
- \
- if ((byte & 0xc0) != 0x80) \
- /* This is an illegal encoding. */ \
- break; \
- \
- ch <<= 6; \
- ch |= byte & 0x3f; \
- } \
- \
- /* If i < cnt, some trail byte was not >= 0x80, < 0xc0. \
- If cnt > 2 and ch < 2^(5*cnt-4), the wide character ch could \
- have been represented with fewer than cnt bytes. */ \
- if (i < cnt || (cnt > 2 && (ch >> (5 * cnt - 4)) == 0)) \
- { \
- /* This is an illegal encoding. */ \
- goto errout; \
- } \
- \
- inptr += cnt; \
- } \
- \
- /* Now adjust the pointers and store the result. */ \
- *((uint32_t *) outptr) = ch; \
- outptr += sizeof (uint32_t); \
- }
-#define LOOP_NEED_FLAGS
-
-#define STORE_REST \
- { \
- /* We store the remaining bytes while converting them into the UCS4 \
- format. We can assume that the first byte in the buffer is \
- correct and that it requires a larger number of bytes than there \
- are in the input buffer. */ \
- wint_t ch = **inptrp; \
- size_t cnt, r; \
- \
- state->__count = inend - *inptrp; \
- \
- if (ch >= 0xc2 && ch < 0xe0) \
- { \
- /* We expect two bytes. The first byte cannot be 0xc0 or \
- 0xc1, otherwise the wide character could have been \
- represented using a single byte. */ \
- cnt = 2; \
- ch &= 0x1f; \
- } \
- else if (__glibc_likely ((ch & 0xf0) == 0xe0)) \
- { \
- /* We expect three bytes. */ \
- cnt = 3; \
- ch &= 0x0f; \
- } \
- else if (__glibc_likely ((ch & 0xf8) == 0xf0)) \
- { \
- /* We expect four bytes. */ \
- cnt = 4; \
- ch &= 0x07; \
- } \
- else if (__glibc_likely ((ch & 0xfc) == 0xf8)) \
- { \
- /* We expect five bytes. */ \
- cnt = 5; \
- ch &= 0x03; \
- } \
- else \
- { \
- /* We expect six bytes. */ \
- cnt = 6; \
- ch &= 0x01; \
- } \
- \
- /* The first byte is already consumed. */ \
- r = cnt - 1; \
- while (++(*inptrp) < inend) \
- { \
- ch <<= 6; \
- ch |= **inptrp & 0x3f; \
- --r; \
- } \
- \
- /* Shift for the so far missing bytes. */ \
- ch <<= r * 6; \
- \
- /* Store the number of bytes expected for the entire sequence. */ \
- state->__count |= cnt << 8; \
- \
- /* Store the value. */ \
- state->__value.__wch = ch; \
- }
-
-#define UNPACK_BYTES \
- { \
- static const unsigned char inmask[5] = { 0xc0, 0xe0, 0xf0, 0xf8, 0xfc }; \
- wint_t wch = state->__value.__wch; \
- size_t ntotal = state->__count >> 8; \
- \
- inlen = state->__count & 255; \
- \
- bytebuf[0] = inmask[ntotal - 2]; \
- \
- do \
- { \
- if (--ntotal < inlen) \
- bytebuf[ntotal] = 0x80 | (wch & 0x3f); \
- wch >>= 6; \
- } \
- while (ntotal > 1); \
- \
- bytebuf[0] |= wch; \
- }
-
-#define CLEAR_STATE \
- state->__count = 0
-
-#include <iconv/loop.c>
-
-/* Conversion from UTF-32 internal/BE to UTF-8. */
-
-#define MIN_NEEDED_INPUT MIN_NEEDED_TO
-#define MIN_NEEDED_OUTPUT MIN_NEEDED_FROM
-#define MAX_NEEDED_OUTPUT MAX_NEEDED_FROM
-#define LOOPFCT TO_LOOP
-/* The software routine mimics the S/390 cu41 instruction. */
-#define BODY \
- { \
- if (GLRO (dl_hwcap) & HWCAP_S390_ETF3EH) \
- { \
- HARDWARE_CONVERT ("cu41 %0, %1"); \
- \
- if (inptr != inend) \
- { \
- result = __GCONV_INCOMPLETE_INPUT; \
- break; \
- } \
- continue; \
- } \
- \
- uint32_t wc = *((const uint32_t *) inptr); \
- \
- if (__glibc_likely (wc <= 0x7f)) \
- { \
- /* Single UTF-8 char. */ \
- *outptr = (uint8_t)wc; \
- outptr++; \
- } \
- else if (wc <= 0x7ff) \
- { \
- /* Two UTF-8 chars. */ \
- if (__glibc_unlikely (outptr + 2 > outend)) \
- { \
- /* Overflow in the output buffer. */ \
- result = __GCONV_FULL_OUTPUT; \
- break; \
- } \
- \
- outptr[0] = 0xc0; \
- outptr[0] |= wc >> 6; \
- \
- outptr[1] = 0x80; \
- outptr[1] |= wc & 0x3f; \
- \
- outptr += 2; \
- } \
- else if (wc <= 0xffff) \
- { \
- /* Three UTF-8 chars. */ \
- if (__glibc_unlikely (outptr + 3 > outend)) \
- { \
- /* Overflow in the output buffer. */ \
- result = __GCONV_FULL_OUTPUT; \
- break; \
- } \
- outptr[0] = 0xe0; \
- outptr[0] |= wc >> 12; \
- \
- outptr[1] = 0x80; \
- outptr[1] |= (wc >> 6) & 0x3f; \
- \
- outptr[2] = 0x80; \
- outptr[2] |= wc & 0x3f; \
- \
- outptr += 3; \
- } \
- else if (wc <= 0x10ffff) \
- { \
- /* Four UTF-8 chars. */ \
- if (__glibc_unlikely (outptr + 4 > outend)) \
- { \
- /* Overflow in the output buffer. */ \
- result = __GCONV_FULL_OUTPUT; \
- break; \
- } \
- outptr[0] = 0xf0; \
- outptr[0] |= wc >> 18; \
- \
- outptr[1] = 0x80; \
- outptr[1] |= (wc >> 12) & 0x3f; \
- \
- outptr[2] = 0x80; \
- outptr[2] |= (wc >> 6) & 0x3f; \
- \
- outptr[3] = 0x80; \
- outptr[3] |= wc & 0x3f; \
- \
- outptr += 4; \
- } \
- else \
- { \
- STANDARD_TO_LOOP_ERR_HANDLER (4); \
- } \
- inptr += 4; \
- }
-#define LOOP_NEED_FLAGS
-#include <iconv/loop.c>
-
-#include <iconv/skeleton.c>
diff --git a/sysdeps/s390/sotruss-lib.c b/sysdeps/s390/sotruss-lib.c
index 8c53bc5b79..90b8f77e55 100644
--- a/sysdeps/s390/sotruss-lib.c
+++ b/sysdeps/s390/sotruss-lib.c
@@ -1,5 +1,5 @@
/* Override generic sotruss-lib.c to define actual functions for s390.
- Copyright (C) 2012-2016 Free Software Foundation, Inc.
+ Copyright (C) 2012-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
diff --git a/sysdeps/s390/stackinfo.h b/sysdeps/s390/stackinfo.h
index 0d4b70abd7..e429f361ae 100644
--- a/sysdeps/s390/stackinfo.h
+++ b/sysdeps/s390/stackinfo.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000-2016 Free Software Foundation, Inc.
+/* Copyright (C) 2000-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
diff --git a/sysdeps/s390/string_private.h b/sysdeps/s390/string_private.h
index 9e11eee3dc..32e40d3603 100644
--- a/sysdeps/s390/string_private.h
+++ b/sysdeps/s390/string_private.h
@@ -1,5 +1,5 @@
/* Define _STRING_ARCH_unaligned. S/390 version.
- Copyright (C) 2016 Free Software Foundation, Inc.
+ Copyright (C) 2016-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
diff --git a/sysdeps/s390/utf16-utf32-z9.c b/sysdeps/s390/utf16-utf32-z9.c
new file mode 100644
index 0000000000..27086d3e8a
--- /dev/null
+++ b/sysdeps/s390/utf16-utf32-z9.c
@@ -0,0 +1,819 @@
+/* Conversion between UTF-16 and UTF-32 BE/internal.
+
+ This module uses the Z9-109 variants of the Convert Unicode
+ instructions.
+ Copyright (C) 1997-2018 Free Software Foundation, Inc.
+
+ Author: Andreas Krebbel <Andreas.Krebbel@de.ibm.com>
+ Based on the work by Ulrich Drepper <drepper@cygnus.com>, 1997.
+
+ Thanks to Daniel Appich who covered the relevant performance work
+ in his diploma thesis.
+
+ This 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.
+
+ This 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, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <dlfcn.h>
+#include <stdint.h>
+#include <unistd.h>
+#include <gconv.h>
+#include <string.h>
+
+/* Select which versions should be defined depending on support
+ for multiarch, vector and used minimum architecture level. */
+#define HAVE_FROM_C 1
+#define FROM_LOOP_DEFAULT FROM_LOOP_C
+#define HAVE_TO_C 1
+#define TO_LOOP_DEFAULT TO_LOOP_C
+
+#if defined HAVE_S390_VX_ASM_SUPPORT && defined USE_MULTIARCH
+# define HAVE_FROM_VX 1
+# define HAVE_FROM_VX_CU 1
+# define HAVE_TO_VX 1
+# define HAVE_TO_VX_CU 1
+#else
+# define HAVE_FROM_VX 0
+# define HAVE_FROM_VX_CU 0
+# define HAVE_TO_VX 0
+# define HAVE_TO_VX_CU 0
+#endif
+
+#if defined HAVE_S390_VX_GCC_SUPPORT
+# define ASM_CLOBBER_VR(NR) , NR
+#else
+# 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
+
+/* UTF-16 big endian byte order mark. */
+#define BOM_UTF16 0xfeff
+
+#define DEFINE_INIT 0
+#define DEFINE_FINI 0
+#define MIN_NEEDED_FROM 2
+#define MAX_NEEDED_FROM 4
+#define MIN_NEEDED_TO 4
+#define FROM_LOOP FROM_LOOP_DEFAULT
+#define TO_LOOP TO_LOOP_DEFAULT
+#define FROM_DIRECTION (dir == from_utf16)
+#define ONE_DIRECTION 0
+
+/* Direction of the transformation. */
+enum direction
+{
+ illegal_dir,
+ to_utf16,
+ from_utf16
+};
+
+struct utf16_data
+{
+ enum direction dir;
+ int emit_bom;
+};
+
+
+extern int gconv_init (struct __gconv_step *step);
+int
+gconv_init (struct __gconv_step *step)
+{
+ /* Determine which direction. */
+ struct utf16_data *new_data;
+ enum direction dir = illegal_dir;
+ int emit_bom;
+ int result;
+
+ emit_bom = (__strcasecmp (step->__to_name, "UTF-32//") == 0
+ || __strcasecmp (step->__to_name, "UTF-16//") == 0);
+
+ if (__strcasecmp (step->__from_name, "UTF-16BE//") == 0
+ && (__strcasecmp (step->__to_name, "UTF-32//") == 0
+ || __strcasecmp (step->__to_name, "UTF-32BE//") == 0
+ || __strcasecmp (step->__to_name, "INTERNAL") == 0))
+ {
+ dir = from_utf16;
+ }
+ else if ((__strcasecmp (step->__to_name, "UTF-16//") == 0
+ || __strcasecmp (step->__to_name, "UTF-16BE//") == 0)
+ && (__strcasecmp (step->__from_name, "UTF-32BE//") == 0
+ || __strcasecmp (step->__from_name, "INTERNAL") == 0))
+ {
+ dir = to_utf16;
+ }
+
+ result = __GCONV_NOCONV;
+ if (dir != illegal_dir)
+ {
+ new_data = (struct utf16_data *) malloc (sizeof (struct utf16_data));
+
+ result = __GCONV_NOMEM;
+ if (new_data != NULL)
+ {
+ new_data->dir = dir;
+ new_data->emit_bom = emit_bom;
+ step->__data = new_data;
+
+ if (dir == from_utf16)
+ {
+ step->__min_needed_from = MIN_NEEDED_FROM;
+ step->__max_needed_from = MIN_NEEDED_FROM;
+ step->__min_needed_to = MIN_NEEDED_TO;
+ step->__max_needed_to = MIN_NEEDED_TO;
+ }
+ else
+ {
+ step->__min_needed_from = MIN_NEEDED_TO;
+ step->__max_needed_from = MIN_NEEDED_TO;
+ step->__min_needed_to = MIN_NEEDED_FROM;
+ step->__max_needed_to = MIN_NEEDED_FROM;
+ }
+
+ step->__stateful = 0;
+
+ result = __GCONV_OK;
+ }
+ }
+
+ return result;
+}
+
+
+extern void gconv_end (struct __gconv_step *data);
+void
+gconv_end (struct __gconv_step *data)
+{
+ free (data->__data);
+}
+
+#define PREPARE_LOOP \
+ enum direction dir = ((struct utf16_data *) step->__data)->dir; \
+ int emit_bom = ((struct utf16_data *) step->__data)->emit_bom; \
+ \
+ if (emit_bom && !data->__internal_use \
+ && data->__invocation_counter == 0) \
+ { \
+ if (dir == to_utf16) \
+ { \
+ /* Emit the UTF-16 Byte Order Mark. */ \
+ if (__glibc_unlikely (outbuf + 2 > outend)) \
+ return __GCONV_FULL_OUTPUT; \
+ \
+ put16u (outbuf, BOM_UTF16); \
+ outbuf += 2; \
+ } \
+ else \
+ { \
+ /* Emit the UTF-32 Byte Order Mark. */ \
+ if (__glibc_unlikely (outbuf + 4 > outend)) \
+ return __GCONV_FULL_OUTPUT; \
+ \
+ put32u (outbuf, BOM_UTF32); \
+ outbuf += 4; \
+ } \
+ }
+
+/* Conversion function from UTF-16 to UTF-32 internal/BE. */
+
+#if HAVE_FROM_C == 1
+/* The software routine is copied from utf-16.c (minus bytes
+ swapping). */
+# define BODY_FROM_C \
+ { \
+ uint16_t u1 = get16 (inptr); \
+ \
+ if (__builtin_expect (u1 < 0xd800, 1) || u1 > 0xdfff) \
+ { \
+ /* No surrogate. */ \
+ put32 (outptr, u1); \
+ inptr += 2; \
+ } \
+ else \
+ { \
+ /* An isolated low-surrogate was found. This has to be \
+ considered ill-formed. */ \
+ if (__glibc_unlikely (u1 >= 0xdc00)) \
+ { \
+ STANDARD_FROM_LOOP_ERR_HANDLER (2); \
+ } \
+ /* It's a surrogate character. At least the first word says \
+ it is. */ \
+ if (__glibc_unlikely (inptr + 4 > inend)) \
+ { \
+ /* We don't have enough input for another complete input \
+ character. */ \
+ result = __GCONV_INCOMPLETE_INPUT; \
+ break; \
+ } \
+ \
+ inptr += 2; \
+ uint16_t u2 = get16 (inptr); \
+ if (__builtin_expect (u2 < 0xdc00, 0) \
+ || __builtin_expect (u2 > 0xdfff, 0)) \
+ { \
+ /* This is no valid second word for a surrogate. */ \
+ inptr -= 2; \
+ STANDARD_FROM_LOOP_ERR_HANDLER (2); \
+ } \
+ \
+ put32 (outptr, ((u1 - 0xd7c0) << 10) + (u2 - 0xdc00)); \
+ inptr += 2; \
+ } \
+ outptr += 4; \
+ }
+
+
+/* Generate loop-function with software routing. */
+# define MIN_NEEDED_INPUT MIN_NEEDED_FROM
+# define MAX_NEEDED_INPUT MAX_NEEDED_FROM
+# define MIN_NEEDED_OUTPUT MIN_NEEDED_TO
+# define FROM_LOOP_C __from_utf16_loop_c
+# define LOOPFCT FROM_LOOP_C
+# define LOOP_NEED_FLAGS
+# define BODY BODY_FROM_C
+# include <iconv/loop.c>
+#else
+# define FROM_LOOP_C NULL
+#endif /* HAVE_FROM_C != 1 */
+
+#if HAVE_FROM_VX == 1
+# define BODY_FROM_VX \
+ { \
+ size_t inlen = inend - inptr; \
+ size_t outlen = outend - outptr; \
+ unsigned long tmp, tmp2, tmp3; \
+ asm volatile (".machine push\n\t" \
+ ".machine \"z13\"\n\t" \
+ ".machinemode \"zarch_nohighgprs\"\n\t" \
+ /* 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" \
+ "1: vl %%v16,0(%[R_IN])\n\t" \
+ /* Check for surrogate chars. */ \
+ " vstrchs %%v19,%%v16,%%v30,%%v31\n\t" \
+ " jno 10f\n\t" \
+ /* Enlarge to UTF-32. */ \
+ " vuplhh %%v17,%%v16\n\t" \
+ " la %[R_IN],16(%[R_IN])\n\t" \
+ " vupllh %%v18,%%v16\n\t" \
+ " aghi %[R_INLEN],-16\n\t" \
+ /* Store 32 bytes to buf_out. */ \
+ " vstm %%v17,%%v18,0(%[R_OUT])\n\t" \
+ " aghi %[R_OUTLEN],-32\n\t" \
+ " la %[R_OUT],32(%[R_OUT])\n\t" \
+ " clgijl %[R_INLEN],16,2f\n\t" \
+ " clgijl %[R_OUTLEN],32,2f\n\t" \
+ " j 1b\n\t" \
+ /* Setup to check for ch >= 0xd800 && ch <= 0xdfff. (v30, v31) */ \
+ "9: .short 0xd800,0xdfff,0x0,0x0,0x0,0x0,0x0,0x0\n\t" \
+ " .short 0xa000,0xc000,0x0,0x0,0x0,0x0,0x0,0x0\n\t" \
+ /* At least one uint16_t is in range of surrogates. \
+ Store the preceding chars. */ \
+ "10: vlgvb %[R_TMP],%%v19,7\n\t" \
+ " vuplhh %%v17,%%v16\n\t" \
+ " sllg %[R_TMP3],%[R_TMP],1\n\t" /* Number of out bytes. */ \
+ " ahik %[R_TMP2],%[R_TMP3],-1\n\t" /* Highest index to store. */ \
+ " jl 12f\n\t" \
+ " vstl %%v17,%[R_TMP2],0(%[R_OUT])\n\t" \
+ " vupllh %%v18,%%v16\n\t" \
+ " ahi %[R_TMP2],-16\n\t" \
+ " jl 11f\n\t" \
+ " vstl %%v18,%[R_TMP2],16(%[R_OUT])\n\t" \
+ "11: \n\t" /* Update pointers. */ \
+ " la %[R_IN],0(%[R_TMP],%[R_IN])\n\t" \
+ " slgr %[R_INLEN],%[R_TMP]\n\t" \
+ " la %[R_OUT],0(%[R_TMP3],%[R_OUT])\n\t" \
+ " slgr %[R_OUTLEN],%[R_TMP3]\n\t" \
+ /* Calculate remaining uint16_t values in loaded vrs. */ \
+ "12: lghi %[R_TMP2],16\n\t" \
+ " slgr %[R_TMP2],%[R_TMP]\n\t" \
+ " srl %[R_TMP2],1\n\t" \
+ " llh %[R_TMP],0(%[R_IN])\n\t" \
+ " aghi %[R_OUTLEN],-4\n\t" \
+ " j 16f\n\t" \
+ /* Handle remaining bytes. */ \
+ "2: \n\t" \
+ /* Zero, one or more bytes available? */ \
+ " clgfi %[R_INLEN],1\n\t" \
+ " je 97f\n\t" /* Only one byte available. */ \
+ " jl 99f\n\t" /* End if no bytes available. */ \
+ /* Calculate remaining uint16_t values in inptr. */ \
+ " srlg %[R_TMP2],%[R_INLEN],1\n\t" \
+ /* Handle remaining uint16_t values. */ \
+ "13: llh %[R_TMP],0(%[R_IN])\n\t" \
+ " slgfi %[R_OUTLEN],4\n\t" \
+ " jl 96f \n\t" \
+ " clfi %[R_TMP],0xd800\n\t" \
+ " jhe 15f\n\t" \
+ "14: st %[R_TMP],0(%[R_OUT])\n\t" \
+ " la %[R_IN],2(%[R_IN])\n\t" \
+ " aghi %[R_INLEN],-2\n\t" \
+ " la %[R_OUT],4(%[R_OUT])\n\t" \
+ " brctg %[R_TMP2],13b\n\t" \
+ " j 0b\n\t" /* Switch to vx-loop. */ \
+ /* Handle UTF-16 surrogate pair. */ \
+ "15: clfi %[R_TMP],0xdfff\n\t" \
+ " jh 14b\n\t" /* Jump away if ch > 0xdfff. */ \
+ "16: clfi %[R_TMP],0xdc00\n\t" \
+ " jhe 98f\n\t" /* Jump away in case of low-surrogate. */ \
+ " slgfi %[R_INLEN],4\n\t" \
+ " jl 97f\n\t" /* Big enough input? */ \
+ " llh %[R_TMP3],2(%[R_IN])\n\t" /* Load low surrogate. */ \
+ " slfi %[R_TMP],0xd7c0\n\t" \
+ " sll %[R_TMP],10\n\t" \
+ " risbgn %[R_TMP],%[R_TMP3],54,63,0\n\t" /* Insert klmnopqrst. */ \
+ " nilf %[R_TMP3],0xfc00\n\t" \
+ " clfi %[R_TMP3],0xdc00\n\t" /* Check if it starts with 0xdc00. */ \
+ " jne 98f\n\t" \
+ " st %[R_TMP],0(%[R_OUT])\n\t" \
+ " la %[R_IN],4(%[R_IN])\n\t" \
+ " la %[R_OUT],4(%[R_OUT])\n\t" \
+ " aghi %[R_TMP2],-2\n\t" \
+ " jh 13b\n\t" /* Handle remaining uint16_t values. */ \
+ " j 0b\n\t" /* Switch to vx-loop. */ \
+ "96: \n\t" /* Return full output. */ \
+ " lghi %[R_RES],%[RES_OUT_FULL]\n\t" \
+ " j 99f\n\t" \
+ "97: \n\t" /* Return incomplete input. */ \
+ " lghi %[R_RES],%[RES_IN_FULL]\n\t" \
+ " j 99f\n\t" \
+ "98:\n\t" /* Return Illegal character. */ \
+ " lghi %[R_RES],%[RES_IN_ILL]\n\t" \
+ "99:\n\t" \
+ ".machine pop" \
+ : /* outputs */ [R_IN] "+a" (inptr) \
+ , [R_INLEN] "+d" (inlen), [R_OUT] "+a" (outptr) \
+ , [R_OUTLEN] "+d" (outlen), [R_TMP] "=a" (tmp) \
+ , [R_TMP2] "=d" (tmp2), [R_TMP3] "=a" (tmp3) \
+ , [R_RES] "+d" (result) \
+ : /* inputs */ \
+ [RES_OUT_FULL] "i" (__GCONV_FULL_OUTPUT) \
+ , [RES_IN_ILL] "i" (__GCONV_ILLEGAL_INPUT) \
+ , [RES_IN_FULL] "i" (__GCONV_INCOMPLETE_INPUT) \
+ : /* clobber list */ "memory", "cc" \
+ ASM_CLOBBER_VR ("v16") ASM_CLOBBER_VR ("v17") \
+ ASM_CLOBBER_VR ("v18") ASM_CLOBBER_VR ("v19") \
+ ASM_CLOBBER_VR ("v30") ASM_CLOBBER_VR ("v31") \
+ ); \
+ if (__glibc_likely (inptr == inend) \
+ || result != __GCONV_ILLEGAL_INPUT) \
+ break; \
+ \
+ STANDARD_FROM_LOOP_ERR_HANDLER (2); \
+ }
+
+/* Generate loop-function with hardware vector instructions. */
+# define MIN_NEEDED_INPUT MIN_NEEDED_FROM
+# define MAX_NEEDED_INPUT MAX_NEEDED_FROM
+# define MIN_NEEDED_OUTPUT MIN_NEEDED_TO
+# define FROM_LOOP_VX __from_utf16_loop_vx
+# define LOOPFCT FROM_LOOP_VX
+# define LOOP_NEED_FLAGS
+# define BODY BODY_FROM_VX
+# include <iconv/loop.c>
+#else
+# define FROM_LOOP_VX NULL
+#endif /* HAVE_FROM_VX != 1 */
+
+#if HAVE_FROM_VX_CU == 1
+#define BODY_FROM_VX_CU \
+ { \
+ register const unsigned char* pInput asm ("8") = inptr; \
+ register size_t inlen asm ("9") = inend - inptr; \
+ register unsigned char* pOutput asm ("10") = outptr; \
+ register size_t outlen asm ("11") = outend - outptr; \
+ unsigned long tmp, tmp2, tmp3; \
+ asm volatile (".machine push\n\t" \
+ ".machine \"z13\"\n\t" \
+ ".machinemode \"zarch_nohighgprs\"\n\t" \
+ /* 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,20f\n\t" \
+ " clgijl %[R_OUTLEN],32,20f\n\t" \
+ "1: vl %%v16,0(%[R_IN])\n\t" \
+ /* Check for surrogate chars. */ \
+ " vstrchs %%v19,%%v16,%%v30,%%v31\n\t" \
+ " jno 10f\n\t" \
+ /* Enlarge to UTF-32. */ \
+ " vuplhh %%v17,%%v16\n\t" \
+ " la %[R_IN],16(%[R_IN])\n\t" \
+ " vupllh %%v18,%%v16\n\t" \
+ " aghi %[R_INLEN],-16\n\t" \
+ /* Store 32 bytes to buf_out. */ \
+ " vstm %%v17,%%v18,0(%[R_OUT])\n\t" \
+ " aghi %[R_OUTLEN],-32\n\t" \
+ " la %[R_OUT],32(%[R_OUT])\n\t" \
+ " clgijl %[R_INLEN],16,20f\n\t" \
+ " clgijl %[R_OUTLEN],32,20f\n\t" \
+ " j 1b\n\t" \
+ /* Setup to check for ch >= 0xd800 && ch <= 0xdfff. (v30, v31) */ \
+ "9: .short 0xd800,0xdfff,0x0,0x0,0x0,0x0,0x0,0x0\n\t" \
+ " .short 0xa000,0xc000,0x0,0x0,0x0,0x0,0x0,0x0\n\t" \
+ /* At least one uint16_t is in range of surrogates. \
+ Store the preceding chars. */ \
+ "10: vlgvb %[R_TMP],%%v19,7\n\t" \
+ " vuplhh %%v17,%%v16\n\t" \
+ " sllg %[R_TMP3],%[R_TMP],1\n\t" /* Number of out bytes. */ \
+ " ahik %[R_TMP2],%[R_TMP3],-1\n\t" /* Highest index to store. */ \
+ " jl 20f\n\t" \
+ " vstl %%v17,%[R_TMP2],0(%[R_OUT])\n\t" \
+ " vupllh %%v18,%%v16\n\t" \
+ " ahi %[R_TMP2],-16\n\t" \
+ " jl 11f\n\t" \
+ " vstl %%v18,%[R_TMP2],16(%[R_OUT])\n\t" \
+ "11: \n\t" /* Update pointers. */ \
+ " la %[R_IN],0(%[R_TMP],%[R_IN])\n\t" \
+ " slgr %[R_INLEN],%[R_TMP]\n\t" \
+ " la %[R_OUT],0(%[R_TMP3],%[R_OUT])\n\t" \
+ " slgr %[R_OUTLEN],%[R_TMP3]\n\t" \
+ /* Handles UTF16 surrogates with convert instruction. */ \
+ "20: cu24 %[R_OUT],%[R_IN],1\n\t" \
+ " jo 0b\n\t" /* Try vector implemenation again. */ \
+ " lochil %[R_RES],%[RES_OUT_FULL]\n\t" /* cc == 1. */ \
+ " lochih %[R_RES],%[RES_IN_ILL]\n\t" /* cc == 2. */ \
+ ".machine pop" \
+ : /* outputs */ [R_IN] "+a" (pInput) \
+ , [R_INLEN] "+d" (inlen), [R_OUT] "+a" (pOutput) \
+ , [R_OUTLEN] "+d" (outlen), [R_TMP] "=a" (tmp) \
+ , [R_TMP2] "=d" (tmp2), [R_TMP3] "=a" (tmp3) \
+ , [R_RES] "+d" (result) \
+ : /* inputs */ \
+ [RES_OUT_FULL] "i" (__GCONV_FULL_OUTPUT) \
+ , [RES_IN_ILL] "i" (__GCONV_ILLEGAL_INPUT) \
+ : /* clobber list */ "memory", "cc" \
+ ASM_CLOBBER_VR ("v16") ASM_CLOBBER_VR ("v17") \
+ ASM_CLOBBER_VR ("v18") ASM_CLOBBER_VR ("v19") \
+ ASM_CLOBBER_VR ("v30") ASM_CLOBBER_VR ("v31") \
+ ); \
+ inptr = pInput; \
+ outptr = pOutput; \
+ \
+ if (__glibc_likely (inlen == 0) \
+ || result == __GCONV_FULL_OUTPUT) \
+ break; \
+ if (inlen == 1) \
+ { \
+ /* Input does not contain a complete utf16 character. */ \
+ result = __GCONV_INCOMPLETE_INPUT; \
+ break; \
+ } \
+ else if (result != __GCONV_ILLEGAL_INPUT) \
+ { \
+ /* Input is >= 2 and < 4 bytes (as cu24 would have processed \
+ a possible next utf16 character) and not illegal. \
+ => we have a single high surrogate at end of input. */ \
+ result = __GCONV_INCOMPLETE_INPUT; \
+ break; \
+ } \
+ \
+ STANDARD_FROM_LOOP_ERR_HANDLER (2); \
+ }
+
+/* Generate loop-function with hardware vector and utf-convert instructions. */
+# define MIN_NEEDED_INPUT MIN_NEEDED_FROM
+# define MAX_NEEDED_INPUT MAX_NEEDED_FROM
+# define MIN_NEEDED_OUTPUT MIN_NEEDED_TO
+# define FROM_LOOP_VX_CU __from_utf16_loop_vx_cu
+# define LOOPFCT FROM_LOOP_VX_CU
+# define LOOP_NEED_FLAGS
+# define BODY BODY_FROM_VX_CU
+# include <iconv/loop.c>
+#else
+# define FROM_LOOP_VX_CU NULL
+#endif /* HAVE_FROM_VX_CU != 1 */
+
+/* Conversion from UTF-32 internal/BE to UTF-16. */
+
+#if HAVE_TO_C == 1
+/* The software routine is copied from utf-16.c (minus bytes
+ swapping). */
+# define BODY_TO_C \
+ { \
+ uint32_t c = get32 (inptr); \
+ \
+ if (__builtin_expect (c <= 0xd7ff, 1) \
+ || (c > 0xdfff && c <= 0xffff)) \
+ { \
+ /* Two UTF-16 chars. */ \
+ put16 (outptr, c); \
+ } \
+ else if (__builtin_expect (c >= 0x10000, 1) \
+ && __builtin_expect (c <= 0x10ffff, 1)) \
+ { \
+ /* Four UTF-16 chars. */ \
+ uint16_t zabcd = ((c & 0x1f0000) >> 16) - 1; \
+ uint16_t out; \
+ \
+ /* Generate a surrogate character. */ \
+ if (__glibc_unlikely (outptr + 4 > outend)) \
+ { \
+ /* Overflow in the output buffer. */ \
+ result = __GCONV_FULL_OUTPUT; \
+ break; \
+ } \
+ \
+ out = 0xd800; \
+ out |= (zabcd & 0xff) << 6; \
+ out |= (c >> 10) & 0x3f; \
+ put16 (outptr, out); \
+ outptr += 2; \
+ \
+ out = 0xdc00; \
+ out |= c & 0x3ff; \
+ put16 (outptr, out); \
+ } \
+ else \
+ { \
+ STANDARD_TO_LOOP_ERR_HANDLER (4); \
+ } \
+ outptr += 2; \
+ inptr += 4; \
+ }
+
+/* Generate loop-function with software routing. */
+# define MIN_NEEDED_INPUT MIN_NEEDED_TO
+# define MIN_NEEDED_OUTPUT MIN_NEEDED_FROM
+# define MAX_NEEDED_OUTPUT MAX_NEEDED_FROM
+# define TO_LOOP_C __to_utf16_loop_c
+# define LOOPFCT TO_LOOP_C
+# define LOOP_NEED_FLAGS
+# define BODY BODY_TO_C
+# include <iconv/loop.c>
+#else
+# define TO_LOOP_C NULL
+#endif /* HAVE_TO_C != 1 */
+
+#if HAVE_TO_VX == 1
+# define BODY_TO_VX \
+ { \
+ size_t inlen = inend - inptr; \
+ size_t outlen = outend - outptr; \
+ unsigned long tmp, tmp2, tmp3; \
+ asm volatile (".machine push\n\t" \
+ ".machine \"z13\"\n\t" \
+ ".machinemode \"zarch_nohighgprs\"\n\t" \
+ /* 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-32 chars \
+ ch < 0xd800 || (ch > 0xdfff && ch < 0x10000). */ \
+ "0: clgijl %[R_INLEN],32,2f\n\t" \
+ " clgijl %[R_OUTLEN],16,2f\n\t" \
+ "1: vlm %%v16,%%v17,0(%[R_IN])\n\t" \
+ " lghi %[R_TMP2],0\n\t" \
+ /* Shorten to UTF-16. */ \
+ " vpkf %%v18,%%v16,%%v17\n\t" \
+ /* Check for surrogate chars. */ \
+ " vstrcfs %%v19,%%v16,%%v30,%%v31\n\t" \
+ " jno 10f\n\t" \
+ " vstrcfs %%v19,%%v17,%%v30,%%v31\n\t" \
+ " jno 11f\n\t" \
+ /* Store 16 bytes to buf_out. */ \
+ " vst %%v18,0(%[R_OUT])\n\t" \
+ " la %[R_IN],32(%[R_IN])\n\t" \
+ " aghi %[R_INLEN],-32\n\t" \
+ " aghi %[R_OUTLEN],-16\n\t" \
+ " la %[R_OUT],16(%[R_OUT])\n\t" \
+ " clgijl %[R_INLEN],32,2f\n\t" \
+ " clgijl %[R_OUTLEN],16,2f\n\t" \
+ " j 1b\n\t" \
+ /* Calculate remaining uint32_t values in inptr. */ \
+ "2: \n\t" \
+ " clgije %[R_INLEN],0,99f\n\t" \
+ " clgijl %[R_INLEN],4,92f\n\t" \
+ " srlg %[R_TMP2],%[R_INLEN],2\n\t" \
+ " j 20f\n\t" \
+ /* Setup to check for ch >= 0xd800 && ch <= 0xdfff \
+ and check for ch >= 0x10000. (v30, v31) */ \
+ "9: .long 0xd800,0xdfff,0x10000,0x10000\n\t" \
+ " .long 0xa0000000,0xc0000000, 0xa0000000,0xa0000000\n\t" \
+ /* At least on UTF32 char is in range of surrogates. \
+ Store the preceding characters. */ \
+ "11: ahi %[R_TMP2],16\n\t" \
+ "10: vlgvb %[R_TMP],%%v19,7\n\t" \
+ " agr %[R_TMP],%[R_TMP2]\n\t" \
+ " srlg %[R_TMP3],%[R_TMP],1\n\t" /* Number of out bytes. */ \
+ " ahik %[R_TMP2],%[R_TMP3],-1\n\t" /* Highest index to store. */ \
+ " jl 12f\n\t" \
+ " vstl %%v18,%[R_TMP2],0(%[R_OUT])\n\t" \
+ /* Update pointers. */ \
+ " la %[R_IN],0(%[R_TMP],%[R_IN])\n\t" \
+ " slgr %[R_INLEN],%[R_TMP]\n\t" \
+ " la %[R_OUT],0(%[R_TMP3],%[R_OUT])\n\t" \
+ " slgr %[R_OUTLEN],%[R_TMP3]\n\t" \
+ /* Calculate remaining uint32_t values in vrs. */ \
+ "12: lghi %[R_TMP2],8\n\t" \
+ " srlg %[R_TMP3],%[R_TMP3],1\n\t" \
+ " slgr %[R_TMP2],%[R_TMP3]\n\t" \
+ /* Handle remaining UTF-32 characters. */ \
+ "20: l %[R_TMP],0(%[R_IN])\n\t" \
+ " aghi %[R_INLEN],-4\n\t" \
+ /* Test if ch is 2byte UTF-16 char. */ \
+ " clfi %[R_TMP],0xffff\n\t" \
+ " jh 21f\n\t" \
+ /* Handle 2 byte UTF16 char. */ \
+ " lgr %[R_TMP3],%[R_TMP]\n\t" \
+ " nilf %[R_TMP],0xf800\n\t" \
+ " clfi %[R_TMP],0xd800\n\t" \
+ " je 91f\n\t" /* Do not accept UTF-16 surrogates. */ \
+ " slgfi %[R_OUTLEN],2\n\t" \
+ " jl 90f \n\t" \
+ " sth %[R_TMP3],0(%[R_OUT])\n\t" \
+ " la %[R_IN],4(%[R_IN])\n\t" \
+ " la %[R_OUT],2(%[R_OUT])\n\t" \
+ " brctg %[R_TMP2],20b\n\t" \
+ " j 0b\n\t" /* Switch to vx-loop. */ \
+ /* Test if ch is 4byte UTF-16 char. */ \
+ "21: clfi %[R_TMP],0x10ffff\n\t" \
+ " jh 91f\n\t" /* ch > 0x10ffff is not allowed! */ \
+ /* Handle 4 byte UTF16 char. */ \
+ " slgfi %[R_OUTLEN],4\n\t" \
+ " jl 90f \n\t" \
+ " slfi %[R_TMP],0x10000\n\t" /* zabcd = uvwxy - 1. */ \
+ " llilf %[R_TMP3],0xd800dc00\n\t" \
+ " la %[R_IN],4(%[R_IN])\n\t" \
+ " risbgn %[R_TMP3],%[R_TMP],38,47,6\n\t" /* High surrogate. */ \
+ " risbgn %[R_TMP3],%[R_TMP],54,63,0\n\t" /* Low surrogate. */ \
+ " st %[R_TMP3],0(%[R_OUT])\n\t" \
+ " la %[R_OUT],4(%[R_OUT])\n\t" \
+ " brctg %[R_TMP2],20b\n\t" \
+ " j 0b\n\t" /* Switch to vx-loop. */ \
+ "92: lghi %[R_RES],%[RES_IN_FULL]\n\t" \
+ " j 99f\n\t" \
+ "91: lghi %[R_RES],%[RES_IN_ILL]\n\t" \
+ " j 99f\n\t" \
+ "90: lghi %[R_RES],%[RES_OUT_FULL]\n\t" \
+ "99: \n\t" \
+ ".machine pop" \
+ : /* outputs */ [R_IN] "+a" (inptr) \
+ , [R_INLEN] "+d" (inlen), [R_OUT] "+a" (outptr) \
+ , [R_OUTLEN] "+d" (outlen), [R_TMP] "=a" (tmp) \
+ , [R_TMP2] "=d" (tmp2), [R_TMP3] "=a" (tmp3) \
+ , [R_RES] "+d" (result) \
+ : /* inputs */ \
+ [RES_OUT_FULL] "i" (__GCONV_FULL_OUTPUT) \
+ , [RES_IN_ILL] "i" (__GCONV_ILLEGAL_INPUT) \
+ , [RES_IN_FULL] "i" (__GCONV_INCOMPLETE_INPUT) \
+ : /* clobber list */ "memory", "cc" \
+ ASM_CLOBBER_VR ("v16") ASM_CLOBBER_VR ("v17") \
+ ASM_CLOBBER_VR ("v18") ASM_CLOBBER_VR ("v19") \
+ ASM_CLOBBER_VR ("v30") ASM_CLOBBER_VR ("v31") \
+ ); \
+ if (__glibc_likely (inptr == inend) \
+ || result != __GCONV_ILLEGAL_INPUT) \
+ break; \
+ \
+ STANDARD_TO_LOOP_ERR_HANDLER (4); \
+ }
+
+/* Generate loop-function with hardware vector instructions. */
+# define MIN_NEEDED_INPUT MIN_NEEDED_TO
+# define MIN_NEEDED_OUTPUT MIN_NEEDED_FROM
+# define MAX_NEEDED_OUTPUT MAX_NEEDED_FROM
+# define TO_LOOP_VX __to_utf16_loop_vx
+# define LOOPFCT TO_LOOP_VX
+# define LOOP_NEED_FLAGS
+# define BODY BODY_TO_VX
+# include <iconv/loop.c>
+#else
+# define TO_LOOP_VX NULL
+#endif /* HAVE_TO_VX != 1 */
+
+#if HAVE_TO_VX_CU == 1
+#define BODY_TO_VX_CU \
+ { \
+ register const unsigned char* pInput asm ("8") = inptr; \
+ register size_t inlen asm ("9") = inend - inptr; \
+ register unsigned char* pOutput asm ("10") = outptr; \
+ register size_t outlen asm ("11") = outend - outptr; \
+ unsigned long tmp, tmp2, tmp3; \
+ asm volatile (".machine push\n\t" \
+ ".machine \"z13\"\n\t" \
+ ".machinemode \"zarch_nohighgprs\"\n\t" \
+ /* 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-32 chars \
+ ch < 0xd800 || (ch > 0xdfff && ch < 0x10000). */ \
+ "0: clgijl %[R_INLEN],32,20f\n\t" \
+ " clgijl %[R_OUTLEN],16,20f\n\t" \
+ "1: vlm %%v16,%%v17,0(%[R_IN])\n\t" \
+ " lghi %[R_TMP2],0\n\t" \
+ /* Shorten to UTF-16. */ \
+ " vpkf %%v18,%%v16,%%v17\n\t" \
+ /* Check for surrogate chars. */ \
+ " vstrcfs %%v19,%%v16,%%v30,%%v31\n\t" \
+ " jno 10f\n\t" \
+ " vstrcfs %%v19,%%v17,%%v30,%%v31\n\t" \
+ " jno 11f\n\t" \
+ /* Store 16 bytes to buf_out. */ \
+ " vst %%v18,0(%[R_OUT])\n\t" \
+ " la %[R_IN],32(%[R_IN])\n\t" \
+ " aghi %[R_INLEN],-32\n\t" \
+ " aghi %[R_OUTLEN],-16\n\t" \
+ " la %[R_OUT],16(%[R_OUT])\n\t" \
+ " clgijl %[R_INLEN],32,20f\n\t" \
+ " clgijl %[R_OUTLEN],16,20f\n\t" \
+ " j 1b\n\t" \
+ /* Setup to check for ch >= 0xd800 && ch <= 0xdfff \
+ and check for ch >= 0x10000. (v30, v31) */ \
+ "9: .long 0xd800,0xdfff,0x10000,0x10000\n\t" \
+ " .long 0xa0000000,0xc0000000, 0xa0000000,0xa0000000\n\t" \
+ /* At least one UTF32 char is in range of surrogates. \
+ Store the preceding characters. */ \
+ "11: ahi %[R_TMP2],16\n\t" \
+ "10: vlgvb %[R_TMP],%%v19,7\n\t" \
+ " agr %[R_TMP],%[R_TMP2]\n\t" \
+ " srlg %[R_TMP3],%[R_TMP],1\n\t" /* Number of out bytes. */ \
+ " ahik %[R_TMP2],%[R_TMP3],-1\n\t" /* Highest index to store. */ \
+ " jl 20f\n\t" \
+ " vstl %%v18,%[R_TMP2],0(%[R_OUT])\n\t" \
+ /* Update pointers. */ \
+ " la %[R_IN],0(%[R_TMP],%[R_IN])\n\t" \
+ " slgr %[R_INLEN],%[R_TMP]\n\t" \
+ " la %[R_OUT],0(%[R_TMP3],%[R_OUT])\n\t" \
+ " slgr %[R_OUTLEN],%[R_TMP3]\n\t" \
+ /* Handles UTF16 surrogates with convert instruction. */ \
+ "20: cu42 %[R_OUT],%[R_IN]\n\t" \
+ " jo 0b\n\t" /* Try vector implemenation again. */ \
+ " lochil %[R_RES],%[RES_OUT_FULL]\n\t" /* cc == 1. */ \
+ " lochih %[R_RES],%[RES_IN_ILL]\n\t" /* cc == 2. */ \
+ ".machine pop" \
+ : /* outputs */ [R_IN] "+a" (pInput) \
+ , [R_INLEN] "+d" (inlen), [R_OUT] "+a" (pOutput) \
+ , [R_OUTLEN] "+d" (outlen), [R_TMP] "=a" (tmp) \
+ , [R_TMP2] "=d" (tmp2), [R_TMP3] "=a" (tmp3) \
+ , [R_RES] "+d" (result) \
+ : /* inputs */ \
+ [RES_OUT_FULL] "i" (__GCONV_FULL_OUTPUT) \
+ , [RES_IN_ILL] "i" (__GCONV_ILLEGAL_INPUT) \
+ : /* clobber list */ "memory", "cc" \
+ ASM_CLOBBER_VR ("v16") ASM_CLOBBER_VR ("v17") \
+ ASM_CLOBBER_VR ("v18") ASM_CLOBBER_VR ("v19") \
+ ASM_CLOBBER_VR ("v30") ASM_CLOBBER_VR ("v31") \
+ ); \
+ inptr = pInput; \
+ outptr = pOutput; \
+ \
+ if (__glibc_likely (inlen == 0) \
+ || result == __GCONV_FULL_OUTPUT) \
+ break; \
+ if (inlen < 4) \
+ { \
+ result = __GCONV_INCOMPLETE_INPUT; \
+ break; \
+ } \
+ \
+ STANDARD_TO_LOOP_ERR_HANDLER (4); \
+ }
+
+/* Generate loop-function with hardware vector and utf-convert instructions. */
+# define MIN_NEEDED_INPUT MIN_NEEDED_TO
+# define MIN_NEEDED_OUTPUT MIN_NEEDED_FROM
+# define MAX_NEEDED_OUTPUT MAX_NEEDED_FROM
+# define TO_LOOP_VX_CU __to_utf16_loop_vx_cu
+# define LOOPFCT TO_LOOP_VX_CU
+# define LOOP_NEED_FLAGS
+# define BODY BODY_TO_VX_CU
+# include <iconv/loop.c>
+#else
+# define TO_LOOP_VX_CU NULL
+#endif /* HAVE_TO_VX_CU != 1 */
+
+/* This file also exists in sysdeps/s390/multiarch/ which
+ generates ifunc resolvers for FROM/TO_LOOP functions
+ and includes iconv/skeleton.c afterwards. */
+#if ! defined USE_MULTIARCH
+# include <iconv/skeleton.c>
+#endif
diff --git a/sysdeps/s390/utf8-utf16-z9.c b/sysdeps/s390/utf8-utf16-z9.c
new file mode 100644
index 0000000000..409d64c578
--- /dev/null
+++ b/sysdeps/s390/utf8-utf16-z9.c
@@ -0,0 +1,942 @@
+/* Conversion between UTF-8 and UTF-16 - s390 version.
+
+ This module uses the Z9-109 variants of the Convert Unicode
+ instructions.
+ Copyright (C) 1997-2018 Free Software Foundation, Inc.
+
+ Author: Andreas Krebbel <Andreas.Krebbel@de.ibm.com>
+ Based on the work by Ulrich Drepper <drepper@cygnus.com>, 1997.
+
+ Thanks to Daniel Appich who covered the relevant performance work
+ in his diploma thesis.
+
+ This 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.
+
+ This 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, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <dlfcn.h>
+#include <stdint.h>
+#include <unistd.h>
+#include <gconv.h>
+#include <string.h>
+
+/* Select which versions should be defined depending on support
+ for multiarch, vector and used minimum architecture level. */
+#ifdef HAVE_S390_MIN_Z196_ZARCH_ASM_SUPPORT
+# define HAVE_FROM_C 0
+# define FROM_LOOP_DEFAULT FROM_LOOP_CU
+#else
+# define HAVE_FROM_C 1
+# define FROM_LOOP_DEFAULT FROM_LOOP_C
+#endif
+
+#define HAVE_TO_C 1
+#define TO_LOOP_DEFAULT TO_LOOP_C
+
+#if defined HAVE_S390_MIN_Z196_ZARCH_ASM_SUPPORT || defined USE_MULTIARCH
+# define HAVE_FROM_CU 1
+#else
+# define HAVE_FROM_CU 0
+#endif
+
+#if defined HAVE_S390_VX_ASM_SUPPORT && defined USE_MULTIARCH
+# define HAVE_FROM_VX 1
+# define HAVE_TO_VX 1
+# define HAVE_TO_VX_CU 1
+#else
+# define HAVE_FROM_VX 0
+# define HAVE_TO_VX 0
+# define HAVE_TO_VX_CU 0
+#endif
+
+#if defined HAVE_S390_VX_GCC_SUPPORT
+# define ASM_CLOBBER_VR(NR) , NR
+#else
+# 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
+#define MIN_NEEDED_FROM 1
+#define MAX_NEEDED_FROM 4
+#define MIN_NEEDED_TO 2
+#define MAX_NEEDED_TO 4
+#define FROM_LOOP FROM_LOOP_DEFAULT
+#define TO_LOOP TO_LOOP_DEFAULT
+#define FROM_DIRECTION (dir == from_utf8)
+#define ONE_DIRECTION 0
+
+
+/* UTF-16 big endian byte order mark. */
+#define BOM_UTF16 0xfeff
+
+/* Direction of the transformation. */
+enum direction
+{
+ illegal_dir,
+ to_utf8,
+ from_utf8
+};
+
+struct utf8_data
+{
+ enum direction dir;
+ int emit_bom;
+};
+
+
+extern int gconv_init (struct __gconv_step *step);
+int
+gconv_init (struct __gconv_step *step)
+{
+ /* Determine which direction. */
+ struct utf8_data *new_data;
+ enum direction dir = illegal_dir;
+ int emit_bom;
+ int result;
+
+ emit_bom = (__strcasecmp (step->__to_name, "UTF-16//") == 0);
+
+ if (__strcasecmp (step->__from_name, "ISO-10646/UTF8/") == 0
+ && (__strcasecmp (step->__to_name, "UTF-16//") == 0
+ || __strcasecmp (step->__to_name, "UTF-16BE//") == 0))
+ {
+ dir = from_utf8;
+ }
+ else if (__strcasecmp (step->__from_name, "UTF-16BE//") == 0
+ && __strcasecmp (step->__to_name, "ISO-10646/UTF8/") == 0)
+ {
+ dir = to_utf8;
+ }
+
+ result = __GCONV_NOCONV;
+ if (dir != illegal_dir)
+ {
+ new_data = (struct utf8_data *) malloc (sizeof (struct utf8_data));
+
+ result = __GCONV_NOMEM;
+ if (new_data != NULL)
+ {
+ new_data->dir = dir;
+ new_data->emit_bom = emit_bom;
+ step->__data = new_data;
+
+ if (dir == from_utf8)
+ {
+ step->__min_needed_from = MIN_NEEDED_FROM;
+ step->__max_needed_from = MIN_NEEDED_FROM;
+ step->__min_needed_to = MIN_NEEDED_TO;
+ step->__max_needed_to = MIN_NEEDED_TO;
+ }
+ else
+ {
+ step->__min_needed_from = MIN_NEEDED_TO;
+ step->__max_needed_from = MIN_NEEDED_TO;
+ step->__min_needed_to = MIN_NEEDED_FROM;
+ step->__max_needed_to = MIN_NEEDED_FROM;
+ }
+
+ step->__stateful = 0;
+
+ result = __GCONV_OK;
+ }
+ }
+
+ return result;
+}
+
+
+extern void gconv_end (struct __gconv_step *data);
+void
+gconv_end (struct __gconv_step *data)
+{
+ free (data->__data);
+}
+
+/* The macro for the hardware loop. This is used for both
+ directions. */
+#define HARDWARE_CONVERT(INSTRUCTION) \
+ { \
+ register const unsigned char* pInput __asm__ ("8") = inptr; \
+ register size_t inlen __asm__ ("9") = inend - inptr; \
+ register unsigned char* pOutput __asm__ ("10") = outptr; \
+ 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" \
+ " ipm %2 \n" \
+ : "+a" (pOutput), "+a" (pInput), "+d" (cc), \
+ "+d" (outlen), "+d" (inlen) \
+ : \
+ : "cc", "memory"); \
+ \
+ inptr = pInput; \
+ outptr = pOutput; \
+ cc >>= 28; \
+ \
+ if (cc == 1) \
+ { \
+ result = __GCONV_FULL_OUTPUT; \
+ } \
+ else if (cc == 2) \
+ { \
+ result = __GCONV_ILLEGAL_INPUT; \
+ } \
+ }
+
+#define PREPARE_LOOP \
+ enum direction dir = ((struct utf8_data *) step->__data)->dir; \
+ int emit_bom = ((struct utf8_data *) step->__data)->emit_bom; \
+ \
+ if (emit_bom && !data->__internal_use \
+ && data->__invocation_counter == 0) \
+ { \
+ /* Emit the UTF-16 Byte Order Mark. */ \
+ if (__glibc_unlikely (outbuf + 2 > outend)) \
+ return __GCONV_FULL_OUTPUT; \
+ \
+ put16u (outbuf, BOM_UTF16); \
+ outbuf += 2; \
+ }
+
+/* Conversion function from UTF-8 to UTF-16. */
+#define BODY_FROM_HW(ASM) \
+ { \
+ ASM; \
+ if (__glibc_likely (inptr == inend) \
+ || result == __GCONV_FULL_OUTPUT) \
+ break; \
+ \
+ int i; \
+ for (i = 1; inptr + i < inend && i < 5; ++i) \
+ if ((inptr[i] & 0xc0) != 0x80) \
+ break; \
+ \
+ if (__glibc_likely (inptr + i == inend \
+ && result == __GCONV_EMPTY_INPUT)) \
+ { \
+ result = __GCONV_INCOMPLETE_INPUT; \
+ break; \
+ } \
+ STANDARD_FROM_LOOP_ERR_HANDLER (i); \
+ }
+
+#if HAVE_FROM_VX == 1
+# define HW_FROM_VX \
+ { \
+ register const unsigned char* pInput asm ("8") = inptr; \
+ register size_t inlen asm ("9") = inend - inptr; \
+ register unsigned char* pOutput asm ("10") = outptr; \
+ register size_t outlen asm("11") = outend - outptr; \
+ unsigned long tmp, tmp2, tmp3; \
+ asm volatile (".machine push\n\t" \
+ ".machine \"z13\"\n\t" \
+ ".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" \
+ "1: vl %%v16,0(%[R_IN])\n\t" \
+ " vstrcbs %%v17,%%v16,%%v30,%%v31\n\t" \
+ " jno 10f\n\t" /* Jump away if not all bytes are 1byte \
+ UTF8 chars. */ \
+ /* Enlarge to UTF-16. */ \
+ " vuplhb %%v18,%%v16\n\t" \
+ " la %[R_IN],16(%[R_IN])\n\t" \
+ " vupllb %%v19,%%v16\n\t" \
+ " aghi %[R_INLEN],-16\n\t" \
+ /* Store 32 bytes to buf_out. */ \
+ " vstm %%v18,%%v19,0(%[R_OUT])\n\t" \
+ " aghi %[R_OUTLEN],-32\n\t" \
+ " la %[R_OUT],32(%[R_OUT])\n\t" \
+ " clgijl %[R_INLEN],16,20f\n\t" \
+ " clgijl %[R_OUTLEN],32,20f\n\t" \
+ " j 1b\n\t" \
+ "10:\n\t" \
+ /* At least one byte is > 0x7f. \
+ Store the preceding 1-byte chars. */ \
+ " vlgvb %[R_TMP],%%v17,7\n\t" \
+ " sllk %[R_TMP2],%[R_TMP],1\n\t" /* Compute highest \
+ index to store. */ \
+ " llgfr %[R_TMP3],%[R_TMP2]\n\t" \
+ " ahi %[R_TMP2],-1\n\t" \
+ " jl 20f\n\t" \
+ " vuplhb %%v18,%%v16\n\t" \
+ " vstl %%v18,%[R_TMP2],0(%[R_OUT])\n\t" \
+ " ahi %[R_TMP2],-16\n\t" \
+ " jl 11f\n\t" \
+ " vupllb %%v19,%%v16\n\t" \
+ " vstl %%v19,%[R_TMP2],16(%[R_OUT])\n\t" \
+ "11: \n\t" /* Update pointers. */ \
+ " la %[R_IN],0(%[R_TMP],%[R_IN])\n\t" \
+ " slgr %[R_INLEN],%[R_TMP]\n\t" \
+ " la %[R_OUT],0(%[R_TMP3],%[R_OUT])\n\t" \
+ " slgr %[R_OUTLEN],%[R_TMP3]\n\t" \
+ /* Handle multibyte utf8-char with convert instruction. */ \
+ "20: cu12 %[R_OUT],%[R_IN],1\n\t" \
+ " jo 0b\n\t" /* Try vector implemenation again. */ \
+ " lochil %[R_RES],%[RES_OUT_FULL]\n\t" /* cc == 1. */ \
+ " lochih %[R_RES],%[RES_IN_ILL]\n\t" /* cc == 2. */ \
+ ".machine pop" \
+ : /* outputs */ [R_IN] "+a" (pInput) \
+ , [R_INLEN] "+d" (inlen), [R_OUT] "+a" (pOutput) \
+ , [R_OUTLEN] "+d" (outlen), [R_TMP] "=a" (tmp) \
+ , [R_TMP2] "=d" (tmp2), [R_TMP3] "=a" (tmp3) \
+ , [R_RES] "+d" (result) \
+ : /* inputs */ \
+ [RES_OUT_FULL] "i" (__GCONV_FULL_OUTPUT) \
+ , [RES_IN_ILL] "i" (__GCONV_ILLEGAL_INPUT) \
+ : /* clobber list */ "memory", "cc" \
+ ASM_CLOBBER_VR ("v16") ASM_CLOBBER_VR ("v17") \
+ ASM_CLOBBER_VR ("v18") ASM_CLOBBER_VR ("v19") \
+ ASM_CLOBBER_VR ("v30") ASM_CLOBBER_VR ("v31") \
+ ); \
+ inptr = pInput; \
+ outptr = pOutput; \
+ }
+# define BODY_FROM_VX BODY_FROM_HW (HW_FROM_VX)
+
+/* Generate loop-function with hardware vector and utf-convert instructions. */
+# define MIN_NEEDED_INPUT MIN_NEEDED_FROM
+# define MAX_NEEDED_INPUT MAX_NEEDED_FROM
+# define MIN_NEEDED_OUTPUT MIN_NEEDED_TO
+# define MAX_NEEDED_OUTPUT MAX_NEEDED_TO
+# define FROM_LOOP_VX __from_utf8_loop_vx
+# define LOOPFCT FROM_LOOP_VX
+# define LOOP_NEED_FLAGS
+# define BODY BODY_FROM_VX
+# include <iconv/loop.c>
+#else
+# define FROM_LOOP_VX NULL
+#endif /* HAVE_FROM_VX != 1 */
+
+#if HAVE_FROM_CU == 1
+# define BODY_FROM_ETF3EH BODY_FROM_HW (HARDWARE_CONVERT ("cu12 %0, %1, 1"))
+
+/* Generate loop-function with hardware utf-convert instruction. */
+# define MIN_NEEDED_INPUT MIN_NEEDED_FROM
+# define MAX_NEEDED_INPUT MAX_NEEDED_FROM
+# define MIN_NEEDED_OUTPUT MIN_NEEDED_TO
+# define MAX_NEEDED_OUTPUT MAX_NEEDED_TO
+# define FROM_LOOP_CU __from_utf8_loop_etf3eh
+# define LOOPFCT FROM_LOOP_CU
+# define LOOP_NEED_FLAGS
+# define BODY BODY_FROM_ETF3EH
+# include <iconv/loop.c>
+#else
+# define FROM_LOOP_CU NULL
+#endif /* HAVE_FROM_CU != 1 */
+
+#if HAVE_FROM_C == 1
+/* The software implementation is based on the code in gconv_simple.c. */
+# define BODY_FROM_C \
+ { \
+ /* Next input byte. */ \
+ uint16_t ch = *inptr; \
+ \
+ if (__glibc_likely (ch < 0x80)) \
+ { \
+ /* One byte sequence. */ \
+ ++inptr; \
+ } \
+ else \
+ { \
+ uint_fast32_t cnt; \
+ uint_fast32_t i; \
+ \
+ if (ch >= 0xc2 && ch < 0xe0) \
+ { \
+ /* We expect two bytes. The first byte cannot be 0xc0 \
+ or 0xc1, otherwise the wide character could have been \
+ represented using a single byte. */ \
+ cnt = 2; \
+ ch &= 0x1f; \
+ } \
+ else if (__glibc_likely ((ch & 0xf0) == 0xe0)) \
+ { \
+ /* We expect three bytes. */ \
+ cnt = 3; \
+ ch &= 0x0f; \
+ } \
+ else if (__glibc_likely ((ch & 0xf8) == 0xf0)) \
+ { \
+ /* We expect four bytes. */ \
+ cnt = 4; \
+ ch &= 0x07; \
+ } \
+ else \
+ { \
+ /* Search the end of this ill-formed UTF-8 character. This \
+ is the next byte with (x & 0xc0) != 0x80. */ \
+ i = 0; \
+ do \
+ ++i; \
+ while (inptr + i < inend \
+ && (*(inptr + i) & 0xc0) == 0x80 \
+ && i < 5); \
+ \
+ errout: \
+ STANDARD_FROM_LOOP_ERR_HANDLER (i); \
+ } \
+ \
+ if (__glibc_unlikely (inptr + cnt > inend)) \
+ { \
+ /* We don't have enough input. But before we report \
+ that check that all the bytes are correct. */ \
+ for (i = 1; inptr + i < inend; ++i) \
+ if ((inptr[i] & 0xc0) != 0x80) \
+ break; \
+ \
+ if (__glibc_likely (inptr + i == inend)) \
+ { \
+ result = __GCONV_INCOMPLETE_INPUT; \
+ break; \
+ } \
+ \
+ goto errout; \
+ } \
+ \
+ if (cnt == 4) \
+ { \
+ /* For 4 byte UTF-8 chars two UTF-16 chars (high and \
+ low) are needed. */ \
+ uint16_t zabcd, high, low; \
+ \
+ if (__glibc_unlikely (outptr + 4 > outend)) \
+ { \
+ /* Overflow in the output buffer. */ \
+ result = __GCONV_FULL_OUTPUT; \
+ break; \
+ } \
+ \
+ /* Check if tail-bytes >= 0x80, < 0xc0. */ \
+ for (i = 1; i < cnt; ++i) \
+ { \
+ if ((inptr[i] & 0xc0) != 0x80) \
+ /* This is an illegal encoding. */ \
+ goto errout; \
+ } \
+ \
+ /* See Principles of Operations cu12. */ \
+ zabcd = (((inptr[0] & 0x7) << 2) | \
+ ((inptr[1] & 0x30) >> 4)) - 1; \
+ \
+ /* z-bit must be zero after subtracting 1. */ \
+ if (zabcd & 0x10) \
+ STANDARD_FROM_LOOP_ERR_HANDLER (4) \
+ \
+ high = (uint16_t)(0xd8 << 8); /* high surrogate id */ \
+ high |= zabcd << 6; /* abcd bits */ \
+ high |= (inptr[1] & 0xf) << 2; /* efgh bits */ \
+ high |= (inptr[2] & 0x30) >> 4; /* ij bits */ \
+ \
+ low = (uint16_t)(0xdc << 8); /* low surrogate id */ \
+ low |= ((uint16_t)inptr[2] & 0xc) << 6; /* kl bits */ \
+ low |= (inptr[2] & 0x3) << 6; /* mn bits */ \
+ low |= inptr[3] & 0x3f; /* opqrst bits */ \
+ \
+ put16 (outptr, high); \
+ outptr += 2; \
+ put16 (outptr, low); \
+ outptr += 2; \
+ inptr += 4; \
+ continue; \
+ } \
+ else \
+ { \
+ /* Read the possible remaining bytes. */ \
+ for (i = 1; i < cnt; ++i) \
+ { \
+ uint16_t byte = inptr[i]; \
+ \
+ if ((byte & 0xc0) != 0x80) \
+ /* This is an illegal encoding. */ \
+ break; \
+ \
+ ch <<= 6; \
+ ch |= byte & 0x3f; \
+ } \
+ \
+ /* If i < cnt, some trail byte was not >= 0x80, < 0xc0. \
+ If cnt > 2 and ch < 2^(5*cnt-4), the wide character ch could \
+ have been represented with fewer than cnt bytes. */ \
+ if (i < cnt || (cnt > 2 && (ch >> (5 * cnt - 4)) == 0) \
+ /* Do not accept UTF-16 surrogates. */ \
+ || (ch >= 0xd800 && ch <= 0xdfff)) \
+ { \
+ /* This is an illegal encoding. */ \
+ goto errout; \
+ } \
+ \
+ inptr += cnt; \
+ } \
+ } \
+ /* Now adjust the pointers and store the result. */ \
+ *((uint16_t *) outptr) = ch; \
+ outptr += sizeof (uint16_t); \
+ }
+
+/* Generate loop-function with software implementation. */
+# define MIN_NEEDED_INPUT MIN_NEEDED_FROM
+# define MAX_NEEDED_INPUT MAX_NEEDED_FROM
+# define MIN_NEEDED_OUTPUT MIN_NEEDED_TO
+# define MAX_NEEDED_OUTPUT MAX_NEEDED_TO
+# define FROM_LOOP_C __from_utf8_loop_c
+# define LOOPFCT FROM_LOOP_C
+# define LOOP_NEED_FLAGS
+# define BODY BODY_FROM_C
+# include <iconv/loop.c>
+#else
+# define FROM_LOOP_C NULL
+#endif /* HAVE_FROM_C != 1 */
+
+/* Conversion from UTF-16 to UTF-8. */
+
+#if HAVE_TO_C == 1
+/* The software routine is based on the functionality of the S/390
+ hardware instruction (cu21) as described in the Principles of
+ Operation. */
+# define BODY_TO_C \
+ { \
+ uint16_t c = get16 (inptr); \
+ \
+ if (__glibc_likely (c <= 0x007f)) \
+ { \
+ /* Single byte UTF-8 char. */ \
+ *outptr = c & 0xff; \
+ outptr++; \
+ } \
+ else if (c >= 0x0080 && c <= 0x07ff) \
+ { \
+ /* Two byte UTF-8 char. */ \
+ \
+ if (__glibc_unlikely (outptr + 2 > outend)) \
+ { \
+ /* Overflow in the output buffer. */ \
+ result = __GCONV_FULL_OUTPUT; \
+ break; \
+ } \
+ \
+ outptr[0] = 0xc0; \
+ outptr[0] |= c >> 6; \
+ \
+ outptr[1] = 0x80; \
+ outptr[1] |= c & 0x3f; \
+ \
+ outptr += 2; \
+ } \
+ else if ((c >= 0x0800 && c <= 0xd7ff) || c > 0xdfff) \
+ { \
+ /* Three byte UTF-8 char. */ \
+ \
+ if (__glibc_unlikely (outptr + 3 > outend)) \
+ { \
+ /* Overflow in the output buffer. */ \
+ result = __GCONV_FULL_OUTPUT; \
+ break; \
+ } \
+ outptr[0] = 0xe0; \
+ outptr[0] |= c >> 12; \
+ \
+ outptr[1] = 0x80; \
+ outptr[1] |= (c >> 6) & 0x3f; \
+ \
+ outptr[2] = 0x80; \
+ outptr[2] |= c & 0x3f; \
+ \
+ outptr += 3; \
+ } \
+ else if (c >= 0xd800 && c <= 0xdbff) \
+ { \
+ /* Four byte UTF-8 char. */ \
+ uint16_t low, uvwxy; \
+ \
+ if (__glibc_unlikely (outptr + 4 > outend)) \
+ { \
+ /* Overflow in the output buffer. */ \
+ result = __GCONV_FULL_OUTPUT; \
+ break; \
+ } \
+ if (__glibc_unlikely (inptr + 4 > inend)) \
+ { \
+ result = __GCONV_INCOMPLETE_INPUT; \
+ break; \
+ } \
+ \
+ inptr += 2; \
+ low = get16 (inptr); \
+ \
+ if ((low & 0xfc00) != 0xdc00) \
+ { \
+ inptr -= 2; \
+ STANDARD_TO_LOOP_ERR_HANDLER (2); \
+ } \
+ uvwxy = ((c >> 6) & 0xf) + 1; \
+ outptr[0] = 0xf0; \
+ outptr[0] |= uvwxy >> 2; \
+ \
+ outptr[1] = 0x80; \
+ outptr[1] |= (uvwxy << 4) & 0x30; \
+ outptr[1] |= (c >> 2) & 0x0f; \
+ \
+ outptr[2] = 0x80; \
+ outptr[2] |= (c & 0x03) << 4; \
+ outptr[2] |= (low >> 6) & 0x0f; \
+ \
+ outptr[3] = 0x80; \
+ outptr[3] |= low & 0x3f; \
+ \
+ outptr += 4; \
+ } \
+ else \
+ { \
+ STANDARD_TO_LOOP_ERR_HANDLER (2); \
+ } \
+ inptr += 2; \
+ }
+
+/* Generate loop-function with software implementation. */
+# define MIN_NEEDED_INPUT MIN_NEEDED_TO
+# define MAX_NEEDED_INPUT MAX_NEEDED_TO
+# define MIN_NEEDED_OUTPUT MIN_NEEDED_FROM
+# define MAX_NEEDED_OUTPUT MAX_NEEDED_FROM
+# define TO_LOOP_C __to_utf8_loop_c
+# define LOOPFCT TO_LOOP_C
+# define BODY BODY_TO_C
+# define LOOP_NEED_FLAGS
+# include <iconv/loop.c>
+#else
+# define TO_LOOP_C NULL
+#endif /* HAVE_TO_C != 1 */
+
+#if HAVE_TO_VX == 1
+# define BODY_TO_VX \
+ { \
+ size_t inlen = inend - inptr; \
+ size_t outlen = outend - outptr; \
+ unsigned long tmp, tmp2, tmp3; \
+ asm volatile (".machine push\n\t" \
+ ".machine \"z13\"\n\t" \
+ ".machinemode \"zarch_nohighgprs\"\n\t" \
+ /* 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" \
+ "1: vlm %%v16,%%v17,0(%[R_IN])\n\t" \
+ " lghi %[R_TMP2],0\n\t" \
+ /* Check for > 1byte UTF-8 chars. */ \
+ " vstrchs %%v19,%%v16,%%v30,%%v31\n\t" \
+ " jno 10f\n\t" /* Jump away if not all bytes are 1byte \
+ UTF8 chars. */ \
+ " vstrchs %%v19,%%v17,%%v30,%%v31\n\t" \
+ " jno 11f\n\t" /* Jump away if not all bytes are 1byte \
+ UTF8 chars. */ \
+ /* Shorten to UTF-8. */ \
+ " vpkh %%v18,%%v16,%%v17\n\t" \
+ " la %[R_IN],32(%[R_IN])\n\t" \
+ " aghi %[R_INLEN],-32\n\t" \
+ /* Store 16 bytes to buf_out. */ \
+ " vst %%v18,0(%[R_OUT])\n\t" \
+ " aghi %[R_OUTLEN],-16\n\t" \
+ " la %[R_OUT],16(%[R_OUT])\n\t" \
+ " clgijl %[R_INLEN],32,2f\n\t" \
+ " clgijl %[R_OUTLEN],16,2f\n\t" \
+ " j 1b\n\t" \
+ /* Setup to check for ch > 0x7f. (v30, v31) */ \
+ "9: .short 0x7f,0x7f,0x0,0x0,0x0,0x0,0x0,0x0\n\t" \
+ " .short 0x2000,0x2000,0x0,0x0,0x0,0x0,0x0,0x0\n\t" \
+ /* At least one byte is > 0x7f. \
+ Store the preceding 1-byte chars. */ \
+ "11: lghi %[R_TMP2],16\n\t" /* match was found in v17. */ \
+ "10:\n\t" \
+ " vlgvb %[R_TMP],%%v19,7\n\t" \
+ /* Shorten to UTF-8. */ \
+ " vpkh %%v18,%%v16,%%v17\n\t" \
+ " ar %[R_TMP],%[R_TMP2]\n\t" /* Number of in bytes. */ \
+ " srlg %[R_TMP3],%[R_TMP],1\n\t" /* Number of out bytes. */ \
+ " ahik %[R_TMP2],%[R_TMP3],-1\n\t" /* Highest index to store. */ \
+ " jl 13f\n\t" \
+ " vstl %%v18,%[R_TMP2],0(%[R_OUT])\n\t" \
+ /* Update pointers. */ \
+ " la %[R_IN],0(%[R_TMP],%[R_IN])\n\t" \
+ " slgr %[R_INLEN],%[R_TMP]\n\t" \
+ " la %[R_OUT],0(%[R_TMP3],%[R_OUT])\n\t" \
+ " slgr %[R_OUTLEN],%[R_TMP3]\n\t" \
+ "13: \n\t" \
+ /* Calculate remaining uint16_t values in loaded vrs. */ \
+ " lghi %[R_TMP2],16\n\t" \
+ " slgr %[R_TMP2],%[R_TMP3]\n\t" \
+ " llh %[R_TMP],0(%[R_IN])\n\t" \
+ " aghi %[R_INLEN],-2\n\t" \
+ " j 22f\n\t" \
+ /* Handle remaining bytes. */ \
+ "2: \n\t" \
+ /* Zero, one or more bytes available? */ \
+ " clgfi %[R_INLEN],1\n\t" \
+ " locghie %[R_RES],%[RES_IN_FULL]\n\t" /* Only one byte. */ \
+ " jle 99f\n\t" /* End if less than two bytes. */ \
+ /* Calculate remaining uint16_t values in inptr. */ \
+ " srlg %[R_TMP2],%[R_INLEN],1\n\t" \
+ /* Handle multibyte utf8-char. */ \
+ "20: llh %[R_TMP],0(%[R_IN])\n\t" \
+ " aghi %[R_INLEN],-2\n\t" \
+ /* Test if ch is 1-byte UTF-8 char. */ \
+ "21: clijh %[R_TMP],0x7f,22f\n\t" \
+ /* Handle 1-byte UTF-8 char. */ \
+ "31: slgfi %[R_OUTLEN],1\n\t" \
+ " jl 90f \n\t" \
+ " stc %[R_TMP],0(%[R_OUT])\n\t" \
+ " la %[R_IN],2(%[R_IN])\n\t" \
+ " la %[R_OUT],1(%[R_OUT])\n\t" \
+ " brctg %[R_TMP2],20b\n\t" \
+ " j 0b\n\t" /* Switch to vx-loop. */ \
+ /* Test if ch is 2-byte UTF-8 char. */ \
+ "22: clfi %[R_TMP],0x7ff\n\t" \
+ " jh 23f\n\t" \
+ /* Handle 2-byte UTF-8 char. */ \
+ "32: slgfi %[R_OUTLEN],2\n\t" \
+ " jl 90f \n\t" \
+ " llill %[R_TMP3],0xc080\n\t" \
+ " la %[R_IN],2(%[R_IN])\n\t" \
+ " risbgn %[R_TMP3],%[R_TMP],51,55,2\n\t" /* 1. byte. */ \
+ " risbgn %[R_TMP3],%[R_TMP],58,63,0\n\t" /* 2. byte. */ \
+ " sth %[R_TMP3],0(%[R_OUT])\n\t" \
+ " la %[R_OUT],2(%[R_OUT])\n\t" \
+ " brctg %[R_TMP2],20b\n\t" \
+ " j 0b\n\t" /* Switch to vx-loop. */ \
+ /* Test if ch is 3-byte UTF-8 char. */ \
+ "23: clfi %[R_TMP],0xd7ff\n\t" \
+ " jh 24f\n\t" \
+ /* Handle 3-byte UTF-8 char. */ \
+ "33: slgfi %[R_OUTLEN],3\n\t" \
+ " jl 90f \n\t" \
+ " llilf %[R_TMP3],0xe08080\n\t" \
+ " la %[R_IN],2(%[R_IN])\n\t" \
+ " risbgn %[R_TMP3],%[R_TMP],44,47,4\n\t" /* 1. byte. */ \
+ " risbgn %[R_TMP3],%[R_TMP],50,55,2\n\t" /* 2. byte. */ \
+ " risbgn %[R_TMP3],%[R_TMP],58,63,0\n\t" /* 3. byte. */ \
+ " stcm %[R_TMP3],7,0(%[R_OUT])\n\t" \
+ " la %[R_OUT],3(%[R_OUT])\n\t" \
+ " brctg %[R_TMP2],20b\n\t" \
+ " j 0b\n\t" /* Switch to vx-loop. */ \
+ /* Test if ch is 4-byte UTF-8 char. */ \
+ "24: clfi %[R_TMP],0xdfff\n\t" \
+ " jh 33b\n\t" /* Handle this 3-byte UTF-8 char. */ \
+ " clfi %[R_TMP],0xdbff\n\t" \
+ " locghih %[R_RES],%[RES_IN_ILL]\n\t" \
+ " jh 99f\n\t" /* Jump away if this is a low surrogate \
+ without a preceding high surrogate. */ \
+ /* Handle 4-byte UTF-8 char. */ \
+ "34: slgfi %[R_OUTLEN],4\n\t" \
+ " jl 90f \n\t" \
+ " slgfi %[R_INLEN],2\n\t" \
+ " locghil %[R_RES],%[RES_IN_FULL]\n\t" \
+ " jl 99f\n\t" /* Jump away if low surrogate is missing. */ \
+ " llilf %[R_TMP3],0xf0808080\n\t" \
+ " aghi %[R_TMP],0x40\n\t" \
+ " risbgn %[R_TMP3],%[R_TMP],37,39,16\n\t" /* 1. byte: uvw */ \
+ " risbgn %[R_TMP3],%[R_TMP],42,43,14\n\t" /* 2. byte: xy */ \
+ " risbgn %[R_TMP3],%[R_TMP],44,47,14\n\t" /* 2. byte: efgh */ \
+ " risbgn %[R_TMP3],%[R_TMP],50,51,12\n\t" /* 3. byte: ij */ \
+ " llh %[R_TMP],2(%[R_IN])\n\t" /* Load low surrogate. */ \
+ " risbgn %[R_TMP3],%[R_TMP],52,55,2\n\t" /* 3. byte: klmn */ \
+ " risbgn %[R_TMP3],%[R_TMP],58,63,0\n\t" /* 4. byte: opqrst */ \
+ " nilf %[R_TMP],0xfc00\n\t" \
+ " clfi %[R_TMP],0xdc00\n\t" /* Check if it starts with 0xdc00. */ \
+ " locghine %[R_RES],%[RES_IN_ILL]\n\t" \
+ " jne 99f\n\t" /* Jump away if low surrogate is invalid. */ \
+ " st %[R_TMP3],0(%[R_OUT])\n\t" \
+ " la %[R_IN],4(%[R_IN])\n\t" \
+ " la %[R_OUT],4(%[R_OUT])\n\t" \
+ " aghi %[R_TMP2],-2\n\t" \
+ " jh 20b\n\t" \
+ " j 0b\n\t" /* Switch to vx-loop. */ \
+ /* Exit with __GCONV_FULL_OUTPUT. */ \
+ "90: lghi %[R_RES],%[RES_OUT_FULL]\n\t" \
+ "99: \n\t" \
+ ".machine pop" \
+ : /* outputs */ [R_IN] "+a" (inptr) \
+ , [R_INLEN] "+d" (inlen), [R_OUT] "+a" (outptr) \
+ , [R_OUTLEN] "+d" (outlen), [R_TMP] "=a" (tmp) \
+ , [R_TMP2] "=d" (tmp2), [R_TMP3] "=a" (tmp3) \
+ , [R_RES] "+d" (result) \
+ : /* inputs */ \
+ [RES_OUT_FULL] "i" (__GCONV_FULL_OUTPUT) \
+ , [RES_IN_ILL] "i" (__GCONV_ILLEGAL_INPUT) \
+ , [RES_IN_FULL] "i" (__GCONV_INCOMPLETE_INPUT) \
+ : /* clobber list */ "memory", "cc" \
+ ASM_CLOBBER_VR ("v16") ASM_CLOBBER_VR ("v17") \
+ ASM_CLOBBER_VR ("v18") ASM_CLOBBER_VR ("v19") \
+ ASM_CLOBBER_VR ("v30") ASM_CLOBBER_VR ("v31") \
+ ); \
+ if (__glibc_likely (inptr == inend) \
+ || result != __GCONV_ILLEGAL_INPUT) \
+ break; \
+ \
+ STANDARD_TO_LOOP_ERR_HANDLER (2); \
+ }
+
+/* Generate loop-function with vector implementation. */
+# define MIN_NEEDED_INPUT MIN_NEEDED_TO
+# define MAX_NEEDED_INPUT MAX_NEEDED_TO
+# define MIN_NEEDED_OUTPUT MIN_NEEDED_FROM
+# define MAX_NEEDED_OUTPUT MAX_NEEDED_FROM
+# define TO_LOOP_VX __to_utf8_loop_vx
+# define LOOPFCT TO_LOOP_VX
+# define BODY BODY_TO_VX
+# define LOOP_NEED_FLAGS
+# include <iconv/loop.c>
+#else
+# define TO_LOOP_VX NULL
+#endif /* HAVE_TO_VX != 1 */
+
+#if HAVE_TO_VX_CU == 1
+#define BODY_TO_VX_CU \
+ { \
+ register const unsigned char* pInput asm ("8") = inptr; \
+ register size_t inlen asm ("9") = inend - inptr; \
+ register unsigned char* pOutput asm ("10") = outptr; \
+ register size_t outlen asm ("11") = outend - outptr; \
+ unsigned long tmp, tmp2, tmp3; \
+ asm volatile (".machine push\n\t" \
+ ".machine \"z13\"\n\t" \
+ ".machinemode \"zarch_nohighgprs\"\n\t" \
+ /* 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,20f\n\t" \
+ " clgijl %[R_OUTLEN],16,20f\n\t" \
+ "1: vlm %%v16,%%v17,0(%[R_IN])\n\t" \
+ " lghi %[R_TMP2],0\n\t" \
+ /* Check for > 1byte UTF-8 chars. */ \
+ " vstrchs %%v19,%%v16,%%v30,%%v31\n\t" \
+ " jno 10f\n\t" /* Jump away if not all bytes are 1byte \
+ UTF8 chars. */ \
+ " vstrchs %%v19,%%v17,%%v30,%%v31\n\t" \
+ " jno 11f\n\t" /* Jump away if not all bytes are 1byte \
+ UTF8 chars. */ \
+ /* Shorten to UTF-8. */ \
+ " vpkh %%v18,%%v16,%%v17\n\t" \
+ " la %[R_IN],32(%[R_IN])\n\t" \
+ " aghi %[R_INLEN],-32\n\t" \
+ /* Store 16 bytes to buf_out. */ \
+ " vst %%v18,0(%[R_OUT])\n\t" \
+ " aghi %[R_OUTLEN],-16\n\t" \
+ " la %[R_OUT],16(%[R_OUT])\n\t" \
+ " clgijl %[R_INLEN],32,20f\n\t" \
+ " clgijl %[R_OUTLEN],16,20f\n\t" \
+ " j 1b\n\t" \
+ /* Setup to check for ch > 0x7f. (v30, v31) */ \
+ "9: .short 0x7f,0x7f,0x0,0x0,0x0,0x0,0x0,0x0\n\t" \
+ " .short 0x2000,0x2000,0x0,0x0,0x0,0x0,0x0,0x0\n\t" \
+ /* At least one byte is > 0x7f. \
+ Store the preceding 1-byte chars. */ \
+ "11: lghi %[R_TMP2],16\n\t" /* match was found in v17. */ \
+ "10: vlgvb %[R_TMP],%%v19,7\n\t" \
+ /* Shorten to UTF-8. */ \
+ " vpkh %%v18,%%v16,%%v17\n\t" \
+ " ar %[R_TMP],%[R_TMP2]\n\t" /* Number of in bytes. */ \
+ " srlg %[R_TMP3],%[R_TMP],1\n\t" /* Number of out bytes. */ \
+ " ahik %[R_TMP2],%[R_TMP3],-1\n\t" /* Highest index to store. */ \
+ " jl 20f\n\t" \
+ " vstl %%v18,%[R_TMP2],0(%[R_OUT])\n\t" \
+ /* Update pointers. */ \
+ " la %[R_IN],0(%[R_TMP],%[R_IN])\n\t" \
+ " slgr %[R_INLEN],%[R_TMP]\n\t" \
+ " la %[R_OUT],0(%[R_TMP3],%[R_OUT])\n\t" \
+ " slgr %[R_OUTLEN],%[R_TMP3]\n\t" \
+ /* Handles UTF16 surrogates with convert instruction. */ \
+ "20: cu21 %[R_OUT],%[R_IN],1\n\t" \
+ " jo 0b\n\t" /* Try vector implemenation again. */ \
+ " lochil %[R_RES],%[RES_OUT_FULL]\n\t" /* cc == 1. */ \
+ " lochih %[R_RES],%[RES_IN_ILL]\n\t" /* cc == 2. */ \
+ ".machine pop" \
+ : /* outputs */ [R_IN] "+a" (pInput) \
+ , [R_INLEN] "+d" (inlen), [R_OUT] "+a" (pOutput) \
+ , [R_OUTLEN] "+d" (outlen), [R_TMP] "=a" (tmp) \
+ , [R_TMP2] "=d" (tmp2), [R_TMP3] "=a" (tmp3) \
+ , [R_RES] "+d" (result) \
+ : /* inputs */ \
+ [RES_OUT_FULL] "i" (__GCONV_FULL_OUTPUT) \
+ , [RES_IN_ILL] "i" (__GCONV_ILLEGAL_INPUT) \
+ : /* clobber list */ "memory", "cc" \
+ ASM_CLOBBER_VR ("v16") ASM_CLOBBER_VR ("v17") \
+ ASM_CLOBBER_VR ("v18") ASM_CLOBBER_VR ("v19") \
+ ASM_CLOBBER_VR ("v30") ASM_CLOBBER_VR ("v31") \
+ ); \
+ inptr = pInput; \
+ outptr = pOutput; \
+ \
+ if (__glibc_likely (inlen == 0) \
+ || result == __GCONV_FULL_OUTPUT) \
+ break; \
+ if (inlen == 1) \
+ { \
+ /* Input does not contain a complete utf16 character. */ \
+ result = __GCONV_INCOMPLETE_INPUT; \
+ break; \
+ } \
+ else if (result != __GCONV_ILLEGAL_INPUT) \
+ { \
+ /* Input is >= 2 and < 4 bytes (as cu21 would have processed \
+ a possible next utf16 character) and not illegal. \
+ => we have a single high surrogate at end of input. */ \
+ result = __GCONV_INCOMPLETE_INPUT; \
+ break; \
+ } \
+ \
+ STANDARD_TO_LOOP_ERR_HANDLER (2); \
+ }
+
+/* Generate loop-function with vector and utf-convert instructions. */
+# define MIN_NEEDED_INPUT MIN_NEEDED_TO
+# define MAX_NEEDED_INPUT MAX_NEEDED_TO
+# define MIN_NEEDED_OUTPUT MIN_NEEDED_FROM
+# define MAX_NEEDED_OUTPUT MAX_NEEDED_FROM
+# define TO_LOOP_VX_CU __to_utf8_loop_vx_cu
+# define LOOPFCT TO_LOOP_VX_CU
+# define BODY BODY_TO_VX_CU
+# define LOOP_NEED_FLAGS
+# include <iconv/loop.c>
+#else
+# define TO_LOOP_VX_CU NULL
+#endif /* HAVE_TO_VX_CU != 1 */
+
+/* This file also exists in sysdeps/s390/multiarch/ which
+ generates ifunc resolvers for FROM/TO_LOOP functions
+ and includes iconv/skeleton.c afterwards. */
+#if ! defined USE_MULTIARCH
+# include <iconv/skeleton.c>
+#endif
diff --git a/sysdeps/s390/utf8-utf32-z9.c b/sysdeps/s390/utf8-utf32-z9.c
new file mode 100644
index 0000000000..c09d9b5bbd
--- /dev/null
+++ b/sysdeps/s390/utf8-utf32-z9.c
@@ -0,0 +1,983 @@
+/* Conversion between UTF-8 and UTF-32 BE/internal.
+
+ This module uses the Z9-109 variants of the Convert Unicode
+ instructions.
+ Copyright (C) 1997-2018 Free Software Foundation, Inc.
+
+ Author: Andreas Krebbel <Andreas.Krebbel@de.ibm.com>
+ Based on the work by Ulrich Drepper <drepper@cygnus.com>, 1997.
+
+ Thanks to Daniel Appich who covered the relevant performance work
+ in his diploma thesis.
+
+ This 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.
+
+ This 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, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <dlfcn.h>
+#include <stdint.h>
+#include <unistd.h>
+#include <gconv.h>
+#include <string.h>
+
+/* Select which versions should be defined depending on support
+ for multiarch, vector and used minimum architecture level. */
+#ifdef HAVE_S390_MIN_Z196_ZARCH_ASM_SUPPORT
+# define HAVE_FROM_C 0
+# define FROM_LOOP_DEFAULT FROM_LOOP_CU
+#else
+# define HAVE_FROM_C 1
+# define FROM_LOOP_DEFAULT FROM_LOOP_C
+#endif
+
+#define HAVE_TO_C 1
+#define TO_LOOP_DEFAULT TO_LOOP_C
+
+#if defined HAVE_S390_MIN_Z196_ZARCH_ASM_SUPPORT || defined USE_MULTIARCH
+# define HAVE_FROM_CU 1
+#else
+# define HAVE_FROM_CU 0
+#endif
+
+#if defined HAVE_S390_VX_ASM_SUPPORT && defined USE_MULTIARCH
+# define HAVE_FROM_VX 1
+# define HAVE_TO_VX 1
+# define HAVE_TO_VX_CU 1
+#else
+# define HAVE_FROM_VX 0
+# define HAVE_TO_VX 0
+# define HAVE_TO_VX_CU 0
+#endif
+
+#if defined HAVE_S390_VX_GCC_SUPPORT
+# define ASM_CLOBBER_VR(NR) , NR
+#else
+# 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
+#define MIN_NEEDED_FROM 1
+#define MAX_NEEDED_FROM 6
+#define MIN_NEEDED_TO 4
+#define FROM_LOOP FROM_LOOP_DEFAULT
+#define TO_LOOP TO_LOOP_DEFAULT
+#define FROM_DIRECTION (dir == from_utf8)
+#define ONE_DIRECTION 0
+
+/* UTF-32 big endian byte order mark. */
+#define BOM 0x0000feffu
+
+/* Direction of the transformation. */
+enum direction
+{
+ illegal_dir,
+ to_utf8,
+ from_utf8
+};
+
+struct utf8_data
+{
+ enum direction dir;
+ int emit_bom;
+};
+
+
+extern int gconv_init (struct __gconv_step *step);
+int
+gconv_init (struct __gconv_step *step)
+{
+ /* Determine which direction. */
+ struct utf8_data *new_data;
+ enum direction dir = illegal_dir;
+ int emit_bom;
+ int result;
+
+ emit_bom = (__strcasecmp (step->__to_name, "UTF-32//") == 0);
+
+ if (__strcasecmp (step->__from_name, "ISO-10646/UTF8/") == 0
+ && (__strcasecmp (step->__to_name, "UTF-32//") == 0
+ || __strcasecmp (step->__to_name, "UTF-32BE//") == 0
+ || __strcasecmp (step->__to_name, "INTERNAL") == 0))
+ {
+ dir = from_utf8;
+ }
+ else if (__strcasecmp (step->__to_name, "ISO-10646/UTF8/") == 0
+ && (__strcasecmp (step->__from_name, "UTF-32BE//") == 0
+ || __strcasecmp (step->__from_name, "INTERNAL") == 0))
+ {
+ dir = to_utf8;
+ }
+
+ result = __GCONV_NOCONV;
+ if (dir != illegal_dir)
+ {
+ new_data = (struct utf8_data *) malloc (sizeof (struct utf8_data));
+
+ result = __GCONV_NOMEM;
+ if (new_data != NULL)
+ {
+ new_data->dir = dir;
+ new_data->emit_bom = emit_bom;
+ step->__data = new_data;
+
+ if (dir == from_utf8)
+ {
+ step->__min_needed_from = MIN_NEEDED_FROM;
+ step->__max_needed_from = MIN_NEEDED_FROM;
+ step->__min_needed_to = MIN_NEEDED_TO;
+ step->__max_needed_to = MIN_NEEDED_TO;
+ }
+ else
+ {
+ step->__min_needed_from = MIN_NEEDED_TO;
+ step->__max_needed_from = MIN_NEEDED_TO;
+ step->__min_needed_to = MIN_NEEDED_FROM;
+ step->__max_needed_to = MIN_NEEDED_FROM;
+ }
+
+ step->__stateful = 0;
+
+ result = __GCONV_OK;
+ }
+ }
+
+ return result;
+}
+
+
+extern void gconv_end (struct __gconv_step *data);
+void
+gconv_end (struct __gconv_step *data)
+{
+ free (data->__data);
+}
+
+/* The macro for the hardware loop. This is used for both
+ directions. */
+#define HARDWARE_CONVERT(INSTRUCTION) \
+ { \
+ register const unsigned char* pInput __asm__ ("8") = inptr; \
+ register size_t inlen __asm__ ("9") = inend - inptr; \
+ register unsigned char* pOutput __asm__ ("10") = outptr; \
+ 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" \
+ " ipm %2 \n" \
+ : "+a" (pOutput), "+a" (pInput), "+d" (cc), \
+ "+d" (outlen), "+d" (inlen) \
+ : \
+ : "cc", "memory"); \
+ \
+ inptr = pInput; \
+ outptr = pOutput; \
+ cc >>= 28; \
+ \
+ if (cc == 1) \
+ { \
+ result = __GCONV_FULL_OUTPUT; \
+ } \
+ else if (cc == 2) \
+ { \
+ result = __GCONV_ILLEGAL_INPUT; \
+ } \
+ }
+
+#define PREPARE_LOOP \
+ enum direction dir = ((struct utf8_data *) step->__data)->dir; \
+ int emit_bom = ((struct utf8_data *) step->__data)->emit_bom; \
+ \
+ if (emit_bom && !data->__internal_use \
+ && data->__invocation_counter == 0) \
+ { \
+ /* Emit the Byte Order Mark. */ \
+ if (__glibc_unlikely (outbuf + 4 > outend)) \
+ return __GCONV_FULL_OUTPUT; \
+ \
+ put32u (outbuf, BOM); \
+ outbuf += 4; \
+ }
+
+/* Conversion function from UTF-8 to UTF-32 internal/BE. */
+
+#define STORE_REST_COMMON \
+ { \
+ /* We store the remaining bytes while converting them into the UCS4 \
+ format. We can assume that the first byte in the buffer is \
+ correct and that it requires a larger number of bytes than there \
+ are in the input buffer. */ \
+ wint_t ch = **inptrp; \
+ size_t cnt, r; \
+ \
+ state->__count = inend - *inptrp; \
+ \
+ assert (ch != 0xc0 && ch != 0xc1); \
+ if (ch >= 0xc2 && ch < 0xe0) \
+ { \
+ /* We expect two bytes. The first byte cannot be 0xc0 or \
+ 0xc1, otherwise the wide character could have been \
+ represented using a single byte. */ \
+ cnt = 2; \
+ ch &= 0x1f; \
+ } \
+ else if (__glibc_likely ((ch & 0xf0) == 0xe0)) \
+ { \
+ /* We expect three bytes. */ \
+ cnt = 3; \
+ ch &= 0x0f; \
+ } \
+ else if (__glibc_likely ((ch & 0xf8) == 0xf0)) \
+ { \
+ /* We expect four bytes. */ \
+ cnt = 4; \
+ ch &= 0x07; \
+ } \
+ else if (__glibc_likely ((ch & 0xfc) == 0xf8)) \
+ { \
+ /* We expect five bytes. */ \
+ cnt = 5; \
+ ch &= 0x03; \
+ } \
+ else \
+ { \
+ /* We expect six bytes. */ \
+ cnt = 6; \
+ ch &= 0x01; \
+ } \
+ \
+ /* The first byte is already consumed. */ \
+ r = cnt - 1; \
+ while (++(*inptrp) < inend) \
+ { \
+ ch <<= 6; \
+ ch |= **inptrp & 0x3f; \
+ --r; \
+ } \
+ \
+ /* Shift for the so far missing bytes. */ \
+ ch <<= r * 6; \
+ \
+ /* Store the number of bytes expected for the entire sequence. */ \
+ state->__count |= cnt << 8; \
+ \
+ /* Store the value. */ \
+ state->__value.__wch = ch; \
+ }
+
+#define UNPACK_BYTES_COMMON \
+ { \
+ static const unsigned char inmask[5] = { 0xc0, 0xe0, 0xf0, 0xf8, 0xfc }; \
+ wint_t wch = state->__value.__wch; \
+ size_t ntotal = state->__count >> 8; \
+ \
+ inlen = state->__count & 255; \
+ \
+ bytebuf[0] = inmask[ntotal - 2]; \
+ \
+ do \
+ { \
+ if (--ntotal < inlen) \
+ bytebuf[ntotal] = 0x80 | (wch & 0x3f); \
+ wch >>= 6; \
+ } \
+ while (ntotal > 1); \
+ \
+ bytebuf[0] |= wch; \
+ }
+
+#define CLEAR_STATE_COMMON \
+ state->__count = 0
+
+#define BODY_FROM_HW(ASM) \
+ { \
+ ASM; \
+ if (__glibc_likely (inptr == inend) \
+ || result == __GCONV_FULL_OUTPUT) \
+ break; \
+ \
+ int i; \
+ for (i = 1; inptr + i < inend && i < 5; ++i) \
+ if ((inptr[i] & 0xc0) != 0x80) \
+ break; \
+ \
+ if (__glibc_likely (inptr + i == inend \
+ && result == __GCONV_EMPTY_INPUT)) \
+ { \
+ result = __GCONV_INCOMPLETE_INPUT; \
+ break; \
+ } \
+ STANDARD_FROM_LOOP_ERR_HANDLER (i); \
+ }
+
+#if HAVE_FROM_C == 1
+/* The software routine is copied from gconv_simple.c. */
+# define BODY_FROM_C \
+ { \
+ /* Next input byte. */ \
+ uint32_t ch = *inptr; \
+ \
+ if (__glibc_likely (ch < 0x80)) \
+ { \
+ /* One byte sequence. */ \
+ ++inptr; \
+ } \
+ else \
+ { \
+ uint_fast32_t cnt; \
+ uint_fast32_t i; \
+ \
+ if (ch >= 0xc2 && ch < 0xe0) \
+ { \
+ /* We expect two bytes. The first byte cannot be 0xc0 or \
+ 0xc1, otherwise the wide character could have been \
+ represented using a single byte. */ \
+ cnt = 2; \
+ ch &= 0x1f; \
+ } \
+ else if (__glibc_likely ((ch & 0xf0) == 0xe0)) \
+ { \
+ /* We expect three bytes. */ \
+ cnt = 3; \
+ ch &= 0x0f; \
+ } \
+ else if (__glibc_likely ((ch & 0xf8) == 0xf0)) \
+ { \
+ /* We expect four bytes. */ \
+ cnt = 4; \
+ ch &= 0x07; \
+ } \
+ else \
+ { \
+ /* Search the end of this ill-formed UTF-8 character. This \
+ is the next byte with (x & 0xc0) != 0x80. */ \
+ i = 0; \
+ do \
+ ++i; \
+ while (inptr + i < inend \
+ && (*(inptr + i) & 0xc0) == 0x80 \
+ && i < 5); \
+ \
+ errout: \
+ STANDARD_FROM_LOOP_ERR_HANDLER (i); \
+ } \
+ \
+ if (__glibc_unlikely (inptr + cnt > inend)) \
+ { \
+ /* We don't have enough input. But before we report \
+ that check that all the bytes are correct. */ \
+ for (i = 1; inptr + i < inend; ++i) \
+ if ((inptr[i] & 0xc0) != 0x80) \
+ break; \
+ \
+ if (__glibc_likely (inptr + i == inend)) \
+ { \
+ result = __GCONV_INCOMPLETE_INPUT; \
+ break; \
+ } \
+ \
+ goto errout; \
+ } \
+ \
+ /* Read the possible remaining bytes. */ \
+ for (i = 1; i < cnt; ++i) \
+ { \
+ uint32_t byte = inptr[i]; \
+ \
+ if ((byte & 0xc0) != 0x80) \
+ /* This is an illegal encoding. */ \
+ break; \
+ \
+ ch <<= 6; \
+ ch |= byte & 0x3f; \
+ } \
+ \
+ /* If i < cnt, some trail byte was not >= 0x80, < 0xc0. \
+ If cnt > 2 and ch < 2^(5*cnt-4), the wide character ch could \
+ have been represented with fewer than cnt bytes. */ \
+ if (i < cnt || (cnt > 2 && (ch >> (5 * cnt - 4)) == 0) \
+ /* Do not accept UTF-16 surrogates. */ \
+ || (ch >= 0xd800 && ch <= 0xdfff) \
+ || (ch > 0x10ffff)) \
+ { \
+ /* This is an illegal encoding. */ \
+ goto errout; \
+ } \
+ \
+ inptr += cnt; \
+ } \
+ \
+ /* Now adjust the pointers and store the result. */ \
+ *((uint32_t *) outptr) = ch; \
+ outptr += sizeof (uint32_t); \
+ }
+
+/* These definitions apply to the UTF-8 to UTF-32 direction. The
+ software implementation for UTF-8 still supports multibyte
+ characters up to 6 bytes whereas the hardware variant does not. */
+# define MIN_NEEDED_INPUT MIN_NEEDED_FROM
+# define MAX_NEEDED_INPUT MAX_NEEDED_FROM
+# define MIN_NEEDED_OUTPUT MIN_NEEDED_TO
+# define FROM_LOOP_C __from_utf8_loop_c
+# define LOOPFCT FROM_LOOP_C
+
+# define LOOP_NEED_FLAGS
+
+# define STORE_REST STORE_REST_COMMON
+# define UNPACK_BYTES UNPACK_BYTES_COMMON
+# define CLEAR_STATE CLEAR_STATE_COMMON
+# define BODY BODY_FROM_C
+# include <iconv/loop.c>
+#else
+# define FROM_LOOP_C NULL
+#endif /* HAVE_FROM_C != 1 */
+
+#if HAVE_FROM_CU == 1
+/* This hardware routine uses the Convert UTF8 to UTF32 (cu14) instruction. */
+# define BODY_FROM_ETF3EH BODY_FROM_HW (HARDWARE_CONVERT ("cu14 %0, %1, 1"))
+
+/* Generate loop-function with hardware utf-convert instruction. */
+# define MIN_NEEDED_INPUT MIN_NEEDED_FROM
+# define MAX_NEEDED_INPUT MAX_NEEDED_FROM
+# define MIN_NEEDED_OUTPUT MIN_NEEDED_TO
+# define FROM_LOOP_CU __from_utf8_loop_etf3eh
+# define LOOPFCT FROM_LOOP_CU
+
+# define LOOP_NEED_FLAGS
+
+# define STORE_REST STORE_REST_COMMON
+# define UNPACK_BYTES UNPACK_BYTES_COMMON
+# define CLEAR_STATE CLEAR_STATE_COMMON
+# define BODY BODY_FROM_ETF3EH
+# include <iconv/loop.c>
+#else
+# define FROM_LOOP_CU NULL
+#endif /* HAVE_FROM_CU != 1 */
+
+#if HAVE_FROM_VX == 1
+# define HW_FROM_VX \
+ { \
+ register const unsigned char* pInput asm ("8") = inptr; \
+ register size_t inlen asm ("9") = inend - inptr; \
+ register unsigned char* pOutput asm ("10") = outptr; \
+ register size_t outlen asm("11") = outend - outptr; \
+ unsigned long tmp, tmp2, tmp3; \
+ asm volatile (".machine push\n\t" \
+ ".machine \"z13\"\n\t" \
+ ".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" \
+ "1: vl %%v16,0(%[R_IN])\n\t" \
+ " vstrcbs %%v17,%%v16,%%v30,%%v31\n\t" \
+ " jno 10f\n\t" /* Jump away if not all bytes are 1byte \
+ UTF8 chars. */ \
+ /* Enlarge to UCS4. */ \
+ " vuplhb %%v18,%%v16\n\t" \
+ " vupllb %%v19,%%v16\n\t" \
+ " la %[R_IN],16(%[R_IN])\n\t" \
+ " vuplhh %%v20,%%v18\n\t" \
+ " aghi %[R_INLEN],-16\n\t" \
+ " vupllh %%v21,%%v18\n\t" \
+ " aghi %[R_OUTLEN],-64\n\t" \
+ " vuplhh %%v22,%%v19\n\t" \
+ " vupllh %%v23,%%v19\n\t" \
+ /* Store 64 bytes to buf_out. */ \
+ " vstm %%v20,%%v23,0(%[R_OUT])\n\t" \
+ " la %[R_OUT],64(%[R_OUT])\n\t" \
+ " clgijl %[R_INLEN],16,20f\n\t" \
+ " clgijl %[R_OUTLEN],64,20f\n\t" \
+ " j 1b\n\t" \
+ "10: \n\t" \
+ /* At least one byte is > 0x7f. \
+ Store the preceding 1-byte chars. */ \
+ " vlgvb %[R_TMP],%%v17,7\n\t" \
+ " sllk %[R_TMP2],%[R_TMP],2\n\t" /* Compute highest \
+ index to store. */ \
+ " llgfr %[R_TMP3],%[R_TMP2]\n\t" \
+ " ahi %[R_TMP2],-1\n\t" \
+ " jl 20f\n\t" \
+ " vuplhb %%v18,%%v16\n\t" \
+ " vuplhh %%v20,%%v18\n\t" \
+ " vstl %%v20,%[R_TMP2],0(%[R_OUT])\n\t" \
+ " ahi %[R_TMP2],-16\n\t" \
+ " jl 11f\n\t" \
+ " vupllh %%v21,%%v18\n\t" \
+ " vstl %%v21,%[R_TMP2],16(%[R_OUT])\n\t" \
+ " ahi %[R_TMP2],-16\n\t" \
+ " jl 11f\n\t" \
+ " vupllb %%v19,%%v16\n\t" \
+ " vuplhh %%v22,%%v19\n\t" \
+ " vstl %%v22,%[R_TMP2],32(%[R_OUT])\n\t" \
+ " ahi %[R_TMP2],-16\n\t" \
+ " jl 11f\n\t" \
+ " vupllh %%v23,%%v19\n\t" \
+ " vstl %%v23,%[R_TMP2],48(%[R_OUT])\n\t" \
+ "11: \n\t" \
+ /* Update pointers. */ \
+ " la %[R_IN],0(%[R_TMP],%[R_IN])\n\t" \
+ " slgr %[R_INLEN],%[R_TMP]\n\t" \
+ " la %[R_OUT],0(%[R_TMP3],%[R_OUT])\n\t" \
+ " slgr %[R_OUTLEN],%[R_TMP3]\n\t" \
+ /* Handle multibyte utf8-char with convert instruction. */ \
+ "20: cu14 %[R_OUT],%[R_IN],1\n\t" \
+ " jo 0b\n\t" /* Try vector implemenation again. */ \
+ " lochil %[R_RES],%[RES_OUT_FULL]\n\t" /* cc == 1. */ \
+ " lochih %[R_RES],%[RES_IN_ILL]\n\t" /* cc == 2. */ \
+ ".machine pop" \
+ : /* outputs */ [R_IN] "+a" (pInput) \
+ , [R_INLEN] "+d" (inlen), [R_OUT] "+a" (pOutput) \
+ , [R_OUTLEN] "+d" (outlen), [R_TMP] "=a" (tmp) \
+ , [R_TMP2] "=d" (tmp2), [R_TMP3] "=a" (tmp3) \
+ , [R_RES] "+d" (result) \
+ : /* inputs */ \
+ [RES_OUT_FULL] "i" (__GCONV_FULL_OUTPUT) \
+ , [RES_IN_ILL] "i" (__GCONV_ILLEGAL_INPUT) \
+ : /* clobber list */ "memory", "cc" \
+ ASM_CLOBBER_VR ("v16") ASM_CLOBBER_VR ("v17") \
+ ASM_CLOBBER_VR ("v18") ASM_CLOBBER_VR ("v19") \
+ ASM_CLOBBER_VR ("v20") ASM_CLOBBER_VR ("v21") \
+ ASM_CLOBBER_VR ("v22") ASM_CLOBBER_VR ("v30") \
+ ASM_CLOBBER_VR ("v31") \
+ ); \
+ inptr = pInput; \
+ outptr = pOutput; \
+ }
+# define BODY_FROM_VX BODY_FROM_HW (HW_FROM_VX)
+
+/* Generate loop-function with hardware vector and utf-convert instructions. */
+# define MIN_NEEDED_INPUT MIN_NEEDED_FROM
+# define MAX_NEEDED_INPUT MAX_NEEDED_FROM
+# define MIN_NEEDED_OUTPUT MIN_NEEDED_TO
+# define FROM_LOOP_VX __from_utf8_loop_vx
+# define LOOPFCT FROM_LOOP_VX
+
+# define LOOP_NEED_FLAGS
+
+# define STORE_REST STORE_REST_COMMON
+# define UNPACK_BYTES UNPACK_BYTES_COMMON
+# define CLEAR_STATE CLEAR_STATE_COMMON
+# define BODY BODY_FROM_VX
+# include <iconv/loop.c>
+#else
+# define FROM_LOOP_VX NULL
+#endif /* HAVE_FROM_VX != 1 */
+
+#if HAVE_TO_C == 1
+/* The software routine mimics the S/390 cu41 instruction. */
+# define BODY_TO_C \
+ { \
+ uint32_t wc = *((const uint32_t *) inptr); \
+ \
+ if (__glibc_likely (wc <= 0x7f)) \
+ { \
+ /* Single UTF-8 char. */ \
+ *outptr = (uint8_t)wc; \
+ outptr++; \
+ } \
+ else if (wc <= 0x7ff) \
+ { \
+ /* Two UTF-8 chars. */ \
+ if (__glibc_unlikely (outptr + 2 > outend)) \
+ { \
+ /* Overflow in the output buffer. */ \
+ result = __GCONV_FULL_OUTPUT; \
+ break; \
+ } \
+ \
+ outptr[0] = 0xc0; \
+ outptr[0] |= wc >> 6; \
+ \
+ outptr[1] = 0x80; \
+ outptr[1] |= wc & 0x3f; \
+ \
+ outptr += 2; \
+ } \
+ else if (wc <= 0xffff) \
+ { \
+ /* Three UTF-8 chars. */ \
+ if (__glibc_unlikely (outptr + 3 > outend)) \
+ { \
+ /* Overflow in the output buffer. */ \
+ result = __GCONV_FULL_OUTPUT; \
+ break; \
+ } \
+ if (wc >= 0xd800 && wc <= 0xdfff) \
+ { \
+ /* Do not accept UTF-16 surrogates. */ \
+ result = __GCONV_ILLEGAL_INPUT; \
+ STANDARD_TO_LOOP_ERR_HANDLER (4); \
+ } \
+ outptr[0] = 0xe0; \
+ outptr[0] |= wc >> 12; \
+ \
+ outptr[1] = 0x80; \
+ outptr[1] |= (wc >> 6) & 0x3f; \
+ \
+ outptr[2] = 0x80; \
+ outptr[2] |= wc & 0x3f; \
+ \
+ outptr += 3; \
+ } \
+ else if (wc <= 0x10ffff) \
+ { \
+ /* Four UTF-8 chars. */ \
+ if (__glibc_unlikely (outptr + 4 > outend)) \
+ { \
+ /* Overflow in the output buffer. */ \
+ result = __GCONV_FULL_OUTPUT; \
+ break; \
+ } \
+ outptr[0] = 0xf0; \
+ outptr[0] |= wc >> 18; \
+ \
+ outptr[1] = 0x80; \
+ outptr[1] |= (wc >> 12) & 0x3f; \
+ \
+ outptr[2] = 0x80; \
+ outptr[2] |= (wc >> 6) & 0x3f; \
+ \
+ outptr[3] = 0x80; \
+ outptr[3] |= wc & 0x3f; \
+ \
+ outptr += 4; \
+ } \
+ else \
+ { \
+ STANDARD_TO_LOOP_ERR_HANDLER (4); \
+ } \
+ inptr += 4; \
+ }
+
+/* Generate loop-function with software routing. */
+# define MIN_NEEDED_INPUT MIN_NEEDED_TO
+# define MIN_NEEDED_OUTPUT MIN_NEEDED_FROM
+# define MAX_NEEDED_OUTPUT MAX_NEEDED_FROM
+# define TO_LOOP_C __to_utf8_loop_c
+# define LOOPFCT TO_LOOP_C
+# define BODY BODY_TO_C
+# define LOOP_NEED_FLAGS
+# include <iconv/loop.c>
+#else
+# define TO_LOOP_C NULL
+#endif /* HAVE_TO_C != 1 */
+
+#if HAVE_TO_VX == 1
+/* The hardware routine uses the S/390 vector instructions. */
+# define BODY_TO_VX \
+ { \
+ size_t inlen = inend - inptr; \
+ size_t outlen = outend - outptr; \
+ unsigned long tmp, tmp2, tmp3; \
+ asm volatile (".machine push\n\t" \
+ ".machine \"z13\"\n\t" \
+ ".machinemode \"zarch_nohighgprs\"\n\t" \
+ " vleif %%v20,127,0\n\t" /* element 0: 127 */ \
+ " 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,2f\n\t" \
+ " clgijl %[R_OUTLEN],16,2f\n\t" \
+ "1: vlm %%v16,%%v19,0(%[R_IN])\n\t" \
+ " lghi %[R_TMP2],0\n\t" \
+ /* Shorten to byte values. */ \
+ " vpkf %%v23,%%v16,%%v17\n\t" \
+ " vpkf %%v24,%%v18,%%v19\n\t" \
+ " vpkh %%v23,%%v23,%%v24\n\t" \
+ /* Checking for values > 0x7f. */ \
+ " vstrcfs %%v22,%%v16,%%v20,%%v21\n\t" \
+ " jno 10f\n\t" \
+ " vstrcfs %%v22,%%v17,%%v20,%%v21\n\t" \
+ " jno 11f\n\t" \
+ " vstrcfs %%v22,%%v18,%%v20,%%v21\n\t" \
+ " jno 12f\n\t" \
+ " vstrcfs %%v22,%%v19,%%v20,%%v21\n\t" \
+ " jno 13f\n\t" \
+ /* Store 16bytes to outptr. */ \
+ " vst %%v23,0(%[R_OUT])\n\t" \
+ " aghi %[R_INLEN],-64\n\t" \
+ " aghi %[R_OUTLEN],-16\n\t" \
+ " la %[R_IN],64(%[R_IN])\n\t" \
+ " la %[R_OUT],16(%[R_OUT])\n\t" \
+ " clgijl %[R_INLEN],64,2f\n\t" \
+ " clgijl %[R_OUTLEN],16,2f\n\t" \
+ " j 1b\n\t" \
+ /* Found a value > 0x7f. */ \
+ "13: ahi %[R_TMP2],4\n\t" \
+ "12: ahi %[R_TMP2],4\n\t" \
+ "11: ahi %[R_TMP2],4\n\t" \
+ "10: vlgvb %[R_TMP],%%v22,7\n\t" \
+ " srlg %[R_TMP],%[R_TMP],2\n\t" \
+ " agr %[R_TMP],%[R_TMP2]\n\t" \
+ " je 16f\n\t" \
+ /* Store characters before invalid one... */ \
+ " slgr %[R_OUTLEN],%[R_TMP]\n\t" \
+ "15: aghi %[R_TMP],-1\n\t" \
+ " vstl %%v23,%[R_TMP],0(%[R_OUT])\n\t" \
+ /* ... and update pointers. */ \
+ " aghi %[R_TMP],1\n\t" \
+ " la %[R_OUT],0(%[R_TMP],%[R_OUT])\n\t" \
+ " sllg %[R_TMP2],%[R_TMP],2\n\t" \
+ " la %[R_IN],0(%[R_TMP2],%[R_IN])\n\t" \
+ " slgr %[R_INLEN],%[R_TMP2]\n\t" \
+ /* Calculate remaining uint32_t values in loaded vrs. */ \
+ "16: lghi %[R_TMP2],16\n\t" \
+ " sgr %[R_TMP2],%[R_TMP]\n\t" \
+ " l %[R_TMP],0(%[R_IN])\n\t" \
+ " aghi %[R_INLEN],-4\n\t" \
+ " j 22f\n\t" \
+ /* Handle remaining bytes. */ \
+ "2: clgije %[R_INLEN],0,99f\n\t" \
+ " clgijl %[R_INLEN],4,92f\n\t" \
+ /* Calculate remaining uint32_t values in inptr. */ \
+ " srlg %[R_TMP2],%[R_INLEN],2\n\t" \
+ /* Handle multibyte utf8-char. */ \
+ "20: l %[R_TMP],0(%[R_IN])\n\t" \
+ " aghi %[R_INLEN],-4\n\t" \
+ /* Test if ch is 1byte UTF-8 char. */ \
+ "21: clijh %[R_TMP],0x7f,22f\n\t" \
+ /* Handle 1-byte UTF-8 char. */ \
+ "31: slgfi %[R_OUTLEN],1\n\t" \
+ " jl 90f \n\t" \
+ " stc %[R_TMP],0(%[R_OUT])\n\t" \
+ " la %[R_IN],4(%[R_IN])\n\t" \
+ " la %[R_OUT],1(%[R_OUT])\n\t" \
+ " brctg %[R_TMP2],20b\n\t" \
+ " j 0b\n\t" /* Switch to vx-loop. */ \
+ /* Test if ch is 2byte UTF-8 char. */ \
+ "22: clfi %[R_TMP],0x7ff\n\t" \
+ " jh 23f\n\t" \
+ /* Handle 2-byte UTF-8 char. */ \
+ "32: slgfi %[R_OUTLEN],2\n\t" \
+ " jl 90f \n\t" \
+ " llill %[R_TMP3],0xc080\n\t" \
+ " risbgn %[R_TMP3],%[R_TMP],51,55,2\n\t" /* 1. byte. */ \
+ " risbgn %[R_TMP3],%[R_TMP],58,63,0\n\t" /* 2. byte. */ \
+ " sth %[R_TMP3],0(%[R_OUT])\n\t" \
+ " la %[R_IN],4(%[R_IN])\n\t" \
+ " la %[R_OUT],2(%[R_OUT])\n\t" \
+ " brctg %[R_TMP2],20b\n\t" \
+ " j 0b\n\t" /* Switch to vx-loop. */ \
+ /* Test if ch is 3-byte UTF-8 char. */ \
+ "23: clfi %[R_TMP],0xffff\n\t" \
+ " jh 24f\n\t" \
+ /* Handle 3-byte UTF-8 char. */ \
+ "33: slgfi %[R_OUTLEN],3\n\t" \
+ " jl 90f \n\t" \
+ " llilf %[R_TMP3],0xe08080\n\t" \
+ " risbgn %[R_TMP3],%[R_TMP],44,47,4\n\t" /* 1. byte. */ \
+ " risbgn %[R_TMP3],%[R_TMP],50,55,2\n\t" /* 2. byte. */ \
+ " risbgn %[R_TMP3],%[R_TMP],58,63,0\n\t" /* 3. byte. */ \
+ /* Test if ch is a UTF-16 surrogate: ch & 0xf800 == 0xd800 */ \
+ " nilf %[R_TMP],0xf800\n\t" \
+ " clfi %[R_TMP],0xd800\n\t" \
+ " je 91f\n\t" /* Do not accept UTF-16 surrogates. */ \
+ " stcm %[R_TMP3],7,0(%[R_OUT])\n\t" \
+ " la %[R_IN],4(%[R_IN])\n\t" \
+ " la %[R_OUT],3(%[R_OUT])\n\t" \
+ " brctg %[R_TMP2],20b\n\t" \
+ " j 0b\n\t" /* Switch to vx-loop. */ \
+ /* Test if ch is 4-byte UTF-8 char. */ \
+ "24: clfi %[R_TMP],0x10ffff\n\t" \
+ " jh 91f\n\t" /* ch > 0x10ffff is not allowed! */ \
+ /* Handle 4-byte UTF-8 char. */ \
+ "34: slgfi %[R_OUTLEN],4\n\t" \
+ " jl 90f \n\t" \
+ " llilf %[R_TMP3],0xf0808080\n\t" \
+ " risbgn %[R_TMP3],%[R_TMP],37,39,6\n\t" /* 1. byte. */ \
+ " risbgn %[R_TMP3],%[R_TMP],42,47,4\n\t" /* 2. byte. */ \
+ " risbgn %[R_TMP3],%[R_TMP],50,55,2\n\t" /* 3. byte. */ \
+ " risbgn %[R_TMP3],%[R_TMP],58,63,0\n\t" /* 4. byte. */ \
+ " st %[R_TMP3],0(%[R_OUT])\n\t" \
+ " la %[R_IN],4(%[R_IN])\n\t" \
+ " la %[R_OUT],4(%[R_OUT])\n\t" \
+ " brctg %[R_TMP2],20b\n\t" \
+ " j 0b\n\t" /* Switch to vx-loop. */ \
+ "92: lghi %[R_RES],%[RES_IN_FULL]\n\t" \
+ " j 99f\n\t" \
+ "91: lghi %[R_RES],%[RES_IN_ILL]\n\t" \
+ " j 99f\n\t" \
+ "90: lghi %[R_RES],%[RES_OUT_FULL]\n\t" \
+ "99: \n\t" \
+ ".machine pop" \
+ : /* outputs */ [R_IN] "+a" (inptr) \
+ , [R_INLEN] "+d" (inlen), [R_OUT] "+a" (outptr) \
+ , [R_OUTLEN] "+d" (outlen), [R_TMP] "=a" (tmp) \
+ , [R_TMP2] "=a" (tmp2), [R_TMP3] "=d" (tmp3) \
+ , [R_RES] "+d" (result) \
+ : /* inputs */ \
+ [RES_OUT_FULL] "i" (__GCONV_FULL_OUTPUT) \
+ , [RES_IN_ILL] "i" (__GCONV_ILLEGAL_INPUT) \
+ , [RES_IN_FULL] "i" (__GCONV_INCOMPLETE_INPUT) \
+ : /* clobber list */ "memory", "cc" \
+ ASM_CLOBBER_VR ("v16") ASM_CLOBBER_VR ("v17") \
+ ASM_CLOBBER_VR ("v18") ASM_CLOBBER_VR ("v19") \
+ ASM_CLOBBER_VR ("v20") ASM_CLOBBER_VR ("v21") \
+ ASM_CLOBBER_VR ("v22") ASM_CLOBBER_VR ("v23") \
+ ASM_CLOBBER_VR ("v24") \
+ ); \
+ if (__glibc_likely (inptr == inend) \
+ || result != __GCONV_ILLEGAL_INPUT) \
+ break; \
+ \
+ STANDARD_TO_LOOP_ERR_HANDLER (4); \
+ }
+
+/* Generate loop-function with hardware vector instructions. */
+# define MIN_NEEDED_INPUT MIN_NEEDED_TO
+# define MIN_NEEDED_OUTPUT MIN_NEEDED_FROM
+# define MAX_NEEDED_OUTPUT MAX_NEEDED_FROM
+# define TO_LOOP_VX __to_utf8_loop_vx
+# define LOOPFCT TO_LOOP_VX
+# define BODY BODY_TO_VX
+# define LOOP_NEED_FLAGS
+# include <iconv/loop.c>
+#else
+# define TO_LOOP_VX NULL
+#endif /* HAVE_TO_VX != 1 */
+
+#if HAVE_TO_VX_CU == 1
+#define BODY_TO_VX_CU \
+ { \
+ register const unsigned char* pInput asm ("8") = inptr; \
+ register size_t inlen asm ("9") = inend - inptr; \
+ register unsigned char* pOutput asm ("10") = outptr; \
+ register size_t outlen asm ("11") = outend - outptr; \
+ unsigned long tmp, tmp2; \
+ asm volatile (".machine push\n\t" \
+ ".machine \"z13\"\n\t" \
+ ".machinemode \"zarch_nohighgprs\"\n\t" \
+ " vleif %%v20,127,0\n\t" /* element 0: 127 */ \
+ " 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" \
+ "1: vlm %%v16,%%v19,0(%[R_IN])\n\t" \
+ " lghi %[R_TMP],0\n\t" \
+ /* Shorten to byte values. */ \
+ " vpkf %%v23,%%v16,%%v17\n\t" \
+ " vpkf %%v24,%%v18,%%v19\n\t" \
+ " vpkh %%v23,%%v23,%%v24\n\t" \
+ /* Checking for values > 0x7f. */ \
+ " vstrcfs %%v22,%%v16,%%v20,%%v21\n\t" \
+ " jno 10f\n\t" \
+ " vstrcfs %%v22,%%v17,%%v20,%%v21\n\t" \
+ " jno 11f\n\t" \
+ " vstrcfs %%v22,%%v18,%%v20,%%v21\n\t" \
+ " jno 12f\n\t" \
+ " vstrcfs %%v22,%%v19,%%v20,%%v21\n\t" \
+ " jno 13f\n\t" \
+ /* Store 16bytes to outptr. */ \
+ " vst %%v23,0(%[R_OUT])\n\t" \
+ " aghi %[R_INLEN],-64\n\t" \
+ " aghi %[R_OUTLEN],-16\n\t" \
+ " la %[R_IN],64(%[R_IN])\n\t" \
+ " la %[R_OUT],16(%[R_OUT])\n\t" \
+ " clgijl %[R_INLEN],64,20f\n\t" \
+ " clgijl %[R_OUTLEN],16,20f\n\t" \
+ " j 1b\n\t" \
+ /* Found a value > 0x7f. */ \
+ "13: ahi %[R_TMP],4\n\t" \
+ "12: ahi %[R_TMP],4\n\t" \
+ "11: ahi %[R_TMP],4\n\t" \
+ "10: vlgvb %[R_I],%%v22,7\n\t" \
+ " srlg %[R_I],%[R_I],2\n\t" \
+ " agr %[R_I],%[R_TMP]\n\t" \
+ " je 20f\n\t" \
+ /* Store characters before invalid one... */ \
+ " slgr %[R_OUTLEN],%[R_I]\n\t" \
+ "15: aghi %[R_I],-1\n\t" \
+ " vstl %%v23,%[R_I],0(%[R_OUT])\n\t" \
+ /* ... and update pointers. */ \
+ " aghi %[R_I],1\n\t" \
+ " la %[R_OUT],0(%[R_I],%[R_OUT])\n\t" \
+ " sllg %[R_I],%[R_I],2\n\t" \
+ " la %[R_IN],0(%[R_I],%[R_IN])\n\t" \
+ " slgr %[R_INLEN],%[R_I]\n\t" \
+ /* Handle multibyte utf8-char with convert instruction. */ \
+ "20: cu41 %[R_OUT],%[R_IN]\n\t" \
+ " jo 0b\n\t" /* Try vector implemenation again. */ \
+ " lochil %[R_RES],%[RES_OUT_FULL]\n\t" /* cc == 1. */ \
+ " lochih %[R_RES],%[RES_IN_ILL]\n\t" /* cc == 2. */ \
+ ".machine pop" \
+ : /* outputs */ [R_IN] "+a" (pInput) \
+ , [R_INLEN] "+d" (inlen), [R_OUT] "+a" (pOutput) \
+ , [R_OUTLEN] "+d" (outlen), [R_TMP] "=d" (tmp) \
+ , [R_I] "=a" (tmp2) \
+ , [R_RES] "+d" (result) \
+ : /* inputs */ \
+ [RES_OUT_FULL] "i" (__GCONV_FULL_OUTPUT) \
+ , [RES_IN_ILL] "i" (__GCONV_ILLEGAL_INPUT) \
+ : /* clobber list */ "memory", "cc" \
+ ASM_CLOBBER_VR ("v16") ASM_CLOBBER_VR ("v17") \
+ ASM_CLOBBER_VR ("v18") ASM_CLOBBER_VR ("v19") \
+ ASM_CLOBBER_VR ("v20") ASM_CLOBBER_VR ("v21") \
+ ASM_CLOBBER_VR ("v22") ASM_CLOBBER_VR ("v23") \
+ ASM_CLOBBER_VR ("v24") \
+ ); \
+ inptr = pInput; \
+ outptr = pOutput; \
+ \
+ if (__glibc_likely (inptr == inend) \
+ || result == __GCONV_FULL_OUTPUT) \
+ break; \
+ if (inptr + 4 > inend) \
+ { \
+ result = __GCONV_INCOMPLETE_INPUT; \
+ break; \
+ } \
+ STANDARD_TO_LOOP_ERR_HANDLER (4); \
+ }
+
+/* Generate loop-function with hardware vector and utf-convert instructions. */
+# define MIN_NEEDED_INPUT MIN_NEEDED_TO
+# define MIN_NEEDED_OUTPUT MIN_NEEDED_FROM
+# define MAX_NEEDED_OUTPUT MAX_NEEDED_FROM
+# define TO_LOOP_VX_CU __to_utf8_loop_vx_cu
+# define LOOPFCT TO_LOOP_VX_CU
+# define BODY BODY_TO_VX_CU
+# define LOOP_NEED_FLAGS
+# include <iconv/loop.c>
+#else
+# define TO_LOOP_VX_CU NULL
+#endif /* HAVE_TO_VX_CU != 1 */
+
+/* This file also exists in sysdeps/s390/multiarch/ which
+ generates ifunc resolvers for FROM/TO_LOOP functions
+ and includes iconv/skeleton.c afterwards. */
+#if ! defined USE_MULTIARCH
+# include <iconv/skeleton.c>
+#endif