aboutsummaryrefslogtreecommitdiff
path: root/REORG.TODO/sysdeps/s390
diff options
context:
space:
mode:
authorZack Weinberg <zackw@panix.com>2017-06-08 15:39:03 -0400
committerZack Weinberg <zackw@panix.com>2017-06-08 15:39:03 -0400
commit5046dbb4a7eba5eccfd258f92f4735c9ffc8d069 (patch)
tree4470480d904b65cf14ca524f96f79eca818c3eaf /REORG.TODO/sysdeps/s390
parent199fc19d3aaaf57944ef036e15904febe877fc93 (diff)
downloadglibc-zack/build-layout-experiment.tar
glibc-zack/build-layout-experiment.tar.gz
glibc-zack/build-layout-experiment.tar.bz2
glibc-zack/build-layout-experiment.zip
Prepare for radical source tree reorganization.zack/build-layout-experiment
All top-level files and directories are moved into a temporary storage directory, REORG.TODO, except for files that will certainly still exist in their current form at top level when we're done (COPYING, COPYING.LIB, LICENSES, NEWS, README), all old ChangeLog files (which are moved to the new directory OldChangeLogs, instead), and the generated file INSTALL (which is just deleted; in the new order, there will be no generated files checked into version control).
Diffstat (limited to 'REORG.TODO/sysdeps/s390')
-rw-r--r--REORG.TODO/sysdeps/s390/Implies3
-rw-r--r--REORG.TODO/sysdeps/s390/Makefile31
-rw-r--r--REORG.TODO/sysdeps/s390/Versions17
-rw-r--r--REORG.TODO/sysdeps/s390/abort-instr.h2
-rw-r--r--REORG.TODO/sysdeps/s390/asm-syntax.h24
-rw-r--r--REORG.TODO/sysdeps/s390/atomic-machine.h161
-rw-r--r--REORG.TODO/sysdeps/s390/bits/byteswap-16.h65
-rw-r--r--REORG.TODO/sysdeps/s390/bits/byteswap.h134
-rw-r--r--REORG.TODO/sysdeps/s390/bits/endian.h7
-rw-r--r--REORG.TODO/sysdeps/s390/bits/flt-eval-method.h24
-rw-r--r--REORG.TODO/sysdeps/s390/bits/link.h139
-rw-r--r--REORG.TODO/sysdeps/s390/bits/setjmp.h47
-rw-r--r--REORG.TODO/sysdeps/s390/bits/string.h252
-rw-r--r--REORG.TODO/sysdeps/s390/bits/xtitypes.h33
-rw-r--r--REORG.TODO/sysdeps/s390/configure217
-rw-r--r--REORG.TODO/sysdeps/s390/configure.ac116
-rw-r--r--REORG.TODO/sysdeps/s390/dl-irel.h52
-rw-r--r--REORG.TODO/sysdeps/s390/dl-procinfo.c79
-rw-r--r--REORG.TODO/sysdeps/s390/dl-procinfo.h98
-rw-r--r--REORG.TODO/sysdeps/s390/dl-tls.h104
-rw-r--r--REORG.TODO/sysdeps/s390/ffs.c70
-rw-r--r--REORG.TODO/sysdeps/s390/fix-fp-int-convert-overflow.h33
-rw-r--r--REORG.TODO/sysdeps/s390/fpu/bits/fenv.h100
-rw-r--r--REORG.TODO/sysdeps/s390/fpu/bits/mathinline.h100
-rw-r--r--REORG.TODO/sysdeps/s390/fpu/e_sqrt.c29
-rw-r--r--REORG.TODO/sysdeps/s390/fpu/e_sqrtf.c29
-rw-r--r--REORG.TODO/sysdeps/s390/fpu/e_sqrtl.c30
-rw-r--r--REORG.TODO/sysdeps/s390/fpu/fclrexcpt.c45
-rw-r--r--REORG.TODO/sysdeps/s390/fpu/fedisblxcpt.c34
-rw-r--r--REORG.TODO/sysdeps/s390/fpu/feenablxcpt.c34
-rw-r--r--REORG.TODO/sysdeps/s390/fpu/fegetenv.c33
-rw-r--r--REORG.TODO/sysdeps/s390/fpu/fegetexcept.c30
-rw-r--r--REORG.TODO/sysdeps/s390/fpu/fegetmode.c27
-rw-r--r--REORG.TODO/sysdeps/s390/fpu/fegetround.c34
-rw-r--r--REORG.TODO/sysdeps/s390/fpu/feholdexcpt.c37
-rw-r--r--REORG.TODO/sysdeps/s390/fpu/fenv_libc.h39
-rw-r--r--REORG.TODO/sysdeps/s390/fpu/fesetenv.c50
-rw-r--r--REORG.TODO/sysdeps/s390/fpu/fesetexcept.c33
-rw-r--r--REORG.TODO/sysdeps/s390/fpu/fesetmode.c39
-rw-r--r--REORG.TODO/sysdeps/s390/fpu/fesetround.c39
-rw-r--r--REORG.TODO/sysdeps/s390/fpu/fetestexceptflag.c31
-rw-r--r--REORG.TODO/sysdeps/s390/fpu/feupdateenv.c42
-rw-r--r--REORG.TODO/sysdeps/s390/fpu/fgetexcptflg.c41
-rw-r--r--REORG.TODO/sysdeps/s390/fpu/fix-fp-int-compare-invalid.h36
-rw-r--r--REORG.TODO/sysdeps/s390/fpu/fpu_control.h43
-rw-r--r--REORG.TODO/sysdeps/s390/fpu/fraiseexcpt.c107
-rw-r--r--REORG.TODO/sysdeps/s390/fpu/fsetexcptflg.c53
-rw-r--r--REORG.TODO/sysdeps/s390/fpu/ftestexcept.c39
-rw-r--r--REORG.TODO/sysdeps/s390/fpu/get-rounding-mode.h37
-rw-r--r--REORG.TODO/sysdeps/s390/fpu/libm-test-ulps2270
-rw-r--r--REORG.TODO/sysdeps/s390/fpu/libm-test-ulps-name1
-rw-r--r--REORG.TODO/sysdeps/s390/fpu/s_fma.c36
-rw-r--r--REORG.TODO/sysdeps/s390/fpu/s_fmaf.c31
-rw-r--r--REORG.TODO/sysdeps/s390/gccframe.h21
-rw-r--r--REORG.TODO/sysdeps/s390/gconv-modules50
-rw-r--r--REORG.TODO/sysdeps/s390/gmp-mparam.h30
-rw-r--r--REORG.TODO/sysdeps/s390/iso-8859-1_cp037_z900.c262
-rw-r--r--REORG.TODO/sysdeps/s390/jmpbuf-offsets.h28
-rw-r--r--REORG.TODO/sysdeps/s390/jmpbuf-unwind.h54
-rw-r--r--REORG.TODO/sysdeps/s390/ldsodefs.h57
-rw-r--r--REORG.TODO/sysdeps/s390/libc-tls.c32
-rw-r--r--REORG.TODO/sysdeps/s390/linkmap.h13
-rw-r--r--REORG.TODO/sysdeps/s390/longjmp.c52
-rw-r--r--REORG.TODO/sysdeps/s390/machine-gmon.h35
-rw-r--r--REORG.TODO/sysdeps/s390/mempcpy.S19
-rw-r--r--REORG.TODO/sysdeps/s390/memusage.h20
-rw-r--r--REORG.TODO/sysdeps/s390/multiarch/8bit-generic.c398
-rw-r--r--REORG.TODO/sysdeps/s390/multiarch/Makefile59
-rw-r--r--REORG.TODO/sysdeps/s390/multiarch/gconv_simple.c1266
-rw-r--r--REORG.TODO/sysdeps/s390/multiarch/gen-8bit.sh6
-rw-r--r--REORG.TODO/sysdeps/s390/multiarch/iconv/skeleton.c21
-rw-r--r--REORG.TODO/sysdeps/s390/multiarch/ifunc-impl-list.c152
-rw-r--r--REORG.TODO/sysdeps/s390/multiarch/ifunc-resolve.h90
-rw-r--r--REORG.TODO/sysdeps/s390/multiarch/memccpy-c.c25
-rw-r--r--REORG.TODO/sysdeps/s390/multiarch/memccpy-vx.S156
-rw-r--r--REORG.TODO/sysdeps/s390/multiarch/memccpy.c28
-rw-r--r--REORG.TODO/sysdeps/s390/multiarch/memchr-vx.S159
-rw-r--r--REORG.TODO/sysdeps/s390/multiarch/memchr.c27
-rw-r--r--REORG.TODO/sysdeps/s390/multiarch/mempcpy.c32
-rw-r--r--REORG.TODO/sysdeps/s390/multiarch/memrchr-c.c25
-rw-r--r--REORG.TODO/sysdeps/s390/multiarch/memrchr-vx.S160
-rw-r--r--REORG.TODO/sysdeps/s390/multiarch/memrchr.c28
-rw-r--r--REORG.TODO/sysdeps/s390/multiarch/rawmemchr-c.c34
-rw-r--r--REORG.TODO/sysdeps/s390/multiarch/rawmemchr-vx.S92
-rw-r--r--REORG.TODO/sysdeps/s390/multiarch/rawmemchr.c31
-rw-r--r--REORG.TODO/sysdeps/s390/multiarch/stpcpy-c.c35
-rw-r--r--REORG.TODO/sysdeps/s390/multiarch/stpcpy-vx.S104
-rw-r--r--REORG.TODO/sysdeps/s390/multiarch/stpcpy.c35
-rw-r--r--REORG.TODO/sysdeps/s390/multiarch/stpncpy-c.c28
-rw-r--r--REORG.TODO/sysdeps/s390/multiarch/stpncpy-vx.S200
-rw-r--r--REORG.TODO/sysdeps/s390/multiarch/stpncpy.c32
-rw-r--r--REORG.TODO/sysdeps/s390/multiarch/strcat-c.c28
-rw-r--r--REORG.TODO/sysdeps/s390/multiarch/strcat-vx.S161
-rw-r--r--REORG.TODO/sysdeps/s390/multiarch/strcat.c29
-rw-r--r--REORG.TODO/sysdeps/s390/multiarch/strchr-c.c29
-rw-r--r--REORG.TODO/sysdeps/s390/multiarch/strchr-vx.S100
-rw-r--r--REORG.TODO/sysdeps/s390/multiarch/strchr.c32
-rw-r--r--REORG.TODO/sysdeps/s390/multiarch/strchrnul-c.c26
-rw-r--r--REORG.TODO/sysdeps/s390/multiarch/strchrnul-vx.S93
-rw-r--r--REORG.TODO/sysdeps/s390/multiarch/strchrnul.c28
-rw-r--r--REORG.TODO/sysdeps/s390/multiarch/strcmp-vx.S116
-rw-r--r--REORG.TODO/sysdeps/s390/multiarch/strcmp.c29
-rw-r--r--REORG.TODO/sysdeps/s390/multiarch/strcpy-vx.S109
-rw-r--r--REORG.TODO/sysdeps/s390/multiarch/strcpy.c27
-rw-r--r--REORG.TODO/sysdeps/s390/multiarch/strcspn-c.c28
-rw-r--r--REORG.TODO/sysdeps/s390/multiarch/strcspn-vx.S281
-rw-r--r--REORG.TODO/sysdeps/s390/multiarch/strcspn.c31
-rw-r--r--REORG.TODO/sysdeps/s390/multiarch/strlen-c.c28
-rw-r--r--REORG.TODO/sysdeps/s390/multiarch/strlen-vx.S84
-rw-r--r--REORG.TODO/sysdeps/s390/multiarch/strlen.c29
-rw-r--r--REORG.TODO/sysdeps/s390/multiarch/strncat-c.c23
-rw-r--r--REORG.TODO/sysdeps/s390/multiarch/strncat-vx.S239
-rw-r--r--REORG.TODO/sysdeps/s390/multiarch/strncat.c27
-rw-r--r--REORG.TODO/sysdeps/s390/multiarch/strncmp-c.c28
-rw-r--r--REORG.TODO/sysdeps/s390/multiarch/strncmp-vx.S137
-rw-r--r--REORG.TODO/sysdeps/s390/multiarch/strncmp.c31
-rw-r--r--REORG.TODO/sysdeps/s390/multiarch/strncpy-vx.S207
-rw-r--r--REORG.TODO/sysdeps/s390/multiarch/strncpy.c29
-rw-r--r--REORG.TODO/sysdeps/s390/multiarch/strnlen-c.c30
-rw-r--r--REORG.TODO/sysdeps/s390/multiarch/strnlen-vx.S134
-rw-r--r--REORG.TODO/sysdeps/s390/multiarch/strnlen.c32
-rw-r--r--REORG.TODO/sysdeps/s390/multiarch/strpbrk-c.c28
-rw-r--r--REORG.TODO/sysdeps/s390/multiarch/strpbrk-vx.S302
-rw-r--r--REORG.TODO/sysdeps/s390/multiarch/strpbrk.c31
-rw-r--r--REORG.TODO/sysdeps/s390/multiarch/strrchr-c.c29
-rw-r--r--REORG.TODO/sysdeps/s390/multiarch/strrchr-vx.S180
-rw-r--r--REORG.TODO/sysdeps/s390/multiarch/strrchr.c30
-rw-r--r--REORG.TODO/sysdeps/s390/multiarch/strspn-c.c28
-rw-r--r--REORG.TODO/sysdeps/s390/multiarch/strspn-vx.S256
-rw-r--r--REORG.TODO/sysdeps/s390/multiarch/strspn.c31
-rw-r--r--REORG.TODO/sysdeps/s390/multiarch/utf16-utf32-z9.c44
-rw-r--r--REORG.TODO/sysdeps/s390/multiarch/utf8-utf16-z9.c48
-rw-r--r--REORG.TODO/sysdeps/s390/multiarch/utf8-utf32-z9.c48
-rw-r--r--REORG.TODO/sysdeps/s390/multiarch/wcpcpy-c.c25
-rw-r--r--REORG.TODO/sysdeps/s390/multiarch/wcpcpy-vx.S114
-rw-r--r--REORG.TODO/sysdeps/s390/multiarch/wcpcpy.c28
-rw-r--r--REORG.TODO/sysdeps/s390/multiarch/wcpncpy-c.c25
-rw-r--r--REORG.TODO/sysdeps/s390/multiarch/wcpncpy-vx.S222
-rw-r--r--REORG.TODO/sysdeps/s390/multiarch/wcpncpy.c28
-rw-r--r--REORG.TODO/sysdeps/s390/multiarch/wcscat-c.c25
-rw-r--r--REORG.TODO/sysdeps/s390/multiarch/wcscat-vx.S175
-rw-r--r--REORG.TODO/sysdeps/s390/multiarch/wcscat.c28
-rw-r--r--REORG.TODO/sysdeps/s390/multiarch/wcschr-c.c37
-rw-r--r--REORG.TODO/sysdeps/s390/multiarch/wcschr-vx.S103
-rw-r--r--REORG.TODO/sysdeps/s390/multiarch/wcschr.c32
-rw-r--r--REORG.TODO/sysdeps/s390/multiarch/wcschrnul-c.c25
-rw-r--r--REORG.TODO/sysdeps/s390/multiarch/wcschrnul-vx.S97
-rw-r--r--REORG.TODO/sysdeps/s390/multiarch/wcschrnul.c28
-rw-r--r--REORG.TODO/sysdeps/s390/multiarch/wcscmp-c.c32
-rw-r--r--REORG.TODO/sysdeps/s390/multiarch/wcscmp-vx.S131
-rw-r--r--REORG.TODO/sysdeps/s390/multiarch/wcscmp.c30
-rw-r--r--REORG.TODO/sysdeps/s390/multiarch/wcscpy-c.c25
-rw-r--r--REORG.TODO/sysdeps/s390/multiarch/wcscpy-vx.S111
-rw-r--r--REORG.TODO/sysdeps/s390/multiarch/wcscpy.c27
-rw-r--r--REORG.TODO/sysdeps/s390/multiarch/wcscspn-c.c26
-rw-r--r--REORG.TODO/sysdeps/s390/multiarch/wcscspn-vx.S293
-rw-r--r--REORG.TODO/sysdeps/s390/multiarch/wcscspn.c27
-rw-r--r--REORG.TODO/sysdeps/s390/multiarch/wcslen-c.c25
-rw-r--r--REORG.TODO/sysdeps/s390/multiarch/wcslen-vx.S91
-rw-r--r--REORG.TODO/sysdeps/s390/multiarch/wcslen.c28
-rw-r--r--REORG.TODO/sysdeps/s390/multiarch/wcsncat-c.c25
-rw-r--r--REORG.TODO/sysdeps/s390/multiarch/wcsncat-vx.S265
-rw-r--r--REORG.TODO/sysdeps/s390/multiarch/wcsncat.c27
-rw-r--r--REORG.TODO/sysdeps/s390/multiarch/wcsncmp-c.c25
-rw-r--r--REORG.TODO/sysdeps/s390/multiarch/wcsncmp-vx.S177
-rw-r--r--REORG.TODO/sysdeps/s390/multiarch/wcsncmp.c27
-rw-r--r--REORG.TODO/sysdeps/s390/multiarch/wcsncpy-c.c25
-rw-r--r--REORG.TODO/sysdeps/s390/multiarch/wcsncpy-vx.S223
-rw-r--r--REORG.TODO/sysdeps/s390/multiarch/wcsncpy.c28
-rw-r--r--REORG.TODO/sysdeps/s390/multiarch/wcsnlen-c.c25
-rw-r--r--REORG.TODO/sysdeps/s390/multiarch/wcsnlen-vx.S151
-rw-r--r--REORG.TODO/sysdeps/s390/multiarch/wcsnlen.c28
-rw-r--r--REORG.TODO/sysdeps/s390/multiarch/wcspbrk-c.c31
-rw-r--r--REORG.TODO/sysdeps/s390/multiarch/wcspbrk-vx.S315
-rw-r--r--REORG.TODO/sysdeps/s390/multiarch/wcspbrk.c29
-rw-r--r--REORG.TODO/sysdeps/s390/multiarch/wcsrchr-c.c25
-rw-r--r--REORG.TODO/sysdeps/s390/multiarch/wcsrchr-vx.S190
-rw-r--r--REORG.TODO/sysdeps/s390/multiarch/wcsrchr.c27
-rw-r--r--REORG.TODO/sysdeps/s390/multiarch/wcsspn-c.c31
-rw-r--r--REORG.TODO/sysdeps/s390/multiarch/wcsspn-vx.S270
-rw-r--r--REORG.TODO/sysdeps/s390/multiarch/wcsspn.c29
-rw-r--r--REORG.TODO/sysdeps/s390/multiarch/wmemchr-c.c37
-rw-r--r--REORG.TODO/sysdeps/s390/multiarch/wmemchr-vx.S166
-rw-r--r--REORG.TODO/sysdeps/s390/multiarch/wmemchr.c32
-rw-r--r--REORG.TODO/sysdeps/s390/multiarch/wmemcmp-c.c26
-rw-r--r--REORG.TODO/sysdeps/s390/multiarch/wmemcmp-vx.S149
-rw-r--r--REORG.TODO/sysdeps/s390/multiarch/wmemcmp.c27
-rw-r--r--REORG.TODO/sysdeps/s390/multiarch/wmemset-c.c37
-rw-r--r--REORG.TODO/sysdeps/s390/multiarch/wmemset-vx.S142
-rw-r--r--REORG.TODO/sysdeps/s390/multiarch/wmemset.c32
-rw-r--r--REORG.TODO/sysdeps/s390/nptl/Makefile25
-rw-r--r--REORG.TODO/sysdeps/s390/nptl/bits/pthreadtypes-arch.h81
-rw-r--r--REORG.TODO/sysdeps/s390/nptl/bits/semaphore.h39
-rw-r--r--REORG.TODO/sysdeps/s390/nptl/pthreaddef.h33
-rw-r--r--REORG.TODO/sysdeps/s390/nptl/tcb-offsets.sym6
-rw-r--r--REORG.TODO/sysdeps/s390/nptl/tls.h196
-rw-r--r--REORG.TODO/sysdeps/s390/preconfigure6
-rw-r--r--REORG.TODO/sysdeps/s390/s390-32/Implies1
-rw-r--r--REORG.TODO/sysdeps/s390/s390-32/Makefile9
-rw-r--r--REORG.TODO/sysdeps/s390/s390-32/Versions6
-rw-r--r--REORG.TODO/sysdeps/s390/s390-32/__longjmp.c83
-rw-r--r--REORG.TODO/sysdeps/s390/s390-32/add_n.S63
-rw-r--r--REORG.TODO/sysdeps/s390/s390-32/addmul_1.S58
-rw-r--r--REORG.TODO/sysdeps/s390/s390-32/backtrace.c148
-rw-r--r--REORG.TODO/sysdeps/s390/s390-32/bcopy.S85
-rw-r--r--REORG.TODO/sysdeps/s390/s390-32/bits/wordsize.h11
-rw-r--r--REORG.TODO/sysdeps/s390/s390-32/bsd-_setjmp.S1
-rw-r--r--REORG.TODO/sysdeps/s390/s390-32/bsd-setjmp.S1
-rw-r--r--REORG.TODO/sysdeps/s390/s390-32/bzero.S42
-rw-r--r--REORG.TODO/sysdeps/s390/s390-32/crti.S102
-rw-r--r--REORG.TODO/sysdeps/s390/s390-32/crtn.S47
-rw-r--r--REORG.TODO/sysdeps/s390/s390-32/dl-machine.h522
-rw-r--r--REORG.TODO/sysdeps/s390/s390-32/dl-sysdep.h23
-rw-r--r--REORG.TODO/sysdeps/s390/s390-32/dl-trampoline.S33
-rw-r--r--REORG.TODO/sysdeps/s390/s390-32/dl-trampoline.h231
-rw-r--r--REORG.TODO/sysdeps/s390/s390-32/memchr.S41
-rw-r--r--REORG.TODO/sysdeps/s390/s390-32/memcmp.S66
-rw-r--r--REORG.TODO/sysdeps/s390/s390-32/memcpy.S89
-rw-r--r--REORG.TODO/sysdeps/s390/s390-32/memset.S65
-rw-r--r--REORG.TODO/sysdeps/s390/s390-32/mul_1.S55
-rw-r--r--REORG.TODO/sysdeps/s390/s390-32/multiarch/Makefile4
-rw-r--r--REORG.TODO/sysdeps/s390/s390-32/multiarch/memchr.c21
-rw-r--r--REORG.TODO/sysdeps/s390/s390-32/multiarch/memcmp-s390.S107
-rw-r--r--REORG.TODO/sysdeps/s390/s390-32/multiarch/memcmp.c27
-rw-r--r--REORG.TODO/sysdeps/s390/s390-32/multiarch/memcpy-s390.S128
-rw-r--r--REORG.TODO/sysdeps/s390/s390-32/multiarch/memcpy.c27
-rw-r--r--REORG.TODO/sysdeps/s390/s390-32/multiarch/memset-s390.S116
-rw-r--r--REORG.TODO/sysdeps/s390/s390-32/multiarch/memset.c26
-rw-r--r--REORG.TODO/sysdeps/s390/s390-32/multiarch/strcmp.c21
-rw-r--r--REORG.TODO/sysdeps/s390/s390-32/multiarch/strcpy.c21
-rw-r--r--REORG.TODO/sysdeps/s390/s390-32/multiarch/strncpy.c21
-rw-r--r--REORG.TODO/sysdeps/s390/s390-32/s390-mcount.S89
-rw-r--r--REORG.TODO/sysdeps/s390/s390-32/setjmp.S123
-rw-r--r--REORG.TODO/sysdeps/s390/s390-32/stackguard-macros.h15
-rw-r--r--REORG.TODO/sysdeps/s390/s390-32/start.S211
-rw-r--r--REORG.TODO/sysdeps/s390/s390-32/strcmp.S41
-rw-r--r--REORG.TODO/sysdeps/s390/s390-32/strcpy.S36
-rw-r--r--REORG.TODO/sysdeps/s390/s390-32/strncpy.S79
-rw-r--r--REORG.TODO/sysdeps/s390/s390-32/sub_n.S62
-rw-r--r--REORG.TODO/sysdeps/s390/s390-32/symbol-hacks.h21
-rw-r--r--REORG.TODO/sysdeps/s390/s390-32/sysdep.h101
-rw-r--r--REORG.TODO/sysdeps/s390/s390-32/tls-macros.h104
-rw-r--r--REORG.TODO/sysdeps/s390/s390-32/tst-audit.h25
-rw-r--r--REORG.TODO/sysdeps/s390/s390-64/Implies1
-rw-r--r--REORG.TODO/sysdeps/s390/s390-64/Makefile9
-rw-r--r--REORG.TODO/sysdeps/s390/s390-64/__longjmp.c89
-rw-r--r--REORG.TODO/sysdeps/s390/s390-64/add_n.S63
-rw-r--r--REORG.TODO/sysdeps/s390/s390-64/backtrace.c147
-rw-r--r--REORG.TODO/sysdeps/s390/s390-64/bcopy.S71
-rw-r--r--REORG.TODO/sysdeps/s390/s390-64/bits/wordsize.h11
-rw-r--r--REORG.TODO/sysdeps/s390/s390-64/bsd-_setjmp.S1
-rw-r--r--REORG.TODO/sysdeps/s390/s390-64/bsd-setjmp.S1
-rw-r--r--REORG.TODO/sysdeps/s390/s390-64/bzero.S41
-rw-r--r--REORG.TODO/sysdeps/s390/s390-64/crti.S91
-rw-r--r--REORG.TODO/sysdeps/s390/s390-64/crtn.S50
-rw-r--r--REORG.TODO/sysdeps/s390/s390-64/dl-machine.h476
-rw-r--r--REORG.TODO/sysdeps/s390/s390-64/dl-trampoline.S33
-rw-r--r--REORG.TODO/sysdeps/s390/s390-64/dl-trampoline.h225
-rw-r--r--REORG.TODO/sysdeps/s390/s390-64/memchr.S40
-rw-r--r--REORG.TODO/sysdeps/s390/s390-64/memcmp.S64
-rw-r--r--REORG.TODO/sysdeps/s390/s390-64/memcpy.S88
-rw-r--r--REORG.TODO/sysdeps/s390/s390-64/memset.S64
-rw-r--r--REORG.TODO/sysdeps/s390/s390-64/multiarch/Makefile4
-rw-r--r--REORG.TODO/sysdeps/s390/s390-64/multiarch/memchr.c21
-rw-r--r--REORG.TODO/sysdeps/s390/s390-64/multiarch/memcmp-s390x.S104
-rw-r--r--REORG.TODO/sysdeps/s390/s390-64/multiarch/memcmp.c27
-rw-r--r--REORG.TODO/sysdeps/s390/s390-64/multiarch/memcpy-s390x.S122
-rw-r--r--REORG.TODO/sysdeps/s390/s390-64/multiarch/memcpy.c27
-rw-r--r--REORG.TODO/sysdeps/s390/s390-64/multiarch/memset-s390x.S112
-rw-r--r--REORG.TODO/sysdeps/s390/s390-64/multiarch/memset.c26
-rw-r--r--REORG.TODO/sysdeps/s390/s390-64/multiarch/strcmp.c21
-rw-r--r--REORG.TODO/sysdeps/s390/s390-64/multiarch/strcpy.c21
-rw-r--r--REORG.TODO/sysdeps/s390/s390-64/multiarch/strncpy.c21
-rw-r--r--REORG.TODO/sysdeps/s390/s390-64/s390x-mcount.S77
-rw-r--r--REORG.TODO/sysdeps/s390/s390-64/setjmp.S118
-rw-r--r--REORG.TODO/sysdeps/s390/s390-64/stackguard-macros.h18
-rw-r--r--REORG.TODO/sysdeps/s390/s390-64/start.S100
-rw-r--r--REORG.TODO/sysdeps/s390/s390-64/strcmp.S41
-rw-r--r--REORG.TODO/sysdeps/s390/s390-64/strcpy.S35
-rw-r--r--REORG.TODO/sysdeps/s390/s390-64/strncpy.S90
-rw-r--r--REORG.TODO/sysdeps/s390/s390-64/sub_n.S60
-rw-r--r--REORG.TODO/sysdeps/s390/s390-64/sysdep.h94
-rw-r--r--REORG.TODO/sysdeps/s390/s390-64/tls-macros.h88
-rw-r--r--REORG.TODO/sysdeps/s390/s390-64/tst-audit.h25
-rw-r--r--REORG.TODO/sysdeps/s390/sotruss-lib.c62
-rw-r--r--REORG.TODO/sysdeps/s390/stackinfo.h33
-rw-r--r--REORG.TODO/sysdeps/s390/string_private.h20
-rw-r--r--REORG.TODO/sysdeps/s390/utf16-utf32-z9.c603
-rw-r--r--REORG.TODO/sysdeps/s390/utf8-utf16-z9.c825
-rw-r--r--REORG.TODO/sysdeps/s390/utf8-utf32-z9.c871
290 files changed, 25677 insertions, 0 deletions
diff --git a/REORG.TODO/sysdeps/s390/Implies b/REORG.TODO/sysdeps/s390/Implies
new file mode 100644
index 0000000000..1945b1f4bb
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/Implies
@@ -0,0 +1,3 @@
+ieee754/ldbl-128
+ieee754/dbl-64
+ieee754/flt-32
diff --git a/REORG.TODO/sysdeps/s390/Makefile b/REORG.TODO/sysdeps/s390/Makefile
new file mode 100644
index 0000000000..8a54f88cd7
--- /dev/null
+++ b/REORG.TODO/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/REORG.TODO/sysdeps/s390/Versions b/REORG.TODO/sysdeps/s390/Versions
new file mode 100644
index 0000000000..8417623353
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/Versions
@@ -0,0 +1,17 @@
+libc {
+ GLIBC_2.19 {
+ setjmp; _setjmp; __sigsetjmp;
+ longjmp; _longjmp; siglongjmp;
+ }
+}
+
+ld {
+ GLIBC_2.3 {
+ # runtime interface to TLS
+ __tls_get_offset;
+ }
+ GLIBC_PRIVATE {
+ # Exported by ld used by libc.
+ __tls_get_addr_internal;
+ }
+}
diff --git a/REORG.TODO/sysdeps/s390/abort-instr.h b/REORG.TODO/sysdeps/s390/abort-instr.h
new file mode 100644
index 0000000000..825601ad50
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/abort-instr.h
@@ -0,0 +1,2 @@
+/* An op-code of 0 should crash any program. */
+#define ABORT_INSTRUCTION __asm__ (".word 0")
diff --git a/REORG.TODO/sysdeps/s390/asm-syntax.h b/REORG.TODO/sysdeps/s390/asm-syntax.h
new file mode 100644
index 0000000000..00b6338a7b
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/asm-syntax.h
@@ -0,0 +1,24 @@
+/* Definitions for S/390 syntax variations.
+ Copyright (C) 1992-2017 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.
+
+ 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/>. */
+
+#undef ALIGN
+#define ALIGN(log) .align 1<<log
+
+#undef L
+#define L(body) .L##body
diff --git a/REORG.TODO/sysdeps/s390/atomic-machine.h b/REORG.TODO/sysdeps/s390/atomic-machine.h
new file mode 100644
index 0000000000..adaca40798
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/atomic-machine.h
@@ -0,0 +1,161 @@
+/* Copyright (C) 2003-2017 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
+ 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 <stdint.h>
+
+typedef int8_t atomic8_t;
+typedef uint8_t uatomic8_t;
+typedef int_fast8_t atomic_fast8_t;
+typedef uint_fast8_t uatomic_fast8_t;
+
+typedef int16_t atomic16_t;
+typedef uint16_t uatomic16_t;
+typedef int_fast16_t atomic_fast16_t;
+typedef uint_fast16_t uatomic_fast16_t;
+
+typedef int32_t atomic32_t;
+typedef uint32_t uatomic32_t;
+typedef int_fast32_t atomic_fast32_t;
+typedef uint_fast32_t uatomic_fast32_t;
+
+typedef int64_t atomic64_t;
+typedef uint64_t uatomic64_t;
+typedef int_fast64_t atomic_fast64_t;
+typedef uint_fast64_t uatomic_fast64_t;
+
+typedef intptr_t atomicptr_t;
+typedef uintptr_t uatomicptr_t;
+typedef intmax_t atomic_max_t;
+typedef uintmax_t uatomic_max_t;
+
+/* 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.
+
+ 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.
+
+ 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
+#else
+# define __HAVE_64B_ATOMICS 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. */
+#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/REORG.TODO/sysdeps/s390/bits/byteswap-16.h b/REORG.TODO/sysdeps/s390/bits/byteswap-16.h
new file mode 100644
index 0000000000..85ae5f5505
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/bits/byteswap-16.h
@@ -0,0 +1,65 @@
+/* Macros to swap the order of bytes in 16-bit integer values. s390 version
+ Copyright (C) 2012-2017 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/REORG.TODO/sysdeps/s390/bits/byteswap.h b/REORG.TODO/sysdeps/s390/bits/byteswap.h
new file mode 100644
index 0000000000..6d5f65e6f8
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/bits/byteswap.h
@@ -0,0 +1,134 @@
+/* Macros to swap the order of bytes in integer values. s390 version.
+ Copyright (C) 2000-2017 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/REORG.TODO/sysdeps/s390/bits/endian.h b/REORG.TODO/sysdeps/s390/bits/endian.h
new file mode 100644
index 0000000000..ac27f0119a
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/bits/endian.h
@@ -0,0 +1,7 @@
+/* s390 is big-endian */
+
+#ifndef _ENDIAN_H
+# error "Never use <bits/endian.h> directly; include <endian.h> instead."
+#endif
+
+#define __BYTE_ORDER __BIG_ENDIAN
diff --git a/REORG.TODO/sysdeps/s390/bits/flt-eval-method.h b/REORG.TODO/sysdeps/s390/bits/flt-eval-method.h
new file mode 100644
index 0000000000..c0fc68af06
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/bits/flt-eval-method.h
@@ -0,0 +1,24 @@
+/* Define __GLIBC_FLT_EVAL_METHOD. S/390 version.
+ Copyright (C) 2016-2017 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/REORG.TODO/sysdeps/s390/bits/link.h b/REORG.TODO/sysdeps/s390/bits/link.h
new file mode 100644
index 0000000000..5960b9642c
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/bits/link.h
@@ -0,0 +1,139 @@
+/* Copyright (C) 2005-2017 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 _LINK_H
+# 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
+
+/* Registers for entry into PLT on s390-32. */
+typedef struct La_s390_32_regs
+{
+ uint32_t lr_r2;
+ uint32_t lr_r3;
+ uint32_t lr_r4;
+ uint32_t lr_r5;
+ 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. */
+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;
+
+
+__BEGIN_DECLS
+
+extern Elf32_Addr la_s390_32_gnu_pltenter (Elf32_Sym *__sym,
+ unsigned int __ndx,
+ uintptr_t *__refcook,
+ uintptr_t *__defcook,
+ La_s390_32_regs *__regs,
+ unsigned int *__flags,
+ const char *__symname,
+ long int *__framesizep);
+extern unsigned int la_s390_32_gnu_pltexit (Elf32_Sym *__sym,
+ unsigned int __ndx,
+ uintptr_t *__refcook,
+ uintptr_t *__defcook,
+ const La_s390_32_regs *__inregs,
+ La_s390_32_retval *__outregs,
+ const char *symname);
+
+__END_DECLS
+
+#else
+
+/* Registers for entry into PLT on s390-64. */
+typedef struct La_s390_64_regs
+{
+ uint64_t lr_r2;
+ uint64_t lr_r3;
+ uint64_t lr_r4;
+ uint64_t lr_r5;
+ uint64_t lr_r6;
+ double lr_fp0;
+ 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. */
+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;
+
+
+__BEGIN_DECLS
+
+extern Elf64_Addr la_s390_64_gnu_pltenter (Elf64_Sym *__sym,
+ unsigned int __ndx,
+ uintptr_t *__refcook,
+ uintptr_t *__defcook,
+ La_s390_64_regs *__regs,
+ unsigned int *__flags,
+ const char *__symname,
+ long int *__framesizep);
+extern unsigned int la_s390_64_gnu_pltexit (Elf64_Sym *__sym,
+ unsigned int __ndx,
+ uintptr_t *__refcook,
+ uintptr_t *__defcook,
+ const La_s390_64_regs *__inregs,
+ La_s390_64_retval *__outregs,
+ const char *__symname);
+
+__END_DECLS
+
+#endif
diff --git a/REORG.TODO/sysdeps/s390/bits/setjmp.h b/REORG.TODO/sysdeps/s390/bits/setjmp.h
new file mode 100644
index 0000000000..9aa3fe204f
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/bits/setjmp.h
@@ -0,0 +1,47 @@
+/* Copyright (C) 2000-2017 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/>. */
+
+/* Define the machine-dependent type `jmp_buf'. IBM s390 version. */
+
+#ifndef __S390_SETJMP_H__
+#define __S390_SETJMP_H__
+
+#if !defined _SETJMP_H && !defined _PTHREAD_H
+# error "Never include <bits/setjmp.h> directly; use <setjmp.h> instead."
+#endif
+
+#include <bits/wordsize.h>
+
+#ifndef _ASM
+
+typedef struct __s390_jmp_buf
+{
+ /* We save registers 6-15. */
+ long int __gregs[10];
+
+# if __WORDSIZE == 64
+ /* We save fpu registers f8 - f15. */
+ long __fpregs[8];
+# else
+ /* We save fpu registers 4 and 6. */
+ long __fpregs[4];
+# endif
+} __jmp_buf[1];
+
+#endif
+
+#endif /* __S390_SETJMP_H__ */
diff --git a/REORG.TODO/sysdeps/s390/bits/string.h b/REORG.TODO/sysdeps/s390/bits/string.h
new file mode 100644
index 0000000000..1e794f925d
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/bits/string.h
@@ -0,0 +1,252 @@
+/* Optimized, inlined string functions. S/390 version.
+ Copyright (C) 2000-2017 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/REORG.TODO/sysdeps/s390/bits/xtitypes.h b/REORG.TODO/sysdeps/s390/bits/xtitypes.h
new file mode 100644
index 0000000000..dd3fe43880
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/bits/xtitypes.h
@@ -0,0 +1,33 @@
+/* bits/xtitypes.h -- Define some types used by <bits/stropts.h>. S390/S390x
+ Copyright (C) 2002-2017 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 _STROPTS_H
+# error "Never include <bits/xtitypes.h> directly; use <stropts.h> instead."
+#endif
+
+#ifndef _BITS_XTITYPES_H
+#define _BITS_XTITYPES_H 1
+
+#include <bits/types.h>
+
+/* This type is used by some structs in <bits/stropts.h>. */
+typedef __S32_TYPE __t_scalar_t;
+typedef __U32_TYPE __t_uscalar_t;
+
+
+#endif /* bits/xtitypes.h */
diff --git a/REORG.TODO/sysdeps/s390/configure b/REORG.TODO/sysdeps/s390/configure
new file mode 100644
index 0000000000..347ac28528
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/configure
@@ -0,0 +1,217 @@
+# This file is generated from configure.ac by Autoconf. DO NOT EDIT!
+ # Local configure fragment for sysdeps/s390.
+
+$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 :
+ $as_echo_n "(cached) " >&6
+else
+ cat > conftest.c <<\EOF
+#include <htmintrin.h>
+void testtransaction ()
+{
+ if (__builtin_tbegin (0) == _HTM_TBEGIN_STARTED)
+ {
+ __builtin_tend ();
+ }
+}
+EOF
+if { ac_try='${CC-cc} -mhtm -O2 -S conftest.c -o - | grep -w tbegin > /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_builtin_tbegin=yes
+else
+ libc_cv_gcc_builtin_tbegin=no
+fi
+rm -f conftest*
+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
+ critic_missing="$critic_missing The used GCC has no support for __builtin_tbegin, which is needed for lock-elision on target S390."
+fi
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for S390 vector instruction support" >&5
+$as_echo_n "checking for S390 vector instruction support... " >&6; }
+if ${libc_cv_asm_s390_vx+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat > conftest.c <<\EOF
+void testvecinsn ()
+{
+ __asm__ (".machine \"z13\" \n\t"
+ ".machinemode \"zarch_nohighgprs\" \n\t"
+ "vistrbs %%v16,%%v17 \n\t"
+ "locghie %%r1,0" : :);
+}
+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_asm_s390_vx=yes
+else
+ libc_cv_asm_s390_vx=no
+fi
+rm -f conftest*
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libc_cv_asm_s390_vx" >&5
+$as_echo "$libc_cv_asm_s390_vx" >&6; }
+
+if test "$libc_cv_asm_s390_vx" = yes ;
+then
+ $as_echo "#define HAVE_S390_VX_ASM_SUPPORT 1" >>confdefs.h
+
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Use binutils with vector-support in order to use optimized implementations." >&5
+$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/REORG.TODO/sysdeps/s390/configure.ac b/REORG.TODO/sysdeps/s390/configure.ac
new file mode 100644
index 0000000000..8a782e7c3a
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/configure.ac
@@ -0,0 +1,116 @@
+GLIBC_PROVIDES dnl See aclocal.m4 in the top level source directory.
+# Local configure fragment for sysdeps/s390.
+
+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>
+void testtransaction ()
+{
+ if (__builtin_tbegin (0) == _HTM_TBEGIN_STARTED)
+ {
+ __builtin_tend ();
+ }
+}
+EOF
+dnl
+dnl test, if the tbegin instruction is used by __builtin_tbegin
+if AC_TRY_COMMAND([${CC-cc} -mhtm -O2 -S conftest.c -o - | grep -w tbegin > /dev/null]) ;
+then
+ libc_cv_gcc_builtin_tbegin=yes
+else
+ libc_cv_gcc_builtin_tbegin=no
+fi
+rm -f conftest* ])
+
+if test "$enable_lock_elision" = yes && 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
+
+
+AC_CACHE_CHECK(for S390 vector instruction support, libc_cv_asm_s390_vx, [dnl
+cat > conftest.c <<\EOF
+void testvecinsn ()
+{
+ __asm__ (".machine \"z13\" \n\t"
+ ".machinemode \"zarch_nohighgprs\" \n\t"
+ "vistrbs %%v16,%%v17 \n\t"
+ "locghie %%r1,0" : :);
+}
+EOF
+dnl
+dnl test, if assembler supports S390 vector instructions
+if AC_TRY_COMMAND([${CC-cc} --shared conftest.c -o conftest.o &> /dev/null]) ;
+then
+ libc_cv_asm_s390_vx=yes
+else
+ libc_cv_asm_s390_vx=no
+fi
+rm -f conftest* ])
+
+if test "$libc_cv_asm_s390_vx" = yes ;
+then
+ AC_DEFINE(HAVE_S390_VX_ASM_SUPPORT)
+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/REORG.TODO/sysdeps/s390/dl-irel.h b/REORG.TODO/sysdeps/s390/dl-irel.h
new file mode 100644
index 0000000000..731e3070f2
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/dl-irel.h
@@ -0,0 +1,52 @@
+/* Machine-dependent ELF indirect relocation inline functions.
+ Version for S/390 32 and 64 bit.
+ Copyright (C) 2012-2017 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 _DL_IREL_H
+#define _DL_IREL_H
+
+#include <stdio.h>
+#include <unistd.h>
+#include <ldsodefs.h>
+
+#define ELF_MACHINE_IRELA 1
+
+static inline ElfW(Addr)
+__attribute ((always_inline))
+elf_ifunc_invoke (ElfW(Addr) addr)
+{
+ return ((ElfW(Addr) (*) (unsigned long int)) (addr)) (GLRO(dl_hwcap));
+}
+
+static inline void
+__attribute ((always_inline))
+elf_irela (const ElfW(Rela) *reloc)
+{
+ ElfW(Addr) *const reloc_addr = (void *) reloc->r_offset;
+ const unsigned long int r_type = ELFW(R_TYPE) (reloc->r_info);
+
+ if (__glibc_likely (r_type == R_390_IRELATIVE))
+ {
+ ElfW(Addr) value = elf_ifunc_invoke(reloc->r_addend);
+ *reloc_addr = value;
+ }
+ else
+ __libc_fatal ("unexpected reloc type in static binary");
+}
+
+#endif /* dl-irel.h */
diff --git a/REORG.TODO/sysdeps/s390/dl-procinfo.c b/REORG.TODO/sysdeps/s390/dl-procinfo.c
new file mode 100644
index 0000000000..4fcde8e889
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/dl-procinfo.c
@@ -0,0 +1,79 @@
+/* Data for s390 version of processor capability information.
+ Copyright (C) 2006-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Martin Schwidefsky <schwidefsky@de.ibm.com>, 2006.
+
+ 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 information must be kept in sync with the _DL_HWCAP_COUNT and
+ _DL_PLATFORM_COUNT definitions in procinfo.h.
+
+ If anything should be added here check whether the size of each string
+ is still ok with the given array size.
+
+ All the #ifdefs in the definitions are quite irritating but
+ necessary if we want to avoid duplicating the information. There
+ are three different modes:
+
+ - PROCINFO_DECL is defined. This means we are only interested in
+ declarations.
+
+ - PROCINFO_DECL is not defined:
+
+ + if SHARED is defined the file is included in an array
+ initializer. The .element = { ... } syntax is needed.
+
+ + if SHARED is not defined a normal array initialization is
+ needed.
+ */
+
+#ifndef PROCINFO_CLASS
+# define PROCINFO_CLASS
+#endif
+
+#if !defined PROCINFO_DECL && defined SHARED
+ ._dl_s390_cap_flags
+#else
+PROCINFO_CLASS const char _dl_s390_cap_flags[12][9]
+#endif
+#ifndef PROCINFO_DECL
+= {
+ "esan3", "zarch", "stfle", "msa", "ldisp", "eimm", "dfp", "edat", "etf3eh", "highgprs", "te", "vx"
+ }
+#endif
+#if !defined SHARED || defined PROCINFO_DECL
+;
+#else
+,
+#endif
+
+#if !defined PROCINFO_DECL && defined SHARED
+ ._dl_s390_platforms
+#else
+PROCINFO_CLASS const char _dl_s390_platforms[8][7]
+#endif
+#ifndef PROCINFO_DECL
+= {
+ "g5", "z900", "z990", "z9-109", "z10", "z196", "zEC12", "z13"
+ }
+#endif
+#if !defined SHARED || defined PROCINFO_DECL
+;
+#else
+,
+#endif
+
+#undef PROCINFO_DECL
+#undef PROCINFO_CLASS
diff --git a/REORG.TODO/sysdeps/s390/dl-procinfo.h b/REORG.TODO/sysdeps/s390/dl-procinfo.h
new file mode 100644
index 0000000000..c99789629a
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/dl-procinfo.h
@@ -0,0 +1,98 @@
+/* s390 version of processor capability information handling macros.
+ Copyright (C) 2006-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Martin Schwidefsky <schwidefsky@de.ibm.com>, 2006.
+
+ 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 _DL_PROCINFO_H
+#define _DL_PROCINFO_H 1
+#include <ldsodefs.h>
+
+#define _DL_HWCAP_COUNT 12
+
+#define _DL_PLATFORMS_COUNT 8
+
+/* The kernel provides up to 32 capability bits with elf_hwcap. */
+#define _DL_FIRST_PLATFORM 32
+/* Mask to filter out platforms. */
+#define _DL_HWCAP_PLATFORM (((1ULL << _DL_PLATFORMS_COUNT) - 1) \
+ << _DL_FIRST_PLATFORM)
+
+/* Hardware capability bit numbers are derived directly from the
+ facility indications as stored by the "store facility list" (STFL)
+ instruction.
+ highgprs is an alien in that list. It describes a *kernel*
+ capability. */
+
+enum
+{
+ HWCAP_S390_ESAN3 = 1 << 0,
+ HWCAP_S390_ZARCH = 1 << 1,
+ HWCAP_S390_STFLE = 1 << 2,
+ HWCAP_S390_MSA = 1 << 3,
+ HWCAP_S390_LDISP = 1 << 4,
+ HWCAP_S390_EIMM = 1 << 5,
+ HWCAP_S390_DFP = 1 << 6,
+ HWCAP_S390_HPAGE = 1 << 7,
+ HWCAP_S390_ETF3EH = 1 << 8,
+ HWCAP_S390_HIGH_GPRS = 1 << 9,
+ HWCAP_S390_TE = 1 << 10,
+ HWCAP_S390_VX = 1 << 11,
+};
+
+#define HWCAP_IMPORTANT (HWCAP_S390_ZARCH | HWCAP_S390_LDISP \
+ | HWCAP_S390_EIMM | HWCAP_S390_DFP)
+
+/* We cannot provide a general printing function. */
+#define _dl_procinfo(type, word) -1
+
+static inline const char *
+__attribute__ ((unused))
+_dl_hwcap_string (int idx)
+{
+ return GLRO(dl_s390_cap_flags)[idx];
+};
+
+static inline int
+__attribute__ ((unused, always_inline))
+_dl_string_hwcap (const char *str)
+{
+ int i;
+
+ for (i = 0; i < _DL_HWCAP_COUNT; i++)
+ {
+ if (strcmp (str, GLRO(dl_s390_cap_flags)[i]) == 0)
+ return i;
+ }
+ return -1;
+};
+
+static inline int
+__attribute__ ((unused, always_inline))
+_dl_string_platform (const char *str)
+{
+ int i;
+
+ if (str != NULL)
+ for (i = 0; i < _DL_PLATFORMS_COUNT; ++i)
+ {
+ if (strcmp (str, GLRO(dl_s390_platforms)[i]) == 0)
+ return _DL_FIRST_PLATFORM + i;
+ }
+ return -1;
+};
+
+#endif /* dl-procinfo.h */
diff --git a/REORG.TODO/sysdeps/s390/dl-tls.h b/REORG.TODO/sysdeps/s390/dl-tls.h
new file mode 100644
index 0000000000..3298acfbcf
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/dl-tls.h
@@ -0,0 +1,104 @@
+/* Thread-local storage handling in the ELF dynamic linker. s390 version.
+ Copyright (C) 2003-2017 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/>. */
+
+
+/* Type used for the representation of TLS information in the GOT. */
+typedef struct
+{
+ unsigned long int ti_module;
+ unsigned long int ti_offset;
+} tls_index;
+
+
+#ifdef SHARED
+
+extern unsigned long __tls_get_offset (unsigned long got_offset);
+
+# if IS_IN (rtld)
+
+# include <shlib-compat.h>
+
+/* dl-tls.c declares __tls_get_addr as an exported symbol if it is not defined
+ as a macro. It seems suitable to do that in the generic code because all
+ architectures other than s390 export __tls_get_addr. The declaration causes
+ problems in s390 though, so we define __tls_get_addr here to avoid declaring
+ __tls_get_addr again. */
+# define __tls_get_addr __tls_get_addr
+
+extern void *__tls_get_addr (tls_index *ti) attribute_hidden;
+/* Make a temporary alias of __tls_get_addr to remove the hidden
+ attribute. Then export __tls_get_addr as __tls_get_addr_internal
+ for use from libc. We do not want to export __tls_get_addr, but we
+ do need to use it from libc when looking up the address of a TLS
+ variable. We don't use __tls_get_offset because it requires r12 to
+ be setup and that might not always be true. Either way it's more
+ optimal to use __tls_get_addr directly (that's what
+ __tls_get_offset does anyways). */
+strong_alias (__tls_get_addr, __tls_get_addr_internal_tmp);
+versioned_symbol (ld, __tls_get_addr_internal_tmp,
+ __tls_get_addr_internal, GLIBC_PRIVATE);
+
+/* The special thing about the s390 TLS ABI is that we do not have the
+ standard __tls_get_addr function but the __tls_get_offset function
+ which differs in two important aspects:
+ 1) __tls_get_offset gets a got offset instead of a pointer to the
+ tls_index structure
+ 2) __tls_get_offset returns the offset of the requested variable to
+ the thread descriptor instead of a pointer to the variable.
+ */
+# ifdef __s390x__
+__asm__("\n\
+ .text\n\
+ .globl __tls_get_offset\n\
+ .type __tls_get_offset, @function\n\
+ .align 4\n\
+__tls_get_offset:\n\
+ la %r2,0(%r2,%r12)\n\
+ jg __tls_get_addr\n\
+");
+# elif defined __s390__
+__asm__("\n\
+ .text\n\
+ .globl __tls_get_offset\n\
+ .type __tls_get_offset, @function\n\
+ .align 4\n\
+__tls_get_offset:\n\
+ basr %r3,0\n\
+0: la %r2,0(%r2,%r12)\n\
+ l %r4,1f-0b(%r3)\n\
+ b 0(%r4,%r3)\n\
+1: .long __tls_get_addr - 0b\n\
+");
+# endif
+# else /* IS_IN (rtld) */
+extern void *__tls_get_addr_internal (tls_index *ti);
+# endif /* !IS_IN (rtld) */
+
+# define GET_ADDR_OFFSET \
+ (ti->ti_offset - (unsigned long) __builtin_thread_pointer ())
+
+/* Use the privately exported __tls_get_addr_internal instead of
+ __tls_get_offset in order to avoid the __tls_get_offset special
+ linkage requiring the GOT pointer to be set up in r12. The
+ compiler will take care of setting up r12 only if itself issued the
+ __tls_get_offset call. */
+# define __TLS_GET_ADDR(__ti) \
+ ({ __tls_get_addr_internal (__ti) \
+ + (unsigned long) __builtin_thread_pointer (); })
+
+#endif
diff --git a/REORG.TODO/sysdeps/s390/ffs.c b/REORG.TODO/sysdeps/s390/ffs.c
new file mode 100644
index 0000000000..c36f60045b
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/ffs.c
@@ -0,0 +1,70 @@
+/* ffs -- find first set bit in a word, counted from least significant end.
+ S/390 version.
+ Copyright (C) 2000-2017 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/>. */
+
+#include <limits.h>
+#define ffsl __something_else
+#include <string.h>
+
+#undef ffs
+
+/* ffs: find first bit set. This is defined the same way as
+ the libc and compiler builtin ffs routines, therefore
+ differs in spirit from the above ffz (man ffs). */
+
+int
+__ffs (int x)
+{
+ int r;
+
+ if (x == 0)
+ return 0;
+ __asm__(" lr %%r1,%1\n"
+ " sr %0,%0\n"
+ " tml %%r1,0xFFFF\n"
+ " jnz 0f\n"
+ " ahi %0,16\n"
+ " srl %%r1,16\n"
+ "0: tml %%r1,0x00FF\n"
+ " jnz 1f\n"
+ " ahi %0,8\n"
+ " srl %%r1,8\n"
+ "1: tml %%r1,0x000F\n"
+ " jnz 2f\n"
+ " ahi %0,4\n"
+ " srl %%r1,4\n"
+ "2: tml %%r1,0x0003\n"
+ " jnz 3f\n"
+ " ahi %0,2\n"
+ " srl %%r1,2\n"
+ "3: tml %%r1,0x0001\n"
+ " jnz 4f\n"
+ " ahi %0,1\n"
+ "4:"
+ : "=&d" (r) : "d" (x) : "cc", "1" );
+ return r+1;
+}
+
+weak_alias (__ffs, ffs)
+libc_hidden_def (__ffs)
+libc_hidden_builtin_def (ffs)
+#if ULONG_MAX == UINT_MAX
+#undef ffsl
+weak_alias (__ffs, ffsl)
+#endif
diff --git a/REORG.TODO/sysdeps/s390/fix-fp-int-convert-overflow.h b/REORG.TODO/sysdeps/s390/fix-fp-int-convert-overflow.h
new file mode 100644
index 0000000000..cef804e259
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/fix-fp-int-convert-overflow.h
@@ -0,0 +1,33 @@
+/* Fix for conversion of floating point to integer overflow. S390 version.
+ Copyright (C) 2016-2017 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_CONVERT_OVERFLOW_H
+#define FIX_FP_INT_CONVERT_OVERFLOW_H 1
+
+/* GCC emits "convert to fixed" instructions for casting floating point values
+ to integer values. These instructions raise invalid and inexact exceptions
+ if the floating point value exceeds the integer type ranges. */
+#define FIX_FLT_LLONG_CONVERT_OVERFLOW 1
+#define FIX_DBL_LLONG_CONVERT_OVERFLOW 1
+#define FIX_LDBL_LLONG_CONVERT_OVERFLOW 1
+
+#define FIX_FLT_LONG_CONVERT_OVERFLOW 1
+#define FIX_DBL_LONG_CONVERT_OVERFLOW 1
+#define FIX_LDBL_LONG_CONVERT_OVERFLOW 1
+
+#endif /* fix-fp-int-convert-overflow.h */
diff --git a/REORG.TODO/sysdeps/s390/fpu/bits/fenv.h b/REORG.TODO/sysdeps/s390/fpu/bits/fenv.h
new file mode 100644
index 0000000000..3110ed71d4
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/fpu/bits/fenv.h
@@ -0,0 +1,100 @@
+/* Copyright (C) 2000-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Denis Joseph Barrow <djbarrow@de.ibm.com>.
+
+ 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 _FENV_H
+# error "Never use <bits/fenv.h> directly; include <fenv.h> instead."
+#endif
+
+/* Define bits representing the exception. We use the bit positions
+ of the appropriate bits in the FPU control word. */
+enum
+ {
+ FE_INVALID =
+#define FE_INVALID 0x80
+ FE_INVALID,
+ FE_DIVBYZERO =
+#define FE_DIVBYZERO 0x40
+ FE_DIVBYZERO,
+ FE_OVERFLOW =
+#define FE_OVERFLOW 0x20
+ FE_OVERFLOW,
+ FE_UNDERFLOW =
+#define FE_UNDERFLOW 0x10
+ FE_UNDERFLOW,
+ FE_INEXACT =
+#define FE_INEXACT 0x08
+ FE_INEXACT
+ };
+/* We dont use the y bit of the DXC in the floating point control register
+ as glibc has no FE encoding for fe inexact incremented
+ or fe inexact truncated.
+ We currently use the flag bits in the fpc
+ as these are sticky for feholdenv & feupdatenv as it is defined
+ in the HP Manpages. */
+
+
+#define FE_ALL_EXCEPT \
+ (FE_INEXACT | FE_DIVBYZERO | FE_UNDERFLOW | FE_OVERFLOW | FE_INVALID)
+
+enum
+ {
+ FE_TONEAREST =
+#define FE_TONEAREST 0
+ FE_TONEAREST,
+ FE_DOWNWARD =
+#define FE_DOWNWARD 0x3
+ FE_DOWNWARD,
+ FE_UPWARD =
+#define FE_UPWARD 0x2
+ FE_UPWARD,
+ FE_TOWARDZERO =
+#define FE_TOWARDZERO 0x1
+ FE_TOWARDZERO
+ };
+
+
+/* Type representing exception flags. */
+typedef unsigned int fexcept_t; /* size of fpc */
+
+
+/* Type representing floating-point environment. This function corresponds
+ to the layout of the block written by the `fstenv'. */
+typedef struct
+{
+ fexcept_t __fpc;
+ void *__unused;
+ /* The field __unused (formerly __ieee_instruction_pointer) is a relict from
+ commit "Remove PTRACE_PEEKUSER" (87b9b50f0d4b92248905e95a06a13c513dc45e59)
+ and isn´t used anymore. */
+} fenv_t;
+
+/* If the default argument is used we use this value. */
+#define FE_DFL_ENV ((const fenv_t *) -1)
+
+#ifdef __USE_GNU
+/* 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/REORG.TODO/sysdeps/s390/fpu/bits/mathinline.h b/REORG.TODO/sysdeps/s390/fpu/bits/mathinline.h
new file mode 100644
index 0000000000..52e21db98d
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/fpu/bits/mathinline.h
@@ -0,0 +1,100 @@
+/* Inline math functions for s390.
+ Copyright (C) 2004-2017 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/REORG.TODO/sysdeps/s390/fpu/e_sqrt.c b/REORG.TODO/sysdeps/s390/fpu/e_sqrt.c
new file mode 100644
index 0000000000..bcb93098c3
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/fpu/e_sqrt.c
@@ -0,0 +1,29 @@
+/* Copyright (C) 2004-2017 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/>. */
+
+#include <math_private.h>
+
+double
+__ieee754_sqrt (double x)
+{
+ double res;
+
+ __asm__ ( "sqdbr %0,%1" : "=f" (res) : "f" (x) );
+ return res;
+}
+strong_alias (__ieee754_sqrt, __sqrt_finite)
diff --git a/REORG.TODO/sysdeps/s390/fpu/e_sqrtf.c b/REORG.TODO/sysdeps/s390/fpu/e_sqrtf.c
new file mode 100644
index 0000000000..42dad4389a
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/fpu/e_sqrtf.c
@@ -0,0 +1,29 @@
+/* Copyright (C) 2004-2017 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/>. */
+
+#include <math_private.h>
+
+float
+__ieee754_sqrtf (float x)
+{
+ float res;
+
+ __asm__ ( "sqebr %0,%1" : "=f" (res) : "f" (x) );
+ return res;
+}
+strong_alias (__ieee754_sqrtf, __sqrtf_finite)
diff --git a/REORG.TODO/sysdeps/s390/fpu/e_sqrtl.c b/REORG.TODO/sysdeps/s390/fpu/e_sqrtl.c
new file mode 100644
index 0000000000..8eab5f0b6a
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/fpu/e_sqrtl.c
@@ -0,0 +1,30 @@
+/* Square root. S/390 FPU version.
+ Copyright (C) 2004-2017 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/>. */
+
+#include <math_private.h>
+
+long double
+__ieee754_sqrtl (long double x)
+{
+ long double res;
+
+ __asm__ ( "sqxbr %0,%1" : "=f" (res) : "f" (x) );
+ return res;
+}
+strong_alias (__ieee754_sqrtl, __sqrtl_finite)
diff --git a/REORG.TODO/sysdeps/s390/fpu/fclrexcpt.c b/REORG.TODO/sysdeps/s390/fpu/fclrexcpt.c
new file mode 100644
index 0000000000..06c66279ff
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/fpu/fclrexcpt.c
@@ -0,0 +1,45 @@
+/* Clear given exceptions in current floating-point environment.
+ Copyright (C) 2000-2017 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_libc.h>
+#include <fpu_control.h>
+
+int
+feclearexcept (int excepts)
+{
+ fexcept_t temp;
+
+ /* Mask out unsupported bits/exceptions. */
+ excepts &= FE_ALL_EXCEPT;
+
+ _FPU_GETCW (temp);
+ /* Clear the relevant bits. */
+ temp &= ~(excepts << FPC_FLAGS_SHIFT);
+ if ((temp & FPC_NOT_FPU_EXCEPTION) == 0)
+ /* Bits 6, 7 of dxc-byte are zero,
+ thus bits 0-5 of dxc-byte correspond to the flag-bits.
+ Clear the relevant bits in flags and dxc-field. */
+ temp &= ~(excepts << FPC_DXC_SHIFT);
+
+ /* Put the new data in effect. */
+ _FPU_SETCW (temp);
+
+ /* Success. */
+ return 0;
+}
+libm_hidden_def (feclearexcept)
diff --git a/REORG.TODO/sysdeps/s390/fpu/fedisblxcpt.c b/REORG.TODO/sysdeps/s390/fpu/fedisblxcpt.c
new file mode 100644
index 0000000000..2fdb413968
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/fpu/fedisblxcpt.c
@@ -0,0 +1,34 @@
+/* Disable floating-point exceptions.
+ Copyright (C) 2000-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Denis Joseph Barrow (djbarrow@de.ibm.com).
+
+ 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_libc.h>
+#include <fpu_control.h>
+
+int
+fedisableexcept (int excepts)
+{
+ fexcept_t temp, old_exc, new_flags;
+
+ _FPU_GETCW (temp);
+ old_exc = (temp & FPC_EXCEPTION_MASK) >> FPC_EXCEPTION_MASK_SHIFT;
+ new_flags = (temp & (~((excepts & FE_ALL_EXCEPT) << FPC_EXCEPTION_MASK_SHIFT)));
+ _FPU_SETCW (new_flags);
+
+ return old_exc;
+}
diff --git a/REORG.TODO/sysdeps/s390/fpu/feenablxcpt.c b/REORG.TODO/sysdeps/s390/fpu/feenablxcpt.c
new file mode 100644
index 0000000000..4a9e64dc30
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/fpu/feenablxcpt.c
@@ -0,0 +1,34 @@
+/* Enable floating-point exceptions.
+ Copyright (C) 2000-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Denis Joseph Barrow (djbarrow@de.ibm.com).
+
+ 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_libc.h>
+#include <fpu_control.h>
+
+int
+feenableexcept (int excepts)
+{
+ fexcept_t temp, old_exc, new_flags;
+
+ _FPU_GETCW (temp);
+ old_exc = (temp & FPC_EXCEPTION_MASK) >> FPC_EXCEPTION_MASK_SHIFT;
+ new_flags = (temp | ((excepts & FE_ALL_EXCEPT) << FPC_EXCEPTION_MASK_SHIFT));
+ _FPU_SETCW (new_flags);
+
+ return old_exc;
+}
diff --git a/REORG.TODO/sysdeps/s390/fpu/fegetenv.c b/REORG.TODO/sysdeps/s390/fpu/fegetenv.c
new file mode 100644
index 0000000000..d3455a0df3
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/fpu/fegetenv.c
@@ -0,0 +1,33 @@
+/* Store current floating-point environment.
+ Copyright (C) 2000-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Denis Joseph Barrow (djbarrow@de.ibm.com).
+
+ 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_libc.h>
+#include <fpu_control.h>
+
+int
+__fegetenv (fenv_t *envp)
+{
+ _FPU_GETCW (envp->__fpc);
+
+ /* Success. */
+ return 0;
+}
+libm_hidden_def (__fegetenv)
+weak_alias (__fegetenv, fegetenv)
+libm_hidden_weak (fegetenv)
diff --git a/REORG.TODO/sysdeps/s390/fpu/fegetexcept.c b/REORG.TODO/sysdeps/s390/fpu/fegetexcept.c
new file mode 100644
index 0000000000..95cd133c5b
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/fpu/fegetexcept.c
@@ -0,0 +1,30 @@
+/* Get enabled floating-point exceptions.
+ Copyright (C) 2000-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Denis Joseph Barrow (djbarrow@de.ibm.com).
+
+ 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_libc.h>
+#include <fpu_control.h>
+
+int
+fegetexcept (void)
+{
+ fexcept_t exc;
+
+ _FPU_GETCW (exc);
+ return ((exc & FPC_EXCEPTION_MASK) >> FPC_EXCEPTION_MASK_SHIFT);
+}
diff --git a/REORG.TODO/sysdeps/s390/fpu/fegetmode.c b/REORG.TODO/sysdeps/s390/fpu/fegetmode.c
new file mode 100644
index 0000000000..9286df3576
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/fpu/fegetmode.c
@@ -0,0 +1,27 @@
+/* Store current floating-point control modes. S/390 version.
+ Copyright (C) 2016-2017 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 <fpu_control.h>
+
+int
+fegetmode (femode_t *modep)
+{
+ _FPU_GETCW (*modep);
+ return 0;
+}
diff --git a/REORG.TODO/sysdeps/s390/fpu/fegetround.c b/REORG.TODO/sysdeps/s390/fpu/fegetround.c
new file mode 100644
index 0000000000..81d2ef6e41
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/fpu/fegetround.c
@@ -0,0 +1,34 @@
+/* Return current rounding direction.
+ Copyright (C) 2000-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Denis Joseph Barrow (djbarrow@de.ibm.com).
+
+ 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_libc.h>
+#include <fpu_control.h>
+
+int
+__fegetround (void)
+{
+ fexcept_t cw;
+
+ _FPU_GETCW (cw);
+
+ return cw & FPC_RM_MASK;
+}
+libm_hidden_def (__fegetround)
+weak_alias (__fegetround, fegetround)
+libm_hidden_weak (fegetround)
diff --git a/REORG.TODO/sysdeps/s390/fpu/feholdexcpt.c b/REORG.TODO/sysdeps/s390/fpu/feholdexcpt.c
new file mode 100644
index 0000000000..1cd1d445c7
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/fpu/feholdexcpt.c
@@ -0,0 +1,37 @@
+/* Store current floating-point environment and clear exceptions.
+ Copyright (C) 2000-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Denis Joseph Barrow (djbarrow@de.ibm.com).
+
+ 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_libc.h>
+#include <fpu_control.h>
+
+int __feholdexcept (fenv_t *envp)
+{
+ fexcept_t fpc;
+ /* Store the environment. */
+ fegetenv (envp);
+ /* Clear the current sticky bits as more than one exception
+ may be generated. */
+ fpc = envp->__fpc & ~(FPC_FLAGS_MASK | FPC_DXC_MASK);
+ /* Hold from generating fpu exceptions temporarily. */
+ _FPU_SETCW ((fpc & ~(FE_ALL_EXCEPT << FPC_EXCEPTION_MASK_SHIFT)));
+ return 0;
+}
+libm_hidden_def (__feholdexcept)
+weak_alias (__feholdexcept, feholdexcept)
+libm_hidden_weak (feholdexcept)
diff --git a/REORG.TODO/sysdeps/s390/fpu/fenv_libc.h b/REORG.TODO/sysdeps/s390/fpu/fenv_libc.h
new file mode 100644
index 0000000000..4d088e4613
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/fpu/fenv_libc.h
@@ -0,0 +1,39 @@
+/* Copyright (C) 2000-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Denis Joseph Barrow (djbarrow@de.ibm.com).
+
+ 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 _FENV_LIBC_H
+#define _FENV_LIBC_H 1
+
+#include <fenv.h>
+
+/* Definitions from asm/s390-regs-common.h that are needed in glibc. */
+
+
+#define FPC_EXCEPTION_MASK 0xF8000000
+#define FPC_FLAGS_MASK 0x00F80000
+#define FPC_DXC_MASK 0x0000FF00
+#define FPC_RM_MASK 0x00000003
+#define FPC_VALID_MASK ((FPC_EXCEPTION_MASK|FPC_FLAGS_MASK| \
+ FPC_DXC_MASK|FPC_RM_MASK))
+
+#define FPC_EXCEPTION_MASK_SHIFT 24
+#define FPC_FLAGS_SHIFT 16
+#define FPC_DXC_SHIFT 8
+#define FPC_NOT_FPU_EXCEPTION 0x300
+
+#endif /* _FENV_LIBC_H */
diff --git a/REORG.TODO/sysdeps/s390/fpu/fesetenv.c b/REORG.TODO/sysdeps/s390/fpu/fesetenv.c
new file mode 100644
index 0000000000..4c9bcf0629
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/fpu/fesetenv.c
@@ -0,0 +1,50 @@
+/* Install given floating-point environment.
+ Copyright (C) 2000-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Denis Joseph Barrow (djbarrow@de.ibm.com).
+
+ 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_libc.h>
+#include <fpu_control.h>
+#include <stddef.h>
+#include <asm/ptrace.h>
+#include <sys/ptrace.h>
+#include <unistd.h>
+
+int
+__fesetenv (const fenv_t *envp)
+{
+ fenv_t env;
+
+ if (envp == FE_DFL_ENV)
+ {
+ env.__fpc = _FPU_DEFAULT;
+ }
+ else if (envp == FE_NOMASK_ENV)
+ {
+ env.__fpc = FPC_EXCEPTION_MASK;
+ }
+ else
+ env = (*envp);
+
+ _FPU_SETCW (env.__fpc);
+
+ /* Success. */
+ return 0;
+}
+libm_hidden_def (__fesetenv)
+weak_alias (__fesetenv, fesetenv)
+libm_hidden_weak (fesetenv)
diff --git a/REORG.TODO/sysdeps/s390/fpu/fesetexcept.c b/REORG.TODO/sysdeps/s390/fpu/fesetexcept.c
new file mode 100644
index 0000000000..0b4d1f33f3
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/fpu/fesetexcept.c
@@ -0,0 +1,33 @@
+/* Set given exception flags. S/390 version.
+ Copyright (C) 2016-2017 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 <fpu_control.h>
+#include <fenv_libc.h>
+
+int
+fesetexcept (int excepts)
+{
+ fexcept_t temp;
+
+ _FPU_GETCW (temp);
+ temp |= (excepts & FE_ALL_EXCEPT) << FPC_FLAGS_SHIFT;
+ _FPU_SETCW (temp);
+
+ return 0;
+}
diff --git a/REORG.TODO/sysdeps/s390/fpu/fesetmode.c b/REORG.TODO/sysdeps/s390/fpu/fesetmode.c
new file mode 100644
index 0000000000..14b7457fa5
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/fpu/fesetmode.c
@@ -0,0 +1,39 @@
+/* Install given floating-point control modes. S/390 version.
+ Copyright (C) 2016-2017 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 <fpu_control.h>
+#include <fenv_libc.h>
+
+#define FPC_STATUS (FPC_FLAGS_MASK | FPC_DXC_MASK)
+
+int
+fesetmode (const femode_t *modep)
+{
+ 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;
+}
diff --git a/REORG.TODO/sysdeps/s390/fpu/fesetround.c b/REORG.TODO/sysdeps/s390/fpu/fesetround.c
new file mode 100644
index 0000000000..5ed14fac06
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/fpu/fesetround.c
@@ -0,0 +1,39 @@
+/* Set current rounding direction.
+ Copyright (C) 2000-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Denis Joseph Barrow (djbarrow@de.ibm.com).
+
+ 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_libc.h>
+#include <fpu_control.h>
+
+int
+__fesetround (int round)
+{
+ if ((round|FPC_RM_MASK) != FPC_RM_MASK)
+ {
+ /* ROUND is not a valid rounding mode. */
+ return 1;
+ }
+ __asm__ __volatile__ ("srnm 0(%0)"
+ :
+ : "a" (round));
+
+ return 0;
+}
+libm_hidden_def (__fesetround)
+weak_alias (__fesetround, fesetround)
+libm_hidden_weak (fesetround)
diff --git a/REORG.TODO/sysdeps/s390/fpu/fetestexceptflag.c b/REORG.TODO/sysdeps/s390/fpu/fetestexceptflag.c
new file mode 100644
index 0000000000..21fe64de8a
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/fpu/fetestexceptflag.c
@@ -0,0 +1,31 @@
+/* Test exception in saved exception state. S/390 version.
+ Copyright (C) 2016-2017 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/REORG.TODO/sysdeps/s390/fpu/feupdateenv.c b/REORG.TODO/sysdeps/s390/fpu/feupdateenv.c
new file mode 100644
index 0000000000..de764b029e
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/fpu/feupdateenv.c
@@ -0,0 +1,42 @@
+/* Install given floating-point environment and raise exceptions.
+ Copyright (C) 2000-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Denis Joseph Barrow (djbarrow@de.ibm.com).
+
+ 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_libc.h>
+#include <fpu_control.h>
+
+int
+__feupdateenv (const fenv_t *envp)
+{
+ fexcept_t temp;
+
+ _FPU_GETCW (temp);
+ temp = (temp & FPC_FLAGS_MASK) >> FPC_FLAGS_SHIFT;
+
+ /* Raise the exceptions since the last call to feholdenv */
+ /* re install saved environment. */
+ __fesetenv (envp);
+ __feraiseexcept ((int) temp);
+
+ /* Success. */
+ return 0;
+}
+libm_hidden_def (__feupdateenv)
+weak_alias (__feupdateenv, feupdateenv)
+libm_hidden_weak (feupdateenv)
diff --git a/REORG.TODO/sysdeps/s390/fpu/fgetexcptflg.c b/REORG.TODO/sysdeps/s390/fpu/fgetexcptflg.c
new file mode 100644
index 0000000000..f49410550e
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/fpu/fgetexcptflg.c
@@ -0,0 +1,41 @@
+/* Store current representation for exceptions.
+ Copyright (C) 2000-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Denis Joseph Barrow (djbarrow@de.ibm.com).
+
+ 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_libc.h>
+#include <fpu_control.h>
+
+int
+fegetexceptflag (fexcept_t *flagp, int excepts)
+{
+ fexcept_t temp, newexcepts;
+
+ /* Get the current exceptions. */
+ _FPU_GETCW (temp);
+ newexcepts = excepts << FPC_FLAGS_SHIFT;
+ if ((temp & FPC_NOT_FPU_EXCEPTION) == 0)
+ /* Bits 6, 7 of dxc-byte are zero,
+ thus bits 0-5 of dxc-byte correspond to the flag-bits.
+ Evaluate flags and last dxc-exception-code. */
+ newexcepts |= excepts << FPC_DXC_SHIFT;
+
+ *flagp = temp & newexcepts;
+
+ /* Success. */
+ return 0;
+}
diff --git a/REORG.TODO/sysdeps/s390/fpu/fix-fp-int-compare-invalid.h b/REORG.TODO/sysdeps/s390/fpu/fix-fp-int-compare-invalid.h
new file mode 100644
index 0000000000..bccdf8d56b
--- /dev/null
+++ b/REORG.TODO/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-2017 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/REORG.TODO/sysdeps/s390/fpu/fpu_control.h b/REORG.TODO/sysdeps/s390/fpu/fpu_control.h
new file mode 100644
index 0000000000..c855b014cb
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/fpu/fpu_control.h
@@ -0,0 +1,43 @@
+/* FPU control word definitions. Stub version.
+ Copyright (C) 2000-2017 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.
+
+ 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 _FPU_CONTROL_H
+#define _FPU_CONTROL_H
+
+#include <features.h>
+
+/* These bits are reserved are not changed. */
+#define _FPU_RESERVED 0x0707FFFC
+
+/* The fdlibm code requires no interrupts for exceptions. Don't
+ change the rounding mode, it would break long double I/O! */
+#define _FPU_DEFAULT 0x00000000 /* Default value. */
+
+/* Type of the control word. */
+typedef unsigned int fpu_control_t;
+
+/* Macros for accessing the hardware control word. */
+#define _FPU_GETCW(cw) __asm__ __volatile__ ("efpc %0,0" : "=d" (cw))
+#define _FPU_SETCW(cw) __asm__ __volatile__ ("sfpc %0,0" : : "d" (cw))
+
+/* Default control word set at startup. */
+extern fpu_control_t __fpu_control;
+
+#endif /* _FPU_CONTROL_H */
diff --git a/REORG.TODO/sysdeps/s390/fpu/fraiseexcpt.c b/REORG.TODO/sysdeps/s390/fpu/fraiseexcpt.c
new file mode 100644
index 0000000000..d0d93dd5a9
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/fpu/fraiseexcpt.c
@@ -0,0 +1,107 @@
+/* Raise given exceptions.
+ Copyright (C) 2000-2017 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).
+
+ 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_libc.h>
+#include <float.h>
+#include <math.h>
+
+
+static __inline__ void
+fexceptdiv (float d, float e)
+{
+ __asm__ __volatile__ ("debr %0,%1" : : "f" (d), "f" (e) );
+}
+
+static __inline__ void
+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)
+{
+ /* Raise exceptions represented by EXPECTS. But we must raise only
+ one signal at a time. It is important that if the overflow/underflow
+ exception and the inexact exception are given at the same time,
+ the overflow/underflow exception follows the inexact exception. */
+
+ /* First: invalid exception. */
+ if (FE_INVALID & excepts)
+ fexceptdiv (0.0, 0.0);
+
+ /* Next: division by zero. */
+ if (FE_DIVBYZERO & excepts)
+ fexceptdiv (1.0, 0.0);
+
+ /* Next: overflow. */
+ if (FE_OVERFLOW & excepts)
+ {
+#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)
+ {
+#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)
+ fexceptdiv (2.0, 3.0);
+
+ /* Success. */
+ return 0;
+}
+libm_hidden_def (__feraiseexcept)
+weak_alias (__feraiseexcept, feraiseexcept)
+libm_hidden_weak (feraiseexcept)
diff --git a/REORG.TODO/sysdeps/s390/fpu/fsetexcptflg.c b/REORG.TODO/sysdeps/s390/fpu/fsetexcptflg.c
new file mode 100644
index 0000000000..58e462fb5a
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/fpu/fsetexcptflg.c
@@ -0,0 +1,53 @@
+/* Set floating-point environment exception handling.
+ Copyright (C) 2000-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Denis Joseph Barrow (djbarrow@de.ibm.com).
+
+ 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_libc.h>
+#include <math.h>
+#include <fpu_control.h>
+
+int
+fesetexceptflag (const fexcept_t *flagp, int excepts)
+{
+ fexcept_t temp, newexcepts;
+
+ /* Get the current environment. We have to do this since we cannot
+ separately set the status word. */
+ _FPU_GETCW (temp);
+ /* Install the new exception bits in the Accrued Exception Byte. */
+ excepts = excepts & FE_ALL_EXCEPT;
+ newexcepts = excepts << FPC_FLAGS_SHIFT;
+ temp &= ~newexcepts;
+ if ((temp & FPC_NOT_FPU_EXCEPTION) == 0)
+ /* Bits 6, 7 of dxc-byte are zero,
+ thus bits 0-5 of dxc-byte correspond to the flag-bits.
+ Clear given exceptions in dxc-field. */
+ temp &= ~(excepts << FPC_DXC_SHIFT);
+
+ /* Integrate dxc-byte of flagp into flags. The dxc-byte of flagp contains
+ either an ieee-exception or 0 (see fegetexceptflag). */
+ temp |= (*flagp | ((*flagp >> FPC_DXC_SHIFT) << FPC_FLAGS_SHIFT))
+ & newexcepts;
+
+ /* Store the new status word (along with the rest of the environment.
+ Possibly new exceptions are set but they won't get executed. */
+ _FPU_SETCW (temp);
+
+ /* Success. */
+ return 0;
+}
diff --git a/REORG.TODO/sysdeps/s390/fpu/ftestexcept.c b/REORG.TODO/sysdeps/s390/fpu/ftestexcept.c
new file mode 100644
index 0000000000..8c56f78a40
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/fpu/ftestexcept.c
@@ -0,0 +1,39 @@
+/* Test exception in current environment.
+ Copyright (C) 2000-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Denis Joseph Barrow (djbarrow@de.ibm.com).
+
+ 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_libc.h>
+#include <fpu_control.h>
+
+int
+fetestexcept (int excepts)
+{
+ fexcept_t temp, res;
+
+ /* Get current exceptions. */
+ _FPU_GETCW (temp);
+ res = temp >> FPC_FLAGS_SHIFT;
+ if ((temp & FPC_NOT_FPU_EXCEPTION) == 0)
+ /* Bits 6, 7 of dxc-byte are zero,
+ thus bits 0-5 of dxc-byte correspond to the flag-bits.
+ Evaluate flags and last dxc-exception-code. */
+ res |= temp >> FPC_DXC_SHIFT;
+
+ return res & excepts & FE_ALL_EXCEPT;
+}
+libm_hidden_def (fetestexcept)
diff --git a/REORG.TODO/sysdeps/s390/fpu/get-rounding-mode.h b/REORG.TODO/sysdeps/s390/fpu/get-rounding-mode.h
new file mode 100644
index 0000000000..7fffa0a947
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/fpu/get-rounding-mode.h
@@ -0,0 +1,37 @@
+/* Determine floating-point rounding mode within libc. S/390 version.
+ Copyright (C) 2012-2017 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 _S390_GET_ROUNDING_MODE_H
+#define _S390_GET_ROUNDING_MODE_H 1
+
+#include <fenv.h>
+#include <fenv_libc.h>
+#include <fpu_control.h>
+
+/* Return the floating-point rounding mode. */
+
+static inline int
+get_rounding_mode (void)
+{
+ fpu_control_t fc;
+
+ _FPU_GETCW (fc);
+ return fc & FPC_RM_MASK;
+}
+
+#endif /* get-rounding-mode.h */
diff --git a/REORG.TODO/sysdeps/s390/fpu/libm-test-ulps b/REORG.TODO/sysdeps/s390/fpu/libm-test-ulps
new file mode 100644
index 0000000000..dad5205ae7
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/fpu/libm-test-ulps
@@ -0,0 +1,2270 @@
+# Begin of automatic generation
+
+# Maximal error of functions:
+Function: "acos":
+float: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+Function: "acos_downward":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+Function: "acos_towardzero":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+Function: "acos_upward":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+Function: "acosh":
+double: 2
+float: 2
+idouble: 2
+ifloat: 2
+ildouble: 2
+ldouble: 2
+
+Function: "acosh_downward":
+double: 2
+float: 2
+idouble: 2
+ifloat: 2
+ildouble: 3
+ldouble: 3
+
+Function: "acosh_towardzero":
+double: 2
+float: 2
+idouble: 2
+ifloat: 2
+ildouble: 2
+ldouble: 2
+
+Function: "acosh_upward":
+double: 2
+float: 2
+idouble: 2
+ifloat: 2
+ildouble: 2
+ldouble: 2
+
+Function: "asin":
+float: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+Function: "asin_downward":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 2
+ldouble: 2
+
+Function: "asin_towardzero":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+Function: "asin_upward":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 2
+ldouble: 2
+
+Function: "asinh":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 3
+ldouble: 3
+
+Function: "asinh_downward":
+double: 3
+float: 3
+idouble: 3
+ifloat: 3
+ildouble: 4
+ldouble: 4
+
+Function: "asinh_towardzero":
+double: 2
+float: 2
+idouble: 2
+ifloat: 2
+ildouble: 2
+ldouble: 2
+
+Function: "asinh_upward":
+double: 3
+float: 3
+idouble: 3
+ifloat: 3
+ildouble: 4
+ldouble: 4
+
+Function: "atan":
+float: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+Function: "atan2":
+float: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+Function: "atan2_downward":
+double: 1
+float: 2
+idouble: 1
+ifloat: 2
+ildouble: 2
+ldouble: 2
+
+Function: "atan2_towardzero":
+double: 1
+float: 2
+idouble: 1
+ifloat: 2
+ildouble: 3
+ldouble: 3
+
+Function: "atan2_upward":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 2
+ldouble: 2
+
+Function: "atan_downward":
+double: 1
+float: 2
+idouble: 1
+ifloat: 2
+ildouble: 2
+ldouble: 2
+
+Function: "atan_towardzero":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+Function: "atan_upward":
+double: 1
+float: 2
+idouble: 1
+ifloat: 2
+ildouble: 2
+ldouble: 2
+
+Function: "atanh":
+double: 2
+float: 2
+idouble: 2
+ifloat: 2
+ildouble: 3
+ldouble: 3
+
+Function: "atanh_downward":
+double: 3
+float: 3
+idouble: 3
+ifloat: 3
+ildouble: 4
+ldouble: 4
+
+Function: "atanh_towardzero":
+double: 2
+float: 2
+idouble: 2
+ifloat: 2
+ildouble: 2
+ldouble: 2
+
+Function: "atanh_upward":
+double: 3
+float: 3
+idouble: 3
+ifloat: 3
+ildouble: 4
+ldouble: 4
+
+Function: "cabs":
+double: 1
+idouble: 1
+ildouble: 1
+ldouble: 1
+
+Function: "cabs_downward":
+double: 1
+idouble: 1
+ildouble: 1
+ldouble: 1
+
+Function: "cabs_towardzero":
+double: 1
+idouble: 1
+ildouble: 1
+ldouble: 1
+
+Function: "cabs_upward":
+double: 1
+idouble: 1
+ildouble: 1
+ldouble: 1
+
+Function: Real part of "cacos":
+double: 1
+float: 2
+idouble: 1
+ifloat: 2
+ildouble: 2
+ldouble: 2
+
+Function: Imaginary part of "cacos":
+double: 2
+float: 2
+idouble: 2
+ifloat: 2
+ildouble: 2
+ldouble: 2
+
+Function: Real part of "cacos_downward":
+double: 3
+float: 2
+idouble: 3
+ifloat: 2
+ildouble: 3
+ldouble: 3
+
+Function: Imaginary part of "cacos_downward":
+double: 5
+float: 3
+idouble: 5
+ifloat: 3
+ildouble: 6
+ldouble: 6
+
+Function: Real part of "cacos_towardzero":
+double: 3
+float: 2
+idouble: 3
+ifloat: 2
+ildouble: 3
+ldouble: 3
+
+Function: Imaginary part of "cacos_towardzero":
+double: 4
+float: 2
+idouble: 4
+ifloat: 2
+ildouble: 5
+ldouble: 5
+
+Function: Real part of "cacos_upward":
+double: 2
+float: 2
+idouble: 2
+ifloat: 2
+ildouble: 3
+ldouble: 3
+
+Function: Imaginary part of "cacos_upward":
+double: 5
+float: 5
+idouble: 5
+ifloat: 5
+ildouble: 7
+ldouble: 7
+
+Function: Real part of "cacosh":
+double: 2
+float: 2
+idouble: 2
+ifloat: 2
+ildouble: 2
+ldouble: 2
+
+Function: Imaginary part of "cacosh":
+double: 1
+float: 2
+idouble: 1
+ifloat: 2
+ildouble: 2
+ldouble: 2
+
+Function: Real part of "cacosh_downward":
+double: 4
+float: 2
+idouble: 4
+ifloat: 2
+ildouble: 5
+ldouble: 5
+
+Function: Imaginary part of "cacosh_downward":
+double: 3
+float: 3
+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: 3
+float: 2
+idouble: 3
+ifloat: 2
+ildouble: 3
+ldouble: 3
+
+Function: Real part of "cacosh_upward":
+double: 4
+float: 3
+idouble: 4
+ifloat: 3
+ildouble: 6
+ldouble: 6
+
+Function: Imaginary part of "cacosh_upward":
+double: 3
+float: 2
+idouble: 3
+ifloat: 2
+ildouble: 4
+ldouble: 4
+
+Function: "carg":
+float: 1
+ifloat: 1
+ildouble: 2
+ldouble: 2
+
+Function: "carg_downward":
+double: 1
+float: 2
+idouble: 1
+ifloat: 2
+ildouble: 2
+ldouble: 2
+
+Function: "carg_towardzero":
+double: 1
+float: 2
+idouble: 1
+ifloat: 2
+ildouble: 3
+ldouble: 3
+
+Function: "carg_upward":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 2
+ldouble: 2
+
+Function: Real part of "casin":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 2
+ldouble: 2
+
+Function: Imaginary part of "casin":
+double: 2
+float: 2
+idouble: 2
+ifloat: 2
+ildouble: 2
+ldouble: 2
+
+Function: Real part of "casin_downward":
+double: 3
+float: 2
+idouble: 3
+ifloat: 2
+ildouble: 3
+ldouble: 3
+
+Function: Imaginary part of "casin_downward":
+double: 5
+float: 3
+idouble: 5
+ifloat: 3
+ildouble: 6
+ldouble: 6
+
+Function: Real part of "casin_towardzero":
+double: 3
+float: 1
+idouble: 3
+ifloat: 1
+ildouble: 3
+ldouble: 3
+
+Function: Imaginary part of "casin_towardzero":
+double: 4
+float: 2
+idouble: 4
+ifloat: 2
+ildouble: 5
+ldouble: 5
+
+Function: Real part of "casin_upward":
+double: 3
+float: 2
+idouble: 3
+ifloat: 2
+ildouble: 3
+ldouble: 3
+
+Function: Imaginary part of "casin_upward":
+double: 5
+float: 5
+idouble: 5
+ifloat: 5
+ildouble: 7
+ldouble: 7
+
+Function: Real part of "casinh":
+double: 2
+float: 2
+idouble: 2
+ifloat: 2
+ildouble: 2
+ldouble: 2
+
+Function: Imaginary part of "casinh":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 2
+ldouble: 2
+
+Function: Real part of "casinh_downward":
+double: 5
+float: 3
+idouble: 5
+ifloat: 3
+ildouble: 6
+ldouble: 6
+
+Function: Imaginary part of "casinh_downward":
+double: 3
+float: 2
+idouble: 3
+ifloat: 2
+ildouble: 3
+ldouble: 3
+
+Function: Real part of "casinh_towardzero":
+double: 4
+float: 2
+idouble: 4
+ifloat: 2
+ildouble: 5
+ldouble: 5
+
+Function: Imaginary part of "casinh_towardzero":
+double: 3
+float: 1
+idouble: 3
+ifloat: 1
+ildouble: 3
+ldouble: 3
+
+Function: Real part of "casinh_upward":
+double: 5
+float: 5
+idouble: 5
+ifloat: 5
+ildouble: 7
+ldouble: 7
+
+Function: Imaginary part of "casinh_upward":
+double: 3
+float: 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
+
+Function: Imaginary part of "catan":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+Function: Real part of "catan_downward":
+double: 1
+float: 2
+idouble: 1
+ifloat: 2
+ildouble: 2
+ldouble: 2
+
+Function: Imaginary part of "catan_downward":
+double: 2
+float: 2
+idouble: 2
+ifloat: 2
+ildouble: 2
+ldouble: 2
+
+Function: Real part of "catan_towardzero":
+double: 1
+float: 2
+idouble: 1
+ifloat: 2
+ildouble: 2
+ldouble: 2
+
+Function: Imaginary part of "catan_towardzero":
+double: 2
+float: 2
+idouble: 2
+ifloat: 2
+ildouble: 2
+ldouble: 2
+
+Function: Real part of "catan_upward":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 2
+ldouble: 2
+
+Function: Imaginary part of "catan_upward":
+double: 2
+float: 2
+idouble: 2
+ifloat: 2
+ildouble: 3
+ldouble: 3
+
+Function: Real part of "catanh":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+Function: Imaginary part of "catanh":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+Function: Real part of "catanh_downward":
+double: 2
+float: 2
+idouble: 2
+ifloat: 2
+ildouble: 2
+ldouble: 2
+
+Function: Imaginary part of "catanh_downward":
+double: 1
+float: 2
+idouble: 1
+ifloat: 2
+ildouble: 2
+ldouble: 2
+
+Function: Real part of "catanh_towardzero":
+double: 2
+float: 2
+idouble: 2
+ifloat: 2
+ildouble: 2
+ldouble: 2
+
+Function: Imaginary part of "catanh_towardzero":
+double: 1
+float: 2
+idouble: 1
+ifloat: 2
+ildouble: 2
+ldouble: 2
+
+Function: Real part of "catanh_upward":
+double: 4
+float: 4
+idouble: 4
+ifloat: 4
+ildouble: 4
+ldouble: 4
+
+Function: Imaginary part of "catanh_upward":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 2
+ldouble: 2
+
+Function: "cbrt":
+double: 3
+float: 1
+idouble: 3
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+Function: "cbrt_downward":
+double: 4
+float: 1
+idouble: 4
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+Function: "cbrt_towardzero":
+double: 3
+float: 1
+idouble: 3
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+Function: "cbrt_upward":
+double: 5
+float: 1
+idouble: 5
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+Function: Real part of "ccos":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+Function: Imaginary part of "ccos":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+Function: Real part of "ccos_downward":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 2
+ldouble: 2
+
+Function: Imaginary part of "ccos_downward":
+double: 2
+float: 3
+idouble: 2
+ifloat: 3
+ildouble: 2
+ldouble: 2
+
+Function: Real part of "ccos_towardzero":
+double: 1
+float: 2
+idouble: 1
+ifloat: 2
+ildouble: 2
+ldouble: 2
+
+Function: Imaginary part of "ccos_towardzero":
+double: 2
+float: 3
+idouble: 2
+ifloat: 3
+ildouble: 2
+ldouble: 2
+
+Function: Real part of "ccos_upward":
+double: 1
+float: 2
+idouble: 1
+ifloat: 2
+ildouble: 3
+ldouble: 3
+
+Function: Imaginary part of "ccos_upward":
+double: 2
+float: 2
+idouble: 2
+ifloat: 2
+ildouble: 2
+ldouble: 2
+
+Function: Real part of "ccosh":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+Function: Imaginary part of "ccosh":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+Function: Real part of "ccosh_downward":
+double: 1
+float: 3
+idouble: 1
+ifloat: 3
+ildouble: 2
+ldouble: 2
+
+Function: Imaginary part of "ccosh_downward":
+double: 2
+float: 3
+idouble: 2
+ifloat: 3
+ildouble: 2
+ldouble: 2
+
+Function: Real part of "ccosh_towardzero":
+double: 1
+float: 3
+idouble: 1
+ifloat: 3
+ildouble: 2
+ldouble: 2
+
+Function: Imaginary part of "ccosh_towardzero":
+double: 2
+float: 3
+idouble: 2
+ifloat: 3
+ildouble: 2
+ldouble: 2
+
+Function: Real part of "ccosh_upward":
+double: 1
+float: 2
+idouble: 1
+ifloat: 2
+ildouble: 3
+ldouble: 3
+
+Function: Imaginary part of "ccosh_upward":
+double: 2
+float: 2
+idouble: 2
+ifloat: 2
+ildouble: 2
+ldouble: 2
+
+Function: Real part of "cexp":
+double: 2
+float: 1
+idouble: 2
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+Function: Imaginary part of "cexp":
+double: 1
+float: 2
+idouble: 1
+ifloat: 2
+ildouble: 1
+ldouble: 1
+
+Function: Real part of "cexp_downward":
+double: 1
+float: 2
+idouble: 1
+ifloat: 2
+ildouble: 2
+ldouble: 2
+
+Function: Imaginary part of "cexp_downward":
+double: 1
+float: 3
+idouble: 1
+ifloat: 3
+ildouble: 2
+ldouble: 2
+
+Function: Real part of "cexp_towardzero":
+double: 1
+float: 2
+idouble: 1
+ifloat: 2
+ildouble: 2
+ldouble: 2
+
+Function: Imaginary part of "cexp_towardzero":
+double: 1
+float: 3
+idouble: 1
+ifloat: 3
+ildouble: 2
+ldouble: 2
+
+Function: Real part of "cexp_upward":
+double: 1
+float: 2
+idouble: 1
+ifloat: 2
+ildouble: 3
+ldouble: 3
+
+Function: Imaginary part of "cexp_upward":
+double: 1
+float: 2
+idouble: 1
+ifloat: 2
+ildouble: 3
+ldouble: 3
+
+Function: Real part of "clog":
+double: 3
+float: 3
+idouble: 3
+ifloat: 3
+ildouble: 2
+ldouble: 2
+
+Function: Imaginary part of "clog":
+float: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+Function: Real part of "clog10":
+double: 3
+float: 4
+idouble: 3
+ifloat: 4
+ildouble: 2
+ldouble: 2
+
+Function: Imaginary part of "clog10":
+double: 2
+float: 2
+idouble: 2
+ifloat: 2
+ildouble: 2
+ldouble: 2
+
+Function: Real part of "clog10_downward":
+double: 5
+float: 4
+idouble: 5
+ifloat: 4
+ildouble: 3
+ldouble: 3
+
+Function: Imaginary part of "clog10_downward":
+double: 2
+float: 4
+idouble: 2
+ifloat: 4
+ildouble: 3
+ldouble: 3
+
+Function: Real part of "clog10_towardzero":
+double: 5
+float: 5
+idouble: 5
+ifloat: 5
+ildouble: 4
+ldouble: 4
+
+Function: Imaginary part of "clog10_towardzero":
+double: 2
+float: 4
+idouble: 2
+ifloat: 4
+ildouble: 3
+ldouble: 3
+
+Function: Real part of "clog10_upward":
+double: 6
+float: 5
+idouble: 6
+ifloat: 5
+ildouble: 4
+ldouble: 4
+
+Function: Imaginary part of "clog10_upward":
+double: 2
+float: 4
+idouble: 2
+ifloat: 4
+ildouble: 3
+ldouble: 3
+
+Function: Real part of "clog_downward":
+double: 4
+float: 3
+idouble: 4
+ifloat: 3
+ildouble: 3
+ldouble: 3
+
+Function: Imaginary part of "clog_downward":
+double: 1
+float: 2
+idouble: 1
+ifloat: 2
+ildouble: 2
+ldouble: 2
+
+Function: Real part of "clog_towardzero":
+double: 4
+float: 4
+idouble: 4
+ifloat: 4
+ildouble: 3
+ldouble: 3
+
+Function: Imaginary part of "clog_towardzero":
+double: 1
+float: 3
+idouble: 1
+ifloat: 3
+ildouble: 2
+ldouble: 2
+
+Function: Real part of "clog_upward":
+double: 4
+float: 3
+idouble: 4
+ifloat: 3
+ildouble: 4
+ldouble: 4
+
+Function: Imaginary part of "clog_upward":
+double: 1
+float: 2
+idouble: 1
+ifloat: 2
+ildouble: 2
+ldouble: 2
+
+Function: "cos":
+float: 1
+ifloat: 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
+
+Function: "cosh":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+Function: "cosh_downward":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 2
+
+Function: "cosh_towardzero":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 2
+
+Function: "cosh_upward":
+double: 1
+float: 2
+idouble: 1
+ifloat: 2
+ildouble: 1
+ldouble: 3
+
+Function: Real part of "cpow":
+double: 2
+float: 5
+idouble: 2
+ifloat: 5
+ildouble: 4
+ldouble: 4
+
+Function: Imaginary part of "cpow":
+float: 2
+ifloat: 2
+ildouble: 1
+ldouble: 1
+
+Function: Real part of "cpow_downward":
+double: 4
+float: 8
+idouble: 4
+ifloat: 8
+ildouble: 6
+ldouble: 6
+
+Function: Imaginary part of "cpow_downward":
+double: 1
+float: 2
+idouble: 1
+ifloat: 2
+ildouble: 2
+ldouble: 2
+
+Function: Real part of "cpow_towardzero":
+double: 4
+float: 8
+idouble: 4
+ifloat: 8
+ildouble: 6
+ldouble: 6
+
+Function: Imaginary part of "cpow_towardzero":
+double: 1
+float: 2
+idouble: 1
+ifloat: 2
+ildouble: 2
+ldouble: 2
+
+Function: Real part of "cpow_upward":
+double: 4
+float: 1
+idouble: 4
+ifloat: 1
+ildouble: 3
+ldouble: 3
+
+Function: Imaginary part of "cpow_upward":
+double: 1
+float: 2
+idouble: 1
+ifloat: 2
+ildouble: 2
+ldouble: 2
+
+Function: Real part of "csin":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+Function: Imaginary part of "csin":
+ildouble: 1
+ldouble: 1
+
+Function: Real part of "csin_downward":
+double: 2
+float: 3
+idouble: 2
+ifloat: 3
+ildouble: 2
+ldouble: 2
+
+Function: Imaginary part of "csin_downward":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 2
+ldouble: 2
+
+Function: Real part of "csin_towardzero":
+double: 2
+float: 3
+idouble: 2
+ifloat: 3
+ildouble: 2
+ldouble: 2
+
+Function: Imaginary part of "csin_towardzero":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 2
+ldouble: 2
+
+Function: Real part of "csin_upward":
+double: 2
+float: 2
+idouble: 2
+ifloat: 2
+ildouble: 2
+ldouble: 2
+
+Function: Imaginary part of "csin_upward":
+double: 1
+float: 2
+idouble: 1
+ifloat: 2
+ildouble: 3
+ldouble: 3
+
+Function: Real part of "csinh":
+float: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+Function: Imaginary part of "csinh":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+Function: Real part of "csinh_downward":
+double: 2
+float: 2
+idouble: 2
+ifloat: 2
+ildouble: 2
+ldouble: 2
+
+Function: Imaginary part of "csinh_downward":
+double: 2
+float: 3
+idouble: 2
+ifloat: 3
+ildouble: 2
+ldouble: 2
+
+Function: Real part of "csinh_towardzero":
+double: 2
+float: 2
+idouble: 2
+ifloat: 2
+ildouble: 2
+ldouble: 2
+
+Function: Imaginary part of "csinh_towardzero":
+double: 2
+float: 3
+idouble: 2
+ifloat: 3
+ildouble: 2
+ldouble: 2
+
+Function: Real part of "csinh_upward":
+double: 1
+float: 2
+idouble: 1
+ifloat: 2
+ildouble: 3
+ldouble: 3
+
+Function: Imaginary part of "csinh_upward":
+double: 2
+float: 2
+idouble: 2
+ifloat: 2
+ildouble: 2
+ldouble: 2
+
+Function: Real part of "csqrt":
+double: 2
+float: 2
+idouble: 2
+ifloat: 2
+ildouble: 2
+ldouble: 2
+
+Function: Imaginary part of "csqrt":
+double: 2
+float: 2
+idouble: 2
+ifloat: 2
+ildouble: 2
+ldouble: 2
+
+Function: Real part of "csqrt_downward":
+double: 5
+float: 4
+idouble: 5
+ifloat: 4
+ildouble: 4
+ldouble: 4
+
+Function: Imaginary part of "csqrt_downward":
+double: 4
+float: 3
+idouble: 4
+ifloat: 3
+ildouble: 3
+ldouble: 3
+
+Function: Real part of "csqrt_towardzero":
+double: 4
+float: 3
+idouble: 4
+ifloat: 3
+ildouble: 3
+ldouble: 3
+
+Function: Imaginary part of "csqrt_towardzero":
+double: 4
+float: 3
+idouble: 4
+ifloat: 3
+ildouble: 3
+ldouble: 3
+
+Function: Real part of "csqrt_upward":
+double: 5
+float: 4
+idouble: 5
+ifloat: 4
+ildouble: 4
+ldouble: 4
+
+Function: Imaginary part of "csqrt_upward":
+double: 3
+float: 3
+idouble: 3
+ifloat: 3
+ildouble: 3
+ldouble: 3
+
+Function: Real part of "ctan":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 3
+ldouble: 3
+
+Function: Imaginary part of "ctan":
+double: 2
+float: 1
+idouble: 2
+ifloat: 1
+ildouble: 3
+ldouble: 3
+
+Function: Real part of "ctan_downward":
+double: 6
+float: 5
+idouble: 6
+ifloat: 5
+ildouble: 4
+ldouble: 4
+
+Function: Imaginary part of "ctan_downward":
+double: 2
+float: 1
+idouble: 2
+ifloat: 1
+ildouble: 5
+ldouble: 5
+
+Function: Real part of "ctan_towardzero":
+double: 5
+float: 3
+idouble: 5
+ifloat: 3
+ildouble: 4
+ldouble: 4
+
+Function: Imaginary part of "ctan_towardzero":
+double: 2
+float: 2
+idouble: 2
+ifloat: 2
+ildouble: 5
+ldouble: 5
+
+Function: Real part of "ctan_upward":
+double: 2
+float: 3
+idouble: 2
+ifloat: 3
+ildouble: 5
+ldouble: 5
+
+Function: Imaginary part of "ctan_upward":
+double: 2
+float: 3
+idouble: 2
+ifloat: 3
+ildouble: 5
+ldouble: 5
+
+Function: Real part of "ctanh":
+double: 2
+float: 2
+idouble: 2
+ifloat: 2
+ildouble: 3
+ldouble: 3
+
+Function: Imaginary part of "ctanh":
+double: 2
+float: 1
+idouble: 2
+ifloat: 1
+ildouble: 3
+ldouble: 3
+
+Function: Real part of "ctanh_downward":
+double: 4
+float: 1
+idouble: 4
+ifloat: 1
+ildouble: 5
+ldouble: 5
+
+Function: Imaginary part of "ctanh_downward":
+double: 6
+float: 5
+idouble: 6
+ifloat: 5
+ildouble: 4
+ldouble: 4
+
+Function: Real part of "ctanh_towardzero":
+double: 2
+float: 2
+idouble: 2
+ifloat: 2
+ildouble: 5
+ldouble: 5
+
+Function: Imaginary part of "ctanh_towardzero":
+double: 5
+float: 2
+idouble: 5
+ifloat: 2
+ildouble: 3
+ldouble: 3
+
+Function: Real part of "ctanh_upward":
+double: 2
+float: 3
+idouble: 2
+ifloat: 3
+ildouble: 5
+ldouble: 5
+
+Function: Imaginary part of "ctanh_upward":
+double: 2
+float: 3
+idouble: 2
+ifloat: 3
+ildouble: 5
+ldouble: 5
+
+Function: "erf":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+Function: "erf_downward":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 2
+ldouble: 2
+
+Function: "erf_towardzero":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+Function: "erf_upward":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 2
+ldouble: 2
+
+Function: "erfc":
+double: 2
+float: 2
+idouble: 2
+ifloat: 2
+ildouble: 2
+ldouble: 2
+
+Function: "erfc_downward":
+double: 3
+float: 4
+idouble: 3
+ifloat: 4
+ildouble: 5
+ldouble: 5
+
+Function: "erfc_towardzero":
+double: 3
+float: 3
+idouble: 3
+ifloat: 3
+ildouble: 4
+ldouble: 4
+
+Function: "erfc_upward":
+double: 3
+float: 4
+idouble: 3
+ifloat: 4
+ildouble: 5
+ldouble: 5
+
+Function: "exp":
+float: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+Function: "exp10":
+double: 2
+idouble: 2
+ildouble: 2
+ldouble: 2
+
+Function: "exp10_downward":
+double: 2
+float: 1
+idouble: 2
+ifloat: 1
+ildouble: 3
+ldouble: 3
+
+Function: "exp10_towardzero":
+double: 2
+float: 1
+idouble: 2
+ifloat: 1
+ildouble: 3
+ldouble: 3
+
+Function: "exp10_upward":
+double: 2
+float: 1
+idouble: 2
+ifloat: 1
+ildouble: 3
+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
+
+Function: "exp2_upward":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 2
+ldouble: 2
+
+Function: "exp_downward":
+double: 1
+idouble: 1
+
+Function: "exp_towardzero":
+double: 1
+idouble: 1
+
+Function: "exp_upward":
+double: 1
+idouble: 1
+
+Function: "expm1":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+Function: "expm1_downward":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 2
+ldouble: 2
+
+Function: "expm1_towardzero":
+double: 1
+float: 2
+idouble: 1
+ifloat: 2
+ildouble: 4
+ldouble: 4
+
+Function: "expm1_upward":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 3
+ldouble: 3
+
+Function: "gamma":
+double: 3
+float: 4
+idouble: 3
+ifloat: 4
+ildouble: 5
+ldouble: 5
+
+Function: "gamma_downward":
+double: 4
+float: 4
+idouble: 4
+ifloat: 4
+ildouble: 8
+ldouble: 8
+
+Function: "gamma_towardzero":
+double: 4
+float: 3
+idouble: 4
+ifloat: 3
+ildouble: 5
+ldouble: 5
+
+Function: "gamma_upward":
+double: 4
+float: 5
+idouble: 4
+ifloat: 5
+ildouble: 8
+ldouble: 8
+
+Function: "hypot":
+double: 1
+idouble: 1
+ildouble: 1
+ldouble: 1
+
+Function: "hypot_downward":
+double: 1
+idouble: 1
+ildouble: 1
+ldouble: 1
+
+Function: "hypot_towardzero":
+double: 1
+idouble: 1
+ildouble: 1
+ldouble: 1
+
+Function: "hypot_upward":
+double: 1
+idouble: 1
+ildouble: 1
+ldouble: 1
+
+Function: "j0":
+double: 2
+float: 2
+idouble: 2
+ifloat: 2
+ildouble: 2
+ldouble: 2
+
+Function: "j0_downward":
+double: 2
+float: 3
+idouble: 2
+ifloat: 3
+ildouble: 4
+ldouble: 4
+
+Function: "j0_towardzero":
+double: 2
+float: 1
+idouble: 2
+ifloat: 1
+ildouble: 2
+ldouble: 2
+
+Function: "j0_upward":
+double: 3
+float: 2
+idouble: 3
+ifloat: 2
+ildouble: 5
+ldouble: 5
+
+Function: "j1":
+double: 1
+float: 2
+idouble: 1
+ifloat: 2
+ildouble: 4
+ldouble: 4
+
+Function: "j1_downward":
+double: 3
+float: 2
+idouble: 3
+ifloat: 2
+ildouble: 4
+ldouble: 4
+
+Function: "j1_towardzero":
+double: 3
+float: 2
+idouble: 3
+ifloat: 2
+ildouble: 4
+ldouble: 4
+
+Function: "j1_upward":
+double: 3
+float: 4
+idouble: 3
+ifloat: 4
+ildouble: 3
+ldouble: 3
+
+Function: "jn":
+double: 4
+float: 4
+idouble: 4
+ifloat: 4
+ildouble: 7
+ldouble: 7
+
+Function: "jn_downward":
+double: 4
+float: 5
+idouble: 4
+ifloat: 5
+ildouble: 8
+ldouble: 8
+
+Function: "jn_towardzero":
+double: 4
+float: 5
+idouble: 4
+ifloat: 5
+ildouble: 8
+ldouble: 8
+
+Function: "jn_upward":
+double: 5
+float: 4
+idouble: 5
+ifloat: 4
+ildouble: 7
+ldouble: 7
+
+Function: "lgamma":
+double: 3
+float: 4
+idouble: 3
+ifloat: 4
+ildouble: 5
+ldouble: 5
+
+Function: "lgamma_downward":
+double: 4
+float: 4
+idouble: 4
+ifloat: 4
+ildouble: 8
+ldouble: 8
+
+Function: "lgamma_towardzero":
+double: 4
+float: 3
+idouble: 4
+ifloat: 3
+ildouble: 5
+ldouble: 5
+
+Function: "lgamma_upward":
+double: 4
+float: 5
+idouble: 4
+ifloat: 5
+ildouble: 8
+ldouble: 8
+
+Function: "log":
+float: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+Function: "log10":
+double: 2
+float: 2
+idouble: 2
+ifloat: 2
+ildouble: 1
+ldouble: 1
+
+Function: "log10_downward":
+double: 2
+float: 3
+idouble: 2
+ifloat: 3
+ildouble: 1
+ldouble: 1
+
+Function: "log10_towardzero":
+double: 2
+float: 2
+idouble: 2
+ifloat: 2
+ildouble: 1
+ldouble: 1
+
+Function: "log10_upward":
+double: 2
+float: 2
+idouble: 2
+ifloat: 2
+ildouble: 1
+ldouble: 1
+
+Function: "log1p":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 2
+ldouble: 2
+
+Function: "log1p_downward":
+double: 1
+float: 2
+idouble: 1
+ifloat: 2
+ildouble: 3
+ldouble: 3
+
+Function: "log1p_towardzero":
+double: 2
+float: 2
+idouble: 2
+ifloat: 2
+ildouble: 3
+ldouble: 3
+
+Function: "log1p_upward":
+double: 2
+float: 2
+idouble: 2
+ifloat: 2
+ildouble: 2
+ldouble: 2
+
+Function: "log2":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 2
+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: 2
+ifloat: 2
+ildouble: 2
+ldouble: 2
+
+Function: "log_upward":
+double: 1
+float: 2
+idouble: 1
+ifloat: 2
+ildouble: 1
+ldouble: 1
+
+Function: "pow":
+float: 1
+ifloat: 1
+ildouble: 2
+ldouble: 2
+
+Function: "pow10":
+double: 2
+idouble: 2
+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
+idouble: 1
+ifloat: 1
+ildouble: 2
+ldouble: 2
+
+Function: "pow_towardzero":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 2
+ldouble: 2
+
+Function: "pow_upward":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 2
+ldouble: 2
+
+Function: "sin":
+float: 1
+ifloat: 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
+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
+
+Function: "sinh":
+double: 2
+float: 2
+idouble: 2
+ifloat: 2
+ildouble: 2
+ldouble: 2
+
+Function: "sinh_downward":
+double: 3
+float: 3
+idouble: 3
+ifloat: 3
+ildouble: 3
+ldouble: 3
+
+Function: "sinh_towardzero":
+double: 2
+float: 2
+idouble: 2
+ifloat: 2
+ildouble: 3
+ldouble: 3
+
+Function: "sinh_upward":
+double: 3
+float: 3
+idouble: 3
+ifloat: 3
+ildouble: 4
+ldouble: 4
+
+Function: "tan":
+float: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+Function: "tan_downward":
+double: 1
+float: 2
+idouble: 1
+ifloat: 2
+ildouble: 1
+ldouble: 1
+
+Function: "tan_towardzero":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+Function: "tan_upward":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+Function: "tanh":
+double: 2
+float: 2
+idouble: 2
+ifloat: 2
+ildouble: 2
+ldouble: 2
+
+Function: "tanh_downward":
+double: 3
+float: 3
+idouble: 3
+ifloat: 3
+ildouble: 4
+ldouble: 4
+
+Function: "tanh_towardzero":
+double: 2
+float: 2
+idouble: 2
+ifloat: 2
+ildouble: 3
+ldouble: 3
+
+Function: "tanh_upward":
+double: 3
+float: 3
+idouble: 3
+ifloat: 3
+ildouble: 3
+ldouble: 3
+
+Function: "tgamma":
+double: 5
+float: 4
+idouble: 5
+ifloat: 4
+ildouble: 4
+ldouble: 4
+
+Function: "tgamma_downward":
+double: 5
+float: 5
+idouble: 5
+ifloat: 5
+ildouble: 5
+ldouble: 5
+
+Function: "tgamma_towardzero":
+double: 5
+float: 4
+idouble: 5
+ifloat: 4
+ildouble: 5
+ldouble: 5
+
+Function: "tgamma_upward":
+double: 4
+float: 4
+idouble: 4
+ifloat: 4
+ildouble: 4
+ldouble: 4
+
+Function: "y0":
+double: 2
+float: 1
+idouble: 2
+ifloat: 1
+ildouble: 3
+ldouble: 3
+
+Function: "y0_downward":
+double: 3
+float: 2
+idouble: 3
+ifloat: 2
+ildouble: 4
+ldouble: 4
+
+Function: "y0_towardzero":
+double: 3
+float: 3
+idouble: 3
+ifloat: 3
+ildouble: 3
+ldouble: 3
+
+Function: "y0_upward":
+double: 2
+float: 3
+idouble: 2
+ifloat: 3
+ildouble: 3
+ldouble: 3
+
+Function: "y1":
+double: 3
+float: 2
+idouble: 3
+ifloat: 2
+ildouble: 2
+ldouble: 2
+
+Function: "y1_downward":
+double: 3
+float: 2
+idouble: 3
+ifloat: 2
+ildouble: 4
+ldouble: 4
+
+Function: "y1_towardzero":
+double: 3
+float: 2
+idouble: 3
+ifloat: 2
+ildouble: 2
+ldouble: 2
+
+Function: "y1_upward":
+double: 5
+float: 2
+idouble: 5
+ifloat: 2
+ildouble: 5
+ldouble: 5
+
+Function: "yn":
+double: 3
+float: 2
+idouble: 3
+ifloat: 2
+ildouble: 5
+ldouble: 5
+
+Function: "yn_downward":
+double: 3
+float: 2
+idouble: 3
+ifloat: 2
+ildouble: 5
+ldouble: 5
+
+Function: "yn_towardzero":
+double: 3
+float: 3
+idouble: 3
+ifloat: 3
+ildouble: 5
+ldouble: 5
+
+Function: "yn_upward":
+double: 4
+float: 3
+idouble: 4
+ifloat: 3
+ildouble: 5
+ldouble: 5
+
+# end of automatic generation
diff --git a/REORG.TODO/sysdeps/s390/fpu/libm-test-ulps-name b/REORG.TODO/sysdeps/s390/fpu/libm-test-ulps-name
new file mode 100644
index 0000000000..4a55100a0e
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/fpu/libm-test-ulps-name
@@ -0,0 +1 @@
+S/390
diff --git a/REORG.TODO/sysdeps/s390/fpu/s_fma.c b/REORG.TODO/sysdeps/s390/fpu/s_fma.c
new file mode 100644
index 0000000000..fb7210b19a
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/fpu/s_fma.c
@@ -0,0 +1,36 @@
+/* Compute x * y + z as ternary operation. S/390 version.
+ Copyright (C) 2010-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Jakub Jelinek <jakub@redhat.com>, 2010.
+
+ 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 <math.h>
+
+double
+__fma (double x, double y, double z)
+{
+ double r;
+ __asm__ ("madbr %0,%1,%2" : "=f" (r) : "%f" (x), "fR" (y), "0" (z));
+ return r;
+}
+#ifndef __fma
+weak_alias (__fma, fma)
+#endif
+
+#ifdef NO_LONG_DOUBLE
+strong_alias (__fma, __fmal)
+weak_alias (__fmal, fmal)
+#endif
diff --git a/REORG.TODO/sysdeps/s390/fpu/s_fmaf.c b/REORG.TODO/sysdeps/s390/fpu/s_fmaf.c
new file mode 100644
index 0000000000..c56cc040e8
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/fpu/s_fmaf.c
@@ -0,0 +1,31 @@
+/* Compute x * y + z as ternary operation. S/390 version.
+ Copyright (C) 2010-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Jakub Jelinek <jakub@redhat.com>, 2010.
+
+ 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 <math.h>
+
+float
+__fmaf (float x, float y, float z)
+{
+ float r;
+ __asm__ ("maebr %0,%1,%2" : "=f" (r) : "%f" (x), "fR" (y), "0" (z));
+ return r;
+}
+#ifndef __fmaf
+weak_alias (__fmaf, fmaf)
+#endif
diff --git a/REORG.TODO/sysdeps/s390/gccframe.h b/REORG.TODO/sysdeps/s390/gccframe.h
new file mode 100644
index 0000000000..2a8b92fdeb
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/gccframe.h
@@ -0,0 +1,21 @@
+/* Definition of object in frame unwind info. s390 version.
+ Copyright (C) 2001-2017 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/>. */
+
+#define FIRST_PSEUDO_REGISTER 34
+
+#include <sysdeps/generic/gccframe.h>
diff --git a/REORG.TODO/sysdeps/s390/gconv-modules b/REORG.TODO/sysdeps/s390/gconv-modules
new file mode 100644
index 0000000000..16ab030626
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/gconv-modules
@@ -0,0 +1,50 @@
+# GNU libc iconv configuration.
+# Copyright (C) 1997-2017 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/REORG.TODO/sysdeps/s390/gmp-mparam.h b/REORG.TODO/sysdeps/s390/gmp-mparam.h
new file mode 100644
index 0000000000..ec0139ade8
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/gmp-mparam.h
@@ -0,0 +1,30 @@
+/* gmp-mparam.h -- Compiler/machine parameter header file.
+ Copyright (C) 2000-2017 Free Software Foundation, Inc.
+ Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com).
+
+ This file is part of the GNU MP Library.
+
+ The GNU MP 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 MP 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; see the file COPYING.LIB. If
+ not, see <http://www.gnu.org/licenses/>. */
+
+#include <bits/wordsize.h>
+
+#define BITS_PER_MP_LIMB __WORDSIZE
+#define BYTES_PER_MP_LIMB (__WORDSIZE / 8)
+#define BITS_PER_LONGINT __WORDSIZE
+#define BITS_PER_INT 32
+#define BITS_PER_SHORTINT 16
+#define BITS_PER_CHAR 8
+
+#define IEEE_DOUBLE_BIG_ENDIAN 0
diff --git a/REORG.TODO/sysdeps/s390/iso-8859-1_cp037_z900.c b/REORG.TODO/sysdeps/s390/iso-8859-1_cp037_z900.c
new file mode 100644
index 0000000000..f4a5b14fd7
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/iso-8859-1_cp037_z900.c
@@ -0,0 +1,262 @@
+/* Conversion between ISO 8859-1 and IBM037.
+
+ This module uses the translate instruction.
+ Copyright (C) 1997-2017 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>
+
+// conversion table from ISO-8859-1 to IBM037
+static const unsigned char table_iso8859_1_to_cp037[256]
+__attribute__ ((aligned (8))) =
+{
+ [0x00] = 0x00, [0x01] = 0x01, [0x02] = 0x02, [0x03] = 0x03,
+ [0x04] = 0x37, [0x05] = 0x2D, [0x06] = 0x2E, [0x07] = 0x2F,
+ [0x08] = 0x16, [0x09] = 0x05, [0x0A] = 0x25, [0x0B] = 0x0B,
+ [0x0C] = 0x0C, [0x0D] = 0x0D, [0x0E] = 0x0E, [0x0F] = 0x0F,
+ [0x10] = 0x10, [0x11] = 0x11, [0x12] = 0x12, [0x13] = 0x13,
+ [0x14] = 0x3C, [0x15] = 0x3D, [0x16] = 0x32, [0x17] = 0x26,
+ [0x18] = 0x18, [0x19] = 0x19, [0x1A] = 0x3F, [0x1B] = 0x27,
+ [0x1C] = 0x1C, [0x1D] = 0x1D, [0x1E] = 0x1E, [0x1F] = 0x1F,
+ [0x20] = 0x40, [0x21] = 0x5A, [0x22] = 0x7F, [0x23] = 0x7B,
+ [0x24] = 0x5B, [0x25] = 0x6C, [0x26] = 0x50, [0x27] = 0x7D,
+ [0x28] = 0x4D, [0x29] = 0x5D, [0x2A] = 0x5C, [0x2B] = 0x4E,
+ [0x2C] = 0x6B, [0x2D] = 0x60, [0x2E] = 0x4B, [0x2F] = 0x61,
+ [0x30] = 0xF0, [0x31] = 0xF1, [0x32] = 0xF2, [0x33] = 0xF3,
+ [0x34] = 0xF4, [0x35] = 0xF5, [0x36] = 0xF6, [0x37] = 0xF7,
+ [0x38] = 0xF8, [0x39] = 0xF9, [0x3A] = 0x7A, [0x3B] = 0x5E,
+ [0x3C] = 0x4C, [0x3D] = 0x7E, [0x3E] = 0x6E, [0x3F] = 0x6F,
+ [0x40] = 0x7C, [0x41] = 0xC1, [0x42] = 0xC2, [0x43] = 0xC3,
+ [0x44] = 0xC4, [0x45] = 0xC5, [0x46] = 0xC6, [0x47] = 0xC7,
+ [0x48] = 0xC8, [0x49] = 0xC9, [0x4A] = 0xD1, [0x4B] = 0xD2,
+ [0x4C] = 0xD3, [0x4D] = 0xD4, [0x4E] = 0xD5, [0x4F] = 0xD6,
+ [0x50] = 0xD7, [0x51] = 0xD8, [0x52] = 0xD9, [0x53] = 0xE2,
+ [0x54] = 0xE3, [0x55] = 0xE4, [0x56] = 0xE5, [0x57] = 0xE6,
+ [0x58] = 0xE7, [0x59] = 0xE8, [0x5A] = 0xE9, [0x5B] = 0xBA,
+ [0x5C] = 0xE0, [0x5D] = 0xBB, [0x5E] = 0xB0, [0x5F] = 0x6D,
+ [0x60] = 0x79, [0x61] = 0x81, [0x62] = 0x82, [0x63] = 0x83,
+ [0x64] = 0x84, [0x65] = 0x85, [0x66] = 0x86, [0x67] = 0x87,
+ [0x68] = 0x88, [0x69] = 0x89, [0x6A] = 0x91, [0x6B] = 0x92,
+ [0x6C] = 0x93, [0x6D] = 0x94, [0x6E] = 0x95, [0x6F] = 0x96,
+ [0x70] = 0x97, [0x71] = 0x98, [0x72] = 0x99, [0x73] = 0xA2,
+ [0x74] = 0xA3, [0x75] = 0xA4, [0x76] = 0xA5, [0x77] = 0xA6,
+ [0x78] = 0xA7, [0x79] = 0xA8, [0x7A] = 0xA9, [0x7B] = 0xC0,
+ [0x7C] = 0x4F, [0x7D] = 0xD0, [0x7E] = 0xA1, [0x7F] = 0x07,
+ [0x80] = 0x20, [0x81] = 0x21, [0x82] = 0x22, [0x83] = 0x23,
+ [0x84] = 0x24, [0x85] = 0x15, [0x86] = 0x06, [0x87] = 0x17,
+ [0x88] = 0x28, [0x89] = 0x29, [0x8A] = 0x2A, [0x8B] = 0x2B,
+ [0x8C] = 0x2C, [0x8D] = 0x09, [0x8E] = 0x0A, [0x8F] = 0x1B,
+ [0x90] = 0x30, [0x91] = 0x31, [0x92] = 0x1A, [0x93] = 0x33,
+ [0x94] = 0x34, [0x95] = 0x35, [0x96] = 0x36, [0x97] = 0x08,
+ [0x98] = 0x38, [0x99] = 0x39, [0x9A] = 0x3A, [0x9B] = 0x3B,
+ [0x9C] = 0x04, [0x9D] = 0x14, [0x9E] = 0x3E, [0x9F] = 0xFF,
+ [0xA0] = 0x41, [0xA1] = 0xAA, [0xA2] = 0x4A, [0xA3] = 0xB1,
+ [0xA4] = 0x9F, [0xA5] = 0xB2, [0xA6] = 0x6A, [0xA7] = 0xB5,
+ [0xA8] = 0xBD, [0xA9] = 0xB4, [0xAA] = 0x9A, [0xAB] = 0x8A,
+ [0xAC] = 0x5F, [0xAD] = 0xCA, [0xAE] = 0xAF, [0xAF] = 0xBC,
+ [0xB0] = 0x90, [0xB1] = 0x8F, [0xB2] = 0xEA, [0xB3] = 0xFA,
+ [0xB4] = 0xBE, [0xB5] = 0xA0, [0xB6] = 0xB6, [0xB7] = 0xB3,
+ [0xB8] = 0x9D, [0xB9] = 0xDA, [0xBA] = 0x9B, [0xBB] = 0x8B,
+ [0xBC] = 0xB7, [0xBD] = 0xB8, [0xBE] = 0xB9, [0xBF] = 0xAB,
+ [0xC0] = 0x64, [0xC1] = 0x65, [0xC2] = 0x62, [0xC3] = 0x66,
+ [0xC4] = 0x63, [0xC5] = 0x67, [0xC6] = 0x9E, [0xC7] = 0x68,
+ [0xC8] = 0x74, [0xC9] = 0x71, [0xCA] = 0x72, [0xCB] = 0x73,
+ [0xCC] = 0x78, [0xCD] = 0x75, [0xCE] = 0x76, [0xCF] = 0x77,
+ [0xD0] = 0xAC, [0xD1] = 0x69, [0xD2] = 0xED, [0xD3] = 0xEE,
+ [0xD4] = 0xEB, [0xD5] = 0xEF, [0xD6] = 0xEC, [0xD7] = 0xBF,
+ [0xD8] = 0x80, [0xD9] = 0xFD, [0xDA] = 0xFE, [0xDB] = 0xFB,
+ [0xDC] = 0xFC, [0xDD] = 0xAD, [0xDE] = 0xAE, [0xDF] = 0x59,
+ [0xE0] = 0x44, [0xE1] = 0x45, [0xE2] = 0x42, [0xE3] = 0x46,
+ [0xE4] = 0x43, [0xE5] = 0x47, [0xE6] = 0x9C, [0xE7] = 0x48,
+ [0xE8] = 0x54, [0xE9] = 0x51, [0xEA] = 0x52, [0xEB] = 0x53,
+ [0xEC] = 0x58, [0xED] = 0x55, [0xEE] = 0x56, [0xEF] = 0x57,
+ [0xF0] = 0x8C, [0xF1] = 0x49, [0xF2] = 0xCD, [0xF3] = 0xCE,
+ [0xF4] = 0xCB, [0xF5] = 0xCF, [0xF6] = 0xCC, [0xF7] = 0xE1,
+ [0xF8] = 0x70, [0xF9] = 0xDD, [0xFA] = 0xDE, [0xFB] = 0xDB,
+ [0xFC] = 0xDC, [0xFD] = 0x8D, [0xFE] = 0x8E, [0xFF] = 0xDF
+};
+
+// conversion table from IBM037 to ISO-8859-1
+static const unsigned char table_cp037_iso8859_1[256]
+__attribute__ ((aligned (8))) =
+{
+ [0x00] = 0x00, [0x01] = 0x01, [0x02] = 0x02, [0x03] = 0x03,
+ [0x04] = 0x9C, [0x05] = 0x09, [0x06] = 0x86, [0x07] = 0x7F,
+ [0x08] = 0x97, [0x09] = 0x8D, [0x0A] = 0x8E, [0x0B] = 0x0B,
+ [0x0C] = 0x0C, [0x0D] = 0x0D, [0x0E] = 0x0E, [0x0F] = 0x0F,
+ [0x10] = 0x10, [0x11] = 0x11, [0x12] = 0x12, [0x13] = 0x13,
+ [0x14] = 0x9D, [0x15] = 0x85, [0x16] = 0x08, [0x17] = 0x87,
+ [0x18] = 0x18, [0x19] = 0x19, [0x1A] = 0x92, [0x1B] = 0x8F,
+ [0x1C] = 0x1C, [0x1D] = 0x1D, [0x1E] = 0x1E, [0x1F] = 0x1F,
+ [0x20] = 0x80, [0x21] = 0x81, [0x22] = 0x82, [0x23] = 0x83,
+ [0x24] = 0x84, [0x25] = 0x0A, [0x26] = 0x17, [0x27] = 0x1B,
+ [0x28] = 0x88, [0x29] = 0x89, [0x2A] = 0x8A, [0x2B] = 0x8B,
+ [0x2C] = 0x8C, [0x2D] = 0x05, [0x2E] = 0x06, [0x2F] = 0x07,
+ [0x30] = 0x90, [0x31] = 0x91, [0x32] = 0x16, [0x33] = 0x93,
+ [0x34] = 0x94, [0x35] = 0x95, [0x36] = 0x96, [0x37] = 0x04,
+ [0x38] = 0x98, [0x39] = 0x99, [0x3A] = 0x9A, [0x3B] = 0x9B,
+ [0x3C] = 0x14, [0x3D] = 0x15, [0x3E] = 0x9E, [0x3F] = 0x1A,
+ [0x40] = 0x20, [0x41] = 0xA0, [0x42] = 0xE2, [0x43] = 0xE4,
+ [0x44] = 0xE0, [0x45] = 0xE1, [0x46] = 0xE3, [0x47] = 0xE5,
+ [0x48] = 0xE7, [0x49] = 0xF1, [0x4A] = 0xA2, [0x4B] = 0x2E,
+ [0x4C] = 0x3C, [0x4D] = 0x28, [0x4E] = 0x2B, [0x4F] = 0x7C,
+ [0x50] = 0x26, [0x51] = 0xE9, [0x52] = 0xEA, [0x53] = 0xEB,
+ [0x54] = 0xE8, [0x55] = 0xED, [0x56] = 0xEE, [0x57] = 0xEF,
+ [0x58] = 0xEC, [0x59] = 0xDF, [0x5A] = 0x21, [0x5B] = 0x24,
+ [0x5C] = 0x2A, [0x5D] = 0x29, [0x5E] = 0x3B, [0x5F] = 0xAC,
+ [0x60] = 0x2D, [0x61] = 0x2F, [0x62] = 0xC2, [0x63] = 0xC4,
+ [0x64] = 0xC0, [0x65] = 0xC1, [0x66] = 0xC3, [0x67] = 0xC5,
+ [0x68] = 0xC7, [0x69] = 0xD1, [0x6A] = 0xA6, [0x6B] = 0x2C,
+ [0x6C] = 0x25, [0x6D] = 0x5F, [0x6E] = 0x3E, [0x6F] = 0x3F,
+ [0x70] = 0xF8, [0x71] = 0xC9, [0x72] = 0xCA, [0x73] = 0xCB,
+ [0x74] = 0xC8, [0x75] = 0xCD, [0x76] = 0xCE, [0x77] = 0xCF,
+ [0x78] = 0xCC, [0x79] = 0x60, [0x7A] = 0x3A, [0x7B] = 0x23,
+ [0x7C] = 0x40, [0x7D] = 0x27, [0x7E] = 0x3D, [0x7F] = 0x22,
+ [0x80] = 0xD8, [0x81] = 0x61, [0x82] = 0x62, [0x83] = 0x63,
+ [0x84] = 0x64, [0x85] = 0x65, [0x86] = 0x66, [0x87] = 0x67,
+ [0x88] = 0x68, [0x89] = 0x69, [0x8A] = 0xAB, [0x8B] = 0xBB,
+ [0x8C] = 0xF0, [0x8D] = 0xFD, [0x8E] = 0xFE, [0x8F] = 0xB1,
+ [0x90] = 0xB0, [0x91] = 0x6A, [0x92] = 0x6B, [0x93] = 0x6C,
+ [0x94] = 0x6D, [0x95] = 0x6E, [0x96] = 0x6F, [0x97] = 0x70,
+ [0x98] = 0x71, [0x99] = 0x72, [0x9A] = 0xAA, [0x9B] = 0xBA,
+ [0x9C] = 0xE6, [0x9D] = 0xB8, [0x9E] = 0xC6, [0x9F] = 0xA4,
+ [0xA0] = 0xB5, [0xA1] = 0x7E, [0xA2] = 0x73, [0xA3] = 0x74,
+ [0xA4] = 0x75, [0xA5] = 0x76, [0xA6] = 0x77, [0xA7] = 0x78,
+ [0xA8] = 0x79, [0xA9] = 0x7A, [0xAA] = 0xA1, [0xAB] = 0xBF,
+ [0xAC] = 0xD0, [0xAD] = 0xDD, [0xAE] = 0xDE, [0xAF] = 0xAE,
+ [0xB0] = 0x5E, [0xB1] = 0xA3, [0xB2] = 0xA5, [0xB3] = 0xB7,
+ [0xB4] = 0xA9, [0xB5] = 0xA7, [0xB6] = 0xB6, [0xB7] = 0xBC,
+ [0xB8] = 0xBD, [0xB9] = 0xBE, [0xBA] = 0x5B, [0xBB] = 0x5D,
+ [0xBC] = 0xAF, [0xBD] = 0xA8, [0xBE] = 0xB4, [0xBF] = 0xD7,
+ [0xC0] = 0x7B, [0xC1] = 0x41, [0xC2] = 0x42, [0xC3] = 0x43,
+ [0xC4] = 0x44, [0xC5] = 0x45, [0xC6] = 0x46, [0xC7] = 0x47,
+ [0xC8] = 0x48, [0xC9] = 0x49, [0xCA] = 0xAD, [0xCB] = 0xF4,
+ [0xCC] = 0xF6, [0xCD] = 0xF2, [0xCE] = 0xF3, [0xCF] = 0xF5,
+ [0xD0] = 0x7D, [0xD1] = 0x4A, [0xD2] = 0x4B, [0xD3] = 0x4C,
+ [0xD4] = 0x4D, [0xD5] = 0x4E, [0xD6] = 0x4F, [0xD7] = 0x50,
+ [0xD8] = 0x51, [0xD9] = 0x52, [0xDA] = 0xB9, [0xDB] = 0xFB,
+ [0xDC] = 0xFC, [0xDD] = 0xF9, [0xDE] = 0xFA, [0xDF] = 0xFF,
+ [0xE0] = 0x5C, [0xE1] = 0xF7, [0xE2] = 0x53, [0xE3] = 0x54,
+ [0xE4] = 0x55, [0xE5] = 0x56, [0xE6] = 0x57, [0xE7] = 0x58,
+ [0xE8] = 0x59, [0xE9] = 0x5A, [0xEA] = 0xB2, [0xEB] = 0xD4,
+ [0xEC] = 0xD6, [0xED] = 0xD2, [0xEE] = 0xD3, [0xEF] = 0xD5,
+ [0xF0] = 0x30, [0xF1] = 0x31, [0xF2] = 0x32, [0xF3] = 0x33,
+ [0xF4] = 0x34, [0xF5] = 0x35, [0xF6] = 0x36, [0xF7] = 0x37,
+ [0xF8] = 0x38, [0xF9] = 0x39, [0xFA] = 0xB3, [0xFB] = 0xDB,
+ [0xFC] = 0xDC, [0xFD] = 0xD9, [0xFE] = 0xDA, [0xFF] = 0x9F
+};
+
+/* Definitions used in the body of the `gconv' function. */
+#define CHARSET_NAME "ISO-8859-1//"
+#define FROM_LOOP iso8859_1_to_cp037_z900
+#define TO_LOOP cp037_to_iso8859_1_z900
+#define DEFINE_INIT 1
+#define DEFINE_FINI 1
+#define MIN_NEEDED_FROM 1
+#define MIN_NEEDED_TO 1
+
+# if defined __s390x__
+# define BRANCH_ON_COUNT(REG,LBL) "brctg %" #REG "," #LBL "\n\t"
+# else
+# define BRANCH_ON_COUNT(REG,LBL) "brct %" #REG "," #LBL "\n\t"
+# endif
+
+#define TR_LOOP(TABLE) \
+ { \
+ size_t length = (inend - inptr < outend - outptr \
+ ? 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; \
+ } \
+ \
+ /* 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; \
+ } \
+ \
+ /* 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 TR_LOOP (table_iso8859_1_to_cp037)
+
+#include <iconv/loop.c>
+
+
+/* Next, define the conversion function from CP037 to ISO 8859-1. */
+#define MIN_NEEDED_INPUT MIN_NEEDED_TO
+#define MIN_NEEDED_OUTPUT MIN_NEEDED_FROM
+#define LOOPFCT TO_LOOP
+#define BODY TR_LOOP (table_cp037_iso8859_1);
+
+#include <iconv/loop.c>
+
+
+/* Now define the toplevel functions. */
+#include <iconv/skeleton.c>
diff --git a/REORG.TODO/sysdeps/s390/jmpbuf-offsets.h b/REORG.TODO/sysdeps/s390/jmpbuf-offsets.h
new file mode 100644
index 0000000000..e175801ffa
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/jmpbuf-offsets.h
@@ -0,0 +1,28 @@
+/* Private macros for accessing __jmp_buf contents. S/390 version.
+ Copyright (C) 2006-2017 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/>. */
+
+#define __JB_GPR6 0
+#define __JB_GPR7 1
+#define __JB_GPR8 2
+#define __JB_GPR9 3
+#define __JB_GPR10 4
+#define __JB_GPR11 5
+#define __JB_GPR12 6
+#define __JB_GPR13 7
+#define __JB_GPR14 8
+#define __JB_GPR15 9
diff --git a/REORG.TODO/sysdeps/s390/jmpbuf-unwind.h b/REORG.TODO/sysdeps/s390/jmpbuf-unwind.h
new file mode 100644
index 0000000000..4c8e91cea7
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/jmpbuf-unwind.h
@@ -0,0 +1,54 @@
+/* Copyright (C) 2003-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Jakub Jelinek <jakub@redhat.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
+ 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 <setjmp.h>
+#include <jmpbuf-offsets.h>
+#include <stdint.h>
+#include <unwind.h>
+#include <bits/wordsize.h>
+#include <sysdep.h>
+
+
+/* Test if longjmp to JMPBUF would unwind the frame
+ containing a local variable at ADDRESS. */
+#define _JMPBUF_UNWINDS(jmpbuf, address, demangle) \
+ ((void *) (address) < (void *) demangle ((jmpbuf)->__gregs[__JB_GPR15]))
+
+
+/* On s390{,x}, CFA is always 96 (resp. 160) bytes above actual
+ %r15. */
+#define _JMPBUF_CFA_UNWINDS_ADJ(_jmpbuf, _context, _adj) \
+ _JMPBUF_UNWINDS_ADJ (_jmpbuf, \
+ (void *) (_Unwind_GetCFA (_context) \
+ - 32 - 2 * __WORDSIZE), _adj)
+
+static inline uintptr_t __attribute__ ((unused))
+_jmpbuf_sp (__jmp_buf regs)
+{
+ void *sp = (void *) (uintptr_t) regs[0].__gregs[__JB_GPR15];
+#ifdef PTR_DEMANGLE
+ PTR_DEMANGLE (sp);
+#endif
+ return (uintptr_t) sp;
+}
+
+#define _JMPBUF_UNWINDS_ADJ(_jmpbuf, _address, _adj) \
+ ((uintptr_t) (_address) - (_adj) < _jmpbuf_sp (_jmpbuf) - (_adj))
+
+/* We use the normal longjmp for unwinding. */
+#define __libc_unwind_longjmp(buf, val) __libc_longjmp (buf, val)
diff --git a/REORG.TODO/sysdeps/s390/ldsodefs.h b/REORG.TODO/sysdeps/s390/ldsodefs.h
new file mode 100644
index 0000000000..706f57dc9c
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/ldsodefs.h
@@ -0,0 +1,57 @@
+/* Run-time dynamic linker data structures for loaded ELF shared objects.
+ Copyright (C) 1995-2017 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 _S390_LDSODEFS_H
+#define _S390_LDSODEFS_H 1
+
+#include <elf.h>
+
+struct La_s390_32_regs;
+struct La_s390_32_retval;
+struct La_s390_64_regs;
+struct La_s390_64_retval;
+
+#define ARCH_PLTENTER_MEMBERS \
+ Elf32_Addr (*s390_32_gnu_pltenter) (Elf32_Sym *, unsigned int, \
+ uintptr_t *, \
+ uintptr_t *, \
+ struct La_s390_32_regs *, \
+ unsigned int *, const char *name, \
+ long int *framesizep); \
+ Elf64_Addr (*s390_64_gnu_pltenter) (Elf64_Sym *, unsigned int, \
+ uintptr_t *, \
+ uintptr_t *, \
+ struct La_s390_64_regs *, \
+ unsigned int *, const char *name, \
+ long int *framesizep)
+
+#define ARCH_PLTEXIT_MEMBERS \
+ unsigned int (*s390_32_gnu_pltexit) (Elf32_Sym *, unsigned int, \
+ uintptr_t *, uintptr_t *, \
+ const struct La_s390_32_regs *, \
+ struct La_s390_32_retval *, \
+ const char *); \
+ unsigned int (*s390_64_gnu_pltexit) (Elf64_Sym *, unsigned int, \
+ uintptr_t *, uintptr_t *, \
+ const struct La_s390_64_regs *, \
+ struct La_s390_64_retval *, \
+ const char *)
+
+#include_next <ldsodefs.h>
+
+#endif
diff --git a/REORG.TODO/sysdeps/s390/libc-tls.c b/REORG.TODO/sysdeps/s390/libc-tls.c
new file mode 100644
index 0000000000..d19632f7fb
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/libc-tls.c
@@ -0,0 +1,32 @@
+/* Thread-local storage handling in the ELF dynamic linker. S390 version.
+ Copyright (C) 2003-2017 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 <stdlib.h>
+#include <csu/libc-tls.c>
+
+/* On s390, the literal pool entry that refers to __tls_get_offset
+ is not removed, even if all branches that use the literal pool
+ entry gets removed by TLS optimizations. To get binaries
+ statically linked __tls_get_offset is defined here but
+ aborts if it is used. */
+
+void *
+__tls_get_offset (size_t m, size_t offset)
+{
+ abort ();
+}
diff --git a/REORG.TODO/sysdeps/s390/linkmap.h b/REORG.TODO/sysdeps/s390/linkmap.h
new file mode 100644
index 0000000000..283615b99a
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/linkmap.h
@@ -0,0 +1,13 @@
+#if __WORDSIZE == 64
+struct link_map_machine
+ {
+ Elf64_Addr plt; /* Address of .plt + 0x2e */
+ const Elf64_Rela *jmprel; /* Address of first JMP_SLOT reloc */
+ };
+#else
+struct link_map_machine
+ {
+ Elf32_Addr plt; /* Address of .plt + 0x2c */
+ const Elf32_Rela *jmprel; /* Address of first JMP_SLOT reloc */
+ };
+#endif
diff --git a/REORG.TODO/sysdeps/s390/longjmp.c b/REORG.TODO/sysdeps/s390/longjmp.c
new file mode 100644
index 0000000000..d108669ecc
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/longjmp.c
@@ -0,0 +1,52 @@
+/* Copyright (C) 2014-2017 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/>.
+
+ Versioned copy of setjmp/longjmp.c modified for versioning
+ the reverted jmpbuf extension. */
+
+#include <shlib-compat.h>
+
+#if defined SHARED && SHLIB_COMPAT (libc, GLIBC_2_19, GLIBC_2_20)
+/* We don't want the weak alias to longjmp, _longjmp, siglongjmp here,
+ because we create the default/versioned symbols later. */
+# define __libc_siglongjmp __libc_siglongjmp
+#endif /* SHARED && SHLIB_COMPAT (libc, GLIBC_2_19, GLIBC_2_20) */
+
+#include <setjmp/longjmp.c>
+
+#if defined SHARED && SHLIB_COMPAT (libc, GLIBC_2_19, GLIBC_2_20)
+/* In glibc release 2.19 new versions of longjmp-functions were introduced,
+ 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)
+versioned_symbol (libc, __v1_longjmp, _longjmp, GLIBC_2_0);
+compat_symbol (libc, __v2_longjmp, _longjmp, GLIBC_2_19);
+
+weak_alias (__libc_siglongjmp, __v1longjmp)
+weak_alias (__libc_siglongjmp, __v2longjmp)
+versioned_symbol (libc, __v1longjmp, longjmp, GLIBC_2_0);
+compat_symbol (libc, __v2longjmp, longjmp, GLIBC_2_19);
+
+weak_alias (__libc_siglongjmp, __v1siglongjmp)
+weak_alias (__libc_siglongjmp, __v2siglongjmp)
+versioned_symbol (libc, __v1siglongjmp, siglongjmp, GLIBC_2_0);
+compat_symbol (libc, __v2siglongjmp, siglongjmp, GLIBC_2_19);
+#endif /* SHARED && SHLIB_COMPAT (libc, GLIBC_2_19, GLIBC_2_20) */
diff --git a/REORG.TODO/sysdeps/s390/machine-gmon.h b/REORG.TODO/sysdeps/s390/machine-gmon.h
new file mode 100644
index 0000000000..dac340cf7e
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/machine-gmon.h
@@ -0,0 +1,35 @@
+/* s390-specific implementation of profiling support.
+ Copyright (C) 2000-2017 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 <sysdep.h>
+
+/* We need a special version of the `mcount' function since for S/390 it
+ must not clobber any register. */
+
+/* We must not pollute the global namespace. */
+#define mcount_internal __mcount_internal
+
+void mcount_internal (u_long frompc, u_long selfpc);
+
+#define _MCOUNT_DECL(frompc, selfpc) \
+void mcount_internal (u_long frompc, u_long selfpc)
+
+
+/* Define MCOUNT as empty since we have the implementation in another
+ file. */
+#define MCOUNT
diff --git a/REORG.TODO/sysdeps/s390/mempcpy.S b/REORG.TODO/sysdeps/s390/mempcpy.S
new file mode 100644
index 0000000000..acb90bb260
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/mempcpy.S
@@ -0,0 +1,19 @@
+/* CPU specific mempcpy without multiarch - 32/64 bit S/390 version.
+ Copyright (C) 2016-2017 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/>. */
+
+/* mempcpy is implemented in memcpy.S. */
diff --git a/REORG.TODO/sysdeps/s390/memusage.h b/REORG.TODO/sysdeps/s390/memusage.h
new file mode 100644
index 0000000000..347272c483
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/memusage.h
@@ -0,0 +1,20 @@
+/* Copyright (C) 2000-2017 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/>. */
+
+#define GETSP() ({ register uintptr_t stack_ptr __asm__ ("15"); stack_ptr; })
+
+#include <sysdeps/generic/memusage.h>
diff --git a/REORG.TODO/sysdeps/s390/multiarch/8bit-generic.c b/REORG.TODO/sysdeps/s390/multiarch/8bit-generic.c
new file mode 100644
index 0000000000..49f0ed8ae5
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/multiarch/8bit-generic.c
@@ -0,0 +1,398 @@
+/* Generic conversion to and from 8bit charsets - S390 version.
+ Copyright (C) 2016-2017 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; \
+ } \
+ } \
+ \
+ 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/REORG.TODO/sysdeps/s390/multiarch/Makefile b/REORG.TODO/sysdeps/s390/multiarch/Makefile
new file mode 100644
index 0000000000..c893ebc565
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/multiarch/Makefile
@@ -0,0 +1,59 @@
+ifeq ($(subdir),string)
+sysdep_routines += strlen strlen-vx strlen-c \
+ strnlen strnlen-vx strnlen-c \
+ strcpy strcpy-vx \
+ stpcpy stpcpy-vx stpcpy-c \
+ strncpy strncpy-vx \
+ stpncpy stpncpy-vx stpncpy-c \
+ strcat strcat-vx strcat-c \
+ strncat strncat-vx strncat-c \
+ strcmp strcmp-vx \
+ strncmp strncmp-vx strncmp-c \
+ strchr strchr-vx strchr-c \
+ strchrnul strchrnul-vx strchrnul-c \
+ strrchr strrchr-vx strrchr-c \
+ strspn strspn-vx strspn-c \
+ strpbrk strpbrk-vx strpbrk-c \
+ strcspn strcspn-vx strcspn-c \
+ memchr memchr-vx \
+ rawmemchr rawmemchr-vx rawmemchr-c \
+ memccpy memccpy-vx memccpy-c \
+ memrchr memrchr-vx memrchr-c \
+ mempcpy
+endif
+
+ifeq ($(subdir),wcsmbs)
+sysdep_routines += wcslen wcslen-vx wcslen-c \
+ wcsnlen wcsnlen-vx wcsnlen-c \
+ wcscpy wcscpy-vx wcscpy-c \
+ wcpcpy wcpcpy-vx wcpcpy-c \
+ wcsncpy wcsncpy-vx wcsncpy-c \
+ wcpncpy wcpncpy-vx wcpncpy-c \
+ wcscat wcscat-vx wcscat-c \
+ wcsncat wcsncat-vx wcsncat-c \
+ wcscmp wcscmp-vx wcscmp-c \
+ wcsncmp wcsncmp-vx wcsncmp-c \
+ wcschr wcschr-vx wcschr-c \
+ wcschrnul wcschrnul-vx wcschrnul-c \
+ wcsrchr wcsrchr-vx wcsrchr-c \
+ wcsspn wcsspn-vx wcsspn-c \
+ wcspbrk wcspbrk-vx wcspbrk-c \
+ wcscspn wcscspn-vx wcscspn-c \
+ wmemchr wmemchr-vx wmemchr-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/REORG.TODO/sysdeps/s390/multiarch/gconv_simple.c b/REORG.TODO/sysdeps/s390/multiarch/gconv_simple.c
new file mode 100644
index 0000000000..75632873e3
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/multiarch/gconv_simple.c
@@ -0,0 +1,1266 @@
+/* Simple transformations functions - s390 version.
+ Copyright (C) 2016-2017 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/REORG.TODO/sysdeps/s390/multiarch/gen-8bit.sh b/REORG.TODO/sysdeps/s390/multiarch/gen-8bit.sh
new file mode 100644
index 0000000000..6f88c4bd9d
--- /dev/null
+++ b/REORG.TODO/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/REORG.TODO/sysdeps/s390/multiarch/iconv/skeleton.c b/REORG.TODO/sysdeps/s390/multiarch/iconv/skeleton.c
new file mode 100644
index 0000000000..ca9ad1206f
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/multiarch/iconv/skeleton.c
@@ -0,0 +1,21 @@
+/* Skeleton for a conversion module - S390 version.
+ Copyright (C) 2016-2017 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/REORG.TODO/sysdeps/s390/multiarch/ifunc-impl-list.c b/REORG.TODO/sysdeps/s390/multiarch/ifunc-impl-list.c
new file mode 100644
index 0000000000..6210f50acb
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/multiarch/ifunc-impl-list.c
@@ -0,0 +1,152 @@
+/* Enumerate available IFUNC implementations of a function. s390/s390x version.
+ Copyright (C) 2015-2017 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 <assert.h>
+#include <string.h>
+#include <wchar.h>
+#include <ifunc-impl-list.h>
+#include <ifunc-resolve.h>
+
+/* Maximum number of IFUNC implementations. */
+#define MAX_IFUNC 3
+
+/* Fill ARRAY of MAX elements with IFUNC implementations for function
+ NAME supported on target machine and return the number of valid
+ entries. */
+size_t
+__libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
+ size_t max)
+{
+ assert (max >= MAX_IFUNC);
+
+ size_t i = 0;
+
+ /* Get hardware information. */
+ unsigned long int dl_hwcap = GLRO (dl_hwcap);
+ unsigned long long stfle_bits = 0ULL;
+ if ((dl_hwcap & HWCAP_S390_STFLE)
+ && (dl_hwcap & HWCAP_S390_ZARCH)
+ && (dl_hwcap & HWCAP_S390_HIGH_GPRS))
+ {
+ S390_STORE_STFLE (stfle_bits);
+ }
+
+ IFUNC_IMPL (i, name, memset,
+ IFUNC_IMPL_ADD (array, i, memset,
+ S390_IS_Z196 (stfle_bits), __memset_z196)
+ IFUNC_IMPL_ADD (array, i, memset,
+ S390_IS_Z10 (stfle_bits), __memset_z10)
+ IFUNC_IMPL_ADD (array, i, memset, 1, __memset_default))
+
+ IFUNC_IMPL (i, name, memcmp,
+ IFUNC_IMPL_ADD (array, i, memcmp,
+ S390_IS_Z196 (stfle_bits), __memcmp_z196)
+ IFUNC_IMPL_ADD (array, i, memcmp,
+ S390_IS_Z10 (stfle_bits), __memcmp_z10)
+ IFUNC_IMPL_ADD (array, i, memcmp, 1, __memcmp_default))
+
+#ifdef SHARED
+
+ IFUNC_IMPL (i, name, memcpy,
+ IFUNC_IMPL_ADD (array, i, memcpy,
+ S390_IS_Z196 (stfle_bits), __memcpy_z196)
+ IFUNC_IMPL_ADD (array, i, memcpy,
+ 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
+
+# define IFUNC_VX_IMPL(FUNC) \
+ IFUNC_IMPL (i, name, FUNC, \
+ IFUNC_IMPL_ADD (array, i, FUNC, dl_hwcap & HWCAP_S390_VX, \
+ __##FUNC##_vx) \
+ IFUNC_IMPL_ADD (array, i, FUNC, 1, __##FUNC##_c))
+
+ IFUNC_VX_IMPL (strlen);
+ IFUNC_VX_IMPL (wcslen);
+
+ IFUNC_VX_IMPL (strnlen);
+ IFUNC_VX_IMPL (wcsnlen);
+
+ IFUNC_VX_IMPL (strcpy);
+ IFUNC_VX_IMPL (wcscpy);
+
+ IFUNC_VX_IMPL (stpcpy);
+ IFUNC_VX_IMPL (wcpcpy);
+
+ IFUNC_VX_IMPL (strncpy);
+ IFUNC_VX_IMPL (wcsncpy);
+
+ IFUNC_VX_IMPL (stpncpy);
+ IFUNC_VX_IMPL (wcpncpy);
+
+ IFUNC_VX_IMPL (strcat);
+ IFUNC_VX_IMPL (wcscat);
+
+ IFUNC_VX_IMPL (strncat);
+ IFUNC_VX_IMPL (wcsncat);
+
+ IFUNC_VX_IMPL (strcmp);
+ IFUNC_VX_IMPL (wcscmp);
+
+ IFUNC_VX_IMPL (strncmp);
+ IFUNC_VX_IMPL (wcsncmp);
+
+ IFUNC_VX_IMPL (strchr);
+ IFUNC_VX_IMPL (wcschr);
+
+ IFUNC_VX_IMPL (strchrnul);
+ IFUNC_VX_IMPL (wcschrnul);
+
+ IFUNC_VX_IMPL (strrchr);
+ IFUNC_VX_IMPL (wcsrchr);
+
+ IFUNC_VX_IMPL (strspn);
+ IFUNC_VX_IMPL (wcsspn);
+
+ IFUNC_VX_IMPL (strpbrk);
+ IFUNC_VX_IMPL (wcspbrk);
+
+ IFUNC_VX_IMPL (strcspn);
+ IFUNC_VX_IMPL (wcscspn);
+
+ IFUNC_VX_IMPL (memchr);
+ IFUNC_VX_IMPL (wmemchr);
+ IFUNC_VX_IMPL (rawmemchr);
+
+ IFUNC_VX_IMPL (memccpy);
+
+ IFUNC_VX_IMPL (wmemset);
+
+ IFUNC_VX_IMPL (wmemcmp);
+
+ IFUNC_VX_IMPL (memrchr);
+
+#endif /* HAVE_S390_VX_ASM_SUPPORT */
+
+ return i;
+}
diff --git a/REORG.TODO/sysdeps/s390/multiarch/ifunc-resolve.h b/REORG.TODO/sysdeps/s390/multiarch/ifunc-resolve.h
new file mode 100644
index 0000000000..adbd08a6ee
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/multiarch/ifunc-resolve.h
@@ -0,0 +1,90 @@
+/* IFUNC resolver function for CPU specific functions.
+ 32/64 bit S/390 version.
+ Copyright (C) 2015-2017 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 <unistd.h>
+#include <dl-procinfo.h>
+
+#define S390_STFLE_BITS_Z10 34 /* General instructions extension */
+#define S390_STFLE_BITS_Z196 45 /* Distinct operands, pop ... */
+
+#define S390_IS_Z196(STFLE_BITS) \
+ ((STFLE_BITS & (1ULL << (63 - S390_STFLE_BITS_Z196))) != 0)
+
+#define S390_IS_Z10(STFLE_BITS) \
+ ((STFLE_BITS & (1ULL << (63 - S390_STFLE_BITS_Z10))) != 0)
+
+#define S390_STORE_STFLE(STFLE_BITS) \
+ /* We want just 1 double word to be returned. */ \
+ register unsigned long reg0 __asm__("0") = 0; \
+ \
+ __asm__ __volatile__(".machine push" "\n\t" \
+ ".machine \"z9-109\"" "\n\t" \
+ ".machinemode \"zarch_nohighgprs\"\n\t" \
+ "stfle %0" "\n\t" \
+ ".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(TYPE_FUNC, RESOLVERFUNC, FUNC) \
+ /* Make the declarations of the optimized functions hidden in order
+ to prevent GOT slots being generated for them. */ \
+ 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_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) \
+ 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 (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/REORG.TODO/sysdeps/s390/multiarch/memccpy-c.c b/REORG.TODO/sysdeps/s390/multiarch/memccpy-c.c
new file mode 100644
index 0000000000..73069ae502
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/multiarch/memccpy-c.c
@@ -0,0 +1,25 @@
+/* Default memccpy implementation for S/390.
+ Copyright (C) 2015-2017 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 && IS_IN (libc)
+# define MEMCCPY __memccpy_c
+
+# include <string.h>
+extern __typeof (__memccpy) __memccpy_c;
+# include <string/memccpy.c>
+#endif
diff --git a/REORG.TODO/sysdeps/s390/multiarch/memccpy-vx.S b/REORG.TODO/sysdeps/s390/multiarch/memccpy-vx.S
new file mode 100644
index 0000000000..f60aecef77
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/multiarch/memccpy-vx.S
@@ -0,0 +1,156 @@
+/* Vector optimized 32/64 bit S/390 version of memccpy.
+ Copyright (C) 2015-2017 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 && IS_IN (libc)
+
+# include "sysdep.h"
+# include "asm-syntax.h"
+
+ .text
+
+/* void *memccpy (void * dest, const void *src, int c, size_t n)
+ Copies no more than n bytes from src to dest,
+ stopping when the character c is found
+ and returns pointer next to c in dest or null if c not found.
+
+ Register usage:
+ -r0=tmp
+ -r1=tmp
+ -r2=dest
+ -r3=src
+ -r4=c
+ -r5=n
+ -r6=current_len
+ -v16=part of s
+ -v17=index of found c
+ -v18=c replicated
+ -v19=part #2 of s
+ -v31=save area for r6
+*/
+ENTRY(__memccpy_vx)
+ .machine "z13"
+ .machinemode "zarch_nohighgprs"
+
+# if !defined __s390x__
+ llgfr %r5,%r5
+# endif /* !defined __s390x__ */
+
+ vlvgp %v31,%r6,%r7 /* Save registers. */
+ clgije %r5,0,.Lnf_end /* If len == 0 then exit. */
+
+ vlbb %v16,0(%r3),6 /* Load s until next 4k-byte boundary. */
+ lcbb %r0,0(%r3),6 /* Get bytes to 4k-byte boundary or 16. */
+ llgfr %r0,%r0 /* Convert 32bit to 64bit. */
+
+ vlvgb %v18,%r4,0 /* Generate vector which elements are all c.
+ if c > 255, c will be truncated. */
+ vrepb %v18,%v18,0
+ lghi %r6,0 /* current_len = 0. */
+
+ clgrjle %r5,%r0,.Lremaining_v16 /* If maxlen <= loaded-bytes
+ -> Process remaining. */
+
+ vfeebs %v17,%v16,%v18 /* Find c. */
+ vlgvb %r1,%v17,7 /* Load byte index of c. */
+ clgrjl %r1,%r0,.Lfound_v16 /* Found c is within loaded bytes. */
+
+ /* Align s to 16 byte. */
+ risbgn %r1,%r3,60,128+63,0 /* %r3 = bits 60-63 of %r2 'and' 15. */
+ lghi %r6,15 /* current_len = 15. */
+ slr %r6,%r1 /* Compute highest index to 16byte boundary. */
+
+ vstl %v16,%r6,0(%r2) /* Store prcessed bytes */
+ ahi %r6,1
+
+.Lpreloop1:
+ /* Now we are 16byte aligned, so we can load
+ a full vreg without page fault. */
+ vl %v16,0(%r6,%r3) /* Load s. */
+ clgijl %r5,17,.Lremaining_v16 /* If n <= 16,
+ process remaining bytes. */
+ lgr %r7,%r5
+ slgfi %r7,16 /* border_len = n - 16. */
+ j .Lloop1
+
+.Lloop2:
+ vl %v16,16(%r6,%r3)
+ vst %v19,0(%r6,%r2)
+ aghi %r6,16
+
+.Lloop1:
+ clgrjhe %r6,%r7,.Lremaining_v16 /* If current_len >= border
+ then process remaining bytes. */
+ vfeebs %v17,%v16,%v18 /* Find c. */
+ jl .Lfound_v16 /* Jump away if c was found. */
+ vl %v19,16(%r6,%r3) /* Load next s part. */
+ vst %v16,0(%r6,%r2) /* Store previous part without c. */
+ aghi %r6,16
+
+ clgrjhe %r6,%r7,.Lremaining_v19
+ vfeebs %v17,%v19,%v18
+ jl .Lfound_v19
+ vl %v16,16(%r6,%r3)
+ vst %v19,0(%r6,%r2)
+ aghi %r6,16
+
+ clgrjhe %r6,%r7,.Lremaining_v16
+ vfeebs %v17,%v16,%v18
+ jl .Lfound_v16
+ vl %v19,16(%r6,%r3)
+ vst %v16,0(%r6,%r2)
+ aghi %r6,16
+
+ clgrjhe %r6,%r7,.Lremaining_v19
+ vfeebs %v17,%v19,%v18
+ jo .Lloop2
+
+.Lfound_v19:
+ vlr %v16,%v19
+.Lfound_v16:
+ /* v16 contains c. Store remaining bytes to c. currlen hasn´t
+ reached border, thus checking for maxlen is not needed! */
+ vlgvb %r1,%v17,7 /* Load byte index of c. */
+ la %r2,0(%r6,%r2) /* vstl has no support for index-register. */
+.Lfound_v16_store:
+ vstl %v16,%r1,0(%r2) /* Copy bytes including c. */
+ la %r2,1(%r1,%r2) /* Return pointer next to c in dest. */
+ vlgvg %r6,%v31,0
+ vlgvg %r7,%v31,1
+ br %r14
+
+.Lremaining_v19:
+ vlr %v16,%v19
+.Lremaining_v16:
+ /* v16 contains the remaining bytes [1...16].
+ Check and store remaining bytes. */
+ vfeebs %v17,%v16,%v18
+ slgrk %r7,%r5,%r6 /* Remaining bytes = maxlen - current_len. */
+ aghi %r7,-1 /* vstl needs highest index. */
+ la %r2,0(%r6,%r2) /* vstl has no index register. */
+ vlgvb %r1,%v17,7 /* Load index of c or 16 if not found. */
+ /* c in remaining bytes? -> Jump away (c-index <= max-index) */
+ clrjle %r1,%r7,.Lfound_v16_store
+ vstl %v16,%r7,0(%r2) /* Store remaining bytes. */
+
+.Lnf_end:
+ vlgvg %r6,%v31,0
+ vlgvg %r7,%v31,1
+ lghi %r2,0 /* Return null. */
+ br %r14
+END(__memccpy_vx)
+#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */
diff --git a/REORG.TODO/sysdeps/s390/multiarch/memccpy.c b/REORG.TODO/sysdeps/s390/multiarch/memccpy.c
new file mode 100644
index 0000000000..5adc1a8063
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/multiarch/memccpy.c
@@ -0,0 +1,28 @@
+/* Multiple versions of memccpy.
+ Copyright (C) 2015-2017 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 && IS_IN (libc)
+# include <string.h>
+# include <ifunc-resolve.h>
+
+s390_vx_libc_ifunc (__memccpy)
+weak_alias (__memccpy, memccpy)
+
+#else
+# include <string/memccpy.c>
+#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)) */
diff --git a/REORG.TODO/sysdeps/s390/multiarch/memchr-vx.S b/REORG.TODO/sysdeps/s390/multiarch/memchr-vx.S
new file mode 100644
index 0000000000..e9cb06f948
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/multiarch/memchr-vx.S
@@ -0,0 +1,159 @@
+/* Vector optimized 32/64 bit S/390 version of memchr.
+ Copyright (C) 2015-2017 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 && IS_IN (libc)
+
+# include "sysdep.h"
+# include "asm-syntax.h"
+
+ .text
+
+/* void *memchr (const void *s, int c, size_t n)
+ Scans memory for character c
+ and returns pointer to first c.
+
+ Register usage:
+ -r0=tmp
+ -r1=tmp
+ -r2=s
+ -r3=c
+ -r4=n
+ -r5=current_len
+ -v16=part of s
+ -v17=index of found c
+ -v18=c replicated
+*/
+ENTRY(__memchr_vx)
+
+ .machine "z13"
+ .machinemode "zarch_nohighgprs"
+
+# if !defined __s390x__
+ llgfr %r4,%r4
+# endif /* !defined __s390x__ */
+
+ clgije %r4,0,.Lnf_end /* If len == 0 then exit. */
+
+ vlbb %v16,0(%r2),6 /* Load s until next 4k-byte boundary. */
+ lcbb %r0,0(%r2),6 /* Get bytes to 4k-byte boundary or 16. */
+ llgfr %r0,%r0 /* Convert 32bit to 64bit. */
+
+ vlvgb %v18,%r3,0 /* Generate vector which elements are all c.
+ if c > 255, c will be truncated. */
+ vrepb %v18,%v18,0
+ lghi %r5,16 /* current_len = 16. */
+
+ clgrjhe %r0,%r4,.Llastcmp /* If (bytes to boundary) >= n,
+ jump to lastcmp. */
+
+ vfeebs %v17,%v16,%v18 /* Find c. */
+ vlgvb %r1,%v17,7 /* Load byte index of c. */
+ clgrjl %r1,%r0,.Lfound2 /* Found c is within loaded bytes. */
+
+ /* Align s to 16 byte. */
+ risbgn %r1,%r2,60,128+63,0 /* %r3 = bits 60-63 of %r2 'and' 15. */
+ slr %r5,%r1 /* Compute bytes to 16bytes boundary. */
+
+ lgr %r0,%r5 /* If %r5 + 64 < n? -> loop64. */
+ aghi %r0,64
+ clgrjl %r0,%r4,.Lloop64
+.Llt64:
+ vl %v16,0(%r5,%r2)
+ aghi %r5,16
+ clgrjhe %r5,%r4,.Llastcmp /* Do last compare if curr-len >= n. */
+ vfeebs %v17,%v16,%v18 /* Find c. */
+ jl .Lfound /* Jump away if c was found. */
+
+ vl %v16,0(%r5,%r2)
+ aghi %r5,16
+ clgrjhe %r5,%r4,.Llastcmp
+ vfeebs %v17,%v16,%v18
+ jl .Lfound
+
+ vl %v16,0(%r5,%r2)
+ aghi %r5,16
+ clgrjhe %r5,%r4,.Llastcmp
+ vfeebs %v17,%v16,%v18
+ jl .Lfound
+
+ vl %v16,0(%r5,%r2)
+ aghi %r5,16
+
+.Llastcmp:
+ /* Use comparision result only if located within first n characters.
+ %r5: current_len;
+ %r4: n;
+ (current_len - n): [0...16[
+ first ignored match index: vr-width - (current_len - n) ]0...16]
+ */
+ vfeebs %v17,%v16,%v18 /* Find c. */
+ slgrk %r4,%r5,%r4 /* %r5 = current_len - n. */
+ lghi %r0,16 /* Register width = 16. */
+ vlgvb %r1,%v17,7 /* Extract found index or 16 if all equal. */
+ slr %r0,%r4 /* %r0 = first ignored match index. */
+ clrjl %r1,%r0,.Lfound2 /* Go away if miscompare is below n bytes. */
+ /* c not found within n-bytes. */
+.Lnf_end:
+ lghi %r2,0 /* Return null. */
+ br %r14
+
+.Lfound48:
+ aghi %r5,16
+.Lfound32:
+ aghi %r5,16
+.Lfound16:
+ aghi %r5,16
+.Lfound0:
+ aghi %r5,16
+.Lfound:
+ vlgvb %r1,%v17,7 /* Load byte index of c. */
+.Lfound2:
+ slgfi %r5,16 /* current_len -=16 */
+ algr %r5,%r1 /* Zero byte index is added to current len. */
+ la %r2,0(%r5,%r2) /* Return pointer to c. */
+ br %r14
+
+
+.Lloop64:
+ vl %v16,0(%r5,%r2)
+ vfeebs %v17,%v16,%v18 /* Find c. */
+ jl .Lfound0 /* Jump away if c was found. */
+ vl %v16,16(%r5,%r2)
+ vfeebs %v17,%v16,%v18
+ jl .Lfound16
+ vl %v16,32(%r5,%r2)
+ vfeebs %v17,%v16,%v18
+ jl .Lfound32
+ vl %v16,48(%r5,%r2)
+ vfeebs %v17,%v16,%v18
+ jl .Lfound48
+
+ aghi %r5,64
+ lgr %r0,%r5 /* If %r5 + 64 < n? -> loop64. */
+ aghi %r0,64
+ clgrjl %r0,%r4,.Lloop64
+
+ j .Llt64
+END(__memchr_vx)
+
+# define memchr __memchr_c
+# undef libc_hidden_builtin_def
+# define libc_hidden_builtin_def(name) strong_alias(__memchr_c, __GI_memchr)
+#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */
+
+#include <memchr.S>
diff --git a/REORG.TODO/sysdeps/s390/multiarch/memchr.c b/REORG.TODO/sysdeps/s390/multiarch/memchr.c
new file mode 100644
index 0000000000..f0bf41f8e4
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/multiarch/memchr.c
@@ -0,0 +1,27 @@
+/* Multiple versions of memchr.
+ Copyright (C) 2015-2017 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 && IS_IN (libc)
+# define memchr __redirect_memchr
+# include <string.h>
+# undef memchr
+# include <ifunc-resolve.h>
+
+s390_vx_libc_ifunc2_redirected (__redirect_memchr, __memchr, memchr)
+
+#endif
diff --git a/REORG.TODO/sysdeps/s390/multiarch/mempcpy.c b/REORG.TODO/sysdeps/s390/multiarch/mempcpy.c
new file mode 100644
index 0000000000..bf111a3aea
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/multiarch/mempcpy.c
@@ -0,0 +1,32 @@
+/* Multiple versions of mempcpy.
+ Copyright (C) 2016-2017 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
+/* Omit the mempcpy inline definitions because it would redefine mempcpy. */
+# define _HAVE_STRING_ARCH_mempcpy 1
+# 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/REORG.TODO/sysdeps/s390/multiarch/memrchr-c.c b/REORG.TODO/sysdeps/s390/multiarch/memrchr-c.c
new file mode 100644
index 0000000000..7382b7ff05
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/multiarch/memrchr-c.c
@@ -0,0 +1,25 @@
+/* Default memrchr implementation for S/390.
+ Copyright (C) 2015-2017 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 && IS_IN (libc)
+# define MEMRCHR __memrchr_c
+
+# include <string.h>
+extern __typeof (__memrchr) __memrchr_c;
+# include <string/memrchr.c>
+#endif
diff --git a/REORG.TODO/sysdeps/s390/multiarch/memrchr-vx.S b/REORG.TODO/sysdeps/s390/multiarch/memrchr-vx.S
new file mode 100644
index 0000000000..c6b0d34692
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/multiarch/memrchr-vx.S
@@ -0,0 +1,160 @@
+/* Vector optimized 32/64 bit S/390 version of memrchr.
+ Copyright (C) 2015-2017 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 && IS_IN (libc)
+
+# include "sysdep.h"
+# include "asm-syntax.h"
+
+ .text
+
+/* void *memrchr (const void *s, int c, size_t n)
+ Scans memory for character c backwards
+ and returns pointer to first c.
+
+ Register usage:
+ -r0=tmp
+ -r1=tmp
+ -r2=s
+ -r3=c
+ -r4=n
+ -r5=s in loop
+
+ -v16=part of s
+ -v17=index of found c
+ -v18=c replicated
+ -v20=permute pattern
+*/
+ENTRY(__memrchr_vx)
+ .machine "z13"
+ .machinemode "zarch_nohighgprs"
+
+# if !defined __s390x__
+ llgfr %r4,%r4
+# endif /* !defined __s390x__ */
+ clgije %r4,0,.Lnot_found
+
+ vlvgb %v18,%r3,0 /* Generate vector which elements are all c.
+ If c > 255, c will be truncated. */
+ vrepb %v18,%v18,0
+
+ llcr %r3,%r3 /* char c_char = (char) c. */
+
+ /* check byte n - 1. */
+ llc %r0,-1(%r4,%r2)
+ slgfi %r4,1
+ clrje %r0,%r3,.Lfound_end
+ jh .Lnot_found /* Return NULL if n is now 0. */
+
+ larl %r1,.Lpermute_mask /* Load permute mask. */
+ vl %v20,0(%r1)
+
+ /* check byte n - 2. */
+ llc %r0,-1(%r4,%r2)
+ slgfi %r4,1
+ clrje %r0,%r3,.Lfound_end
+ jh .Lnot_found /* Return NULL if n is now 0. */
+
+ clgijhe %r4,64,.Lloop64 /* If n >= 64 -> loop64. */
+
+.Llt64:
+ /* Process n < 64 bytes. */
+ clgijl %r4,16,.Llt16 /* Jump away if n < 16. */
+ aghi %r4,-16
+ vl %v16,0(%r4,%r2)
+ vfeebs %v17,%v16,%v18
+ jno .Lfound0
+ clgijl %r4,16,.Llt16
+ aghi %r4,-16
+ vl %v16,0(%r4,%r2)
+ vfeebs %v17,%v16,%v18
+ jno .Lfound0
+ clgijl %r4,16,.Llt16
+ aghi %r4,-16
+ vl %v16,0(%r4,%r2)
+ vfeebs %v17,%v16,%v18
+ jno .Lfound0
+.Llt16:
+ clgfi %r4,0 /* if remaining bytes == 0, return NULL. */
+ locghie %r2,0
+ ber %r14
+
+ aghi %r4,-1 /* vll needs highest index. */
+ vll %v16,%r4,0(%r2) /* Load remaining bytes. */
+
+ /* Right-shift of v16 to mask bytes after highest index. */
+ lhi %r0,15
+ slr %r0,%r4 /* Compute byte count for vector shift right. */
+ sll %r0,3 /* Convert to bit count. */
+ vlvgb %v17,%r0,7
+ vsrlb %v16,%v16,%v17 /* Vector shift right by byte by number of bytes
+ specified in bits 1-4 of byte 7 in v17. */
+ j .Lfound_permute
+
+.Lfound48:
+ aghi %r4,16
+.Lfound32:
+ aghi %r4,16
+.Lfound16:
+ aghi %r4,16
+.Lfound0:
+ la %r2,0(%r4,%r2) /* Set pointer to start of v16. */
+ lghi %r4,15 /* Set highest index in v16 to last index. */
+.Lfound_permute:
+ /* Search for a c in v16 in reversed byte order. v16 contains %r4 + 1
+ bytes. If v16 was not fully loaded, the bytes are already
+ right shifted, so that the bytes in v16 can simply be reversed. */
+ vperm %v16,%v16,%v16,%v20 /* Permute v16 to reversed order. */
+ vfeeb %v16,%v16,%v18 /* Find c in reversed v16. */
+ vlgvb %r1,%v16,7 /* Index of c or 16 if not found. */
+
+ /* Return NULL if there is no c in loaded bytes. */
+ clrjh %r1,%r4,.Lnot_found
+
+ slgr %r4,%r1
+.Lfound_end:
+ la %r2,0(%r4,%r2) /* Return pointer to c. */
+ br %r14
+
+.Lnot_found:
+ lghi %r2,0
+ br %r14
+
+.Lpermute_mask:
+ .byte 0x0F,0x0E,0x0D,0x0C,0x0B,0x0A,0x09,0x08
+ .byte 0x07,0x06,0x05,0x04,0x03,0x02,0x01,0x00
+
+.Lloop64:
+ aghi %r4,-64
+ vl %v16,48(%r4,%r2) /* Load 16bytes of memory area. */
+ vfeebs %v17,%v16,%v18 /* Find c. */
+ jno .Lfound48 /* Jump away if c was found. */
+ vl %v16,32(%r4,%r2)
+ vfeebs %v17,%v16,%v18
+ jno .Lfound32
+ vl %v16,16(%r4,%r2)
+ vfeebs %v17,%v16,%v18
+ jno .Lfound16
+ vl %v16,0(%r4,%r2)
+ vfeebs %v17,%v16,%v18
+ jno .Lfound0
+
+ clgijhe %r4,64,.Lloop64 /* If n >= 64 -> loop64. */
+ j .Llt64
+END(__memrchr_vx)
+#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */
diff --git a/REORG.TODO/sysdeps/s390/multiarch/memrchr.c b/REORG.TODO/sysdeps/s390/multiarch/memrchr.c
new file mode 100644
index 0000000000..3a76c62376
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/multiarch/memrchr.c
@@ -0,0 +1,28 @@
+/* Multiple versions of memrchr.
+ Copyright (C) 2015-2017 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 && IS_IN (libc)
+# include <string.h>
+# include <ifunc-resolve.h>
+
+s390_vx_libc_ifunc (__memrchr)
+weak_alias (__memrchr, memrchr)
+
+#else
+# include <string/memrchr.c>
+#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)) */
diff --git a/REORG.TODO/sysdeps/s390/multiarch/rawmemchr-c.c b/REORG.TODO/sysdeps/s390/multiarch/rawmemchr-c.c
new file mode 100644
index 0000000000..12a64d338d
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/multiarch/rawmemchr-c.c
@@ -0,0 +1,34 @@
+/* Default rawmemchr implementation for S/390.
+ Copyright (C) 2015-2017 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 && IS_IN (libc)
+# include <string.h>
+
+# define RAWMEMCHR __rawmemchr_c
+# undef weak_alias
+# define weak_alias(a, b)
+# ifdef SHARED
+# undef libc_hidden_def
+# define libc_hidden_def(name) \
+ __hidden_ver1 (__rawmemchr_c, __GI___rawmemchr, __rawmemchr_c);
+# endif /* SHARED */
+
+extern __typeof (rawmemchr) __rawmemchr_c attribute_hidden;
+
+# include <string/rawmemchr.c>
+#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)) */
diff --git a/REORG.TODO/sysdeps/s390/multiarch/rawmemchr-vx.S b/REORG.TODO/sysdeps/s390/multiarch/rawmemchr-vx.S
new file mode 100644
index 0000000000..e2ac9a88e1
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/multiarch/rawmemchr-vx.S
@@ -0,0 +1,92 @@
+/* Vector optimized 32/64 bit S/390 version of rawmemchr.
+ Copyright (C) 2015-2017 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 && IS_IN (libc)
+
+# include "sysdep.h"
+# include "asm-syntax.h"
+
+ .text
+
+/* void *rawmemchr (const void *s, int c)
+ Scans memory for character c
+ and returns pointer to first c.
+
+ Register usage:
+ -r1=tmp
+ -r2=s
+ -r3=c
+ -r4=tmp
+ -r5=current_len
+ -v16=part of s
+ -v17=index of unequal
+ -v18=c replicated
+*/
+ENTRY(__rawmemchr_vx)
+ .machine "z13"
+ .machinemode "zarch_nohighgprs"
+
+ vlbb %v16,0(%r2),6 /* Load s until next 4k-byte boundary. */
+ lcbb %r1,0(%r2),6 /* Get bytes to 4k-byte boundary or 16. */
+
+ vlvgb %v18,%r3,0 /* Generate vector which elements are all c.
+ If c > 255, c will be truncated. */
+ vrepb %v18,%v18,0
+
+ vfeeb %v17,%v16,%v18 /* Vector find element equal. */
+ vlgvb %r5,%v17,7 /* Load byte index of character or zero. */
+ clrjl %r5,%r1,.Lend_found /* If found c is in loaded bytes, end. */
+
+ /* Align s to 16 byte. */
+ risbgn %r1,%r2,60,128+63,0 /* %r3 = bits 60-63 of %r2 'and' 15. */
+ lghi %r5,16
+ slr %r5,%r1 /* Compute bytes to 16bytes boundary. */
+
+ /* Find c in a 16byte aligned loop. */
+.Lloop:
+ vl %v16,0(%r5,%r2) /* Load s. */
+ vfeebs %v17,%v16,%v18 /* Vector find element equal. */
+ jno .Lcharacter /* Jump away if element found. */
+ vl %v16,16(%r5,%r2)
+ vfeebs %v17,%v16,%v18
+ jno .Lcharacter16
+ vl %v16,32(%r5,%r2)
+ vfeebs %v17,%v16,%v18
+ jno .Lcharacter32
+ vl %v16,48(%r5,%r2)
+ vfeebs %v17,%v16,%v18
+ jno .Lcharacter48
+
+ aghi %r5,64
+ j .Lloop /* No character found -> loop. */
+
+ /* Found character. */
+.Lcharacter48:
+ aghi %r5,16
+.Lcharacter32:
+ aghi %r5,16
+.Lcharacter16:
+ aghi %r5,16
+.Lcharacter:
+ vlgvb %r1,%v17,7 /* Load byte index of character. */
+ algr %r5,%r1
+.Lend_found:
+ la %r2,0(%r5,%r2) /* Return pointer to character. */
+ br %r14
+END(__rawmemchr_vx)
+#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */
diff --git a/REORG.TODO/sysdeps/s390/multiarch/rawmemchr.c b/REORG.TODO/sysdeps/s390/multiarch/rawmemchr.c
new file mode 100644
index 0000000000..74b0accb33
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/multiarch/rawmemchr.c
@@ -0,0 +1,31 @@
+/* Multiple versions of rawmemchr.
+ Copyright (C) 2015-2017 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 && IS_IN (libc)
+# define __rawmemchr __redirect___rawmemchr
+# include <string.h>
+# undef __rawmemchr
+# include <ifunc-resolve.h>
+
+s390_vx_libc_ifunc2_redirected (__redirect___rawmemchr, __rawmemchr
+ , __rawmemchr)
+weak_alias (__rawmemchr, rawmemchr)
+
+#else
+# include <string/rawmemchr.c>
+#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)) */
diff --git a/REORG.TODO/sysdeps/s390/multiarch/stpcpy-c.c b/REORG.TODO/sysdeps/s390/multiarch/stpcpy-c.c
new file mode 100644
index 0000000000..3818cfc24a
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/multiarch/stpcpy-c.c
@@ -0,0 +1,35 @@
+/* Default stpcpy implementation for S/390.
+ Copyright (C) 2015-2017 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 && IS_IN (libc)
+# define STPCPY __stpcpy_c
+# undef weak_alias
+# define weak_alias(a, b)
+# ifdef SHARED
+# undef libc_hidden_def
+# define libc_hidden_def(name) \
+ __hidden_ver1 (__stpcpy_c, __GI___stpcpy, __stpcpy_c);
+# undef libc_hidden_builtin_def
+# define libc_hidden_builtin_def(name) \
+ strong_alias (__stpcpy_c, __stpcpy_c_1); \
+ __hidden_ver1 (__stpcpy_c_1, __GI_stpcpy, __stpcpy_c_1);
+# endif /* SHARED */
+
+
+# include <string/stpcpy.c>
+#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */
diff --git a/REORG.TODO/sysdeps/s390/multiarch/stpcpy-vx.S b/REORG.TODO/sysdeps/s390/multiarch/stpcpy-vx.S
new file mode 100644
index 0000000000..a9e5be2e68
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/multiarch/stpcpy-vx.S
@@ -0,0 +1,104 @@
+/* Vector optimized 32/64 bit S/390 version of stpcpy.
+ Copyright (C) 2015-2017 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 && IS_IN (libc)
+
+# include "sysdep.h"
+# include "asm-syntax.h"
+
+ .text
+
+/* char * stpcpy (const char *dest, const char *src)
+ Copy string src to dest returning a pointer to its end.
+
+ Register usage:
+ -r1=tmp
+ -r2=dest and return value
+ -r3=src
+ -r4=tmp
+ -r5=current_len
+ -v16=part of src
+ -v17=index of zero
+ -v18=part of src
+*/
+ENTRY(__stpcpy_vx)
+ .machine "z13"
+ .machinemode "zarch_nohighgprs"
+
+ vlbb %v16,0(%r3),6 /* Load s until next 4k-byte boundary. */
+ lcbb %r1,0(%r3),6 /* Get bytes to 4k-byte boundary or 16. */
+
+ vfenezb %v17,%v16,%v16 /* Find element not equal with zero search. */
+ vlgvb %r5,%v17,7 /* Load zero index or 16 if not found. */
+ clrjl %r5,%r1,.Lfound_align /* If found zero within loaded bytes,
+ copy bytes before and return. */
+
+ /* Align s to 16 byte. */
+ risbgn %r4,%r3,60,128+63,0 /* %r3 = bits 60-63 of %r2 'and' 15. */
+ lghi %r5,15 /* current_len = 15. */
+ slr %r5,%r4 /* Compute highest index to 16byte boundary. */
+
+ vstl %v16,%r5,0(%r2) /* Copy loaded characters - no zero. */
+ ahi %r5,1 /* Start loop at next character. */
+
+ /* Find zero in 16byte aligned loop. */
+.Lloop:
+ vl %v16,0(%r5,%r3) /* Load s. */
+ vfenezbs %v17,%v16,%v16 /* Find element not equal with zero search. */
+ je .Lfound_v16_0 /* Jump away if zero was found. */
+ vl %v18,16(%r5,%r3) /* Load next part of s. */
+ vst %v16,0(%r5,%r2) /* Store previous part without zero to dst. */
+ vfenezbs %v17,%v18,%v18
+ je .Lfound_v18_16
+ vl %v16,32(%r5,%r3)
+ vst %v18,16(%r5,%r2)
+ vfenezbs %v17,%v16,%v16
+ je .Lfound_v16_32
+ vl %v18,48(%r5,%r3)
+ vst %v16,32(%r5,%r2)
+ vfenezbs %v17,%v18,%v18
+ je .Lfound_v18_48
+ vst %v18,48(%r5,%r2)
+
+ aghi %r5,64
+ j .Lloop /* No zero found -> loop. */
+
+.Lfound_v16_32:
+ aghi %r5,32
+.Lfound_v16_0:
+ la %r3,0(%r5,%r2)
+ vlgvb %r1,%v17,7 /* Load byte index of zero. */
+ vstl %v16,%r1,0(%r3) /* Copy characters including zero. */
+ la %r2,0(%r1,%r3) /* Return pointer to zero. */
+ br %r14
+
+.Lfound_v18_48:
+ aghi %r5,32
+.Lfound_v18_16:
+ la %r3,16(%r5,%r2)
+ vlgvb %r1,%v17,7 /* Load byte index of zero. */
+ vstl %v18,%r1,0(%r3) /* Copy characters including zero. */
+ la %r2,0(%r1,%r3) /* Return pointer to zero. */
+ br %r14
+
+.Lfound_align:
+ vstl %v16,%r5,0(%r2) /* Copy characters including zero. */
+ la %r2,0(%r5,%r2) /* Return pointer to zero. */
+ br %r14
+END(__stpcpy_vx)
+#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */
diff --git a/REORG.TODO/sysdeps/s390/multiarch/stpcpy.c b/REORG.TODO/sysdeps/s390/multiarch/stpcpy.c
new file mode 100644
index 0000000000..611cf0765e
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/multiarch/stpcpy.c
@@ -0,0 +1,35 @@
+/* Multiple versions of stpcpy.
+ Copyright (C) 2015-2017 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 && 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_redirected (__redirect___stpcpy, __stpcpy);
+weak_alias (__stpcpy, stpcpy)
+
+#else
+# include <string/stpcpy.c>
+#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)) */
diff --git a/REORG.TODO/sysdeps/s390/multiarch/stpncpy-c.c b/REORG.TODO/sysdeps/s390/multiarch/stpncpy-c.c
new file mode 100644
index 0000000000..95efa38895
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/multiarch/stpncpy-c.c
@@ -0,0 +1,28 @@
+/* Default stpncpy implementation for S/390.
+ Copyright (C) 2015-2017 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 && IS_IN (libc)
+# define STPNCPY __stpncpy_c
+# ifdef SHARED
+# undef libc_hidden_def
+# define libc_hidden_def(name) \
+ __hidden_ver1 (__stpncpy_c, __GI___stpncpy, __stpncpy_c);
+# endif /* SHARED */
+
+# include <string/stpncpy.c>
+#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */
diff --git a/REORG.TODO/sysdeps/s390/multiarch/stpncpy-vx.S b/REORG.TODO/sysdeps/s390/multiarch/stpncpy-vx.S
new file mode 100644
index 0000000000..869e8f7aef
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/multiarch/stpncpy-vx.S
@@ -0,0 +1,200 @@
+/* Vector optimized 32/64 bit S/390 version of stpncpy.
+ Copyright (C) 2015-2017 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 && IS_IN (libc)
+
+# include "sysdep.h"
+# include "asm-syntax.h"
+
+ .text
+
+/* char * stpncpy (char *dest, const char *src, size_t n)
+ Copies at most n characters of string src to dest
+ returning a pointer to its end or dest+n
+ if src is smaller than n.
+
+ Register usage:
+ -%r0 = return value
+ -%r1 = zero byte index
+ -%r2 = curr dst pointer
+ -%r3 = curr src pointer
+ -%r4 = n
+ -%r5 = current_len
+ -%r6 = loaded bytes
+ -%r7 = border, tmp
+*/
+ENTRY(__stpncpy_vx)
+ .machine "z13"
+ .machinemode "zarch_nohighgprs"
+
+# if !defined __s390x__
+ llgfr %r4,%r4
+# endif /* !defined __s390x__ */
+
+ clgfi %r4,0
+ ber %r14 /* Nothing to do, if n == 0. */
+
+ la %r0,0(%r4,%r2) /* Save destination pointer + n for return. */
+ vlvgp %v31,%r6,%r7 /* Save registers. */
+
+ vlbb %v16,0(%r3),6 /* Load s until next 4k-byte boundary. */
+ lcbb %r6,0(%r3),6 /* Get bytes to 4k-byte boundary or 16. */
+ llgfr %r6,%r6 /* Convert 32bit to 64bit. */
+
+ lghi %r5,0 /* current_len = 0. */
+
+ clgrjle %r4,%r6,.Lremaining_v16 /* If n <= loaded-bytes
+ -> process remaining. */
+
+ /* n > loaded-byte-count */
+ vfenezb %v17,%v16,%v16 /* Find element not equal with zero search. */
+ vlgvb %r1,%v17,7 /* Load zero index or 16 if not found. */
+ clrjl %r1,%r6,.Lfound_v16_store /* Found zero within loaded bytes,
+ copy and return. */
+
+ /* Align s to 16 byte. */
+ risbgn %r7,%r3,60,128+63,0 /* %r3 = bits 60-63 of %r2 'and' 15. */
+ lghi %r5,15 /* current_len = 15. */
+ slr %r5,%r7 /* Compute highest index to 16byte boundary. */
+
+ /* Zero not found and n > loaded-byte-count. */
+ vstl %v16,%r5,0(%r2) /* Copy loaded characters - no zero. */
+ ahi %r5,1 /* Start loop at next character. */
+
+ /* Now we are 16byte aligned, so we can load a full vreg
+ without page fault. */
+ lgr %r1,%r5 /* If %r5 + 64 < maxlen? -> loop64. */
+ aghi %r1,64
+ clgrjl %r1,%r4,.Lloop64
+
+ vl %v16,0(%r5,%r3) /* Load s. */
+ clgijl %r4,17,.Lremaining_v16 /* If n <= 16, process remaining
+ bytes. */
+.Llt64:
+ lgr %r7,%r4
+ slgfi %r7,16 /* border_len = n - 16. */
+
+ clgrjhe %r5,%r7,.Lremaining_v16 /* If current_len >= border
+ then process remaining bytes. */
+ vfenezbs %v17,%v16,%v16 /* Find element not equal with zero search. */
+ je .Lfound_v16 /* Jump away if zero was found. */
+ vl %v18,16(%r5,%r3) /* Load next part of s. */
+ vst %v16,0(%r5,%r2) /* Save previous part without zero to dst. */
+ aghi %r5,16
+
+ clgrjhe %r5,%r7,.Lremaining_v18
+ vfenezbs %v17,%v18,%v18
+ je .Lfound_v18
+ vl %v16,16(%r5,%r3)
+ vst %v18,0(%r5,%r2)
+ aghi %r5,16
+
+ clgrjhe %r5,%r7,.Lremaining_v16
+ vfenezbs %v17,%v16,%v16
+ je .Lfound_v16
+ vl %v18,16(%r5,%r3)
+ vst %v16,0(%r5,%r2)
+ aghi %r5,16
+
+.Lremaining_v18:
+ vlr %v16,%v18
+.Lremaining_v16:
+ /* v16 contains the remaining bytes [1...16].
+ Store remaining bytes and append string-termination. */
+ vfenezb %v17,%v16,%v16 /* Find element not equal with zero search. */
+ slgrk %r7,%r4,%r5 /* Remaining bytes = maxlen - current_len */
+ aghi %r7,-1 /* vstl needs highest index. */
+ la %r2,0(%r5,%r2) /* vstl has no index register. */
+ vlgvb %r1,%v17,7 /* Load zero index or 16 if not found. */
+ /* Zero in remaining bytes? -> jump away (zero-index <= max-index). */
+ clrjle %r1,%r7,.Lfound_v16_store
+ vstl %v16,%r7,0(%r2) /* Store remaining bytes without null
+ termination! */
+.Lend:
+ /* Restore saved registers. */
+ vlgvg %r6,%v31,0
+ vlgvg %r7,%v31,1
+ lgr %r2,%r0 /* Load saved dest-ptr. */
+ br %r14
+
+.Lfound_v16_32:
+ aghi %r5,32
+ j .Lfound_v16
+.Lfound_v18_48:
+ aghi %r5,32
+.Lfound_v18_16:
+ aghi %r5,16
+.Lfound_v18:
+ vlr %v16,%v18
+.Lfound_v16:
+ /* v16 contains a zero. Store remaining bytes to zero. current_len
+ has not reached border, thus checking for n is not needed! */
+ vlgvb %r1,%v17,7 /* Load byte index of zero. */
+ la %r2,0(%r5,%r2) /* vstl has no support for index-register. */
+.Lfound_v16_store:
+ vstl %v16,%r1,0(%r2) /* Copy characters including zero. */
+ /* Fill remaining bytes with zero - remaining count always > 0. */
+ algr %r5,%r1 /* Remaining bytes (=%r4) = ... */
+ slgr %r4,%r5 /* = maxlen - (currlen + zero_index + 1) */
+ la %r2,0(%r1,%r2) /* Pointer to zero. start filling beyond. */
+ lgr %r0,%r2 /* Save return-pointer to found zero. */
+ clgije %r4,1,.Lend /* Skip zero-filling, if found zero is last
+ possible character.
+ (1 is substracted from r4 below!). */
+ aghi %r4,-2 /* mvc with exrl needs count - 1.
+ (additional -1, see remaining bytes above) */
+ srlg %r6,%r4,8 /* Split into 256 byte blocks. */
+ ltgr %r6,%r6
+ je .Lzero_lt256
+.Lzero_loop256:
+ mvc 1(256,%r2),0(%r2) /* Fill 256 zeros at once. */
+ la %r2,256(%r2)
+ brctg %r6,.Lzero_loop256 /* Loop until all blocks are processed. */
+.Lzero_lt256:
+ exrl %r4,.Lmvc_lt256
+ j .Lend
+.Lmvc_lt256:
+ mvc 1(1,%r2),0(%r2)
+
+.Lloop64:
+ vl %v16,0(%r5,%r3)
+ vfenezbs %v17,%v16,%v16 /* Find element not equal with zero search. */
+ je .Lfound_v16 /* Jump away if zero was found. */
+ vl %v18,16(%r5,%r3) /* Load next part of s. */
+ vst %v16,0(%r5,%r2) /* Save previous part without zero to dst. */
+ vfenezbs %v17,%v18,%v18
+ je .Lfound_v18_16
+ vl %v16,32(%r5,%r3)
+ vst %v18,16(%r5,%r2)
+ vfenezbs %v17,%v16,%v16
+ je .Lfound_v16_32
+ vl %v18,48(%r5,%r3)
+ vst %v16,32(%r5,%r2)
+ vfenezbs %v17,%v18,%v18
+ je .Lfound_v18_48
+ vst %v18,48(%r5,%r2)
+
+ aghi %r5,64
+ lgr %r1,%r5 /* If %r5 + 64 < maxlen? -> loop64. */
+ aghi %r1,64
+ clgrjl %r1,%r4,.Lloop64
+
+ vl %v16,0(%r5,%r3) /* Load s. */
+ j .Llt64
+END(__stpncpy_vx)
+#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */
diff --git a/REORG.TODO/sysdeps/s390/multiarch/stpncpy.c b/REORG.TODO/sysdeps/s390/multiarch/stpncpy.c
new file mode 100644
index 0000000000..74f5ddc25e
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/multiarch/stpncpy.c
@@ -0,0 +1,32 @@
+/* Multiple versions of stpncpy.
+ Copyright (C) 2015-2017 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 && 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_redirected (__redirect___stpncpy, __stpncpy)
+weak_alias (__stpncpy, stpncpy)
+
+#else
+# include <string/stpncpy.c>
+#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)) */
diff --git a/REORG.TODO/sysdeps/s390/multiarch/strcat-c.c b/REORG.TODO/sysdeps/s390/multiarch/strcat-c.c
new file mode 100644
index 0000000000..0b88c1fc28
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/multiarch/strcat-c.c
@@ -0,0 +1,28 @@
+/* Default strcat implementation for S/390.
+ Copyright (C) 2015-2017 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 && IS_IN (libc)
+# define STRCAT __strcat_c
+# ifdef SHARED
+# undef libc_hidden_builtin_def
+# define libc_hidden_builtin_def(name) \
+ __hidden_ver1 (__strcat_c, __GI_strcat, __strcat_c);
+# endif /* SHARED */
+
+# include <string/strcat.c>
+#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */
diff --git a/REORG.TODO/sysdeps/s390/multiarch/strcat-vx.S b/REORG.TODO/sysdeps/s390/multiarch/strcat-vx.S
new file mode 100644
index 0000000000..65c19c21c8
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/multiarch/strcat-vx.S
@@ -0,0 +1,161 @@
+/* Vector optimized 32/64 bit S/390 version of strcat.
+ Copyright (C) 2015-2017 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 && IS_IN (libc)
+
+# include "sysdep.h"
+# include "asm-syntax.h"
+
+ .text
+
+/* char * strcat (const char *dest, const char *src)
+ Concatenate two strings.
+
+ Register usage:
+ -r0=saved dest pointer for return
+ -r1=tmp
+ -r2=dest
+ -r3=src
+ -r4=tmp
+ -r5=current_len
+ -v16=part of src
+ -v17=index of zero
+ -v18=part of src
+*/
+ENTRY(__strcat_vx)
+ .machine "z13"
+ .machinemode "zarch_nohighgprs"
+
+ lgr %r0,%r2 /* Save destination pointer for return. */
+
+ /* STRLEN
+ r1 = loaded bytes (tmp)
+ r4 = zero byte index (tmp)
+ r2 = dst
+ */
+ vlbb %v16,0(%r2),6 /* Load s until next 4k-byte boundary. */
+ lcbb %r1,0(%r2),6 /* Get bytes to 4k-byte boundary or 16. */
+
+ vfenezb %v16,%v16,%v16 /* Find element not equal with zero search. */
+ vlgvb %r5,%v16,7 /* Load zero index or 16 if not found. */
+ clrjl %r5,%r1,.Llen_end /* Found zero within loaded bytes, end. */
+
+ /* Align s to 16 byte. */
+ risbgn %r1,%r2,60,128+63,0 /* %r3 = bits 60-63 of %r2 'and' 15. */
+ lghi %r5,16 /* current_len = 16. */
+ slr %r5,%r1 /* Compute bytes to 16bytes boundary. */
+
+ /* Find zero in 16byte aligned loop. */
+.Llen_loop:
+ vl %v16,0(%r5,%r2) /* Load s. */
+ vfenezbs %v16,%v16,%v16 /* Find element not equal with zero search. */
+ je .Llen_found /* Jump away if zero was found. */
+ vl %v16,16(%r5,%r2)
+ vfenezbs %v16,%v16,%v16
+ je .Llen_found16
+ vl %v16,32(%r5,%r2)
+ vfenezbs %v16,%v16,%v16
+ je .Llen_found32
+ vl %v16,48(%r5,%r2)
+ vfenezbs %v16,%v16,%v16
+ je .Llen_found48
+
+ aghi %r5,64
+ j .Llen_loop /* No zero -> loop. */
+
+.Llen_found48:
+ aghi %r5,16
+.Llen_found32:
+ aghi %r5,16
+.Llen_found16:
+ aghi %r5,16
+.Llen_found:
+ vlgvb %r4,%v16,7 /* Load byte index of zero. */
+ algr %r5,%r4
+
+.Llen_end:
+ /* STRCPY
+ %r1 = loaded bytes (tmp)
+ %r4 = zero byte index (tmp)
+ %r3 = curr src pointer
+ %r2 = curr dst pointer
+ */
+ la %r2,0(%r5,%r2) /* strcpy at end of dst-string. */
+
+ vlbb %v16,0(%r3),6 /* Load s until next 4k-byte boundary. */
+ lcbb %r1,0(%r3),6 /* Get bytes to 4k-byte boundary or 16. */
+
+ vfenezb %v17,%v16,%v16 /* Find element not equal with zero search. */
+ vlgvb %r5,%v17,7 /* Load zero index or 16 if not found. */
+ clrjl %r5,%r1,.Lcpy_found_align /* If found zero within loaded bytes,
+ copy bytes before and return. */
+
+ /* Align s to 16 byte. */
+ risbgn %r4,%r3,60,128+63,0 /* %r3 = bits 60-63 of %r2 'and' 15. */
+ lghi %r5,15 /* current_len = 15. */
+ slr %r5,%r4 /* Compute highest index to 16byte boundary. */
+
+ vstl %v16,%r5,0(%r2) /* Copy loaded characters - no zero. */
+ ahi %r5,1 /* Start loop at next character. */
+
+ /* Find zero in 16byte aligned loop. */
+.Lcpy_loop:
+ vl %v16,0(%r5,%r3) /* Load s. */
+ vfenezbs %v17,%v16,%v16 /* Find element not equal with zero search. */
+ je .Lcpy_found_v16_0 /* Jump away if zero was found. */
+ vl %v18,16(%r5,%r3)/* Load next part of s. */
+ vst %v16,0(%r5,%r2) /* Store previous part without zero to dst. */
+ vfenezbs %v17,%v18,%v18
+ je .Lcpy_found_v18_16
+ vl %v16,32(%r5,%r3)
+ vst %v18,16(%r5,%r2)
+ vfenezbs %v17,%v16,%v16
+ je .Lcpy_found_v16_32
+ vl %v18,48(%r5,%r3)
+ vst %v16,32(%r5,%r2)
+ vfenezbs %v17,%v18,%v18
+ je .Lcpy_found_v18_48
+ vst %v18,48(%r5,%r2)
+
+ aghi %r5,64
+ j .Lcpy_loop /* No zero -> loop. */
+
+.Lcpy_found_v16_32:
+ aghi %r5,32
+.Lcpy_found_v16_0:
+ la %r4,0(%r5,%r2)
+ vlgvb %r1,%v17,7 /* Load byte index of zero. */
+ vstl %v16,%r1,0(%r4) /* Copy characters including zero. */
+ lgr %r2,%r0 /* Load saved dest-ptr. */
+ br %r14
+
+.Lcpy_found_v18_48:
+ aghi %r5,32
+.Lcpy_found_v18_16:
+ la %r4,16(%r5,%r2)
+ vlgvb %r1,%v17,7 /* Load byte index of zero. */
+ vstl %v18,%r1,0(%r4) /* Copy characters including zero. */
+ lgr %r2,%r0 /* Load saved dest-ptr. */
+ br %r14
+
+.Lcpy_found_align:
+ vstl %v16,%r5,0(%r2) /* Copy characters including zero. */
+ lgr %r2,%r0 /* Load saved dest-ptr. */
+ br %r14
+END(__strcat_vx)
+#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */
diff --git a/REORG.TODO/sysdeps/s390/multiarch/strcat.c b/REORG.TODO/sysdeps/s390/multiarch/strcat.c
new file mode 100644
index 0000000000..d1c5d4c55e
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/multiarch/strcat.c
@@ -0,0 +1,29 @@
+/* Multiple versions of strcat.
+ Copyright (C) 2015-2017 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 && IS_IN (libc)
+# define strcat __redirect_strcat
+# include <string.h>
+# undef strcat
+# include <ifunc-resolve.h>
+
+s390_vx_libc_ifunc2_redirected (__redirect_strcat, __strcat, strcat)
+
+#else
+# include <string/strcat.c>
+#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)) */
diff --git a/REORG.TODO/sysdeps/s390/multiarch/strchr-c.c b/REORG.TODO/sysdeps/s390/multiarch/strchr-c.c
new file mode 100644
index 0000000000..636d8dd016
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/multiarch/strchr-c.c
@@ -0,0 +1,29 @@
+/* Default strchr implementation for S/390.
+ Copyright (C) 2015-2017 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 && IS_IN (libc)
+# define STRCHR __strchr_c
+# undef weak_alias
+# ifdef SHARED
+# undef libc_hidden_builtin_def
+# define libc_hidden_builtin_def(name) \
+ __hidden_ver1 (__strchr_c, __GI_strchr, __strchr_c);
+# endif /* SHARED */
+
+# include <string/strchr.c>
+#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */
diff --git a/REORG.TODO/sysdeps/s390/multiarch/strchr-vx.S b/REORG.TODO/sysdeps/s390/multiarch/strchr-vx.S
new file mode 100644
index 0000000000..bd2109bc05
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/multiarch/strchr-vx.S
@@ -0,0 +1,100 @@
+/* Vector optimized 32/64 bit S/390 version of strchr.
+ Copyright (C) 2015-2017 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 && IS_IN (libc)
+
+# include "sysdep.h"
+# include "asm-syntax.h"
+
+ .text
+
+/* char *strchr (const char *s, int c)
+ Locate character in string.
+
+ Register usage:
+ -r1=tmp
+ -r2=s
+ -r3=c
+ -r4=tmp
+ -r5=current_len
+ -v16=part of s
+ -v17=index of unequal
+ -v18=replicated c
+*/
+ENTRY(__strchr_vx)
+ .machine "z13"
+ .machinemode "zarch_nohighgprs"
+
+ vlbb %v16,0(%r2),6 /* Load s until next 4k-byte boundary. */
+ lcbb %r1,0(%r2),6 /* Get bytes to 4k-byte boundary or 16. */
+
+ lghi %r5,0 /* current_len = 0. */
+
+ vlvgb %v18,%r3,0 /* Generate vector which elements are all c.
+ If c > 255, c will be truncated. */
+ vrepb %v18,%v18,0
+
+ vfeezbs %v16,%v16,%v18 /* Find element equal with zero search. */
+ vlgvb %r4,%v16,7 /* Load byte index of character or zero. */
+ clrjl %r4,%r1,.Lfound /* Return if c/zero is in loaded bytes. */
+
+ /* Align s to 16 byte. */
+ risbgn %r4,%r2,60,128+63,0 /* %r3 = bits 60-63 of %r2 'and' 15. */
+ lghi %r5,16 /* current_len = 16. */
+ slr %r5,%r4 /* Compute bytes to 16bytes boundary. */
+
+ /* Find c/zero in 16 byte aligned loop */
+.Lloop:
+ vl %v16,0(%r5,%r2) /* Load s. */
+ vfeezbs %v16,%v16,%v18 /* Find element equal with zero search. */
+ jno .Lfound /* Found c/zero (cc=0|1|2). */
+ vl %v16,16(%r5,%r2)
+ vfeezbs %v16,%v16,%v18
+ jno .Lfound16
+ vl %v16,32(%r5,%r2)
+ vfeezbs %v16,%v16,%v18
+ jno .Lfound32
+ vl %v16,48(%r5,%r2)
+ vfeezbs %v16,%v16,%v18
+ jno .Lfound48
+
+ aghi %r5,64
+ j .Lloop /* No character and no zero -> loop. */
+
+.Lfound48:
+ la %r5,16(%r5) /* Use la since aghi would clobber cc. */
+.Lfound32:
+ la %r5,16(%r5)
+.Lfound16:
+ la %r5,16(%r5)
+.Lfound:
+ je .Lzero /* Found zero, but no c before that zero. */
+
+.Lcharacter:
+ vlgvb %r4,%v16,7 /* Load byte index of character. */
+ algr %r5,%r4
+ la %r2,0(%r5,%r2) /* Return pointer to character. */
+ br %r14
+
+.Lzero:
+ llgcr %r3,%r3 /* char c_char = (char) c. */
+ clije %r3,0,.Lcharacter /* Found zero and c is zero. */
+ lghi %r2,0 /* Return null if character not found. */
+ br %r14
+END(__strchr_vx)
+#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */
diff --git a/REORG.TODO/sysdeps/s390/multiarch/strchr.c b/REORG.TODO/sysdeps/s390/multiarch/strchr.c
new file mode 100644
index 0000000000..3df90aff14
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/multiarch/strchr.c
@@ -0,0 +1,32 @@
+/* Multiple versions of strchr.
+ Copyright (C) 2015-2017 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 && 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_redirected (__redirect_strchr, __strchr, strchr)
+weak_alias (strchr, index)
+
+#else
+# include <string/strchr.c>
+#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)) */
diff --git a/REORG.TODO/sysdeps/s390/multiarch/strchrnul-c.c b/REORG.TODO/sysdeps/s390/multiarch/strchrnul-c.c
new file mode 100644
index 0000000000..cd43d3a450
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/multiarch/strchrnul-c.c
@@ -0,0 +1,26 @@
+/* Default strchrnul implementation for S/390.
+ Copyright (C) 2015-2017 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 && IS_IN (libc)
+# define STRCHRNUL __strchrnul_c
+# define __strchrnul STRCHRNUL
+# undef weak_alias
+# define weak_alias(name, alias)
+
+# include <string/strchrnul.c>
+#endif
diff --git a/REORG.TODO/sysdeps/s390/multiarch/strchrnul-vx.S b/REORG.TODO/sysdeps/s390/multiarch/strchrnul-vx.S
new file mode 100644
index 0000000000..cfc8cbf6e9
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/multiarch/strchrnul-vx.S
@@ -0,0 +1,93 @@
+/* Vector optimized 32/64 bit S/390 version of strchrnul.
+ Copyright (C) 2015-2017 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 && IS_IN (libc)
+
+# include "sysdep.h"
+# include "asm-syntax.h"
+
+ .text
+
+/* char *strchrnul (const char *s, int c)
+ Returns pointer to first c or to \0 if c not found.
+
+ Register usage:
+ -r1=tmp
+ -r2=s and return pointer
+ -r3=c
+ -r4=tmp
+ -r5=current_len
+ -v16=part of s
+ -v18=vector with c replicated in every byte
+*/
+ENTRY(__strchrnul_vx)
+ .machine "z13"
+ .machinemode "zarch_nohighgprs"
+
+ vlbb %v16,0(%r2),6 /* Load s until next 4k-byte boundary. */
+ lcbb %r1,0(%r2),6 /* Get bytes to 4k-byte boundary or 16. */
+
+ lghi %r5,0 /* current_len = 0. */
+
+ vlvgb %v18,%r3,0 /* Generate vector which elements are all c.
+ If c > 255, c will be truncated. */
+ vrepb %v18,%v18,0
+
+ vfeezbs %v16,%v16,%v18 /* Find element equal with zero search. */
+ vlgvb %r4,%v16,7 /* Load byte index of character or zero. */
+ clrjl %r4,%r1,.Lfound /* Return if c/zero is in loaded bytes. */
+
+ /* Align s to 16 byte. */
+ risbgn %r4,%r2,60,128+63,0 /* %r3 = bits 60-63 of %r2 'and' 15. */
+ lghi %r5,16 /* current_len = 16. */
+ slr %r5,%r4 /* Compute bytes to 16bytes boundary. */
+
+ /* Find c/zero in 16byte aligned loop */
+.Lloop:
+ vl %v16,0(%r5,%r2) /* Load s */
+ vfeezbs %v16,%v16,%v18 /* Find element equal with zero search. */
+ jno .Lfound /* Found c/zero (cc=0|1|2). */
+ vl %v16,16(%r5,%r2)
+ vfeezbs %v16,%v16,%v18
+ jno .Lfound16
+ vl %v16,32(%r5,%r2)
+ vfeezbs %v16,%v16,%v18
+ jno .Lfound32
+ vl %v16,48(%r5,%r2)
+ vfeezbs %v16,%v16,%v18
+ jno .Lfound48
+
+ aghi %r5,64
+ j .Lloop /* No character and no zero -> loop. */
+
+ /* Found character or zero */
+.Lfound48:
+ aghi %r5,16
+.Lfound32:
+ aghi %r5,16
+.Lfound16:
+ aghi %r5,16
+.Lfound:
+ vlgvb %r1,%v16,7 /* Load byte index of character. */
+ algr %r5,%r1
+ la %r2,0(%r5,%r2) /* Return pointer to character. */
+
+.Lend:
+ br %r14
+END(__strchrnul_vx)
+#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */
diff --git a/REORG.TODO/sysdeps/s390/multiarch/strchrnul.c b/REORG.TODO/sysdeps/s390/multiarch/strchrnul.c
new file mode 100644
index 0000000000..9447523f25
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/multiarch/strchrnul.c
@@ -0,0 +1,28 @@
+/* Multiple versions of strchrnul.
+ Copyright (C) 2015-2017 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 && IS_IN (libc)
+# include <string.h>
+# include <ifunc-resolve.h>
+
+s390_vx_libc_ifunc (__strchrnul)
+weak_alias (__strchrnul, strchrnul)
+
+#else
+# include <string/strchrnul.c>
+#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)) */
diff --git a/REORG.TODO/sysdeps/s390/multiarch/strcmp-vx.S b/REORG.TODO/sysdeps/s390/multiarch/strcmp-vx.S
new file mode 100644
index 0000000000..640e4d6b4c
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/multiarch/strcmp-vx.S
@@ -0,0 +1,116 @@
+/* Vector optimized 32/64 bit S/390 version of strcmp.
+ Copyright (C) 2015-2017 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 && IS_IN (libc)
+
+# include "sysdep.h"
+# include "asm-syntax.h"
+
+ .text
+
+/* int strcmp (const char *s1, const char *s2)
+ Compare two strings
+
+ Register usage:
+ -r1=loaded byte count s1
+ -r2=s1
+ -r3=s2
+ -r4=loaded byte coutn s2, tmp
+ -r5=current_len
+ -v16=part of s1
+ -v17=part of s2
+ -v18=index of unequal
+*/
+ENTRY(__strcmp_vx)
+ .machine "z13"
+ .machinemode "zarch_nohighgprs"
+
+ lghi %r5,0 /* current_len = 0. */
+
+.Lloop:
+ vlbb %v16,0(%r5,%r2),6 /* Load s1 to block boundary. */
+ vlbb %v17,0(%r5,%r3),6 /* Load s2 to block boundary. */
+ lcbb %r1,0(%r5,%r2),6 /* Get loaded byte count of s1. */
+ jo .Llt16_1 /* Jump away if vr is not fully loaded. */
+ lcbb %r4,0(%r5,%r3),6
+ jo .Llt16_2 /* Jump away if vr is not fully loaded. */
+ /* Both vrs are fully loaded. */
+ aghi %r5,16
+ vfenezbs %v18,%v16,%v17 /* Compare not equal with zero search. */
+ jno .Lfound
+
+ vlbb %v16,0(%r5,%r2),6
+ vlbb %v17,0(%r5,%r3),6
+ lcbb %r1,0(%r5,%r2),6
+ jo .Llt16_1
+ lcbb %r4,0(%r5,%r3),6
+ jo .Llt16_2
+ aghi %r5,16
+ vfenezbs %v18,%v16,%v17
+ jno .Lfound
+
+ vlbb %v16,0(%r5,%r2),6
+ vlbb %v17,0(%r5,%r3),6
+ lcbb %r1,0(%r5,%r2),6
+ jo .Llt16_1
+ lcbb %r4,0(%r5,%r3),6
+ jo .Llt16_2
+ aghi %r5,16
+ vfenezbs %v18,%v16,%v17
+ jno .Lfound
+
+ vlbb %v16,0(%r5,%r2),6
+ vlbb %v17,0(%r5,%r3),6
+ lcbb %r1,0(%r5,%r2),6
+ jo .Llt16_1
+ lcbb %r4,0(%r5,%r3),6
+ jo .Llt16_2
+ aghi %r5,16
+ vfenezbs %v18,%v16,%v17
+ jno .Lfound
+ j .Lloop
+
+.Llt16_1:
+ lcbb %r4,0(%r5,%r3),6 /* Get loaded byte count of s2. */
+.Llt16_2:
+ clr %r1,%r4
+ locrh %r1,%r4 /* Get minimum of bytes loaded in s1/2. */
+ algfr %r5,%r1 /* Add smallest loaded bytes to current_len. */
+ vfenezbs %v18,%v16,%v17 /* Compare not equal with zero search. */
+ vlgvb %r4,%v18,7 /* Get not equal index or 16 if all equal. */
+ clrjl %r4,%r1,.Lfound /* Jump away if miscompare is within loaded
+ bytes. */
+ j .Lloop
+
+.Lfound:
+ je .Lend_equal
+ lghi %r2,1
+ lghi %r1,-1
+ locgrl %r2,%r1
+ br %r14
+.Lend_equal:
+ lghi %r2,0
+ br %r14
+END(__strcmp_vx)
+
+# define strcmp __strcmp_c
+# undef libc_hidden_builtin_def
+# define libc_hidden_builtin_def(name) strong_alias(__strcmp_c, __GI_strcmp)
+#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */
+
+#include <strcmp.S>
diff --git a/REORG.TODO/sysdeps/s390/multiarch/strcmp.c b/REORG.TODO/sysdeps/s390/multiarch/strcmp.c
new file mode 100644
index 0000000000..19e6d02597
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/multiarch/strcmp.c
@@ -0,0 +1,29 @@
+/* Multiple versions of strcmp.
+ Copyright (C) 2015-2017 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 && 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)
+
+#endif
diff --git a/REORG.TODO/sysdeps/s390/multiarch/strcpy-vx.S b/REORG.TODO/sysdeps/s390/multiarch/strcpy-vx.S
new file mode 100644
index 0000000000..1ae9860a01
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/multiarch/strcpy-vx.S
@@ -0,0 +1,109 @@
+/* Vector optimized 32/64 bit S/390 version of strcpy.
+ Copyright (C) 2015-2017 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 && IS_IN (libc)
+
+# include "sysdep.h"
+# include "asm-syntax.h"
+
+ .text
+
+/* char * strcpy (const char *dest, const char *src)
+ Copy string src to dest.
+
+ Register usage:
+ -r1=tmp
+ -r2=dest and return_value
+ -r3=src
+ -r4=tmp
+ -r5=current_len
+ -v16=part of src
+ -v17=index of zero
+ -v18=part of src
+*/
+ENTRY(__strcpy_vx)
+ .machine "z13"
+ .machinemode "zarch_nohighgprs"
+
+ vlbb %v16,0(%r3),6 /* Load s until next 4k-byte boundary. */
+ lcbb %r1,0(%r3),6 /* Get bytes to 4k-byte boundary or 16. */
+
+ vfenezb %v17,%v16,%v16 /* Find element not equal with zero search. */
+ vlgvb %r5,%v17,7 /* Load zero index or 16 if not found. */
+ clrjl %r5,%r1,.Lfound_align /* If found zero within loaded bytes,
+ copy bytes before and return. */
+
+ /* Align s to 16 byte. */
+ risbgn %r4,%r3,60,128+63,0 /* %r3 = bits 60-63 of %r2 'and' 15. */
+ lghi %r5,15 /* current_len = 15. */
+ slr %r5,%r4 /* Compute highest index to 16byte boundary. */
+
+ vstl %v16,%r5,0(%r2) /* Copy loaded characters - no zero. */
+ ahi %r5,1 /* Start loop at next character. */
+
+ /* Find zero in 16byte aligned loop. */
+.Lloop:
+ vl %v16,0(%r5,%r3) /* Load s. */
+ vfenezbs %v17,%v16,%v16 /* Find element not equal with zero search. */
+ je .Lfound_v16_0 /* Jump away if zero was found. */
+ vl %v18,16(%r5,%r3)/* Load next part of s. */
+ vst %v16,0(%r5,%r2) /* Store previous part without zero to dst. */
+ vfenezbs %v17,%v18,%v18
+ je .Lfound_v18_16
+ vl %v16,32(%r5,%r3)
+ vst %v18,16(%r5,%r2)
+ vfenezbs %v17,%v16,%v16
+ je .Lfound_v16_32
+ vl %v18,48(%r5,%r3)
+ vst %v16,32(%r5,%r2)
+ vfenezbs %v17,%v18,%v18
+ je .Lfound_v18_48
+ vst %v18,48(%r5,%r2)
+
+ aghi %r5,64
+ j .Lloop /* No zero found -> loop. */
+
+.Lfound_v16_32:
+ aghi %r5,32
+.Lfound_v16_0:
+ la %r3,0(%r5,%r2)
+ vlgvb %r4,%v17,7 /* Load byte index of zero. */
+ vstl %v16,%r4,0(%r3) /* Store characters including zero. */
+ br %r14
+
+.Lfound_v18_48:
+ aghi %r5,32
+.Lfound_v18_16:
+ la %r3,16(%r5,%r2)
+ vlgvb %r4,%v17,7 /* Load byte index of zero. */
+ vstl %v18,%r4,0(%r3) /* Store characters including zero. */
+ br %r14
+
+.Lfound_align:
+ vstl %v16,%r5,0(%r2) /* Copy characters including zero. */
+ br %r14
+END(__strcpy_vx)
+
+/* Use mvst-strcpy-implementation as default implementation. */
+# define strcpy __strcpy_c
+# undef libc_hidden_builtin_def
+# define libc_hidden_builtin_def(name) strong_alias(__strcpy_c, __GI_strcpy)
+#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */
+
+/* Include mvst-strcpy-implementation in s390-32/s390-64 subdirectory. */
+#include <strcpy.S>
diff --git a/REORG.TODO/sysdeps/s390/multiarch/strcpy.c b/REORG.TODO/sysdeps/s390/multiarch/strcpy.c
new file mode 100644
index 0000000000..5a5107690b
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/multiarch/strcpy.c
@@ -0,0 +1,27 @@
+/* Multiple versions of strcpy.
+ Copyright (C) 2015-2017 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 && IS_IN (libc)
+# define strcpy __redirect_strcpy
+# include <string.h>
+# undef strcpy
+# include <ifunc-resolve.h>
+
+s390_vx_libc_ifunc2_redirected (__redirect_strcpy, __strcpy, strcpy)
+
+#endif
diff --git a/REORG.TODO/sysdeps/s390/multiarch/strcspn-c.c b/REORG.TODO/sysdeps/s390/multiarch/strcspn-c.c
new file mode 100644
index 0000000000..f67e30d031
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/multiarch/strcspn-c.c
@@ -0,0 +1,28 @@
+/* Default strcspn implementation for S/390.
+ Copyright (C) 2015-2017 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 && IS_IN (libc)
+# define STRCSPN __strcspn_c
+# ifdef SHARED
+# undef libc_hidden_builtin_def
+# define libc_hidden_builtin_def(name) \
+ __hidden_ver1 (__strcspn_c, __GI_strcspn, __strcspn_c);
+# endif /* SHARED */
+
+# include <string/strcspn.c>
+#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */
diff --git a/REORG.TODO/sysdeps/s390/multiarch/strcspn-vx.S b/REORG.TODO/sysdeps/s390/multiarch/strcspn-vx.S
new file mode 100644
index 0000000000..840d94ab10
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/multiarch/strcspn-vx.S
@@ -0,0 +1,281 @@
+/* Vector optimized 32/64 bit S/390 version of strcspn.
+ Copyright (C) 2015-2017 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 && IS_IN (libc)
+
+# include "sysdep.h"
+# include "asm-syntax.h"
+
+ .text
+
+/* size_t strcspn (const char *s, const char * reject)
+ The strcspn() function calculates the length of the initial segment
+ of s which consists entirely of characters not in reject.
+
+ This method checks the length of reject string. If it fits entirely
+ in one vector register, a fast algorithm is used, which does not need
+ to check multiple parts of accept-string. Otherwise a slower full
+ check of accept-string is used.
+
+ register overview:
+ r3: pointer to start of reject-string
+ r2: pointer to start of search-string
+ r0: loaded byte count of vlbb search-string
+ r4: found byte index
+ r1: current return len
+ v16: search-string
+ v17: reject-string
+ v18: temp-vreg
+
+ ONLY FOR SLOW:
+ v19: first reject-string
+ v20: zero for preparing acc-vector
+ v21: global mask; 1 indicates a match between
+ search-string-vreg and any reject-character
+ v22: current mask; 1 indicates a match between
+ search-string-vreg and any reject-character in current acc-vreg
+ v24: one for result-checking of former string-part
+ v30, v31: for re-/storing registers r6, r8, r9
+ r5: current len of reject-string
+ r6: zero-index in search-string or 16 if no zero
+ or min(zero-index, loaded byte count)
+ r8: >0, if former reject-string-part contains a zero,
+ otherwise =0;
+ r9: loaded byte count of vlbb reject-string
+*/
+ENTRY(__strcspn_vx)
+ .machine "z13"
+ .machinemode "zarch_nohighgprs"
+
+ /*
+ Check if reject-string fits in one vreg:
+ ----------------------------------------
+ */
+ vlbb %v17,0(%r3),6 /* Load reject. */
+ lghi %r1,0 /* Zero out current len. */
+ lcbb %r0,0(%r3),6
+ jo .Lcheck_onbb /* Special case if reject
+ lays on block-boundary. */
+.Lcheck_notonbb:
+ vistrbs %v17,%v17 /* Fill with zeros after first zero. */
+ je .Lfast /* Zero found -> reject fits in one vreg. */
+ j .Lslow /* No zero -> reject exceeds one vreg. */
+
+
+.Lcheck_onbb:
+ /* Reject lays on block-boundary. */
+ vfenezb %v18,%v17,%v17 /* Search zero in loaded reject bytes. */
+ vlgvb %r4,%v18,7 /* Get index of zero or 16 if not found. */
+ clrjl %r4,%r0,.Lcheck_notonbb /* Zero index < loaded bytes count ->
+ Reject fits in one vreg;
+ Fill with zeros and proceed
+ with FAST. */
+ vl %v17,0(%r3) /* Load reject, which exceeds loaded bytes. */
+ j .Lcheck_notonbb /* Check if reject fits in one vreg. */
+
+
+ /*
+ Search s for reject in one vreg
+ -------------------------------
+ */
+.Lfast:
+ /* Complete reject-string in v17 and remaining bytes are zero. */
+
+ vlbb %v16,0(%r2),6 /* Load s until next 4k-byte boundary. */
+ lcbb %r0,0(%r2),6 /* Get bytes to 4k-byte boundary or 16. */
+
+ vfaezbs %v18,%v16,%v17,0 /* Find first element in v16
+ unequal to any in v17
+ or first zero element. */
+
+ vlgvb %r4,%v18,7 /* Load byte index of found element. */
+ clrjl %r4,%r0,.Lfast_loop_found2 /* If found index is within loaded
+ bytes, return with found element
+ index (=equal count). */
+
+ /* Align s to 16 byte. */
+ risbgn %r4,%r2,60,128+63,0 /* %r3 = bits 60-63 of %r2 'and' 15. */
+ lghi %r1,16 /* current_len = 16. */
+ slr %r1,%r4 /* Compute bytes to 16bytes boundary. */
+
+ /* Process s in 16byte aligned loop. */
+.Lfast_loop:
+ vl %v16,0(%r1,%r2) /* Load search-string. */
+ vfaezbs %v18,%v16,%v17,0 /* Find first element in v16 equal to any
+ in v17 or first zero element. */
+ jno .Lfast_loop_found
+
+ vl %v16,16(%r1,%r2)
+ vfaezbs %v18,%v16,%v17,0
+ jno .Lfast_loop_found16
+
+ vl %v16,32(%r1,%r2)
+ vfaezbs %v18,%v16,%v17,0
+ jno .Lfast_loop_found32
+
+ vl %v16,48(%r1,%r2)
+ vfaezbs %v18,%v16,%v17,0
+ jno .Lfast_loop_found48
+
+ aghi %r1,64
+ j .Lfast_loop /* Loop if no element was unequal to reject
+ and not zero. */
+
+ /* Found equal or zero element. */
+.Lfast_loop_found48:
+ aghi %r1,16
+.Lfast_loop_found32:
+ aghi %r1,16
+.Lfast_loop_found16:
+ aghi %r1,16
+.Lfast_loop_found:
+ vlgvb %r4,%v18,7 /* Load byte index of found element or zero. */
+.Lfast_loop_found2:
+ algrk %r2,%r1,%r4 /* Add found index to current len. */
+ br %r14
+
+
+
+ /*
+ Search s for reject in multiple vregs
+ -------------------------------------
+ */
+.Lslow:
+ /* Save registers. */
+ vlvgg %v30,%r6,0
+ vlvgp %v31,%r8,%r9
+
+ /* Reject in v17 without zero. */
+ vlr %v19,%v17 /* Save first acc-part for a fast reload. */
+ vzero %v20 /* Zero for preparing acc-vector. */
+ vone %v24 /* One for checking result of former
+ string-part. */
+
+ /* Align s to 16 byte. */
+ risbg %r4,%r2,60,128+63,0 /* Test if s is aligned and
+ %r4 = bits 60-63 'and' 15. */
+ je .Lslow_loop_str /* If s is aligned, loop aligned. */
+ lghi %r0,15
+ slr %r0,%r4 /* Compute highest index to load (15-x). */
+ vll %v16,%r0,0(%r2) /* Load up to 16 byte boundary (vll needs
+ highest index, remaining bytes are 0). */
+ ahi %r0,1 /* Work with loaded byte count. */
+ vzero %v21 /* Zero out global mask. */
+ lghi %r5,0 /* Set current len of reject-string to zero. */
+ vfenezb %v18,%v16,%v16 /* Find zero in current string-part. */
+ lghi %r8,0 /* There is no zero in first reject-part. */
+ vlgvb %r6,%v18,7 /* Load byte index of zero or 16 if no zero. */
+ clije %r6,0,.Lslow_end /* If first element is zero -> return 0. */
+ clr %r0,%r6 /* cc==1 if loaded byte count < zero-index. */
+ locrl %r6,%r0 /* Load on cc==1; zero-index = lbc. */
+ j .Lslow_loop_acc
+
+
+ /* Process s in 16byte aligned loop. */
+.Lslow_next_str:
+ /* Check results of former processed str-part. */
+ vfeeb %v18,%v21,%v24 /* Find first equal match in global mask
+ (ones in element). */
+ vlgvb %r4,%v18,7 /* Get index of first one (=equal) or 16. */
+ /* Equal-index < min(zero-index, loaded byte count)
+ -> Return pointer to equal element. */
+ clrjl %r4,%r6,.Lslow_index_found
+ /* Zero-index < loaded byte count
+ -> Former str-part was last str-part
+ -> Return null */
+ clrjl %r6,%r0,.Lslow_end_not_found
+
+ /* All elements are zero (=no match) -> Proceed with next str-part. */
+ vlr %v17,%v19 /* Load first part of reject (no zero). */
+ algfr %r1,%r0 /* Add loaded byte count to current len. */
+
+.Lslow_loop_str:
+ vl %v16,0(%r1,%r2) /* Load search-string. */
+ lghi %r0,16 /* Loaded byte count is 16. */
+ vzero %v21 /* Zero out global mask. */
+ lghi %r5,0 /* Set current len of reject to zero. */
+ vfenezb %v18,%v16,%v16 /* Find zero in current string-part. */
+ lghi %r8,0 /* There is no zero in first reject-part. */
+ vlgvb %r6,%v18,7 /* Load byte index of zero or 16 if no zero. */
+ clije %r6,0,.Lslow_end /* If first element is zero (end of string)
+ -> Return current length. */
+
+.Lslow_loop_acc:
+ vfaeb %v22,%v16,%v17,4 /* Create matching-mask (1 in mask ->
+ Character matches any rejected character in
+ this reject-string-part) IN=0, RT=1. */
+ vlgvb %r4,%v22,0 /* Get result of first element. */
+ /* First element is equal to any rejected characters?
+ (all other parts of reject cannot lead to a match before this one)
+ -> Return current len, which is pointing to this element. */
+ clijh %r4,0,.Lslow_end
+ vo %v21,%v21,%v22 /* Global-mask = global-|matching-mask. */
+ /* Proceed with next acc until end of acc is reached. */
+
+
+.Lslow_next_acc:
+ clijh %r8,0,.Lslow_next_str /* There was a zero in last reject-part
+ -> Add found index to current len
+ and end. */
+ vlbb %v17,16(%r5,%r3),6 /* Load next reject part. */
+ aghi %r5,16 /* Increment current len of reject-string. */
+ lcbb %r9,0(%r5,%r3),6 /* Get loaded byte count of reject-string. */
+ jo .Lslow_next_acc_onbb /* Jump away if reject-string is
+ on block-boundary. */
+.Lslow_next_acc_notonbb:
+ vistrbs %v17,%v17 /* Fill with zeros after first zero. */
+ jo .Lslow_loop_acc /* No zero found -> no preparation needed. */
+
+.Lslow_next_acc_prepare_zero:
+ /* Zero in reject-part: fill zeros with first-reject-character. */
+ vlgvb %r8,%v17,0 /* Load first element of reject-part. */
+ clije %r8,0,.Lslow_next_str /* Process next str-part if first
+ character in this part of reject
+ is a zero. */
+ /* r8>0 -> zero found in this acc-part. */
+ vrepb %v18,%v17,0 /* Replicate first char accross all chars. */
+ vceqb %v22,%v20,%v17 /* Create a mask (v22) of null chars
+ by comparing with 0 (v20). */
+ vsel %v17,%v18,%v17,%v22 /* Replace null chars with first char. */
+ j .Lslow_loop_acc /* Reject-string part is prepared. */
+
+.Lslow_next_acc_onbb:
+ vfenezb %v18,%v17,%v17 /* Find zero in loaded bytes of reject part. */
+ vlgvb %r8,%v18,7 /* Load byte index of zero. */
+ clrjl %r8,%r9,.Lslow_next_acc_notonbb /* Found a zero in loaded bytes
+ -> Prepare vreg. */
+ vl %v17,0(%r5,%r3) /* Load over boundary ... */
+ lghi %r8,0 /* r8=0 -> no zero in this part of acc,
+ check for zero is in jump-target. */
+ j .Lslow_next_acc_notonbb /* ... and search for zero in
+ fully loaded vreg again. */
+
+.Lslow_end_not_found:
+ algfr %r1,%r6 /* Add zero-index to current len. */
+ j .Lslow_end
+.Lslow_index_found:
+ algfr %r1,%r4 /* Add found index of char to current len. */
+.Lslow_end:
+ lgr %r2,%r1
+ /* Restore registers. */
+ vlgvg %r6,%v30,0
+ vlgvg %r8,%v31,0
+ vlgvg %r9,%v31,1
+ br %r14
+END(__strcspn_vx)
+#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */
diff --git a/REORG.TODO/sysdeps/s390/multiarch/strcspn.c b/REORG.TODO/sysdeps/s390/multiarch/strcspn.c
new file mode 100644
index 0000000000..414f313c75
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/multiarch/strcspn.c
@@ -0,0 +1,31 @@
+/* Multiple versions of strcspn.
+ Copyright (C) 2015-2017 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 && 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_redirected (__redirect_strcspn, __strcspn, strcspn)
+
+#else
+# include <string/strcspn.c>
+#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)) */
diff --git a/REORG.TODO/sysdeps/s390/multiarch/strlen-c.c b/REORG.TODO/sysdeps/s390/multiarch/strlen-c.c
new file mode 100644
index 0000000000..b72366920c
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/multiarch/strlen-c.c
@@ -0,0 +1,28 @@
+/* Default strlen implementation for S/390.
+ Copyright (C) 2015-2017 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 && IS_IN (libc)
+# define STRLEN __strlen_c
+# ifdef SHARED
+# undef libc_hidden_builtin_def
+# define libc_hidden_builtin_def(name) \
+ __hidden_ver1 (__strlen_c, __GI_strlen, __strlen_c);
+# endif /* SHARED */
+
+# include <string/strlen.c>
+#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */
diff --git a/REORG.TODO/sysdeps/s390/multiarch/strlen-vx.S b/REORG.TODO/sysdeps/s390/multiarch/strlen-vx.S
new file mode 100644
index 0000000000..a779d6521a
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/multiarch/strlen-vx.S
@@ -0,0 +1,84 @@
+/* Vector optimized 32/64 bit S/390 version of strlen.
+ Copyright (C) 2015-2017 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 && IS_IN (libc)
+
+# include "sysdep.h"
+# include "asm-syntax.h"
+
+ .text
+
+/* size_t strlen (const char *s)
+ Returns length of string s.
+
+ Register usage:
+ -r1=bytes to 4k-byte boundary
+ -r2=s
+ -r3=tmp
+ -r4=tmp
+ -r5=current_len and return_value
+ -v16=part of s
+*/
+ENTRY(__strlen_vx)
+ .machine "z13"
+ .machinemode "zarch_nohighgprs"
+
+ vlbb %v16,0(%r2),6 /* Load s until next 4k-byte boundary. */
+ lcbb %r1,0(%r2),6 /* Get bytes to 4k-byte boundary or 16. */
+
+ vfenezb %v16,%v16,%v16 /* Find element not equal with zero search. */
+ vlgvb %r4,%v16,7 /* Load zero index or 16 if not found. */
+ clr %r4,%r1 /* If found zero within loaded bytes? */
+ locgrl %r2,%r4 /* Then copy return value. */
+ blr %r14 /* And return. */
+
+ /* Align s to 16 byte. */
+ risbgn %r3,%r2,60,128+63,0 /* %r3 = bits 60-63 of %r2 'and' 15. */
+ lghi %r5,16 /* current_len = 16. */
+ slr %r5,%r3 /* Compute bytes to 16bytes boundary. */
+
+ /* Find zero in 16 byte aligned loop. */
+.Lloop:
+ vl %v16,0(%r5,%r2) /* Load s. */
+ vfenezbs %v16,%v16,%v16 /* Find element not equal with zero search. */
+ je .Lfound /* Jump away if zero was found. */
+ vl %v16,16(%r5,%r2)
+ vfenezbs %v16,%v16,%v16
+ je .Lfound16
+ vl %v16,32(%r5,%r2)
+ vfenezbs %v16,%v16,%v16
+ je .Lfound32
+ vl %v16,48(%r5,%r2)
+ vfenezbs %v16,%v16,%v16
+ je .Lfound48
+
+ aghi %r5,64
+ j .Lloop /* No zero found -> loop. */
+
+.Lfound48:
+ aghi %r5,16
+.Lfound32:
+ aghi %r5,16
+.Lfound16:
+ aghi %r5,16
+.Lfound:
+ vlgvb %r2,%v16,7 /* Load byte index of zero. */
+ algr %r2,%r5
+ br %r14
+END(__strlen_vx)
+#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */
diff --git a/REORG.TODO/sysdeps/s390/multiarch/strlen.c b/REORG.TODO/sysdeps/s390/multiarch/strlen.c
new file mode 100644
index 0000000000..615274e4b8
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/multiarch/strlen.c
@@ -0,0 +1,29 @@
+/* Multiple versions of strlen.
+ Copyright (C) 2015-2017 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 && IS_IN (libc)
+# define strlen __redirect_strlen
+# include <string.h>
+# include <ifunc-resolve.h>
+# undef strlen
+
+s390_vx_libc_ifunc2_redirected (__redirect_strlen, __strlen, strlen)
+
+#else
+# include <string/strlen.c>
+#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)) */
diff --git a/REORG.TODO/sysdeps/s390/multiarch/strncat-c.c b/REORG.TODO/sysdeps/s390/multiarch/strncat-c.c
new file mode 100644
index 0000000000..e72d778fb4
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/multiarch/strncat-c.c
@@ -0,0 +1,23 @@
+/* Default strncat implementation for S/390.
+ Copyright (C) 2015-2017 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 && IS_IN (libc)
+# define STRNCAT __strncat_c
+
+# include <string/strncat.c>
+#endif
diff --git a/REORG.TODO/sysdeps/s390/multiarch/strncat-vx.S b/REORG.TODO/sysdeps/s390/multiarch/strncat-vx.S
new file mode 100644
index 0000000000..c41509ceb5
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/multiarch/strncat-vx.S
@@ -0,0 +1,239 @@
+/* Vector optimized 32/64 bit S/390 version of strncat.
+ Copyright (C) 2015-2017 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 && IS_IN (libc)
+
+# include "sysdep.h"
+# include "asm-syntax.h"
+
+ .text
+
+/* char * strncat (const char *dest, const char *src, size_t n)
+ Concatenate two strings - at most n characters of src.
+
+ Register usage:
+ -r0=saved dest pointer for return
+ -r1=tmp
+ -r2=dest
+ -r3=src
+ -r4=n
+ -r5=current_len
+ -r6=tmp
+ -r7=tmp
+ -v16=part of src
+ -v17=index of zero
+ -v18=part of src
+ -v31=register save area for r6, r7
+*/
+ENTRY(__strncat_vx)
+ .machine "z13"
+ .machinemode "zarch_nohighgprs"
+
+# if !defined __s390x__
+ llgfr %r4,%r4
+# endif /* !defined __s390x__ */
+
+ clgfi %r4,0
+ ber %r14 /* Nothing to do, if n == 0. */
+ lgr %r0,%r2 /* Save destination pointer for return. */
+ vlvgp %v31,%r6,%r7 /* Save registers. */
+
+ /* STRLEN
+ %r1 = loaded bytes (tmp)
+ %r6 = zero byte index (tmp)
+ %r2 = dst
+ */
+ vlbb %v16,0(%r2),6 /* Load s until next 4k-byte boundary. */
+ lcbb %r1,0(%r2),6 /* Get bytes to 4k-byte boundary or 16. */
+
+ vfenezb %v16,%v16,%v16 /* Find element not equal with zero search. */
+ vlgvb %r5,%v16,7 /* Load zero index or 16 if not found. */
+ clrjl %r5,%r1,.Llen_end /* Found zero within loaded bytes, end. */
+
+ /* Align s to 16 byte. */
+ risbgn %r1,%r2,60,128+63,0 /* %r3 = bits 60-63 of %r2 'and' 15. */
+ lghi %r5,16 /* current_len = 16. */
+ slr %r5,%r1 /* Compute bytes to 16bytes boundary. */
+
+ /* Find zero in 16byte aligned loop. */
+.Llen_loop:
+ vl %v16,0(%r5,%r2) /* Load s. */
+ vfenezbs %v16,%v16,%v16 /* Find element not equal with zero search. */
+ je .Llen_found /* Jump away if zero was found. */
+ vl %v16,16(%r5,%r2)
+ vfenezbs %v16,%v16,%v16
+ je .Llen_found16
+ vl %v16,32(%r5,%r2)
+ vfenezbs %v16,%v16,%v16
+ je .Llen_found32
+ vl %v16,48(%r5,%r2)
+ vfenezbs %v16,%v16,%v16
+ je .Llen_found48
+
+ aghi %r5,64
+ j .Llen_loop /* No zero -> loop. */
+
+.Llen_found48:
+ aghi %r5,16
+.Llen_found32:
+ aghi %r5,16
+.Llen_found16:
+ aghi %r5,16
+.Llen_found:
+ vlgvb %r1,%v16,7 /* Load byte index of zero. */
+ algr %r5,%r1
+
+.Llen_end:
+ /* STRCPY
+ %r1 = zero byte index (tmp)
+ %r6 = loaded bytes (tmp)
+ %r3 = curr src pointer
+ %r2 = curr dst pointer
+ %r7 = border, tmp
+ */
+ la %r2,0(%r5,%r2) /* strcpy at end of dst-string. */
+
+ vlbb %v16,0(%r3),6 /* Load s until next 4k-byte boundary. */
+ lcbb %r6,0(%r3),6 /* Get bytes to 4k-byte boundary or 16. */
+ llgfr %r6,%r6 /* Convert 32bit to 64bit. */
+
+ lghi %r5,0 /* current_len = 0. */
+
+ clgrjle %r4,%r6,.Lcpy_remaining_v16 /* If n <= loaded-bytes
+ -> process remaining. */
+
+ /* n > loaded-byte-count. */
+ vfenezb %v17,%v16,%v16 /* Find element not equal with zero search. */
+ vlgvb %r1,%v17,7 /* Load zero index or 16 if not found. */
+ clrjl %r1,%r6,.Lcpy_found_v16_store /* Found zero within loaded
+ bytes, copy and return. */
+
+ /* Align s to 16 byte. */
+ risbgn %r7,%r3,60,128+63,0 /* %r3 = bits 60-63 of %r2 'and' 15. */
+ lghi %r5,15 /* current_len = 15. */
+ slr %r5,%r7 /* Compute highest index to 16byte boundary. */
+
+ /* Zero not found and n > loaded-byte-count. */
+ vstl %v16,%r5,0(%r2) /* Copy loaded characters - no zero. */
+ ahi %r5,1 /* Start loop at next character. */
+
+ /*
+ Now we are 16byte aligned, so we can load a full vreg
+ without page fault.
+ */
+ lgr %r1,%r5 /* If %r5 + 64 < maxlen? -> loop64. */
+ aghi %r1,64
+ clgrjl %r1,%r4,.Lcpy_loop64
+
+ vl %v16,0(%r5,%r3) /* Load s. */
+ clgijl %r4,17,.Lcpy_remaining_v16 /* If n <=16,
+ process remaining bytes. */
+.Lcpy_lt64:
+ lgr %r7,%r4
+ slgfi %r7,16 /* border_len = n - 16. */
+
+ /* If current_len >= border then process remaining bytes. */
+ clgrjhe %r5,%r7,.Lcpy_remaining_v16
+ vfenezbs %v17,%v16,%v16 /* Find element not equal with zero search. */
+ je .Lcpy_found_v16 /* Jump away if zero was found. */
+ vl %v18,16(%r5,%r3) /* Load next part of s. */
+ vst %v16,0(%r5,%r2) /* Store previous part without zero to dst. */
+ aghi %r5,16
+
+ clgrjhe %r5,%r7,.Lcpy_remaining_v18
+ vfenezbs %v17,%v18,%v18
+ je .Lcpy_found_v18
+ vl %v16,16(%r5,%r3)
+ vst %v18,0(%r5,%r2)
+ aghi %r5,16
+
+ clgrjhe %r5,%r7,.Lcpy_remaining_v16
+ vfenezbs %v17,%v16,%v16
+ je .Lcpy_found_v16
+ vl %v18,16(%r5,%r3)
+ vst %v16,0(%r5,%r2)
+ aghi %r5,16
+
+.Lcpy_remaining_v18:
+ vlr %v16,%v18
+.Lcpy_remaining_v16:
+ /* v16 contains the remaining bytes [1...16].
+ Store remaining bytes and append string-termination. */
+ vfenezb %v17,%v16,%v16 /* Find element not equal with zero search. */
+ slgrk %r7,%r4,%r5 /* Remaining bytes = maxlen - current_len. */
+ aghi %r7,-1 /* vstl needs highest index. */
+ vlgvb %r1,%v17,7 /* Load zero index or 16 if not found. */
+ la %r2,0(%r5,%r2) /* vstl has no index register. */
+ /* Zero-index within remaining-bytes, store up to zero and end. */
+ clgrjle %r1,%r7,.Lcpy_found_v16_store
+ vstl %v16,%r7,0(%r2) /* Store remaining bytes. */
+ lghi %r1,0
+ stc %r1,1(%r7,%r2) /* Store string-null-termination beyond n. */
+.Lcpy_end:
+ /* Restore saved registers. */
+ vlgvg %r6,%v31,0
+ vlgvg %r7,%v31,1
+ lgr %r2,%r0 /* Load saved dest-ptr. */
+ br %r14
+
+.Lcpy_found_v16_32:
+ aghi %r5,32
+ j .Lcpy_found_v16
+.Lcpy_found_v18_48:
+ aghi %r5,32
+.Lcpy_found_v18_16:
+ aghi %r5,16
+.Lcpy_found_v18:
+ vlr %v16,%v18
+.Lcpy_found_v16:
+ /* v16 contains a zero. Store remaining bytes to zero. current_len
+ has not reached border, thus checking for n is not needed! */
+ vlgvb %r1,%v17,7 /* Load byte index of zero. */
+ la %r2,0(%r5,%r2)
+.Lcpy_found_v16_store:
+ vstl %v16,%r1,0(%r2) /* Copy characters including zero. */
+ j .Lcpy_end
+
+ /* Find zero in 16byte aligned loop. */
+.Lcpy_loop64:
+ vl %v16,0(%r5,%r3) /* Load s. */
+ vfenezbs %v17,%v16,%v16 /* Find element not equal with zero search. */
+ je .Lcpy_found_v16 /* Jump away if zero was found. */
+ vl %v18,16(%r5,%r3) /* Load next part of s. */
+ vst %v16,0(%r5,%r2) /* Store previous part without zero to dst. */
+ vfenezbs %v17,%v18,%v18
+ je .Lcpy_found_v18_16
+ vl %v16,32(%r5,%r3)
+ vst %v18,16(%r5,%r2)
+ vfenezbs %v17,%v16,%v16
+ je .Lcpy_found_v16_32
+ vl %v18,48(%r5,%r3)
+ vst %v16,32(%r5,%r2)
+ vfenezbs %v17,%v18,%v18
+ je .Lcpy_found_v18_48
+ vst %v18,48(%r5,%r2)
+
+ aghi %r5,64
+ lgr %r1,%r5 /* If %r5 + 64 < maxlen? -> loop64. */
+ aghi %r1,64
+ clgrjl %r1,%r4,.Lcpy_loop64
+
+ vl %v16,0(%r5,%r3) /* Load s. */
+ j .Lcpy_lt64
+END(__strncat_vx)
+#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */
diff --git a/REORG.TODO/sysdeps/s390/multiarch/strncat.c b/REORG.TODO/sysdeps/s390/multiarch/strncat.c
new file mode 100644
index 0000000000..d931ca6c85
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/multiarch/strncat.c
@@ -0,0 +1,27 @@
+/* Multiple versions of strncat.
+ Copyright (C) 2015-2017 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 && IS_IN (libc)
+# include <string.h>
+# include <ifunc-resolve.h>
+
+s390_vx_libc_ifunc2 (__strncat, strncat)
+
+#else
+# include <string/strncat.c>
+#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)) */
diff --git a/REORG.TODO/sysdeps/s390/multiarch/strncmp-c.c b/REORG.TODO/sysdeps/s390/multiarch/strncmp-c.c
new file mode 100644
index 0000000000..fddd5ed97e
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/multiarch/strncmp-c.c
@@ -0,0 +1,28 @@
+/* Default strncmp implementation for S/390.
+ Copyright (C) 2015-2017 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 && IS_IN (libc)
+# define STRNCMP __strncmp_c
+# ifdef SHARED
+# undef libc_hidden_builtin_def
+# define libc_hidden_builtin_def(name) \
+ __hidden_ver1 (__strncmp_c, __GI_strncmp, __strncmp_c);
+# endif /* SHARED */
+
+# include <string/strncmp.c>
+#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */
diff --git a/REORG.TODO/sysdeps/s390/multiarch/strncmp-vx.S b/REORG.TODO/sysdeps/s390/multiarch/strncmp-vx.S
new file mode 100644
index 0000000000..ee35d2debf
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/multiarch/strncmp-vx.S
@@ -0,0 +1,137 @@
+/* Vector optimized 32/64 bit S/390 version of strncmp.
+ Copyright (C) 2015-2017 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 && IS_IN (libc)
+
+# include "sysdep.h"
+# include "asm-syntax.h"
+
+ .text
+
+/* int strncmp (const char *s1, const char *s2, size_t n)
+ Compare at most n characters of two strings.
+
+ Register usage:
+ -r0=tmp
+ -r1=tmp
+ -r2=s1
+ -r3=s2
+ -r4=n
+ -r5=current_len
+ -v16=part of s1
+ -v17=part of s2
+ -v18=index of unequal
+*/
+ENTRY(__strncmp_vx)
+ .machine "z13"
+ .machinemode "zarch_nohighgprs"
+
+# if !defined __s390x__
+ llgfr %r4,%r4
+# endif /* !defined __s390x__ */
+
+ clgije %r4,0,.Lend_equal /* Nothing to do if n == 0, */
+ lghi %r5,0 /* current_len = 0. */
+
+.Lloop:
+ vlbb %v16,0(%r5,%r2),6 /* Load s1 to block boundary. */
+ vlbb %v17,0(%r5,%r3),6 /* Load s2 to block boundary. */
+ lcbb %r0,0(%r5,%r2),6 /* Get loaded byte count of s1. */
+ jo .Llt16_1 /* Jump away if vr is not fully loaded. */
+ lcbb %r1,0(%r5,%r3),6 /* Get loaded byte count of s2. */
+ jo .Llt16_2 /* Jump away if vr is not fully loaded. */
+ aghi %r5,16 /* Both vrs are fully loaded. */
+ clgrjhe %r5,%r4,.Llastcmp /* If current_len >= n ->last compare. */
+ vfenezbs %v18,%v16,%v17 /* Compare not equal with zero search. */
+ jno .Lfound
+
+ vlbb %v16,0(%r5,%r2),6
+ vlbb %v17,0(%r5,%r3),6
+ lcbb %r0,0(%r5,%r2),6
+ jo .Llt16_1
+ lcbb %r1,0(%r5,%r3),6
+ jo .Llt16_2
+ aghi %r5,16
+ clgrjhe %r5,%r4,.Llastcmp
+ vfenezbs %v18,%v16,%v17
+ jno .Lfound
+
+ vlbb %v16,0(%r5,%r2),6
+ vlbb %v17,0(%r5,%r3),6
+ lcbb %r0,0(%r5,%r2),6
+ jo .Llt16_1
+ lcbb %r1,0(%r5,%r3),6
+ jo .Llt16_2
+ aghi %r5,16
+ clgrjhe %r5,%r4,.Llastcmp
+ vfenezbs %v18,%v16,%v17
+ jno .Lfound
+
+ vlbb %v16,0(%r5,%r2),6
+ vlbb %v17,0(%r5,%r3),6
+ lcbb %r0,0(%r5,%r2),6
+ jo .Llt16_1
+ lcbb %r1,0(%r5,%r3),6
+ jo .Llt16_2
+ aghi %r5,16
+ clgrjhe %r5,%r4,.Llastcmp
+ vfenezbs %v18,%v16,%v17
+ jno .Lfound
+ j .Lloop
+
+.Llt16_1:
+ lcbb %r1,0(%r5,%r3),6 /* Get loaded byte count ofs2. */
+.Llt16_2:
+ clr %r0,%r1 /* Compare logical. */
+ locrh %r0,%r1 /* Compute minimum of bytes loaded. */
+ algfr %r5,%r0 /* Add smallest loaded bytes to current_len. */
+ clgrj %r5,%r4,10,.Llastcmp /* If current_len >= n ->last compare. */
+ vfenezbs %v18,%v16,%v17 /* Compare not equal with zero search. */
+ vlgvb %r1,%v18,7 /* Get not equal index or 16 if all equal. */
+ clrjl %r1,%r0,.Lfound /* Jump away if miscompare is within
+ loaded bytes (index < loaded-bytes) */
+ j .Lloop
+
+.Llastcmp:
+ /* Use comparision result only if located within first n characters.
+ %r0: loaded byte count in vreg;
+ %r5: current_len;
+ %r4: n;
+ (current_len - n): [0...16[
+ First ignored match index: loaded bytes - (current_len-n): ]0...16]
+ */
+ slgr %r5,%r4 /* %r5 = current_len - n. */
+ slr %r0,%r5 /* %r0 = first ignored match index. */
+ vfenezbs %v18,%v16,%v17 /* Compare not equal with zero search. */
+ vlgvb %r1,%v18,7 /* Get not equal index or 16 if all equal. */
+ clrjl %r1,%r0,.Lfound /* Jump away if miscompare is within
+ loaded bytes and below n bytes. */
+ j .Lend_equal /* Miscompare after n-bytes -> end equal. */
+
+.Lfound:
+ /* Difference or end of string. */
+ je .Lend_equal
+ lghi %r2,1
+ lghi %r1,-1
+ locgrl %r2,%r1
+ br %r14
+.Lend_equal:
+ lghi %r2,0
+ br %r14
+END(__strncmp_vx)
+#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */
diff --git a/REORG.TODO/sysdeps/s390/multiarch/strncmp.c b/REORG.TODO/sysdeps/s390/multiarch/strncmp.c
new file mode 100644
index 0000000000..c97753cc70
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/multiarch/strncmp.c
@@ -0,0 +1,31 @@
+/* Multiple versions of strncmp.
+ Copyright (C) 2015-2017 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 && 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>
+
+s390_vx_libc_ifunc2_redirected (__redirect_strncmp, __strncmp, strncmp)
+
+#else
+# include <string/strncmp.c>
+#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)) */
diff --git a/REORG.TODO/sysdeps/s390/multiarch/strncpy-vx.S b/REORG.TODO/sysdeps/s390/multiarch/strncpy-vx.S
new file mode 100644
index 0000000000..4f58977b9b
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/multiarch/strncpy-vx.S
@@ -0,0 +1,207 @@
+/* Vector optimized 32/64 bit S/390 version of strncpy.
+ Copyright (C) 2015-2017 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 && IS_IN (libc)
+
+# include "sysdep.h"
+# include "asm-syntax.h"
+
+ .text
+
+/* char * strncpy (const char *dest, const char *src, size_t n)
+ Copy at most n characters of string src to dest.
+
+ Register usage:
+ -r0=dest pointer for return
+ -r1=tmp, zero byte index
+ -r2=dest
+ -r3=src
+ -r4=n
+ -r5=current_len
+ -r6=tmp, loaded bytes
+ -r7=tmp, border
+ -v16=part of src
+ -v17=index of zero
+ -v18=part of src
+ -v31=register save area for r6, r7
+*/
+ENTRY(__strncpy_vx)
+ .machine "z13"
+ .machinemode "zarch_nohighgprs"
+
+# if !defined __s390x__
+ llgfr %r4,%r4
+# endif /* !defined __s390x__ */
+
+ clgfi %r4,0
+ ber %r14 /* Nothing to do, if n == 0. */
+ lgr %r0,%r2 /* Save destination pointer for return. */
+ vlvgp %v31,%r6,%r7 /* Save registers. */
+
+ vlbb %v16,0(%r3),6 /* Load s until next 4k-byte boundary. */
+ lcbb %r6,0(%r3),6 /* Get bytes to 4k-byte boundary or 16. */
+ llgfr %r6,%r6 /* Convert 32bit to 64bit. */
+
+ lghi %r5,0 /* current_len = 0. */
+
+ clgrjle %r4,%r6,.Lremaining_v16 /* If n <= loaded-bytes
+ -> process remaining. */
+
+ /* n > loaded-byte-count. */
+ vfenezb %v17,%v16,%v16 /* Find element not equal with zero search. */
+ vlgvb %r1,%v17,7 /* Load zero index or 16 if not found. */
+ clrjl %r1,%r6,.Lfound_v16_store /* Found zero within loaded bytes,
+ copy and return. */
+
+ /* Align s to 16 byte. */
+ risbgn %r7,%r3,60,128+63,0 /* %r3 = bits 60-63 of %r2 'and' 15. */
+ lghi %r5,15 /* current_len = 15. */
+ slr %r5,%r7 /* Compute highest index to 16byte boundary. */
+
+ /* Zero not found and n > loaded-byte-count. */
+ vstl %v16,%r5,0(%r2) /* Copy loaded characters - no zero. */
+ ahi %r5,1 /* Start loop at next character. */
+
+ /* Now we are 16byte aligned, so we can load
+ a full vreg without page fault. */
+ lgr %r1,%r5 /* If %r5 + 64 < maxlen? -> loop64. */
+ aghi %r1,64
+ clgrjl %r1,%r4,.Lloop64
+
+ vl %v16,0(%r5,%r3) /* Load s. */
+ clgijl %r4,17,.Lremaining_v16 /* If n <= 16, process remaining
+ bytes. */
+.Llt64:
+ lgr %r7,%r4
+ slgfi %r7,16 /* border_len = n - 16. */
+
+ clgrjhe %r5,%r7,.Lremaining_v16 /* If current_len >= border
+ then process remaining bytes. */
+ vfenezbs %v17,%v16,%v16 /* Find element not equal with zero search. */
+ je .Lfound_v16 /* Jump away if zero was found. */
+ vl %v18,16(%r5,%r3) /* Load next part of s. */
+ vst %v16,0(%r5,%r2) /* Store previous part without zero to dst. */
+ aghi %r5,16
+
+ clgrjhe %r5,%r7,.Lremaining_v18
+ vfenezbs %v17,%v18,%v18
+ je .Lfound_v18
+ vl %v16,16(%r5,%r3)
+ vst %v18,0(%r5,%r2)
+ aghi %r5,16
+
+ clgrjhe %r5,%r7,.Lremaining_v16
+ vfenezbs %v17,%v16,%v16
+ je .Lfound_v16
+ vl %v18,16(%r5,%r3)
+ vst %v16,0(%r5,%r2)
+ aghi %r5,16
+
+.Lremaining_v18:
+ vlr %v16,%v18
+.Lremaining_v16:
+ /* v16 contains the remaining bytes [1...16].
+ Store remaining bytes and append string-termination. */
+ vfenezb %v17,%v16,%v16 /* Find element not equal with zero search. */
+ slgrk %r7,%r4,%r5 /* Remaining bytes = maxlen - current_len. */
+ aghi %r7,-1 /* vstl needs highest index. */
+ la %r2,0(%r5,%r2) /* vstl has no index register. */
+ vlgvb %r1,%v17,7 /* Load zero index or 16 if not found. */
+ /* Zero in remaining bytes? -> jump away (zero-index < max-index)
+ Do not jump away if zero-index == max-index,
+ but simply copy zero with vstl below. */
+ clrjl %r1,%r7,.Lfound_v16_store
+ vstl %v16,%r7,0(%r2) /* Store remaining bytes without null
+ termination!. */
+.Lend:
+ /* Restore saved registers. */
+ vlgvg %r6,%v31,0
+ vlgvg %r7,%v31,1
+ lgr %r2,%r0 /* Load saved dest-ptr. */
+ br %r14
+
+
+.Lfound_v16_32:
+ aghi %r5,32
+ j .Lfound_v16
+.Lfound_v18_48:
+ aghi %r5,32
+.Lfound_v18_16:
+ aghi %r5,16
+.Lfound_v18:
+ vlr %v16,%v18
+.Lfound_v16:
+ /* v16 contains a zero. Store remaining bytes to zero. current_len
+ has not reached border, thus checking for n is not needed! */
+ vlgvb %r1,%v17,7 /* Load byte index of zero. */
+ la %r2,0(%r5,%r2) /* vstl has no support for index-register. */
+.Lfound_v16_store:
+ vstl %v16,%r1,0(%r2) /* Copy characters including zero. */
+ /* Fill remaining bytes with zero - remaining count always > 0. */
+ algr %r5,%r1 /* Remaining bytes (=%r4) = ... */
+ slgr %r4,%r5 /* = n - (current_len + zero_index + 1). */
+ la %r2,0(%r1,%r2) /* Pointer to zero. start filling beyond. */
+ aghi %r4,-2 /* mvc with exrl needs count - 1.
+ (additional -1, see remaining bytes above) */
+ srlg %r6,%r4,8 /* Split into 256 byte blocks. */
+ ltgr %r6,%r6
+ je .Lzero_lt256
+.Lzero_loop256:
+ mvc 1(256,%r2),0(%r2) /* Fill 256 zeros at once. */
+ la %r2,256(%r2)
+ brctg %r6,.Lzero_loop256 /* Loop until all blocks are processed. */
+.Lzero_lt256:
+ exrl %r4,.Lmvc_lt256
+ j .Lend
+.Lmvc_lt256:
+ mvc 1(1,%r2),0(%r2)
+
+.Lloop64:
+ vl %v16,0(%r5,%r3) /* Load s. */
+ vfenezbs %v17,%v16,%v16 /* Find element not equal with zero search. */
+ je .Lfound_v16 /* Jump away if zero was found. */
+ vl %v18,16(%r5,%r3) /* Load next part of s. */
+ vst %v16,0(%r5,%r2) /* Store previous part without zero to dst. */
+ vfenezbs %v17,%v18,%v18
+ je .Lfound_v18_16
+ vl %v16,32(%r5,%r3)
+ vst %v18,16(%r5,%r2)
+ vfenezbs %v17,%v16,%v16
+ je .Lfound_v16_32
+ vl %v18,48(%r5,%r3)
+ vst %v16,32(%r5,%r2)
+ vfenezbs %v17,%v18,%v18
+ je .Lfound_v18_48
+ vst %v18,48(%r5,%r2)
+
+ aghi %r5,64
+ lgr %r1,%r5 /* If %r5 + 64 < maxlen? -> loop64. */
+ aghi %r1,64
+ clgrjl %r1,%r4,.Lloop64
+
+ vl %v16,0(%r5,%r3) /* Load s. */
+ j .Llt64
+END(__strncpy_vx)
+
+# define strncpy __strncpy_c
+# undef libc_hidden_builtin_def
+# define libc_hidden_builtin_def(name) strong_alias(__strncpy_c, __GI_strncpy)
+#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */
+
+/* Include strncpy-implementation in s390-32/s390-64 subdirectory. */
+#include <strncpy.S>
diff --git a/REORG.TODO/sysdeps/s390/multiarch/strncpy.c b/REORG.TODO/sysdeps/s390/multiarch/strncpy.c
new file mode 100644
index 0000000000..d44b459093
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/multiarch/strncpy.c
@@ -0,0 +1,29 @@
+/* Multiple versions of strncpy.
+ Copyright (C) 2015-2017 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 && 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_redirected (__redirect_strncpy, __strncpy, strncpy);
+
+#endif
diff --git a/REORG.TODO/sysdeps/s390/multiarch/strnlen-c.c b/REORG.TODO/sysdeps/s390/multiarch/strnlen-c.c
new file mode 100644
index 0000000000..46e2cac342
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/multiarch/strnlen-c.c
@@ -0,0 +1,30 @@
+/* Default strnlen implementation for S/390.
+ Copyright (C) 2015-2017 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 && IS_IN (libc)
+# define STRNLEN __strnlen_c
+# ifdef SHARED
+# undef libc_hidden_def
+# define libc_hidden_def(name) \
+ __hidden_ver1 (__strnlen_c, __GI_strnlen, __strnlen_c); \
+ strong_alias (__strnlen_c, __strnlen_c_1); \
+ __hidden_ver1 (__strnlen_c_1, __GI___strnlen, __strnlen_c_1);
+# endif /* SHARED */
+
+# include <string/strnlen.c>
+#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */
diff --git a/REORG.TODO/sysdeps/s390/multiarch/strnlen-vx.S b/REORG.TODO/sysdeps/s390/multiarch/strnlen-vx.S
new file mode 100644
index 0000000000..da83a0d4f0
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/multiarch/strnlen-vx.S
@@ -0,0 +1,134 @@
+/* Vector optimized 32/64 bit S/390 version of strnlen.
+ Copyright (C) 2015-2017 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 && IS_IN (libc)
+
+# include "sysdep.h"
+# include "asm-syntax.h"
+
+ .text
+
+/* size_t strnlen (const char *s, size_t maxlen)
+ Returns the number of characters in s or at most maxlen.
+
+ Register usage:
+ -r1=tmp
+ -r2=address of string
+ -r3=maxlen (number of characters to be read)
+ -r4=tmp
+ -r5=current_len and return_value
+ -v16=part of s
+*/
+ENTRY(__strnlen_vx)
+ .machine "z13"
+ .machinemode "zarch_nohighgprs"
+
+# if !defined __s390x__
+ llgfr %r3,%r3
+# endif /* !defined __s390x__ */
+
+ clgfi %r3,0 /* if maxlen == 0, return 0. */
+ locgre %r2,%r3
+ ber %r14
+
+ vlbb %v16,0(%r2),6 /* Load s until next 4k-byte boundary. */
+ lcbb %r1,0(%r2),6 /* Get bytes to 4k-byte boundary or 16. */
+ llgfr %r1,%r1 /* Convert 32bit to 64bit. */
+
+ vfenezb %v16,%v16,%v16 /* Find element not equal with zero search. */
+ clgr %r1,%r3
+ locgrh %r1,%r3 /* loaded_byte_count
+ = min (loaded_byte_count, maxlen) */
+
+ vlgvb %r5,%v16,7 /* Load zero index or 16 if not found. */
+ clr %r5,%r1 /* If found zero within loaded bytes? */
+ locgrl %r2,%r5 /* Then copy return value. */
+ blr %r14 /* And return. */
+
+ clgr %r1,%r3 /* If loaded_byte_count == maxlen? */
+ locgre %r2,%r3 /* Then copy return value. */
+ ber %r14 /* And return. */
+
+ /* Align s to 16 byte. */
+ risbgn %r4,%r2,60,128+63,0 /* %r3 = bits 60-63 of %r2 'and' 15. */
+ lghi %r5,16 /* current_len = 16. */
+ slr %r5,%r4 /* Compute bytes to 16bytes boundary. */
+
+ lgr %r1,%r5 /* If %r5 + 64 < maxlen? -> loop64. */
+ aghi %r1,64
+ clgrjl %r1,%r3,.Lloop64
+
+ /* Find zero in max 64byte with aligned s. */
+.Llt64:
+ vl %v16,0(%r5,%r2) /* Load s. */
+ vfenezbs %v16,%v16,%v16 /* Find element not equal with zero search. */
+ je .Lfound /* Jump away if zero was found. */
+ aghi %r5,16
+ clgrjhe %r5,%r3,.Lfound /* current_len >= maxlen -> end. */
+ vl %v16,0(%r5,%r2)
+ vfenezbs %v16,%v16,%v16
+ je .Lfound
+ aghi %r5,16
+ clgrjhe %r5,%r3,.Lfound
+ vl %v16,0(%r5,%r2)
+ vfenezbs %v16,%v16,%v16
+ je .Lfound
+ aghi %r5,16
+ clgrjhe %r5,%r3,.Lfound
+ vl %v16,0(%r5,%r2)
+ vfenezbs %v16,%v16,%v16
+ j .Lfound
+
+.Lfound48:
+ aghi %r5,16
+.Lfound32:
+ aghi %r5,16
+.Lfound16:
+ aghi %r5,16
+.Lfound:
+ vlgvb %r4,%v16,7 /* Load byte index of zero or 16 if no zero. */
+ algr %r5,%r4
+
+ clgr %r5,%r3
+ locgrh %r5,%r3 /* Return min (current_len, maxlen). */
+ lgr %r2,%r5
+ br %r14
+
+ /* Find zero in 16 byte aligned loop. */
+.Lloop64:
+ vl %v16,0(%r5,%r2) /* Load s. */
+ vfenezbs %v16,%v16,%v16 /* Find element not equal with zero search. */
+ je .Lfound /* Jump away if zero was found. */
+ vl %v16,16(%r5,%r2)
+ vfenezbs %v16,%v16,%v16
+ je .Lfound16
+ vl %v16,32(%r5,%r2)
+ vfenezbs %v16,%v16,%v16
+ je .Lfound32
+ vl %v16,48(%r5,%r2)
+ vfenezbs %v16,%v16,%v16
+ je .Lfound48
+
+ aghi %r5,64
+ lgr %r1,%r5 /* If %r5 + 64 < maxlen? -> loop64. */
+ aghi %r1,64
+ clgrjl %r1,%r3,.Lloop64
+
+ j .Llt64
+END(__strnlen_vx)
+#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */
diff --git a/REORG.TODO/sysdeps/s390/multiarch/strnlen.c b/REORG.TODO/sysdeps/s390/multiarch/strnlen.c
new file mode 100644
index 0000000000..6ebcafbd16
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/multiarch/strnlen.c
@@ -0,0 +1,32 @@
+/* Multiple versions of strnlen.
+ Copyright (C) 2015-2017 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 && 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_redirected (__redirect___strnlen, __strnlen)
+weak_alias (__strnlen, strnlen)
+
+#else
+# include <string/strnlen.c>
+#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)) */
diff --git a/REORG.TODO/sysdeps/s390/multiarch/strpbrk-c.c b/REORG.TODO/sysdeps/s390/multiarch/strpbrk-c.c
new file mode 100644
index 0000000000..f099c0607f
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/multiarch/strpbrk-c.c
@@ -0,0 +1,28 @@
+/* Default strpbrk implementation for S/390.
+ Copyright (C) 2015-2017 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 && IS_IN (libc)
+# define STRPBRK __strpbrk_c
+# ifdef SHARED
+# undef libc_hidden_builtin_def
+# define libc_hidden_builtin_def(name) \
+ __hidden_ver1 (__strpbrk_c, __GI_strpbrk, __strpbrk_c);
+# endif /* SHARED */
+
+# include <string/strpbrk.c>
+#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */
diff --git a/REORG.TODO/sysdeps/s390/multiarch/strpbrk-vx.S b/REORG.TODO/sysdeps/s390/multiarch/strpbrk-vx.S
new file mode 100644
index 0000000000..dd24d5e9db
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/multiarch/strpbrk-vx.S
@@ -0,0 +1,302 @@
+/* Vector optimized 32/64 bit S/390 version of strpbrk.
+ Copyright (C) 2015-2017 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 && IS_IN (libc)
+
+# include "sysdep.h"
+# include "asm-syntax.h"
+
+ .text
+
+/* char *strpbrk (const char *s, const char * accept)
+ The strpbrk() function locates the first occurrence in the string s
+ of any of the characters in the string accept and returns a pointer
+ to that character or NULL if not found.
+
+ This method checks the length of accept string. If it fits entirely
+ in one vector register, a fast algorithm is used, which does not need
+ to check multiple parts of accept-string. Otherwise a slower full
+ check of accept-string is used.
+
+ register overview:
+ r3: pointer to start of accept-string
+ r2: pointer to start of search-string
+ r0: loaded byte count of vlbb search-string (32bit unsigned)
+ r4: found byte index (32bit unsigned)
+ r1: current return len (64bit unsigned)
+ v16: search-string
+ v17: accept-string
+ v18: temp-vreg
+
+ ONLY FOR SLOW:
+ v19: first accept-string
+ v20: zero for preparing acc-vector
+ v21: global mask; 1 indicates a match between
+ search-string-vreg and any accept-character
+ v22: current mask; 1 indicates a match between
+ search-string-vreg and any accept-character in current acc-vreg
+ v24: one for result-checking of former string-part
+ v30, v31: for re-/storing registers r6, r8, r9
+ r5: current len of accept-string
+ r6: zero-index in search-string or 16 if no zero
+ or min(zero-index, loaded byte count)
+ r8: >0, if former accept-string-part contains a zero,
+ otherwise =0;
+ r9: loaded byte count of vlbb accept-string
+*/
+ENTRY(__strpbrk_vx)
+ .machine "z13"
+ .machinemode "zarch_nohighgprs"
+
+ /*
+ Check if accept-string fits in one vreg:
+ ----------------------------------------
+ */
+ vlbb %v17,0(%r3),6 /* Load accept. */
+ lghi %r1,0 /* Zero out current len. */
+ vlgvb %r0,%v17,0 /* Get first element. */
+ clije %r0,0,.Lfast_end_null /* Return null if accept is empty. */
+ lcbb %r0,0(%r3),6
+ jo .Lcheck_onbb /* Special case if accept lays
+ on block-boundary. */
+.Lcheck_notonbb:
+ vistrbs %v17,%v17 /* Fill with zeros after first zero. */
+ je .Lfast /* Zero found -> accept fits in one vreg. */
+ j .Lslow /* No zero -> accept exceeds one vreg */
+
+
+.Lcheck_onbb:
+ /* Accept lays on block-boundary. */
+ vfenezb %v18,%v17,%v17 /* Search zero in loaded accept bytes. */
+ vlgvb %r4,%v18,7 /* Get index of zero or 16 if not found. */
+ clrjl %r4,%r0,.Lcheck_notonbb /* Zero index < loaded bytes count ->
+ Accept fits in one vreg;
+ Fill with zeros and proceed
+ with FAST. */
+ vl %v17,0(%r3) /* Load accept, which exceeds loaded bytes. */
+ j .Lcheck_notonbb /* Check if accept fits in one vreg. */
+
+
+ /*
+ Search s for accept in one vreg
+ -------------------------------
+ */
+.Lfast:
+ /* Complete accept-string in v17 and remaining bytes are zero. */
+
+ vlbb %v16,0(%r2),6 /* Load s until next 4k-byte boundary. */
+ lcbb %r0,0(%r2),6 /* Get bytes to 4k-byte boundary or 16. */
+
+ vfaezbs %v18,%v16,%v17,0 /* Find first element in v16 unequal to any
+ in v17 or first zero element. */
+
+ vlgvb %r4,%v18,7 /* Load byte index of found element. */
+ /* If found index is within loaded bytes, return with found
+ element index (=equal count). */
+ clrjl %r4,%r0,.Lfast_loop_found2
+
+ /* Align s to 16 byte. */
+ risbgn %r4,%r2,60,128+63,0 /* %r3 = bits 60-63 of %r2 'and' 15. */
+ lghi %r1,16 /* current_len = 16. */
+ slr %r1,%r4 /* Compute bytes to 16bytes boundary. */
+
+ /* Process s in 16byte aligned loop. */
+.Lfast_loop:
+ vl %v16,0(%r1,%r2) /* Load search-string. */
+ vfaezbs %v18,%v16,%v17,0 /* Find first element in v16 equal to any
+ in v17 or first zero element. */
+ jno .Lfast_loop_found
+
+ vl %v16,16(%r1,%r2)
+ vfaezbs %v18,%v16,%v17,0
+ jno .Lfast_loop_found16
+
+ vl %v16,32(%r1,%r2)
+ vfaezbs %v18,%v16,%v17,0
+ jno .Lfast_loop_found32
+
+ vl %v16,48(%r1,%r2)
+ vfaezbs %v18,%v16,%v17,0
+ jno .Lfast_loop_found48
+
+ aghi %r1,64
+ j .Lfast_loop /* Loop if no element was unequal to accept
+ and not zero. */
+
+ /* Found equal or zero element. */
+.Lfast_loop_found48:
+ aghi %r1,16
+.Lfast_loop_found32:
+ aghi %r1,16
+.Lfast_loop_found16:
+ aghi %r1,16
+.Lfast_loop_found:
+ vlgvb %r4,%v18,7 /* Load byte index of found element. */
+.Lfast_loop_found2:
+ vlgvb %r0,%v16,0(%r4) /* Get found element. */
+ clije %r0,0,.Lfast_end_null /* Return null if no accept-char found */
+ algfr %r1,%r4 /* Add found index of char to current len. */
+ la %r2,0(%r1,%r2) /* And return pointer to first equal char. */
+ br %r14
+
+.Lfast_end_null:
+ lghi %r2,0 /* Return null if no character is equal. */
+ br %r14
+
+
+
+
+ /*
+ Search s for accept in multiple vregs
+ -------------------------------------
+ */
+.Lslow:
+ /* Save registers. */
+ vlvgg %v30,%r6,0
+ vlvgp %v31,%r8,%r9
+
+ /* accept in v17 without zero. */
+ vlr %v19,%v17 /* Save first acc-part for a fast reload. */
+ vzero %v20 /* Zero for preparing acc-vector. */
+ vone %v24 /* One for checking result of former string. */
+
+ /* Align s to 16 byte. */
+ risbg %r4,%r2,60,128+63,0 /* Test if s is aligned and
+ %r4 = bits 60-63 'and' 15. */
+ je .Lslow_loop_str /* If s is aligned, loop aligned. */
+ lghi %r0,15
+ slr %r0,%r4 /* Compute highest index to load (15-x). */
+ vll %v16,%r0,0(%r2) /* Load up to 16 byte boundary (vll needs
+ highest index, remaining bytes are 0). */
+ ahi %r0,1 /* Work with loaded byte count. */
+ vzero %v21 /* Zero out global mask. */
+ lghi %r5,0 /* Set current len of accept-string to zero. */
+ vfenezb %v18,%v16,%v16 /* Find zero in current string-part. */
+ lghi %r8,0 /* There is no zero in first accept-part. */
+ vlgvb %r6,%v18,7 /* Load byte index of zero or 16 if no zero. */
+ clije %r6,0,.Lslow_end_null /* If first element is zero
+ (end of string) -> return null */
+ clr %r0,%r6 /* cc==1 if loaded byte count < zero-index. */
+ locrl %r6,%r0 /* Load on cc==1; zero-index = lbc. */
+ j .Lslow_loop_acc
+
+
+ /* Process s in 16byte aligned loop. */
+.Lslow_next_str:
+ /* Check results of former processed str-part. */
+ vfeeb %v18,%v21,%v24 /* Find first equal match in global mask
+ (ones in element). */
+ vlgvb %r4,%v18,7 /* Get index of first one (=equal)
+ or 16 if no match. */
+ /* Equal-index < min(zero-index, loaded byte count)
+ -> return pointer to equal element. */
+ clrjl %r4,%r6,.Lslow_index_found
+ /* Zero-index < loaded byte count
+ -> former str-part was last str-part
+ -> return null */
+ clrjl %r6,%r0,.Lslow_end_null
+ /* All elements are zero (=no match) -> proceed with next str-part. */
+
+ vlr %v17,%v19 /* Load first part of accept (no zero). */
+ algfr %r1,%r0 /* Add loaded byte count to current len. */
+
+.Lslow_loop_str:
+ vl %v16,0(%r1,%r2) /* Load search-string */
+ lghi %r0,16 /* Loaded byte count is 16. */
+ vzero %v21 /* Zero out global mask. */
+ lghi %r5,0 /* Set current len of accept to zero. */
+ vfenezb %v18,%v16,%v16 /* Find zero in current string-part. */
+ lghi %r8,0 /* There is no zero in first accept-part. */
+ vlgvb %r6,%v18,7 /* Load byte index of zero or 16 if no zero. */
+ clije %r6,0,.Lslow_end_null /* If first element is zero
+ (end of string) -> return null. */
+
+.Lslow_loop_acc:
+ vfaeb %v22,%v16,%v17,4 /* Create matching-mask (1 in mask ->
+ Character matches any accepted character in
+ this accept-string-part) IN=0, RT=1. */
+ vlgvb %r4,%v22,0 /* Get result of first element. */
+ /* First element is equal to any accepted characters
+ (all other parts of accept cannot lead to a match before this one)
+ -> current len is pointing to first element
+ -> return found */
+ clijh %r4,0,.Lslow_end_found
+ vo %v21,%v21,%v22 /* Global-mask = global-|matching-mask. */
+ /* Proceed with next acc until end of acc is reached. */
+
+
+.Lslow_next_acc:
+ clijh %r8,0,.Lslow_next_str /* There was a zero in the last acc-part
+ -> add index to current_len and
+ end. */
+ vlbb %v17,16(%r5,%r3),6 /* Load next accept part. */
+ aghi %r5,16 /* Increment current len of accept-string. */
+ lcbb %r9,0(%r5,%r3),6 /* Get loaded byte count of accept-string. */
+ jo .Lslow_next_acc_onbb /* Jump away ifaccept-string is
+ on block-boundary. */
+.Lslow_next_acc_notonbb:
+ vistrbs %v17,%v17 /* Fill with zeros after first zero. */
+ jo .Lslow_loop_acc /* No zero found -> no preparation needed. */
+
+.Lslow_next_acc_prepare_zero:
+ /* Zero in accept-part: fill zeros with first-accept-character. */
+ vlgvb %r8,%v17,0 /* Load first element of acc-part. */
+ clije %r8,0,.Lslow_next_str /* Proceed with next string-part,
+ if first char in this part of accept
+ is a zero. */
+ /* r8>0 -> zero found in this acc-part. */
+ vrepb %v18,%v17,0 /* Replicate first char accross all chars. */
+ vceqb %v22,%v20,%v17 /* Create a mask (v22) of null chars
+ by comparing with 0 (v20). */
+ vsel %v17,%v18,%v17,%v22 /* Replace null chars with first char. */
+ j .Lslow_loop_acc /* Accept part is prepared -> process. */
+
+.Lslow_next_acc_onbb:
+ vfenezb %v18,%v17,%v17 /* Find zero in loaded bytes of accept part. */
+ vlgvb %r8,%v18,7 /* Load byte index of zero. */
+ clrjl %r8,%r9,.Lslow_next_acc_notonbb /* Found a zero in loaded bytes
+ -> Prepare vreg. */
+ vl %v17,0(%r5,%r3) /* Load over boundary ... */
+ lghi %r8,0 /* r8=0 -> no zero in this part of acc,
+ check for zero is in jump-target. */
+ j .Lslow_next_acc_notonbb /* ... and search for zero in
+ fully loaded vreg again. */
+
+.Lslow_end_null:
+ lghi %r1,0 /* Return null if no character is equal. */
+ j .Lslow_end
+
+.Lslow_loop_found:
+ vlgvb %r4,%v18,7 /* Load byte index of found element. */
+ vlgvb %r0,%v16,0(%r4) /* Get found element. */
+ clije %r0,0,.Lslow_end_null /* Return null if no acc-char found. */
+
+.Lslow_index_found:
+ algfr %r1,%r4 /* Add found index of char to current len. */
+.Lslow_end_found:
+ la %r1,0(%r1,%r2) /* And return pointer to first equal char. */
+
+.Lslow_end:
+ /* Restore registers. */
+ vlgvg %r6,%v30,0
+ vlgvg %r8,%v31,0
+ vlgvg %r9,%v31,1
+ lgr %r2,%r1
+ br %r14
+END(__strpbrk_vx)
+#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */
diff --git a/REORG.TODO/sysdeps/s390/multiarch/strpbrk.c b/REORG.TODO/sysdeps/s390/multiarch/strpbrk.c
new file mode 100644
index 0000000000..89bdb2b26c
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/multiarch/strpbrk.c
@@ -0,0 +1,31 @@
+/* Multiple versions of strpbrk.
+ Copyright (C) 2015-2017 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 && 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_redirected (__redirect_strpbrk, __strpbrk, strpbrk)
+
+#else
+# include <string/strpbrk.c>
+#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)) */
diff --git a/REORG.TODO/sysdeps/s390/multiarch/strrchr-c.c b/REORG.TODO/sysdeps/s390/multiarch/strrchr-c.c
new file mode 100644
index 0000000000..d1a8c4bd31
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/multiarch/strrchr-c.c
@@ -0,0 +1,29 @@
+/* Default strrchr implementation for S/390.
+ Copyright (C) 2015-2017 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 && IS_IN (libc)
+# define STRRCHR __strrchr_c
+# undef weak_alias
+# ifdef SHARED
+# undef libc_hidden_builtin_def
+# define libc_hidden_builtin_def(name) \
+ __hidden_ver1 (__strrchr_c, __GI_strrchr, __strrchr_c);
+# endif /* SHARED */
+
+# include <string/strrchr.c>
+#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */
diff --git a/REORG.TODO/sysdeps/s390/multiarch/strrchr-vx.S b/REORG.TODO/sysdeps/s390/multiarch/strrchr-vx.S
new file mode 100644
index 0000000000..89a8f5f14c
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/multiarch/strrchr-vx.S
@@ -0,0 +1,180 @@
+/* Vector optimized 32/64 bit S/390 version of strrchr.
+ Copyright (C) 2015-2017 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 && IS_IN (libc)
+
+# include "sysdep.h"
+# include "asm-syntax.h"
+
+ .text
+
+/* char *strrchr (const char *s, int c)
+ Locate the last character c in string.
+
+ Register usage:
+ -r0=loaded bytes in first part of s.
+ -r1=pointer to last occurence of c or NULL if not found.
+ -r2=s
+ -r3=c
+ -r4=tmp
+ -r5=current_len
+ -v16=part of s
+ -v17=index of found element
+ -v18=replicated c
+ -v19=part of s with last occurence of c.
+ -v20=permute pattern
+*/
+ENTRY(__strrchr_vx)
+ .machine "z13"
+ .machinemode "zarch_nohighgprs"
+
+ vlbb %v16,0(%r2),6 /* Load s until next 4k-byte boundary. */
+ lcbb %r0,0(%r2),6 /* Get bytes to 4k-byte boundary or 16. */
+
+ vlvgb %v18,%r3,0 /* Generate vector which elements are all c.
+ if c > 255, c will be truncated. */
+ vrepb %v18,%v18,0
+
+ lghi %r1,-1 /* Currently no c found. */
+ lghi %r5,0 /* current_len = 0. */
+
+ vfeezbs %v17,%v16,%v18 /* Find element equal or zero. */
+ vlgvb %r4,%v17,7 /* Load byte index of c/zero or 16. */
+ clrjl %r4,%r0,.Lfound_first_part /* Found c/zero in loaded bytes. */
+.Lalign:
+ /* Align s to 16 byte. */
+ risbgn %r4,%r2,60,128+63,0 /* %r3 = bits 60-63 of %r2 'and' 15. */
+ lghi %r5,16 /* current_len = 16. */
+ slr %r5,%r4 /* Compute bytes to 16bytes boundary. */
+
+.Lloop:
+ vl %v16,0(%r5,%r2) /* Load s. */
+ vfeezbs %v17,%v16,%v18 /* Find element equal with zero search. */
+ jno .Lfound /* Found c/zero (cc=0|1|2). */
+ vl %v16,16(%r5,%r2)
+ vfeezbs %v17,%v16,%v18
+ jno .Lfound16
+ vl %v16,32(%r5,%r2)
+ vfeezbs %v17,%v16,%v18
+ jno .Lfound32
+ vl %v16,48(%r5,%r2)
+ vfeezbs %v17,%v16,%v18
+ jno .Lfound48
+
+ aghi %r5,64
+ j .Lloop /* No character and no zero -> loop. */
+
+.Lfound48:
+ la %r5,16(%r5) /* Use la since aghi would clobber cc. */
+.Lfound32:
+ la %r5,16(%r5)
+.Lfound16:
+ la %r5,16(%r5)
+.Lfound:
+ je .Lzero /* Found zero, but no c before that zero. */
+ /* Save this part of s to check for further matches after reaching
+ the end of the complete string. */
+ vlr %v19,%v16
+ lgr %r1,%r5
+
+ jh .Lzero /* Found a zero after the found c. */
+ aghi %r5,16 /* Start search of next part of s. */
+ j .Lloop
+
+.Lfound_first_part:
+ /* This code is only executed if the found c/zero is whithin loaded
+ bytes. If no c/zero was found (cc==3) the found index = 16, thus
+ this code is not called.
+ Resulting condition code of vector find element equal:
+ cc==0: no c, found zero
+ cc==1: c found, no zero
+ cc==2: c found, found zero after c
+ cc==3: no c, no zero (this case can be ignored). */
+ je .Lzero /* Found zero, but no c before that zero. */
+
+ locgrne %r1,%r5 /* Mark c as found in first part of s. */
+ vlr %v19,%v16
+
+ jl .Lalign /* No zero (e.g. if vr was fully loaded)
+ -> Align and loop afterwards. */
+
+ /* Found a zero in vr. If vr was not fully loaded due to block
+ boundary, the remaining bytes are filled with zero and we can't
+ rely on zero indication of condition code here! */
+
+ vfenezb %v17,%v16,%v16 /* Find zero. */
+ vlgvb %r4,%v17,7 /* Load byte index of zero or 16. */
+ clrjl %r4,%r0,.Lzero /* Zero within loaded bytes -> end. */
+ j .Lalign /* Align and loop afterwards. */
+
+.Lend_searched_zero:
+ vlgvb %r4,%v17,7 /* Load byte index of zero. */
+ algr %r5,%r4
+ la %r2,0(%r5,%r2) /* Return pointer to zero. */
+ br %r14
+
+.Lzero:
+ /* Reached end of string. Check if one c was found before. */
+ clije %r3,0,.Lend_searched_zero /* Found zero and c is zero. */
+
+ cgfi %r1,-1 /* No c found -> return NULL. */
+ locghie %r2,0
+ ber %r14
+
+ larl %r3,.Lpermute_mask /* Load permute mask. */
+ vl %v20,0(%r3)
+
+ /* c was found and is part of v19. */
+ vfenezb %v17,%v19,%v19 /* Find zero. */
+ vlgvb %r4,%v17,7 /* Load byte index of zero or 16. */
+
+ clgfi %r5,0 /* Loaded byte count in v19 is 16, ... */
+ lochine %r0,16 /* ... if v19 is not the first part of s. */
+ ahi %r0,-1 /* Convert byte count to highest index. */
+
+ clr %r0,%r4
+ locrl %r4,%r0 /* r4 = min (zero-index, highest-index). */
+
+ /* Right-shift of v19 to mask bytes after zero. */
+ clije %r4,15,.Lzero_permute /* No shift is needed if highest index
+ in vr is 15. */
+ lhi %r0,15
+ slr %r0,%r4 /* Compute byte count for vector shift right. */
+ sll %r0,3 /* Convert to bit count. */
+ vlvgb %v17,%r0,7
+ vsrlb %v19,%v19,%v17 /* Vector shift right by byte by number of bytes
+ specified in bits 1-4 of byte 7 in v17. */
+
+ /* Reverse bytes in v19. */
+.Lzero_permute:
+ vperm %v19,%v19,%v19,%v20 /* Permute v19 to reversed order. */
+
+ /* Find c in reversed v19. */
+ vfeeb %v19,%v19,%v18 /* Find c. */
+ la %r2,0(%r1,%r2)
+ vlgvb %r3,%v19,7 /* Load byte index of c. */
+
+ /* Compute index in real s and return. */
+ slgr %r4,%r3
+ la %r2,0(%r4,%r2) /* Return pointer to zero. */
+ br %r14
+.Lpermute_mask:
+ .byte 0x0F,0x0E,0x0D,0x0C,0x0B,0x0A,0x09,0x08
+ .byte 0x07,0x06,0x05,0x04,0x03,0x02,0x01,0x00
+END(__strrchr_vx)
+#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */
diff --git a/REORG.TODO/sysdeps/s390/multiarch/strrchr.c b/REORG.TODO/sysdeps/s390/multiarch/strrchr.c
new file mode 100644
index 0000000000..edb8ce6caf
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/multiarch/strrchr.c
@@ -0,0 +1,30 @@
+/* Multiple versions of strrchr.
+ Copyright (C) 2015-2017 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 && IS_IN (libc)
+# define strrchr __redirect_strrchr
+# include <string.h>
+# undef strrchr
+# include <ifunc-resolve.h>
+
+s390_vx_libc_ifunc2_redirected (__redirect_strrchr, __strrchr, strrchr)
+weak_alias (strrchr, rindex);
+
+#else
+# include <string/strrchr.c>
+#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)) */
diff --git a/REORG.TODO/sysdeps/s390/multiarch/strspn-c.c b/REORG.TODO/sysdeps/s390/multiarch/strspn-c.c
new file mode 100644
index 0000000000..99e1f20da4
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/multiarch/strspn-c.c
@@ -0,0 +1,28 @@
+/* Default strspn implementation for S/390.
+ Copyright (C) 2015-2017 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 && IS_IN (libc)
+# define STRSPN __strspn_c
+# ifdef SHARED
+# undef libc_hidden_builtin_def
+# define libc_hidden_builtin_def(name) \
+ __hidden_ver1 (__strspn_c, __GI_strspn, __strspn_c);
+# endif /* SHARED */
+
+# include <string/strspn.c>
+#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */
diff --git a/REORG.TODO/sysdeps/s390/multiarch/strspn-vx.S b/REORG.TODO/sysdeps/s390/multiarch/strspn-vx.S
new file mode 100644
index 0000000000..1cb3d0d598
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/multiarch/strspn-vx.S
@@ -0,0 +1,256 @@
+/* Vector optimized 32/64 bit S/390 version of strspn.
+ Copyright (C) 2015-2017 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 && IS_IN (libc)
+
+# include "sysdep.h"
+# include "asm-syntax.h"
+
+ .text
+
+/* size_t strspn (const char *s, const char * accept)
+ The strspn() function calculates the length of the initial segment
+ of s which consists entirely of characters in accept.
+
+ This method checks the length of accept string. If it fits entirely
+ in one vector register, a fast algorithm is used, which does not need
+ to check multiple parts of accept-string. Otherwise a slower full
+ check of accept-string is used.
+
+ register overview:
+ r3: pointer to start of accept-string
+ r2: pointer to start of search-string
+ r4: loaded byte count of vl search-string
+ r0: found byte index
+ r1: current return len of s
+ v16: search-string
+ v17: accept-string
+ v18: temp-vreg
+
+ ONLY FOR SLOW:
+ v19: first accept-string
+ v20: zero for preparing acc-vector
+ v21: global mask; 1 indicates a match between
+ search-string-vreg and any accept-character
+ v22: current mask; 1 indicates a match between
+ search-string-vreg and any accept-character in current acc-vreg
+ v30, v31: for re-/storing registers r6, r8, r9
+ r5: current len of accept-string
+ r6: zero-index in search-string or 16 if no zero
+ or min(zero-index, loaded byte count)
+ r8: >0, if former accept-string-part contains a zero,
+ otherwise =0;
+ r9: loaded byte count of vlbb accept-string
+*/
+ENTRY(__strspn_vx)
+ .machine "z13"
+ .machinemode "zarch_nohighgprs"
+
+ /*
+ Check if accept-string fits in one vreg:
+ ----------------------------------------
+ */
+ vlbb %v17,0(%r3),6 /* Load accept. */
+ lcbb %r4,0(%r3),6
+ jo .Lcheck_onbb /* Special case if accept lays
+ on block-boundary. */
+.Lcheck_notonbb:
+ vistrbs %v17,%v17 /* Fill with zeros after first zero. */
+ je .Lfast /* Zero found -> accept fits in one vreg. */
+ j .Lslow /* No zero -> accept exceeds one vreg. */
+
+.Lcheck_onbb:
+ /* Accept lays on block-boundary. */
+ vfenezb %v18,%v17,%v17 /* Search zero in loaded accept bytes. */
+ vlgvb %r0,%v18,7 /* Get index of zero or 16 if not found. */
+ clrjl %r0,%r4,.Lcheck_notonbb /* Zero index < loaded bytes count ->
+ Accept fits in one vreg;
+ Fill with zeros and proceed
+ with FAST. */
+ vl %v17,0(%r3) /* Load accept, which exceeds loaded bytes. */
+ j .Lcheck_notonbb /* Check if accept fits in one vreg. */
+
+
+ /*
+ Search s for accept in one vreg
+ -------------------------------
+ */
+.Lfast:
+ /* Complete accept-string is in v17 and remaining bytes are zero. */
+
+ vlbb %v16,0(%r2),6 /* Load s until next 4k-byte boundary. */
+ lcbb %r1,0(%r2),6 /* Get bytes to 4k-byte boundary or 16. */
+
+ vfaezbs %v16,%v16,%v17,8 /* Find first element in v16
+ unequal to any in v17
+ or first zero element. */
+ vlgvb %r0,%v16,7 /* Load byte index of found element. */
+ /* If found index is within loaded bytes (%r0 < %r1),
+ return with found element index (=equal count). */
+ clr %r0,%r1
+ locgrl %r2,%r0
+ blr %r14
+
+ /* Align s to 16 byte. */
+ risbgn %r4,%r2,60,128+63,0 /* %r3 = bits 60-63 of %r2 'and' 15. */
+ lghi %r1,16 /* current_len = 16. */
+ slr %r1,%r4 /* Compute bytes to 16bytes boundary. */
+
+.Lfast_loop:
+ vl %v16,0(%r1,%r2) /* Load search-string. */
+ vfaezbs %v16,%v16,%v17,8 /* Find first element in v16
+ unequal to any in v17
+ or first zero element. */
+ jno .Lfast_loop_found
+ vl %v16,16(%r1,%r2)
+ vfaezbs %v16,%v16,%v17,8
+ jno .Lfast_loop_found16
+ vl %v16,32(%r1,%r2)
+ vfaezbs %v16,%v16,%v17,8
+ jno .Lfast_loop_found32
+ vl %v16,48(%r1,%r2)
+ vfaezbs %v16,%v16,%v17,8
+ jno .Lfast_loop_found48
+
+ aghi %r1,64
+ j .Lfast_loop /* Loop if no element was unequal to accept
+ and not zero. */
+
+ /* Found unequal or zero element. */
+.Lfast_loop_found48:
+ aghi %r1,16
+.Lfast_loop_found32:
+ aghi %r1,16
+.Lfast_loop_found16:
+ aghi %r1,16
+.Lfast_loop_found:
+ vlgvb %r0,%v16,7 /* Load byte index of found element. */
+ algrk %r2,%r1,%r0 /* And add it to current len. */
+ br %r14
+
+
+ /*
+ Search s for accept in multiple vregs
+ -------------------------------------
+ */
+.Lslow:
+ /* Save registers. */
+ vlvgg %v30,%r6,0
+ vlvgp %v31,%r8,%r9
+ lghi %r1,0 /* current_len = 0. */
+
+ /* Accept in v17 without zero. */
+ vlr %v19,%v17 /* Save first acc-part for a fast reload. */
+ vzero %v20 /* Zero for preparing acc-vector. */
+
+ /* Align s to 16 byte. */
+ risbg %r0,%r2,60,128+63,0 /* Test if s is aligned and
+ %r0 = bits 60-63 'and' 15 */
+ je .Lslow_loop_str /* If s is aligned, loop aligned */
+ lghi %r4,15
+ slr %r4,%r0 /* Compute highest index to load (15-x). */
+ vll %v16,%r4,0(%r2) /* Load up to 16byte boundary (vll needs
+ highest index, left bytes are 0). */
+ ahi %r4,1 /* Work with loaded byte count. */
+ vzero %v21 /* Zero out global mask. */
+ lghi %r5,0 /* Set current len of accept-string to zero. */
+ vfenezb %v18,%v16,%v16 /* Find zero in current string-part. */
+ lghi %r8,0 /* There is no zero in first accept-part. */
+ vlgvb %r6,%v18,7 /* Load byte index of zero or 16
+ if there is no zero. */
+ clr %r4,%r6 /* cc==1 if loaded byte count < zero-index. */
+ locrl %r6,%r4 /* Load on cc==1. */
+ j .Lslow_loop_acc
+
+ /* Process s in 16byte aligned loop. */
+.Lslow_next_str:
+ vlr %v17,%v19 /* Load first part of accept (no zero). */
+ algfr %r1,%r4 /* Add loaded byte count to current len. */
+.Lslow_loop_str:
+ vl %v16,0(%r1,%r2) /* Load search-string. */
+ lghi %r4,16 /* Loaded byte count is 16. */
+ vzero %v21 /* Zero out global mask. */
+ lghi %r5,0 /* Set current len of accept-string to zero. */
+ vfenezb %v18,%v16,%v16 /* Find zero in current string-part. */
+ lghi %r8,0 /* There is no zero in first accept-part. */
+ vlgvb %r6,%v18,7 /* Load byte index of zero or 16 if no zero. */
+
+.Lslow_loop_acc:
+ vfaeb %v22,%v16,%v17,4 /* Create matching-mask (1 in mask ->
+ character matches any accepted character in
+ this accept-string-part) IN=0, RT=1. */
+ vo %v21,%v21,%v22 /* global-mask = global- | matching-mask. */
+ vfenezb %v18,%v21,%v21 /* Find first zero in global-mask. */
+ vlgvb %r0,%v18,7 /* Get first found zero-index
+ (= first mismatch). */
+ clrjl %r0,%r6,.Lslow_next_acc /* Mismatch-index < min(lbc,zero-index)
+ -> Process this string-part
+ with next acc-part. */
+ clrjhe %r0,%r4,.Lslow_next_str /* Found-index >= loaded byte count
+ -> All loaded bytes are matching
+ any accept-character
+ and are not zero. */
+ /* All bytes are matching any characters in accept-string
+ and search-string is fully processed (found-index == zero-index) */
+.Lslow_add_lbc_end:
+ algrk %r2,%r1,%r0 /* Add matching characters to current_len. */
+ /* Restore registers. */
+ vlgvg %r6,%v30,0
+ vlgvg %r8,%v31,0
+ vlgvg %r9,%v31,1
+ br %r14
+
+
+
+.Lslow_next_acc:
+ clijh %r8,0,.Lslow_add_lbc_end /* There was a zero in last acc-part
+ -> Add found index to current len
+ and end. */
+ vlbb %v17,16(%r5,%r3),6 /* Load next accept part. */
+ aghi %r5,16 /* Add current_len of accept-string. */
+ lcbb %r9,0(%r5,%r3),6 /* Get loaded byte count of accept-string. */
+ jo .Lslow_next_acc_onbb /* Jump away if accept-string is
+ on block-boundary. */
+.Lslow_next_acc_notonbb:
+ vistrbs %v17,%v17 /* Fill with zeros after first zero. */
+ jo .Lslow_loop_acc /* No zero found -> no preparation needed. */
+
+.Lslow_next_acc_prepare_zero:
+ /* Zero in accept-part: fill zeros with first-accept-character. */
+ vlgvb %r8,%v17,0 /* Load first element of acc-part. */
+ clije %r8,0,.Lslow_add_lbc_end /* End if zero is first character
+ in this part of accept-string. */
+ /* r8>0 -> zero found in this acc-part. */
+ vrepb %v18,%v17,0 /* Replicate first char accross all chars. */
+ vceqb %v22,%v20,%v17 /* Create a mask (v22) of null chars
+ by comparing with 0 (v20). */
+ vsel %v17,%v18,%v17,%v22 /* Replace null chars with first char. */
+ j .Lslow_loop_acc /* Accept part is prepared -> process. */
+
+.Lslow_next_acc_onbb:
+ vfenezb %v18,%v17,%v17 /* Find zero in loaded bytes of accept part. */
+ vlgvb %r8,%v18,7 /* Load byte index of zero. */
+ clrjl %r8,%r9,.Lslow_next_acc_notonbb /* Found a zero in loaded bytes
+ -> Prepare vr. */
+ vl %v17,0(%r5,%r3) /* Load over boundary ... */
+ lghi %r8,0 /* r8=0 -> no zero in this part of acc,
+ Check for zero is in jump-target. */
+ j .Lslow_next_acc_notonbb /* ... and search for zero in
+ fully loaded vreg again. */
+END(__strspn_vx)
+#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */
diff --git a/REORG.TODO/sysdeps/s390/multiarch/strspn.c b/REORG.TODO/sysdeps/s390/multiarch/strspn.c
new file mode 100644
index 0000000000..b9cf295fb3
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/multiarch/strspn.c
@@ -0,0 +1,31 @@
+/* Multiple versions of strspn.
+ Copyright (C) 2015-2017 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 && 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_redirected (__redirect_strspn, __strspn, strspn)
+
+#else
+# include <string/strspn.c>
+#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)) */
diff --git a/REORG.TODO/sysdeps/s390/multiarch/utf16-utf32-z9.c b/REORG.TODO/sysdeps/s390/multiarch/utf16-utf32-z9.c
new file mode 100644
index 0000000000..6e64169835
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/multiarch/utf16-utf32-z9.c
@@ -0,0 +1,44 @@
+/* Conversion between UTF-16 and UTF-32 BE/internal - multiarch s390 version.
+
+ Copyright (C) 2017 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 && (hwcap & HWCAP_S390_VX))
+ ? FROM_LOOP_VX
+ : FROM_LOOP_DEFAULT);
+
+s390_libc_ifunc_expr (TO_LOOP_DEFAULT, TO_LOOP,
+ (HAVE_TO_VX && (hwcap & HWCAP_S390_VX))
+ ? TO_LOOP_VX
+ : TO_LOOP_DEFAULT);
+
+#include <iconv/skeleton.c>
diff --git a/REORG.TODO/sysdeps/s390/multiarch/utf8-utf16-z9.c b/REORG.TODO/sysdeps/s390/multiarch/utf8-utf16-z9.c
new file mode 100644
index 0000000000..b55ef1aaec
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/multiarch/utf8-utf16-z9.c
@@ -0,0 +1,48 @@
+/* Conversion between UTF-8 and UTF-16 - multiarch s390 version.
+
+ Copyright (C) 2017 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 && (hwcap & HWCAP_S390_VX))
+ ? TO_LOOP_VX
+ : TO_LOOP_DEFAULT);
+
+#include <iconv/skeleton.c>
diff --git a/REORG.TODO/sysdeps/s390/multiarch/utf8-utf32-z9.c b/REORG.TODO/sysdeps/s390/multiarch/utf8-utf32-z9.c
new file mode 100644
index 0000000000..faf1f46aa9
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/multiarch/utf8-utf32-z9.c
@@ -0,0 +1,48 @@
+/* Conversion between UTF-8 and UTF-32 - multiarch s390 version.
+
+ Copyright (C) 2017 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 && (hwcap & HWCAP_S390_VX))
+ ? TO_LOOP_VX
+ : TO_LOOP_DEFAULT);
+
+#include <iconv/skeleton.c>
diff --git a/REORG.TODO/sysdeps/s390/multiarch/wcpcpy-c.c b/REORG.TODO/sysdeps/s390/multiarch/wcpcpy-c.c
new file mode 100644
index 0000000000..6eadde5441
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/multiarch/wcpcpy-c.c
@@ -0,0 +1,25 @@
+/* Default wcslen implementation for S/390.
+ Copyright (C) 2015-2017 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 && IS_IN (libc)
+# define WCPCPY __wcpcpy_c
+
+# include <wchar.h>
+extern __typeof (__wcpcpy) __wcpcpy_c;
+# include <wcsmbs/wcpcpy.c>
+#endif
diff --git a/REORG.TODO/sysdeps/s390/multiarch/wcpcpy-vx.S b/REORG.TODO/sysdeps/s390/multiarch/wcpcpy-vx.S
new file mode 100644
index 0000000000..73b2670786
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/multiarch/wcpcpy-vx.S
@@ -0,0 +1,114 @@
+/* Vector optimized 32/64 bit S/390 version of wcpcpy.
+ Copyright (C) 2015-2017 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 && IS_IN (libc)
+
+# include "sysdep.h"
+# include "asm-syntax.h"
+
+ .text
+
+/* wchar_t * wcpcpy (const wchar_t *dest, const wchar_t *src)
+ Copy string src to dest returning a pointer to its end.
+
+ Register usage:
+ -r0=border-len for switching to vector-instructions
+ -r1=tmp
+ -r2=dest and return value
+ -r3=src
+ -r4=tmp
+ -r5=current_len
+ -v16=part of src
+ -v17=index of zero
+ -v18=part of src
+*/
+ENTRY(__wcpcpy_vx)
+ .machine "z13"
+ .machinemode "zarch_nohighgprs"
+
+ vlbb %v16,0(%r3),6 /* Load s until next 4k-byte boundary. */
+ lcbb %r1,0(%r3),6 /* Get bytes to 4k-byte boundary or 16. */
+
+ tmll %r3,3 /* Test if s is 4-byte aligned? */
+ jne .Lfallback /* And use common-code variant if not. */
+
+ vfenezf %v17,%v16,%v16 /* Find element not equal with zero search. */
+ vlgvb %r5,%v17,7 /* Load zero index or 16 if not found. */
+ clrjl %r5,%r1,.Lfound_align /* If found zero within loaded bytes,
+ copy bytes before and return. */
+
+ /* Align s to 16 byte. */
+ risbgn %r4,%r3,60,128+63,0 /* %r3 = bits 60-63 of %r2 'and' 15. */
+ lghi %r5,15 /* current_len = 15. */
+ slr %r5,%r4 /* Compute highest index to 16byte boundary. */
+
+ vstl %v16,%r5,0(%r2) /* Copy loaded characters - no zero. */
+ ahi %r5,1 /* Start loop at next character. */
+
+ /* Find zero in 16byte aligned loop. */
+.Lloop:
+ vl %v16,0(%r5,%r3) /* Load s. */
+ vfenezfs %v17,%v16,%v16 /* Find element not equal with zero search. */
+ je .Lfound_v16_0 /* Jump away if zero was found. */
+ vl %v18,16(%r5,%r3) /* Load next part of s. */
+ vst %v16,0(%r5,%r2) /* Store previous part without zero to dst. */
+ vfenezfs %v17,%v18,%v18
+ je .Lfound_v18_16
+ vl %v16,32(%r5,%r3)
+ vst %v18,16(%r5,%r2)
+ vfenezfs %v17,%v16,%v16
+ je .Lfound_v16_32
+ vl %v18,48(%r5,%r3)
+ vst %v16,32(%r5,%r2)
+ vfenezfs %v17,%v18,%v18
+ je .Lfound_v18_48
+ vst %v18,48(%r5,%r2)
+
+ aghi %r5,64
+ j .Lloop /* No zero found -> loop. */
+
+.Lfound_v16_32:
+ aghi %r5,32
+.Lfound_v16_0:
+ la %r3,0(%r5,%r2)
+ vlgvb %r1,%v17,7 /* Load byte index of zero. */
+ aghi %r1,3 /* Also copy remaining bytes of zero. */
+ vstl %v16,%r1,0(%r3) /* Copy characters including zero. */
+ lay %r2,-3(%r1,%r3) /* Return pointer to zero. */
+ br %r14
+
+.Lfound_v18_48:
+ aghi %r5,32
+.Lfound_v18_16:
+ la %r3,16(%r5,%r2)
+ vlgvb %r1,%v17,7 /* Load byte index of zero. */
+ aghi %r1,3 /* Also copy remaining bytes of zero. */
+ vstl %v18,%r1,0(%r3) /* Copy characters including zero. */
+ lay %r2,-3(%r1,%r3) /* Return pointer to zero. */
+ br %r14
+
+.Lfound_align:
+ aghi %r5,3 /* Also copy remaining bytes of zero. */
+ vstl %v16,%r5,0(%r2) /* Copy characters including zero. */
+ lay %r2,-3(%r5,%r2) /* Return pointer to zero. */
+ br %r14
+
+.Lfallback:
+ jg __wcpcpy_c
+END(__wcpcpy_vx)
+#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */
diff --git a/REORG.TODO/sysdeps/s390/multiarch/wcpcpy.c b/REORG.TODO/sysdeps/s390/multiarch/wcpcpy.c
new file mode 100644
index 0000000000..79d1641606
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/multiarch/wcpcpy.c
@@ -0,0 +1,28 @@
+/* Multiple versions of wcpcpy.
+ Copyright (C) 2015-2017 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 && IS_IN (libc)
+# include <wchar.h>
+# include <ifunc-resolve.h>
+
+s390_vx_libc_ifunc (__wcpcpy)
+weak_alias (__wcpcpy, wcpcpy)
+
+#else
+# include <wcsmbs/wcpcpy.c>
+#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)) */
diff --git a/REORG.TODO/sysdeps/s390/multiarch/wcpncpy-c.c b/REORG.TODO/sysdeps/s390/multiarch/wcpncpy-c.c
new file mode 100644
index 0000000000..7cb834bba8
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/multiarch/wcpncpy-c.c
@@ -0,0 +1,25 @@
+/* Default wcsncpy implementation for S/390.
+ Copyright (C) 2015-2017 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 && IS_IN (libc)
+# define WCPNCPY __wcpncpy_c
+
+# include <wchar.h>
+extern __typeof (__wcpncpy) __wcpncpy_c;
+# include <wcsmbs/wcpncpy.c>
+#endif
diff --git a/REORG.TODO/sysdeps/s390/multiarch/wcpncpy-vx.S b/REORG.TODO/sysdeps/s390/multiarch/wcpncpy-vx.S
new file mode 100644
index 0000000000..6a1b587f0e
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/multiarch/wcpncpy-vx.S
@@ -0,0 +1,222 @@
+/* Vector optimized 32/64 bit S/390 version of wcpncpy.
+ Copyright (C) 2015-2017 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 && IS_IN (libc)
+
+# include "sysdep.h"
+# include "asm-syntax.h"
+
+ .text
+
+/* wchar_t * wcpncpy (wchar_t *dest, const wchar_t *src, size_t n)
+ Copies at most n characters of string src to dest
+ returning a pointer to its end or dest+n
+ if src is smaller than n.
+
+ Register usage:
+ -%r0 = return value
+ -%r1 = zero byte index
+ -%r2 = curr dst pointer
+ -%r3 = curr src pointer
+ -%r4 = n
+ -%r5 = current_len
+ -%r6 = loaded bytes
+ -%r7 = border, tmp
+*/
+ENTRY(__wcpncpy_vx)
+ .machine "z13"
+ .machinemode "zarch_nohighgprs"
+
+# if !defined __s390x__
+ llgfr %r4,%r4
+# endif /* !defined __s390x__ */
+
+ clgfi %r4,0
+ ber %r14 /* Nothing to do, if n == 0. */
+
+ vlbb %v16,0(%r3),6 /* Load s until next 4k-byte boundary. */
+
+ tmll %r3,3 /* Test if s is 4-byte aligned? */
+ jne .Lfallback /* And use common-code variant if not. */
+
+ vlvgp %v31,%r6,%r7 /* Save registers. */
+ lghi %r5,0 /* current_len = 0. */
+
+ lcbb %r6,0(%r3),6 /* Get bytes to 4k-byte boundary or 16. */
+ llgfr %r6,%r6 /* Convert 32bit to 64bit. */
+
+ /* Check range of maxlen and convert to byte-count. */
+# ifdef __s390x__
+ tmhh %r4,49152 /* Test bit 0 or 1 of maxlen. */
+ lghi %r1,-4 /* Max byte-count is 18446744073709551612. */
+# else
+ tmlh %r4,49152 /* Test bit 0 or 1 of maxlen. */
+ llilf %r1,4294967292 /* Max byte-count is 4294967292. */
+# endif /* !__s390x__ */
+ sllg %r4,%r4,2 /* Convert character-count to byte-count. */
+ locgrne %r4,%r1 /* Use max byte-count, if bit 0/1 was one. */
+
+ la %r0,0(%r4,%r2) /* Save destination pointer + n for return. */
+
+ clgrjle %r4,%r6,.Lremaining_v16 /* If n <= loaded-bytes
+ -> process remaining. */
+
+ /* n > loaded-byte-count */
+ vfenezf %v17,%v16,%v16 /* Find element not equal with zero search. */
+ vlgvb %r1,%v17,7 /* Load zero index or 16 if not found. */
+ aghi %r1,3 /* Also copy remaining bytes of zero. */
+ clrjl %r1,%r6,.Lfound_v16_store /* Found zero within loaded bytes,
+ copy and return. */
+
+ /* Align s to 16 byte. */
+ risbgn %r7,%r3,60,128+63,0 /* %r3 = bits 60-63 of %r2 'and' 15. */
+ lghi %r5,15 /* current_len = 15. */
+ slr %r5,%r7 /* Compute highest index to 16byte boundary. */
+
+ /* Zero not found and n > loaded-byte-count. */
+ vstl %v16,%r5,0(%r2) /* Copy loaded characters - no zero. */
+ ahi %r5,1 /* Start loop at next character. */
+
+ /* Now we are 16byte aligned, so we can load a full vreg
+ without page fault. */
+ lgr %r1,%r5 /* If %r5 + 64 < maxlen? -> loop64. */
+ aghi %r1,64
+ clgrjl %r1,%r4,.Lloop64
+
+ vl %v16,0(%r5,%r3) /* Load s. */
+ clgijl %r4,17,.Lremaining_v16 /* If n <=16,
+ process remaining bytes. */
+.Llt64:
+ lgr %r7,%r4
+ slgfi %r7,16 /* border_len = n - 16. */
+
+ clgrjhe %r5,%r7,.Lremaining_v16 /* If current_len >= border
+ then process remaining bytes. */
+ vfenezfs %v17,%v16,%v16 /* Find element not equal with zero search. */
+ je .Lfound_v16 /* Jump away if zero was found. */
+ vl %v18,16(%r5,%r3) /* Load next part of s. */
+ vst %v16,0(%r5,%r2) /* Store previous part without zero to dst. */
+ aghi %r5,16
+
+ clgrjhe %r5,%r7,.Lremaining_v18
+ vfenezfs %v17,%v18,%v18
+ je .Lfound_v18
+ vl %v16,16(%r5,%r3)
+ vst %v18,0(%r5,%r2)
+ aghi %r5,16
+
+ clgrjhe %r5,%r7,.Lremaining_v16
+ vfenezfs %v17,%v16,%v16
+ je .Lfound_v16
+ vl %v18,16(%r5,%r3)
+ vst %v16,0(%r5,%r2)
+ aghi %r5,16
+
+.Lremaining_v18:
+ vlr %v16,%v18
+.Lremaining_v16:
+ /* v16 contains the remaining bytes [1...16].
+ Store remaining bytes and append string-termination. */
+ vfenezf %v17,%v16,%v16 /* Find element not equal with zero search. */
+ slgrk %r7,%r4,%r5 /* Remaining bytes = maxlen - current_len */
+ aghi %r7,-1 /* vstl needs highest index. */
+ la %r2,0(%r5,%r2) /* vstl has no index register. */
+ vlgvb %r1,%v17,7 /* Load zero index or 16 if not found. */
+ aghi %r1,3 /* Also copy remaining bytes of zero. */
+ /* Zero in remaining bytes? -> jump away (zero-index <= max-index). */
+ clrjle %r1,%r7,.Lfound_v16_store
+ vstl %v16,%r7,0(%r2) /* Store remaining bytes without null
+ termination! */
+.Lend:
+ /* Restore saved registers. */
+ vlgvg %r6,%v31,0
+ vlgvg %r7,%v31,1
+ lgr %r2,%r0 /* Load saved dest-ptr. */
+ br %r14
+
+.Lfound_v16_32:
+ aghi %r5,32
+ j .Lfound_v16
+.Lfound_v18_48:
+ aghi %r5,32
+.Lfound_v18_16:
+ aghi %r5,16
+.Lfound_v18:
+ vlr %v16,%v18
+.Lfound_v16:
+ /* v16 contains a zero. Store remaining bytes to zero. current_len
+ has not reached border, thus checking for n is not needed! */
+ vlgvb %r1,%v17,7 /* Load byte index of zero. */
+ la %r2,0(%r5,%r2) /* vstl has no support for index-register. */
+ aghi %r1,3 /* Also copy remaining bytes of zero. */
+.Lfound_v16_store:
+ vstl %v16,%r1,0(%r2) /* Copy characters including zero. */
+ /* Fill remaining bytes with zero - remaining byte count always > 0. */
+ algr %r5,%r1 /* Remaining bytes (=%r4) = ... */
+ slgr %r4,%r5 /* = n - (currlen + zero_index + 1) */
+ la %r2,0(%r1,%r2) /* Pointer to zero. start filling beyond. */
+ lay %r0,-3(%r2) /* Save return-pointer to found zero. */
+ clgije %r4,1,.Lend /* Skip zero-filling, if found-zero is last
+ possible character.
+ (1 is substracted from r4 below!). */
+ aghi %r4,-2 /* mvc with exrl needs count - 1.
+ (additional -1, see remaining bytes above) */
+ srlg %r6,%r4,8 /* Split into 256 byte blocks. */
+ ltgr %r6,%r6
+ je .Lzero_lt256
+.Lzero_loop256:
+ mvc 1(256,%r2),0(%r2) /* Fill 256 zeros at once. */
+ la %r2,256(%r2)
+ brctg %r6,.Lzero_loop256 /* Loop until all blocks are processed. */
+.Lzero_lt256:
+ exrl %r4,.Lmvc_lt256
+ j .Lend
+.Lmvc_lt256:
+ mvc 1(1,%r2),0(%r2)
+
+ /* Find zero in 16byte aligned loop. */
+.Lloop64:
+ vl %v16,0(%r5,%r3)
+ vfenezfs %v17,%v16,%v16 /* Find element not equal with zero search. */
+ je .Lfound_v16 /* Jump away if zero was found. */
+ vl %v18,16(%r5,%r3) /* Load next part of s. */
+ vst %v16,0(%r5,%r2) /* Store previous part without zero to dst. */
+ vfenezfs %v17,%v18,%v18
+ je .Lfound_v18_16
+ vl %v16,32(%r5,%r3)
+ vst %v18,16(%r5,%r2)
+ vfenezfs %v17,%v16,%v16
+ je .Lfound_v16_32
+ vl %v18,48(%r5,%r3)
+ vst %v16,32(%r5,%r2)
+ vfenezfs %v17,%v18,%v18
+ je .Lfound_v18_48
+ vst %v18,48(%r5,%r2)
+
+ aghi %r5,64
+ lgr %r1,%r5 /* If %r5 + 64 < maxlen? -> loop64. */
+ aghi %r1,64
+ clgrjl %r1,%r4,.Lloop64
+
+ vl %v16,0(%r5,%r3) /* Load s. */
+ j .Llt64
+
+.Lfallback:
+ jg __wcpncpy_c
+END(__wcpncpy_vx)
+#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */
diff --git a/REORG.TODO/sysdeps/s390/multiarch/wcpncpy.c b/REORG.TODO/sysdeps/s390/multiarch/wcpncpy.c
new file mode 100644
index 0000000000..1a19a9939a
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/multiarch/wcpncpy.c
@@ -0,0 +1,28 @@
+/* Multiple versions of wcpncpy.
+ Copyright (C) 2015-2017 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 && IS_IN (libc)
+# include <wchar.h>
+# include <ifunc-resolve.h>
+
+s390_vx_libc_ifunc (__wcpncpy)
+weak_alias (__wcpncpy, wcpncpy)
+
+#else
+# include <wcsmbs/wcpncpy.c>
+#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)) */
diff --git a/REORG.TODO/sysdeps/s390/multiarch/wcscat-c.c b/REORG.TODO/sysdeps/s390/multiarch/wcscat-c.c
new file mode 100644
index 0000000000..ef7c000455
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/multiarch/wcscat-c.c
@@ -0,0 +1,25 @@
+/* Default wcscat implementation for S/390.
+ Copyright (C) 2015-2017 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 && IS_IN (libc)
+# define WCSCAT __wcscat_c
+
+# include <wchar.h>
+extern __typeof (__wcscat) __wcscat_c;
+# include <wcsmbs/wcscat.c>
+#endif
diff --git a/REORG.TODO/sysdeps/s390/multiarch/wcscat-vx.S b/REORG.TODO/sysdeps/s390/multiarch/wcscat-vx.S
new file mode 100644
index 0000000000..604a849906
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/multiarch/wcscat-vx.S
@@ -0,0 +1,175 @@
+/* Vector optimized 32/64 bit S/390 version of wcscat.
+ Copyright (C) 2015-2017 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 && IS_IN (libc)
+
+# include "sysdep.h"
+# include "asm-syntax.h"
+
+ .text
+
+/* wchar_t * wcscat (wchar_t *dest, const wchar_t *src)
+ Concatenate two strings.
+
+ Register usage:
+ -r0=saved dest pointer for return
+ -r1=tmp
+ -r2=dest
+ -r3=src
+ -r4=tmp
+ -r5=current_len
+ -v16=part of src
+ -v17=index of zero
+ -v18=part of src
+*/
+ENTRY(__wcscat_vx)
+ .machine "z13"
+ .machinemode "zarch_nohighgprs"
+
+ vlbb %v16,0(%r2),6 /* Load s until next 4k-byte boundary. */
+ lcbb %r1,0(%r2),6 /* Get bytes to 4k-byte boundary or 16. */
+
+ /* __wcslen_c can handle non 4byte aligned pointers,
+ but __wcscpy_c not. Thus if either src or dest is
+ not 4byte aligned, use __wcscat_c. */
+ tmll %r2,3 /* Test if s is 4-byte aligned? */
+ jne .Lfallback /* And use common-code variant if not. */
+ tmll %r3,3 /* Test if src is 4-byte aligned? */
+ jne .Lfallback /* And use common-code variant if not. */
+
+ lgr %r0,%r2 /* Save destination pointer for return. */
+
+ /* WCSLEN
+ r1 = loaded bytes (tmp)
+ r4 = zero byte index (tmp)
+ r2 = dst
+ */
+
+ vfenezf %v16,%v16,%v16 /* Find element not equal with zero search. */
+ vlgvb %r5,%v16,7 /* Load zero index or 16 if not found. */
+ clrjl %r5,%r1,.Llen_end /* Found zero within loaded bytes, end. */
+
+ /* Align s to 16 byte. */
+ risbgn %r1,%r2,60,128+63,0 /* %r3 = bits 60-63 of %r2 'and' 15. */
+ lghi %r5,16 /* current_len = 16. */
+ slr %r5,%r1 /* Compute bytes to 16bytes boundary. */
+
+ /* Find zero in 16byte aligned loop. */
+.Llen_loop:
+ vl %v16,0(%r5,%r2) /* Load s. */
+ vfenezfs %v16,%v16,%v16 /* Find element not equal with zero search. */
+ je .Llen_found /* Jump away if zero was found. */
+ vl %v16,16(%r5,%r2)
+ vfenezfs %v16,%v16,%v16
+ je .Llen_found16
+ vl %v16,32(%r5,%r2)
+ vfenezfs %v16,%v16,%v16
+ je .Llen_found32
+ vl %v16,48(%r5,%r2)
+ vfenezfs %v16,%v16,%v16
+ je .Llen_found48
+
+ aghi %r5,64
+ j .Llen_loop /* No zero -> loop. */
+
+.Llen_found48:
+ aghi %r5,16
+.Llen_found32:
+ aghi %r5,16
+.Llen_found16:
+ aghi %r5,16
+.Llen_found:
+ vlgvb %r4,%v16,7 /* Load byte index of zero. */
+ algr %r5,%r4
+
+.Llen_end:
+ /* WCSCPY
+ %r1 = loaded bytes (tmp)
+ %r4 = zero byte index (tmp)
+ %r3 = curr src pointer
+ %r2 = curr dst pointer
+ */
+ la %r2,0(%r5,%r2) /* strcpy at end of dst-string. */
+
+ vlbb %v16,0(%r3),6 /* Load s until next 4k-byte boundary. */
+ lcbb %r1,0(%r3),6 /* Get bytes to 4k-byte boundary or 16. */
+
+ vfenezf %v17,%v16,%v16 /* Find element not equal with zero search. */
+ vlgvb %r5,%v17,7 /* Load zero index or 16 if not found. */
+ clrjl %r5,%r1,.Lcpy_found_align /* If found zero within loaded bytes,
+ copy bytes before and return. */
+
+ /* Align s to 16 byte. */
+ risbgn %r4,%r3,60,128+63,0 /* %r3 = bits 60-63 of %r2 'and' 15. */
+ lghi %r5,15 /* current_len = 15. */
+ slr %r5,%r4 /* Compute highest index to 16byte boundary. */
+
+ vstl %v16,%r5,0(%r2) /* Copy loaded characters - no zero. */
+ ahi %r5,1 /* Start loop at next character. */
+
+ /* Find zero in 16byte aligned loop. */
+.Lcpy_loop:
+ vl %v16,0(%r5,%r3) /* Load s. */
+ vfenezfs %v17,%v16,%v16 /* Find element not equal with zero search. */
+ je .Lcpy_found_v16_0 /* Jump away if zero was found. */
+ vl %v18,16(%r5,%r3) /* Load next part of s. */
+ vst %v16,0(%r5,%r2) /* Save previous part without zero to dst. */
+ vfenezfs %v17,%v18,%v18
+ je .Lcpy_found_v18_16
+ vl %v16,32(%r5,%r3)
+ vst %v18,16(%r5,%r2)
+ vfenezfs %v17,%v16,%v16
+ je .Lcpy_found_v16_32
+ vl %v18,48(%r5,%r3)
+ vst %v16,32(%r5,%r2)
+ vfenezfs %v17,%v18,%v18
+ je .Lcpy_found_v18_48
+ vst %v18,48(%r5,%r2)
+
+ aghi %r5,64
+ j .Lcpy_loop /* No zero -> loop. */
+
+.Lcpy_found_v16_32:
+ aghi %r5,32
+.Lcpy_found_v16_0:
+ la %r4,0(%r5,%r2)
+ vlgvb %r1,%v17,7 /* Load byte index of zero. */
+ aghi %r1,3 /* Also copy remaining bytes of zero. */
+ vstl %v16,%r1,0(%r4) /* Copy characters including zero. */
+ lgr %r2,%r0 /* Load saved dest-ptr. */
+ br %r14
+
+.Lcpy_found_v18_48:
+ aghi %r5,32
+.Lcpy_found_v18_16:
+ la %r4,16(%r5,%r2)
+ vlgvb %r1,%v17,7 /* Load byte index of zero. */
+ aghi %r1,3 /* Also copy remaining bytes of zero. */
+ vstl %v18,%r1,0(%r4) /* Copy characters including zero. */
+ lgr %r2,%r0 /* Load saved dest-ptr. */
+ br %r14
+
+.Lcpy_found_align:
+ aghi %r5,3 /* Also copy remaining bytes of found zero. */
+ vstl %v16,%r5,0(%r2) /* Copy characters including zero. */
+ lgr %r2,%r0 /* Load saved dest-ptr. */
+ br %r14
+.Lfallback:
+ jg __wcscat_c
+END(__wcscat_vx)
+#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */
diff --git a/REORG.TODO/sysdeps/s390/multiarch/wcscat.c b/REORG.TODO/sysdeps/s390/multiarch/wcscat.c
new file mode 100644
index 0000000000..2e7fdedf22
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/multiarch/wcscat.c
@@ -0,0 +1,28 @@
+/* Multiple versions of wcscat.
+ Copyright (C) 2015-2017 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 && IS_IN (libc)
+# include <wchar.h>
+# include <ifunc-resolve.h>
+
+s390_vx_libc_ifunc (__wcscat)
+weak_alias (__wcscat, wcscat)
+
+#else
+# include <wcsmbs/wcscat.c>
+#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)) */
diff --git a/REORG.TODO/sysdeps/s390/multiarch/wcschr-c.c b/REORG.TODO/sysdeps/s390/multiarch/wcschr-c.c
new file mode 100644
index 0000000000..b084983dd8
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/multiarch/wcschr-c.c
@@ -0,0 +1,37 @@
+/* Default wcschr implementation for S/390.
+ Copyright (C) 2015-2017 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 && IS_IN (libc)
+# define WCSCHR __wcschr_c
+
+# include <wchar.h>
+extern __typeof (__wcschr) __wcschr_c;
+# undef weak_alias
+# define weak_alias(name, alias)
+# ifdef SHARED
+# undef libc_hidden_def
+# define libc_hidden_def(name) \
+ __hidden_ver1 (__wcschr_c, __GI_wcschr, __wcschr_c); \
+ strong_alias (__wcschr_c, __wcschr_c_1); \
+ __hidden_ver1 (__wcschr_c_1, __GI___wcschr, __wcschr_c_1);
+# undef libc_hidden_weak
+# define libc_hidden_weak(name)
+# endif /* SHARED */
+
+# include <wcsmbs/wcschr.c>
+#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */
diff --git a/REORG.TODO/sysdeps/s390/multiarch/wcschr-vx.S b/REORG.TODO/sysdeps/s390/multiarch/wcschr-vx.S
new file mode 100644
index 0000000000..5a04d44dde
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/multiarch/wcschr-vx.S
@@ -0,0 +1,103 @@
+/* Vector optimized 32/64 bit S/390 version of wcschr.
+ Copyright (C) 2015-2017 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 && IS_IN (libc)
+
+# include "sysdep.h"
+# include "asm-syntax.h"
+
+ .text
+
+/* wchar_t *wcschr (const wchar_t *s, wchar_t c)
+ Locate character in string.
+
+ Register usage:
+ -r1=tmp
+ -r2=s
+ -r3=c
+ -r4=tmp
+ -r5=current_len
+ -v16=part of s
+ -v17=index of unequal
+ -v18=replicated c
+*/
+ENTRY(__wcschr_vx)
+ .machine "z13"
+ .machinemode "zarch_nohighgprs"
+
+ vlbb %v16,0(%r2),6 /* Load s until next 4k-byte boundary. */
+ lcbb %r1,0(%r2),6 /* Get bytes to 4k-byte boundary or 16. */
+
+ tmll %r2,3 /* Test if s is 4-byte aligned? */
+ jne .Lfallback /* And use common-code variant if not. */
+
+ lghi %r5,0 /* current_len = 0. */
+
+ vlvgf %v18,%r3,0 /* Generate vector which elements are all c. */
+ vrepf %v18,%v18,0
+
+ vfeezfs %v16,%v16,%v18 /* Find element equal with zero search. */
+ vlgvb %r4,%v16,7 /* Load byte index of character or zero. */
+ clrjl %r4,%r1,.Lfound /* Return if c/zero is in loaded bytes. */
+
+ /* Align s to 16 byte. */
+ risbgn %r4,%r2,60,128+63,0 /* %r3 = bits 60-63 of %r2 'and' 15. */
+ lghi %r5,16 /* current_len = 16. */
+ slr %r5,%r4 /* Compute bytes to 16bytes boundary. */
+
+ /* Find c/zero in 16byte aligned loop */
+.Lloop:
+ vl %v16,0(%r5,%r2) /* Load s. */
+ vfeezfs %v16,%v16,%v18 /* Find element equal with zero search. */
+ jno .Lfound /* Found c/zero (cc=0|1|2). */
+ vl %v16,16(%r5,%r2)
+ vfeezfs %v16,%v16,%v18
+ jno .Lfound16
+ vl %v16,32(%r5,%r2)
+ vfeezfs %v16,%v16,%v18
+ jno .Lfound32
+ vl %v16,48(%r5,%r2)
+ vfeezfs %v16,%v16,%v18
+ jno .Lfound48
+
+ aghi %r5,64
+ j .Lloop /* No character and no zero -> loop. */
+
+.Lfound48:
+ la %r5,16(%r5) /* Use la since aghi would clobber cc. */
+.Lfound32:
+ la %r5,16(%r5)
+.Lfound16:
+ la %r5,16(%r5)
+.Lfound:
+ je .Lzero /* Found zero, but no c before that zero. */
+
+.Lcharacter:
+ vlgvb %r4,%v16,7 /* Load byte index of character. */
+ algr %r5,%r4
+ la %r2,0(%r5,%r2) /* Return pointer to character. */
+ br %r14
+
+.Lzero:
+ clije %r3,0,.Lcharacter /* Found zero and c is zero. */
+ lghi %r2,0 /* Return null if character not found. */
+ br %r14
+.Lfallback:
+ jg __wcschr_c
+END(__wcschr_vx)
+#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */
diff --git a/REORG.TODO/sysdeps/s390/multiarch/wcschr.c b/REORG.TODO/sysdeps/s390/multiarch/wcschr.c
new file mode 100644
index 0000000000..59e5df5706
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/multiarch/wcschr.c
@@ -0,0 +1,32 @@
+/* Multiple versions of wcschr.
+ Copyright (C) 2015-2017 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 && 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_redirected (__redirect___wcschr, __wcschr)
+weak_alias (__wcschr, wcschr)
+
+#else
+# include <wcsmbs/wcschr.c>
+#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)) */
diff --git a/REORG.TODO/sysdeps/s390/multiarch/wcschrnul-c.c b/REORG.TODO/sysdeps/s390/multiarch/wcschrnul-c.c
new file mode 100644
index 0000000000..095ea1202c
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/multiarch/wcschrnul-c.c
@@ -0,0 +1,25 @@
+/* Default wcschrnul implementation for S/390.
+ Copyright (C) 2015-2017 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 && IS_IN (libc)
+# define WCSCHRNUL __wcschrnul_c
+
+# include <wchar.h>
+extern __typeof (__wcschrnul) __wcschrnul_c;
+# include <wcsmbs/wcschrnul.c>
+#endif
diff --git a/REORG.TODO/sysdeps/s390/multiarch/wcschrnul-vx.S b/REORG.TODO/sysdeps/s390/multiarch/wcschrnul-vx.S
new file mode 100644
index 0000000000..6aa94823ab
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/multiarch/wcschrnul-vx.S
@@ -0,0 +1,97 @@
+/* Vector optimized 32/64 bit S/390 version of wcschrnul.
+ Copyright (C) 2015-2017 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 && IS_IN (libc)
+
+# include "sysdep.h"
+# include "asm-syntax.h"
+
+ .text
+
+/* wchar_t* wcschrnul (const wchar_t *s, wchar_t c)
+ Returns pointer to first c or to \0 if c not found.
+
+ Register usage:
+ -r1=tmp
+ -r2=s and return pointer
+ -r3=c
+ -r4=tmp
+ -r5=current_len
+ -v16=part of s
+ -v18=vector with c replicated in every byte
+*/
+ENTRY(__wcschrnul_vx)
+ .machine "z13"
+ .machinemode "zarch_nohighgprs"
+
+ vlbb %v16,0(%r2),6 /* Load s until next 4k-byte boundary. */
+ lcbb %r1,0(%r2),6 /* Get bytes to 4k-byte boundary or 16. */
+
+ tmll %r2,3 /* Test if s is 4-byte aligned? */
+ jne .Lfallback /* And use common-code variant if not. */
+
+ lghi %r5,0 /* current_len = 0. */
+
+ vlvgf %v18,%r3,0 /* Generate vector which elements are all c. */
+ vrepf %v18,%v18,0
+
+ vfeezfs %v16,%v16,%v18 /* Find element equal with zero search. */
+ vlgvb %r4,%v16,7 /* Load byte index of character or zero. */
+ clrjl %r4,%r1,.Lfound /* Return if c/zero is in loaded bytes. */
+
+ /* Align s to 16 byte. */
+ risbgn %r4,%r2,60,128+63,0 /* %r3 = bits 60-63 of %r2 'and' 15. */
+ lghi %r5,16 /* current_len = 16. */
+ slr %r5,%r4 /* Compute bytes to 16bytes boundary. */
+
+ /* Find c/zero in 16byte aligned loop */
+.Lloop:
+ vl %v16,0(%r5,%r2) /* Load s. */
+ vfeezfs %v16,%v16,%v18 /* Find element equal with zero search. */
+ jno .Lfound /* Found c/zero (cc=0|1|2). */
+ vl %v16,16(%r5,%r2)
+ vfeezfs %v16,%v16,%v18
+ jno .Lfound16
+ vl %v16,32(%r5,%r2)
+ vfeezfs %v16,%v16,%v18
+ jno .Lfound32
+ vl %v16,48(%r5,%r2)
+ vfeezfs %v16,%v16,%v18
+ jno .Lfound48
+
+ aghi %r5,64
+ j .Lloop /* No character and no zero -> loop. */
+
+ /* Found character or zero */
+.Lfound48:
+ aghi %r5,16
+.Lfound32:
+ aghi %r5,16
+.Lfound16:
+ aghi %r5,16
+.Lfound:
+ vlgvb %r1,%v16,7 /* Load byte index of character. */
+ algr %r5,%r1
+ la %r2,0(%r5,%r2) /* Return pointer to character. */
+
+.Lend:
+ br %r14
+.Lfallback:
+ jg __wcschrnul_c
+END(__wcschrnul_vx)
+#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */
diff --git a/REORG.TODO/sysdeps/s390/multiarch/wcschrnul.c b/REORG.TODO/sysdeps/s390/multiarch/wcschrnul.c
new file mode 100644
index 0000000000..f01ea9f9ac
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/multiarch/wcschrnul.c
@@ -0,0 +1,28 @@
+/* Multiple versions of wcschrnul.
+ Copyright (C) 2015-2017 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 && IS_IN (libc)
+# include <wchar.h>
+# include <ifunc-resolve.h>
+
+s390_vx_libc_ifunc (__wcschrnul)
+weak_alias (__wcschrnul, wcschrnul)
+
+#else
+# include <wcsmbs/wcschrnul.c>
+#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)) */
diff --git a/REORG.TODO/sysdeps/s390/multiarch/wcscmp-c.c b/REORG.TODO/sysdeps/s390/multiarch/wcscmp-c.c
new file mode 100644
index 0000000000..7a148f41bb
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/multiarch/wcscmp-c.c
@@ -0,0 +1,32 @@
+/* Default wcscmp implementation for S/390.
+ Copyright (C) 2015-2017 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 && IS_IN (libc)
+# define WCSCMP __wcscmp_c
+
+# include <wchar.h>
+extern __typeof (wcscmp) __wcscmp_c;
+# undef weak_alias
+# define weak_alias(name, alias)
+# ifdef SHARED
+# undef libc_hidden_def
+# define libc_hidden_def(name) \
+ __hidden_ver1 (__wcscmp_c, __GI___wcscmp, __wcscmp_c);
+# endif /* SHARED */
+# include <wcsmbs/wcscmp.c>
+#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */
diff --git a/REORG.TODO/sysdeps/s390/multiarch/wcscmp-vx.S b/REORG.TODO/sysdeps/s390/multiarch/wcscmp-vx.S
new file mode 100644
index 0000000000..3b92bbd515
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/multiarch/wcscmp-vx.S
@@ -0,0 +1,131 @@
+/* Vector optimized 32/64 bit S/390 version of wcscmp.
+ Copyright (C) 2015-2017 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 && IS_IN (libc)
+
+# include "sysdep.h"
+# include "asm-syntax.h"
+
+ .text
+
+/* int wcscmp (const wchar_t *s1, const wchar_t *s2)
+ Compare two strings
+
+ Register usage:
+ -r1=loaded byte count s1
+ -r2=s1
+ -r3=s2
+ -r4=loaded byte coutn s2, tmp
+ -r5=current_len
+ -v16=part of s1
+ -v17=part of s2
+ -v18=index of unequal
+*/
+ENTRY(__wcscmp_vx)
+ .machine "z13"
+ .machinemode "zarch_nohighgprs"
+
+ lghi %r5,0 /* current_len = 0. */
+
+.Lloop:
+ vlbb %v16,0(%r5,%r2),6 /* Load s1 to block boundary. */
+ vlbb %v17,0(%r5,%r3),6 /* Load s2 to block boundary. */
+ lcbb %r1,0(%r5,%r2),6 /* Get loaded byte count of s1. */
+ jo .Llt16_1 /* Jump away if vr is not fully loaded. */
+ lcbb %r4,0(%r5,%r3),6
+ jo .Llt16_2 /* Jump away if vr is not fully loaded. */
+ /* Both vrs are fully loaded. */
+ aghi %r5,16
+ vfenezfs %v18,%v16,%v17 /* Compare not equal with zero search. */
+ jno .Lfound
+
+ vlbb %v16,0(%r5,%r2),6
+ vlbb %v17,0(%r5,%r3),6
+ lcbb %r1,0(%r5,%r2),6
+ jo .Llt16_1
+ lcbb %r4,0(%r5,%r3),6
+ jo .Llt16_2
+ aghi %r5,16
+ vfenezfs %v18,%v16,%v17
+ jno .Lfound
+
+ vlbb %v16,0(%r5,%r2),6
+ vlbb %v17,0(%r5,%r3),6
+ lcbb %r1,0(%r5,%r2),6
+ jo .Llt16_1
+ lcbb %r4,0(%r5,%r3),6
+ jo .Llt16_2
+ aghi %r5,16
+ vfenezfs %v18,%v16,%v17
+ jno .Lfound
+
+ vlbb %v16,0(%r5,%r2),6
+ vlbb %v17,0(%r5,%r3),6
+ lcbb %r1,0(%r5,%r2),6
+ jo .Llt16_1
+ lcbb %r4,0(%r5,%r3),6
+ jo .Llt16_2
+ aghi %r5,16
+ vfenezfs %v18,%v16,%v17
+ jno .Lfound
+ j .Lloop
+
+.Lcmp_one_char:
+ /* At least one of both strings is not 4-byte aligned
+ and there is no full character before next block-boundary.
+ Compare one character to get over the boundary and
+ proceed with normal loop! */
+ vlef %v16,0(%r5,%r2),0 /* Load one character. */
+ vlef %v17,0(%r5,%r3),0
+ lghi %r1,4 /* Loaded byte count is 4. */
+ j .Llt_cmp /* Proceed with comparision. */
+
+.Llt16_1:
+ lcbb %r4,0(%r5,%r3),6 /* Get loaded byte count of s2. */
+.Llt16_2:
+ clr %r1,%r4
+ locrh %r1,%r4 /* Get minimum of bytes loaded in s1/2. */
+ nill %r1,65532 /* Align bytes loaded to full characters. */
+ jz .Lcmp_one_char /* Jump away if no full char is available. */
+.Llt_cmp:
+ algfr %r5,%r1 /* Add smallest loaded bytes to current_len. */
+ vfenezfs %v18,%v16,%v17 /* Compare not equal with zero search. */
+ vlgvb %r4,%v18,7 /* Get not equal index or 16 if all equal. */
+ clrjl %r4,%r1,.Lfound /* Jump away if miscompare is within loaded
+ bytes. */
+ j .Lloop
+
+.Lfound:
+ /* vfenezf found an unequal element or zero.
+ This instruction compares unsigned words, but wchar_t is signed.
+ Thus we have to compare the found element again. */
+ vlgvb %r4,%v18,7 /* Extract not equal byte-index, */
+ srl %r4,2 /* Convert it to character-index. */
+ vlgvf %r3,%v16,0(%r4) /* Load character-values. */
+ vlgvf %r4,%v17,0(%r4)
+ cr %r3,%r4
+ je .Lend_equal
+ lghi %r2,1
+ lghi %r1,-1
+ locgrl %r2,%r1
+ br %r14
+.Lend_equal:
+ lghi %r2,0
+ br %r14
+END(__wcscmp_vx)
+#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */
diff --git a/REORG.TODO/sysdeps/s390/multiarch/wcscmp.c b/REORG.TODO/sysdeps/s390/multiarch/wcscmp.c
new file mode 100644
index 0000000000..a5c2b69a29
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/multiarch/wcscmp.c
@@ -0,0 +1,30 @@
+/* Multiple versions of wcscmp.
+ Copyright (C) 2015-2017 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 && IS_IN (libc)
+# define __wcscmp __redirect___wcscmp
+# include <wchar.h>
+# undef __wcscmp
+# include <ifunc-resolve.h>
+
+s390_vx_libc_ifunc_redirected (__redirect___wcscmp, __wcscmp)
+weak_alias (__wcscmp, wcscmp)
+
+#else
+# include <wcsmbs/wcscmp.c>
+#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)) */
diff --git a/REORG.TODO/sysdeps/s390/multiarch/wcscpy-c.c b/REORG.TODO/sysdeps/s390/multiarch/wcscpy-c.c
new file mode 100644
index 0000000000..342c247a8f
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/multiarch/wcscpy-c.c
@@ -0,0 +1,25 @@
+/* Default wcscpy implementation for S/390.
+ Copyright (C) 2015-2017 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 && IS_IN (libc)
+# define WCSCPY __wcscpy_c
+
+# include <wchar.h>
+extern __typeof (wcscpy) __wcscpy_c;
+# include <wcsmbs/wcscpy.c>
+#endif
diff --git a/REORG.TODO/sysdeps/s390/multiarch/wcscpy-vx.S b/REORG.TODO/sysdeps/s390/multiarch/wcscpy-vx.S
new file mode 100644
index 0000000000..a8adc20dea
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/multiarch/wcscpy-vx.S
@@ -0,0 +1,111 @@
+/* Vector optimized 32/64 bit S/390 version of wcscpy.
+ Copyright (C) 2015-2017 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 && IS_IN (libc)
+
+# include "sysdep.h"
+# include "asm-syntax.h"
+
+ .text
+
+/* char * wcscpy (const wchar_t *dest, const wchar_t *src)
+ Copy string src to dest.
+
+ Register usage:
+ -r0=border-len for switching to vector-instructions
+ -r1=tmp
+ -r2=dest and return value
+ -r3=src
+ -r4=tmp
+ -r5=current_len
+ -v16=part of src
+ -v17=index of zero
+ -v18=part of src
+*/
+ENTRY(__wcscpy_vx)
+ .machine "z13"
+ .machinemode "zarch_nohighgprs"
+
+ vlbb %v16,0(%r3),6 /* Load s until next 4k-byte boundary. */
+ lcbb %r1,0(%r3),6 /* Get bytes to 4k-byte boundary or 16. */
+
+ tmll %r3,3 /* Test if s is 4-byte aligned? */
+ jne .Lfallback /* And use common-code variant if not. */
+
+ vfenezf %v17,%v16,%v16 /* Find element not equal with zero search. */
+ vlgvb %r5,%v17,7 /* Load zero index or 16 if not found. */
+ clrjl %r5,%r1,.Lfound_align /* If found zero within loaded bytes,
+ copy bytes before and return. */
+
+ /* Align s to 16 byte. */
+ risbgn %r4,%r3,60,128+63,0 /* %r3 = bits 60-63 of %r2 'and' 15. */
+ lghi %r5,15 /* current_len = 15. */
+ slr %r5,%r4 /* Compute highest index to 16byte boundary. */
+
+ vstl %v16,%r5,0(%r2) /* Copy loaded characters - no zero. */
+ ahi %r5,1 /* Start loop at next character. */
+
+ /* Find zero in 16byte aligned loop. */
+.Lloop:
+ vl %v16,0(%r5,%r3) /* Load s. */
+ vfenezfs %v17,%v16,%v16 /* Find element not equal with zero search. */
+ je .Lfound_v16_0 /* Jump away if zero was found. */
+ vl %v18,16(%r5,%r3) /* Load next part of s. */
+ vst %v16,0(%r5,%r2) /* Store previous part without zero to dst. */
+ vfenezfs %v17,%v18,%v18
+ je .Lfound_v18_16
+ vl %v16,32(%r5,%r3)
+ vst %v18,16(%r5,%r2)
+ vfenezfs %v17,%v16,%v16
+ je .Lfound_v16_32
+ vl %v18,48(%r5,%r3)
+ vst %v16,32(%r5,%r2)
+ vfenezfs %v17,%v18,%v18
+ je .Lfound_v18_48
+ vst %v18,48(%r5,%r2)
+
+ aghi %r5,64
+ j .Lloop /* No zero found -> loop. */
+
+.Lfound_v16_32:
+ aghi %r5,32
+.Lfound_v16_0:
+ la %r3,0(%r5,%r2)
+ vlgvb %r1,%v17,7 /* Load byte index of zero. */
+ aghi %r1,3 /* Also copy remaining bytes of zero. */
+ vstl %v16,%r1,0(%r3) /* Copy characters including zero. */
+ br %r14
+
+.Lfound_v18_48:
+ aghi %r5,32
+.Lfound_v18_16:
+ la %r3,16(%r5,%r2)
+ vlgvb %r1,%v17,7 /* Load byte index of zero. */
+ aghi %r1,3 /* Also copy remaining bytes of zero. */
+ vstl %v18,%r1,0(%r3) /* Copy characters including zero. */
+ br %r14
+
+.Lfound_align:
+ aghi %r5,3 /* Also copy remaining bytes of zero. */
+ vstl %v16,%r5,0(%r2) /* Copy characters including zero. */
+ br %r14
+
+.Lfallback:
+ jg __wcscpy_c
+END(__wcscpy_vx)
+#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */
diff --git a/REORG.TODO/sysdeps/s390/multiarch/wcscpy.c b/REORG.TODO/sysdeps/s390/multiarch/wcscpy.c
new file mode 100644
index 0000000000..bd68b1725d
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/multiarch/wcscpy.c
@@ -0,0 +1,27 @@
+/* Multiple versions of wcscpy.
+ Copyright (C) 2015-2017 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 && IS_IN (libc)
+# include <wchar.h>
+# include <ifunc-resolve.h>
+
+s390_vx_libc_ifunc2 (__wcscpy, wcscpy)
+
+#else
+# include <wcsmbs/wcscpy.c>
+#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)) */
diff --git a/REORG.TODO/sysdeps/s390/multiarch/wcscspn-c.c b/REORG.TODO/sysdeps/s390/multiarch/wcscspn-c.c
new file mode 100644
index 0000000000..937e1d1963
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/multiarch/wcscspn-c.c
@@ -0,0 +1,26 @@
+/* Default wcscscpn implementation for S/390.
+ Copyright (C) 2015-2017 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 && IS_IN (libc)
+# define WCSCSPN __wcscspn_c
+
+# include <wchar.h>
+extern __typeof (wcscspn) __wcscspn_c;
+
+# include <wcsmbs/wcscspn.c>
+#endif
diff --git a/REORG.TODO/sysdeps/s390/multiarch/wcscspn-vx.S b/REORG.TODO/sysdeps/s390/multiarch/wcscspn-vx.S
new file mode 100644
index 0000000000..cd528907d6
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/multiarch/wcscspn-vx.S
@@ -0,0 +1,293 @@
+/* Vector optimized 32/64 bit S/390 version of wcscspn.
+ Copyright (C) 2015-2017 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 && IS_IN (libc)
+
+# include "sysdep.h"
+# include "asm-syntax.h"
+
+ .text
+
+/* size_t wcscspn (const wchar_t *s, const wchar_t * reject)
+ The wcscspn() function calculates the length of the initial segment
+ of s which consists entirely of characters not in reject.
+
+ This method checks the length of reject string. If it fits entirely
+ in one vector register, a fast algorithm is used, which does not need
+ to check multiple parts of accept-string. Otherwise a slower full
+ check of accept-string is used.
+
+ register overview:
+ r3: pointer to start of reject-string
+ r2: pointer to start of search-string
+ r0: loaded byte count of vlbb search-string
+ r4: found byte index
+ r1: current return len
+ v16: search-string
+ v17: reject-string
+ v18: temp-vreg
+
+ ONLY FOR SLOW:
+ v19: first reject-string
+ v20: zero for preparing acc-vector
+ v21: global mask; 1 indicates a match between
+ search-string-vreg and any reject-character
+ v22: current mask; 1 indicates a match between
+ search-string-vreg and any reject-character in current acc-vreg
+ v30, v31: for re-/storing registers r6, r8, r9
+ r5: current len of reject-string
+ r6: zero-index in search-string or 16 if no zero
+ or min(zero-index, loaded byte count)
+ r8: >0, if former reject-string-part contains a zero,
+ otherwise =0;
+ r9: loaded byte count of vlbb reject-string
+*/
+ENTRY(__wcscspn_vx)
+ .machine "z13"
+ .machinemode "zarch_nohighgprs"
+
+ tmll %r2,3 /* Test if s is 4-byte aligned? */
+ jne .Lfallback /* And use common-code variant if not. */
+
+ /*
+ Check if reject-string fits in one vreg:
+ ----------------------------------------
+ */
+ vlbb %v17,0(%r3),0 /* Load reject. */
+ lcbb %r0,0(%r3),0
+ jo .Lcheck_onbb /* Special case if reject
+ lays on block-boundary. */
+
+.Lcheck_notonbb:
+ lghi %r1,0 /* Zero out current len. */
+ vistrfs %v17,%v17 /* Fill with zeros after first zero. */
+ je .Lfast /* Zero found -> reject fits in one vreg. */
+ j .Lslow /* No zero -> reject exceeds one vreg. */
+
+
+.Lcheck_onbb:
+ /* Reject lays on block-boundary. */
+ nill %r0,65532 /* Recognize only fully loaded characters. */
+ je .Lcheck_onbb2 /* Reload vr, if we loaded no full wchar_t. */
+ vfenezf %v18,%v17,%v17 /* Search zero in loaded reject bytes. */
+ vlgvb %r4,%v18,7 /* Get index of zero or 16 if not found. */
+ clrjl %r4,%r0,.Lcheck_notonbb /* Zero index < loaded bytes count ->
+ Reject fits in one vreg;
+ Fill with zeros and proceed
+ with FAST. */
+.Lcheck_onbb2:
+ vl %v17,0(%r3) /* Load reject, which exceeds loaded bytes. */
+ j .Lcheck_notonbb /* Check if reject fits in one vreg. */
+
+
+ /*
+ Search s for reject in one vreg
+ -------------------------------
+ */
+.Lfast:
+ /* Complete reject-string in v17 and remaining bytes are zero. */
+
+ vlbb %v16,0(%r2),6 /* Load s until next 4k-byte boundary. */
+ lcbb %r0,0(%r2),6 /* Get bytes to 4k-byte boundary or 16. */
+
+ vfaezfs %v18,%v16,%v17,0 /* Find first element in v16
+ unequal to any in v17
+ or first zero element. */
+ vlgvb %r4,%v18,7 /* Load byte index of found element. */
+ clrjl %r4,%r0,.Lfast_loop_found2 /* If found index is within loaded
+ bytes, return with found element
+ index (=equal count). */
+
+ /* Align s to 16 byte. */
+ risbgn %r4,%r2,60,128+63,0 /* %r3 = bits 60-63 of %r2 'and' 15. */
+ lghi %r1,16 /* current_len = 16. */
+ slr %r1,%r4 /* Compute bytes to 16bytes boundary. */
+
+ /* Process s in 16byte aligned loop. */
+.Lfast_loop:
+ vl %v16,0(%r1,%r2) /* Load search-string. */
+ vfaezfs %v18,%v16,%v17,0 /* Find first element in v16 equal to any
+ in v17 or first zero element. */
+ jno .Lfast_loop_found
+
+ vl %v16,16(%r1,%r2)
+ vfaezfs %v18,%v16,%v17,0
+ jno .Lfast_loop_found16
+
+ vl %v16,32(%r1,%r2)
+ vfaezfs %v18,%v16,%v17,0
+ jno .Lfast_loop_found32
+
+ vl %v16,48(%r1,%r2)
+ vfaezfs %v18,%v16,%v17,0
+ jno .Lfast_loop_found48
+
+ aghi %r1,64
+ j .Lfast_loop /* Loop if no element was unequal to reject
+ and not zero. */
+
+ /* Found equal or zero element. */
+.Lfast_loop_found48:
+ aghi %r1,16
+.Lfast_loop_found32:
+ aghi %r1,16
+.Lfast_loop_found16:
+ aghi %r1,16
+.Lfast_loop_found:
+ vlgvb %r4,%v18,7 /* Load byte index of found element or zero. */
+.Lfast_loop_found2:
+ algrk %r2,%r1,%r4 /* Add found index to current len. */
+ srlg %r2,%r2,2 /* Convert byte-count to character-count. */
+ br %r14
+
+
+
+ /*
+ Search s for reject in multiple vregs
+ -------------------------------------
+ */
+.Lslow:
+ /* Save registers. */
+ vlvgg %v30,%r6,0
+ vlvgp %v31,%r8,%r9
+
+ /* Reject in v17 without zero. */
+ vlr %v19,%v17 /* Save first acc-part for a fast reload. */
+ vzero %v20 /* Zero for preparing acc-vector. */
+ vone %v24 /* One for checking result of former
+ string-part. */
+
+ /* Align s to 16 byte. */
+ risbg %r4,%r2,60,128+63,0 /* Test if s is aligned and
+ %r4 = bits 60-63 'and' 15. */
+ je .Lslow_loop_str /* If s is aligned, loop aligned. */
+ lghi %r0,15
+ slr %r0,%r4 /* Compute highest index to load (15-x). */
+ vll %v16,%r0,0(%r2) /* Load up to 16byte boundary (vll needs
+ highest index, remaining bytes are 0). */
+ ahi %r0,1 /* Work with loaded byte count. */
+ vzero %v21 /* Zero out global mask. */
+ lghi %r5,0 /* Set current len of reject-string to zero. */
+ vfenezf %v18,%v16,%v16 /* Find zero in current string-part. */
+ lghi %r8,0 /* There is no zero in first reject-part. */
+ vlgvb %r6,%v18,7 /* Load byte index of zero or 16 if no zero. */
+ clije %r6,0,.Lslow_end /* If first element is zero -> return 0. */
+ clr %r0,%r6 /* cc==1 if loaded byte count < zero-index. */
+ locrl %r6,%r0 /* Load on cc==1; zero-index = lbc. */
+ j .Lslow_loop_acc
+
+
+ /* Process s in 16byte aligned loop. */
+.Lslow_next_str:
+ /* Check results of former processed str-part. */
+ vfeef %v18,%v21,%v24 /* Find first equal match in global mask
+ (ones in element). */
+ vlgvb %r4,%v18,7 /* Get index of first one (=equal) or 16. */
+ /* Equal-index < min(zero-index, loaded byte count)
+ -> Return pointer to equal element. */
+ clrjl %r4,%r6,.Lslow_index_found
+ /* Zero-index < loaded byte count
+ -> Former str-part was last str-part
+ -> Return null */
+ clrjl %r6,%r0,.Lslow_end_not_found
+
+ /* All elements are zero (=no match) -> proceed with next str-part. */
+ vlr %v17,%v19 /* Load first part of reject (no zero). */
+ algfr %r1,%r0 /* Add loaded byte count to current len. */
+
+.Lslow_loop_str:
+ vl %v16,0(%r1,%r2) /* Load search-string. */
+ lghi %r0,16 /* Loaded byte count is 16. */
+ vzero %v21 /* Zero out global mask. */
+ lghi %r5,0 /* Set current len of reject to zero. */
+ vfenezf %v18,%v16,%v16 /* Find zero in current string-part. */
+ lghi %r8,0 /* There is no zero in first reject-part. */
+ vlgvb %r6,%v18,7 /* Load byte index of zero or 16 if no zero. */
+ clije %r6,0,.Lslow_end /* If first element is zero (end of string)
+ -> Return current length. */
+
+.Lslow_loop_acc:
+ vfaef %v22,%v16,%v17,4 /* Create matching-mask (1 in mask ->
+ Character matches any rejected character in
+ this reject-string-part) IN=0, RT=1. */
+ vlgvf %r4,%v22,0 /* Get result of first element. */
+ /* First element is equal to any rejected characters?
+ (All other parts of reject cannot lead to a match before this one)
+ -> Return current len, which is pointing to this element. */
+ clijh %r4,0,.Lslow_end
+ vo %v21,%v21,%v22 /* Global-mask = global-|matching-mask. */
+ /* Proceed with next acc until end of acc is reached. */
+
+
+.Lslow_next_acc:
+ clijh %r8,0,.Lslow_next_str /* There was a zero in last reject-part
+ -> Add found index to current len
+ and end. */
+ vlbb %v17,16(%r5,%r3),6 /* Load next reject part. */
+ aghi %r5,16 /* Increment current len of reject-string. */
+ lcbb %r9,0(%r5,%r3),6 /* Get loaded byte count of reject-string. */
+ jo .Lslow_next_acc_onbb /* Jump away if reject-string is
+ on block-boundary. */
+.Lslow_next_acc_notonbb:
+ vistrfs %v17,%v17 /* Fill with zeros after first zero. */
+ jo .Lslow_loop_acc /* No zero found -> no preparation needed. */
+
+.Lslow_next_acc_prepare_zero:
+ /* Zero in reject-part: fill zeros with first-reject-character. */
+ vlgvf %r8,%v17,0 /* Load first element of reject-part. */
+ clije %r8,0,.Lslow_next_str /* Process next str-part if first
+ character in this part of reject
+ is a zero. */
+ /* r8>0 -> zero found in this acc-part. */
+ vrepf %v18,%v17,0 /* Replicate first char accross all chars. */
+ vceqf %v22,%v20,%v17 /* Create a mask (v22) of null chars
+ by comparing with 0 (v20). */
+ vsel %v17,%v18,%v17,%v22 /* Replace null chars with first char. */
+ j .Lslow_loop_acc /* Reject-string part is prepared. */
+
+.Lslow_next_acc_onbb:
+ nill %r9,65532 /* Recognize only fully loaded characters. */
+ je .Lslow_next_acc_onbb2 /* Reload vr, if no full wchar_t
+ loaded. */
+ vfenezf %v18,%v17,%v17 /* Find zero in loaded bytes of reject part. */
+ vlgvb %r8,%v18,7 /* Load byte index of zero. */
+ clrjl %r8,%r9,.Lslow_next_acc_notonbb /* Found a zero in loaded bytes
+ -> Prepare vreg. */
+.Lslow_next_acc_onbb2:
+ vl %v17,0(%r5,%r3) /* Load over boundary ... */
+ lghi %r8,0 /* r8=0 -> no zero in this part of acc,
+ check for zero is in jump-target. */
+ j .Lslow_next_acc_notonbb /* ... and search for zero in
+ fully loaded vreg again. */
+
+.Lslow_end_not_found:
+ algfr %r1,%r6 /* Add zero-index to current len. */
+ j .Lslow_end
+.Lslow_index_found:
+ algfr %r1,%r4 /* Add found index of char to current len. */
+.Lslow_end:
+ srlg %r2,%r1,2 /* Convert byte-count to character-count. */
+ /* Restore registers. */
+ vlgvg %r6,%v30,0
+ vlgvg %r8,%v31,0
+ vlgvg %r9,%v31,1
+ br %r14
+.Lfallback:
+ jg __wcscspn_c
+END(__wcscspn_vx)
+#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */
diff --git a/REORG.TODO/sysdeps/s390/multiarch/wcscspn.c b/REORG.TODO/sysdeps/s390/multiarch/wcscspn.c
new file mode 100644
index 0000000000..f38ed9c7f4
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/multiarch/wcscspn.c
@@ -0,0 +1,27 @@
+/* Multiple versions of wcscspn.
+ Copyright (C) 2015-2017 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 && IS_IN (libc)
+# include <wchar.h>
+# include <ifunc-resolve.h>
+
+s390_vx_libc_ifunc2 (__wcscspn, wcscspn)
+
+#else
+# include <wcsmbs/wcscspn.c>
+#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)) */
diff --git a/REORG.TODO/sysdeps/s390/multiarch/wcslen-c.c b/REORG.TODO/sysdeps/s390/multiarch/wcslen-c.c
new file mode 100644
index 0000000000..9626a76da5
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/multiarch/wcslen-c.c
@@ -0,0 +1,25 @@
+/* Default wcslen implementation for S/390.
+ Copyright (C) 2015-2017 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 && IS_IN (libc)
+# define WCSLEN __wcslen_c
+
+# include <wchar.h>
+extern __typeof (__wcslen) __wcslen_c;
+# include <wcsmbs/wcslen.c>
+#endif
diff --git a/REORG.TODO/sysdeps/s390/multiarch/wcslen-vx.S b/REORG.TODO/sysdeps/s390/multiarch/wcslen-vx.S
new file mode 100644
index 0000000000..7539303fbd
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/multiarch/wcslen-vx.S
@@ -0,0 +1,91 @@
+/* Vector optimized 32/64 bit S/390 version of wcslen.
+ Copyright (C) 2015-2017 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 && IS_IN (libc)
+
+# include "sysdep.h"
+# include "asm-syntax.h"
+
+ .text
+
+/* size_t wcslen (const wchar_t *s)
+ Returns length of string s.
+
+ Register usage:
+ -r1=bytes to 4k-byte boundary
+ -r2=s
+ -r3=tmp
+ -r4=tmp
+ -r5=current_len and return_value
+ -v16=part of s
+*/
+ENTRY(__wcslen_vx)
+ .machine "z13"
+ .machinemode "zarch_nohighgprs"
+
+ vlbb %v16,0(%r2),6 /* Load s until next 4k-byte boundary. */
+ lcbb %r1,0(%r2),6 /* Get bytes to 4k-byte boundary or 16. */
+
+ tmll %r2,3 /* Test if s is 4-byte aligned? */
+ jne .Lfallback /* And use common-code variant if not. */
+
+ vfenezf %v16,%v16,%v16 /* Find element not equal with zero search. */
+ vlgvb %r4,%v16,7 /* Load zero index or 16 if not found. */
+ clr %r4,%r1 /* If found zero within loaded bytes? */
+ locgrl %r2,%r4 /* Then copy return value. */
+ jl .Lend /* And return. */
+
+ /* Align s to 16 byte. */
+ risbgn %r3,%r2,60,128+63,0 /* %r3 = bits 60-63 of %r2 'and' 15. */
+ lghi %r5,16 /* current_len = 16. */
+ slr %r5,%r3 /* Compute bytes to 16bytes boundary. */
+
+ /* Find zero in 16byte aligned loop. */
+.Lloop:
+ vl %v16,0(%r5,%r2) /* Load s. */
+ vfenezfs %v16,%v16,%v16 /* Find element not equal with zero search. */
+ je .Lfound /* Jump away if zero was found. */
+ vl %v16,16(%r5,%r2)
+ vfenezfs %v16,%v16,%v16
+ je .Lfound16
+ vl %v16,32(%r5,%r2)
+ vfenezfs %v16,%v16,%v16
+ je .Lfound32
+ vl %v16,48(%r5,%r2)
+ vfenezfs %v16,%v16,%v16
+ je .Lfound48
+
+ aghi %r5,64
+ j .Lloop /* No zero found -> loop. */
+
+.Lfound48:
+ aghi %r5,16
+.Lfound32:
+ aghi %r5,16
+.Lfound16:
+ aghi %r5,16
+.Lfound:
+ vlgvb %r2,%v16,7 /* Load byte index of zero. */
+ algr %r2,%r5
+.Lend:
+ srlg %r2,%r2,2 /* Convert byte-count to character-count. */
+ br %r14
+.Lfallback:
+ jg __wcslen_c
+END(__wcslen_vx)
+#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */
diff --git a/REORG.TODO/sysdeps/s390/multiarch/wcslen.c b/REORG.TODO/sysdeps/s390/multiarch/wcslen.c
new file mode 100644
index 0000000000..bfb577797e
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/multiarch/wcslen.c
@@ -0,0 +1,28 @@
+/* Multiple versions of wcslen.
+ Copyright (C) 2015-2017 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 && IS_IN (libc)
+# include <wchar.h>
+# include <ifunc-resolve.h>
+
+s390_vx_libc_ifunc (__wcslen)
+weak_alias (__wcslen, wcslen)
+
+#else
+# include <wcsmbs/wcslen.c>
+#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)) */
diff --git a/REORG.TODO/sysdeps/s390/multiarch/wcsncat-c.c b/REORG.TODO/sysdeps/s390/multiarch/wcsncat-c.c
new file mode 100644
index 0000000000..84b3eb1124
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/multiarch/wcsncat-c.c
@@ -0,0 +1,25 @@
+/* Default wcsncat implementation for S/390.
+ Copyright (C) 2015-2017 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 && IS_IN (libc)
+# define WCSNCAT __wcsncat_c
+
+# include <wchar.h>
+extern __typeof (wcsncat) __wcsncat_c;
+# include <wcsmbs/wcsncat.c>
+#endif
diff --git a/REORG.TODO/sysdeps/s390/multiarch/wcsncat-vx.S b/REORG.TODO/sysdeps/s390/multiarch/wcsncat-vx.S
new file mode 100644
index 0000000000..5c49a1e499
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/multiarch/wcsncat-vx.S
@@ -0,0 +1,265 @@
+/* Vector optimized 32/64 bit S/390 version of wcsncat.
+ Copyright (C) 2015-2017 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 && IS_IN (libc)
+
+# include "sysdep.h"
+# include "asm-syntax.h"
+
+ .text
+
+/* wchar_t * wcsncat (wchar_t *dest, const wchar_t *src, size_t n)
+ Concatenate two strings - at most n characters of src.
+
+ Register usage:
+ -r0=saved dest pointer for return
+ -r1=tmp
+ -r2=dest
+ -r3=src
+ -r4=n
+ -r5=current_len
+ -r6=tmp
+ -r7=tmp
+ -v16=part of src
+ -v17=index of zero
+ -v18=part of src
+ -v31=register save area for r6, r7
+*/
+ENTRY(__wcsncat_vx)
+ .machine "z13"
+ .machinemode "zarch_nohighgprs"
+
+# if !defined __s390x__
+ llgfr %r4,%r4
+# endif /* !defined __s390x__ */
+
+ clgfi %r4,0
+ ber %r14 /* Nothing to do, if n == 0. */
+
+ vlbb %v16,0(%r2),6 /* Load s until next 4k-byte boundary. */
+ lcbb %r1,0(%r2),6 /* Get bytes to 4k-byte boundary or 16. */
+
+ /* If either src or dest is not 4byte aligned, use __wcsncat_c. */
+ tmll %r2,3 /* Test if s is 4-byte aligned? */
+ jne .Lfallback /* And use common-code variant if not. */
+ tmll %r3,3 /* Test if src is 4-byte aligned? */
+ jne .Lfallback /* And use common-code variant if not. */
+
+ lgr %r0,%r2 /* Save destination pointer for return. */
+ vlvgp %v31,%r6,%r7 /* Save registers. */
+
+ /* WCSLEN
+ %r1 = loaded bytes (tmp)
+ %r6 = zero byte index (tmp)
+ %r2 = dst
+ */
+ vfenezf %v16,%v16,%v16 /* Find element not equal with zero search. */
+ vlgvb %r5,%v16,7 /* Load zero index or 16 if not found. */
+ clrjl %r5,%r1,.Llen_end /* Found zero within loaded bytes, end. */
+
+ /* Align s to 16 byte. */
+ risbgn %r1,%r2,60,128+63,0 /* %r3 = bits 60-63 of %r2 'and' 15. */
+ lghi %r5,16 /* current_len = 16. */
+ slr %r5,%r1 /* Compute bytes to 16bytes boundary. */
+
+ /* Find zero in 16byte aligned loop. */
+.Llen_loop:
+ vl %v16,0(%r5,%r2) /* Load s. */
+ vfenezfs %v16,%v16,%v16 /* Find element not equal with zero search. */
+ je .Llen_found /* Jump away if zero was found. */
+ vl %v16,16(%r5,%r2)
+ vfenezfs %v16,%v16,%v16
+ je .Llen_found16
+ vl %v16,32(%r5,%r2)
+ vfenezfs %v16,%v16,%v16
+ je .Llen_found32
+ vl %v16,48(%r5,%r2)
+ vfenezfs %v16,%v16,%v16
+ je .Llen_found48
+
+ aghi %r5,64
+ j .Llen_loop /* No zero -> loop. */
+
+.Llen_found48:
+ aghi %r5,16
+.Llen_found32:
+ aghi %r5,16
+.Llen_found16:
+ aghi %r5,16
+.Llen_found:
+ vlgvb %r1,%v16,7 /* Load byte index of zero. */
+ algr %r5,%r1
+
+.Llen_end:
+ /* WCSNCPY
+ %r1 = zero byte index (tmp)
+ %r6 = loaded bytes (tmp)
+ %r3 = curr src pointer
+ %r2 = curr dst pointer
+ %r7 = border, tmp
+ */
+ la %r2,0(%r5,%r2) /* strcpy at end of dst-string. */
+
+ vlbb %v16,0(%r3),6 /* Load s until next 4k-byte boundary. */
+ lcbb %r6,0(%r3),6 /* Get bytes to 4k-byte boundary or 16. */
+ llgfr %r6,%r6 /* Convert 32bit to 64bit. */
+
+ lghi %r5,0 /* current_len = 0. */
+
+ /* Check range of maxlen and convert to byte-count. */
+# ifdef __s390x__
+ tmhh %r4,49152 /* Test bit 0 or 1 of maxlen. */
+ lghi %r1,-4 /* Max byte-count is 18446744073709551612. */
+# else
+ tmlh %r4,49152 /* Test bit 0 or 1 of maxlen. */
+ llilf %r1,4294967292 /* Max byte-count is 4294967292. */
+# endif /* !__s390x__ */
+ sllg %r4,%r4,2 /* Convert character-count to byte-count. */
+ locgrne %r4,%r1 /* Use max byte-count, if bit 0/1 was one. */
+
+ clgrjle %r4,%r6,.Lcpy_remaining_v16 /* If n <= loaded-bytes
+ -> process remaining. */
+
+ /* n > loaded-byte-count. */
+ vfenezf %v17,%v16,%v16 /* Find element not equal with zero search. */
+ vlgvb %r1,%v17,7 /* Load zero index or 16 if not found. */
+ clrjl %r1,%r6,.Lcpy_found_v16_store /* Found zero within loaded bytes,
+ copy and return. */
+
+ /* Align s to 16 byte. */
+ risbgn %r1,%r3,60,128+63,0 /* %r3 = bits 60-63 of %r2 'and' 15. */
+ lghi %r5,15 /* current_len = 15. */
+ slr %r5,%r1 /* Compute highest index to 16byte boundary. *
+
+ /* Zero not found and maxlen > loaded-byte-count. */
+ vstl %v16,%r5,0(%r2) /* Copy loaded characters - no zero. */
+ ahi %r5,1 /* Start loop at next character. */
+
+ /*
+ Now we are 16byte aligned, so we can load a full vreg
+ without page fault.
+ */
+ lgr %r1,%r5 /* If %r5 + 64 < maxlen? -> loop64. */
+ aghi %r1,64
+ clgrjl %r1,%r4,.Lcpy_loop64
+
+ vl %v16,0(%r5,%r3) /* Load s. */
+ clgijl %r4,17,.Lcpy_remaining_v16 /* If n <=16,
+ process remaining bytes. */
+.Lcpy_lt64:
+ lgr %r7,%r4
+ slgfi %r7,16 /* border_len = n - 16. */
+
+ clgrjhe %r5,%r7,.Lcpy_remaining_v16
+ vfenezfs %v17,%v16,%v16 /* Find element not equal with zero search. */
+ je .Lcpy_found_v16 /* Jump away if zero was found. */
+ vl %v18,16(%r5,%r3) /* Load next part of s. */
+ vst %v16,0(%r5,%r2) /* Save previous part without zero to dst. */
+ aghi %r5,16
+
+ clgrjhe %r5,%r7,.Lcpy_remaining_v18
+ vfenezfs %v17,%v18,%v18
+ je .Lcpy_found_v18
+ vl %v16,16(%r5,%r3)
+ vst %v18,0(%r5,%r2)
+ aghi %r5,16
+
+ clgrjhe %r5,%r7,.Lcpy_remaining_v16
+ vfenezfs %v17,%v16,%v16
+ je .Lcpy_found_v16
+ vl %v18,16(%r5,%r3)
+ vst %v16,0(%r5,%r2)
+ aghi %r5,16
+
+.Lcpy_remaining_v18:
+ vlr %v16,%v18
+.Lcpy_remaining_v16:
+ /* v16 contains the remaining bytes [1...16].
+ Store remaining bytes and append string-termination. */
+ vfenezf %v17,%v16,%v16 /* Find element not equal with zero search. */
+ slgrk %r7,%r4,%r5 /* Remaining bytes = maxlen - current_len. */
+ aghi %r7,-1 /* vstl needs highest index. */
+ vlgvb %r1,%v17,7 /* Load zero index or 16 if not found. */
+ la %r2,0(%r5,%r2) /* vstl has no index register. */
+ /* Zero-index within remaining-bytes, store up to zero and end. */
+ clgrjle %r1,%r7,.Lcpy_found_v16_store
+ vstl %v16,%r7,0(%r2) /* Store remaining bytes. */
+ lghi %r1,0
+ st %r1,1(%r7,%r2) /* Store string-null-termination beyond n. */
+.Lcpy_end:
+ /* Restore saved registers. */
+ vlgvg %r6,%v31,0
+ vlgvg %r7,%v31,1
+ lgr %r2,%r0 /* Load saved dest-ptr. */
+ br %r14
+
+.Lcpy_found_v16_32:
+ aghi %r5,32
+ j .Lcpy_found_v16
+.Lcpy_found_v18_48:
+ aghi %r5,32
+.Lcpy_found_v18_16:
+ aghi %r5,16
+.Lcpy_found_v18:
+ vlr %v16,%v18
+.Lcpy_found_v16:
+ /* v16 contains a zero. Store remaining bytes to zero. current_len
+ has not reached border, thus checking for n is not needed! */
+ vlgvb %r1,%v17,7 /* Load byte index of zero. */
+ la %r2,0(%r5,%r2)
+.Lcpy_found_v16_store:
+ aghi %r1,3 /* Also copy remaining bytes of zero. */
+ vstl %v16,%r1,0(%r2) /* Copy characters including zero. */
+ j .Lcpy_end
+
+ /* Find zero in 16byte aligned loop. */
+.Lcpy_loop2:
+ vl %v16,16(%r5,%r3)
+ vst %v18,0(%r5,%r2)
+ aghi %r5,16
+
+.Lcpy_loop64:
+ vl %v16,0(%r5,%r3)
+ vfenezfs %v17,%v16,%v16 /* Find element not equal with zero search. */
+ je .Lcpy_found_v16 /* Jump away if zero was found. */
+ vl %v18,16(%r5,%r3) /* Load next part of s. */
+ vst %v16,0(%r5,%r2) /* Save previous part without zero to dst. */
+ vfenezfs %v17,%v18,%v18
+ je .Lcpy_found_v18_16
+ vl %v16,32(%r5,%r3)
+ vst %v18,16(%r5,%r2)
+ vfenezfs %v17,%v16,%v16
+ je .Lcpy_found_v16_32
+ vl %v18,48(%r5,%r3)
+ vst %v16,32(%r5,%r2)
+ vfenezfs %v17,%v18,%v18
+ je .Lcpy_found_v18_48
+ vst %v18,48(%r5,%r2)
+
+ aghi %r5,64
+ lgr %r1,%r5 /* If %r5 + 64 < maxlen? -> loop64. */
+ aghi %r1,64
+ clgrjl %r1,%r4,.Lcpy_loop64
+
+ vl %v16,0(%r5,%r3) /* Load s. */
+ j .Lcpy_lt64
+
+.Lfallback:
+ jg __wcsncat_c
+END(__wcsncat_vx)
+#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */
diff --git a/REORG.TODO/sysdeps/s390/multiarch/wcsncat.c b/REORG.TODO/sysdeps/s390/multiarch/wcsncat.c
new file mode 100644
index 0000000000..be545d091d
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/multiarch/wcsncat.c
@@ -0,0 +1,27 @@
+/* Multiple versions of wcsncat.
+ Copyright (C) 2015-2017 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 && IS_IN (libc)
+# include <wchar.h>
+# include <ifunc-resolve.h>
+
+s390_vx_libc_ifunc2 (__wcsncat, wcsncat)
+
+#else
+# include <wcsmbs/wcsncat.c>
+#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)) */
diff --git a/REORG.TODO/sysdeps/s390/multiarch/wcsncmp-c.c b/REORG.TODO/sysdeps/s390/multiarch/wcsncmp-c.c
new file mode 100644
index 0000000000..72ee85ab7a
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/multiarch/wcsncmp-c.c
@@ -0,0 +1,25 @@
+/* Default wcsncmp implementation for S/390.
+ Copyright (C) 2015-2017 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 && IS_IN (libc)
+# define WCSNCMP __wcsncmp_c
+
+# include <wchar.h>
+extern __typeof (wcsncmp) __wcsncmp_c;
+# include <wcsmbs/wcsncmp.c>
+#endif
diff --git a/REORG.TODO/sysdeps/s390/multiarch/wcsncmp-vx.S b/REORG.TODO/sysdeps/s390/multiarch/wcsncmp-vx.S
new file mode 100644
index 0000000000..e44c53a1a9
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/multiarch/wcsncmp-vx.S
@@ -0,0 +1,177 @@
+/* Vector optimized 32/64 bit S/390 version of wcsncmp.
+ Copyright (C) 2015-2017 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 && IS_IN (libc)
+
+# include "sysdep.h"
+# include "asm-syntax.h"
+
+ .text
+
+/* int wcsncmp (const wchar_t *s1, const wchar_t *s2, size_t n)
+ Compare at most n characters of two strings.
+
+ Register usage:
+ -r0=tmp
+ -r1=tmp
+ -r2=s1
+ -r3=s2
+ -r4=n
+ -r5=current_len
+ -v16=part of s1
+ -v17=part of s2
+ -v18=index of unequal
+*/
+ENTRY(__wcsncmp_vx)
+ .machine "z13"
+ .machinemode "zarch_nohighgprs"
+
+# if !defined __s390x__
+ llgfr %r4,%r4
+# endif /* !defined __s390x__ */
+
+ clgije %r4,0,.Lend_equal /* Nothing to do if n == 0. */
+
+ /* Check range of n and convert to byte-count. */
+# ifdef __s390x__
+ tmhh %r4,49152 /* Test bit 0 or 1 of maxlen. */
+ lghi %r1,-4 /* Max byte-count is 18446744073709551612. */
+# else
+ tmlh %r4,49152 /* Test bit 0 or 1 of maxlen. */
+ llilf %r1,4294967292 /* Max byte-count is 4294967292. */
+# endif /* !__s390x__ */
+ sllg %r4,%r4,2 /* Convert character-count to byte-count. */
+ locgrne %r4,%r1 /* Use max byte-count, if bit 0/1 was one. */
+
+ /* Check first character without vector load. */
+ lghi %r5,4 /* current_len = 4 bytes. */
+ /* Check s1/2[0]. */
+ lt %r0,0(%r2)
+ l %r1,0(%r3)
+ je .Lend_cmp_one_char
+ crjne %r0,%r1,.Lend_cmp_one_char
+
+.Lloop:
+ vlbb %v17,0(%r5,%r3),6 /* Load s2 to block boundary. */
+ vlbb %v16,0(%r5,%r2),6 /* Load s1 to block boundary. */
+ lcbb %r0,0(%r5,%r2),6 /* Get loaded byte count of s1. */
+ jo .Llt16_1 /* Jump away if vector not fully loaded. */
+ lcbb %r1,0(%r5,%r3),6 /* Get loaded byte count of s2. */
+ jo .Llt16_2 /* Jump away if vector not fully loaded. */
+ aghi %r5,16 /* Both vectors are fully loaded. */
+ vfenezfs %v18,%v16,%v17 /* Compare not equal with zero search. */
+ clgrjhe %r5,%r4,.Llastcmp /* If current_len >= n ->last compare. */
+ jno .Lfound
+
+ vlbb %v17,0(%r5,%r3),6
+ vlbb %v16,0(%r5,%r2),6
+ lcbb %r0,0(%r5,%r2),6
+ jo .Llt16_1
+ lcbb %r1,0(%r5,%r3),6
+ jo .Llt16_2
+ aghi %r5,16
+ vfenezfs %v18,%v16,%v17
+ clgrjhe %r5,%r4,.Llastcmp
+ jno .Lfound
+
+ vlbb %v17,0(%r5,%r3),6
+ vlbb %v16,0(%r5,%r2),6
+ lcbb %r0,0(%r5,%r2),6
+ jo .Llt16_1
+ lcbb %r1,0(%r5,%r3),6
+ jo .Llt16_2
+ aghi %r5,16
+ vfenezfs %v18,%v16,%v17
+ clgrjhe %r5,%r4,.Llastcmp
+ jno .Lfound
+
+ vlbb %v17,0(%r5,%r3),6
+ vlbb %v16,0(%r5,%r2),6
+ lcbb %r0,0(%r5,%r2),6
+ jo .Llt16_1
+ lcbb %r1,0(%r5,%r3),6
+ jo .Llt16_2
+ aghi %r5,16
+ vfenezfs %v18,%v16,%v17
+ clgrjhe %r5,%r4,.Llastcmp
+ jno .Lfound
+
+ j .Lloop
+
+.Llt16_1:
+ lcbb %r1,0(%r5,%r3),6 /* Get loaded byte count of s2. */
+.Llt16_2:
+ clr %r0,%r1 /* Compare logical. */
+ locrh %r0,%r1 /* Compute minimum of bytes loaded. */
+ nill %r0,65532 /* Align bytes loaded to full characters. */
+ jz .Lcmp_one_char /* Jump away if no full char is available. */
+.Llt_cmp:
+ algfr %r5,%r0 /* Add smallest loaded bytes to current_len. */
+ vfenezfs %v18,%v16,%v17 /* Compare not equal with zero search. */
+ clgrj %r5,%r4,10,.Llastcmp /* If current_len >= n -> last compare */
+ vlgvb %r1,%v18,7 /* Get not equal index or 16 if all equal. */
+ clrjl %r1,%r0,.Lfound /* Jump away if miscompare is within
+ loaded bytes; (index < loaded-bytes) */
+ j .Lloop
+
+.Lcmp_one_char:
+ /* At least one of both strings is not 4-byte aligned
+ and there is no full character before next block-boundary.
+ Compare one character to get over the boundary and
+ proceed with normal loop! */
+ vlef %v16,0(%r5,%r2),0 /* Load one character. */
+ lghi %r0,4 /* Loaded byte count is 4. */
+ vlef %v17,0(%r5,%r3),0
+ j .Llt_cmp /* Proceed with comparision. */
+
+.Llastcmp:
+ /* Use comparision result only if located within first n characters.
+ %r0: loaded byte count in vreg;
+ %r5: current_len;
+ %r4: n;
+ (current_len - n): [0...16[
+ First ignored match index: loaded bytes - (current_len-n): ]0...16]
+ */
+ slgr %r5,%r4 /* %r5 = current_len - n. */
+ slr %r0,%r5 /* %r0 = first ignored match index. */
+ vlgvb %r4,%v18,7 /* Get not equal index or 16 if all equal. */
+ clrjl %r4,%r0,.Lfound2 /* Jump away if miscompare is within
+ loaded bytes and below n bytes. */
+.Lend_equal:
+ lghi %r2,0
+ br %r14
+
+.Lfound:
+ /* Difference or end of string. */
+ /* vfenezf found an unequal element or zero.
+ This instruction compares unsigned words, but wchar_t is signed.
+ Thus we have to compare the found element again. */
+ vlgvb %r4,%v18,7 /* Extract not equal byte-index. */
+.Lfound2:
+ srl %r4,2 /* And convert it to character-index. */
+ vlgvf %r0,%v16,0(%r4) /* Load character-values. */
+ vlgvf %r1,%v17,0(%r4)
+.Lend_cmp_one_char:
+ cr %r0,%r1
+ je .Lend_equal
+ lghi %r2,1
+ lghi %r1,-1
+ locgrl %r2,%r1
+ br %r14
+END(__wcsncmp_vx)
+#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */
diff --git a/REORG.TODO/sysdeps/s390/multiarch/wcsncmp.c b/REORG.TODO/sysdeps/s390/multiarch/wcsncmp.c
new file mode 100644
index 0000000000..9b8e968d1f
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/multiarch/wcsncmp.c
@@ -0,0 +1,27 @@
+/* Multiple versions of wcsncmp.
+ Copyright (C) 2015-2017 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 && IS_IN (libc)
+# include <wchar.h>
+# include <ifunc-resolve.h>
+
+s390_vx_libc_ifunc2 (__wcsncmp, wcsncmp)
+
+#else
+# include <wcsmbs/wcsncmp.c>
+#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)) */
diff --git a/REORG.TODO/sysdeps/s390/multiarch/wcsncpy-c.c b/REORG.TODO/sysdeps/s390/multiarch/wcsncpy-c.c
new file mode 100644
index 0000000000..32ec8ffe64
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/multiarch/wcsncpy-c.c
@@ -0,0 +1,25 @@
+/* Default wcsncpy implementation for S/390.
+ Copyright (C) 2015-2017 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 && IS_IN (libc)
+# define WCSNCPY __wcsncpy_c
+
+# include <wchar.h>
+extern __typeof (__wcsncpy) __wcsncpy_c;
+# include <wcsmbs/wcsncpy.c>
+#endif
diff --git a/REORG.TODO/sysdeps/s390/multiarch/wcsncpy-vx.S b/REORG.TODO/sysdeps/s390/multiarch/wcsncpy-vx.S
new file mode 100644
index 0000000000..3d1a67e0d6
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/multiarch/wcsncpy-vx.S
@@ -0,0 +1,223 @@
+/* Vector optimized 32/64 bit S/390 version of wcsncpy.
+ Copyright (C) 2015-2017 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 && IS_IN (libc)
+
+# include "sysdep.h"
+# include "asm-syntax.h"
+
+ .text
+
+/* wchar_t *wcsncpy (const wchar_t *dest, const wchar_t *src, size_t n)
+ Copy at most n characters of string src to dest.
+
+ Register usage:
+ -r0=dest pointer for return
+ -r1=tmp, zero byte index
+ -r2=dest
+ -r3=src
+ -r4=n
+ -r5=current_len
+ -r6=tmp, loaded bytes
+ -r7=tmp, border
+ -v16=part of src
+ -v17=index of zero
+ -v18=part of src
+ -v31=register save area for r6, r7
+*/
+ENTRY(__wcsncpy_vx)
+ .machine "z13"
+ .machinemode "zarch_nohighgprs"
+
+# if !defined __s390x__
+ llgfr %r4,%r4
+# endif /* !defined __s390x__ */
+
+ clgfi %r4,0
+ ber %r14 /* Nothing to do, if n == 0. */
+
+ vlbb %v16,0(%r3),6 /* Load s until next 4k-byte boundary. */
+
+ tmll %r3,3 /* Test if s is 4-byte aligned? */
+ jne .Lfallback /* And use common-code variant if not. */
+
+ vlvgp %v31,%r6,%r7 /* Save registers. */
+ lgr %r0,%r2 /* Save destination pointer for return. */
+
+ lcbb %r6,0(%r3),6 /* Get bytes to 4k-byte boundary or 16. */
+ llgfr %r6,%r6 /* Convert 32bit to 64bit. */
+
+ lghi %r5,0 /* current_len = 0. */
+
+ /* Check range of maxlen and convert to byte-count. */
+# ifdef __s390x__
+ tmhh %r4,49152 /* Test bit 0 or 1 of n. */
+ lghi %r1,-4 /* Max byte-count is 18446744073709551612. */
+# else
+ tmlh %r4,49152 /* Test bit 0 or 1 of n. */
+ llilf %r1,4294967292 /* Max byte-count is 4294967292. */
+# endif /* !__s390x__ */
+ sllg %r4,%r4,2 /* Convert character-count to byte-count. */
+ locgrne %r4,%r1 /* Use max byte-count, if bit 0/1 was one. */
+
+ clgrjle %r4,%r6,.Lremaining_v16 /* If n <= loaded-bytes
+ -> process remaining. */
+
+ /* n > loaded-byte-count. */
+ vfenezf %v17,%v16,%v16 /* Find element not equal with zero search. */
+ vlgvb %r1,%v17,7 /* Load zero index or 16 if not found. */
+ aghi %r1,3 /* Also copy remaining bytes of zero. */
+ clrjl %r1,%r6,.Lfound_v16_store /* Found zero within loaded bytes,
+ copy and return. */
+
+ /* Align s to 16 byte. */
+ risbgn %r7,%r3,60,128+63,0 /* %r3 = bits 60-63 of %r2 'and' 15. */
+ lghi %r5,15 /* current_len = 15. */
+ slr %r5,%r7 /* Compute highest index to 16byte boundary. */
+
+ /* Zero not found and n > loaded-byte-count. */
+ vstl %v16,%r5,0(%r2) /* Copy loaded characters - no zero. */
+ ahi %r5,1 /* Start loop at next character. */
+
+ /* Now we are 16byte aligned, so we can load
+ a full vreg without page fault. */
+ lgr %r1,%r5 /* If %r5 + 64 < maxlen? -> loop64. */
+ aghi %r1,64
+ clgrjl %r1,%r4,.Lloop64
+
+ vl %v16,0(%r5,%r3) /* Load s. */
+ clgijl %r4,17,.Lremaining_v16 /* If n <=16, process remaining
+ bytes. */
+.Llt64:
+ lgr %r7,%r4
+ slgfi %r7,16 /* border_len = maxlen - 16. */
+
+ clgrjhe %r5,%r7,.Lremaining_v16 /* If current_len >= border
+ then process remaining bytes. */
+ vfenezfs %v17,%v16,%v16 /* Find element not equal with zero search. */
+ je .Lfound_v16 /* Jump away if zero was found. */
+ vl %v18,16(%r5,%r3) /* Load next part of s. */
+ vst %v16,0(%r5,%r2) /* Store previous part without zero to dst. */
+ aghi %r5,16
+
+ clgrjhe %r5,%r7,.Lremaining_v18
+ vfenezfs %v17,%v18,%v18
+ je .Lfound_v18
+ vl %v16,16(%r5,%r3)
+ vst %v18,0(%r5,%r2)
+ aghi %r5,16
+
+ clgrjhe %r5,%r7,.Lremaining_v16
+ vfenezfs %v17,%v16,%v16
+ je .Lfound_v16
+ vl %v18,16(%r5,%r3)
+ vst %v16,0(%r5,%r2)
+ aghi %r5,16
+
+.Lremaining_v18:
+ vlr %v16,%v18
+.Lremaining_v16:
+ /* v16 contains the remaining bytes [1...16].
+ Store remaining bytes and append string-termination. */
+ vfenezf %v17,%v16,%v16 /* Find element not equal with zero search. */
+ slgrk %r7,%r4,%r5 /* Remaining bytes = maxlen - current_len. */
+ aghi %r7,-1 /* vstl needs highest index. */
+ la %r2,0(%r5,%r2) /* vstl has no index register. */
+ vlgvb %r1,%v17,7 /* Load zero index or 16 if not found. */
+ aghi %r1,3 /* Also copy remaining bytes of zero. */
+ /* Zero in remaining bytes? -> jump away (zero-index < max-index)
+ Do not jump away if zero-index == max-index,
+ but simply copy zero with vstl below. */
+ clrjl %r1,%r7,.Lfound_v16_store
+ vstl %v16,%r7,0(%r2) /* Store remaining bytes without null
+ termination!. */
+.Lend:
+ /* Restore saved registers. */
+ vlgvg %r6,%v31,0
+ vlgvg %r7,%v31,1
+ lgr %r2,%r0 /* Load saved dest-ptr. */
+ br %r14
+
+.Lfound_v16_32:
+ aghi %r5,32
+ j .Lfound_v16
+.Lfound_v18_48:
+ aghi %r5,32
+.Lfound_v18_16:
+ aghi %r5,16
+.Lfound_v18:
+ vlr %v16,%v18
+.Lfound_v16:
+ /* v16 contains a zero. Store remaining bytes to zero. current_len
+ has not reached border, thus checking for n is not needed! */
+ vlgvb %r1,%v17,7 /* Load byte index of zero. */
+ la %r2,0(%r5,%r2) /* vstl has no support for index-register. */
+ aghi %r1,3 /* Also copy remaining bytes of zero. */
+.Lfound_v16_store:
+ vstl %v16,%r1,0(%r2) /* Copy characters including zero. */
+ /* Fill remaining bytes with zero - remaining count always > 0. */
+ algr %r5,%r1 /* Remaining bytes (=%r4) = ... */
+ slgr %r4,%r5 /* = maxlen - (currlen + zero_index + 1). */
+ la %r2,0(%r1,%r2) /* Pointer to zero. start filling beyond. */
+ aghi %r4,-2 /* mvc with exrl needs count - 1.
+ (additional -1, see remaining bytes above) */
+ srlg %r6,%r4,8 /* Split into 256 byte blocks. */
+ ltgr %r6,%r6
+ je .Lzero_lt256
+.Lzero_loop256:
+ mvc 1(256,%r2),0(%r2) /* Fill 256 zeros at once. */
+ la %r2,256(%r2)
+ brctg %r6,.Lzero_loop256 /* Loop until all blocks are processed. */
+.Lzero_lt256:
+ exrl %r4,.Lmvc_lt256
+ j .Lend
+.Lmvc_lt256:
+ mvc 1(1,%r2),0(%r2)
+
+ /* Find zero in 16byte aligned loop. */
+.Lloop64:
+ vl %v16,0(%r5,%r3) /* Load s. */
+ vfenezfs %v17,%v16,%v16 /* Find element not equal with zero search. */
+ je .Lfound_v16 /* Jump away if zero was found. */
+ vl %v18,16(%r5,%r3) /* Load next part of s. */
+ vst %v16,0(%r5,%r2) /* Store previous part without zero to dst. */
+ vfenezfs %v17,%v18,%v18
+ je .Lfound_v18_16
+ vl %v16,32(%r5,%r3)
+ vst %v18,16(%r5,%r2)
+ vfenezfs %v17,%v16,%v16
+ je .Lfound_v16_32
+ vl %v18,48(%r5,%r3)
+ vst %v16,32(%r5,%r2)
+ vfenezfs %v17,%v18,%v18
+ je .Lfound_v18_48
+ vst %v18,48(%r5,%r2)
+
+ aghi %r5,64
+ lgr %r1,%r5 /* If %r5 + 64 < maxlen? -> loop64. */
+ aghi %r1,64
+ clgrjl %r1,%r4,.Lloop64
+
+ vl %v16,0(%r5,%r3) /* Load s. */
+ j .Llt64
+
+.Lfallback:
+ jg __wcsncpy_c
+END(__wcsncpy_vx)
+
+#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */
diff --git a/REORG.TODO/sysdeps/s390/multiarch/wcsncpy.c b/REORG.TODO/sysdeps/s390/multiarch/wcsncpy.c
new file mode 100644
index 0000000000..6e1e8f01fb
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/multiarch/wcsncpy.c
@@ -0,0 +1,28 @@
+/* Multiple versions of wcsncpy.
+ Copyright (C) 2015-2017 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 && IS_IN (libc)
+# include <wchar.h>
+# include <ifunc-resolve.h>
+
+s390_vx_libc_ifunc (__wcsncpy)
+weak_alias (__wcsncpy, wcsncpy)
+
+#else
+# include <wcsmbs/wcsncpy.c>
+#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)) */
diff --git a/REORG.TODO/sysdeps/s390/multiarch/wcsnlen-c.c b/REORG.TODO/sysdeps/s390/multiarch/wcsnlen-c.c
new file mode 100644
index 0000000000..e86ca654e0
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/multiarch/wcsnlen-c.c
@@ -0,0 +1,25 @@
+/* Default wcsnlen implementation for S/390.
+ Copyright (C) 2015-2017 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 && IS_IN (libc)
+# define WCSNLEN __wcsnlen_c
+
+# include <wchar.h>
+extern __typeof (__wcsnlen) __wcsnlen_c;
+# include <wcsmbs/wcsnlen.c>
+#endif
diff --git a/REORG.TODO/sysdeps/s390/multiarch/wcsnlen-vx.S b/REORG.TODO/sysdeps/s390/multiarch/wcsnlen-vx.S
new file mode 100644
index 0000000000..c678b94cac
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/multiarch/wcsnlen-vx.S
@@ -0,0 +1,151 @@
+/* Vector optimized 32/64 bit S/390 version of wcsnlen.
+ Copyright (C) 2015-2017 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 && IS_IN (libc)
+
+# include "sysdep.h"
+# include "asm-syntax.h"
+
+ .text
+
+/* size_t wcsnlen (const wchar_t *s, size_t maxlen)
+ Returns the number of characters in s or at most maxlen.
+
+ Register usage:
+ -r1=tmp
+ -r2=address of string
+ -r3=maxlen (number of characters to be read)
+ -r4=tmp
+ -r5=current_len and return_value
+ -v16=part of s
+*/
+ENTRY(__wcsnlen_vx)
+
+ .machine "z13"
+ .machinemode "zarch_nohighgprs"
+
+# if !defined __s390x__
+ llgfr %r3,%r3
+# endif /* !defined __s390x__ */
+
+ clgfi %r3,0 /* if maxlen == 0, return 0. */
+ locgre %r2,%r3
+ ber %r14
+
+ vlbb %v16,0(%r2),6 /* Load s until next 4k-byte boundary. */
+ lcbb %r1,0(%r2),6 /* Get bytes to 4k-byte boundary or 16. */
+ llgfr %r1,%r1 /* Convert 32bit to 64bit. */
+
+ tmll %r2,3 /* Test if s is 4-byte aligned? */
+ jne .Lfallback /* And use common-code variant if not. */
+
+ /* Check range of maxlen and convert to byte-count. */
+# ifdef __s390x__
+ tmhh %r3,49152 /* Test bit 0 or 1 of maxlen. */
+ lghi %r4,-4 /* Max byte-count is 18446744073709551612. */
+# else
+ tmlh %r3,49152 /* Test bit 0 or 1 of maxlen. */
+ llilf %r4,4294967292 /* Max byte-count is 4294967292. */
+# endif /* !__s390x__ */
+ sllg %r3,%r3,2 /* Convert character-count to byte-count. */
+ locgrne %r3,%r4 /* Use max byte-count, if bit 0/1 was one. */
+
+ vfenezf %v16,%v16,%v16 /* Find element not equal with zero search. */
+ clgr %r1,%r3
+ locgrh %r1,%r3 /* loaded_byte_count
+ = min (loaded_byte_count, maxlen) */
+
+ vlgvb %r5,%v16,7 /* Load zero index or 16 if not found. */
+ clrjl %r5,%r1,.Lend /* Found zero within loaded bytes -> return. */
+
+ clgr %r1,%r3 /* If loaded_byte_count == maxlen -> end. */
+ locgre %r5,%r3
+ je .Lend
+
+ /* Align s to 16 byte. */
+ risbgn %r4,%r2,60,128+63,0 /* %r3 = bits 60-63 of %r2 'and' 15. */
+ lghi %r5,16 /* current_len = 16. */
+ slr %r5,%r4 /* Compute bytes to 16bytes boundary. */
+
+ lgr %r1,%r5 /* If %r5 + 64 < maxlen? -> loop64. */
+ aghi %r1,64
+ clgrjl %r1,%r3,.Lloop64
+
+ /* Find zero in max 64byte with aligned s. */
+.Llt64:
+ vl %v16,0(%r5,%r2) /* Load s. */
+ vfenezfs %v16,%v16,%v16 /* Find element not equal with zero search. */
+ je .Lfound /* Jump away if zero was found. */
+ aghi %r5,16
+ clgrjhe %r5,%r3,.Lfound /* If current_len >= maxlen -> end. */
+ vl %v16,0(%r5,%r2)
+ vfenezfs %v16,%v16,%v16
+ je .Lfound
+ aghi %r5,16
+ clgrjhe %r5,%r3,.Lfound
+ vl %v16,0(%r5,%r2)
+ vfenezfs %v16,%v16,%v16
+ je .Lfound
+ aghi %r5,16
+ clgrjhe %r5,%r3,.Lfound
+ vl %v16,0(%r5,%r2)
+ vfenezfs %v16,%v16,%v16
+ j .Lfound
+
+.Lfound48:
+ aghi %r5,16
+.Lfound32:
+ aghi %r5,16
+.Lfound16:
+ aghi %r5,16
+.Lfound:
+ vlgvb %r4,%v16,7 /* Load byte index of zero or 16 if no zero. */
+ algr %r5,%r4
+
+ clgr %r5,%r3
+ locgrh %r5,%r3 /* Return min (current_len, maxlen). */
+.Lend:
+ srlg %r2,%r5,2 /* Convert byte-count to character-count. */
+ br %r14
+
+ /* Find zero in 16byte aligned loop. */
+.Lloop64:
+ vl %v16,0(%r5,%r2) /* Load s. */
+ vfenezfs %v16,%v16,%v16 /* Find element not equal with zero search. */
+ je .Lfound /* Jump away if zero was found. */
+ vl %v16,16(%r5,%r2)
+ vfenezfs %v16,%v16,%v16
+ je .Lfound16
+ vl %v16,32(%r5,%r2)
+ vfenezfs %v16,%v16,%v16
+ je .Lfound32
+ vl %v16,48(%r5,%r2)
+ vfenezfs %v16,%v16,%v16
+ je .Lfound48
+
+ aghi %r5,64
+ lgr %r1,%r5 /* If %r5 + 64 < maxlen? -> loop64. */
+ aghi %r1,64
+ clgrjl %r1,%r3,.Lloop64
+
+ j .Llt64
+
+.Lfallback:
+ jg __wcsnlen_c
+END(__wcsnlen_vx)
+#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */
diff --git a/REORG.TODO/sysdeps/s390/multiarch/wcsnlen.c b/REORG.TODO/sysdeps/s390/multiarch/wcsnlen.c
new file mode 100644
index 0000000000..54486b9158
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/multiarch/wcsnlen.c
@@ -0,0 +1,28 @@
+/* Multiple versions of wcsnlen.
+ Copyright (C) 2015-2017 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 && IS_IN (libc)
+# include <wchar.h>
+# include <ifunc-resolve.h>
+
+s390_vx_libc_ifunc (__wcsnlen)
+weak_alias (__wcsnlen, wcsnlen)
+
+#else
+# include <wcsmbs/wcsnlen.c>
+#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)) */
diff --git a/REORG.TODO/sysdeps/s390/multiarch/wcspbrk-c.c b/REORG.TODO/sysdeps/s390/multiarch/wcspbrk-c.c
new file mode 100644
index 0000000000..0a2e4c8e4d
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/multiarch/wcspbrk-c.c
@@ -0,0 +1,31 @@
+/* Default wcspbrk implementation for S/390.
+ Copyright (C) 2015-2017 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 && IS_IN (libc)
+# define WCSPBRK __wcspbrk_c
+
+# include <wchar.h>
+extern __typeof (wcspbrk) __wcspbrk_c;
+# ifdef SHARED
+# undef libc_hidden_def
+# define libc_hidden_def(name) \
+ __hidden_ver1 (__wcspbrk_c, __GI_wcspbrk, __wcspbrk_c);
+# endif /* SHARED */
+
+# include <wcsmbs/wcspbrk.c>
+#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */
diff --git a/REORG.TODO/sysdeps/s390/multiarch/wcspbrk-vx.S b/REORG.TODO/sysdeps/s390/multiarch/wcspbrk-vx.S
new file mode 100644
index 0000000000..267baf091d
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/multiarch/wcspbrk-vx.S
@@ -0,0 +1,315 @@
+/* Vector optimized 32/64 bit S/390 version of wcspbrk.
+ Copyright (C) 2015-2017 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 && IS_IN (libc)
+
+# include "sysdep.h"
+# include "asm-syntax.h"
+
+ .text
+
+/* wchar_t *wcspbrk (const wchar_t *s, const wchar_t * accept)
+ The wcspbrk() function locates the first occurrence in the string s
+ of any of the characters in the string accept and returns a pointer
+ to that character or NULL if not found.
+
+ This method checks the length of accept string. If it fits entirely
+ in one vector register, a fast algorithm is used, which does not need
+ to check multiple parts of accept-string. Otherwise a slower full
+ check of accept-string is used.
+
+ register overview:
+ r3: pointer to start of accept-string
+ r2: pointer to start of search-string
+ r0: loaded byte count of vlbb search-string (32bit unsigned)
+ r4: found byte index (32bit unsigned)
+ r1: current return len (64bit unsigned)
+ v16: search-string
+ v17: accept-string
+ v18: temp-vreg
+
+ ONLY FOR SLOW:
+ v19: first accept-string
+ v20: zero for preparing acc-vector
+ v21: global mask; 1 indicates a match between
+ search-string-vreg and any accept-character
+ v22: current mask; 1 indicates a match between
+ search-string-vreg and any accept-character in current acc-vreg
+ v24: one for result-checking of former string-part
+ v30, v31: for re-/storing registers r6, r8, r9
+ r5: current len of accept-string
+ r6: zero-index in search-string or 16 if no zero
+ or min(zero-index, loaded byte count)
+ r8: >0, if former accept-string-part contains a zero,
+ otherwise =0;
+ r9: loaded byte count of vlbb accept-string
+*/
+ENTRY(__wcspbrk_vx)
+ .machine "z13"
+ .machinemode "zarch_nohighgprs"
+
+ tmll %r2,3 /* Test if s is 4-byte aligned? */
+ jne .Lfallback /* And use common-code variant if not. */
+
+ /*
+ Check if accept-string fits in one vreg:
+ ----------------------------------------
+ */
+ vlbb %v17,0(%r3),6 /* Load accept. */
+ lcbb %r0,0(%r3),6
+ jo .Lcheck_onbb /* Special case if accept lays
+ on block-boundary. */
+
+.Lcheck_notonbb:
+ lghi %r1,0 /* Zero out current len. */
+ vlgvf %r0,%v17,0 /* Get first element. */
+ clije %r0,0,.Lfast_end_null /* Return null if accept is empty. */
+
+ vistrfs %v17,%v17 /* Fill with zeros after first zero. */
+ je .Lfast /* Zero found -> accept fits in one vreg. */
+ j .Lslow /* No zero -> accept exceeds one vreg */
+
+
+.Lcheck_onbb:
+ /* Accept lays on block-boundary. */
+ nill %r0,65532 /* Recognize only fully loaded characters. */
+ je .Lcheck_onbb2 /* Reload vr, if we loaded no full wchar_t. */
+ vfenezf %v18,%v17,%v17 /* Search zero in loaded accept bytes. */
+ vlgvb %r4,%v18,7 /* Get index of zero or 16 if not found. */
+ clrjl %r4,%r0,.Lcheck_notonbb /* Zero index < loaded bytes count ->
+ accept fits in one vreg;
+ Fill with zeros and proceed
+ with FAST. */
+.Lcheck_onbb2:
+ vl %v17,0(%r3) /* Load accept, which exceeds loaded bytes. */
+ j .Lcheck_notonbb /* Check if accept fits in one vreg. */
+
+
+ /*
+ Search s for accept in one vreg
+ -------------------------------
+ */
+.Lfast:
+ /* Complete accept-string in v17 and remaining bytes are zero. */
+
+ vlbb %v16,0(%r2),6 /* Load s until next 4k-byte boundary. */
+ lcbb %r0,0(%r2),6 /* Get bytes to 4k-byte boundary or 16. */
+
+ vfaezfs %v18,%v16,%v17,0 /* Find first element in v16 unequal to any
+ in v17 or first zero element. */
+ vlgvb %r4,%v18,7 /* Load byte index of found element. */
+ /* If found index is within loaded bytes, return with found
+ element index (=equal count). */
+ clrjl %r4,%r0,.Lfast_loop_found2
+
+ /* Align s to 16 byte. */
+ risbgn %r4,%r2,60,128+63,0 /* %r3 = bits 60-63 of %r2 'and' 15. */
+ lghi %r1,16 /* current_len = 16. */
+ slr %r1,%r4 /* Compute bytes to 16bytes boundary. */
+
+.Lfast_loop:
+ vl %v16,0(%r1,%r2) /* Load search-string. */
+ vfaezfs %v18,%v16,%v17,0 /* Find first element in v16 equal to any
+ in v17 or first zero element. */
+ jno .Lfast_loop_found
+
+ vl %v16,16(%r1,%r2)
+ vfaezfs %v18,%v16,%v17,0
+ jno .Lfast_loop_found16
+
+ vl %v16,32(%r1,%r2)
+ vfaezfs %v18,%v16,%v17,0
+ jno .Lfast_loop_found32
+
+ vl %v16,48(%r1,%r2)
+ vfaezfs %v18,%v16,%v17,0
+ jno .Lfast_loop_found48
+
+ aghi %r1,64
+ j .Lfast_loop /* Loop if no element was unequal to accept
+ and not zero. */
+
+ /* Found equal or zero element. */
+.Lfast_loop_found48:
+ aghi %r1,16
+.Lfast_loop_found32:
+ aghi %r1,16
+.Lfast_loop_found16:
+ aghi %r1,16
+.Lfast_loop_found:
+ vlgvb %r4,%v18,7 /* Load byte index of found element. */
+.Lfast_loop_found2:
+ srlg %r5,%r4,2 /* Convert byte-index to character-index. */
+ vlgvf %r0,%v16,0(%r5) /* Get found element. */
+ clije %r0,0,.Lfast_end_null /* Return null if no accept-char found */
+ algfr %r1,%r4 /* Add found index of char to current len. */
+ la %r2,0(%r1,%r2) /* And return pointer to first equal char. */
+ br %r14
+
+.Lfast_end_null:
+ lghi %r2,0 /* Return null if no character is equal. */
+ br %r14
+
+
+
+
+ /*
+ Search s for accept in multiple vregs
+ -------------------------------------
+ */
+.Lslow:
+ /* Save registers. */
+ vlvgg %v30,%r6,0
+ vlvgp %v31,%r8,%r9
+
+ /* Accept in v17 without zero */
+ vlr %v19,%v17 /* Save first acc-part for a fast reload. */
+ vzero %v20 /* Zero for preparing acc-vector. */
+ vone %v24 /* One for checking result of former string. */
+
+ /* Align s to 16 byte. */
+ risbg %r4,%r2,60,128+63,0 /* Test if s is aligned and
+ %r4 = bits 60-63 'and' 15. */
+ je .Lslow_loop_str /* If s is aligned, loop aligned. */
+ lghi %r0,15
+ slr %r0,%r4 /* Compute highest index to load (15-x). */
+ vll %v16,%r0,0(%r2) /* Load up to 16byte boundary;
+ needs highest index, left bytes are 0. */
+ ahi %r0,1 /* Work with loaded byte count. */
+ vzero %v21 /* Zero out global mask. */
+ lghi %r5,0 /* Set current len of accept-string to zero. */
+ vfenezf %v18,%v16,%v16 /* Find zero in current string-part. */
+ lghi %r8,0 /* There is no zero in first accept-part. */
+ vlgvb %r6,%v18,7 /* Load byte index of zero or 16 if no zero. */
+ clije %r6,0,.Lslow_end_null /* If first element is zero
+ (end of string) -> return null */
+ clr %r0,%r6 /* cc==1 if loaded byte count < zero-index. */
+ locrl %r6,%r0 /* Load on cc==1; zero-index = lbc. */
+ j .Lslow_loop_acc
+
+
+ /* Process s in 16byte aligned loop. */
+.Lslow_next_str:
+ /* Check results of former processed str-part. */
+ vfeef %v18,%v21,%v24 /* Find first equal match in global mask
+ (ones in element). */
+ vlgvb %r4,%v18,7 /* Get index of first one (=equal)
+ or 16 if no match. */
+ /* Equal-index < min(zero-index, loaded byte count)
+ -> return pointer to equal element. */
+ clrjl %r4,%r6,.Lslow_index_found
+ /* Zero-index < loaded byte count
+ -> former str-part was last str-part
+ -> return null */
+ clrjl %r6,%r0,.Lslow_end_null
+ /* All elements are zero (=no match) -> proceed with next str-part. */
+
+ vlr %v17,%v19 /* Load first part of accept (no zero). */
+ algfr %r1,%r0 /* Add loaded byte count to current len. */
+
+.Lslow_loop_str:
+ vl %v16,0(%r1,%r2) /* Load search-string */
+ lghi %r0,16 /* Loaded byte count is 16. */
+ vzero %v21 /* Zero out global mask. */
+ lghi %r5,0 /* Set current len of accept to zero. */
+ vfenezf %v18,%v16,%v16 /* Find zero in current string-part. */
+ lghi %r8,0 /* There is no zero in first accept-part. */
+ vlgvb %r6,%v18,7 /* Load byte index of zero or 16 if no zero. */
+ clije %r6,0,.Lslow_end_null /* If first element is zero
+ (end of string) -> return null. */
+
+.Lslow_loop_acc:
+ vfaef %v22,%v16,%v17,4 /* Create matching-mask (1 in mask ->
+ Character matches any accepted character in
+ this accept-string-part) IN=0, RT=1. */
+ vlgvf %r4,%v22,0 /* Get result of first element. */
+ /* First element is equal to any accepted characters
+ (all other parts of accept cannot lead to a match before this one)
+ -> current len is pointing to first element
+ -> return found */
+ clijh %r4,0,.Lslow_end_found
+ vo %v21,%v21,%v22 /* Global-mask = global-|matching-mask. */
+ /* Proceed with next acc until end of acc is reached. */
+
+
+.Lslow_next_acc:
+ clijh %r8,0,.Lslow_next_str /* There was a zero in the last acc-part
+ -> add index to current len and
+ end. */
+ vlbb %v17,16(%r5,%r3),6 /* Load next accept part. */
+ aghi %r5,16 /* Increment current len of accept-string. */
+ lcbb %r9,0(%r5,%r3),6 /* Get loaded byte count of accept-string. */
+ jo .Lslow_next_acc_onbb /* Jump away ifaccept-string is
+ on block-boundary. */
+.Lslow_next_acc_notonbb:
+ vistrfs %v17,%v17 /* Fill with zeros after first zero. */
+ jo .Lslow_loop_acc /* No zero found -> no preparation needed. */
+
+.Lslow_next_acc_prepare_zero:
+ /* Zero in accept-part: fill zeros with first-accept-character. */
+ vlgvf %r8,%v17,0 /* Load first element of acc-part. */
+ clije %r8,0,.Lslow_next_str /* Proceed with next string-part,
+ If first char in this part of accept
+ is a zero. */
+ /* r8>0 -> zero found in this acc-part. */
+ vrepf %v18,%v17,0 /* Replicate first char accross all chars. */
+ vceqf %v22,%v20,%v17 /* Create a mask (v22) of null chars
+ by comparing with 0 (v20). */
+ vsel %v17,%v18,%v17,%v22 /* Replace null chars with first char. */
+ j .Lslow_loop_acc /* Accept part is prepared -> process. */
+
+.Lslow_next_acc_onbb:
+ nill %r9,65532 /* Recognize only fully loaded characters. */
+ je .Lslow_next_acc_onbb2 /* Reload vr, if no full wchar_t. */
+ vfenezf %v18,%v17,%v17 /* Find zero in loaded bytes of accept part. */
+ vlgvb %r8,%v18,7 /* Load byte index of zero. */
+ clrjl %r8,%r9,.Lslow_next_acc_notonbb /* Found a zero in loaded bytes
+ -> Prepare vreg. */
+.Lslow_next_acc_onbb2:
+ vl %v17,0(%r5,%r3) /* Load over boundary ... */
+ lghi %r8,0 /* r8=0 -> no zero in this part of acc,
+ check for zero is in jump-target. */
+ j .Lslow_next_acc_notonbb /* ... and search for zero in
+ fully loaded vreg again. */
+
+.Lslow_end_null:
+ lghi %r1,0 /* Return null if no character is equal. */
+ j .Lslow_end
+
+.Lslow_loop_found:
+ vlgvb %r4,%v18,7 /* Load byte index of found element. */
+ srlg %r5,%r4,2 /* Convert byte-index to character-index. */
+ vlgvf %r0,%v16,0(%r5) /* Get found element. */
+ clije %r0,0,.Lslow_end_null /* Return null if no acc-char found. */
+
+.Lslow_index_found:
+ algfr %r1,%r4 /* Add found index of char to current len. */
+.Lslow_end_found:
+ la %r1,0(%r1,%r2) /* And return pointer to first equal char. */
+
+.Lslow_end:
+ /* Restore registers. */
+ vlgvg %r6,%v30,0
+ vlgvg %r8,%v31,0
+ vlgvg %r9,%v31,1
+ lgr %r2,%r1
+ br %r14
+.Lfallback:
+ jg __wcspbrk_c
+END(__wcspbrk_vx)
+#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */
diff --git a/REORG.TODO/sysdeps/s390/multiarch/wcspbrk.c b/REORG.TODO/sysdeps/s390/multiarch/wcspbrk.c
new file mode 100644
index 0000000000..9f14f9a4f2
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/multiarch/wcspbrk.c
@@ -0,0 +1,29 @@
+/* Multiple versions of wcspbrk.
+ Copyright (C) 2015-2017 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 && IS_IN (libc)
+# define wcspbrk __redirect_wcspbrk
+# include <wchar.h>
+# undef wcspbrk
+# include <ifunc-resolve.h>
+
+s390_vx_libc_ifunc2_redirected (__redirect_wcspbrk, __wcspbrk, wcspbrk)
+
+#else
+# include <wcsmbs/wcspbrk.c>
+#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)) */
diff --git a/REORG.TODO/sysdeps/s390/multiarch/wcsrchr-c.c b/REORG.TODO/sysdeps/s390/multiarch/wcsrchr-c.c
new file mode 100644
index 0000000000..bc462a7c71
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/multiarch/wcsrchr-c.c
@@ -0,0 +1,25 @@
+/* Default wcsrchr implementation for S/390.
+ Copyright (C) 2015-2017 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 && IS_IN (libc)
+# define WCSRCHR __wcsrchr_c
+
+# include <wchar.h>
+extern __typeof (wcsrchr) __wcsrchr_c;
+# include <wcsmbs/wcsrchr.c>
+#endif
diff --git a/REORG.TODO/sysdeps/s390/multiarch/wcsrchr-vx.S b/REORG.TODO/sysdeps/s390/multiarch/wcsrchr-vx.S
new file mode 100644
index 0000000000..ba605f579d
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/multiarch/wcsrchr-vx.S
@@ -0,0 +1,190 @@
+/* Vector optimized 32/64 bit S/390 version of wcsrchr.
+ Copyright (C) 2015-2017 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 && IS_IN (libc)
+
+# include "sysdep.h"
+# include "asm-syntax.h"
+
+ .text
+
+/* wchar_t *wcsrchr (const wchar_t *s, wchar_t c)
+ Locate the last character c in string.
+
+ Register usage:
+ -r0=loaded bytes in first part of s.
+ -r1=pointer to last occurence of c or NULL if not found.
+ -r2=s
+ -r3=c
+ -r4=tmp
+ -r5=current_len
+ -v16=part of s
+ -v17=index of found element
+ -v18=replicated c
+ -v19=part of s with last occurence of c.
+ -v20=permute pattern
+*/
+ENTRY(__wcsrchr_vx)
+ .machine "z13"
+ .machinemode "zarch_nohighgprs"
+
+ vlbb %v16,0(%r2),6 /* Load s until next 4k-byte boundary. */
+ lcbb %r0,0(%r2),6 /* Get bytes to 4k-byte boundary or 16. */
+
+ tmll %r2,3 /* Test if s is 4-byte aligned? */
+ jne .Lfallback /* And use common-code variant if not. */
+
+ vlvgf %v18,%r3,0 /* Generate vector which elements are all c. */
+ vrepf %v18,%v18,0
+
+ lghi %r1,-1 /* Currently no c found. */
+ lghi %r5,0 /* current_len = 0. */
+
+ vfeezfs %v17,%v16,%v18 /* Find element equal or zero. */
+ vlgvb %r4,%v17,7 /* Load byte index of c/zero or 16. */
+ clrjl %r4,%r0,.Lfound_first_part /* Found c/zero in loaded bytes. */
+.Lalign:
+ /* Align s to 16 byte. */
+ risbgn %r4,%r2,60,128+63,0 /* %r3 = bits 60-63 of %r2 'and' 15. */
+ lghi %r5,16 /* current_len = 16. */
+ slr %r5,%r4 /* Compute bytes to 16bytes boundary. */
+
+.Lloop:
+ vl %v16,0(%r5,%r2) /* Load s. */
+ vfeezfs %v17,%v16,%v18 /* Find element equal with zero search. */
+ jno .Lfound /* Found c/zero (cc=0|1|2). */
+ vl %v16,16(%r5,%r2)
+ vfeezfs %v17,%v16,%v18
+ jno .Lfound16
+ vl %v16,32(%r5,%r2)
+ vfeezfs %v17,%v16,%v18
+ jno .Lfound32
+ vl %v16,48(%r5,%r2)
+ vfeezfs %v17,%v16,%v18
+ jno .Lfound48
+
+ aghi %r5,64
+ j .Lloop /* No character and no zero -> loop. */
+
+.Lfound48:
+ la %r5,16(%r5) /* Use la since aghi would clobber cc. */
+.Lfound32:
+ la %r5,16(%r5)
+.Lfound16:
+ la %r5,16(%r5)
+.Lfound:
+ je .Lzero /* Found zero, but no c before that zero. */
+ /* Save this part of s to check for further matches after reaching
+ the end of the complete string. */
+ vlr %v19,%v16
+ lgr %r1,%r5
+
+ jh .Lzero /* Found a zero after the found c. */
+ aghi %r5,16 /* Start search of next part of s. */
+ j .Lloop
+
+.Lfound_first_part:
+ /* This code is only executed if the found c/zero is whithin loaded
+ bytes. If no c/zero was found (cc==3) the found index = 16, thus
+ this code is not called.
+ Resulting condition code of vector find element equal:
+ cc==0: no c, found zero
+ cc==1: c found, no zero
+ cc==2: c found, found zero after c
+ cc==3: no c, no zero (this case can be ignored). */
+ je .Lzero /* Found zero, but no c before that zero. */
+
+ locgrne %r1,%r5 /* Mark c as found in first part of s. */
+ vlr %v19,%v16
+
+ jl .Lalign /* No zero (e.g. if vr was fully loaded)
+ -> Align and loop afterwards. */
+
+ /* Found a zero in vr. If vr was not fully loaded due to block
+ boundary, the remaining bytes are filled with zero and we can't
+ rely on zero indication of condition code here! */
+
+ vfenezf %v17,%v16,%v16
+ vlgvb %r4,%v17,7 /* Load byte index of zero or 16. */
+ clrjl %r4,%r0,.Lzero /* Zero within loaded bytes -> end. */
+ j .Lalign /* Align and loop afterwards. */
+
+.Lend_searched_zero:
+ vlgvb %r4,%v17,7 /* Load byte index of zero. */
+ algr %r5,%r4
+ la %r2,0(%r5,%r2) /* Return pointer to zero. */
+ br %r14
+
+.Lzero:
+ /* Reached end of string. Check if one c was found before. */
+ clije %r3,0,.Lend_searched_zero /* Found zero and c is zero. */
+
+ cgfi %r1,-1 /* No c found -> return NULL. */
+ locghie %r2,0
+ ber %r14
+
+ larl %r3,.Lpermute_mask /* Load permute mask. */
+ vl %v20,0(%r3)
+
+ /* c was found and is part of v19. */
+ vfenezf %v17,%v19,%v19 /* Find zero. */
+ vlgvb %r4,%v17,7 /* Load byte index of zero or 16. */
+ ahi %r4,3 /* Found zero index is first byte,
+ thus highest byte index is last byte of
+ wchar_t zero. */
+
+ clgfi %r5,0 /* Loaded byte count in v19 is 16, ... */
+ lochine %r0,16 /* ... if v19 is not the first part of s. */
+ ahi %r0,-1 /* Convert byte count to highest index. */
+
+ clr %r0,%r4
+ locrl %r4,%r0 /* r4 = min (zero-index, highest-index). */
+
+ /* Right-shift of v19 to mask bytes after zero. */
+ clije %r4,15,.Lzero_permute /* No shift is needed if highest index
+ in vr is 15. */
+ lhi %r0,15
+ slr %r0,%r4 /* Compute byte count for vector shift left. */
+ sll %r0,3 /* Convert to bit count. */
+ vlvgb %v17,%r0,7
+ vsrlb %v19,%v19,%v17 /* Vector shift right by byte by number of bytes
+ specified in bits 1-4 of byte 7 in v17. */
+
+ /* Reverse bytes in v19. */
+.Lzero_permute:
+ vperm %v19,%v19,%v19,%v20 /* Permute v19 to reversed order. */
+
+ /* Find c in reversed v19. */
+ vfeef %v19,%v19,%v18 /* Find c. */
+ la %r2,0(%r1,%r2)
+ vlgvb %r3,%v19,7 /* Load byte index of c. */
+
+ /* Compute index in real s and return. */
+ slgr %r4,%r3
+ lay %r2,-3(%r4,%r2) /* Return pointer to zero. -3 is needed,
+ because the found byte index is reversed in
+ vector-register. Thus point to first byte of
+ wchar_t. */
+ br %r14
+.Lpermute_mask:
+ .byte 0x0C,0x0D,0x0E,0x0F,0x08,0x09,0x0A,0x0B
+ .byte 0x04,0x05,0x06,0x07,0x00,0x01,0x02,0x03
+.Lfallback:
+ jg __wcsrchr_c
+END(__wcsrchr_vx)
+#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */
diff --git a/REORG.TODO/sysdeps/s390/multiarch/wcsrchr.c b/REORG.TODO/sysdeps/s390/multiarch/wcsrchr.c
new file mode 100644
index 0000000000..cd3f695117
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/multiarch/wcsrchr.c
@@ -0,0 +1,27 @@
+/* Multiple versions of wcsrchr.
+ Copyright (C) 2015-2017 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 && IS_IN (libc)
+# include <wchar.h>
+# include <ifunc-resolve.h>
+
+s390_vx_libc_ifunc2 (__wcsrchr, wcsrchr)
+
+#else
+# include <wcsmbs/wcsrchr.c>
+#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)) */
diff --git a/REORG.TODO/sysdeps/s390/multiarch/wcsspn-c.c b/REORG.TODO/sysdeps/s390/multiarch/wcsspn-c.c
new file mode 100644
index 0000000000..7790556b0d
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/multiarch/wcsspn-c.c
@@ -0,0 +1,31 @@
+/* Default wcsspn implementation for S/390.
+ Copyright (C) 2015-2017 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 && IS_IN (libc)
+# define WCSSPN __wcsspn_c
+
+# include <wchar.h>
+extern __typeof (wcsspn) __wcsspn_c;
+# ifdef SHARED
+# undef libc_hidden_def
+# define libc_hidden_def(name) \
+ __hidden_ver1 (__wcsspn_c, __GI_wcsspn, __wcsspn_c);
+# endif /* SHARED */
+
+# include <wcsmbs/wcsspn.c>
+#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */
diff --git a/REORG.TODO/sysdeps/s390/multiarch/wcsspn-vx.S b/REORG.TODO/sysdeps/s390/multiarch/wcsspn-vx.S
new file mode 100644
index 0000000000..77806c3a50
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/multiarch/wcsspn-vx.S
@@ -0,0 +1,270 @@
+/* Vector optimized 32/64 bit S/390 version of wcsspn.
+ Copyright (C) 2015-2017 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 && IS_IN (libc)
+
+# include "sysdep.h"
+# include "asm-syntax.h"
+
+ .text
+
+/* size_t wcsspn (const wchar_t *s, const wchar_t * accept)
+ The wcsspn() function calculates the length of the initial segment
+ of s which consists entirely of characters in accept.
+
+ This method checks the length of accept string. If it fits entirely
+ in one vector register, a fast algorithm is used, which does not need
+ to check multiple parts of accept-string. Otherwise a slower full
+ check of accept-string is used.
+
+ register overview:
+ r3: pointer to start of accept-string
+ r2: pointer to start of search-string
+ r4: loaded byte count of vl search-string
+ r0: found byte index
+ r1: current return len of s
+ v16: search-string
+ v17: accept-string
+ v18: temp-vreg
+
+ ONLY FOR SLOW:
+ v19: first accept-string
+ v20: zero for preparing acc-vector
+ v21: global mask; 1 indicates a match between
+ search-string-vreg and any accept-character
+ v22: current mask; 1 indicates a match between
+ search-string-vreg and any accept-character in current acc-vreg
+ v30, v31: for re-/storing registers r6, r8, r9
+ r5: current len of accept-string
+ r6: zero-index in search-string or 16 if no zero
+ or min(zero-index, loaded byte count)
+ r8: >0, if former accept-string-part contains a zero,
+ otherwise =0;
+ r9: loaded byte count of vlbb accept-string
+*/
+ENTRY(__wcsspn_vx)
+ .machine "z13"
+ .machinemode "zarch_nohighgprs"
+
+ tmll %r2,3 /* Test if s is 4-byte aligned? */
+ jne .Lfallback /* And use common-code variant if not. */
+
+ /*
+ Check if accept-string fits in one vreg:
+ ----------------------------------------
+ */
+ vlbb %v17,0(%r3),6 /* Load accept. */
+ lcbb %r4,0(%r3),6
+ jo .Lcheck_onbb /* Special case if accept lays
+ on block-boundary. */
+.Lcheck_notonbb:
+ vistrfs %v17,%v17 /* Fill with zeros after first zero. */
+ je .Lfast /* Zero found -> accept fits in one vreg. */
+ j .Lslow /* No zero -> accept exceeds one vreg. */
+
+.Lcheck_onbb:
+ /* Accept lays on block-boundary. */
+ nill %r4,65532 /* Recognize only fully loaded characters. */
+ je .Lcheck_onbb2 /* Reload vr if no full wchar_t. */
+ vfenezf %v18,%v17,%v17 /* Search zero in loaded accept bytes. */
+ vlgvb %r0,%v18,7 /* Get index of zero or 16 if not found. */
+ clrjl %r0,%r4,.Lcheck_notonbb /* Zero index < loaded bytes count ->
+ Accept fits in one vreg;
+ Fill with zeros and proceed
+ with FAST. */
+.Lcheck_onbb2:
+ vl %v17,0(%r3) /* Load accept, which exceeds loaded bytes. */
+ j .Lcheck_notonbb /* Check if accept fits in one vreg. */
+
+
+ /*
+ Search s for accept in one vreg
+ -------------------------------
+ */
+.Lfast:
+ /* Complete accept-string in v17 and remaining bytes are zero. */
+
+ vlbb %v16,0(%r2),6 /* Load s until next 4k-byte boundary. */
+ lcbb %r1,0(%r2),6 /* Get bytes to 4k-byte boundary or 16. */
+
+ vfaezfs %v16,%v16,%v17,8 /* Find first element in v16
+ unequal to any in v17
+ or first zero element. */
+
+ vlgvb %r0,%v16,7 /* Load byte index of found element. */
+ /* If found index is within loaded bytes (%r0 < %r1),
+ return with found element index (=equal count). */
+ clr %r0,%r1
+ srlg %r0,%r0,2 /* Convert byte-count to character-count. */
+ locgrl %r2,%r0
+ blr %r14
+
+ /* Align s to 16 byte. */
+ risbgn %r4,%r2,60,128+63,0 /* %r3 = bits 60-63 of %r2 'and' 15. */
+ lghi %r1,16 /* current_len = 16. */
+ slr %r1,%r4 /* Compute bytes to 16bytes boundary. */
+
+.Lfast_loop:
+ vl %v16,0(%r1,%r2) /* Load search-string. */
+ vfaezfs %v16,%v16,%v17,8 /* Find first element in v16
+ unequal to any in v17
+ or first zero element. */
+ jno .Lfast_loop_found
+ vl %v16,16(%r1,%r2)
+ vfaezfs %v16,%v16,%v17,8
+ jno .Lfast_loop_found16
+ vl %v16,32(%r1,%r2)
+ vfaezfs %v16,%v16,%v17,8
+ jno .Lfast_loop_found32
+ vl %v16,48(%r1,%r2)
+ vfaezfs %v16,%v16,%v17,8
+ jno .Lfast_loop_found48
+
+ aghi %r1,64
+ j .Lfast_loop /* Loop if no element was unequal to accept
+ and not zero. */
+
+ /* Found unequal or zero element. */
+.Lfast_loop_found48:
+ aghi %r1,16
+.Lfast_loop_found32:
+ aghi %r1,16
+.Lfast_loop_found16:
+ aghi %r1,16
+.Lfast_loop_found:
+ vlgvb %r0,%v16,7 /* Load byte index of found element. */
+ algrk %r2,%r1,%r0 /* And add it to current len. */
+ srlg %r2,%r2,2 /* Convert byte-count to character-count. */
+ br %r14
+
+
+ /*
+ Search s for accept in multiple vregs
+ -------------------------------------
+ */
+.Lslow:
+ /* Save registers. */
+ vlvgg %v30,%r6,0
+ vlvgp %v31,%r8,%r9
+ lghi %r1,0 /* Zero out current len. */
+
+ /* accept in v17 without zero. */
+ vlr %v19,%v17 /* Save first acc-part for a fast reload. */
+ vzero %v20 /* Zero for preparing acc-vector. */
+
+ /* Align s to 16 byte. */
+ risbg %r0,%r2,60,128+63,0 /* Test if s is aligned and
+ %r0 = bits 60-63 'and' 15. */
+ je .Lslow_loop_str /* If s is aligned, loop aligned */
+ lghi %r4,15
+ slr %r4,%r0 /* Compute highest index to load (15-x). */
+ vll %v16,%r4,0(%r2) /* Load up to 16byte boundary (vll needs
+ highest index, remaining bytes are 0). */
+ aghi %r4,1 /* Work with loaded byte count. */
+ vzero %v21 /* Zero out global mask. */
+ lghi %r5,0 /* Set current len of accept-string to zero. */
+ vfenezf %v18,%v16,%v16 /* Find zero in current string-part. */
+ lghi %r8,0 /* There is no zero in first accept-part. */
+ vlgvb %r6,%v18,7 /* Load byte index of zero or 16
+ if there is no zero. */
+ clr %r4,%r6 /* cc==1 if loaded byte count < zero-index. */
+ locrl %r6,%r4 /* Load on cc==1. */
+ j .Lslow_loop_acc
+
+ /* Process s in 16byte aligned loop. */
+.Lslow_next_str:
+ vlr %v17,%v19 /* Load first part of accept (no zero). */
+ algfr %r1,%r4 /* Add loaded byte count to current len. */
+.Lslow_loop_str:
+ vl %v16,0(%r1,%r2) /* Load search-string. */
+ lghi %r4,16 /* Loaded byte count is 16. */
+ vzero %v21 /* Zero out global mask. */
+ lghi %r5,0 /* Set current len of accept-string to zero. */
+ vfenezf %v18,%v16,%v16 /* Find zero in current string-part. */
+ lghi %r8,0 /* There is no zero in first accept-part. */
+ vlgvb %r6,%v18,7 /* Load byte index of zero or 16 if no zero. */
+
+.Lslow_loop_acc:
+ vfaef %v22,%v16,%v17,4 /* Create matching-mask (1 in mask ->
+ character matches any accepted character in
+ this accept-string-part) IN=0, RT=1. */
+ vo %v21,%v21,%v22 /* global-mask = global- | matching-mask. */
+ vfenezf %v18,%v21,%v21 /* Find first zero in global-mask. */
+ vlgvb %r0,%v18,7 /* Get first found zero-index
+ (= first mismatch). */
+ clrjl %r0,%r6,.Lslow_next_acc /* Mismatch-index < min(lbc,zero-index)
+ -> Process this string-part
+ with next acc-part. */
+ clrjhe %r0,%r4,.Lslow_next_str /* Found-index >= loaded byte count
+ -> All loaded bytes are matching
+ any accept-character
+ and are not zero. */
+ /* All bytes are matching any characters in accept-string
+ and search-string is fully processed (found-index == zero-index). */
+.Lslow_add_lbc_end:
+ algrk %r2,%r1,%r0 /* Add matching characters to current len. */
+ srlg %r2,%r2,2 /* Convert byte-count to character-count. */
+ /* Restore registers. */
+ vlgvg %r6,%v30,0
+ vlgvg %r8,%v31,0
+ vlgvg %r9,%v31,1
+ br %r14
+
+.Lslow_next_acc:
+ clijh %r8,0,.Lslow_add_lbc_end /* There was a zero in last acc-part
+ -> Add found index to current len
+ and end. */
+ vlbb %v17,16(%r5,%r3),6 /* Load next accept part. */
+ aghi %r5,16 /* Increment current len of accept-string. */
+ lcbb %r9,0(%r5,%r3),6 /* Get loaded byte count of accept-string. */
+ jo .Lslow_next_acc_onbb /* Jump away if accept-string is
+ on block-boundary. */
+.Lslow_next_acc_notonbb:
+ vistrfs %v17,%v17 /* Fill with zeros after first zero. */
+ jo .Lslow_loop_acc /* No zero found -> no preparation needed. */
+
+.Lslow_next_acc_prepare_zero:
+ /* Zero in accept-part: fill zeros with first-accept-character. */
+ vlgvf %r8,%v17,0 /* Load first element of acc-part. */
+ clije %r8,0,.Lslow_add_lbc_end /* End if zero is first character
+ in this part of accept-string. */
+ /* r8>0 -> zero found in this acc-part. */
+ vrepf %v18,%v17,0 /* Replicate first char accross all chars. */
+ vceqf %v22,%v20,%v17 /* Create a mask (v22) of null chars
+ by comparing with 0 (v20). */
+ vsel %v17,%v18,%v17,%v22 /* Replace null chars with first char. */
+ j .Lslow_loop_acc /* Accept part is prepared -> process. */
+
+.Lslow_next_acc_onbb:
+ nill %r9,65532 /* Recognize only fully loaded characters. */
+ je .Lslow_next_acc_onbb2 /* Reload vr, if we loaded no full
+ wchar_t. */
+ vfenezf %v18,%v17,%v17 /* Find zero in loaded bytes of accept part. */
+ vlgvb %r8,%v18,7 /* Load byte index of zero. */
+ clrjl %r8,%r9,.Lslow_next_acc_notonbb /* Found a zero in loaded bytes
+ -> Prepare vreg. */
+.Lslow_next_acc_onbb2:
+ vl %v17,0(%r5,%r3) /* Load over boundary ... */
+ lghi %r8,0 /* r8=0 -> no zero in this part of acc,
+ check for zero is in jump-target. */
+ j .Lslow_next_acc_notonbb /* ... and search for zero in
+ fully loaded vreg again. */
+.Lfallback:
+ jg __wcsspn_c
+END(__wcsspn_vx)
+#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */
diff --git a/REORG.TODO/sysdeps/s390/multiarch/wcsspn.c b/REORG.TODO/sysdeps/s390/multiarch/wcsspn.c
new file mode 100644
index 0000000000..6eaec7dd65
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/multiarch/wcsspn.c
@@ -0,0 +1,29 @@
+/* Multiple versions of wcsspn.
+ Copyright (C) 2015-2017 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 && IS_IN (libc)
+# define wcsspn __redirect_wcsspn
+# include <wchar.h>
+# undef wcsspn
+# include <ifunc-resolve.h>
+
+s390_vx_libc_ifunc2_redirected (__redirect_wcsspn, __wcsspn, wcsspn)
+
+#else
+# include <wcsmbs/wcsspn.c>
+#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)) */
diff --git a/REORG.TODO/sysdeps/s390/multiarch/wmemchr-c.c b/REORG.TODO/sysdeps/s390/multiarch/wmemchr-c.c
new file mode 100644
index 0000000000..0d04494ac8
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/multiarch/wmemchr-c.c
@@ -0,0 +1,37 @@
+/* Default wmemchr implementation for S/390.
+ Copyright (C) 2015-2017 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 && IS_IN (libc)
+# define WMEMCHR __wmemchr_c
+
+# include <wchar.h>
+extern __typeof (wmemchr) __wmemchr_c;
+# undef weak_alias
+# define weak_alias(name, alias)
+# ifdef SHARED
+# undef libc_hidden_def
+# define libc_hidden_def(name) \
+ __hidden_ver1 (__wmemchr_c, __GI___wmemchr, __wmemchr_c);
+# undef libc_hidden_weak
+# define libc_hidden_weak(name) \
+ strong_alias (__wmemchr_c, __wmemchr_c_1); \
+ __hidden_ver1 (__wmemchr_c_1, __GI_wmemchr, __wmemchr_c_1);
+# endif /* SHARED */
+
+# include <wcsmbs/wmemchr.c>
+#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */
diff --git a/REORG.TODO/sysdeps/s390/multiarch/wmemchr-vx.S b/REORG.TODO/sysdeps/s390/multiarch/wmemchr-vx.S
new file mode 100644
index 0000000000..f5ab76e5bc
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/multiarch/wmemchr-vx.S
@@ -0,0 +1,166 @@
+/* Vector optimized 32/64 bit S/390 version of wmemchr.
+ Copyright (C) 2015-2017 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 && IS_IN (libc)
+
+# include "sysdep.h"
+# include "asm-syntax.h"
+
+ .text
+
+/* wchar_t *wmemchr (const wchar_t *s, wchar_t c, size_t n)
+ Scans memory for character c
+ and returns pointer to first c.
+
+ Register usage:
+ -r0=tmp
+ -r1=tmp
+ -r2=s
+ -r3=c
+ -r4=n
+ -r5=current_len
+ -v16=part of s
+ -v17=index of found c
+ -v18=c replicated
+*/
+ENTRY(__wmemchr_vx)
+ .machine "z13"
+ .machinemode "zarch_nohighgprs"
+
+# if !defined __s390x__
+ llgfr %r4,%r4
+# endif /* !defined __s390x__ */
+
+ clgije %r4,0,.Lnf_end /* If len == 0 then exit. */
+
+ vlbb %v16,0(%r2),6 /* Load s until next 4k-byte boundary. */
+ lcbb %r0,0(%r2),6 /* Get bytes to 4k-byte boundary or 16. */
+ llgfr %r0,%r0 /* Convert 32bit to 64bit. */
+
+ tmll %r2,3 /* Test if s is 4-byte aligned? */
+ jne .Lfallback /* And use common-code variant if not. */
+
+ vlvgf %v18,%r3,0 /* Generate vector which elements are all c. */
+ vrepf %v18,%v18,0
+ lghi %r5,16 /* current_len = 16. */
+
+ /* Check range of maxlen and convert to byte-count. */
+# ifdef __s390x__
+ tmhh %r4,49152 /* Test bit 0 or 1 of maxlen. */
+ lghi %r1,-4 /* Max byte-count is 18446744073709551612. */
+# else
+ tmlh %r4,49152 /* Test bit 0 or 1 of maxlen. */
+ llilf %r1,4294967292 /* Max byte-count is 4294967292. */
+# endif /* !__s390x__ */
+ sllg %r4,%r4,2 /* Convert character-count to byte-count. */
+ locgrne %r4,%r1 /* Use max byte-count, if bit 0/1 was one. */
+
+ clgrjhe %r0,%r4,.Llastcmp /* If (bytes to boundary) >= n,
+ jump to lastcmp. */
+
+ vfeefs %v17,%v16,%v18 /* Find c. */
+ vlgvb %r1,%v17,7 /* Load byte index of c. */
+ clgrjl %r1,%r0,.Lfound2 /* Found c is within loaded bytes. */
+
+ /* Align s to 16 byte. */
+ risbgn %r1,%r2,60,128+63,0 /* %r3 = bits 60-63 of %r2 'and' 15. */
+ slr %r5,%r1 /* Compute bytes to 16bytes boundary. */
+
+ lgr %r0,%r5 /* If %r5 + 64 < n? -> loop64. */
+ aghi %r0,64
+ clgrjl %r0,%r4,.Lloop64
+.Llt64:
+ vl %v16,0(%r5,%r2)
+ aghi %r5,16
+ clgrjhe %r5,%r4,.Llastcmp /* Do last compare if curr-len >= n. */
+ vfeefs %v17,%v16,%v18 /* Find c. */
+ jl .Lfound /* Jump away if c was found. */
+
+ vl %v16,0(%r5,%r2)
+ aghi %r5,16
+ clgrjhe %r5,%r4,.Llastcmp
+ vfeefs %v17,%v16,%v18
+ jl .Lfound
+
+ vl %v16,0(%r5,%r2)
+ aghi %r5,16
+ clgrjhe %r5,%r4,.Llastcmp
+ vfeefs %v17,%v16,%v18
+ jl .Lfound
+
+ vl %v16,0(%r5,%r2)
+ aghi %r5,16
+
+.Llastcmp:
+ /* Use comparision result only if located within first n characters.
+ %r5: current_len;
+ %r4: n;
+ (current_len - n): [0...16[
+ first ignored match index = vr-width - (current_len - n) ]0...16]
+ */
+ vfeefs %v17,%v16,%v18 /* Find c. */
+ slgrk %r4,%r5,%r4 /* %r5 = current_len - n. */
+ lghi %r0,16 /* Register width = 16. */
+ vlgvb %r1,%v17,7 /* Extract found index or 16 if all equal. */
+ slr %r0,%r4 /* %r0 = first ignored match index. */
+ clrjl %r1,%r0,.Lfound2 /* Go away if miscompare is below n bytes. */
+ /* c not found within n-bytes. */
+.Lnf_end:
+ lghi %r2,0 /* Return null. */
+ br %r14
+
+.Lfound48:
+ aghi %r5,16
+.Lfound32:
+ aghi %r5,16
+.Lfound16:
+ aghi %r5,16
+.Lfound0:
+ aghi %r5,16
+.Lfound:
+ vlgvb %r1,%v17,7 /* Load byte index of c. */
+.Lfound2:
+ slgfi %r5,16 /* current_len -=16 */
+ algr %r5,%r1 /* Zero byte index is added to current len. */
+ la %r2,0(%r5,%r2) /* Return pointer to c. */
+ br %r14
+
+.Lloop64:
+ vl %v16,0(%r5,%r2)
+ vfeefs %v17,%v16,%v18 /* Find c. */
+ jl .Lfound0 /* Jump away if c was found. */
+ vl %v16,16(%r5,%r2)
+ vfeefs %v17,%v16,%v18
+ jl .Lfound16
+ vl %v16,32(%r5,%r2)
+ vfeefs %v17,%v16,%v18
+ jl .Lfound32
+ vl %v16,48(%r5,%r2)
+ vfeefs %v17,%v16,%v18
+ jl .Lfound48
+
+ aghi %r5,64
+ lgr %r0,%r5 /* If %r5 + 64 < n? -> loop64. */
+ aghi %r0,64
+ clgrjl %r0,%r4,.Lloop64
+
+ j .Llt64
+.Lfallback:
+ jg __wmemchr_c
+END(__wmemchr_vx)
+#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */
diff --git a/REORG.TODO/sysdeps/s390/multiarch/wmemchr.c b/REORG.TODO/sysdeps/s390/multiarch/wmemchr.c
new file mode 100644
index 0000000000..efb4d64e2b
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/multiarch/wmemchr.c
@@ -0,0 +1,32 @@
+/* Multiple versions of wmemchr.
+ Copyright (C) 2015-2017 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 && 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_redirected (__redirect___wmemchr, __wmemchr)
+weak_alias (__wmemchr, wmemchr)
+
+#else
+# include <wcsmbs/wmemchr.c>
+#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)) */
diff --git a/REORG.TODO/sysdeps/s390/multiarch/wmemcmp-c.c b/REORG.TODO/sysdeps/s390/multiarch/wmemcmp-c.c
new file mode 100644
index 0000000000..bdd8995634
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/multiarch/wmemcmp-c.c
@@ -0,0 +1,26 @@
+/* Default wmemcmp implementation for S/390.
+ Copyright (C) 2015-2017 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 && IS_IN (libc)
+# define WMEMCMP __wmemcmp_c
+
+# include <wchar.h>
+extern __typeof (wmemcmp) __wmemcmp_c;
+
+# include <wcsmbs/wmemcmp.c>
+#endif
diff --git a/REORG.TODO/sysdeps/s390/multiarch/wmemcmp-vx.S b/REORG.TODO/sysdeps/s390/multiarch/wmemcmp-vx.S
new file mode 100644
index 0000000000..40e71e5a65
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/multiarch/wmemcmp-vx.S
@@ -0,0 +1,149 @@
+/* Vector Optimized 32/64 bit S/390 version of wmemcmp.
+ Copyright (C) 2015-2017 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 && IS_IN (libc)
+
+# include "sysdep.h"
+# include "asm-syntax.h"
+
+ .text
+
+/* int wmemcmp (const wchar_t *s1, const wchar_t *s2, size_t n)
+ Compare at most n characters of two wchar_t-arrays.
+
+ Register usage:
+ -r0=tmp
+ -r1=number of blocks
+ -r2=s1
+ -r3=s2
+ -r4=n
+ -r5=current_len
+ -v16=part of s1
+ -v17=part of s2
+ -v18=index of unequal
+*/
+ENTRY(__wmemcmp_vx)
+ .machine "z13"
+ .machinemode "zarch_nohighgprs"
+
+# if !defined __s390x__
+ llgfr %r4,%r4
+# endif /* !defined __s390x__ */
+ clgije %r4,0,.Lend_equal /* Nothing to do if n == 0. */
+
+ /* Check range of maxlen and convert to byte-count. */
+# ifdef __s390x__
+ tmhh %r4,49152 /* Test bit 0 or 1 of maxlen. */
+ lghi %r1,-4 /* Max byte-count is 18446744073709551612. */
+# else
+ tmlh %r4,49152 /* Test bit 0 or 1 of maxlen. */
+ llilf %r1,4294967292 /* Max byte-count is 4294967292. */
+# endif /* !__s390x__ */
+ sllg %r4,%r4,2 /* Convert character-count to byte-count. */
+ locgrne %r4,%r1 /* Use max byte-count, if bit 0/1 was one. */
+
+ lghi %r5,0 /* current_len = 0. */
+
+ clgijh %r4,16,.Lgt16
+
+.Lremaining:
+ aghi %r4,-1 /* vstl needs highest index. */
+ vll %v16,%r4,0(%r2)
+ vll %v17,%r4,0(%r3)
+ vfenef %v18,%v16,%v17 /* Compare not equal. */
+ vlgvb %r1,%v18,7 /* Load unequal index or 16 if not found. */
+ clrj %r1,%r4,12,.Lfound2 /* r1 <= r4 -> unequal within loaded
+ bytes. */
+
+.Lend_equal:
+ lghi %r2,0
+ br %r14
+
+.Lfound:
+ /* vfenezf found an unequal element or zero.
+ This instruction compares unsigned words, but wchar_t is signed.
+ Thus we have to compare the found element again. */
+ vlgvb %r1,%v18,7 /* Extract not equal byte-index. */
+.Lfound2:
+ srl %r1,2 /* And convert it to character-index. */
+ vlgvf %r0,%v16,0(%r1) /* Load character-values. */
+ vlgvf %r1,%v17,0(%r1)
+ cr %r0,%r1
+ je .Lend_equal
+ lghi %r2,1
+ lghi %r1,-1
+ locgrl %r2,%r1
+ br %r14
+
+.Lgt16:
+ clgijh %r4,64,.Lpreloop64
+
+.Lpreloop16:
+ srlg %r1,%r4,4 /* Split into 16byte blocks */
+.Lloop16:
+ vl %v16,0(%r5,%r2)
+ vl %v17,0(%r5,%r3)
+ aghi %r5,16
+ vfenefs %v18,%v16,%v17 /* Compare not equal. */
+ jno .Lfound
+ brctg %r1,.Lloop16 /* Loop until all blocks are processed. */
+
+ llgfr %r4,%r4
+ nilf %r4,15 /* Get remaining bytes */
+ locgre %r2,%r4
+ ber %r14
+ la %r2,0(%r5,%r2)
+ la %r3,0(%r5,%r3)
+ j .Lremaining
+
+.Lpreloop64:
+ srlg %r1,%r4,6 /* Split into 64byte blocks */
+.Lloop64:
+ vl %v16,0(%r5,%r2)
+ vl %v17,0(%r5,%r3)
+ vfenefs %v18,%v16,%v17 /* Compare not equal. */
+ jno .Lfound
+
+ vl %v16,16(%r5,%r2)
+ vl %v17,16(%r5,%r3)
+ vfenefs %v18,%v16,%v17
+ jno .Lfound
+
+ vl %v16,32(%r5,%r2)
+ vl %v17,32(%r5,%r3)
+ vfenefs %v18,%v16,%v17
+ jno .Lfound
+
+ vl %v16,48(%r5,%r2)
+ vl %v17,48(%r5,%r3)
+ aghi %r5,64
+ vfenefs %v18,%v16,%v17
+ jno .Lfound
+
+ brctg %r1,.Lloop64 /* Loop until all blocks are processed. */
+
+ llgfr %r4,%r4
+ nilf %r4,63 /* Get remaining bytes */
+ locgre %r2,%r4
+ ber %r14
+ clgijh %r4,16,.Lpreloop16
+ la %r2,0(%r5,%r2)
+ la %r3,0(%r5,%r3)
+ j .Lremaining
+END(__wmemcmp_vx)
+#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */
diff --git a/REORG.TODO/sysdeps/s390/multiarch/wmemcmp.c b/REORG.TODO/sysdeps/s390/multiarch/wmemcmp.c
new file mode 100644
index 0000000000..59471a36b2
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/multiarch/wmemcmp.c
@@ -0,0 +1,27 @@
+/* Multiple versions of wmemcmp.
+ Copyright (C) 2015-2017 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 && IS_IN (libc)
+# include <wchar.h>
+# include <ifunc-resolve.h>
+
+s390_vx_libc_ifunc2 (__wmemcmp, wmemcmp)
+
+#else
+# include <wcsmbs/wmemcmp.c>
+#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)) */
diff --git a/REORG.TODO/sysdeps/s390/multiarch/wmemset-c.c b/REORG.TODO/sysdeps/s390/multiarch/wmemset-c.c
new file mode 100644
index 0000000000..9d5a848ec8
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/multiarch/wmemset-c.c
@@ -0,0 +1,37 @@
+/* Default wmemset implementation for S/390.
+ Copyright (C) 2015-2017 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 && IS_IN (libc)
+# define WMEMSET __wmemset_c
+
+# include <wchar.h>
+extern __typeof (__wmemset) __wmemset_c;
+# undef weak_alias
+# define weak_alias(name, alias)
+# ifdef SHARED
+# undef libc_hidden_def
+# define libc_hidden_def(name) \
+ __hidden_ver1 (__wmemset_c, __GI___wmemset, __wmemset_c);
+# undef libc_hidden_weak
+# define libc_hidden_weak(name) \
+ strong_alias (__wmemset_c, __wmemset_c_1); \
+ __hidden_ver1 (__wmemset_c_1, __GI_wmemset, __wmemset_c_1);
+# endif /* SHARED */
+
+# include <wcsmbs/wmemset.c>
+#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */
diff --git a/REORG.TODO/sysdeps/s390/multiarch/wmemset-vx.S b/REORG.TODO/sysdeps/s390/multiarch/wmemset-vx.S
new file mode 100644
index 0000000000..6b76dead18
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/multiarch/wmemset-vx.S
@@ -0,0 +1,142 @@
+/* Vector Optimized 32/64 bit S/390 version of wmemset.
+ Copyright (C) 2015-2017 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 && IS_IN (libc)
+
+# include "sysdep.h"
+# include "asm-syntax.h"
+
+ .text
+
+/* wchar_t *wmemset(wchar_t *dest, wchar_t wc, size_t n)
+ Fill an array of wide-characters with a constant wide character
+ and returns dest.
+
+ Register usage:
+ -r0=tmp
+ -r1=tmp
+ -r2=dest or current-pointer
+ -r3=wc
+ -r4=n
+ -r5=tmp
+ -v16=replicated wc
+ -v17,v18,v19=copy of v16 for vstm
+ -v31=saved dest for return
+*/
+ENTRY(__wmemset_vx)
+ .machine "z13"
+ .machinemode "zarch_nohighgprs"
+
+# if !defined __s390x__
+ llgfr %r4,%r4
+# endif /* !defined __s390x__ */
+
+ vlvgg %v31,%r2,0 /* Save destination pointer for return. */
+ clgije %r4,0,.Lend
+
+ vlvgf %v16,%r3,0 /* Generate vector with wchar_t wc. */
+ vrepf %v16,%v16,0
+
+ /* Check range of maxlen and convert to byte-count. */
+# ifdef __s390x__
+ tmhh %r4,49152 /* Test bit 0 or 1 of maxlen. */
+ lghi %r5,-4 /* Max byte-count is 18446744073709551612. */
+# else
+ tmlh %r4,49152 /* Test bit 0 or 1 of maxlen. */
+ llilf %r5,4294967292 /* Max byte-count is 4294967292. */
+# endif /* !__s390x__ */
+ sllg %r4,%r4,2 /* Convert character-count to byte-count. */
+ locgrne %r4,%r5 /* Use max byte-count, if bit 0/1 was one. */
+
+ /* Align dest to 16 byte. */
+ risbg %r0,%r2,60,128+63,0 /* Test if s is aligned and
+ %r3 = bits 60-63 'and' 15. */
+ je .Lpreloop /* If s is aligned, loop aligned. */
+ tmll %r2,3 /* Test if s is 4-byte aligned? */
+ jne .Lfallback /* And use common-code variant if not. */
+ lghi %r1,16
+ slr %r1,%r0 /* Compute byte count to load (16-x). */
+ clgr %r1,%r4
+ locgrh %r1,%r4 /* min (byte count, n) */
+ aghik %r5,%r1,-1 /* vstl needs highest index. */
+ vstl %v16,%r5,0(%r2) /* Store remaining bytes. */
+ clgrje %r1,%r4,.Lend /* Return if n bytes where set. */
+ slgr %r4,%r1 /* Compute remaining byte count. */
+ la %r2,0(%r1,%r2)
+
+.Lpreloop:
+ /* Now we are 16-byte aligned. */
+ clgijl %r4,17,.Lremaining
+ srlg %r1,%r4,8 /* Split into 256byte blocks */
+ clgije %r1,0,.Lpreloop64
+ vlr %v17,%v16
+ vlr %v18,%v16
+ vlr %v19,%v16
+
+.Lloop256:
+ vstm %v16,%v19,0(%r2)
+ vstm %v16,%v19,64(%r2)
+ vstm %v16,%v19,128(%r2)
+ vstm %v16,%v19,192(%r2)
+ la %r2,256(%r2)
+ brctg %r1,.Lloop256 /* Loop until all blocks are processed. */
+
+ llgfr %r4,%r4
+ nilf %r4,255 /* Get remaining bytes */
+ je .Lend /* Skip store remaining bytes if zero. */
+
+.Lpreloop64:
+ clgijl %r4,17,.Lremaining
+ clgijl %r4,33,.Lpreloop16
+ srlg %r1,%r4,5 /* Split into 32byte blocks */
+
+.Lloop32:
+ vst %v16,0(%r2)
+ vst %v16,16(%r2)
+ la %r2,32(%r2)
+ brctg %r1,.Lloop32 /* Loop until all blocks are processed. */
+
+ llgfr %r4,%r4
+ nilf %r4,31 /* Get remaining bytes */
+ je .Lend /* Skip store remaining bytes if zero. */
+
+.Lpreloop16:
+ clgijl %r4,17,.Lremaining
+ srlg %r1,%r4,4 /* Split into 16byte blocks */
+
+.Lloop16:
+ vst %v16,0(%r2)
+ la %r2,16(%r2)
+ brctg %r1,.Lloop16 /* Loop until all blocks are processed. */
+
+ llgfr %r4,%r4
+ nilf %r4,15 /* Get remaining bytes */
+ je .Lend /* Skip store remaining bytes if zero. */
+
+.Lremaining:
+ aghi %r4,-1 /* vstl needs highest index. */
+ vstl %v16,%r4,0(%r2)
+
+.Lend:
+ vlgvg %r2,%v31,0 /* Load saved dest for return value. */
+ br %r14
+.Lfallback:
+ srlg %r4,%r4,2 /* Convert byte-count to character-count. */
+ jg __wmemset_c
+END(__wmemset_vx)
+#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */
diff --git a/REORG.TODO/sysdeps/s390/multiarch/wmemset.c b/REORG.TODO/sysdeps/s390/multiarch/wmemset.c
new file mode 100644
index 0000000000..d3eea1cee0
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/multiarch/wmemset.c
@@ -0,0 +1,32 @@
+/* Multiple versions of wmemset.
+ Copyright (C) 2015-2017 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 && 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_redirected (__redirect___wmemset, __wmemset)
+weak_alias (__wmemset, wmemset)
+
+#else
+# include <wcsmbs/wmemset.c>
+#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)) */
diff --git a/REORG.TODO/sysdeps/s390/nptl/Makefile b/REORG.TODO/sysdeps/s390/nptl/Makefile
new file mode 100644
index 0000000000..f5957b9060
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/nptl/Makefile
@@ -0,0 +1,25 @@
+# Copyright (C) 2003-2017 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/>.
+
+ifeq ($(subdir),csu)
+gen-as-const-headers += tcb-offsets.sym
+endif
+
+ifeq ($(subdir),nptl)
+libpthread-routines += sysdep
+libpthread-shared-only-routines += sysdep
+endif
diff --git a/REORG.TODO/sysdeps/s390/nptl/bits/pthreadtypes-arch.h b/REORG.TODO/sysdeps/s390/nptl/bits/pthreadtypes-arch.h
new file mode 100644
index 0000000000..3a9ac57625
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/nptl/bits/pthreadtypes-arch.h
@@ -0,0 +1,81 @@
+/* Copyright (C) 2003-2017 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
+#ifdef ENABLE_LOCK_ELISION
+#define __PTHREAD_MUTEX_LOCK_ELISION 1
+#else
+#define __PTHREAD_MUTEX_LOCK_ELISION 0
+#endif
+
+#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/REORG.TODO/sysdeps/s390/nptl/bits/semaphore.h b/REORG.TODO/sysdeps/s390/nptl/bits/semaphore.h
new file mode 100644
index 0000000000..976a136fd2
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/nptl/bits/semaphore.h
@@ -0,0 +1,39 @@
+/* Copyright (C) 2003-2017 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
+ 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 _SEMAPHORE_H
+# error "Never use <bits/semaphore.h> directly; include <semaphore.h> instead."
+#endif
+
+#include <bits/wordsize.h>
+
+#if __WORDSIZE == 64
+# define __SIZEOF_SEM_T 32
+#else
+# define __SIZEOF_SEM_T 16
+#endif
+
+/* Value returned if `sem_open' failed. */
+#define SEM_FAILED ((sem_t *) 0)
+
+
+typedef union
+{
+ char __size[__SIZEOF_SEM_T];
+ long int __align;
+} sem_t;
diff --git a/REORG.TODO/sysdeps/s390/nptl/pthreaddef.h b/REORG.TODO/sysdeps/s390/nptl/pthreaddef.h
new file mode 100644
index 0000000000..a5ae960c7d
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/nptl/pthreaddef.h
@@ -0,0 +1,33 @@
+/* Copyright (C) 2003-2017 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/>. */
+
+/* Default stack size. */
+#define ARCH_STACK_DEFAULT_SIZE (2 * 1024 * 1024)
+
+/* Required stack pointer alignment at beginning. SSE requires 16
+ bytes. */
+#define STACK_ALIGN 16
+
+/* Minimal stack size after allocating thread descriptor and guard size. */
+#define MINIMAL_REST_STACK 2048
+
+/* Alignment requirement for TCB. */
+#define TCB_ALIGNMENT 16
+
+
+/* Location of current stack frame. */
+#define CURRENT_STACK_FRAME __builtin_frame_address (0)
diff --git a/REORG.TODO/sysdeps/s390/nptl/tcb-offsets.sym b/REORG.TODO/sysdeps/s390/nptl/tcb-offsets.sym
new file mode 100644
index 0000000000..9c1c01f353
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/nptl/tcb-offsets.sym
@@ -0,0 +1,6 @@
+#include <sysdep.h>
+#include <tls.h>
+
+MULTIPLE_THREADS_OFFSET offsetof (tcbhead_t, multiple_threads)
+STACK_GUARD offsetof (tcbhead_t, stack_guard)
+TID offsetof (struct pthread, tid)
diff --git a/REORG.TODO/sysdeps/s390/nptl/tls.h b/REORG.TODO/sysdeps/s390/nptl/tls.h
new file mode 100644
index 0000000000..7bc6c897b3
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/nptl/tls.h
@@ -0,0 +1,196 @@
+/* Definition for thread-local data handling. NPTL/s390 version.
+ Copyright (C) 2003-2017 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 _TLS_H
+#define _TLS_H 1
+
+#include <dl-sysdep.h>
+#ifndef __ASSEMBLER__
+# include <stdbool.h>
+# include <stddef.h>
+# include <stdint.h>
+# include <stdlib.h>
+# include <list.h>
+# include <kernel-features.h>
+# include <dl-dtv.h>
+
+typedef struct
+{
+ void *tcb; /* Pointer to the TCB. Not necessary the
+ thread descriptor used by libpthread. */
+ dtv_t *dtv;
+ void *self; /* Pointer to the thread descriptor. */
+ int multiple_threads;
+ 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;
+
+# ifndef __s390x__
+# define TLS_MULTIPLE_THREADS_IN_TCB 1
+# endif
+
+#else /* __ASSEMBLER__ */
+# include <tcb-offsets.h>
+#endif
+
+
+/* Alignment requirement for the stack. For IA-32 this is governed by
+ the SSE memory functions. */
+#define STACK_ALIGN 16
+
+#ifndef __ASSEMBLER__
+/* Get system call information. */
+# include <sysdep.h>
+
+/* This is the size of the initial TCB. Can't be just sizeof (tcbhead_t),
+ because NPTL getpid, __libc_alloca_cutoff etc. need (almost) the whole
+ struct pthread even when not linked with -lpthread. */
+# define TLS_INIT_TCB_SIZE sizeof (struct pthread)
+
+/* Alignment requirements for the initial TCB. */
+# define TLS_INIT_TCB_ALIGN __alignof__ (struct pthread)
+
+/* This is the size of the TCB. */
+# define TLS_TCB_SIZE sizeof (struct pthread)
+
+/* Alignment requirements for the TCB. */
+# define TLS_TCB_ALIGN __alignof__ (struct pthread)
+
+/* The TCB can have any size and the memory following the address the
+ thread pointer points to is unspecified. Allocate the TCB there. */
+# define TLS_TCB_AT_TP 1
+# define TLS_DTV_AT_TP 0
+
+/* Get the thread descriptor definition. */
+# include <nptl/descr.h>
+
+
+/* Install the dtv pointer. The pointer passed is to the element with
+ index -1 which contain the length. */
+# define INSTALL_DTV(descr, dtvp) \
+ ((tcbhead_t *) (descr))->dtv = (dtvp) + 1
+
+/* Install new dtv for current thread. */
+# define INSTALL_NEW_DTV(dtv) \
+ (((tcbhead_t *) __builtin_thread_pointer ())->dtv = (dtv))
+
+/* Return dtv of given thread descriptor. */
+# define GET_DTV(descr) \
+ (((tcbhead_t *) (descr))->dtv)
+
+#if defined NEED_DL_SYSINFO && defined SHARED
+# define INIT_SYSINFO \
+ _head->sysinfo = GLRO(dl_sysinfo)
+#else
+# define INIT_SYSINFO
+#endif
+
+/* Code to initially initialize the thread pointer. This might need
+ special attention since 'errno' is not yet available and if the
+ operation can cause a failure 'errno' must not be touched. */
+# define TLS_INIT_TP(thrdescr) \
+ ({ void *_thrdescr = (thrdescr); \
+ tcbhead_t *_head = _thrdescr; \
+ \
+ _head->tcb = _thrdescr; \
+ /* For now the thread descriptor is at the same address. */ \
+ _head->self = _thrdescr; \
+ /* New syscall handling support. */ \
+ INIT_SYSINFO; \
+ \
+ __builtin_set_thread_pointer (_thrdescr); \
+ NULL; \
+ })
+
+/* Value passed to 'clone' for initialization of the thread register. */
+# define TLS_DEFINE_INIT_TP(tp, pd) void *tp = (pd)
+
+/* Return the address of the dtv for the current thread. */
+# define THREAD_DTV() \
+ (((tcbhead_t *) __builtin_thread_pointer ())->dtv)
+
+/* Return the thread descriptor for the current thread. */
+# define THREAD_SELF ((struct pthread *) __builtin_thread_pointer ())
+
+/* Magic for libthread_db to know how to do THREAD_SELF. */
+# define DB_THREAD_SELF REGISTER (32, 32, 18 * 4, 0) \
+ REGISTER (64, __WORDSIZE, 18 * 8, 0)
+
+/* Access to data in the thread descriptor is easy. */
+#define THREAD_GETMEM(descr, member) \
+ descr->member
+#define THREAD_GETMEM_NC(descr, member, idx) \
+ descr->member[idx]
+#define THREAD_SETMEM(descr, member, value) \
+ descr->member = (value)
+#define THREAD_SETMEM_NC(descr, member, idx, value) \
+ descr->member[idx] = (value)
+
+/* Set the stack guard field in TCB head. */
+#define THREAD_SET_STACK_GUARD(value) \
+ do \
+ { \
+ __asm__ __volatile__ ("" : : : "a0", "a1"); \
+ THREAD_SETMEM (THREAD_SELF, header.stack_guard, value); \
+ } \
+ while (0)
+#define THREAD_COPY_STACK_GUARD(descr) \
+ ((descr)->header.stack_guard \
+ = THREAD_GETMEM (THREAD_SELF, header.stack_guard))
+
+/* s390 doesn't have HP_TIMING_*, so for the time being
+ use stack_guard as pointer_guard. */
+#define THREAD_GET_POINTER_GUARD() \
+ THREAD_GETMEM (THREAD_SELF, header.stack_guard)
+#define THREAD_SET_POINTER_GUARD(value) ((void) (value))
+#define THREAD_COPY_POINTER_GUARD(descr)
+
+/* Get and set the global scope generation counter in struct pthread. */
+#define THREAD_GSCOPE_FLAG_UNUSED 0
+#define THREAD_GSCOPE_FLAG_USED 1
+#define THREAD_GSCOPE_FLAG_WAIT 2
+#define THREAD_GSCOPE_RESET_FLAG() \
+ do \
+ { int __res \
+ = atomic_exchange_rel (&THREAD_SELF->header.gscope_flag, \
+ THREAD_GSCOPE_FLAG_UNUSED); \
+ if (__res == THREAD_GSCOPE_FLAG_WAIT) \
+ lll_futex_wake (&THREAD_SELF->header.gscope_flag, 1, LLL_PRIVATE); \
+ } \
+ while (0)
+#define THREAD_GSCOPE_SET_FLAG() \
+ do \
+ { \
+ THREAD_SELF->header.gscope_flag = THREAD_GSCOPE_FLAG_USED; \
+ atomic_write_barrier (); \
+ } \
+ while (0)
+#define THREAD_GSCOPE_WAIT() \
+ GL(dl_wait_lookup_done) ()
+
+#endif /* __ASSEMBLER__ */
+
+#endif /* tls.h */
diff --git a/REORG.TODO/sysdeps/s390/preconfigure b/REORG.TODO/sysdeps/s390/preconfigure
new file mode 100644
index 0000000000..d6302b0c15
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/preconfigure
@@ -0,0 +1,6 @@
+# preconfigure fragment for s390.
+
+case "$machine" in
+s390) base_machine=s390 machine=s390/s390-32 ;;
+s390x) base_machine=s390 machine=s390/s390-64 ;;
+esac
diff --git a/REORG.TODO/sysdeps/s390/s390-32/Implies b/REORG.TODO/sysdeps/s390/s390-32/Implies
new file mode 100644
index 0000000000..39a34c5f57
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/s390-32/Implies
@@ -0,0 +1 @@
+wordsize-32
diff --git a/REORG.TODO/sysdeps/s390/s390-32/Makefile b/REORG.TODO/sysdeps/s390/s390-32/Makefile
new file mode 100644
index 0000000000..a07f2986ae
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/s390-32/Makefile
@@ -0,0 +1,9 @@
+ifeq ($(subdir),gmon)
+sysdep_routines += s390-mcount
+endif
+
+ifeq ($(subdir),elf)
+CFLAGS-rtld.c += -Wno-uninitialized -Wno-unused
+CFLAGS-dl-load.c += -Wno-unused
+CFLAGS-dl-reloc.c += -Wno-unused
+endif
diff --git a/REORG.TODO/sysdeps/s390/s390-32/Versions b/REORG.TODO/sysdeps/s390/s390-32/Versions
new file mode 100644
index 0000000000..2b020f8f58
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/s390-32/Versions
@@ -0,0 +1,6 @@
+libc {
+ GLIBC_2.0 {
+ # Functions from libgcc.
+ __divdi3; __moddi3; __udivdi3; __umoddi3;
+ }
+}
diff --git a/REORG.TODO/sysdeps/s390/s390-32/__longjmp.c b/REORG.TODO/sysdeps/s390/s390-32/__longjmp.c
new file mode 100644
index 0000000000..abdd9641e6
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/s390-32/__longjmp.c
@@ -0,0 +1,83 @@
+/* Copyright (C) 2000-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com).
+
+ 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 <errno.h>
+#include <sysdep.h>
+#include <setjmp.h>
+#include <bits/setjmp.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <stap-probe.h>
+
+/* Jump to the position specified by ENV, causing the
+ setjmp call there to return VAL, or 1 if VAL is 0. */
+void
+__longjmp (__jmp_buf env, int val)
+{
+#ifdef PTR_DEMANGLE
+ uintptr_t guard = THREAD_GET_POINTER_GUARD ();
+# ifdef CHECK_SP
+ CHECK_SP (env, guard);
+# endif
+#elif defined CHECK_SP
+ CHECK_SP (env, 0);
+#endif
+ register int r2 __asm__ ("%r2") = val == 0 ? 1 : val;
+#ifdef PTR_DEMANGLE
+ register uintptr_t r3 __asm__ ("%r3") = guard;
+ register void *r1 __asm__ ("%r1") = (void *) env;
+#endif
+ /* Restore registers and jump back. */
+ __asm__ __volatile__ (
+ /* longjmp probe expects longjmp first argument, second
+ argument and target address. */
+#ifdef PTR_DEMANGLE
+ "lm %%r4,%%r5,32(%1)\n\t"
+ "xr %%r4,%2\n\t"
+ "xr %%r5,%2\n\t"
+ LIBC_PROBE_ASM (longjmp, 4@%1 -4@%0 4@%%r4)
+#else
+ LIBC_PROBE_ASM (longjmp, 4@%1 -4@%0 4@%%r14)
+#endif
+
+ /* restore fpregs */
+ "ld %%f6,48(%1)\n\t"
+ "ld %%f4,40(%1)\n\t"
+
+ /* restore gregs and return to jmp_buf target */
+#ifdef PTR_DEMANGLE
+ "lm %%r6,%%r13,0(%1)\n\t"
+ "lr %%r15,%%r5\n\t"
+ LIBC_PROBE_ASM (longjmp_target, 4@%1 -4@%0 4@%%r4)
+ "br %%r4"
+#else
+ "lm %%r6,%%r15,0(%1)\n\t"
+ LIBC_PROBE_ASM (longjmp_target, 4@%1 -4@%0 4@%%r14)
+ "br %%r14"
+#endif
+ : : "r" (r2),
+#ifdef PTR_DEMANGLE
+ "r" (r1), "r" (r3)
+#else
+ "a" (env)
+#endif
+ );
+
+ /* Avoid `volatile function does return' warnings. */
+ for (;;);
+}
diff --git a/REORG.TODO/sysdeps/s390/s390-32/add_n.S b/REORG.TODO/sysdeps/s390/s390-32/add_n.S
new file mode 100644
index 0000000000..ed9cc27693
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/s390-32/add_n.S
@@ -0,0 +1,63 @@
+/* Add two limb vectors of the same length > 0 and store sum in a third
+ limb vector.
+ Copyright (C) 2000-2017 Free Software Foundation, Inc.
+ Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com).
+ This file is part of the GNU MP Library.
+
+ The GNU MP 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 MP 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 MP Library; see the file COPYING.LIB. If not,
+ see <http://www.gnu.org/licenses/>. */
+
+/*
+ INPUT PARAMETERS
+ res_ptr %r2
+ s1_ptr %r3
+ s2_ptr %r4
+ size %r5
+*/
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+
+ .text
+ENTRY(__mpn_add_n)
+ st %r6,24(%r15) # save register 6
+ cfi_offset (%r6, -72)
+ sr %r1,%r1
+ lhi %r0,1 # cannot use ahi to add carry, use alr
+.L0: l %r6,0(%r1,%r3) # .L0 -> no carry from last add
+ al %r6,0(%r1,%r4)
+ st %r6,0(%r1,%r2)
+ la %r1,4(0,%r1)
+ brc 3,.L3
+.L1: brct %r5,.L0
+ slr %r2,%r2 # no last carry to return
+ j .Lexit
+.L2: l %r6,0(%r1,%r3) # .L2 -> carry from last add
+ al %r6,0(%r1,%r4)
+ brc 3,.L4
+ alr %r6,%r0 # no carry yet, add carry from last add
+ st %r6,0(%r1,%r2)
+ la %r1,4(0,%r1)
+ brc 12,.L1 # new carry ?
+.L3: brct %r5,.L2
+ lr %r2,%r0 # return last carry
+ j .Lexit
+.L4: alr %r6,%r0 # already a carry, add carry from last add
+ st %r6,0(%r1,%r2)
+ la %r1,4(0,%r1)
+ brct %r5,.L2
+ lr %r2,%r0 # return last carry
+.Lexit: l %r6,24(%r15) # restore register 6
+ br %r14
+END(__mpn_add_n)
diff --git a/REORG.TODO/sysdeps/s390/s390-32/addmul_1.S b/REORG.TODO/sysdeps/s390/s390-32/addmul_1.S
new file mode 100644
index 0000000000..6a4318ce49
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/s390-32/addmul_1.S
@@ -0,0 +1,58 @@
+/* S390 __mpn_addmul_1 -- Multiply a limb vector with a limb and add
+ the result to a second limb vector.
+ Copyright (C) 2000-2017 Free Software Foundation, Inc.
+ Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com).
+ This file is part of the GNU MP Library.
+
+ The GNU MP 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 MP 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 MP Library; see the file COPYING.LIB. If not,
+ see <http://www.gnu.org/licenses/>. */
+
+/*
+ INPUT PARAMETERS
+ res_ptr %r2
+ s1_ptr %r3
+ sizeP %r4
+ s2_limb %r5
+*/
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+
+ .text
+ENTRY(__mpn_addmul_1)
+ st %r6,24(%r15)
+ cfi_offset (%r6, -72)
+ slr %r6,%r6 # cy_limb = 0
+.L0: icm %r1,15,0(%r3) # get s1_ptr[i]
+ mr %r0,%r5 # umul_ppmm(prod_high,prod_low,s1_ptr[j],s2_limb)
+ jnm .L1
+ alr %r0,%r5
+.L1: ltr %r5,%r5
+ jnm .L2
+ al %r0,0(%r3)
+.L2: alr %r1,%r6 # prod_low += cy_limb
+ lr %r6,%r0 # cy_limb = prod_high
+ brc 12,.L3
+ ahi %r6,1 # + (prod_low < cy_limb)
+.L3: al %r1,0(%r2) # prod_low += res_ptr[i]
+ brc 12,.L4
+ ahi %r6,1 # cy_limb++
+.L4: st %r1,0(%r2)
+ la %r2,4(0,%r2)
+ la %r3,4(0,%r3)
+ brct %r4,.L0
+ lr %r2,%r6 # return cy_limb
+ l %r6,24(%r15)
+.Lexit: br %r14
+END(__mpn_addmul_1)
diff --git a/REORG.TODO/sysdeps/s390/s390-32/backtrace.c b/REORG.TODO/sysdeps/s390/s390-32/backtrace.c
new file mode 100644
index 0000000000..705b05d139
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/s390-32/backtrace.c
@@ -0,0 +1,148 @@
+/* Return backtrace of current program state.
+ Copyright (C) 2000-2017 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/>. */
+
+#include <libc-lock.h>
+#include <dlfcn.h>
+#include <execinfo.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <unwind.h>
+
+/* This is a global variable set at program start time. It marks the
+ highest used stack address. */
+extern void *__libc_stack_end;
+
+
+/* This is the stack layout we see for every non-leaf function.
+ size offset
+ %r15 -> +------------------+
+ 4 | back chain | 0
+ 4 | end of stack | 4
+ 8 | glue | 8
+ 8 | scratch | 16
+ 40 | save area r6-r15 | 24
+ 16 | save area f4,f6 | 64
+ 16 | empty | 80
+ +------------------+
+ r14 in the save area holds the return address.
+*/
+
+struct layout
+{
+ int back_chain;
+ int end_of_stack;
+ int glue[2];
+ int scratch[2];
+ int save_grps[10];
+ int save_fp[4];
+ int empty[2];
+};
+
+struct trace_arg
+{
+ void **array;
+ int cnt, size;
+};
+
+#ifdef SHARED
+static _Unwind_Reason_Code (*unwind_backtrace) (_Unwind_Trace_Fn, void *);
+static _Unwind_Ptr (*unwind_getip) (struct _Unwind_Context *);
+
+static void
+init (void)
+{
+ void *handle = __libc_dlopen ("libgcc_s.so.1");
+
+ if (handle == NULL)
+ return;
+
+ unwind_backtrace = __libc_dlsym (handle, "_Unwind_Backtrace");
+ unwind_getip = __libc_dlsym (handle, "_Unwind_GetIP");
+ if (unwind_getip == NULL)
+ unwind_backtrace = NULL;
+}
+
+static int
+__backchain_backtrace (void **array, int size)
+{
+ /* We assume that all the code is generated with frame pointers set. */
+ struct layout *stack;
+ int cnt = 0;
+
+ __asm__ ("LR %0,%%r15" : "=d" (stack) );
+ /* We skip the call to this function, it makes no sense to record it. */
+ stack = (struct layout *) stack->back_chain;
+ while (cnt < size)
+ {
+ if (stack == NULL || (void *) stack > __libc_stack_end)
+ /* This means the address is out of range. Note that for the
+ toplevel we see a frame pointer with value NULL which clearly is
+ out of range. */
+ break;
+
+ array[cnt++] = (void *) (stack->save_grps[8] & 0x7fffffff);
+
+ stack = (struct layout *) stack->back_chain;
+ }
+
+ return cnt;
+}
+#else
+# define unwind_backtrace _Unwind_Backtrace
+# define unwind_getip _Unwind_GetIP
+#endif
+
+static _Unwind_Reason_Code
+backtrace_helper (struct _Unwind_Context *ctx, void *a)
+{
+ struct trace_arg *arg = a;
+
+ /* We are first called with address in the __backtrace function.
+ Skip it. */
+ if (arg->cnt != -1)
+ arg->array[arg->cnt] = (void *) unwind_getip (ctx);
+ if (++arg->cnt == arg->size)
+ return _URC_END_OF_STACK;
+ return _URC_NO_REASON;
+}
+
+int
+__backtrace (void **array, int size)
+{
+ struct trace_arg arg = { .array = array, .size = size, .cnt = -1 };
+
+ if (size <= 0)
+ return 0;
+
+#ifdef SHARED
+ __libc_once_define (static, once);
+
+ __libc_once (once, init);
+
+ if (unwind_backtrace == NULL)
+ return __backchain_backtrace (array, size);
+#endif
+
+ unwind_backtrace (backtrace_helper, &arg);
+
+ return arg.cnt != -1 ? arg.cnt : 0;
+}
+
+weak_alias (__backtrace, backtrace)
+libc_hidden_def (__backtrace)
diff --git a/REORG.TODO/sysdeps/s390/s390-32/bcopy.S b/REORG.TODO/sysdeps/s390/s390-32/bcopy.S
new file mode 100644
index 0000000000..06f51f3aa7
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/s390-32/bcopy.S
@@ -0,0 +1,85 @@
+/* bcopy -- copy a block from source to destination. S/390 version.
+ This file is part of the GNU C Library.
+ Copyright (C) 2000-2017 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
+ 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/>. */
+
+/* INPUT PARAMETERS
+ %r2 = address of source
+ %r3 = address of destination
+ %r4 = number of bytes to copy. */
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+
+ .text
+ENTRY(__bcopy)
+ ltr %r1,%r4 # zero bcopy ?
+ jz .L4
+ clr %r2,%r3 # check against destructive overlap
+ jnl .L0
+ alr %r1,%r2
+ clr %r1,%r3
+ jh .L7
+.L0: ahi %r4,-1 # length - 1
+ lr %r1,%r4
+ srl %r1,8
+ ltr %r1,%r1 # < 256 bytes to move ?
+ jz .L2
+ chi %r1,255 # > 1MB to move ?
+ jh .L5
+.L1: mvc 0(256,%r3),0(%r2) # move in 256 byte chunks
+ la %r2,256(%r2)
+ la %r3,256(%r3)
+ brct %r1,.L1
+.L2: bras %r1,.L3 # setup base pointer for execute
+ mvc 0(1,%r3),0(%r2) # instruction for execute
+.L3: ex %r4,0(%r1) # execute mvc with length ((%r4)&255)+1
+.L4: br %r14
+
+ # data copies > 1MB are faster with mvcle.
+.L5: ahi %r4,1 # length + 1
+ lr %r5,%r4 # source length
+ lr %r4,%r2 # source address
+ lr %r2,%r3 # set destination
+ lr %r3,%r5 # destination length = source length
+.L6: mvcle %r2,%r4,0 # thats it, MVCLE is your friend
+ jo .L6
+ br %r14
+.L7: # destructive overlay, can not use mvcle
+ lr %r1,%r2 # bcopy is called with source,dest
+ lr %r2,%r3 # memmove with dest,source! Oh, well...
+ lr %r3,%r1
+ basr %r1,0
+.L8:
+#ifdef PIC
+ al %r1,.L9-.L8(%r1) # get address of global offset table
+ # load address of memmove
+ l %r1,memmove@GOT(%r1)
+ br %r1
+.L9: .long _GLOBAL_OFFSET_TABLE_-.L8
+#else
+ al %r1,.L9-.L8(%r1) # load address of memmove
+ br %r1 # jump to memmove
+.L9: .long memmove-.L8
+#endif
+
+END(__bcopy)
+
+#ifndef NO_WEAK_ALIAS
+weak_alias (__bcopy, bcopy)
+#endif
+
diff --git a/REORG.TODO/sysdeps/s390/s390-32/bits/wordsize.h b/REORG.TODO/sysdeps/s390/s390-32/bits/wordsize.h
new file mode 100644
index 0000000000..129e47182b
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/s390-32/bits/wordsize.h
@@ -0,0 +1,11 @@
+/* Determine the wordsize from the preprocessor defines. */
+
+#if defined __s390x__
+# define __WORDSIZE 64
+#else
+# define __WORDSIZE 32
+# define __WORDSIZE32_SIZE_ULONG 1
+# define __WORDSIZE32_PTRDIFF_LONG 0
+#endif
+
+#define __WORDSIZE_TIME64_COMPAT32 0
diff --git a/REORG.TODO/sysdeps/s390/s390-32/bsd-_setjmp.S b/REORG.TODO/sysdeps/s390/s390-32/bsd-_setjmp.S
new file mode 100644
index 0000000000..1417270201
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/s390-32/bsd-_setjmp.S
@@ -0,0 +1 @@
+/* We don't need any code here since the setjmp.S file contains it. */
diff --git a/REORG.TODO/sysdeps/s390/s390-32/bsd-setjmp.S b/REORG.TODO/sysdeps/s390/s390-32/bsd-setjmp.S
new file mode 100644
index 0000000000..1417270201
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/s390-32/bsd-setjmp.S
@@ -0,0 +1 @@
+/* We don't need any code here since the setjmp.S file contains it. */
diff --git a/REORG.TODO/sysdeps/s390/s390-32/bzero.S b/REORG.TODO/sysdeps/s390/s390-32/bzero.S
new file mode 100644
index 0000000000..b6f85e681f
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/s390-32/bzero.S
@@ -0,0 +1,42 @@
+/* bzero -- set a block of memory to zero. IBM S390 version
+ This file is part of the GNU C Library.
+ Copyright (C) 2000-2017 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
+ 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/>. */
+
+/*
+ * R2 = address to memory area
+ * R3 = number of bytes to fill
+ */
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+
+ .text
+ENTRY(__bzero)
+ ltr %r3,%r3
+ jz .L1
+ sr %r1,%r1 # set pad byte to zero
+ sr %r4,%r4 # no source for MVCLE, only a pad byte
+ sr %r5,%r5
+.L0: mvcle %r2,%r4,0(%r1) # thats it, MVCLE is your friend
+ jo .L0
+.L1: br %r14
+END(__bzero)
+
+#ifndef NO_WEAK_ALIAS
+weak_alias (__bzero, bzero)
+#endif
diff --git a/REORG.TODO/sysdeps/s390/s390-32/crti.S b/REORG.TODO/sysdeps/s390/s390-32/crti.S
new file mode 100644
index 0000000000..54bd4590c0
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/s390-32/crti.S
@@ -0,0 +1,102 @@
+/* Special .init and .fini section support for S/390.
+ Copyright (C) 2000-2017 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.
+
+ In addition to the permissions in the GNU Lesser General Public
+ License, the Free Software Foundation gives you unlimited
+ permission to link the compiled version of this file with other
+ programs, and to distribute those programs without any restriction
+ coming from the use of this file. (The GNU Lesser General Public
+ License restrictions do apply in other respects; for example, they
+ cover modification of the file, and distribution when not linked
+ into another program.)
+
+ Note that people who make modified versions of this file are not
+ obligated to grant this special exception for their modified
+ versions; it is their choice whether to do so. The GNU Lesser
+ General Public License gives permission to release a modified
+ version without this exception; this exception also makes it
+ possible to release a modified version which carries forward this
+ exception.
+
+ 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/>. */
+
+/* crti.S puts a function prologue at the beginning of the .init and
+ .fini sections and defines global symbols for those addresses, so
+ they can be called as functions. The symbols _init and _fini are
+ magic and cause the linker to emit DT_INIT and DT_FINI. */
+
+#include <libc-symbols.h>
+#include <sysdep.h>
+
+#ifndef PREINIT_FUNCTION
+# define PREINIT_FUNCTION __gmon_start__
+#endif
+
+#ifndef PREINIT_FUNCTION_WEAK
+# define PREINIT_FUNCTION_WEAK 1
+#endif
+
+#if PREINIT_FUNCTION_WEAK
+ weak_extern (PREINIT_FUNCTION)
+#else
+ .hidden PREINIT_FUNCTION
+#endif
+
+ .section .init,"ax",@progbits
+ .globl _init
+ .type _init,@function
+ .align 4
+_init:
+ stm %r6,%r15,24(%r15)
+ bras %r13,1f
+0:
+#if PREINIT_FUNCTION_WEAK
+ .long PREINIT_FUNCTION@GOT
+#else
+ .long PREINIT_FUNCTION-0b
+#endif
+ .long _GLOBAL_OFFSET_TABLE_-0b
+1: lr %r1,%r15
+ ahi %r15,-96
+ st %r1,0(%r15)
+ l %r12,4(%r13)
+ ar %r12,%r13
+ l %r1,0(%r13)
+#if PREINIT_FUNCTION_WEAK
+ l %r1,0(%r1,%r12)
+ ltr %r1,%r1
+ je 2f
+#else
+ la %r1,0(%r1,%r13)
+#endif
+ basr %r14,%r1
+ .align 4,0x07
+2:
+
+ .section .fini,"ax",@progbits
+ .globl _fini
+ .type _fini,@function
+ .align 4
+_fini:
+ stm %r6,%r15,24(%r15)
+ bras %r13,1f
+0: .long _GLOBAL_OFFSET_TABLE_-0b
+1: lr %r1,%r15
+ ahi %r15,-96
+ st %r1,0(%r15)
+ l %r12,0(%r13)
+ ar %r12,%r13
+ .align 4,0x07
diff --git a/REORG.TODO/sysdeps/s390/s390-32/crtn.S b/REORG.TODO/sysdeps/s390/s390-32/crtn.S
new file mode 100644
index 0000000000..3f5d85e2b2
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/s390-32/crtn.S
@@ -0,0 +1,47 @@
+/* Special .init and .fini section support for S/390.
+ Copyright (C) 2000-2017 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.
+
+ In addition to the permissions in the GNU Lesser General Public
+ License, the Free Software Foundation gives you unlimited
+ permission to link the compiled version of this file with other
+ programs, and to distribute those programs without any restriction
+ coming from the use of this file. (The GNU Lesser General Public
+ License restrictions do apply in other respects; for example, they
+ cover modification of the file, and distribution when not linked
+ into another program.)
+
+ Note that people who make modified versions of this file are not
+ obligated to grant this special exception for their modified
+ versions; it is their choice whether to do so. The GNU Lesser
+ General Public License gives permission to release a modified
+ version without this exception; this exception also makes it
+ possible to release a modified version which carries forward this
+ exception.
+
+ 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/>. */
+
+/* crtn.S puts function epilogues in the .init and .fini sections
+ corresponding to the prologues in crti.S. */
+
+ .section .init,"ax",@progbits
+ l %r4,152(%r15)
+ lm %r6,%r15,120(%r15)
+ br %r4
+
+ .section .fini,"ax",@progbits
+ l %r4,152(%r15)
+ lm %r6,%r15,120(%r15)
+ br %r4
diff --git a/REORG.TODO/sysdeps/s390/s390-32/dl-machine.h b/REORG.TODO/sysdeps/s390/s390-32/dl-machine.h
new file mode 100644
index 0000000000..2e3c77c58e
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/s390-32/dl-machine.h
@@ -0,0 +1,522 @@
+/* Machine-dependent ELF dynamic relocation inline functions. S390 Version.
+ Copyright (C) 2000-2017 Free Software Foundation, Inc.
+ Contributed by Carl Pederson & Martin Schwidefsky.
+ 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 dl_machine_h
+#define dl_machine_h
+
+#define ELF_MACHINE_NAME "s390"
+
+#include <sys/param.h>
+#include <string.h>
+#include <link.h>
+#include <sysdeps/s390/dl-procinfo.h>
+#include <dl-irel.h>
+
+/* This is an older, now obsolete value. */
+#define EM_S390_OLD 0xA390
+
+/* Return nonzero iff ELF header is compatible with the running host. */
+static inline int
+elf_machine_matches_host (const Elf32_Ehdr *ehdr)
+{
+ /* Check if the kernel provides the high gpr facility if needed by
+ the binary. */
+ if ((ehdr->e_flags & EF_S390_HIGH_GPRS)
+ && !(GLRO (dl_hwcap) & HWCAP_S390_HIGH_GPRS))
+ return 0;
+
+ return (ehdr->e_machine == EM_S390 || ehdr->e_machine == EM_S390_OLD)
+ && ehdr->e_ident[EI_CLASS] == ELFCLASS32;
+}
+
+
+/* Return the link-time address of _DYNAMIC. Conveniently, this is the
+ first element of the GOT. This must be inlined in a function which
+ uses global data. */
+
+static inline Elf32_Addr
+elf_machine_dynamic (void)
+{
+ register Elf32_Addr *got;
+
+ __asm__( " bras %0,2f\n"
+ "1: .long _GLOBAL_OFFSET_TABLE_-1b\n"
+ "2: al %0,0(%0)"
+ : "=&a" (got) : : "0" );
+
+ return *got;
+}
+
+
+/* Return the run-time load address of the shared object. */
+static inline Elf32_Addr
+elf_machine_load_address (void)
+{
+ Elf32_Addr addr;
+
+ __asm__( " bras 1,2f\n"
+ "1: .long _GLOBAL_OFFSET_TABLE_ - 1b\n"
+ " .long (_dl_start - 1b - 0x80000000) & 0x00000000ffffffff\n"
+ "2: l %0,4(1)\n"
+ " ar %0,1\n"
+ " al 1,0(1)\n"
+ " sl %0,_dl_start@GOT(1)"
+ : "=&d" (addr) : : "1" );
+ return addr;
+}
+
+/* Set up the loaded object described by L so its unrelocated PLT
+ entries will jump to the on-demand fixup code in dl-runtime.c. */
+
+static inline int __attribute__ ((unused))
+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)
+ {
+ /* The GOT entries for functions in the PLT have not yet been filled
+ in. Their initial contents will arrange when called to push an
+ offset into the .rel.plt section, push _GLOBAL_OFFSET_TABLE_[1],
+ and then jump to _GLOBAL_OFFSET_TABLE[2]. */
+ Elf32_Addr *got;
+ got = (Elf32_Addr *) D_PTR (l, l_info[DT_PLTGOT]);
+ /* If a library is prelinked but we have to relocate anyway,
+ we have to be able to undo the prelinking of .got.plt.
+ The prelinker saved us here address of .plt + 0x2c. */
+ if (got[1])
+ {
+ l->l_mach.plt = got[1] + l->l_addr;
+ l->l_mach.jmprel = (const Elf32_Rela *) D_PTR (l, l_info[DT_JMPREL]);
+ }
+ got[1] = (Elf32_Addr) l; /* Identify this shared object. */
+
+ /* The got[2] entry contains the address of a function which gets
+ called to get the address of a so far unresolved function and
+ jump to it. The profiling extension of the dynamic linker allows
+ to intercept the calls to collect information. In this case we
+ don't store the address in the GOT so that all future calls also
+ 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))
+ /* This is the object we are looking for. Say that we really
+ want profiling and the timers are started. */
+ 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. */
+#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;
+}
+
+/* Mask identifying addresses reserved for the user program,
+ where the dynamic linker should not map anything. */
+#define ELF_MACHINE_USER_ADDRESS_MASK 0xf8000000UL
+
+/* Initial entry point code for the dynamic linker.
+ The C function `_dl_start' is the real entry point;
+ its return value is the user program's entry point. */
+
+#define RTLD_START __asm__ ("\n\
+.text\n\
+.align 4\n\
+.globl _start\n\
+.globl _dl_start_user\n\
+_start:\n\
+ basr %r13,0\n\
+0: ahi %r13,.Llit-0b\n\
+ lr %r2,%r15\n\
+ # Alloc stack frame\n\
+ ahi %r15,-96\n\
+ # Set the back chain to zero\n\
+ xc 0(4,%r15),0(%r15)\n\
+ # Call _dl_start with %r2 pointing to arg on stack\n\
+ l %r14,.Ladr1-.Llit(%r13)\n\
+ bas %r14,0(%r14,%r13) # call _dl_start\n\
+_dl_start_user:\n\
+ # Save the user entry point address in %r8.\n\
+ lr %r8,%r2\n\
+ # Point %r12 at the GOT.\n\
+ l %r12,.Ladr0-.Llit(%r13)\n\
+ ar %r12,%r13\n\
+ # See if we were run as a command with the executable file\n\
+ # name as an extra leading argument.\n\
+ l %r1,_dl_skip_args@GOT(%r12)\n\
+ l %r1,0(%r1) # load _dl_skip_args\n\
+ ltr %r1,%r1\n\
+ je 4f # Skip the arg adjustment if there were none.\n\
+ # Get the original argument count.\n\
+ l %r0,96(%r15)\n\
+ # Subtract _dl_skip_args from it.\n\
+ sr %r0,%r1\n\
+ # Store back the modified argument count.\n\
+ st %r0,96(%r15)\n\
+ # Copy argv and envp forward to account for skipped argv entries.\n\
+ # We skipped at least one argument or we would not get here.\n\
+ la %r6,100(%r15) # Destination pointer i.e. &argv[0]\n\
+ lr %r5,%r6\n\
+ lr %r0,%r1\n\
+ sll %r0,2\n # Number of skipped bytes.\n\
+ ar %r5,%r0 # Source pointer = Dest + Skipped args.\n\
+ # argv copy loop:\n\
+1: l %r7,0(%r5) # Load a word from the source.\n\
+ st %r7,0(%r6) # Store the word in the destination.\n\
+ ahi %r5,4\n\
+ ahi %r6,4\n\
+ ltr %r7,%r7\n\
+ jne 1b # Stop after copying the NULL.\n\
+ # envp copy loop:\n\
+2: l %r7,0(%r5) # Load a word from the source.\n\
+ st %r7,0(%r6) # Store the word in the destination.\n\
+ ahi %r5,4\n\
+ ahi %r6,4\n\
+ ltr %r7,%r7\n\
+ jne 2b # Stop after copying the NULL.\n\
+ # Now we have to zero out the envp entries after NULL to allow\n\
+ # start.S to properly find auxv by skipping zeroes.\n\
+ # zero out loop:\n\
+ lhi %r7,0\n\
+3: st %r7,0(%r6) # Store zero.\n\
+ ahi %r6,4 # Advance dest pointer.\n\
+ ahi %r1,-1 # Subtract one from the word count.\n\
+ ltr %r1,%r1\n\
+ jne 3b # Keep copying if the word count is non-zero.\n\
+ # Adjust _dl_argv\n\
+ la %r6,100(%r15)\n\
+ l %r1,_dl_argv@GOT(%r12)\n\
+ st %r6,0(%r1)\n\
+ # The special initializer gets called with the stack just\n\
+ # as the application's entry point will see it; it can\n\
+ # switch stacks if it moves these contents over.\n\
+" RTLD_START_SPECIAL_INIT "\n\
+ # Call the function to run the initializers.\n\
+ # Load the parameters:\n\
+ # (%r2, %r3, %r4, %r5) = (_dl_loaded, argc, argv, envp)\n\
+4: l %r2,_rtld_local@GOT(%r12)\n\
+ l %r2,0(%r2)\n\
+ l %r3,96(%r15)\n\
+ la %r4,100(%r15)\n\
+ lr %r5,%r3\n\
+ sll %r5,2\n\
+ la %r5,104(%r5,%r15)\n\
+ l %r1,.Ladr4-.Llit(%r13)\n\
+ bas %r14,0(%r1,%r13)\n\
+ # Pass our finalizer function to the user in %r14, as per ELF ABI.\n\
+ l %r14,_dl_fini@GOT(%r12)\n\
+ # Free stack frame\n\
+ ahi %r15,96\n\
+ # Jump to the user's entry point (saved in %r8).\n\
+ br %r8\n\
+.Llit:\n\
+.Ladr0: .long _GLOBAL_OFFSET_TABLE_-.Llit\n\
+.Ladr1: .long _dl_start-.Llit\n\
+.Ladr4: .long _dl_init@PLT-.Llit\n\
+");
+
+#ifndef RTLD_START_SPECIAL_INIT
+#define RTLD_START_SPECIAL_INIT /* nothing */
+#endif
+
+/* ELF_RTYPE_CLASS_PLT iff TYPE describes relocation of a PLT entry or
+ TLS variable, so undefined references should not be allowed to
+ define the value.
+ ELF_RTYPE_CLASS_COPY iff TYPE should not be allowed to resolve to one
+ of the main executable's symbols, as for a COPY reloc. */
+#define elf_machine_type_class(type) \
+ ((((type) == R_390_JMP_SLOT || (type) == R_390_TLS_DTPMOD \
+ || (type) == R_390_TLS_DTPOFF || (type) == R_390_TLS_TPOFF) \
+ * ELF_RTYPE_CLASS_PLT) \
+ | (((type) == R_390_COPY) * ELF_RTYPE_CLASS_COPY))
+
+/* A reloc type used for ld.so cmdline arg lookups to reject PLT entries. */
+#define ELF_MACHINE_JMP_SLOT R_390_JMP_SLOT
+
+/* The S390 never uses Elf32_Rel relocations. */
+#define ELF_MACHINE_NO_REL 1
+#define ELF_MACHINE_NO_RELA 0
+
+/* We define an initialization functions. This is called very early in
+ _dl_sysdep_start. */
+#define DL_PLATFORM_INIT dl_platform_init ()
+
+static inline void __attribute__ ((unused))
+dl_platform_init (void)
+{
+ if (GLRO(dl_platform) != NULL && *GLRO(dl_platform) == '\0')
+ /* Avoid an empty string which would disturb us. */
+ GLRO(dl_platform) = NULL;
+}
+
+static inline Elf32_Addr
+elf_machine_fixup_plt (struct link_map *map, lookup_t t,
+ const Elf32_Rela *reloc,
+ Elf32_Addr *reloc_addr, Elf32_Addr value)
+{
+ return *reloc_addr = value;
+}
+
+/* Return the final value of a plt relocation. */
+static inline Elf32_Addr
+elf_machine_plt_value (struct link_map *map, const Elf32_Rela *reloc,
+ Elf32_Addr value)
+{
+ return value;
+}
+
+/* Names of the architecture-specific auditing callback functions. */
+#define ARCH_LA_PLTENTER s390_32_gnu_pltenter
+#define ARCH_LA_PLTEXIT s390_32_gnu_pltexit
+
+#endif /* !dl_machine_h */
+
+
+#ifdef RESOLVE_MAP
+
+/* Perform the relocation specified by RELOC and SYM (which is fully resolved).
+ MAP is the object containing the reloc. */
+
+auto inline void
+__attribute__ ((always_inline))
+elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc,
+ const Elf32_Sym *sym, const struct r_found_version *version,
+ void *const reloc_addr_arg, int skip_ifunc)
+{
+ Elf32_Addr *const reloc_addr = reloc_addr_arg;
+ const unsigned int r_type = ELF32_R_TYPE (reloc->r_info);
+
+#if !defined RTLD_BOOTSTRAP || !defined HAVE_Z_COMBRELOC
+ if (__glibc_unlikely (r_type == R_390_RELATIVE))
+ {
+# if !defined RTLD_BOOTSTRAP && !defined HAVE_Z_COMBRELOC
+ /* This is defined in rtld.c, but nowhere in the static libc.a;
+ make the reference weak so static programs can still link.
+ This declaration cannot be done when compiling rtld.c
+ (i.e. #ifdef RTLD_BOOTSTRAP) because rtld.c contains the
+ common defn for _dl_rtld_map, which is incompatible with a
+ weak decl in the same file. */
+# ifndef SHARED
+ weak_extern (GL(dl_rtld_map));
+# endif
+ if (map != &GL(dl_rtld_map)) /* Already done in rtld itself. */
+# endif
+ *reloc_addr = map->l_addr + reloc->r_addend;
+ }
+ else
+#endif
+ if (__glibc_unlikely (r_type == R_390_NONE))
+ return;
+ else
+ {
+#if !defined RTLD_BOOTSTRAP && !defined RESOLVE_CONFLICT_FIND_MAP
+ /* Only needed for R_390_COPY below. */
+ 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;
+
+ if (sym != NULL
+ && __builtin_expect (ELFW(ST_TYPE) (sym->st_info) == STT_GNU_IFUNC, 0)
+ && __builtin_expect (sym->st_shndx != SHN_UNDEF, 1)
+ && __builtin_expect (!skip_ifunc, 1))
+ value = elf_ifunc_invoke (value);
+
+ switch (r_type)
+ {
+ case R_390_IRELATIVE:
+ value = map->l_addr + reloc->r_addend;
+ if (__glibc_likely (!skip_ifunc))
+ value = elf_ifunc_invoke (value);
+ *reloc_addr = value;
+ break;
+
+ case R_390_GLOB_DAT:
+ case R_390_JMP_SLOT:
+ *reloc_addr = value + reloc->r_addend;
+ break;
+
+#ifndef RESOLVE_CONFLICT_FIND_MAP
+ case R_390_TLS_DTPMOD:
+# ifdef RTLD_BOOTSTRAP
+ /* During startup the dynamic linker is always the module
+ with index 1.
+ XXX If this relocation is necessary move before RESOLVE
+ call. */
+ *reloc_addr = 1;
+# else
+ /* Get the information from the link map returned by the
+ resolv function. */
+ if (sym_map != NULL)
+ *reloc_addr = sym_map->l_tls_modid;
+# endif
+ break;
+ case R_390_TLS_DTPOFF:
+# ifndef RTLD_BOOTSTRAP
+ /* During relocation all TLS symbols are defined and used.
+ Therefore the offset is already correct. */
+ if (sym != NULL)
+ *reloc_addr = sym->st_value + reloc->r_addend;
+# endif
+ break;
+ case R_390_TLS_TPOFF:
+ /* The offset is negative, forward from the thread pointer. */
+# ifdef RTLD_BOOTSTRAP
+ *reloc_addr = sym->st_value + reloc->r_addend - map->l_tls_offset;
+# else
+ /* We know the offset of the object the symbol is contained in.
+ It is a negative value which will be added to the
+ thread pointer. */
+ if (sym != NULL)
+ {
+ CHECK_STATIC_TLS (map, sym_map);
+ *reloc_addr = (sym->st_value + reloc->r_addend
+ - sym_map->l_tls_offset);
+ }
+#endif
+ break;
+#endif /* use TLS */
+
+#ifndef RTLD_BOOTSTRAP
+# ifndef RESOLVE_CONFLICT_FIND_MAP
+ /* Not needed in dl-conflict.c. */
+ case R_390_COPY:
+ if (sym == NULL)
+ /* This can happen in trace mode if an object could not be
+ found. */
+ break;
+ if (__builtin_expect (sym->st_size > refsym->st_size, 0)
+ || (__builtin_expect (sym->st_size < refsym->st_size, 0)
+ && __builtin_expect (GLRO(dl_verbose), 0)))
+ {
+ const char *strtab;
+
+ strtab = (const char *) D_PTR(map,l_info[DT_STRTAB]);
+ _dl_error_printf ("\
+%s: Symbol `%s' has different size in shared object, consider re-linking\n",
+ RTLD_PROGNAME, strtab + refsym->st_name);
+ }
+ memcpy (reloc_addr_arg, (void *) value,
+ MIN (sym->st_size, refsym->st_size));
+ break;
+# endif
+ case R_390_32:
+ *reloc_addr = value + reloc->r_addend;
+ break;
+ case R_390_16:
+ *(unsigned short *) reloc_addr = value + reloc->r_addend;
+ break;
+ case R_390_8:
+ *(char *) reloc_addr = value + reloc->r_addend;
+ break;
+# ifndef RESOLVE_CONFLICT_FIND_MAP
+ case R_390_PC32:
+ *reloc_addr = value + reloc->r_addend - (Elf32_Addr) reloc_addr;
+ break;
+ case R_390_PC16DBL:
+ *(unsigned short *) reloc_addr = (unsigned short)
+ ((short) (value + reloc->r_addend - (Elf32_Addr) reloc_addr) >> 1);
+ break;
+ case R_390_PC32DBL:
+ *(unsigned int *) reloc_addr = (unsigned int)
+ ((int) (value + reloc->r_addend - (Elf32_Addr) reloc_addr) >> 1);
+ break;
+ case R_390_PC16:
+ *(unsigned short *) reloc_addr =
+ value + reloc->r_addend - (Elf32_Addr) reloc_addr;
+ break;
+ case R_390_NONE:
+ break;
+# endif
+#endif
+#if !defined(RTLD_BOOTSTRAP) || defined(_NDEBUG)
+ default:
+ /* We add these checks in the version to relocate ld.so only
+ if we are still debugging. */
+ _dl_reloc_bad_type (map, r_type, 0);
+ break;
+#endif
+ }
+ }
+}
+
+auto inline void
+__attribute__ ((always_inline))
+elf_machine_rela_relative (Elf32_Addr l_addr, const Elf32_Rela *reloc,
+ void *const reloc_addr_arg)
+{
+ Elf32_Addr *const reloc_addr = reloc_addr_arg;
+ *reloc_addr = l_addr + reloc->r_addend;
+}
+
+auto inline void
+__attribute__ ((always_inline))
+elf_machine_lazy_rel (struct link_map *map,
+ Elf32_Addr l_addr, const Elf32_Rela *reloc,
+ int skip_ifunc)
+{
+ Elf32_Addr *const reloc_addr = (void *) (l_addr + reloc->r_offset);
+ const unsigned int r_type = ELF32_R_TYPE (reloc->r_info);
+ /* Check for unexpected PLT reloc type. */
+ if (__glibc_likely (r_type == R_390_JMP_SLOT))
+ {
+ if (__builtin_expect (map->l_mach.plt, 0) == 0)
+ *reloc_addr += l_addr;
+ else
+ *reloc_addr = map->l_mach.plt + (reloc - map->l_mach.jmprel) * 32;
+ }
+ else if (__glibc_likely (r_type == R_390_IRELATIVE))
+ {
+ Elf32_Addr value = map->l_addr + reloc->r_addend;
+ if (__glibc_likely (!skip_ifunc))
+ value = elf_ifunc_invoke (value);
+ *reloc_addr = value;
+ }
+ else
+ _dl_reloc_bad_type (map, r_type, 1);
+}
+
+#endif /* RESOLVE_MAP */
diff --git a/REORG.TODO/sysdeps/s390/s390-32/dl-sysdep.h b/REORG.TODO/sysdeps/s390/s390-32/dl-sysdep.h
new file mode 100644
index 0000000000..f32114bf56
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/s390-32/dl-sysdep.h
@@ -0,0 +1,23 @@
+/* System-specific settings for dynamic linker code. S/390 version.
+ Copyright (C) 2014-2017 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_next <dl-sysdep.h>
+
+/* _dl_argv cannot be attribute_relro, because _dl_start_user
+ might write into it after _dl_start returns. */
+#define DL_ARGV_NOT_RELRO 1
diff --git a/REORG.TODO/sysdeps/s390/s390-32/dl-trampoline.S b/REORG.TODO/sysdeps/s390/s390-32/dl-trampoline.S
new file mode 100644
index 0000000000..34377e7c51
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/s390-32/dl-trampoline.S
@@ -0,0 +1,33 @@
+/* PLT trampolines. s390 version.
+ Copyright (C) 2005-2017 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 <sysdep.h>
+
+ .text
+/* 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/REORG.TODO/sysdeps/s390/s390-32/dl-trampoline.h b/REORG.TODO/sysdeps/s390/s390-32/dl-trampoline.h
new file mode 100644
index 0000000000..19776eec8a
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/s390-32/dl-trampoline.h
@@ -0,0 +1,231 @@
+/* PLT trampolines. s390 version.
+ Copyright (C) 2016-2017 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)
+ std %f0,56(%r15)
+ cfi_offset (f0, -40)
+ std %f2,64(%r15)
+ cfi_offset (f2, -32)
+ st %r14,8(%r15)
+ cfi_offset (r14, -88)
+ 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
+ ahi %r15,224 # remove stack frame
+ cfi_adjust_cfa_offset (-224)
+#else
+ ahi %r15,96 # remove stack frame
+ cfi_adjust_cfa_offset (-96)
+#endif
+ l %r14,8(15) # restore registers
+ 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/REORG.TODO/sysdeps/s390/s390-32/memchr.S b/REORG.TODO/sysdeps/s390/s390-32/memchr.S
new file mode 100644
index 0000000000..4ffac6061c
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/s390-32/memchr.S
@@ -0,0 +1,41 @@
+/* Search a character in a block of memory. For IBM S390
+ Copyright (C) 2000-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com).
+
+ 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/>. */
+
+/*
+ * R2 = address to memory area
+ * R3 = character to find
+ * R4 = number of bytes to search
+ */
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+
+ .text
+ENTRY(memchr)
+ lhi %r0,0xff
+ nr %r0,%r3
+ lr %r1,%r2
+ la %r2,0(%r4,%r1)
+0: srst %r2,%r1
+ jo 0b
+ brc 13,1f
+ slr %r2,%r2
+1: br %r14
+END(memchr)
+libc_hidden_builtin_def (memchr)
diff --git a/REORG.TODO/sysdeps/s390/s390-32/memcmp.S b/REORG.TODO/sysdeps/s390/s390-32/memcmp.S
new file mode 100644
index 0000000000..ca02144a4a
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/s390-32/memcmp.S
@@ -0,0 +1,66 @@
+/* memcmp - compare two memory blocks. 32 bit S/390 version.
+ Copyright (C) 2012-2017 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 "sysdep.h"
+#include "asm-syntax.h"
+
+/* INPUT PARAMETERS
+ %r2 = address of first memory area
+ %r3 = address of second memory area
+ %r4 = number of bytes to compare. */
+
+ .text
+#ifdef USE_MULTIARCH
+ENTRY(__memcmp_default)
+#else
+ENTRY(memcmp)
+#endif
+ .machine "g5"
+ basr %r5,0
+.L_G5_16:
+ ltr %r4,%r4
+ je .L_G5_4
+ ahi %r4,-1
+ lr %r1,%r4
+ srl %r1,8
+ ltr %r1,%r1
+ jne .L_G5_12
+ ex %r4,.L_G5_17-.L_G5_16(%r5)
+.L_G5_4:
+ ipm %r2
+ sll %r2,2
+ sra %r2,30
+ br %r14
+.L_G5_12:
+ clc 0(256,%r3),0(%r2)
+ jne .L_G5_4
+ la %r3,256(%r3)
+ la %r2,256(%r2)
+ brct %r1,.L_G5_12
+ ex %r4,.L_G5_17-.L_G5_16(%r5)
+ j .L_G5_4
+.L_G5_17:
+ clc 0(1,%r3),0(%r2)
+#ifdef USE_MULTIARCH
+END(__memcmp_default)
+#else
+END(memcmp)
+libc_hidden_builtin_def (memcmp)
+weak_alias(memcmp, bcmp)
+#endif
diff --git a/REORG.TODO/sysdeps/s390/s390-32/memcpy.S b/REORG.TODO/sysdeps/s390/s390-32/memcpy.S
new file mode 100644
index 0000000000..0177f19431
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/s390-32/memcpy.S
@@ -0,0 +1,89 @@
+/* memcpy - copy a block from source to destination. S/390 version.
+ Copyright (C) 2012-2017 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 "sysdep.h"
+#include "asm-syntax.h"
+
+/* INPUT PARAMETERS
+ %r2 = address of destination memory area
+ %r3 = address of source memory area
+ %r4 = number of bytes to copy. */
+
+ .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"
+ lr %r1,%r2 # r1: Use as dest ; r2: Return dest
+.L_G5_start:
+ ltr %r4,%r4
+ je .L_G5_99
+ ahi %r4,-1
+ lr %r5,%r4
+ srl %r5,8
+ ltr %r5,%r5
+ jne .L_G5_13
+.L_G5_4:
+ 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
+ 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
+ j .L_G5_4
+.L_G5_17:
+ mvc 0(1,%r1),0(%r3)
+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.
+ 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,%r0 # return destination address
+ br %r14
+END(__memcpy_mvcle)
diff --git a/REORG.TODO/sysdeps/s390/s390-32/memset.S b/REORG.TODO/sysdeps/s390/s390-32/memset.S
new file mode 100644
index 0000000000..720f393c30
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/s390-32/memset.S
@@ -0,0 +1,65 @@
+/* Set a block of memory to some byte value. For IBM S390
+ Copyright (C) 2012-2017 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 "sysdep.h"
+#include "asm-syntax.h"
+
+/* INPUT PARAMETERS
+ %r2 = address to memory area
+ %r3 = byte to fill memory with
+ %r4 = number of bytes to fill. */
+
+ .text
+
+#ifdef USE_MULTIARCH
+ENTRY(__memset_default)
+#else
+ENTRY(memset)
+#endif
+ .machine "g5"
+ basr %r5,0
+.L_G5_19:
+ ltr %r4,%r4
+ je .L_G5_4
+ stc %r3,0(%r2)
+ chi %r4,1
+ lr %r1,%r2
+ je .L_G5_4
+ ahi %r4,-2
+ lr %r3,%r4
+ srl %r3,8
+ ltr %r3,%r3
+ jne .L_G5_14
+ ex %r4,.L_G5_20-.L_G5_19(%r5)
+.L_G5_4:
+ br %r14
+.L_G5_14:
+ mvc 1(256,%r1),0(%r1)
+ la %r1,256(%r1)
+ brct %r3,.L_G5_14
+ ex %r4,.L_G5_20-.L_G5_19(%r5)
+ j .L_G5_4
+.L_G5_20:
+ mvc 1(1,%r1),0(%r1)
+#ifdef USE_MULTIARCH
+END(__memset_default)
+#else
+END(memset)
+libc_hidden_builtin_def (memset)
+#endif
diff --git a/REORG.TODO/sysdeps/s390/s390-32/mul_1.S b/REORG.TODO/sysdeps/s390/s390-32/mul_1.S
new file mode 100644
index 0000000000..4f08fa2c80
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/s390-32/mul_1.S
@@ -0,0 +1,55 @@
+/* __mpn_mul_1 -- Multiply a limb vector with a limb and store
+ the result in a second limb vector.
+ Copyright (C) 2000-2017 Free Software Foundation, Inc.
+ Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com).
+ This file is part of the GNU MP Library.
+
+ The GNU MP 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 MP 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 MP Library; see the file COPYING.LIB. If not,
+ see <http://www.gnu.org/licenses/>. */
+
+/*
+ INPUT PARAMETERS
+ res_ptr %r2
+ s1_ptr %r3
+ size %r4
+ s2_limb %r5
+*/
+
+#include <sysdep.h>
+#include "asm-syntax.h"
+
+ .text
+ENTRY(__mpn_mul_1)
+ st %r6,24(%r15)
+ cfi_offset (%r6, -72)
+ slr %r6,%r6 # cy_limb = 0
+.L0: icm %r1,15,0(%r3) # get s1_ptr[i]
+ mr %r0,%r5 # umul_ppmm(prod_high,prod_low,s1_ptr[j],s2_limb)
+ jnm .L1
+ alr %r0,%r5
+.L1: ltr %r5,%r5
+ jnm .L2
+ al %r0,0(%r3)
+.L2: alr %r1,%r6 # prod_low += cy_limb
+ lr %r6,%r0 # cy_limb = prod_high
+ brc 12,.L3
+ ahi %r6,1 # + (prod_low < cy_limb)
+.L3: st %r1,0(%r2)
+ la %r2,4(0,%r2)
+ la %r3,4(0,%r3)
+ brct %r4,.L0
+ lr %r2,%r6 # return cy_limb
+ l %r6,24(%r15)
+.Lexit: br %r14
+END(__mpn_mul_1)
diff --git a/REORG.TODO/sysdeps/s390/s390-32/multiarch/Makefile b/REORG.TODO/sysdeps/s390/s390-32/multiarch/Makefile
new file mode 100644
index 0000000000..f8aee14bbd
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/s390-32/multiarch/Makefile
@@ -0,0 +1,4 @@
+ifeq ($(subdir),string)
+sysdep_routines += memset memset-s390 memcpy memcpy-s390 \
+ memcmp memcmp-s390
+endif
diff --git a/REORG.TODO/sysdeps/s390/s390-32/multiarch/memchr.c b/REORG.TODO/sysdeps/s390/s390-32/multiarch/memchr.c
new file mode 100644
index 0000000000..808c3b837a
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/s390-32/multiarch/memchr.c
@@ -0,0 +1,21 @@
+/* Multiple versions of memchr.
+ Copyright (C) 2015-2017 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 wrapper-file is needed, because otherwise file
+ sysdeps/s390/s390-[32|64]/memchr.S will be used. */
+#include <sysdeps/s390/multiarch/memchr.c>
diff --git a/REORG.TODO/sysdeps/s390/s390-32/multiarch/memcmp-s390.S b/REORG.TODO/sysdeps/s390/s390-32/multiarch/memcmp-s390.S
new file mode 100644
index 0000000000..86a76b4c98
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/s390-32/multiarch/memcmp-s390.S
@@ -0,0 +1,107 @@
+/* CPU specific memcmp implementations. 32 bit S/390 version.
+ Copyright (C) 2012-2017 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 "sysdep.h"
+#include "asm-syntax.h"
+
+/* INPUT PARAMETERS
+ %r2 = address of first memory area
+ %r3 = address of second memory area
+ %r4 = number of bytes to compare. */
+
+ .text
+
+#if IS_IN (libc)
+
+ENTRY(__memcmp_z196)
+ .machine "z196"
+ .machinemode "zarch_nohighgprs"
+ ltr %r4,%r4
+ je .L_Z196_4
+ ahi %r4,-1
+ srlk %r1,%r4,8
+ ltr %r1,%r1
+ jne .L_Z196_2
+.L_Z196_3:
+ exrl %r4,.L_Z196_14
+.L_Z196_4:
+ ipm %r2
+ sll %r2,2
+ sra %r2,30
+ br %r14
+.L_Z196_17:
+ la %r3,256(%r3)
+ la %r2,256(%r2)
+ ahi %r1,-1
+ je .L_Z196_3
+.L_Z196_2:
+ pfd 1,512(%r3)
+ pfd 1,512(%r2)
+ clc 0(256,%r3),0(%r2)
+ je .L_Z196_17
+ ipm %r2
+ sll %r2,2
+ sra %r2,30
+ br %r14
+.L_Z196_14:
+ clc 0(1,%r3),0(%r2)
+END(__memcmp_z196)
+
+ENTRY(__memcmp_z10)
+ .machine "z10"
+ .machinemode "zarch_nohighgprs"
+ ltr %r4,%r4
+ je .L_Z10_4
+ ahi %r4,-1
+ lr %r1,%r4
+ srl %r1,8
+ cijlh %r1,0,.L_Z10_12
+.L_Z10_3:
+ exrl %r4,.L_Z10_15
+.L_Z10_4:
+ ipm %r2
+ sll %r2,2
+ sra %r2,30
+ br %r14
+.L_Z10_12:
+ pfd 1,512(%r3)
+ pfd 1,512(%r2)
+ clc 0(256,%r3),0(%r2)
+ jne .L_Z10_4
+ la %r3,256(%r3)
+ la %r2,256(%r2)
+ brct %r1,.L_Z10_12
+ j .L_Z10_3
+.L_Z10_15:
+ clc 0(1,%r3),0(%r2)
+END(__memcmp_z10)
+
+#endif /* IS_IN (libc) */
+
+#include "../memcmp.S"
+
+#if !IS_IN (libc)
+.globl memcmp
+.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/REORG.TODO/sysdeps/s390/s390-32/multiarch/memcmp.c b/REORG.TODO/sysdeps/s390/s390-32/multiarch/memcmp.c
new file mode 100644
index 0000000000..2d8d8f4d50
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/s390-32/multiarch/memcmp.c
@@ -0,0 +1,27 @@
+/* Multiple versions of memcmp.
+ Copyright (C) 2015-2017 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 IS_IN (libc)
+# define memcmp __redirect_memcmp
+# include <string.h>
+# undef memcmp
+# include <ifunc-resolve.h>
+
+s390_libc_ifunc (__redirect_memcmp, __memcmp, memcmp)
+weak_alias (memcmp, bcmp);
+#endif
diff --git a/REORG.TODO/sysdeps/s390/s390-32/multiarch/memcpy-s390.S b/REORG.TODO/sysdeps/s390/s390-32/multiarch/memcpy-s390.S
new file mode 100644
index 0000000000..bec51af110
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/s390-32/multiarch/memcpy-s390.S
@@ -0,0 +1,128 @@
+/* CPU specific memcpy implementations. 32 bit S/390 version.
+ Copyright (C) 2012-2017 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 "sysdep.h"
+#include "asm-syntax.h"
+
+/* INPUT PARAMETERS
+ %r2 = target operands address
+ %r3 = source operands address
+ %r4 = number of bytes to copy. */
+
+ .text
+
+#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
+ srlg %r5,%r4,8
+ ltgr %r5,%r5
+ jne .L_Z196_5
+.L_Z196_3:
+ exrl %r4,.L_Z196_14
+.L_Z196_4:
+ br %r14
+.L_Z196_5:
+ cgfi %r5,262144 # Switch to mvcle for copies >64MB
+ jh __memcpy_mvcle
+.L_Z196_2:
+ pfd 1,768(%r3)
+ pfd 2,768(%r1)
+ mvc 0(256,%r1),0(%r3)
+ aghi %r5,-1
+ la %r1,256(%r1)
+ la %r3,256(%r3)
+ jne .L_Z196_2
+ j .L_Z196_3
+.L_Z196_14:
+ 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
+ srlg %r5,%r4,8
+ cgijlh %r5,0,.L_Z10_13
+.L_Z10_3:
+ exrl %r4,.L_Z10_15
+.L_Z10_4:
+ br %r14
+.L_Z10_13:
+ cgfi %r5,65535 # Switch to mvcle for copies >16MB
+ jh __memcpy_mvcle
+.L_Z10_12:
+ pfd 1,768(%r3)
+ pfd 2,768(%r1)
+ mvc 0(256,%r1),0(%r3)
+ la %r1,256(%r1)
+ la %r3,256(%r3)
+ brctg %r5,.L_Z10_12
+ j .L_Z10_3
+.L_Z10_15:
+ 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)
+.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/REORG.TODO/sysdeps/s390/s390-32/multiarch/memcpy.c b/REORG.TODO/sysdeps/s390/s390-32/multiarch/memcpy.c
new file mode 100644
index 0000000000..4b8e546fb0
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/s390-32/multiarch/memcpy.c
@@ -0,0 +1,27 @@
+/* Multiple versions of memcpy.
+ Copyright (C) 2015-2017 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/>. */
+
+/* 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 (__redirect_memcpy, __memcpy, memcpy)
+#endif
diff --git a/REORG.TODO/sysdeps/s390/s390-32/multiarch/memset-s390.S b/REORG.TODO/sysdeps/s390/s390-32/multiarch/memset-s390.S
new file mode 100644
index 0000000000..59660b2499
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/s390-32/multiarch/memset-s390.S
@@ -0,0 +1,116 @@
+/* Set a block of memory to some byte value. 32 bit S/390 version.
+ Copyright (C) 2012-2017 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 "sysdep.h"
+#include "asm-syntax.h"
+
+/* INPUT PARAMETERS
+ %r2 = address of memory area
+ %r3 = byte to fill memory with
+ %r4 = number of bytes to fill. */
+
+ .text
+
+#if IS_IN (libc)
+
+ENTRY(__memset_z196)
+ .machine "z196"
+ .machinemode "zarch_nohighgprs"
+ llgfr %r4,%r4
+ ltgr %r4,%r4
+ je .L_Z196_4
+ stc %r3,0(%r2)
+ lr %r1,%r2
+ cghi %r4,1
+ je .L_Z196_4
+ aghi %r4,-2
+ srlg %r5,%r4,8
+ ltgr %r5,%r5
+ jne .L_Z196_1
+.L_Z196_3:
+ exrl %r4,.L_Z196_17
+.L_Z196_4:
+ br %r14
+.L_Z196_1:
+ cgfi %r5,1048576
+ jh __memset_mvcle # Switch to mvcle for >256MB
+.L_Z196_2:
+ pfd 2,1024(%r1)
+ mvc 1(256,%r1),0(%r1)
+ aghi %r5,-1
+ la %r1,256(%r1)
+ jne .L_Z196_2
+ j .L_Z196_3
+.L_Z196_17:
+ mvc 1(1,%r1),0(%r1)
+END(__memset_z196)
+
+ENTRY(__memset_z10)
+ .machine "z10"
+ .machinemode "zarch_nohighgprs"
+ llgfr %r4,%r4
+ cgije %r4,0,.L_Z10_4
+ stc %r3,0(%r2)
+ lr %r1,%r2
+ cgije %r4,1,.L_Z10_4
+ aghi %r4,-2
+ srlg %r5,%r4,8
+ cgijlh %r5,0,.L_Z10_15
+.L_Z10_3:
+ exrl %r4,.L_Z10_18
+.L_Z10_4:
+ br %r14
+.L_Z10_15:
+ cgfi %r5,163840 # Switch to mvcle for >40MB
+ jh __memset_mvcle
+.L_Z10_14:
+ pfd 2,1024(%r1)
+ mvc 1(256,%r1),0(%r1)
+ la %r1,256(%r1)
+ brctg %r5,.L_Z10_14
+ j .L_Z10_3
+.L_Z10_18:
+ mvc 1(1,%r1),0(%r1)
+END(__memset_z10)
+
+ENTRY(__memset_mvcle)
+ ahi %r4,2 # take back the change done by the caller
+ lr %r0,%r2 # save source address
+ lr %r1,%r3 # move pad byte to R1
+ lr %r3,%r4
+ sr %r4,%r4 # no source for MVCLE, only a pad byte
+ sr %r5,%r5
+.L0: mvcle %r2,%r4,0(%r1) # thats it, MVCLE is your friend
+ jo .L0
+ lr %r2,%r0 # return value is source address
+.L1:
+ br %r14
+END(__memset_mvcle)
+
+#endif /* IS_IN (libc) */
+
+#include "../memset.S"
+
+#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/REORG.TODO/sysdeps/s390/s390-32/multiarch/memset.c b/REORG.TODO/sysdeps/s390/s390-32/multiarch/memset.c
new file mode 100644
index 0000000000..421c0854a0
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/s390-32/multiarch/memset.c
@@ -0,0 +1,26 @@
+/* Multiple versions of memset.
+ Copyright (C) 2015-2017 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 IS_IN (libc)
+# define memset __redirect_memset
+# include <string.h>
+# undef memset
+# include <ifunc-resolve.h>
+
+s390_libc_ifunc (__redirect_memset, __memset, memset)
+#endif
diff --git a/REORG.TODO/sysdeps/s390/s390-32/multiarch/strcmp.c b/REORG.TODO/sysdeps/s390/s390-32/multiarch/strcmp.c
new file mode 100644
index 0000000000..6a20a304cc
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/s390-32/multiarch/strcmp.c
@@ -0,0 +1,21 @@
+/* Multiple versions of strcmp.
+ Copyright (C) 2015-2017 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 wrapper-file is needed, because otherwise file
+ sysdeps/s390/s390-[32|64]/strcmp.S will be used. */
+#include <sysdeps/s390/multiarch/strcmp.c>
diff --git a/REORG.TODO/sysdeps/s390/s390-32/multiarch/strcpy.c b/REORG.TODO/sysdeps/s390/s390-32/multiarch/strcpy.c
new file mode 100644
index 0000000000..7f380a471d
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/s390-32/multiarch/strcpy.c
@@ -0,0 +1,21 @@
+/* Multiple versions of strcpy.
+ Copyright (C) 2015-2017 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 wrapper-file is needed, because otherwise file
+ sysdeps/s390/s390-[32|64]/strcpy.S will be used. */
+#include <sysdeps/s390/multiarch/strcpy.c>
diff --git a/REORG.TODO/sysdeps/s390/s390-32/multiarch/strncpy.c b/REORG.TODO/sysdeps/s390/s390-32/multiarch/strncpy.c
new file mode 100644
index 0000000000..15dacec974
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/s390-32/multiarch/strncpy.c
@@ -0,0 +1,21 @@
+/* Multiple versions of strncpy.
+ Copyright (C) 2015-2017 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 wrapper-file is needed, because otherwise file
+ sysdeps/s390/s390-[32|64]/strncpy.S will be used. */
+#include <sysdeps/s390/multiarch/strncpy.c>
diff --git a/REORG.TODO/sysdeps/s390/s390-32/s390-mcount.S b/REORG.TODO/sysdeps/s390/s390-32/s390-mcount.S
new file mode 100644
index 0000000000..fe25c5506d
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/s390-32/s390-mcount.S
@@ -0,0 +1,89 @@
+/* S/390-specific implementation of profiling support.
+ Copyright (C) 2000-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com)
+
+ 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 <sysdep.h>
+
+/*
+ * How profiling works on S/390:
+ * On the start of each function _mcount is called with the address of a
+ * data word in %r1 (initialized to 0, used for counting). The compiler
+ * with the option -p generates code of the form:
+ *
+ * STM 6,15,24(15)
+ * BRAS 13,.LTN0_0
+ * .LT0_0:
+ * .LC12: .long _mcount
+ * .LC13: .long .LP0
+ * .data
+ * .align 4
+ * .LP0: .long 0
+ * .text
+ * # function profiler
+ * st 14,4(15)
+ * l 14,.LC12-.LT0_0(13)
+ * l 1,.LC13-.LT0_0(13)
+ * basr 14,14
+ * l 14,4(15)
+ *
+ * The _mcount implementation now has to call __mcount_internal with the
+ * address of .LP0 as first parameter and the return address as second
+ * parameter. &.LP0 was loaded to %r1 and the return address is in %r14.
+ * _mcount may not modify any register.
+ */
+
+ .globl C_SYMBOL_NAME(_mcount)
+ .type C_SYMBOL_NAME(_mcount), @function
+ cfi_startproc
+ .align ALIGNARG(4)
+C_LABEL(_mcount)
+ /* Save the caller-clobbered registers. */
+ ahi %r15,-128
+ cfi_adjust_cfa_offset (128)
+ stm %r14,%r5,96(%r15)
+ cfi_offset (r14, 0)
+ cfi_offset (r15, 4)
+ l %r2,132(%r15) # callers address = first parameter
+ la %r2,0(%r2) # clear bit 0
+ la %r3,0(%r14) # callees address = second parameter
+
+#ifdef PIC
+ bras %r14,0f
+ .long _GLOBAL_OFFSET_TABLE_-.
+0: al %r14,0(%r14)
+ l %r14,__mcount_internal@GOT(%r14)
+#else
+ bras %r14,0f
+ .long __mcount_internal
+0: l %r14,0(%r14)
+#endif
+ basr %r14,%r14
+
+ /*
+ * Pop the saved registers. Please note that `mcount' has no
+ * return value.
+ */
+ lm %r14,%r5,96(%r15)
+ ahi %r15,128
+ cfi_adjust_cfa_offset (-128)
+ br %r14
+ cfi_endproc
+ ASM_SIZE_DIRECTIVE(C_SYMBOL_NAME(_mcount))
+
+#undef mcount
+weak_alias (_mcount, mcount)
diff --git a/REORG.TODO/sysdeps/s390/s390-32/setjmp.S b/REORG.TODO/sysdeps/s390/s390-32/setjmp.S
new file mode 100644
index 0000000000..1e240dbc83
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/s390-32/setjmp.S
@@ -0,0 +1,123 @@
+/* setjmp for s390, ELF version.
+ Copyright (C) 2000-2017 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/>. */
+
+#include <sysdep.h>
+#define _ASM
+#define _SETJMP_H
+#include <bits/setjmp.h>
+#include <shlib-compat.h>
+#include <stap-probe.h>
+
+#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)
+ lhi %r3,1 /* second argument of one */
+ j .Linternal_sigsetjmp /* branch relativ to __sigsetjmp */
+END (setjmp)
+
+ /* Binary compatibility entry point. */
+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 */
+ j .Linternal_sigsetjmp /* branch relativ to __sigsetjmp */
+END (__setjmp)
+
+ENTRY(__sigsetjmp)
+.Linternal_sigsetjmp:
+ /* setjmp probe expects sig/setjmp first argument (4@%r2), second
+ argument (-4@%r3) and target address (4@%r14). */
+ LIBC_PROBE (setjmp, 3, 4@%r2, -4@%r3, 4@%r14)
+#ifdef PTR_MANGLE
+ stm %r6,%r13,0(%r2) /* store registers in jmp_buf */
+ lr %r4,%r14
+ lr %r5,%r15
+ PTR_MANGLE (%r4, %r1)
+ PTR_MANGLE2 (%r5, %r1)
+ stm %r4,%r5,32(%r2)
+#else
+ stm %r6,%r15,0(%r2) /* store registers in jmp_buf */
+#endif
+ std %f4,40(%r2)
+ std %f6,48(%r2)
+#if IS_IN (rtld)
+ /* In ld.so we never save the signal mask. */
+ lhi %r2,0
+ br %r14
+#elif defined PIC
+ /* We cannot use the PLT, because it requires that %r12 be set, but
+ we can't save and restore our caller's value. Instead, we do an
+ indirect jump through the GOT. */
+ basr %r1,0
+.L0: al %r1,.L1 - .L0(0,%r1) /* get address of global offset table */
+ /* get address of __sigjmp_save from got */
+ l %r1,__sigjmp_save@GOT(%r1)
+ br %r1
+.L1: .long _GLOBAL_OFFSET_TABLE_ - .L0
+#else
+ basr %r1,0
+.L0: l %r1,.L1-.L0(0,%r1) /* load address of __sigjmp_save */
+ br %r1 /* tail-call __sigjmp_save */
+.L1: .long __sigjmp_save
+#endif
+END (__sigsetjmp)
+#if NEED_COMPAT_SYMBOLS
+strong_alias (__sigsetjmp, __GI___sigsetjmp)
+#else
+libc_hidden_def (__sigsetjmp)
+#endif
+
+#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
+
+strong_alias (__v1setjmp, __v2setjmp);
+versioned_symbol (libc, __v1setjmp, setjmp, GLIBC_2_0);
+compat_symbol (libc, __v2setjmp, setjmp, GLIBC_2_19);
+
+strong_alias (__v1_setjmp, __v2_setjmp);
+versioned_symbol (libc, __v1_setjmp, _setjmp, GLIBC_2_0);
+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 /* NEED_COMPAT_SYMBOLS */
diff --git a/REORG.TODO/sysdeps/s390/s390-32/stackguard-macros.h b/REORG.TODO/sysdeps/s390/s390-32/stackguard-macros.h
new file mode 100644
index 0000000000..46109744ed
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/s390-32/stackguard-macros.h
@@ -0,0 +1,15 @@
+#include <stdint.h>
+
+#define STACK_CHK_GUARD \
+ ({ uintptr_t x; __asm__ ("ear %0,%%a0; l %0,0x14(%0)" : "=a" (x)); x; })
+
+/* On s390/s390x there is no unique pointer guard, instead we use the
+ same value as the stack guard. */
+#define POINTER_CHK_GUARD \
+ ({ \
+ uintptr_t x; \
+ __asm__ ("ear %0,%%a0; l %0,%1(%0)" \
+ : "=a" (x) \
+ : "i" (offsetof (tcbhead_t, stack_guard))); \
+ x; \
+ })
diff --git a/REORG.TODO/sysdeps/s390/s390-32/start.S b/REORG.TODO/sysdeps/s390/s390-32/start.S
new file mode 100644
index 0000000000..07400f1752
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/s390-32/start.S
@@ -0,0 +1,211 @@
+/* Startup code compliant to the ELF s390 ABI.
+ Copyright (C) 2000-2017 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.
+
+ In addition to the permissions in the GNU Lesser General Public
+ License, the Free Software Foundation gives you unlimited
+ permission to link the compiled version of this file with other
+ programs, and to distribute those programs without any restriction
+ coming from the use of this file. (The GNU Lesser General Public
+ License restrictions do apply in other respects; for example, they
+ cover modification of the file, and distribution when not linked
+ into another program.)
+
+ Note that people who make modified versions of this file are not
+ obligated to grant this special exception for their modified
+ versions; it is their choice whether to do so. The GNU Lesser
+ General Public License gives permission to release a modified
+ version without this exception; this exception also makes it
+ possible to release a modified version which carries forward this
+ exception.
+
+ 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 is the canonical entry point, usually the first thing in the text
+ segment. Most registers' values are unspecified, except for:
+
+ %r14 Contains a function pointer to be registered with `atexit'.
+ This is how the dynamic linker arranges to have DT_FINI
+ functions called for shared libraries that have been loaded
+ before this code runs.
+
+ %r15 The stack contains the arguments and environment:
+ 0(%r15) argc
+ 4(%r15) argv[0]
+ ...
+ (4*argc)(%r15) NULL
+ (4*(argc+1))(%r15) envp[0]
+ ...
+ NULL
+*/
+
+ .text
+ .globl _start
+ .type _start,@function
+_start:
+ /* Check if the kernel provides highgprs facility if needed by
+ the binary. */
+
+ lr %r6,%r15
+ la %r6,4(%r6) /* Skip the argument counter. */
+
+.L11: l %r5,0(%r6) /* Skip the argument vector. */
+ la %r6,4(%r6)
+ ltr %r5,%r5
+ jne .L11
+
+.L12: l %r5,0(%r6) /* Skip the environment vector. */
+ la %r6,4(%r6)
+ ltr %r5,%r5
+ jne .L12
+
+ /* Usually the auxiliary vector can be expected directly after
+ the environment variables. But we have to skip extra zeros
+ because the loader might have removed unsecure variables for
+ setuid programs. */
+
+.L26: l %r5,0(%r6)
+ la %r6,4(%r6)
+ ltr %r5,%r5
+ jz .L26
+
+ ahi %r6,-4
+
+ /* Obtain the needed values from the auxiliary vector. */
+
+ lhi %r7,16 /* AT_HWCAP */
+ lhi %r8,3 /* AT_PHDR */
+ lhi %r9,5 /* AT_PHNUM */
+ lhi %r2,4 /* AT_PHENT */
+.L13: l %r5,0(%r6)
+ clr %r5,%r7
+ jne .L15
+ l %r10,4(%r6) /* r10 = AT_HWCAP value. */
+.L15: clr %r5,%r8
+ jne .L16
+ l %r11,4(%r6) /* r11 = AT_PHDR value. */
+.L16: clr %r5,%r9
+ jne .L17
+ l %r12,4(%r6) /* r12 = AT_PHNUM value. */
+.L17: clr %r5,%r2
+ jne .L18
+ l %r0,4(%r6) /* r0 = AT_PHENT value. */
+.L18: ltr %r5,%r5
+ la %r6,8(%r6)
+ jnz .L13
+
+ /* Locate the ELF header by looking for the first PT_LOAD
+ segment with a p_offset of zero. */
+
+ lr %r4,%r11 /* Backup AT_PHDR. */
+ lhi %r7,1 /* PT_LOAD id */
+ lhi %r8,0
+.L19: cl %r7,0(%r4) /* p_type == PT_LOAD? */
+ jne .L20
+ cl %r8,4(%r4) /* p_offset == 0? */
+ jne .L20
+ l %r9,8(%r4) /* r9 = PT_LOAD.p_vaddr <- ELF header address */
+ j .L24
+.L20: alr %r4,%r0 /* r4 += AT_PHENT value */
+ brct %r12,.L19
+
+ j .+2 /* Trap, there must be such a phdr. */
+
+.L24: lr %r4,%r11 /* Backup AT_PHDR. */
+ lhi %r2,6 /* PT_PHDR id */
+.L23: cl %r2,0(%r4)
+ jne .L22
+ l %r3,8(%r4) /* r3 = PT_PHDR p_vaddr */
+ j .L25
+.L22: alr %r4,%r0 /* r4 += AT_PHENT value */
+ brct %r12,.L23
+
+ j .L14 /* No PT_PHDR found - skip checking. */
+
+.L25: slr %r11,%r3 /* AT_PHDR - PT_PHDR.p_vaddr (relocation offset)*/
+ alr %r9,%r11 /* PT_LOAD.p_vaddr += relocation offset */
+
+ l %r5,36(%r9) /* Load the e_flags field. */
+ tml %r5,1
+ jz .L14 /* Binary does not require highgprs facility. */
+
+ tml %r10,512 /* Check the AT_HWCAP value. */
+ jz 2 /* Trap if no highgprs facility available. */
+.L14:
+
+ /* Setup pointer to literal pool of _start */
+ basr %r13,0
+.L0: ahi %r13,.Llit-.L0
+
+ /* load argc and argv from stack */
+ la %r4,4(%r15) # get argv
+ l %r3,0(%r15) # get argc
+
+ /* align the stack to a double word boundary */
+ lhi %r0,-8
+ nr %r15,%r0
+
+ /* Setup a stack frame and a parameter area */
+ ahi %r15,-104 # make room on stack
+ xc 0(4,%r15),0(%r15) # clear back-chain
+
+ /* set up arguments for __libc_start_main:
+ main, argc, argv, envp, _init, _fini, rtld_fini, stack_end
+ Note that envp will be determined later in __libc_start_main
+ */
+ stm %r14,%r15,96(%r15) # store rtld_fini/stack_end to parameter area
+ la %r7,96(%r15)
+ l %r6,.L2-.Llit(%r13) # load pointer to __libc_csu_fini
+ l %r5,.L1-.Llit(%r13) # load pointer to __libc_csu_init
+ l %r2,.L3-.Llit(%r13) # load pointer to main
+ l %r1,.L4-.Llit(%r13) # load pointer to __libc_start_main
+#ifdef PIC
+ l %r12,.L5-.Llit(%r13) # load .got pointer
+ la %r6,0(%r13,%r6)
+ la %r5,0(%r13,%r5)
+ la %r12,0(%r13,%r12)
+ l %r2,0(%r12,%r2)
+ la %r1,0(%r13,%r1)
+#endif
+
+ /* ok, now branch to the libc main routine */
+ basr %r14,%r1
+
+ /* crash if __libc_start_main returns */
+ .word 0
+
+.Llit:
+#ifndef PIC
+.L1: .long __libc_csu_init
+.L2: .long __libc_csu_fini
+.L3: .long main
+.L4: .long __libc_start_main
+#else
+.L1: .long __libc_csu_init-.Llit
+.L2: .long __libc_csu_fini-.Llit
+.L3: .long main@GOT
+.L4: .long __libc_start_main@plt-.Llit
+.L5: .long _GLOBAL_OFFSET_TABLE_-.Llit
+#endif
+
+/* Define a symbol for the first piece of initialized data. */
+ .data
+ .globl __data_start
+__data_start:
+ .long 0
+ .weak data_start
+ data_start = __data_start
diff --git a/REORG.TODO/sysdeps/s390/s390-32/strcmp.S b/REORG.TODO/sysdeps/s390/s390-32/strcmp.S
new file mode 100644
index 0000000000..69754c5f5a
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/s390-32/strcmp.S
@@ -0,0 +1,41 @@
+/* strcmp - compare two string. S/390 version.
+ This file is part of the GNU C Library.
+ Copyright (C) 2001-2017 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
+ 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/>. */
+
+/* INPUT PARAMETERS
+ %r2 = address of string 1
+ %r3 = address of string 2. */
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+
+ .text
+ENTRY(strcmp)
+ slr %r0,%r0
+0: clst %r2,%r3
+ jo 0b
+ jp 1f
+ jm 2f
+ slr %r2,%r2
+ br %r14
+1: lhi %r2,1
+ br %r14
+2: lhi %r2,-1
+ br %r14
+END(strcmp)
+libc_hidden_builtin_def (strcmp)
diff --git a/REORG.TODO/sysdeps/s390/s390-32/strcpy.S b/REORG.TODO/sysdeps/s390/s390-32/strcpy.S
new file mode 100644
index 0000000000..ab06ff8d72
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/s390-32/strcpy.S
@@ -0,0 +1,36 @@
+/* strcpy - copy a string from source to destination. For IBM S390
+ This file is part of the GNU C Library.
+ Copyright (C) 2000-2017 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
+ 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/>. */
+
+/*
+ * R2 = address of destination
+ * R3 = address of source
+ */
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+
+ .text
+ENTRY(strcpy)
+ slr %r0,%r0
+ lr %r1,%r2
+0: mvst %r1,%r3
+ jo 0b
+ br %r14
+END(strcpy)
+libc_hidden_builtin_def (strcpy)
diff --git a/REORG.TODO/sysdeps/s390/s390-32/strncpy.S b/REORG.TODO/sysdeps/s390/s390-32/strncpy.S
new file mode 100644
index 0000000000..c642bce90d
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/s390-32/strncpy.S
@@ -0,0 +1,79 @@
+/* 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-2017 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
+ 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/>. */
+
+/*
+ * R2 = address of destination (dst)
+ * R3 = address of source (src)
+ * R4 = max of bytes to copy
+ */
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+
+ENTRY(strncpy)
+ .text
+ st %r2,24(%r15) # save dst pointer
+ slr %r2,%r3 # %r3 points to src, %r2+%r3 to dst
+ lhi %r1,3
+ nr %r1,%r4 # last 2 bits of # bytes
+ srl %r4,2
+ ltr %r4,%r4 # less than 4 bytes to copy ?
+ jz .L1
+ bras %r5,.L0 # enter loop & load address of a 0
+ .long 0
+.L0: icm %r0,8,0(%r3) # first byte
+ jz .L3
+ icm %r0,4,1(%r3) # second byte
+ jz .L4
+ icm %r0,2,2(%r3) # third byte
+ jz .L5
+ icm %r0,1,3(%r3) # fourth byte
+ jz .L6
+ st %r0,0(%r2,%r3) # store all four to dest.
+ la %r3,4(%r3)
+ brct %r4,.L0
+.L1: ltr %r1,%r1
+ jz .Lexit
+.L2: icm %r0,1,0(%r3)
+ stc %r0,0(%r2,%r3)
+ la %r3,1(%r3)
+ jz .L7
+ brct %r1,.L2
+ j .Lexit
+.L3: icm %r0,4,0(%r5)
+.L4: icm %r0,2,0(%r5)
+.L5: icm %r0,1,0(%r5)
+.L6: st %r0,0(%r2,%r3)
+ la %r3,4(%r3)
+ ahi %r4,-1
+ j .L8
+.L7: ahi %r1,-1
+.L8: sll %r4,2
+ alr %r4,%r1
+ alr %r2,%r3 # start of dst area to be zeroed
+ lr %r3,%r4
+ slr %r4,%r4
+ slr %r5,%r5
+.L9: mvcle %r2,%r4,0 # pad dst with zeroes
+ jo .L9
+.Lexit: l %r2,24(%r15) # return dst pointer
+ br %r14
+END(strncpy)
+libc_hidden_builtin_def (strncpy)
diff --git a/REORG.TODO/sysdeps/s390/s390-32/sub_n.S b/REORG.TODO/sysdeps/s390/s390-32/sub_n.S
new file mode 100644
index 0000000000..358c8deddb
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/s390-32/sub_n.S
@@ -0,0 +1,62 @@
+/* __mpn_sub_n -- Add two limb vectors of the same length > 0 and store
+ sum in a third limb vector.
+ Copyright (C) 2000-2017 Free Software Foundation, Inc.
+ Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com).
+ This file is part of the GNU MP Library.
+
+ The GNU MP 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 MP 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 MP Library; see the file COPYING.LIB. If not,
+ see <http://www.gnu.org/licenses/>. */
+
+/*
+ INPUT PARAMETERS
+ res_ptr %r2
+ s1_ptr %r3
+ s2_ptr %r4
+ size %r5
+*/
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+
+ENTRY(__mpn_sub_n)
+ st %r6,24(%r15) # save register 6
+ cfi_offset (%r6, -72)
+ sr %r1,%r1
+ lhi %r0,1 # cannot use ahi to add carry, use slr
+.L0: l %r6,0(%r1,%r3) # .L0 -> no carry from last sub
+ sl %r6,0(%r1,%r4)
+ st %r6,0(%r1,%r2)
+ la %r1,4(0,%r1)
+ brc 4,.L3
+.L1: brct %r5,.L0
+ slr %r2,%r2 # no last carry to return
+ j .Lexit
+.L2: l %r6,0(%r1,%r3) # .L2 -> carry from last sub
+ sl %r6,0(%r1,%r4)
+ brc 4,.L4
+ slr %r6,%r0 # no carry yet, add carry from last sub
+ st %r6,0(%r1,%r2)
+ la %r1,4(0,%r1)
+ brc 11,.L1 # new carry ?
+.L3: brct %r5,.L2
+ lr %r2,%r0 # return last carry
+ j .Lexit
+.L4: slr %r6,%r0 # already a carry, add carry from last sub
+ st %r6,0(%r1,%r2)
+ la %r1,4(0,%r1)
+ brct %r5,.L2
+ lr %r2,%r0 # return last carry
+.Lexit: l %r6,24(%r15) # restore register 6
+ br %r14
+END(__mpn_sub_n)
diff --git a/REORG.TODO/sysdeps/s390/s390-32/symbol-hacks.h b/REORG.TODO/sysdeps/s390/s390-32/symbol-hacks.h
new file mode 100644
index 0000000000..585c42365a
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/s390-32/symbol-hacks.h
@@ -0,0 +1,21 @@
+/* Hacks needed for symbol manipulation. s390 version.
+ Copyright (C) 2017 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/REORG.TODO/sysdeps/s390/s390-32/sysdep.h b/REORG.TODO/sysdeps/s390/s390-32/sysdep.h
new file mode 100644
index 0000000000..15a4e3e687
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/s390-32/sysdep.h
@@ -0,0 +1,101 @@
+/* Assembler macros for s390.
+ Copyright (C) 2000-2017 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/>. */
+
+#include <sysdeps/generic/sysdep.h>
+
+#ifdef __ASSEMBLER__
+
+/* Syntactic details of assembler. */
+
+/* ELF uses byte-counts for .align, most others use log2 of count of bytes. */
+#define ALIGNARG(log2) 1<<log2
+#define ASM_SIZE_DIRECTIVE(name) .size name,.-name;
+
+
+/* Define an entry point visible from C. */
+#define ENTRY(name) \
+ .globl C_SYMBOL_NAME(name); \
+ .type C_SYMBOL_NAME(name),@function; \
+ .align ALIGNARG(2); \
+ C_LABEL(name) \
+ cfi_startproc; \
+ CALL_MCOUNT
+
+#undef END
+#define END(name) \
+ cfi_endproc; \
+ ASM_SIZE_DIRECTIVE(name) \
+
+/* If compiled for profiling, call `mcount' at the start of each function. */
+#ifdef PROF
+#ifdef PIC
+#define CALL_MCOUNT \
+ lr 0,14 ; bras 14,.+12 ; .long _GLOBAL_OFFSET_TABLE_ - . ; .long 0f-. ; \
+ lr 1,14 ; al 1,4(14) ; al 14,0(14) ; l 14,_mcount@GOT(14) ; \
+ basr 14,14 ; lr 14,0 ; .data ; .align 4 ; 0: .long 0 ; .text ;
+#else
+#define CALL_MCOUNT \
+ lr 0,14 ; bras 14,.+12 ; .long _mcount ; .long 0f ; \
+ l 1,4(14) ; l 14,0(14) ; basr 14,14 ; lr 14,0 ; \
+ .data ; .align 4 ; 0: .long 0 ; .text ;
+#endif
+#else
+#define CALL_MCOUNT /* Do nothing. */
+#endif
+
+/* Since C identifiers are not normally prefixed with an underscore
+ on this system, the asm identifier `syscall_error' intrudes on the
+ C name space. Make sure we use an innocuous name. */
+#define syscall_error __syscall_error
+#define mcount _mcount
+
+#undef PSEUDO
+#define PSEUDO(name, syscall_name, args) \
+lose: SYSCALL_PIC_SETUP \
+ basr %r1,0; \
+0: al %r1,1f-0b(%r1); \
+ br %r1; \
+1: .long JUMPTARGET(syscall_error) - 0b; \
+ .globl syscall_error; \
+ ENTRY (name) \
+ DO_CALL (syscall_name, args); \
+ jm lose
+
+#undef PSEUDO_END
+#define PSEUDO_END(name) \
+ END (name)
+
+#undef JUMPTARGET
+#ifdef PIC
+#define JUMPTARGET(name) name##@PLT
+#define SYSCALL_PIC_SETUP \
+ bras %r12,1f \
+0: .long _GLOBAL_OFFSET_TABLE_-0b \
+1: al %r12,0(%r12)
+#else
+#define JUMPTARGET(name) name
+#define SYSCALL_PIC_SETUP /* Nothing. */
+#endif
+
+/* Local label name for asm code. */
+#ifndef L
+#define L(name) .L##name
+#endif
+
+#endif /* __ASSEMBLER__ */
diff --git a/REORG.TODO/sysdeps/s390/s390-32/tls-macros.h b/REORG.TODO/sysdeps/s390/s390-32/tls-macros.h
new file mode 100644
index 0000000000..a4c5fffa33
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/s390-32/tls-macros.h
@@ -0,0 +1,104 @@
+#define TLS_LE(x) \
+ ({ unsigned long __offset; \
+ __asm__ ("bras %0,1f\n" \
+ "0:\t.long " #x "@ntpoff\n" \
+ "1:\tl %0,0(%0)" \
+ : "=a" (__offset) : : "cc" ); \
+ (int *) (__builtin_thread_pointer() + __offset); })
+
+#ifdef PIC
+# define TLS_IE(x) \
+ ({ unsigned long __offset, __got; \
+ __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" \
+ "l %0,4(%0)\n\t" \
+ "l %0,0(%0,%1):tls_load:" #x "\n" \
+ : "=&a" (__offset), "=&a" (__got) : : "cc" ); \
+ (int *) (__builtin_thread_pointer() + __offset); })
+#else
+# define TLS_IE(x) \
+ ({ unsigned long __offset; \
+ __asm__ ("bras %0,1f\n" \
+ "0:\t.long " #x "@indntpoff\n" \
+ "1:\t l %0,0(%0)\n\t" \
+ "l %0,0(%0):tls_load:" #x \
+ : "=&a" (__offset) : : "cc" ); \
+ (int *) (__builtin_thread_pointer() + __offset); })
+#endif
+
+#ifdef PIC
+# define TLS_LD(x) \
+ ({ unsigned long __offset, __save12; \
+ __asm__ ("bras %0,1f\n" \
+ "0:\t.long _GLOBAL_OFFSET_TABLE_-0b\n\t" \
+ ".long __tls_get_offset@plt-0b\n\t" \
+ ".long " #x "@tlsldm\n\t" \
+ ".long " #x "@dtpoff\n" \
+ "1:\tlr %1,%%r12\n\t" \
+ "l %%r12,0(%0)\n\t" \
+ "la %%r12,0(%%r12,%0)\n\t" \
+ "l %%r1,4(%0)\n\t" \
+ "l %%r2,8(%0)\n\t" \
+ "bas %%r14,0(%%r1,%0):tls_ldcall:" #x "\n\t" \
+ "l %0,12(%0)\n\t" \
+ "alr %0,%%r2\n\t" \
+ "lr %%r12,%1" \
+ : "=&a" (__offset), "=&a" (__save12) \
+ : : "cc", "0", "1", "2", "3", "4", "5", "14"); \
+ (int *) (__builtin_thread_pointer() + __offset); })
+#else
+# define TLS_LD(x) \
+ ({ unsigned long __offset; \
+ __asm__ ("bras %0,1f\n" \
+ "0:\t.long _GLOBAL_OFFSET_TABLE_\n\t" \
+ ".long __tls_get_offset@plt\n\t" \
+ ".long " #x "@tlsldm\n\t" \
+ ".long " #x "@dtpoff\n" \
+ "1:\tl %%r12,0(%0)\n\t" \
+ "l %%r1,4(%0)\n\t" \
+ "l %%r2,8(%0)\n\t" \
+ "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", "14"); \
+ (int *) (__builtin_thread_pointer() + __offset); })
+#endif
+
+#ifdef PIC
+# define TLS_GD(x) \
+ ({ unsigned long __offset, __save12; \
+ __asm__ ("bras %0,1f\n" \
+ "0:\t.long _GLOBAL_OFFSET_TABLE_-0b\n\t" \
+ ".long __tls_get_offset@plt-0b\n\t" \
+ ".long " #x "@tlsgd\n" \
+ "1:\tlr %1,%%r12\n\t" \
+ "l %%r12,0(%0)\n\t" \
+ "la %%r12,0(%%r12,%0)\n\t" \
+ "l %%r1,4(%0)\n\t" \
+ "l %%r2,8(%0)\n\t" \
+ "bas %%r14,0(%%r1,%0):tls_gdcall:" #x "\n\t" \
+ "lr %0,%%r2\n\t" \
+ "lr %%r12,%1" \
+ : "=&a" (__offset), "=&a" (__save12) \
+ : : "cc", "0", "1", "2", "3", "4", "5", "14"); \
+ (int *) (__builtin_thread_pointer() + __offset); })
+#else
+# define TLS_GD(x) \
+ ({ unsigned long __offset; \
+ __asm__ ("bras %0,1f\n" \
+ "0:\t.long _GLOBAL_OFFSET_TABLE_\n\t" \
+ ".long __tls_get_offset@plt\n\t" \
+ ".long " #x "@tlsgd\n" \
+ "1:\tl %%r12,0(%0)\n\t" \
+ "l %%r1,4(%0)\n\t" \
+ "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", "14"); \
+ (int *) (__builtin_thread_pointer() + __offset); })
+#endif
diff --git a/REORG.TODO/sysdeps/s390/s390-32/tst-audit.h b/REORG.TODO/sysdeps/s390/s390-32/tst-audit.h
new file mode 100644
index 0000000000..daabc70aa9
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/s390-32/tst-audit.h
@@ -0,0 +1,25 @@
+/* Definitions for testing PLT entry/exit auditing. S/390 32-bit version.
+
+ Copyright (C) 2012-2017 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/>. */
+
+#define pltenter la_s390_32_gnu_pltenter
+#define pltexit la_s390_32_gnu_pltexit
+#define La_regs La_s390_32_regs
+#define La_retval La_s390_32_retval
+#define int_retval lrv_r2
diff --git a/REORG.TODO/sysdeps/s390/s390-64/Implies b/REORG.TODO/sysdeps/s390/s390-64/Implies
new file mode 100644
index 0000000000..a8cae95f9d
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/s390-64/Implies
@@ -0,0 +1 @@
+wordsize-64
diff --git a/REORG.TODO/sysdeps/s390/s390-64/Makefile b/REORG.TODO/sysdeps/s390/s390-64/Makefile
new file mode 100644
index 0000000000..b4d793bb3d
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/s390-64/Makefile
@@ -0,0 +1,9 @@
+ifeq ($(subdir),gmon)
+sysdep_routines += s390x-mcount
+endif
+
+ifeq ($(subdir),elf)
+CFLAGS-rtld.c += -Wno-uninitialized -Wno-unused
+CFLAGS-dl-load.c += -Wno-unused
+CFLAGS-dl-reloc.c += -Wno-unused
+endif
diff --git a/REORG.TODO/sysdeps/s390/s390-64/__longjmp.c b/REORG.TODO/sysdeps/s390/s390-64/__longjmp.c
new file mode 100644
index 0000000000..f7be9ddb18
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/s390-64/__longjmp.c
@@ -0,0 +1,89 @@
+/* Copyright (C) 2001-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com).
+
+ 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 <errno.h>
+#include <sysdep.h>
+#include <setjmp.h>
+#include <bits/setjmp.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <stap-probe.h>
+
+/* Jump to the position specified by ENV, causing the
+ setjmp call there to return VAL, or 1 if VAL is 0. */
+void
+__longjmp (__jmp_buf env, int val)
+{
+#ifdef PTR_DEMANGLE
+ uintptr_t guard = THREAD_GET_POINTER_GUARD ();
+# ifdef CHECK_SP
+ CHECK_SP (env, guard);
+# endif
+#elif defined CHECK_SP
+ CHECK_SP (env, 0);
+#endif
+ register long int r2 __asm__ ("%r2") = val == 0 ? 1 : val;
+#ifdef PTR_DEMANGLE
+ register uintptr_t r3 __asm__ ("%r3") = guard;
+ register void *r1 __asm__ ("%r1") = (void *) env;
+#endif
+ /* Restore registers and jump back. */
+ __asm__ __volatile__ (
+ /* longjmp probe expects longjmp first argument, second
+ argument and target address. */
+#ifdef PTR_DEMANGLE
+ "lmg %%r4,%%r5,64(%1)\n\t"
+ "xgr %%r4,%2\n\t"
+ "xgr %%r5,%2\n\t"
+ LIBC_PROBE_ASM (longjmp, 8@%1 -4@%0 8@%%r4)
+#else
+ LIBC_PROBE_ASM (longjmp, 8@%1 -4@%0 8@%%r14)
+#endif
+
+ /* restore fpregs */
+ "ld %%f8,80(%1)\n\t"
+ "ld %%f9,88(%1)\n\t"
+ "ld %%f10,96(%1)\n\t"
+ "ld %%f11,104(%1)\n\t"
+ "ld %%f12,112(%1)\n\t"
+ "ld %%f13,120(%1)\n\t"
+ "ld %%f14,128(%1)\n\t"
+ "ld %%f15,136(%1)\n\t"
+
+ /* restore gregs and return to jmp_buf target */
+#ifdef PTR_DEMANGLE
+ "lmg %%r6,%%r13,0(%1)\n\t"
+ "lgr %%r15,%%r5\n\t"
+ LIBC_PROBE_ASM (longjmp_target, 8@%1 -4@%0 8@%%r4)
+ "br %%r4"
+#else
+ "lmg %%r6,%%r15,0(%1)\n\t"
+ LIBC_PROBE_ASM (longjmp_target, 8@%1 -4@%0 8@%%r14)
+ "br %%r14"
+#endif
+ : : "r" (r2),
+#ifdef PTR_DEMANGLE
+ "r" (r1), "r" (r3)
+#else
+ "a" (env)
+#endif
+ );
+
+ /* Avoid `volatile function does return' warnings. */
+ for (;;);
+}
diff --git a/REORG.TODO/sysdeps/s390/s390-64/add_n.S b/REORG.TODO/sysdeps/s390/s390-64/add_n.S
new file mode 100644
index 0000000000..89197b2dbf
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/s390-64/add_n.S
@@ -0,0 +1,63 @@
+/* Add two limb vectors of the same length > 0 and store sum in a third
+ limb vector.
+ Copyright (C) 2001-2017 Free Software Foundation, Inc.
+ Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com).
+ This file is part of the GNU MP Library.
+
+ The GNU MP 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 MP 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 MP Library; see the file COPYING.LIB. If not,
+ see <http://www.gnu.org/licenses/>. */
+
+/*
+ INPUT PARAMETERS
+ res_ptr %r2
+ s1_ptr %r3
+ s2_ptr %r4
+ size %r5
+*/
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+
+ .text
+ENTRY(__mpn_add_n)
+ stg %r6,48(%r15) # save register 6
+ cfi_offset (%r6,-112)
+ slgr %r1,%r1
+ lghi %r0,1 # cannot use ahi to add carry, use alr
+.L0: lg %r6,0(%r1,%r3) # .L0 -> no carry from last add
+ alg %r6,0(%r1,%r4)
+ stg %r6,0(%r1,%r2)
+ la %r1,8(%r1)
+ brc 3,.L3
+.L1: brct %r5,.L0
+ slgr %r2,%r2 # no last carry to return
+ j .Lexit
+.L2: lg %r6,0(%r1,%r3) # .L2 -> carry from last add
+ alg %r6,0(%r1,%r4)
+ brc 3,.L4
+ algr %r6,%r0 # no carry yet, add carry from last add
+ stg %r6,0(%r1,%r2)
+ la %r1,8(%r1)
+ brc 12,.L1 # new carry ?
+.L3: brct %r5,.L2
+ lgr %r2,%r0 # return last carry
+ j .Lexit
+.L4: algr %r6,%r0 # already a carry, add carry from last add
+ stg %r6,0(%r1,%r2)
+ la %r1,8(%r1)
+ brct %r5,.L2
+ lgr %r2,%r0 # return last carry
+.Lexit: lg %r6,48(%r15) # restore register 6
+ br %r14
+END(__mpn_add_n)
diff --git a/REORG.TODO/sysdeps/s390/s390-64/backtrace.c b/REORG.TODO/sysdeps/s390/s390-64/backtrace.c
new file mode 100644
index 0000000000..4843db623a
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/s390-64/backtrace.c
@@ -0,0 +1,147 @@
+/* Return backtrace of current program state. 64 bit S/390 version.
+ Copyright (C) 2001-2017 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/>. */
+
+#include <libc-lock.h>
+#include <dlfcn.h>
+#include <execinfo.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <unwind.h>
+
+
+/* This is a global variable set at program start time. It marks the
+ highest used stack address. */
+extern void *__libc_stack_end;
+
+
+/* This is the stack layout we see for every non-leaf function.
+ size offset
+ %r15 -> +------------------+
+ 8 | back chain | 0
+ 8 | end of stack | 8
+ 32 | scratch | 16
+ 80 | save area r6-r15 | 48
+ 16 | save area f4,f6 | 128
+ 16 | empty | 144
+ +------------------+
+ r14 in the save area holds the return address.
+*/
+
+struct layout
+{
+ long back_chain;
+ long end_of_stack;
+ long scratch[4];
+ long save_grps[10];
+ long save_fp[2];
+ long empty[2];
+};
+
+struct trace_arg
+{
+ void **array;
+ int cnt, size;
+};
+
+#ifdef SHARED
+static _Unwind_Reason_Code (*unwind_backtrace) (_Unwind_Trace_Fn, void *);
+static _Unwind_Ptr (*unwind_getip) (struct _Unwind_Context *);
+
+static void
+init (void)
+{
+ void *handle = __libc_dlopen ("libgcc_s.so.1");
+
+ if (handle == NULL)
+ return;
+
+ unwind_backtrace = __libc_dlsym (handle, "_Unwind_Backtrace");
+ unwind_getip = __libc_dlsym (handle, "_Unwind_GetIP");
+ if (unwind_getip == NULL)
+ unwind_backtrace = NULL;
+}
+
+static int
+__backchain_backtrace (void **array, int size)
+{
+ /* We assume that all the code is generated with frame pointers set. */
+ struct layout *stack;
+ int cnt = 0;
+
+ __asm__ ("LGR %0,%%r15" : "=d" (stack) );
+ /* We skip the call to this function, it makes no sense to record it. */
+ stack = (struct layout *) stack->back_chain;
+ while (cnt < size)
+ {
+ if (stack == NULL || (void *) stack > __libc_stack_end)
+ /* This means the address is out of range. Note that for the
+ toplevel we see a frame pointer with value NULL which clearly is
+ out of range. */
+ break;
+
+ array[cnt++] = (void *) stack->save_grps[8];
+
+ stack = (struct layout *) stack->back_chain;
+ }
+
+ return cnt;
+}
+#else
+# define unwind_backtrace _Unwind_Backtrace
+# define unwind_getip _Unwind_GetIP
+#endif
+
+static _Unwind_Reason_Code
+backtrace_helper (struct _Unwind_Context *ctx, void *a)
+{
+ struct trace_arg *arg = a;
+
+ /* We are first called with address in the __backtrace function.
+ Skip it. */
+ if (arg->cnt != -1)
+ arg->array[arg->cnt] = (void *) unwind_getip (ctx);
+ if (++arg->cnt == arg->size)
+ return _URC_END_OF_STACK;
+ return _URC_NO_REASON;
+}
+
+int
+__backtrace (void **array, int size)
+{
+ struct trace_arg arg = { .array = array, .size = size, .cnt = -1 };
+
+ if (size <= 0)
+ return 0;
+
+#ifdef SHARED
+ __libc_once_define (static, once);
+
+ __libc_once (once, init);
+
+ if (unwind_backtrace == NULL)
+ return __backchain_backtrace (array, size);
+#endif
+
+ unwind_backtrace (backtrace_helper, &arg);
+
+ return arg.cnt != -1 ? arg.cnt : 0;
+}
+
+weak_alias (__backtrace, backtrace)
+libc_hidden_def (__backtrace)
diff --git a/REORG.TODO/sysdeps/s390/s390-64/bcopy.S b/REORG.TODO/sysdeps/s390/s390-64/bcopy.S
new file mode 100644
index 0000000000..235fc85568
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/s390-64/bcopy.S
@@ -0,0 +1,71 @@
+/* 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-2017 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
+ 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/>. */
+
+/* INPUT PARAMETERS
+ %r2 = address of source
+ %r3 = address of destination
+ %r4 = number of bytes to copy. */
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+
+ .text
+ENTRY(__bcopy)
+ ltgr %r1,%r4 # zero bcopy ?
+ jz .L4
+ clgr %r2,%r3 # check against destructive overlap
+ jnl .L0
+ algr %r1,%r2
+ clgr %r1,%r3
+ jh .L7
+.L0: aghi %r4,-1 # length - 1
+ srlg %r1,%r4,8
+ ltgr %r1,%r1 # < 256 bytes to move ?
+ jz .L2
+ cghi %r1,255 # > 1MB to move ?
+ jh .L5
+.L1: mvc 0(256,%r3),0(%r2) # move in 256 byte chunks
+ la %r2,256(%r2)
+ la %r3,256(%r3)
+ brctg %r1,.L1
+.L2: bras %r1,.L3 # setup base pointer for execute
+ mvc 0(1,%r3),0(%r2) # instruction for execute
+.L3: ex %r4,0(%r1) # execute mvc with length ((%r4)&255)+1
+.L4: br %r14
+ # data copies > 1MB are faster with mvcle.
+.L5: aghi %r4,1 # length + 1
+ lgr %r5,%r4 # source length
+ lgr %r4,%r2 # source address
+ lgr %r2,%r3 # set destination
+ lgr %r3,%r5 # destination length = source length
+.L6: mvcle %r2,%r4,0 # thats it, MVCLE is your friend
+ jo .L6
+ br %r14
+.L7: # destructive overlay, can not use mvcle
+ lgr %r1,%r2 # bcopy is called with source,dest
+ lgr %r2,%r3 # memmove with dest,source! Oh, well...
+ lgr %r3,%r1
+ jg HIDDEN_BUILTIN_JUMPTARGET(memmove)
+
+END(__bcopy)
+
+#ifndef NO_WEAK_ALIAS
+weak_alias (__bcopy, bcopy)
+#endif
+
diff --git a/REORG.TODO/sysdeps/s390/s390-64/bits/wordsize.h b/REORG.TODO/sysdeps/s390/s390-64/bits/wordsize.h
new file mode 100644
index 0000000000..00e88b0628
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/s390-64/bits/wordsize.h
@@ -0,0 +1,11 @@
+/* Determine the wordsize from the preprocessor defines. */
+
+#if defined __s390x__
+# define __WORDSIZE 64
+#else
+# define __WORDSIZE 32
+# define __WORDSIZE32_SIZE_ULONG 1
+# define __WORDSIZE32_PTRDIFF_LONG 0
+#endif
+
+#define __WORDSIZE_TIME64_COMPAT32 0
diff --git a/REORG.TODO/sysdeps/s390/s390-64/bsd-_setjmp.S b/REORG.TODO/sysdeps/s390/s390-64/bsd-_setjmp.S
new file mode 100644
index 0000000000..1417270201
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/s390-64/bsd-_setjmp.S
@@ -0,0 +1 @@
+/* We don't need any code here since the setjmp.S file contains it. */
diff --git a/REORG.TODO/sysdeps/s390/s390-64/bsd-setjmp.S b/REORG.TODO/sysdeps/s390/s390-64/bsd-setjmp.S
new file mode 100644
index 0000000000..1417270201
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/s390-64/bsd-setjmp.S
@@ -0,0 +1 @@
+/* We don't need any code here since the setjmp.S file contains it. */
diff --git a/REORG.TODO/sysdeps/s390/s390-64/bzero.S b/REORG.TODO/sysdeps/s390/s390-64/bzero.S
new file mode 100644
index 0000000000..119c20dcb9
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/s390-64/bzero.S
@@ -0,0 +1,41 @@
+/* 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-2017 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
+ 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/>. */
+
+/* INPUT PARAMETERS
+ %r2 = address of memory area
+ %r3 = number of bytes to fill. */
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+
+ .text
+ENTRY(__bzero)
+ ltgr %r3,%r3
+ jz .L1
+ sgr %r1,%r1 # set pad byte to zero
+ sgr %r4,%r4 # no source for MVCLE, only a pad byte
+ sgr %r5,%r5
+.L0: mvcle %r2,%r4,0(%r1) # thats it, MVCLE is your friend
+ jo .L0
+.L1: br %r14
+END(__bzero)
+
+#ifndef NO_WEAK_ALIAS
+weak_alias (__bzero, bzero)
+#endif
diff --git a/REORG.TODO/sysdeps/s390/s390-64/crti.S b/REORG.TODO/sysdeps/s390/s390-64/crti.S
new file mode 100644
index 0000000000..c9583bb9c9
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/s390-64/crti.S
@@ -0,0 +1,91 @@
+/* Special .init and .fini section support for 64 bit S/390.
+ Copyright (C) 2001-2017 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.
+
+ In addition to the permissions in the GNU Lesser General Public
+ License, the Free Software Foundation gives you unlimited
+ permission to link the compiled version of this file with other
+ programs, and to distribute those programs without any restriction
+ coming from the use of this file. (The GNU Lesser General Public
+ License restrictions do apply in other respects; for example, they
+ cover modification of the file, and distribution when not linked
+ into another program.)
+
+ Note that people who make modified versions of this file are not
+ obligated to grant this special exception for their modified
+ versions; it is their choice whether to do so. The GNU Lesser
+ General Public License gives permission to release a modified
+ version without this exception; this exception also makes it
+ possible to release a modified version which carries forward this
+ exception.
+
+ 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/>. */
+
+/* crti.S puts a function prologue at the beginning of the .init and
+ .fini sections and defines global symbols for those addresses, so
+ they can be called as functions. The symbols _init and _fini are
+ magic and cause the linker to emit DT_INIT and DT_FINI. */
+
+#include <libc-symbols.h>
+#include <sysdep.h>
+
+#ifndef PREINIT_FUNCTION
+# define PREINIT_FUNCTION __gmon_start__
+#endif
+
+#ifndef PREINIT_FUNCTION_WEAK
+# define PREINIT_FUNCTION_WEAK 1
+#endif
+
+#if PREINIT_FUNCTION_WEAK
+ weak_extern (PREINIT_FUNCTION)
+#else
+ .hidden PREINIT_FUNCTION
+#endif
+
+ .section .init,"ax",@progbits
+ .align 4
+ .globl _init
+ .type _init,@function
+_init:
+ stmg %r6,%r15,48(%r15)
+ lgr %r1,%r15
+ aghi %r15,-160
+ stg %r1,0(%r15)
+ larl %r12,_GLOBAL_OFFSET_TABLE_
+#if PREINIT_FUNCTION_WEAK
+ larl %r1,PREINIT_FUNCTION@GOTENT
+ lg %r1,0(%r1)
+ ltgr %r1,%r1
+ je 1f
+ basr %r14,%r1
+#else
+ brasl %r14,PREINIT_FUNCTION
+#endif
+ .align 4,0x07
+1:
+
+ .section .fini,"ax",@progbits
+ .align 4
+ .globl _fini
+ .type _fini,@function
+_fini:
+ stmg %r6,%r15,48(%r15)
+ lgr %r1,%r15
+ aghi %r15,-160
+ stg %r1,0(%r15)
+ larl %r12,_GLOBAL_OFFSET_TABLE_
+ .align 4,0x07
diff --git a/REORG.TODO/sysdeps/s390/s390-64/crtn.S b/REORG.TODO/sysdeps/s390/s390-64/crtn.S
new file mode 100644
index 0000000000..2bb3211e57
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/s390-64/crtn.S
@@ -0,0 +1,50 @@
+/* Special .init and .fini section support for 64 bit S/390.
+ Copyright (C) 2001-2017 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.
+
+ In addition to the permissions in the GNU Lesser General Public
+ License, the Free Software Foundation gives you unlimited
+ permission to link the compiled version of this file with other
+ programs, and to distribute those programs without any restriction
+ coming from the use of this file. (The GNU Lesser General Public
+ License restrictions do apply in other respects; for example, they
+ cover modification of the file, and distribution when not linked
+ into another program.)
+
+ Note that people who make modified versions of this file are not
+ obligated to grant this special exception for their modified
+ versions; it is their choice whether to do so. The GNU Lesser
+ General Public License gives permission to release a modified
+ version without this exception; this exception also makes it
+ possible to release a modified version which carries forward this
+ exception.
+
+ 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/>. */
+
+/* crtn.S puts function epilogues in the .init and .fini sections
+ corresponding to the prologues in crti.S. */
+
+ .section .init
+ .align 4
+ lg %r4,272(%r15)
+ lmg %r6,%r15,208(%r15)
+ br %r4
+
+ .section .fini
+ .align 4
+ lg %r4,272(%r15)
+ lmg %r6,%r15,208(%r15)
+ br %r4
diff --git a/REORG.TODO/sysdeps/s390/s390-64/dl-machine.h b/REORG.TODO/sysdeps/s390/s390-64/dl-machine.h
new file mode 100644
index 0000000000..f2aeb1e78e
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/s390-64/dl-machine.h
@@ -0,0 +1,476 @@
+/* Machine-dependent ELF dynamic relocation inline functions.
+ 64 bit S/390 Version.
+ Copyright (C) 2001-2017 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 dl_machine_h
+#define dl_machine_h
+
+#define ELF_MACHINE_NAME "s390x"
+
+#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
+
+/* This is an older, now obsolete value. */
+#define EM_S390_OLD 0xA390
+
+/* Return nonzero iff E_MACHINE is compatible with the running host. */
+static inline int
+elf_machine_matches_host (const Elf64_Ehdr *ehdr)
+{
+ return (ehdr->e_machine == EM_S390 || ehdr->e_machine == EM_S390_OLD)
+ && ehdr->e_ident[EI_CLASS] == ELFCLASS64;
+}
+
+/* Return the link-time address of _DYNAMIC. Conveniently, this is the
+ first element of the GOT. This must be inlined in a function which
+ uses global data. */
+
+static inline Elf64_Addr
+elf_machine_dynamic (void)
+{
+ register Elf64_Addr *got;
+
+ __asm__ ( " larl %0,_GLOBAL_OFFSET_TABLE_\n"
+ : "=&a" (got) : : "0" );
+
+ return *got;
+}
+
+/* Return the run-time load address of the shared object. */
+static inline Elf64_Addr
+elf_machine_load_address (void)
+{
+ Elf64_Addr addr;
+
+ __asm__( " larl %0,_dl_start\n"
+ " larl 1,_GLOBAL_OFFSET_TABLE_\n"
+ " lghi 2,_dl_start@GOT\n"
+ " slg %0,0(2,1)"
+ : "=&d" (addr) : : "1", "2" );
+ return addr;
+}
+
+/* Set up the loaded object described by L so its unrelocated PLT
+ entries will jump to the on-demand fixup code in dl-runtime.c. */
+
+static inline int __attribute__ ((unused))
+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)
+ {
+ /* The GOT entries for functions in the PLT have not yet been filled
+ in. Their initial contents will arrange when called to push an
+ offset into the .rela.plt section, push _GLOBAL_OFFSET_TABLE_[1],
+ and then jump to _GLOBAL_OFFSET_TABLE[2]. */
+ Elf64_Addr *got;
+ got = (Elf64_Addr *) D_PTR (l, l_info[DT_PLTGOT]);
+ /* If a library is prelinked but we have to relocate anyway,
+ we have to be able to undo the prelinking of .got.plt.
+ The prelinker saved us here address of .plt + 0x2e. */
+ if (got[1])
+ {
+ l->l_mach.plt = got[1] + l->l_addr;
+ l->l_mach.jmprel = (const Elf64_Rela *) D_PTR (l, l_info[DT_JMPREL]);
+ }
+ got[1] = (Elf64_Addr) l; /* Identify this shared object. */
+
+ /* The got[2] entry contains the address of a function which gets
+ called to get the address of a so far unresolved function and
+ jump to it. The profiling extension of the dynamic linker allows
+ to intercept the calls to collect information. In this case we
+ don't store the address in the GOT so that all future calls also
+ 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))
+ /* This is the object we are looking for. Say that we really
+ want profiling and the timers are started. */
+ 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. */
+#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;
+}
+
+/* Initial entry point code for the dynamic linker.
+ The C function `_dl_start' is the real entry point;
+ its return value is the user program's entry point. */
+
+#define RTLD_START __asm__ ("\n\
+.text\n\
+.align 4\n\
+.globl _start\n\
+.globl _dl_start_user\n\
+_start:\n\
+ lgr %r2,%r15\n\
+ # Alloc stack frame\n\
+ aghi %r15,-160\n\
+ # Set the back chain to zero\n\
+ xc 0(8,%r15),0(%r15)\n\
+ # Call _dl_start with %r2 pointing to arg on stack\n\
+ brasl %r14,_dl_start # call _dl_start\n\
+_dl_start_user:\n\
+ # Save the user entry point address in %r8.\n\
+ lgr %r8,%r2\n\
+ # Point %r12 at the GOT.\n\
+ larl %r12,_GLOBAL_OFFSET_TABLE_\n\
+ # See if we were run as a command with the executable file\n\
+ # name as an extra leading argument.\n\
+ lghi %r1,_dl_skip_args@GOT\n\
+ lg %r1,0(%r1,%r12)\n\
+ lgf %r1,0(%r1) # load _dl_skip_args\n\
+ # Get the original argument count.\n\
+ lg %r0,160(%r15)\n\
+ # Subtract _dl_skip_args from it.\n\
+ sgr %r0,%r1\n\
+ # Adjust the stack pointer to skip _dl_skip_args words.\n\
+ sllg %r1,%r1,3\n\
+ agr %r15,%r1\n\
+ # Set the back chain to zero again\n\
+ xc 0(8,%r15),0(%r15)\n\
+ # Store back the modified argument count.\n\
+ stg %r0,160(%r15)\n\
+ # The special initializer gets called with the stack just\n\
+ # as the application's entry point will see it; it can\n\
+ # switch stacks if it moves these contents over.\n\
+" RTLD_START_SPECIAL_INIT "\n\
+ # Call the function to run the initializers.\n\
+ # Load the parameters:\n\
+ # (%r2, %r3, %r4, %r5) = (_dl_loaded, argc, argv, envp)\n\
+ lghi %r2,_rtld_local@GOT\n\
+ lg %r2,0(%r2,%r12)\n\
+ lg %r2,0(%r2)\n\
+ lg %r3,160(%r15)\n\
+ la %r4,168(%r15)\n\
+ lgr %r5,%r3\n\
+ sllg %r5,%r5,3\n\
+ la %r5,176(%r5,%r15)\n\
+ brasl %r14,_dl_init@PLT\n\
+ # Pass our finalizer function to the user in %r14, as per ELF ABI.\n\
+ lghi %r14,_dl_fini@GOT\n\
+ lg %r14,0(%r14,%r12)\n\
+ # Free stack frame\n\
+ aghi %r15,160\n\
+ # Jump to the user's entry point (saved in %r8).\n\
+ br %r8\n\
+");
+
+#ifndef RTLD_START_SPECIAL_INIT
+#define RTLD_START_SPECIAL_INIT /* nothing */
+#endif
+
+/* ELF_RTYPE_CLASS_PLT iff TYPE describes relocation of a PLT entry or
+ TLS variable, so undefined references should not be allowed to
+ define the value.
+ ELF_RTYPE_CLASS_COPY iff TYPE should not be allowed to resolve to one
+ of the main executable's symbols, as for a COPY reloc. */
+#define elf_machine_type_class(type) \
+ ((((type) == R_390_JMP_SLOT || (type) == R_390_TLS_DTPMOD \
+ || (type) == R_390_TLS_DTPOFF || (type) == R_390_TLS_TPOFF) \
+ * ELF_RTYPE_CLASS_PLT) \
+ | (((type) == R_390_COPY) * ELF_RTYPE_CLASS_COPY))
+
+/* A reloc type used for ld.so cmdline arg lookups to reject PLT entries. */
+#define ELF_MACHINE_JMP_SLOT R_390_JMP_SLOT
+
+/* The 64 bit S/390 never uses Elf64_Rel relocations. */
+#define ELF_MACHINE_NO_REL 1
+#define ELF_MACHINE_NO_RELA 0
+
+/* We define an initialization functions. This is called very early in
+ _dl_sysdep_start. */
+#define DL_PLATFORM_INIT dl_platform_init ()
+
+static inline void __attribute__ ((unused))
+dl_platform_init (void)
+{
+ if (GLRO(dl_platform) != NULL && *GLRO(dl_platform) == '\0')
+ /* Avoid an empty string which would disturb us. */
+ GLRO(dl_platform) = NULL;
+}
+
+static inline Elf64_Addr
+elf_machine_fixup_plt (struct link_map *map, lookup_t t,
+ const Elf64_Rela *reloc,
+ Elf64_Addr *reloc_addr, Elf64_Addr value)
+{
+ return *reloc_addr = value;
+}
+
+/* Return the final value of a plt relocation. */
+static inline Elf64_Addr
+elf_machine_plt_value (struct link_map *map, const Elf64_Rela *reloc,
+ Elf64_Addr value)
+{
+ return value;
+}
+
+/* Names of the architecture-specific auditing callback functions. */
+#define ARCH_LA_PLTENTER s390_64_gnu_pltenter
+#define ARCH_LA_PLTEXIT s390_64_gnu_pltexit
+
+#endif /* !dl_machine_h */
+
+#ifdef RESOLVE_MAP
+
+/* Perform the relocation specified by RELOC and SYM (which is fully resolved).
+ MAP is the object containing the reloc. */
+
+auto inline void
+__attribute__ ((always_inline))
+elf_machine_rela (struct link_map *map, const Elf64_Rela *reloc,
+ const Elf64_Sym *sym, const struct r_found_version *version,
+ void *const reloc_addr_arg, int skip_ifunc)
+{
+ Elf64_Addr *const reloc_addr = reloc_addr_arg;
+ const unsigned int r_type = ELF64_R_TYPE (reloc->r_info);
+
+#if !defined RTLD_BOOTSTRAP || !defined HAVE_Z_COMBRELOC
+ if (__glibc_unlikely (r_type == R_390_RELATIVE))
+ {
+# if !defined RTLD_BOOTSTRAP && !defined HAVE_Z_COMBRELOC
+ /* This is defined in rtld.c, but nowhere in the static libc.a;
+ make the reference weak so static programs can still link.
+ This declaration cannot be done when compiling rtld.c
+ (i.e. #ifdef RTLD_BOOTSTRAP) because rtld.c contains the
+ common defn for _dl_rtld_map, which is incompatible with a
+ weak decl in the same file. */
+# ifndef SHARED
+ weak_extern (GL(dl_rtld_map));
+# endif
+ if (map != &GL(dl_rtld_map)) /* Already done in rtld itself. */
+# endif
+ *reloc_addr = map->l_addr + reloc->r_addend;
+ }
+ else
+#endif
+ if (__glibc_unlikely (r_type == R_390_NONE))
+ return;
+ else
+ {
+#if !defined RTLD_BOOTSTRAP && !defined RESOLVE_CONFLICT_FIND_MAP
+ /* Only needed for R_390_COPY below. */
+ 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;
+
+ if (sym != NULL
+ && __builtin_expect (ELFW(ST_TYPE) (sym->st_info) == STT_GNU_IFUNC,
+ 0)
+ && __builtin_expect (sym->st_shndx != SHN_UNDEF, 1)
+ && __builtin_expect (!skip_ifunc, 1))
+ value = elf_ifunc_invoke (value);
+
+ switch (r_type)
+ {
+ case R_390_IRELATIVE:
+ value = map->l_addr + reloc->r_addend;
+ if (__glibc_likely (!skip_ifunc))
+ value = elf_ifunc_invoke (value);
+ *reloc_addr = value;
+ break;
+ case R_390_GLOB_DAT:
+ case R_390_JMP_SLOT:
+ *reloc_addr = value + reloc->r_addend;
+ break;
+
+#ifndef RESOLVE_CONFLICT_FIND_MAP
+ case R_390_TLS_DTPMOD:
+# ifdef RTLD_BOOTSTRAP
+ /* During startup the dynamic linker is always the module
+ with index 1.
+ XXX If this relocation is necessary move before RESOLVE
+ call. */
+ *reloc_addr = 1;
+# else
+ /* Get the information from the link map returned by the
+ resolv function. */
+ if (sym_map != NULL)
+ *reloc_addr = sym_map->l_tls_modid;
+# endif
+ break;
+ case R_390_TLS_DTPOFF:
+# ifndef RTLD_BOOTSTRAP
+ /* During relocation all TLS symbols are defined and used.
+ Therefore the offset is already correct. */
+ if (sym != NULL)
+ *reloc_addr = sym->st_value + reloc->r_addend;
+# endif
+ break;
+ case R_390_TLS_TPOFF:
+ /* The offset is negative, forward from the thread pointer. */
+# ifdef RTLD_BOOTSTRAP
+ *reloc_addr = sym->st_value + reloc->r_addend - map->l_tls_offset;
+# else
+ /* We know the offset of the object the symbol is contained in.
+ It is a negative value which will be added to the
+ thread pointer. */
+ if (sym != NULL)
+ {
+ CHECK_STATIC_TLS (map, sym_map);
+ *reloc_addr = (sym->st_value + reloc->r_addend
+ - sym_map->l_tls_offset);
+ }
+#endif
+ break;
+#endif /* use TLS */
+
+#ifndef RTLD_BOOTSTRAP
+# ifndef RESOLVE_CONFLICT_FIND_MAP
+ /* Not needed for dl-conflict.c. */
+ case R_390_COPY:
+ if (sym == NULL)
+ /* This can happen in trace mode if an object could not be
+ found. */
+ break;
+ if (__builtin_expect (sym->st_size > refsym->st_size, 0)
+ || (__builtin_expect (sym->st_size < refsym->st_size, 0)
+ && __builtin_expect (GLRO(dl_verbose), 0)))
+ {
+ const char *strtab;
+
+ strtab = (const char *) D_PTR (map,l_info[DT_STRTAB]);
+ _dl_error_printf ("\
+%s: Symbol `%s' has different size in shared object, consider re-linking\n",
+ RTLD_PROGNAME, strtab + refsym->st_name);
+ }
+ memcpy (reloc_addr_arg, (void *) value,
+ MIN (sym->st_size, refsym->st_size));
+ break;
+# endif
+ case R_390_64:
+ *reloc_addr = value + reloc->r_addend;
+ break;
+ case R_390_32:
+ *(unsigned int *) reloc_addr = value + reloc->r_addend;
+ break;
+ case R_390_16:
+ *(unsigned short *) reloc_addr = value + reloc->r_addend;
+ break;
+ case R_390_8:
+ *(char *) reloc_addr = value + reloc->r_addend;
+ break;
+# ifndef RESOLVE_CONFLICT_FIND_MAP
+ case R_390_PC64:
+ *reloc_addr = value +reloc->r_addend - (Elf64_Addr) reloc_addr;
+ break;
+ case R_390_PC32DBL:
+ *(unsigned int *) reloc_addr = (unsigned int)
+ ((int) (value + reloc->r_addend - (Elf64_Addr) reloc_addr) >> 1);
+ break;
+ case R_390_PC32:
+ *(unsigned int *) reloc_addr =
+ value + reloc->r_addend - (Elf64_Addr) reloc_addr;
+ break;
+ case R_390_PC16DBL:
+ *(unsigned short *) reloc_addr = (unsigned short)
+ ((short) (value + reloc->r_addend - (Elf64_Addr) reloc_addr) >> 1);
+ break;
+ case R_390_PC16:
+ *(unsigned short *) reloc_addr =
+ value + reloc->r_addend - (Elf64_Addr) reloc_addr;
+ break;
+ case R_390_NONE:
+ break;
+# endif
+#endif
+#if !defined(RTLD_BOOTSTRAP) || defined(_NDEBUG)
+ default:
+ /* We add these checks in the version to relocate ld.so only
+ if we are still debugging. */
+ _dl_reloc_bad_type (map, r_type, 0);
+ break;
+#endif
+ }
+ }
+}
+
+auto inline void
+__attribute__ ((always_inline))
+elf_machine_rela_relative (Elf64_Addr l_addr, const Elf64_Rela *reloc,
+ void *const reloc_addr_arg)
+{
+ Elf64_Addr *const reloc_addr = reloc_addr_arg;
+ *reloc_addr = l_addr + reloc->r_addend;
+}
+
+auto inline void
+__attribute__ ((always_inline))
+elf_machine_lazy_rel (struct link_map *map,
+ Elf64_Addr l_addr, const Elf64_Rela *reloc,
+ int skip_ifunc)
+{
+ Elf64_Addr *const reloc_addr = (void *) (l_addr + reloc->r_offset);
+ const unsigned int r_type = ELF64_R_TYPE (reloc->r_info);
+ /* Check for unexpected PLT reloc type. */
+ if (__glibc_likely (r_type == R_390_JMP_SLOT))
+ {
+ if (__builtin_expect (map->l_mach.plt, 0) == 0)
+ *reloc_addr += l_addr;
+ else
+ *reloc_addr = map->l_mach.plt + (reloc - map->l_mach.jmprel) * 32;
+ }
+ else if (__glibc_likely (r_type == R_390_IRELATIVE))
+ {
+ Elf64_Addr value = map->l_addr + reloc->r_addend;
+ if (__glibc_likely (!skip_ifunc))
+ value = elf_ifunc_invoke (value);
+ *reloc_addr = value;
+ }
+ else
+ _dl_reloc_bad_type (map, r_type, 1);
+}
+
+#endif /* RESOLVE_MAP */
diff --git a/REORG.TODO/sysdeps/s390/s390-64/dl-trampoline.S b/REORG.TODO/sysdeps/s390/s390-64/dl-trampoline.S
new file mode 100644
index 0000000000..2e3b141e30
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/s390-64/dl-trampoline.S
@@ -0,0 +1,33 @@
+/* PLT trampolines. s390x version.
+ Copyright (C) 2005-2017 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 <sysdep.h>
+
+ .text
+/* 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/REORG.TODO/sysdeps/s390/s390-64/dl-trampoline.h b/REORG.TODO/sysdeps/s390/s390-64/dl-trampoline.h
new file mode 100644
index 0000000000..e1f95e2ecd
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/s390-64/dl-trampoline.h
@@ -0,0 +1,225 @@
+/* PLT trampolines. s390x version.
+ Copyright (C) 2016-2017 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)
+ std %f0,104(%r15)
+ cfi_offset (f0, -56)
+ std %f2,112(%r15)
+ cfi_offset (f2, -48)
+ std %f4,120(%r15)
+ cfi_offset (f4, -40)
+ std %f6,128(%r15)
+ cfi_offset (f6, -32)
+ stg %r14,96(15)
+ cfi_offset (r14, -64)
+ 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
+ aghi %r15,288 # remove stack frame
+ cfi_adjust_cfa_offset (-288)
+#else
+ aghi %r15,160 # remove stack frame
+ cfi_adjust_cfa_offset (-160)
+#endif
+ lg %r14,96(%r15) # restore registers
+ ld %f0,104(%r15)
+ ld %f2,112(%r15)
+ ld %f4,120(%r15)
+ ld %f6,128(%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/REORG.TODO/sysdeps/s390/s390-64/memchr.S b/REORG.TODO/sysdeps/s390/s390-64/memchr.S
new file mode 100644
index 0000000000..7deee3d6f3
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/s390-64/memchr.S
@@ -0,0 +1,40 @@
+/* Search a character in a block of memory. 64 bit S/390 version.
+ Copyright (C) 2001-2017 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/>. */
+
+/* INPUT PARAMETERS
+ %r2 = address to memory area
+ %r3 = character to find
+ %r4 = number of bytes to search. */
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+
+ .text
+ENTRY(memchr)
+ lghi %r0,0xff
+ ngr %r0,%r3
+ lgr %r1,%r2
+ la %r2,0(%r4,%r1)
+0: srst %r2,%r1
+ jo 0b
+ brc 13,1f
+ slgr %r2,%r2
+1: br %r14
+END(memchr)
+libc_hidden_builtin_def (memchr)
diff --git a/REORG.TODO/sysdeps/s390/s390-64/memcmp.S b/REORG.TODO/sysdeps/s390/s390-64/memcmp.S
new file mode 100644
index 0000000000..cecffc39f9
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/s390-64/memcmp.S
@@ -0,0 +1,64 @@
+/* memcmp - compare two memory blocks. 64 bit S/390 version.
+ Copyright (C) 2012-2017 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 <sysdep.h>
+#include "asm-syntax.h"
+
+/* INPUT PARAMETERS
+ %r2 = address of first memory area
+ %r3 = address of second memory area
+ %r4 = number of bytes to compare. */
+
+ .text
+#ifdef USE_MULTIARCH
+ENTRY(__memcmp_default)
+#else
+ENTRY(memcmp)
+#endif
+ .machine "z900"
+ ltgr %r4,%r4
+ je .L_Z900_4
+ aghi %r4,-1
+ srlg %r1,%r4,8
+ ltgr %r1,%r1
+ jne .L_Z900_12
+.L_Z900_3:
+ larl %r1,.L_Z900_15
+ ex %r4,0(%r1)
+.L_Z900_4:
+ ipm %r2
+ sllg %r2,%r2,34
+ srag %r2,%r2,62
+ br %r14
+.L_Z900_12:
+ clc 0(256,%r3),0(%r2)
+ jne .L_Z900_4
+ la %r3,256(%r3)
+ la %r2,256(%r2)
+ brctg %r1,.L_Z900_12
+ j .L_Z900_3
+.L_Z900_15:
+ clc 0(1,%r3),0(%r2)
+#ifdef USE_MULTIARCH
+END(__memcmp_default)
+#else
+END(memcmp)
+libc_hidden_builtin_def (memcmp)
+weak_alias (memcmp, bcmp)
+#endif
diff --git a/REORG.TODO/sysdeps/s390/s390-64/memcpy.S b/REORG.TODO/sysdeps/s390/s390-64/memcpy.S
new file mode 100644
index 0000000000..3df07b5e23
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/s390-64/memcpy.S
@@ -0,0 +1,88 @@
+/* memcpy - copy a block from source to destination. 64 bit S/390 version.
+ Copyright (C) 2012-2017 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 <sysdep.h>
+#include "asm-syntax.h"
+
+/* INPUT PARAMETERS
+ %r2 = address of destination memory area
+ %r3 = address of source memory area
+ %r4 = number of bytes to copy. */
+
+
+ .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
+
+ENTRY(memcpy)
+ .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
+ jne .L_Z900_13
+.L_Z900_3:
+ larl %r5,.L_Z900_15
+ ex %r4,0(%r5)
+.L_Z900_4:
+ br %r14
+.L_Z900_13:
+ cghi %r5,4096 # Switch to mvcle for copies >1MB
+ jh __memcpy_mvcle
+.L_Z900_12:
+ mvc 0(256,%r1),0(%r3)
+ la %r1,256(%r1)
+ la %r3,256(%r3)
+ brctg %r5,.L_Z900_12
+ j .L_Z900_3
+.L_Z900_15:
+ mvc 0(1,%r1),0(%r3)
+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.
+ 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,%r0 # return destination address
+ br %r14
+END(__memcpy_mvcle)
diff --git a/REORG.TODO/sysdeps/s390/s390-64/memset.S b/REORG.TODO/sysdeps/s390/s390-64/memset.S
new file mode 100644
index 0000000000..e653f12134
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/s390-64/memset.S
@@ -0,0 +1,64 @@
+/* Set a block of memory to some byte value. 64 bit S/390 version.
+ Copyright (C) 2001-2017 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/>. */
+
+
+#include <sysdep.h>
+#include "asm-syntax.h"
+
+/* INPUT PARAMETERS
+ %r2 = address of memory area
+ %r3 = byte to fill memory with
+ %r4 = number of bytes to fill. */
+
+ .text
+
+#ifdef USE_MULTIARCH
+ENTRY(__memset_default)
+#else
+ENTRY(memset)
+#endif
+ .machine "z900"
+ ltgr %r4,%r4
+ je .L_Z900_4
+ stc %r3,0(%r2)
+ cghi %r4,1
+ lgr %r1,%r2
+ je .L_Z900_4
+ aghi %r4,-2
+ srlg %r3,%r4,8
+ ltgr %r3,%r3
+ jne .L_Z900_14
+.L_Z900_3:
+ larl %r3,.L_Z900_18
+ ex %r4,0(%r3)
+.L_Z900_4:
+ br %r14
+.L_Z900_14:
+ mvc 1(256,%r1),0(%r1)
+ la %r1,256(%r1)
+ brctg %r3,.L_Z900_14
+ j .L_Z900_3
+.L_Z900_18:
+ mvc 1(1,%r1),0(%r1)
+#ifdef USE_MULTIARCH
+END(__memset_default)
+#else
+END(memset)
+libc_hidden_builtin_def (memset)
+#endif
diff --git a/REORG.TODO/sysdeps/s390/s390-64/multiarch/Makefile b/REORG.TODO/sysdeps/s390/s390-64/multiarch/Makefile
new file mode 100644
index 0000000000..91053b5364
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/s390-64/multiarch/Makefile
@@ -0,0 +1,4 @@
+ifeq ($(subdir),string)
+sysdep_routines += memset memset-s390x memcpy memcpy-s390x \
+ memcmp memcmp-s390x
+endif
diff --git a/REORG.TODO/sysdeps/s390/s390-64/multiarch/memchr.c b/REORG.TODO/sysdeps/s390/s390-64/multiarch/memchr.c
new file mode 100644
index 0000000000..808c3b837a
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/s390-64/multiarch/memchr.c
@@ -0,0 +1,21 @@
+/* Multiple versions of memchr.
+ Copyright (C) 2015-2017 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 wrapper-file is needed, because otherwise file
+ sysdeps/s390/s390-[32|64]/memchr.S will be used. */
+#include <sysdeps/s390/multiarch/memchr.c>
diff --git a/REORG.TODO/sysdeps/s390/s390-64/multiarch/memcmp-s390x.S b/REORG.TODO/sysdeps/s390/s390-64/multiarch/memcmp-s390x.S
new file mode 100644
index 0000000000..da956d2568
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/s390-64/multiarch/memcmp-s390x.S
@@ -0,0 +1,104 @@
+/* CPU specific memcmp implementations. 64 bit S/390 version.
+ Copyright (C) 2012-2017 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 "sysdep.h"
+#include "asm-syntax.h"
+
+/* INPUT PARAMETERS
+ %r2 = address of first memory area
+ %r3 = address of second memory area
+ %r4 = number of bytes to compare. */
+
+ .text
+
+#if IS_IN (libc)
+
+ENTRY(__memcmp_z196)
+ .machine "z196"
+ ltgr %r4,%r4
+ je .L_Z196_4
+ aghi %r4,-1
+ srlg %r1,%r4,8
+ ltgr %r1,%r1
+ jne .L_Z196_2
+.L_Z196_3:
+ exrl %r4,.L_Z196_14
+.L_Z196_4:
+ ipm %r2
+ sllg %r2,%r2,34
+ srag %r2,%r2,62
+ br %r14
+.L_Z196_17:
+ la %r3,256(%r3)
+ la %r2,256(%r2)
+ aghi %r1,-1
+ je .L_Z196_3
+.L_Z196_2:
+ pfd 1,512(%r3)
+ pfd 1,512(%r2)
+ clc 0(256,%r3),0(%r2)
+ je .L_Z196_17
+ ipm %r2
+ sllg %r2,%r2,34
+ srag %r2,%r2,62
+ br %r14
+.L_Z196_14:
+ clc 0(1,%r3),0(%r2)
+END(__memcmp_z196)
+
+ENTRY(__memcmp_z10)
+ .machine "z10"
+ ltgr %r4,%r4
+ je .L_Z10_4
+ aghi %r4,-1
+ srlg %r1,%r4,8
+ cgijlh %r1,0,.L_Z10_12
+.L_Z10_3:
+ exrl %r4,.L_Z10_15
+.L_Z10_4:
+ ipm %r2
+ sllg %r2,%r2,34
+ srag %r2,%r2,62
+ br %r14
+.L_Z10_12:
+ pfd 1,512(%r3)
+ pfd 1,512(%r2)
+ clc 0(256,%r3),0(%r2)
+ jne .L_Z10_4
+ la %r3,256(%r3)
+ la %r2,256(%r2)
+ brctg %r1,.L_Z10_12
+ j .L_Z10_3
+.L_Z10_15:
+ clc 0(1,%r3),0(%r2)
+END(__memcmp_z10)
+
+#endif /* IS_IN (libc) */
+
+#include "../memcmp.S"
+
+#if !IS_IN (libc)
+.globl memcmp
+.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/REORG.TODO/sysdeps/s390/s390-64/multiarch/memcmp.c b/REORG.TODO/sysdeps/s390/s390-64/multiarch/memcmp.c
new file mode 100644
index 0000000000..2d8d8f4d50
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/s390-64/multiarch/memcmp.c
@@ -0,0 +1,27 @@
+/* Multiple versions of memcmp.
+ Copyright (C) 2015-2017 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 IS_IN (libc)
+# define memcmp __redirect_memcmp
+# include <string.h>
+# undef memcmp
+# include <ifunc-resolve.h>
+
+s390_libc_ifunc (__redirect_memcmp, __memcmp, memcmp)
+weak_alias (memcmp, bcmp);
+#endif
diff --git a/REORG.TODO/sysdeps/s390/s390-64/multiarch/memcpy-s390x.S b/REORG.TODO/sysdeps/s390/s390-64/multiarch/memcpy-s390x.S
new file mode 100644
index 0000000000..a9ffa9cc98
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/s390-64/multiarch/memcpy-s390x.S
@@ -0,0 +1,122 @@
+/* CPU specific memcpy implementations. 64 bit S/390 version.
+ Copyright (C) 2012-2017 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 "sysdep.h"
+#include "asm-syntax.h"
+
+/* INPUT PARAMETERS
+ %r2 = target operands address
+ %r3 = source operands address
+ %r4 = number of bytes to copy. */
+
+ .text
+
+#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
+ srlg %r5,%r4,8
+ ltgr %r5,%r5
+ jne .L_Z196_5
+.L_Z196_3:
+ exrl %r4,.L_Z196_14
+.L_Z196_4:
+ br %r14
+.L_Z196_5:
+ cgfi %r5,262144 # Switch to mvcle for copies >64MB
+ jh __memcpy_mvcle
+.L_Z196_2:
+ pfd 1,768(%r3)
+ pfd 2,768(%r1)
+ mvc 0(256,%r1),0(%r3)
+ aghi %r5,-1
+ la %r1,256(%r1)
+ la %r3,256(%r3)
+ jne .L_Z196_2
+ j .L_Z196_3
+.L_Z196_14:
+ 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
+ srlg %r5,%r4,8
+ cgijlh %r5,0,.L_Z10_13
+.L_Z10_3:
+ exrl %r4,.L_Z10_15
+.L_Z10_4:
+ br %r14
+.L_Z10_13:
+ cgfi %r5,65535 # Switch to mvcle for copies >16MB
+ jh __memcpy_mvcle
+.L_Z10_12:
+ pfd 1,768(%r3)
+ pfd 2,768(%r1)
+ mvc 0(256,%r1),0(%r3)
+ la %r1,256(%r1)
+ la %r3,256(%r3)
+ brctg %r5,.L_Z10_12
+ j .L_Z10_3
+.L_Z10_15:
+ 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)
+.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/REORG.TODO/sysdeps/s390/s390-64/multiarch/memcpy.c b/REORG.TODO/sysdeps/s390/s390-64/multiarch/memcpy.c
new file mode 100644
index 0000000000..4b8e546fb0
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/s390-64/multiarch/memcpy.c
@@ -0,0 +1,27 @@
+/* Multiple versions of memcpy.
+ Copyright (C) 2015-2017 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/>. */
+
+/* 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 (__redirect_memcpy, __memcpy, memcpy)
+#endif
diff --git a/REORG.TODO/sysdeps/s390/s390-64/multiarch/memset-s390x.S b/REORG.TODO/sysdeps/s390/s390-64/multiarch/memset-s390x.S
new file mode 100644
index 0000000000..ca0c4326b1
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/s390-64/multiarch/memset-s390x.S
@@ -0,0 +1,112 @@
+/* Set a block of memory to some byte value. 64 bit S/390 version.
+ Copyright (C) 2012-2017 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 "sysdep.h"
+#include "asm-syntax.h"
+
+/* INPUT PARAMETERS
+ %r2 = address of memory area
+ %r3 = byte to fill memory with
+ %r4 = number of bytes to fill. */
+
+ .text
+
+#if IS_IN (libc)
+
+ENTRY(__memset_z196)
+ .machine "z196"
+ ltgr %r4,%r4
+ je .L_Z196_4
+ stc %r3,0(%r2)
+ lgr %r1,%r2
+ cghi %r4,1
+ je .L_Z196_4
+ aghi %r4,-2
+ srlg %r5,%r4,8
+ ltgr %r5,%r5
+ jne .L_Z196_1
+.L_Z196_3:
+ exrl %r4,.L_Z196_17
+.L_Z196_4:
+ br %r14
+.L_Z196_1:
+ cgfi %r5,1048576
+ jh __memset_mvcle # Switch to mvcle for >256MB
+.L_Z196_2:
+ pfd 2,1024(%r1)
+ mvc 1(256,%r1),0(%r1)
+ aghi %r5,-1
+ la %r1,256(%r1)
+ jne .L_Z196_2
+ j .L_Z196_3
+.L_Z196_17:
+ mvc 1(1,%r1),0(%r1)
+END(__memset_z196)
+
+ENTRY(__memset_z10)
+ .machine "z10"
+ cgije %r4,0,.L_Z10_4
+ stc %r3,0(%r2)
+ lgr %r1,%r2
+ cgije %r4,1,.L_Z10_4
+ aghi %r4,-2
+ srlg %r5,%r4,8
+ cgijlh %r5,0,.L_Z10_15
+.L_Z10_3:
+ exrl %r4,.L_Z10_18
+.L_Z10_4:
+ br %r14
+.L_Z10_15:
+ cgfi %r5,163840 # Switch to mvcle for >40MB
+ jh __memset_mvcle
+.L_Z10_14:
+ pfd 2,1024(%r1)
+ mvc 1(256,%r1),0(%r1)
+ la %r1,256(%r1)
+ brctg %r5,.L_Z10_14
+ j .L_Z10_3
+.L_Z10_18:
+ mvc 1(1,%r1),0(%r1)
+END(__memset_z10)
+
+ENTRY(__memset_mvcle)
+ aghi %r4,2 # take back the change done by the caller
+ lgr %r0,%r2 # save source address
+ lgr %r1,%r3 # move pad byte to R1
+ lgr %r3,%r4 # move length to r3
+ sgr %r4,%r4 # no source for MVCLE, only a pad byte
+ sgr %r5,%r5
+.L0: mvcle %r2,%r4,0(%r1) # thats it, MVCLE is your friend
+ jo .L0
+ lgr %r2,%r0 # return value is source address
+.L1:
+ br %r14
+END(__memset_mvcle)
+
+#endif /* IS_IN (libc) */
+
+#include "../memset.S"
+
+#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/REORG.TODO/sysdeps/s390/s390-64/multiarch/memset.c b/REORG.TODO/sysdeps/s390/s390-64/multiarch/memset.c
new file mode 100644
index 0000000000..421c0854a0
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/s390-64/multiarch/memset.c
@@ -0,0 +1,26 @@
+/* Multiple versions of memset.
+ Copyright (C) 2015-2017 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 IS_IN (libc)
+# define memset __redirect_memset
+# include <string.h>
+# undef memset
+# include <ifunc-resolve.h>
+
+s390_libc_ifunc (__redirect_memset, __memset, memset)
+#endif
diff --git a/REORG.TODO/sysdeps/s390/s390-64/multiarch/strcmp.c b/REORG.TODO/sysdeps/s390/s390-64/multiarch/strcmp.c
new file mode 100644
index 0000000000..6a20a304cc
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/s390-64/multiarch/strcmp.c
@@ -0,0 +1,21 @@
+/* Multiple versions of strcmp.
+ Copyright (C) 2015-2017 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 wrapper-file is needed, because otherwise file
+ sysdeps/s390/s390-[32|64]/strcmp.S will be used. */
+#include <sysdeps/s390/multiarch/strcmp.c>
diff --git a/REORG.TODO/sysdeps/s390/s390-64/multiarch/strcpy.c b/REORG.TODO/sysdeps/s390/s390-64/multiarch/strcpy.c
new file mode 100644
index 0000000000..7f380a471d
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/s390-64/multiarch/strcpy.c
@@ -0,0 +1,21 @@
+/* Multiple versions of strcpy.
+ Copyright (C) 2015-2017 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 wrapper-file is needed, because otherwise file
+ sysdeps/s390/s390-[32|64]/strcpy.S will be used. */
+#include <sysdeps/s390/multiarch/strcpy.c>
diff --git a/REORG.TODO/sysdeps/s390/s390-64/multiarch/strncpy.c b/REORG.TODO/sysdeps/s390/s390-64/multiarch/strncpy.c
new file mode 100644
index 0000000000..15dacec974
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/s390-64/multiarch/strncpy.c
@@ -0,0 +1,21 @@
+/* Multiple versions of strncpy.
+ Copyright (C) 2015-2017 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 wrapper-file is needed, because otherwise file
+ sysdeps/s390/s390-[32|64]/strncpy.S will be used. */
+#include <sysdeps/s390/multiarch/strncpy.c>
diff --git a/REORG.TODO/sysdeps/s390/s390-64/s390x-mcount.S b/REORG.TODO/sysdeps/s390/s390-64/s390x-mcount.S
new file mode 100644
index 0000000000..510834aa05
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/s390-64/s390x-mcount.S
@@ -0,0 +1,77 @@
+/* 64 bit S/390-specific implementation of profiling support.
+ Copyright (C) 2001-2017 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/>. */
+
+#include <sysdep.h>
+
+/* How profiling works on 64 bit S/390:
+ On the start of each function _mcount is called with the address of a
+ data word in %r1 (initialized to 0, used for counting). The compiler
+ with the option -p generates code of the form:
+
+ STM 6,15,24(15)
+ BRAS 13,.LTN0_0
+ .LT0_0:
+ .LC13: .long .LP0
+ .data
+ .align 4
+ .LP0: .long 0
+ .text
+ # function profiler
+ stg 14,4(15)
+ lg 1,.LC13-.LT0_0(13)
+ brasl 14,_mcount
+ lg 14,4(15)
+
+ The _mcount implementation now has to call __mcount_internal with the
+ address of .LP0 as first parameter and the return address as second
+ parameter. &.LP0 was loaded to %r1 and the return address is in %r14.
+ _mcount may not modify any register. */
+
+ .globl C_SYMBOL_NAME(_mcount)
+ .type C_SYMBOL_NAME(_mcount), @function
+ cfi_startproc
+ .align ALIGNARG(4)
+C_LABEL(_mcount)
+ /* Save the caller-clobbered registers. */
+ aghi %r15,-224
+ cfi_adjust_cfa_offset (224)
+ stmg %r14,%r5,160(%r15)
+ cfi_offset (r14, 0)
+ cfi_offset (r15, 8)
+ lg %r2,232(%r15) # callers address = first parameter
+ la %r2,0(%r2) # clear bit 0
+ la %r3,0(%r14) # callees address = second parameter
+
+#ifdef PIC
+ brasl %r14,__mcount_internal@PLT
+#else
+ brasl %r14,__mcount_internal
+#endif
+
+ /* Pop the saved registers. Please note that `mcount' has no
+ return value. */
+ lmg %r14,%r5,160(%r15)
+ aghi %r15,224
+ cfi_adjust_cfa_offset (-224)
+ br %r14
+ cfi_endproc
+ ASM_SIZE_DIRECTIVE(C_SYMBOL_NAME(_mcount))
+
+#undef mcount
+weak_alias (_mcount, mcount)
diff --git a/REORG.TODO/sysdeps/s390/s390-64/setjmp.S b/REORG.TODO/sysdeps/s390/s390-64/setjmp.S
new file mode 100644
index 0000000000..ac9c878346
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/s390-64/setjmp.S
@@ -0,0 +1,118 @@
+/* setjmp for 64 bit S/390, ELF version.
+ Copyright (C) 2001-2017 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/>. */
+
+#include <sysdep.h>
+#define _ASM
+#define _SETJMP_H
+#include <bits/setjmp.h>
+#include <shlib-compat.h>
+#include <stap-probe.h>
+
+#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)
+ lghi %r3,1 /* Second argument of one. */
+ j .Linternal_sigsetjmp /* Branch relativ to __sigsetjmp. */
+END (setjmp)
+
+ /* Binary compatibility entry point. */
+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. */
+ j .Linternal_sigsetjmp /* Branch relativ to __sigsetjmp. */
+END (__setjmp)
+
+ENTRY(__sigsetjmp)
+.Linternal_sigsetjmp:
+ /* setjmp probe expects sig/setjmp first argument (8@%r2), second
+ argument (-8@%r3) and target address (8@%r14). */
+ LIBC_PROBE (setjmp, 3, 8@%r2, -4@%r3, 8@%r14)
+#ifdef PTR_MANGLE
+ stmg %r6,%r13,0(%r2) /* Store registers in jmp_buf. */
+ lgr %r4,%r14
+ lgr %r5,%r15
+ PTR_MANGLE (%r4, %r1)
+ PTR_MANGLE2 (%r5, %r1)
+ stmg %r4,%r5,64(%r2)
+#else
+ stmg %r6,%r15,0(%r2) /* Store registers in jmp_buf. */
+#endif
+ std %f8,80(%r2)
+ std %f9,88(%r2)
+ std %f10,96(%r2)
+ std %f11,104(%r2)
+ std %f12,112(%r2)
+ std %f13,120(%r2)
+ std %f14,128(%r2)
+ std %f15,136(%r2)
+#if IS_IN (rtld)
+ /* In ld.so we never save the signal mask. */
+ lghi %r2,0
+ br %r14
+#elif defined PIC
+ jg __sigjmp_save@PLT /* Branch to PLT of __sigsetjmp. */
+#else
+ jg __sigjmp_save
+#endif
+END (__sigsetjmp)
+#if NEED_COMPAT_SYMBOLS
+strong_alias (__sigsetjmp, __GI___sigsetjmp)
+#else
+libc_hidden_def (__sigsetjmp)
+#endif
+
+#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
+
+strong_alias (__v1setjmp, __v2setjmp);
+versioned_symbol (libc, __v1setjmp, setjmp, GLIBC_2_0);
+compat_symbol (libc, __v2setjmp, setjmp, GLIBC_2_19);
+
+strong_alias (__v1_setjmp, __v2_setjmp);
+versioned_symbol (libc, __v1_setjmp, _setjmp, GLIBC_2_0);
+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 /* NEED_COMPAT_SYMBOLS */
diff --git a/REORG.TODO/sysdeps/s390/s390-64/stackguard-macros.h b/REORG.TODO/sysdeps/s390/s390-64/stackguard-macros.h
new file mode 100644
index 0000000000..2c97d3824f
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/s390-64/stackguard-macros.h
@@ -0,0 +1,18 @@
+#include <stdint.h>
+
+#define STACK_CHK_GUARD \
+ ({ uintptr_t x; __asm__ ("ear %0,%%a0; sllg %0,%0,32; ear %0,%%a1; lg %0,0x28(%0)" : "=a" (x)); x; })
+
+/* On s390/s390x there is no unique pointer guard, instead we use the
+ same value as the stack guard. */
+#define POINTER_CHK_GUARD \
+ ({ \
+ uintptr_t x; \
+ __asm__ ("ear %0,%%a0;" \
+ "sllg %0,%0,32;" \
+ "ear %0,%%a1;" \
+ "lg %0,%1(%0)" \
+ : "=a" (x) \
+ : "i" (offsetof (tcbhead_t, stack_guard))); \
+ x; \
+ })
diff --git a/REORG.TODO/sysdeps/s390/s390-64/start.S b/REORG.TODO/sysdeps/s390/s390-64/start.S
new file mode 100644
index 0000000000..d8e65450d8
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/s390-64/start.S
@@ -0,0 +1,100 @@
+/* Startup code compliant to the 64 bit S/390 ELF ABI.
+ Copyright (C) 2001-2017 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.
+
+ In addition to the permissions in the GNU Lesser General Public
+ License, the Free Software Foundation gives you unlimited
+ permission to link the compiled version of this file with other
+ programs, and to distribute those programs without any restriction
+ coming from the use of this file. (The GNU Lesser General Public
+ License restrictions do apply in other respects; for example, they
+ cover modification of the file, and distribution when not linked
+ into another program.)
+
+ Note that people who make modified versions of this file are not
+ obligated to grant this special exception for their modified
+ versions; it is their choice whether to do so. The GNU Lesser
+ General Public License gives permission to release a modified
+ version without this exception; this exception also makes it
+ possible to release a modified version which carries forward this
+ exception.
+
+ 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 is the canonical entry point, usually the first thing in the text
+ segment. Most registers' values are unspecified, except for:
+
+ %r14 Contains a function pointer to be registered with `atexit'.
+ This is how the dynamic linker arranges to have DT_FINI
+ functions called for shared libraries that have been loaded
+ before this code runs.
+
+ %r15 The stack contains the arguments and environment:
+ 0(%r15) argc
+ 8(%r15) argv[0]
+ ...
+ (8*argc)(%r15) NULL
+ (8*(argc+1))(%r15) envp[0]
+ ...
+ NULL
+*/
+
+ .text
+ .globl _start
+ .type _start,@function
+_start:
+ /* Load argc and argv from stack. */
+ la %r4,8(%r15) # get argv
+ lg %r3,0(%r15) # get argc
+
+ /* Align the stack to a double word boundary. */
+ lghi %r0,-16
+ ngr %r15,%r0
+
+ /* Setup a stack frame and a parameter area. */
+ aghi %r15,-176 # make room on stack
+ xc 0(8,%r15),0(%r15) # clear back-chain
+
+ /* Set up arguments for __libc_start_main:
+ main, argc, argv, envp, _init, _fini, rtld_fini, stack_end
+ Note that envp will be determined later in __libc_start_main.
+ */
+ stmg %r14,%r15,160(%r15) # store rtld_fini/stack_end to parameter area
+ la %r7,160(%r15)
+ larl %r6,__libc_csu_fini # load pointer to __libc_csu_fini
+ larl %r5,__libc_csu_init # load pointer to __libc_csu_init
+
+ /* Ok, now branch to the libc main routine. */
+#ifdef PIC
+ larl %r2,main@GOTENT # load pointer to main
+ lg %r2,0(%r2)
+ brasl %r14,__libc_start_main@plt
+#else
+ larl %r2,main # load pointer to main
+ brasl %r14,__libc_start_main
+#endif
+
+ /* Crash if __libc_start_main returns. */
+ .word 0
+
+ /* Define a symbol for the first piece of initialized data. */
+ .data
+ .globl __data_start
+__data_start:
+ .long 0
+ .weak data_start
+ data_start = __data_start
diff --git a/REORG.TODO/sysdeps/s390/s390-64/strcmp.S b/REORG.TODO/sysdeps/s390/s390-64/strcmp.S
new file mode 100644
index 0000000000..640493b4df
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/s390-64/strcmp.S
@@ -0,0 +1,41 @@
+/* strcmp - compare two string. 64 bit S/390 version.
+ This file is part of the GNU C Library.
+ Copyright (C) 2001-2017 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
+ 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/>. */
+
+/* INPUT PARAMETERS
+ %r2 = address of string 1
+ %r3 = address of string 2. */
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+
+ .text
+ENTRY(strcmp)
+ slr %r0,%r0
+0: clst %r2,%r3
+ jo 0b
+ jp 1f
+ jm 2f
+ slgr %r2,%r2
+ br %r14
+1: lghi %r2,1
+ br %r14
+2: lghi %r2,-1
+ br %r14
+END(strcmp)
+libc_hidden_builtin_def (strcmp)
diff --git a/REORG.TODO/sysdeps/s390/s390-64/strcpy.S b/REORG.TODO/sysdeps/s390/s390-64/strcpy.S
new file mode 100644
index 0000000000..fee1d3ede6
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/s390-64/strcpy.S
@@ -0,0 +1,35 @@
+/* strcpy - copy a string from source to destination. 64 bit S/390 version.
+ Copyright (C) 2001-2017 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/>. */
+
+/* INPUT PARAMETERS
+ %r2 = address of destination
+ %r3 = address of source. */
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+
+ .text
+ENTRY(strcpy)
+ slgr %r0,%r0
+ lgr %r1,%r2
+0: mvst %r1,%r3
+ jo 0b
+ br %r14
+END(strcpy)
+libc_hidden_builtin_def (strcpy)
diff --git a/REORG.TODO/sysdeps/s390/s390-64/strncpy.S b/REORG.TODO/sysdeps/s390/s390-64/strncpy.S
new file mode 100644
index 0000000000..80aee312e4
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/s390-64/strncpy.S
@@ -0,0 +1,90 @@
+/* strncpy - copy at most n characters from a string from source to
+ destination. 64 bit S/390 version
+ Copyright (C) 2001-2017 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/>. */
+
+/* INPUT PARAMETERS
+ %r2 = address of destination (dst)
+ %r3 = address of source (src)
+ %r4 = max of bytes to copy. */
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+
+ENTRY(strncpy)
+ .text
+ stg %r2,48(%r15) # save dst pointer
+ slgr %r2,%r3 # %r3 points to src, %r2+%r3 to dst
+ lghi %r1,7
+ ngr %r1,%r4 # last 3 bits of # bytes
+ srlg %r4,%r4,3
+ ltgr %r4,%r4 # less than 8 bytes to copy ?
+ jz .L1
+ bras %r5,.L0 # enter loop & load address of a 0
+ .long 0
+.L0: icmh %r0,8,0(%r3) # first byte
+ jz .L3
+ icmh %r0,4,1(%r3) # second byte
+ jz .L4
+ icmh %r0,2,2(%r3) # third byte
+ jz .L5
+ icmh %r0,1,3(%r3) # fourth byte
+ jz .L6
+ icm %r0,8,4(%r3) # fifth byte
+ jz .L7
+ icm %r0,4,5(%r3) # sixth byte
+ jz .L8
+ icm %r0,2,6(%r3) # seventh byte
+ jz .L9
+ icm %r0,1,7(%r3) # eigth byte
+ jz .L10
+ stg %r0,0(%r2,%r3) # store all eight to dest.
+ la %r3,8(%r3)
+ brct %r4,.L0
+.L1: ltgr %r1,%r1
+ jz .Lexit
+.L2: icm %r0,1,0(%r3)
+ stc %r0,0(%r2,%r3)
+ la %r3,1(%r3)
+ jz .L11
+ brct %r1,.L2
+ j .Lexit
+.L3: icmh %r0,4,0(%r5)
+.L4: icmh %r0,2,0(%r5)
+.L5: icmh %r0,1,0(%r5)
+.L6: icm %r0,8,0(%r5)
+.L7: icm %r0,4,0(%r5)
+.L8: icm %r0,2,0(%r5)
+.L9: icm %r0,1,0(%r5)
+.L10: stg %r0,0(%r2,%r3)
+ la %r3,8(%r3)
+ aghi %r4,-1
+ j .L12
+.L11: aghi %r1,-1
+.L12: sllg %r4,%r4,3
+ algr %r4,%r1
+ algr %r2,%r3 # start of dst area to be zeroed
+ lgr %r3,%r4
+ slgr %r4,%r4
+ slgr %r5,%r5
+.L13: mvcle %r2,%r4,0 # pad dst with zeroes
+ jo .L13
+.Lexit: lg %r2,48(%r15) # return dst pointer
+ br %r14
+END(strncpy)
+libc_hidden_builtin_def (strncpy)
diff --git a/REORG.TODO/sysdeps/s390/s390-64/sub_n.S b/REORG.TODO/sysdeps/s390/s390-64/sub_n.S
new file mode 100644
index 0000000000..dc6572ca36
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/s390-64/sub_n.S
@@ -0,0 +1,60 @@
+/* __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-2017 Free Software Foundation, Inc.
+ Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com).
+ This file is part of the GNU MP 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; see the file COPYING.LIB. If not,
+ see <http://www.gnu.org/licenses/>. */
+
+/* INPUT PARAMETERS
+ %r2 = res_ptr
+ %r3 = s1_ptr
+ %r4 = s2_ptr
+ %r5 = size. */
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+
+ENTRY(__mpn_sub_n)
+ stg %r6,48(%r15) # save register 6
+ cfi_offset (%r6,-112)
+ sgr %r1,%r1
+ lghi %r0,1 # cannot use ahi to add carry, use slr
+.L0: lg %r6,0(%r1,%r3) # .L0 -> no carry from last sub
+ slg %r6,0(%r1,%r4)
+ stg %r6,0(%r1,%r2)
+ la %r1,8(%r1)
+ brc 4,.L3
+.L1: brct %r5,.L0
+ slgr %r2,%r2 # no last carry to return
+ j .Lexit
+.L2: lg %r6,0(%r1,%r3) # .L2 -> carry from last sub
+ slg %r6,0(%r1,%r4)
+ brc 4,.L4
+ slgr %r6,%r0 # no carry yet, add carry from last sub
+ stg %r6,0(%r1,%r2)
+ la %r1,8(%r1)
+ brc 11,.L1 # new carry ?
+.L3: brct %r5,.L2
+ lgr %r2,%r0 # return last carry
+ j .Lexit
+.L4: slgr %r6,%r0 # already a carry, add carry from last sub
+ stg %r6,0(%r1,%r2)
+ la %r1,8(%r1)
+ brct %r5,.L2
+ lgr %r2,%r0 # return last carry
+.Lexit: lg %r6,48(%r15) # restore register 6
+ br %r14
+END(__mpn_sub_n)
diff --git a/REORG.TODO/sysdeps/s390/s390-64/sysdep.h b/REORG.TODO/sysdeps/s390/s390-64/sysdep.h
new file mode 100644
index 0000000000..a4dfc67178
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/s390-64/sysdep.h
@@ -0,0 +1,94 @@
+/* Assembler macros for 64 bit S/390.
+ Copyright (C) 2001-2017 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/>. */
+
+#include <sysdeps/generic/sysdep.h>
+
+#ifdef __ASSEMBLER__
+
+/* Syntactic details of assembler. */
+
+/* ELF uses byte-counts for .align, most others use log2 of count of bytes. */
+#define ALIGNARG(log2) 1<<log2
+#define ASM_SIZE_DIRECTIVE(name) .size name,.-name;
+
+
+/* Define an entry point visible from C. */
+#define ENTRY(name) \
+ .globl C_SYMBOL_NAME(name); \
+ .type C_SYMBOL_NAME(name),@function; \
+ .align ALIGNARG(2); \
+ C_LABEL(name) \
+ cfi_startproc; \
+ CALL_MCOUNT
+
+#undef END
+#define END(name) \
+ cfi_endproc; \
+ ASM_SIZE_DIRECTIVE(name) \
+
+/* If compiled for profiling, call `mcount' at the start of each function. */
+#ifdef PROF
+#ifdef PIC
+#define CALL_MCOUNT \
+ lgr 0,14 ; larl 1,0f ; brasl 14,_mcount@PLT ; lgr 14,0 ; \
+ .data ; .align 4 ; 0: .long 0 ; .text ;
+#else
+#define CALL_MCOUNT \
+ lgr 0,14 ; larl 1,0f ; brasl 14,_mcount ; lgr 14,0 ; \
+ .data ; .align 4 ; 0: .long 0 ; .text ;
+#endif
+#else
+#define CALL_MCOUNT /* Do nothing. */
+#endif
+
+/* Since C identifiers are not normally prefixed with an underscore
+ on this system, the asm identifier `syscall_error' intrudes on the
+ C name space. Make sure we use an innocuous name. */
+#define syscall_error __syscall_error
+#define mcount _mcount
+
+#undef PSEUDO
+#define PSEUDO(name, syscall_name, args) \
+lose: SYSCALL_PIC_SETUP \
+ jg JUMPTARGET(syscall_error); \
+ .globl syscall_error; \
+ ENTRY (name) \
+ DO_CALL (syscall_name, args); \
+ jm lose
+
+#undef PSEUDO_END
+#define PSEUDO_END(name) \
+ END (name)
+
+#undef JUMPTARGET
+#ifdef PIC
+#define JUMPTARGET(name) name##@PLT
+#define SYSCALL_PIC_SETUP \
+ larl %r12,_GLOBAL_OFFSET_TABLE_
+#else
+#define JUMPTARGET(name) name
+#define SYSCALL_PIC_SETUP /* Nothing. */
+#endif
+
+/* Local label name for asm code. */
+#ifndef L
+#define L(name) .L##name
+#endif
+
+#endif /* __ASSEMBLER__ */
diff --git a/REORG.TODO/sysdeps/s390/s390-64/tls-macros.h b/REORG.TODO/sysdeps/s390/s390-64/tls-macros.h
new file mode 100644
index 0000000000..d70ea6ce0c
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/s390-64/tls-macros.h
@@ -0,0 +1,88 @@
+#define TLS_LE(x) \
+ ({ unsigned long __offset; \
+ __asm__ ("bras %0,1f\n" \
+ "0:\t.quad " #x "@ntpoff\n" \
+ "1:\tlg %0,0(%0)" \
+ : "=a" (__offset) : : "cc" ); \
+ (int *) (__builtin_thread_pointer() + __offset); })
+
+#ifdef PIC
+# define TLS_IE(x) \
+ ({ unsigned long __offset, __got; \
+ __asm__ ("bras %0,0f\n\t" \
+ ".quad " #x "@gotntpoff\n" \
+ "0:\tlarl %1,_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" ); \
+ (int *) (__builtin_thread_pointer() + __offset); })
+#else
+# define TLS_IE(x) \
+ ({ unsigned long __offset; \
+ __asm__ ("bras %0,1f\n" \
+ "0:\t.quad " #x "@indntpoff\n" \
+ "1:\t lg %0,0(%0)\n\t" \
+ "lg %0,0(%0):tls_load:" #x \
+ : "=&a" (__offset) : : "cc" ); \
+ (int *) (__builtin_thread_pointer() + __offset); })
+#endif
+
+#ifdef PIC
+# define TLS_LD(x) \
+ ({ unsigned long __offset, __save12; \
+ __asm__ ("bras %0,1f\n" \
+ "0:\t.quad " #x "@tlsldm\n\t" \
+ ".quad " #x "@dtpoff\n" \
+ "1:\tlgr %1,%%r12\n\t" \
+ "larl %%r12,_GLOBAL_OFFSET_TABLE_\n\t" \
+ "lg %%r2,0(%0)\n\t" \
+ "brasl %%r14,__tls_get_offset@plt:tls_ldcall:" #x "\n\t" \
+ "lg %0,8(%0)\n\t" \
+ "algr %0,%%r2\n\t" \
+ "lgr %%r12,%1" \
+ : "=&a" (__offset), "=&a" (__save12) \
+ : : "cc", "0", "1", "2", "3", "4", "5", "14" ); \
+ (int *) (__builtin_thread_pointer() + __offset); })
+#else
+# define TLS_LD(x) \
+ ({ unsigned long __offset; \
+ __asm__ ("bras %0,1f\n" \
+ "0:\t.quad " #x "@tlsldm\n\t" \
+ ".quad " #x "@dtpoff\n" \
+ "1:\tlarl %%r12,_GLOBAL_OFFSET_TABLE_\n\t" \
+ "lg %%r2,0(%0)\n\t" \
+ "brasl %%r14,__tls_get_offset@plt:tls_ldcall:" #x "\n\t" \
+ "lg %0,8(%0)\n\t" \
+ "algr %0,%%r2" \
+ : "=&a" (__offset) \
+ : : "cc", "0", "1", "2", "3", "4", "5", "12", "14" ); \
+ (int *) (__builtin_thread_pointer() + __offset); })
+#endif
+
+#ifdef PIC
+# define TLS_GD(x) \
+ ({ unsigned long __offset, __save12; \
+ __asm__ ("bras %0,1f\n" \
+ "0:\t.quad " #x "@tlsgd\n" \
+ "1:\tlgr %1,%%r12\n\t" \
+ "larl %%r12,_GLOBAL_OFFSET_TABLE_\n\t" \
+ "lg %%r2,0(%0)\n\t" \
+ "brasl %%r14,__tls_get_offset@plt:tls_gdcall:" #x "\n\t" \
+ "lgr %0,%%r2\n\t" \
+ "lgr %%r12,%1" \
+ : "=&a" (__offset), "=&a" (__save12) \
+ : : "cc", "0", "1", "2", "3", "4", "5", "14" ); \
+ (int *) (__builtin_thread_pointer() + __offset); })
+#else
+# define TLS_GD(x) \
+ ({ unsigned long __offset; \
+ __asm__ ("bras %0,1f\n" \
+ "0:\t.quad " #x "@tlsgd\n" \
+ "1:\tlarl %%r12,_GLOBAL_OFFSET_TABLE_\n\t" \
+ "lg %%r2,0(%0)\n\t" \
+ "brasl %%r14,__tls_get_offset@plt:tls_gdcall:" #x "\n\t" \
+ "lgr %0,%%r2" \
+ : "=&a" (__offset) \
+ : : "cc", "0", "1", "2", "3", "4", "5", "12", "14" ); \
+ (int *) (__builtin_thread_pointer() + __offset); })
+#endif
diff --git a/REORG.TODO/sysdeps/s390/s390-64/tst-audit.h b/REORG.TODO/sysdeps/s390/s390-64/tst-audit.h
new file mode 100644
index 0000000000..67a93f51f1
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/s390-64/tst-audit.h
@@ -0,0 +1,25 @@
+/* Definitions for testing PLT entry/exit auditing. S/390 64-bit version.
+
+ Copyright (C) 2012-2017 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/>. */
+
+#define pltenter la_s390_64_gnu_pltenter
+#define pltexit la_s390_64_gnu_pltexit
+#define La_regs La_s390_64_regs
+#define La_retval La_s390_64_retval
+#define int_retval lrv_r2
diff --git a/REORG.TODO/sysdeps/s390/sotruss-lib.c b/REORG.TODO/sysdeps/s390/sotruss-lib.c
new file mode 100644
index 0000000000..2b9f1f31e6
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/sotruss-lib.c
@@ -0,0 +1,62 @@
+/* Override generic sotruss-lib.c to define actual functions for s390.
+ Copyright (C) 2012-2017 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/>. */
+
+#define HAVE_ARCH_PLTENTER
+#define HAVE_ARCH_PLTEXIT
+
+#include <elf/sotruss-lib.c>
+
+#if __ELF_NATIVE_CLASS == 32
+# define la_s390_gnu_pltenter la_s390_32_gnu_pltenter
+# define la_s390_gnu_pltexit la_s390_32_gnu_pltexit
+# define La_s390_regs La_s390_32_regs
+# define La_s390_retval La_s390_32_retval
+#else
+# define la_s390_gnu_pltenter la_s390_64_gnu_pltenter
+# define la_s390_gnu_pltexit la_s390_64_gnu_pltexit
+# define La_s390_regs La_s390_64_regs
+# define La_s390_retval La_s390_64_retval
+#endif
+
+ElfW(Addr)
+la_s390_gnu_pltenter (ElfW(Sym) *sym,
+ unsigned int ndx __attribute__ ((unused)),
+ uintptr_t *refcook, uintptr_t *defcook,
+ La_s390_regs *regs, unsigned int *flags,
+ const char *symname, long int *framesizep)
+{
+ print_enter (refcook, defcook, symname,
+ regs->lr_r2, regs->lr_r3, regs->lr_r4, *flags);
+
+ /* No need to copy anything, we will not need the parameters in any case. */
+ *framesizep = 0;
+
+ return sym->st_value;
+}
+
+unsigned int
+la_s390_gnu_pltexit (ElfW(Sym) *sym, unsigned int ndx, uintptr_t *refcook,
+ uintptr_t *defcook,
+ const struct La_s390_regs *inregs,
+ struct La_s390_retval *outregs, const char *symname)
+{
+ print_exit (refcook, defcook, symname, outregs->lrv_r2);
+
+ return 0;
+}
diff --git a/REORG.TODO/sysdeps/s390/stackinfo.h b/REORG.TODO/sysdeps/s390/stackinfo.h
new file mode 100644
index 0000000000..39da94efff
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/stackinfo.h
@@ -0,0 +1,33 @@
+/* Copyright (C) 2000-2017 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 file contains a bit of information about the stack allocation
+ of the processor. */
+
+#ifndef _STACKINFO_H
+#define _STACKINFO_H 1
+
+#include <elf.h>
+
+/* On s390 the stack grows down. */
+#define _STACK_GROWS_DOWN 1
+
+/* Default to an executable stack. PF_X can be overridden if PT_GNU_STACK is
+ * present, but it is presumed absent. */
+#define DEFAULT_STACK_PERMS (PF_R|PF_W|PF_X)
+
+#endif /* stackinfo.h */
diff --git a/REORG.TODO/sysdeps/s390/string_private.h b/REORG.TODO/sysdeps/s390/string_private.h
new file mode 100644
index 0000000000..118db043f4
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/string_private.h
@@ -0,0 +1,20 @@
+/* Define _STRING_ARCH_unaligned. S/390 version.
+ Copyright (C) 2016-2017 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 s390 processors can access unaligned multi-byte variables. */
+#define _STRING_ARCH_unaligned 1
diff --git a/REORG.TODO/sysdeps/s390/utf16-utf32-z9.c b/REORG.TODO/sysdeps/s390/utf16-utf32-z9.c
new file mode 100644
index 0000000000..7a174ea0e5
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/utf16-utf32-z9.c
@@ -0,0 +1,603 @@
+/* Conversion between UTF-16 and UTF-32 BE/internal.
+
+ This module uses the Z9-109 variants of the Convert Unicode
+ instructions.
+ Copyright (C) 1997-2017 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_TO_VX 1
+#else
+# define HAVE_FROM_VX 0
+# define HAVE_TO_VX 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 */
+
+
+/* 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-16 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 */
+
+/* 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/REORG.TODO/sysdeps/s390/utf8-utf16-z9.c b/REORG.TODO/sysdeps/s390/utf8-utf16-z9.c
new file mode 100644
index 0000000000..42163e7a19
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/utf8-utf16-z9.c
@@ -0,0 +1,825 @@
+/* Conversion between UTF-8 and UTF-16 - s390 version.
+
+ This module uses the Z9-109 variants of the Convert Unicode
+ instructions.
+ Copyright (C) 1997-2017 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
+#else
+# define HAVE_FROM_VX 0
+# define HAVE_TO_VX 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 */
+
+/* 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/REORG.TODO/sysdeps/s390/utf8-utf32-z9.c b/REORG.TODO/sysdeps/s390/utf8-utf32-z9.c
new file mode 100644
index 0000000000..57572fa44a
--- /dev/null
+++ b/REORG.TODO/sysdeps/s390/utf8-utf32-z9.c
@@ -0,0 +1,871 @@
+/* Conversion between UTF-8 and UTF-32 BE/internal.
+
+ This module uses the Z9-109 variants of the Convert Unicode
+ instructions.
+ Copyright (C) 1997-2017 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
+#else
+# define HAVE_FROM_VX 0
+# define HAVE_TO_VX 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 */
+
+/* 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