diff options
author | Samuel Thibault <samuel.thibault@ens-lyon.org> | 2018-12-27 19:01:57 +0000 |
---|---|---|
committer | Samuel Thibault <samuel.thibault@ens-lyon.org> | 2018-12-27 19:01:57 +0000 |
commit | cab56836b146bc129f1ad43f0393d95a9deca63a (patch) | |
tree | 4f4e655319bbac78fca170da05275c127429b460 /sysdeps/s390 | |
parent | 04ac1241a4cd004872282c2c82ec37fa33925292 (diff) | |
parent | 82dd75a7f436a19047325d62182590c9f9e23a78 (diff) |
Merge branch 't/tls' into refs/top-bases/t/tls-threadvar
Diffstat (limited to 'sysdeps/s390')
280 files changed, 6691 insertions, 3451 deletions
diff --git a/sysdeps/s390/Makefile b/sysdeps/s390/Makefile new file mode 100644 index 0000000000..8a54f88cd7 --- /dev/null +++ b/sysdeps/s390/Makefile @@ -0,0 +1,31 @@ +ifeq ($(subdir),iconvdata) +ISO-8859-1_CP037_Z900-routines := iso-8859-1_cp037_z900 +ISO-8859-1_CP037_Z900-map := gconv.map + +UTF8_UTF32_Z9-routines := utf8-utf32-z9 +UTF8_UTF32_Z9-map := gconv.map + +UTF16_UTF32_Z9-routines := utf16-utf32-z9 +UTF16_UTF32_Z9-map := gconv.map + +UTF8_UTF16_Z9-routines := utf8-utf16-z9 +UTF8_UTF16_Z9-map := gconv.map + +s390x-iconv-modules = ISO-8859-1_CP037_Z900 UTF8_UTF16_Z9 UTF16_UTF32_Z9 UTF8_UTF32_Z9 + +extra-modules-left += $(s390x-iconv-modules) +include extra-module.mk + +cpp-srcs-left := $(foreach mod,$(s390x-iconv-modules),$($(mod)-routines)) +lib := iconvdata +include $(patsubst %,$(..)libof-iterator.mk,$(cpp-srcs-left)) + +extra-objs += $(addsuffix .so, $(s390x-iconv-modules)) +install-others += $(patsubst %, $(inst_gconvdir)/%.so, $(s390x-iconv-modules)) + +$(patsubst %, $(inst_gconvdir)/%.so, $(s390x-iconv-modules)) : \ +$(inst_gconvdir)/%.so: $(objpfx)%.so $(+force) + $(do-install-program) + +sysdeps-gconv-modules = ../sysdeps/s390/gconv-modules +endif diff --git a/sysdeps/s390/asm-syntax.h b/sysdeps/s390/asm-syntax.h index 64a03b7419..2c37abf483 100644 --- a/sysdeps/s390/asm-syntax.h +++ b/sysdeps/s390/asm-syntax.h @@ -1,5 +1,5 @@ /* Definitions for S/390 syntax variations. - Copyright (C) 1992-2016 Free Software Foundation, Inc. + Copyright (C) 1992-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. Its master source is NOT part of the C library, however. The master source lives in the GNU MP Library. diff --git a/sysdeps/s390/atomic-machine.h b/sysdeps/s390/atomic-machine.h index 4ba41077e4..b80b55ecd2 100644 --- a/sysdeps/s390/atomic-machine.h +++ b/sysdeps/s390/atomic-machine.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2003-2016 Free Software Foundation, Inc. +/* Copyright (C) 2003-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Martin Schwidefsky <schwidefsky@de.ibm.com>, 2003. @@ -43,78 +43,119 @@ typedef uintptr_t uatomicptr_t; typedef intmax_t atomic_max_t; typedef uintmax_t uatomic_max_t; -#define USE_ATOMIC_COMPILER_BUILTINS 0 +/* Activate all C11 atomic builtins. + Note: + E.g. in nptl/pthread_key_delete.c if compiled with GCCs 6 and before, + an extra stack-frame is generated and the old value is stored on stack + before cs instruction but it never loads this value from stack. + An unreleased GCC 7 omit those stack operations. -#define __arch_compare_and_exchange_val_8_acq(mem, newval, oldval) \ - (abort (), (__typeof (*mem)) 0) + E.g. in nptl/pthread_once.c the condition code of cs instruction is + evaluated by a sequence of ipm, sra, compare and jump instructions instead + of one conditional jump instruction. This also occurs with an unreleased + GCC 7. -#define __arch_compare_and_exchange_val_16_acq(mem, newval, oldval) \ - (abort (), (__typeof (*mem)) 0) - -#define __arch_compare_and_exchange_val_32_acq(mem, newval, oldval) \ - ({ __typeof (mem) __archmem = (mem); \ - __typeof (*mem) __archold = (oldval); \ - __asm__ __volatile__ ("cs %0,%2,%1" \ - : "+d" (__archold), "=Q" (*__archmem) \ - : "d" (newval), "m" (*__archmem) : "cc", "memory" ); \ - __archold; }) + The atomic_fetch_abc_def C11 builtins are now using load-and-abc instructions + on z196 zarch and higher cpus instead of a loop with compare-and-swap + instruction. */ +#define USE_ATOMIC_COMPILER_BUILTINS 1 #ifdef __s390x__ # define __HAVE_64B_ATOMICS 1 -# define __arch_compare_and_exchange_val_64_acq(mem, newval, oldval) \ - ({ __typeof (mem) __archmem = (mem); \ - __typeof (*mem) __archold = (oldval); \ - __asm__ __volatile__ ("csg %0,%2,%1" \ - : "+d" (__archold), "=Q" (*__archmem) \ - : "d" ((long) (newval)), "m" (*__archmem) : "cc", "memory" ); \ - __archold; }) #else # define __HAVE_64B_ATOMICS 0 -/* For 31 bit we do not really need 64-bit compare-and-exchange. We can - implement them by use of the csd instruction. The straightforward - implementation causes warnings so we skip the definition for now. */ -# define __arch_compare_and_exchange_val_64_acq(mem, newval, oldval) \ - (abort (), (__typeof (*mem)) 0) #endif +#define ATOMIC_EXCHANGE_USES_CAS 1 + +/* Implement some of the non-C11 atomic macros from include/atomic.h + with help of the C11 atomic builtins. The other non-C11 atomic macros + are using the macros defined here. */ + +/* Atomically store NEWVAL in *MEM if *MEM is equal to OLDVAL. + Return the old *MEM value. */ +#define atomic_compare_and_exchange_val_acq(mem, newval, oldval) \ + ({ __atomic_check_size((mem)); \ + typeof ((__typeof (*(mem))) *(mem)) __atg1_oldval = (oldval); \ + __atomic_compare_exchange_n (mem, (void *) &__atg1_oldval, \ + newval, 1, __ATOMIC_ACQUIRE, \ + __ATOMIC_RELAXED); \ + __atg1_oldval; }) +#define atomic_compare_and_exchange_val_rel(mem, newval, oldval) \ + ({ __atomic_check_size((mem)); \ + typeof ((__typeof (*(mem))) *(mem)) __atg1_2_oldval = (oldval); \ + __atomic_compare_exchange_n (mem, (void *) &__atg1_2_oldval, \ + newval, 1, __ATOMIC_RELEASE, \ + __ATOMIC_RELAXED); \ + __atg1_2_oldval; }) + +/* Atomically store NEWVAL in *MEM if *MEM is equal to OLDVAL. + Return zero if *MEM was changed or non-zero if no exchange happened. */ +#define atomic_compare_and_exchange_bool_acq(mem, newval, oldval) \ + ({ __atomic_check_size((mem)); \ + typeof ((__typeof (*(mem))) *(mem)) __atg2_oldval = (oldval); \ + !__atomic_compare_exchange_n (mem, (void *) &__atg2_oldval, newval, \ + 1, __ATOMIC_ACQUIRE, \ + __ATOMIC_RELAXED); }) +#define catomic_compare_and_exchange_bool_acq(mem, newval, oldval) \ + atomic_compare_and_exchange_bool_acq (mem, newval, oldval) + /* Store NEWVALUE in *MEM and return the old value. */ -/* On s390, the atomic_exchange_acq is different from generic implementation, - because the generic one does not use the condition-code of cs-instruction - to determine if looping is needed. Instead it saves the old-value and - compares it against old-value returned by cs-instruction. */ -#ifdef __s390x__ -# define atomic_exchange_acq(mem, newvalue) \ - ({ __typeof (mem) __atg5_memp = (mem); \ - __typeof (*(mem)) __atg5_oldval = *__atg5_memp; \ - __typeof (*(mem)) __atg5_value = (newvalue); \ - if (sizeof (*mem) == 4) \ - __asm__ __volatile__ ("0: cs %0,%2,%1\n" \ - " jl 0b" \ - : "+d" (__atg5_oldval), "=Q" (*__atg5_memp) \ - : "d" (__atg5_value), "m" (*__atg5_memp) \ - : "cc", "memory" ); \ - else if (sizeof (*mem) == 8) \ - __asm__ __volatile__ ("0: csg %0,%2,%1\n" \ - " jl 0b" \ - : "+d" ( __atg5_oldval), "=Q" (*__atg5_memp) \ - : "d" ((long) __atg5_value), "m" (*__atg5_memp) \ - : "cc", "memory" ); \ - else \ - abort (); \ - __atg5_oldval; }) -#else -# define atomic_exchange_acq(mem, newvalue) \ - ({ __typeof (mem) __atg5_memp = (mem); \ - __typeof (*(mem)) __atg5_oldval = *__atg5_memp; \ - __typeof (*(mem)) __atg5_value = (newvalue); \ - if (sizeof (*mem) == 4) \ - __asm__ __volatile__ ("0: cs %0,%2,%1\n" \ - " jl 0b" \ - : "+d" (__atg5_oldval), "=Q" (*__atg5_memp) \ - : "d" (__atg5_value), "m" (*__atg5_memp) \ - : "cc", "memory" ); \ - else \ - abort (); \ - __atg5_oldval; }) -#endif +#define atomic_exchange_acq(mem, newvalue) \ + ({ __atomic_check_size((mem)); \ + __atomic_exchange_n (mem, newvalue, __ATOMIC_ACQUIRE); }) +#define atomic_exchange_rel(mem, newvalue) \ + ({ __atomic_check_size((mem)); \ + __atomic_exchange_n (mem, newvalue, __ATOMIC_RELEASE); }) + +/* Add VALUE to *MEM and return the old value of *MEM. */ +/* The gcc builtin uses load-and-add instruction on z196 zarch and higher cpus + instead of a loop with compare-and-swap instruction. */ +# define atomic_exchange_and_add_acq(mem, operand) \ + ({ __atomic_check_size((mem)); \ + __atomic_fetch_add ((mem), (operand), __ATOMIC_ACQUIRE); }) +# define atomic_exchange_and_add_rel(mem, operand) \ + ({ __atomic_check_size((mem)); \ + __atomic_fetch_add ((mem), (operand), __ATOMIC_RELEASE); }) +#define catomic_exchange_and_add(mem, value) \ + atomic_exchange_and_add (mem, value) + +/* Atomically *mem |= mask and return the old value of *mem. */ +/* The gcc builtin uses load-and-or instruction on z196 zarch and higher cpus + instead of a loop with compare-and-swap instruction. */ +#define atomic_or_val(mem, operand) \ + ({ __atomic_check_size((mem)); \ + __atomic_fetch_or ((mem), (operand), __ATOMIC_ACQUIRE); }) +/* Atomically *mem |= mask. */ +#define atomic_or(mem, mask) \ + do { \ + atomic_or_val (mem, mask); \ + } while (0) +#define catomic_or(mem, mask) \ + atomic_or (mem, mask) + +/* Atomically *mem |= 1 << bit and return true if the bit was set in old value + of *mem. */ +/* The load-and-or instruction is used on z196 zarch and higher cpus + instead of a loop with compare-and-swap instruction. */ +#define atomic_bit_test_set(mem, bit) \ + ({ __typeof (*(mem)) __atg14_old; \ + __typeof (mem) __atg14_memp = (mem); \ + __typeof (*(mem)) __atg14_mask = ((__typeof (*(mem))) 1 << (bit)); \ + __atg14_old = atomic_or_val (__atg14_memp, __atg14_mask); \ + __atg14_old & __atg14_mask; }) + +/* Atomically *mem &= mask and return the old value of *mem. */ +/* The gcc builtin uses load-and-and instruction on z196 zarch and higher cpus + instead of a loop with compare-and-swap instruction. */ +#define atomic_and_val(mem, operand) \ + ({ __atomic_check_size((mem)); \ + __atomic_fetch_and ((mem), (operand), __ATOMIC_ACQUIRE); }) +/* Atomically *mem &= mask. */ +#define atomic_and(mem, mask) \ + do { \ + atomic_and_val (mem, mask); \ + } while (0) +#define catomic_and(mem, mask) \ + atomic_and(mem, mask) diff --git a/sysdeps/s390/bits/byteswap-16.h b/sysdeps/s390/bits/byteswap-16.h deleted file mode 100644 index 87514d1b92..0000000000 --- a/sysdeps/s390/bits/byteswap-16.h +++ /dev/null @@ -1,65 +0,0 @@ -/* Macros to swap the order of bytes in 16-bit integer values. s390 version - Copyright (C) 2012-2016 Free Software Foundation, Inc. - Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com). - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, see - <http://www.gnu.org/licenses/>. */ - -#ifndef _BITS_BYTESWAP_H -# error "Never use <bits/byteswap-16.h> directly; include <byteswap.h> instead." -#endif - -#include <bits/wordsize.h> - -/* Swap bytes in 16 bit value. */ -#if defined __GNUC__ && __GNUC__ >= 2 -# if __WORDSIZE == 64 -# define __bswap_16(x) \ - (__extension__ \ - ({ unsigned short int __v, __x = (unsigned short int) (x); \ - if (__builtin_constant_p (x)) \ - __v = __bswap_constant_16 (__x); \ - else { \ - unsigned short int __tmp = (unsigned short int) (__x); \ - __asm__ __volatile__ ( \ - "lrvh %0,%1" \ - : "=&d" (__v) : "m" (__tmp) ); \ - } \ - __v; })) -# else -# define __bswap_16(x) \ - (__extension__ \ - ({ unsigned short int __v, __x = (unsigned short int) (x); \ - if (__builtin_constant_p (x)) \ - __v = __bswap_constant_16 (__x); \ - else { \ - unsigned short int __tmp = (unsigned short int) (__x); \ - __asm__ __volatile__ ( \ - "sr %0,%0\n" \ - "la 1,%1\n" \ - "icm %0,2,1(1)\n" \ - "ic %0,0(1)" \ - : "=&d" (__v) : "m" (__tmp) : "1"); \ - } \ - __v; })) -# endif -#else -/* This is better than nothing. */ -static __inline unsigned short int -__bswap_16 (unsigned short int __bsx) -{ - return __bswap_constant_16 (__bsx); -} -#endif diff --git a/sysdeps/s390/bits/byteswap.h b/sysdeps/s390/bits/byteswap.h deleted file mode 100644 index 6a8cb9d82b..0000000000 --- a/sysdeps/s390/bits/byteswap.h +++ /dev/null @@ -1,134 +0,0 @@ -/* Macros to swap the order of bytes in integer values. s390 version. - Copyright (C) 2000-2016 Free Software Foundation, Inc. - Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com). - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, see - <http://www.gnu.org/licenses/>. */ - -#if !defined _BYTESWAP_H && !defined _NETINET_IN_H && !defined _ENDIAN_H -# error "Never use <bits/byteswap.h> directly; include <byteswap.h> instead." -#endif - -#include <bits/wordsize.h> - -#ifndef _BITS_BYTESWAP_H -#define _BITS_BYTESWAP_H 1 - -#define __bswap_constant_16(x) \ - ((unsigned short int) ((((x) >> 8) & 0xff) | (((x) & 0xff) << 8))) - -/* Get __bswap_16. */ -#include <bits/byteswap-16.h> - -/* Swap bytes in 32 bit value. */ -#define __bswap_constant_32(x) \ - ((((x) & 0xff000000) >> 24) | (((x) & 0x00ff0000) >> 8) | \ - (((x) & 0x0000ff00) << 8) | (((x) & 0x000000ff) << 24)) - -#if defined __GNUC__ && __GNUC__ >= 2 -# if __WORDSIZE == 64 -# define __bswap_32(x) \ - (__extension__ \ - ({ unsigned int __v, __x = (x); \ - if (__builtin_constant_p (x)) \ - __v = __bswap_constant_32 (__x); \ - else { \ - unsigned int __tmp = (unsigned int) (__x); \ - __asm__ __volatile__ ( \ - "lrv %0,%1" \ - : "=&d" (__v) : "m" (__tmp)); \ - } \ - __v; })) -# else -# define __bswap_32(x) \ - (__extension__ \ - ({ unsigned int __v, __x = (x); \ - if (__builtin_constant_p (x)) \ - __v = __bswap_constant_32 (__x); \ - else { \ - unsigned int __tmp = (unsigned int) (__x); \ - __asm__ __volatile__ ( \ - "la 1,%1\n" \ - "icm %0,8,3(1)\n" \ - "icm %0,4,2(1)\n" \ - "icm %0,2,1(1)\n" \ - "ic %0,0(1)" \ - : "=&d" (__v) : "m" (__tmp) : "1"); \ - } \ - __v; })) -# endif -#else -static __inline unsigned int -__bswap_32 (unsigned int __bsx) -{ - return __bswap_constant_32 (__bsx); -} -#endif - -/* Swap bytes in 64 bit value. */ -#if defined __GNUC__ && __GNUC__ >= 2 -# define __bswap_constant_64(x) \ - (__extension__ ((((x) & 0xff00000000000000ul) >> 56) \ - | (((x) & 0x00ff000000000000ul) >> 40) \ - | (((x) & 0x0000ff0000000000ul) >> 24) \ - | (((x) & 0x000000ff00000000ul) >> 8) \ - | (((x) & 0x00000000ff000000ul) << 8) \ - | (((x) & 0x0000000000ff0000ul) << 24) \ - | (((x) & 0x000000000000ff00ul) << 40) \ - | (((x) & 0x00000000000000fful) << 56))) - -# if __WORDSIZE == 64 -# define __bswap_64(x) \ - (__extension__ \ - ({ unsigned long __w, __x = (x); \ - if (__builtin_constant_p (x)) \ - __w = __bswap_constant_64 (__x); \ - else { \ - unsigned long __tmp = (unsigned long) (__x); \ - __asm__ __volatile__ ( \ - "lrvg %0,%1" \ - : "=&d" (__w) : "m" (__tmp)); \ - } \ - __w; })) -# else -# define __bswap_64(x) \ - __extension__ \ - ({ union { unsigned long long int __ll; \ - unsigned long int __l[2]; } __w, __r; \ - __w.__ll = (x); \ - __r.__l[0] = __bswap_32 (__w.__l[1]); \ - __r.__l[1] = __bswap_32 (__w.__l[0]); \ - __r.__ll; }) -# endif -#else -# define __bswap_constant_64(x) \ - ((((x) & 0xff00000000000000ull) >> 56) \ - | (((x) & 0x00ff000000000000ull) >> 40) \ - | (((x) & 0x0000ff0000000000ull) >> 24) \ - | (((x) & 0x000000ff00000000ull) >> 8) \ - | (((x) & 0x00000000ff000000ull) << 8) \ - | (((x) & 0x0000000000ff0000ull) << 24) \ - | (((x) & 0x000000000000ff00ull) << 40) \ - | (((x) & 0x00000000000000ffull) << 56)) - -__extension__ -static __inline unsigned long long int -__bswap_64 (unsigned long long int __bsx) -{ - return __bswap_constant_64 (__bsx); -} -#endif - -#endif /* _BITS_BYTESWAP_H */ diff --git a/sysdeps/s390/bits/flt-eval-method.h b/sysdeps/s390/bits/flt-eval-method.h new file mode 100644 index 0000000000..b0663e80cc --- /dev/null +++ b/sysdeps/s390/bits/flt-eval-method.h @@ -0,0 +1,24 @@ +/* Define __GLIBC_FLT_EVAL_METHOD. S/390 version. + Copyright (C) 2016-2018 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#ifndef _MATH_H +# error "Never use <bits/flt-eval-method.h> directly; include <math.h> instead." +#endif + +/* This value is used because of a historical mistake. */ +#define __GLIBC_FLT_EVAL_METHOD 1 diff --git a/sysdeps/s390/bits/link.h b/sysdeps/s390/bits/link.h index 2ef7f44225..8d17e9245b 100644 --- a/sysdeps/s390/bits/link.h +++ b/sysdeps/s390/bits/link.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2005-2016 Free Software Foundation, Inc. +/* Copyright (C) 2005-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -19,6 +19,9 @@ # error "Never include <bits/link.h> directly; use <link.h> instead." #endif +#if defined HAVE_S390_VX_ASM_SUPPORT +typedef char La_s390_vr[16]; +#endif #if __ELF_NATIVE_CLASS == 32 @@ -32,6 +35,16 @@ typedef struct La_s390_32_regs uint32_t lr_r6; double lr_fp0; double lr_fp2; +# if defined HAVE_S390_VX_ASM_SUPPORT + La_s390_vr lr_v24; + La_s390_vr lr_v25; + La_s390_vr lr_v26; + La_s390_vr lr_v27; + La_s390_vr lr_v28; + La_s390_vr lr_v29; + La_s390_vr lr_v30; + La_s390_vr lr_v31; +# endif } La_s390_32_regs; /* Return values for calls from PLT on s390-32. */ @@ -40,6 +53,9 @@ typedef struct La_s390_32_retval uint32_t lrv_r2; uint32_t lrv_r3; double lrv_fp0; +# if defined HAVE_S390_VX_ASM_SUPPORT + La_s390_vr lrv_v24; +# endif } La_s390_32_retval; @@ -77,6 +93,16 @@ typedef struct La_s390_64_regs double lr_fp2; double lr_fp4; double lr_fp6; +# if defined HAVE_S390_VX_ASM_SUPPORT + La_s390_vr lr_v24; + La_s390_vr lr_v25; + La_s390_vr lr_v26; + La_s390_vr lr_v27; + La_s390_vr lr_v28; + La_s390_vr lr_v29; + La_s390_vr lr_v30; + La_s390_vr lr_v31; +# endif } La_s390_64_regs; /* Return values for calls from PLT on s390-64. */ @@ -84,6 +110,9 @@ typedef struct La_s390_64_retval { uint64_t lrv_r2; double lrv_fp0; +# if defined HAVE_S390_VX_ASM_SUPPORT + La_s390_vr lrv_v24; +# endif } La_s390_64_retval; diff --git a/sysdeps/s390/bits/mathdef.h b/sysdeps/s390/bits/mathdef.h deleted file mode 100644 index 8c47ade208..0000000000 --- a/sysdeps/s390/bits/mathdef.h +++ /dev/null @@ -1,36 +0,0 @@ -/* Copyright (C) 1997-2016 Free Software Foundation, Inc. - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, see - <http://www.gnu.org/licenses/>. */ - -#if !defined _MATH_H && !defined _COMPLEX_H -# error "Never use <bits/mathdef.h> directly; include <math.h> instead" -#endif - -#if defined __USE_ISOC99 && defined _MATH_H && !defined _MATH_H_MATHDEF -# define _MATH_H_MATHDEF 1 - -/* Normally, there is no long double type and the `float' and `double' - expressions are evaluated as `double'. */ -typedef double float_t; /* `float' expressions are evaluated as - `double'. */ -typedef double double_t; /* `double' expressions are evaluated as - `double'. */ - -/* The values returned by `ilogb' for 0 and NaN respectively. */ -# define FP_ILOGB0 (-2147483647) -# define FP_ILOGBNAN 2147483647 - -#endif /* ISO C99 */ diff --git a/sysdeps/s390/bits/setjmp.h b/sysdeps/s390/bits/setjmp.h index 8d29e8dbd8..07229c292f 100644 --- a/sysdeps/s390/bits/setjmp.h +++ b/sysdeps/s390/bits/setjmp.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2000-2016 Free Software Foundation, Inc. +/* Copyright (C) 2000-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or diff --git a/sysdeps/s390/bits/string.h b/sysdeps/s390/bits/string.h deleted file mode 100644 index 39e0b7fe7c..0000000000 --- a/sysdeps/s390/bits/string.h +++ /dev/null @@ -1,252 +0,0 @@ -/* Optimized, inlined string functions. S/390 version. - Copyright (C) 2000-2016 Free Software Foundation, Inc. - Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com). - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, see - <http://www.gnu.org/licenses/>. */ - -#ifndef _STRING_H -# error "Never use <bits/string.h> directly; include <string.h> instead." -#endif - -/* Use the unaligned string inline ABI. */ -#define _STRING_INLINE_unaligned 1 - -/* We only provide optimizations if the user selects them and if - GNU CC is used. */ -#if !defined __NO_STRING_INLINES && defined __USE_STRING_INLINES \ - && defined __GNUC__ && __GNUC__ >= 2 - -#ifndef __STRING_INLINE -# ifndef __extern_inline -# define __STRING_INLINE inline -# else -# define __STRING_INLINE __extern_inline -# endif -#endif - -#define _HAVE_STRING_ARCH_strlen 1 -#ifndef _FORCE_INLINES -#define strlen(str) __strlen_g ((str)) - -__STRING_INLINE size_t __strlen_g (const char *) __asm__ ("strlen"); - -__STRING_INLINE size_t -__strlen_g (const char *__str) -{ - char *__ptr, *__tmp; - - __ptr = (char *) 0; - __tmp = (char *) __str; - __asm__ __volatile__ (" la 0,0\n" - "0: srst %0,%1\n" - " jo 0b\n" - : "+&a" (__ptr), "+&a" (__tmp) : - : "cc", "memory", "0" ); - return (size_t) (__ptr - __str); -} -#endif - -/* Copy SRC to DEST. */ -#define _HAVE_STRING_ARCH_strcpy 1 -#ifndef _FORCE_INLINES -#define strcpy(dest, src) __strcpy_g ((dest), (src)) - -__STRING_INLINE char *__strcpy_g (char *, const char *) __asm__ ("strcpy"); - -__STRING_INLINE char * -__strcpy_g (char *__dest, const char *__src) -{ - char *tmp = __dest; - - __asm__ __volatile__ (" la 0,0\n" - "0: mvst %0,%1\n" - " jo 0b" - : "+&a" (__dest), "+&a" (__src) : - : "cc", "memory", "0" ); - return tmp; -} -#endif - -#define _HAVE_STRING_ARCH_strncpy 1 -#ifndef _FORCE_INLINES -#define strncpy(dest, src, n) __strncpy_g ((dest), (src), (n)) - -__STRING_INLINE char *__strncpy_g (char *, const char *, size_t) - __asm__ ("strncpy"); - -__STRING_INLINE char * -__strncpy_g (char *__dest, const char *__src, size_t __n) -{ - char *__ret = __dest; - char *__ptr; - size_t __diff; - - if (__n > 0) { - __diff = (size_t) (__dest - __src); - __ptr = (char *) __src; - __asm__ __volatile__ (" j 1f\n" - "0: la %0,1(%0)\n" - "1: icm 0,1,0(%0)\n" - " stc 0,0(%2,%0)\n" - " jz 3f\n" -#if defined(__s390x__) - " brctg %1,0b\n" -#else - " brct %1,0b\n" -#endif - " j 4f\n" - "2: la %0,1(%0)\n" - " stc 0,0(%2,%0)\n" -#if defined(__s390x__) - "3: brctg %1,2b\n" -#else - "3: brct %1,2b\n" -#endif - "4:" - : "+&a" (__ptr), "+&a" (__n) : "a" (__diff) - : "cc", "memory", "0" ); - } - return __ret; -} -#endif - -/* Append SRC onto DEST. */ -#define _HAVE_STRING_ARCH_strcat 1 -#ifndef _FORCE_INLINES -#define strcat(dest, src) __strcat_g ((dest), (src)) - -__STRING_INLINE char *__strcat_g (char *, const char *) __asm__ ("strcat"); - -__STRING_INLINE char * -__strcat_g (char *__dest, const char *__src) -{ - char *__ret = __dest; - char *__ptr, *__tmp; - - /* Move __ptr to the end of __dest. */ - __ptr = (char *) 0; - __tmp = __dest; - __asm__ __volatile__ (" la 0,0\n" - "0: srst %0,%1\n" - " jo 0b\n" - : "+&a" (__ptr), "+&a" (__tmp) : - : "cc", "0" ); - - /* Now do the copy. */ - __asm__ __volatile__ (" la 0,0\n" - "0: mvst %0,%1\n" - " jo 0b" - : "+&a" (__ptr), "+&a" (__src) : - : "cc", "memory", "0" ); - return __ret; -} -#endif - -/* Append no more than N characters from SRC onto DEST. */ -#define _HAVE_STRING_ARCH_strncat 1 -#ifndef _FORCE_INLINES -#define strncat(dest, src, n) __strncat_g ((dest), (src), (n)) - -__STRING_INLINE char *__strncat_g (char *, const char *, size_t) - __asm__ ("strncat"); - -__STRING_INLINE char * -__strncat_g (char *__dest, const char *__src, size_t __n) -{ - char *__ret = __dest; - char *__ptr, *__tmp; - size_t __diff; - - if (__n > 0) { - /* Move __ptr to the end of __dest. */ - __ptr = (char *) 0; - __tmp = __dest; - __asm__ __volatile__ (" la 0,0\n" - "0: srst %0,%1\n" - " jo 0b\n" - : "+&a" (__ptr), "+&a" (__tmp) : - : "cc", "memory", "0" ); - - __diff = (size_t) (__ptr - __src); - __tmp = (char *) __src; - __asm__ __volatile__ (" j 1f\n" - "0: la %0,1(%0)\n" - "1: icm 0,1,0(%0)\n" - " stc 0,0(%2,%0)\n" - " jz 2f\n" -#if defined(__s390x__) - " brctg %1,0b\n" -#else - " brct %1,0b\n" -#endif - " slr 0,0\n" - " stc 0,1(%2,%0)\n" - "2:" - : "+&a" (__tmp), "+&a" (__n) : "a" (__diff) - : "cc", "memory", "0" ); - - } - return __ret; -} -#endif - -/* Search N bytes of S for C. */ -#define _HAVE_STRING_ARCH_memchr 1 -#ifndef _FORCE_INLINES -__STRING_INLINE void * -memchr (const void *__str, int __c, size_t __n) -{ - char *__ptr, *__tmp; - - __tmp = (char *) __str; - __ptr = (char *) __tmp + __n; - __asm__ __volatile__ (" lhi 0,0xff\n" - " nr 0,%2\n" - "0: srst %0,%1\n" - " jo 0b\n" - " brc 13,1f\n" - " la %0,0\n" - "1:" - : "+&a" (__ptr), "+&a" (__tmp) : "d" (__c) - : "cc", "memory", "0" ); - return __ptr; -} -#endif - -/* Compare S1 and S2. */ -#define _HAVE_STRING_ARCH_strcmp 1 -#ifndef _FORCE_INLINES -__STRING_INLINE int -strcmp (const char *__s1, const char *__s2) -{ - char *__p1, *__p2; - int __ret; - - __p1 = (char *) __s1; - __p2 = (char *) __s2; - __asm__ __volatile__ (" slr 0,0\n" - "0: clst %1,%2\n" - " jo 0b\n" - " ipm %0\n" - " srl %0,28" - : "=d" (__ret), "+&a" (__p1), "+&a" (__p2) : - : "cc", "memory", "0" ); - __ret = (__ret == 0) ? 0 : (__ret == 1) ? -1 : 1; - return __ret; -} -#endif - -#endif /* Use string inlines && GNU CC. */ diff --git a/sysdeps/s390/bits/xtitypes.h b/sysdeps/s390/bits/xtitypes.h index 3c9606a636..462b126d11 100644 --- a/sysdeps/s390/bits/xtitypes.h +++ b/sysdeps/s390/bits/xtitypes.h @@ -1,5 +1,5 @@ /* bits/xtitypes.h -- Define some types used by <bits/stropts.h>. S390/S390x - Copyright (C) 2002-2016 Free Software Foundation, Inc. + Copyright (C) 2002-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or diff --git a/sysdeps/s390/configure b/sysdeps/s390/configure index 0fa54c3061..74b415f2ab 100644 --- a/sysdeps/s390/configure +++ b/sysdeps/s390/configure @@ -4,71 +4,6 @@ $as_echo "#define PI_STATIC_AND_HIDDEN 1" >>confdefs.h -for ac_prog in $AS -do - # Extract the first word of "$ac_prog", so it can be a program name with args. -set dummy $ac_prog; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_AS+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$AS"; then - ac_cv_prog_AS="$AS" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_AS="$ac_prog" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -AS=$ac_cv_prog_AS -if test -n "$AS"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AS" >&5 -$as_echo "$AS" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - - test -n "$AS" && break -done - -if test -z "$AS"; then - ac_verc_fail=yes -else - # Found it, now check the version. - { $as_echo "$as_me:${as_lineno-$LINENO}: checking version of $AS" >&5 -$as_echo_n "checking version of $AS... " >&6; } - ac_prog_version=`$AS --version 2>&1 | sed -n 's/^.*GNU assembler.* \([0-9]*\.[0-9.]*\).*$/\1/p'` - case $ac_prog_version in - '') ac_prog_version="v. ?.??, bad"; ac_verc_fail=yes;; - 2.2[4-9]*|2.[3-9][0-9]*|[3-9].*|[1-9][0-9]*) - ac_prog_version="$ac_prog_version, ok"; ac_verc_fail=no;; - *) ac_prog_version="$ac_prog_version, bad"; ac_verc_fail=yes;; - - esac - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_prog_version" >&5 -$as_echo "$ac_prog_version" >&6; } -fi -if test $ac_verc_fail = yes; then - critic_missing="$critic_missing The program AS is required in version >= 2.24 for target S390." -fi - - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for __builtin_tbegin" >&5 $as_echo_n "checking for __builtin_tbegin... " >&6; } if ${libc_cv_gcc_builtin_tbegin+:} false; then : @@ -100,7 +35,7 @@ fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $libc_cv_gcc_builtin_tbegin" >&5 $as_echo "$libc_cv_gcc_builtin_tbegin" >&6; } -if test "$enable_lock_elision" = yes && test "$libc_cv_gcc_builtin_tbegin" = no ; then +if test "$libc_cv_gcc_builtin_tbegin" = no ; then critic_missing="$critic_missing The used GCC has no support for __builtin_tbegin, which is needed for lock-elision on target S390." fi @@ -144,6 +79,74 @@ else $as_echo "$as_me: WARNING: Use binutils with vector-support in order to use optimized implementations." >&2;} fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for S390 vector support in gcc" >&5 +$as_echo_n "checking for S390 vector support in gcc... " >&6; } +if ${libc_cv_gcc_s390_vx+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat > conftest.c <<\EOF +void testvecclobber () +{ + __asm__ ("" : : : "v16"); +} +EOF +if { ac_try='${CC-cc} --shared conftest.c -o conftest.o &> /dev/null' + { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5 + (eval $ac_try) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; } ; +then + libc_cv_gcc_s390_vx=yes +else + libc_cv_gcc_s390_vx=no +fi +rm -f conftest* +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libc_cv_gcc_s390_vx" >&5 +$as_echo "$libc_cv_gcc_s390_vx" >&6; } + +if test "$libc_cv_gcc_s390_vx" = yes ; +then + $as_echo "#define HAVE_S390_VX_GCC_SUPPORT 1" >>confdefs.h + +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for S390 z196 zarch instruction support as default" >&5 +$as_echo_n "checking for S390 z196 zarch instruction support as default... " >&6; } +if ${libc_cv_asm_s390_min_z196_zarch+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat > conftest.c <<\EOF +float testinsn (double e) +{ + float d; + __asm__ ("ledbra %0,5,%1,4" : "=f" (d) : "f" (e) ); + return d; +} +EOF +if { ac_try='${CC-cc} $CFLAGS $CPPFLAGS $LDFLAGS --shared conftest.c + -o conftest.o &> /dev/null' + { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5 + (eval $ac_try) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; } ; +then + libc_cv_asm_s390_min_z196_zarch=yes +else + libc_cv_asm_s390_min_z196_zarch=no +fi +rm -f conftest* +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libc_cv_asm_s390_min_z196_zarch" >&5 +$as_echo "$libc_cv_asm_s390_min_z196_zarch" >&6; } + +if test "$libc_cv_asm_s390_min_z196_zarch" = yes ; +then + $as_echo "#define HAVE_S390_MIN_Z196_ZARCH_ASM_SUPPORT 1" >>confdefs.h + +fi test -n "$critic_missing" && as_fn_error $? " *** $critic_missing" "$LINENO" 5 diff --git a/sysdeps/s390/configure.ac b/sysdeps/s390/configure.ac index 4da134e9a0..1cdb021282 100644 --- a/sysdeps/s390/configure.ac +++ b/sysdeps/s390/configure.ac @@ -5,12 +5,6 @@ dnl It is always possible to access static and hidden symbols in an dnl position independent way. AC_DEFINE(PI_STATIC_AND_HIDDEN) -dnl Accept as 2.24 or newer. -AC_CHECK_PROG_VER(AS, $AS, --version, - [GNU assembler.* \([0-9]*\.[0-9.]*\)], - [2.2[4-9]*|2.[3-9][0-9]*|[3-9].*|[1-9][0-9]*], critic_missing="$critic_missing The program AS is required in version >= 2.24 for target S390.") - - AC_CACHE_CHECK(for __builtin_tbegin, libc_cv_gcc_builtin_tbegin, [dnl cat > conftest.c <<\EOF #include <htmintrin.h> @@ -32,7 +26,7 @@ else fi rm -f conftest* ]) -if test "$enable_lock_elision" = yes && test "$libc_cv_gcc_builtin_tbegin" = no ; then +if test "$libc_cv_gcc_builtin_tbegin" = no ; then critic_missing="$critic_missing The used GCC has no support for __builtin_tbegin, which is needed for lock-elision on target S390." fi @@ -64,6 +58,53 @@ else AC_MSG_WARN([Use binutils with vector-support in order to use optimized implementations.]) fi +AC_CACHE_CHECK(for S390 vector support in gcc, libc_cv_gcc_s390_vx, [dnl +cat > conftest.c <<\EOF +void testvecclobber () +{ + __asm__ ("" : : : "v16"); +} +EOF +dnl +dnl test, if gcc supports S390 vector registers as clobber in inline assembly +if AC_TRY_COMMAND([${CC-cc} --shared conftest.c -o conftest.o &> /dev/null]) ; +then + libc_cv_gcc_s390_vx=yes +else + libc_cv_gcc_s390_vx=no +fi +rm -f conftest* ]) + +if test "$libc_cv_gcc_s390_vx" = yes ; +then + AC_DEFINE(HAVE_S390_VX_GCC_SUPPORT) +fi + +AC_CACHE_CHECK(for S390 z196 zarch instruction support as default, + libc_cv_asm_s390_min_z196_zarch, [dnl +cat > conftest.c <<\EOF +float testinsn (double e) +{ + float d; + __asm__ ("ledbra %0,5,%1,4" : "=f" (d) : "f" (e) ); + return d; +} +EOF +dnl +dnl test, if assembler supports S390 z196 zarch instructions as default +if AC_TRY_COMMAND([${CC-cc} $CFLAGS $CPPFLAGS $LDFLAGS --shared conftest.c + -o conftest.o &> /dev/null]) ; +then + libc_cv_asm_s390_min_z196_zarch=yes +else + libc_cv_asm_s390_min_z196_zarch=no +fi +rm -f conftest* ]) + +if test "$libc_cv_asm_s390_min_z196_zarch" = yes ; +then + AC_DEFINE(HAVE_S390_MIN_Z196_ZARCH_ASM_SUPPORT) +fi test -n "$critic_missing" && AC_MSG_ERROR([ *** $critic_missing]) diff --git a/sysdeps/s390/dl-irel.h b/sysdeps/s390/dl-irel.h index 38c5761a6e..d8ba7ba427 100644 --- a/sysdeps/s390/dl-irel.h +++ b/sysdeps/s390/dl-irel.h @@ -1,6 +1,6 @@ /* Machine-dependent ELF indirect relocation inline functions. Version for S/390 32 and 64 bit. - Copyright (C) 2012-2016 Free Software Foundation, Inc. + Copyright (C) 2012-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or diff --git a/sysdeps/s390/dl-procinfo.c b/sysdeps/s390/dl-procinfo.c index 22c4cf7a01..86c964caff 100644 --- a/sysdeps/s390/dl-procinfo.c +++ b/sysdeps/s390/dl-procinfo.c @@ -1,5 +1,5 @@ /* Data for s390 version of processor capability information. - Copyright (C) 2006-2016 Free Software Foundation, Inc. + Copyright (C) 2006-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Martin Schwidefsky <schwidefsky@de.ibm.com>, 2006. @@ -46,11 +46,12 @@ #if !defined PROCINFO_DECL && defined SHARED ._dl_s390_cap_flags #else -PROCINFO_CLASS const char _dl_s390_cap_flags[12][9] +PROCINFO_CLASS const char _dl_s390_cap_flags[15][9] #endif #ifndef PROCINFO_DECL = { - "esan3", "zarch", "stfle", "msa", "ldisp", "eimm", "dfp", "edat", "etf3eh", "highgprs", "te", "vx" + "esan3", "zarch", "stfle", "msa", "ldisp", "eimm", "dfp", "edat", "etf3eh", + "highgprs", "te", "vx", "vxd", "vxe", "gs" } #endif #if !defined SHARED || defined PROCINFO_DECL @@ -62,11 +63,11 @@ PROCINFO_CLASS const char _dl_s390_cap_flags[12][9] #if !defined PROCINFO_DECL && defined SHARED ._dl_s390_platforms #else -PROCINFO_CLASS const char _dl_s390_platforms[8][7] +PROCINFO_CLASS const char _dl_s390_platforms[9][7] #endif #ifndef PROCINFO_DECL = { - "g5", "z900", "z990", "z9-109", "z10", "z196", "zEC12", "z13" + "g5", "z900", "z990", "z9-109", "z10", "z196", "zEC12", "z13", "z14" } #endif #if !defined SHARED || defined PROCINFO_DECL diff --git a/sysdeps/s390/dl-procinfo.h b/sysdeps/s390/dl-procinfo.h index 4ae276e4ed..b0383bfb4c 100644 --- a/sysdeps/s390/dl-procinfo.h +++ b/sysdeps/s390/dl-procinfo.h @@ -1,5 +1,5 @@ /* s390 version of processor capability information handling macros. - Copyright (C) 2006-2016 Free Software Foundation, Inc. + Copyright (C) 2006-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Martin Schwidefsky <schwidefsky@de.ibm.com>, 2006. @@ -21,9 +21,9 @@ #define _DL_PROCINFO_H 1 #include <ldsodefs.h> -#define _DL_HWCAP_COUNT 12 +#define _DL_HWCAP_COUNT 15 -#define _DL_PLATFORMS_COUNT 8 +#define _DL_PLATFORMS_COUNT 9 /* The kernel provides up to 32 capability bits with elf_hwcap. */ #define _DL_FIRST_PLATFORM 32 @@ -51,6 +51,9 @@ enum HWCAP_S390_HIGH_GPRS = 1 << 9, HWCAP_S390_TE = 1 << 10, HWCAP_S390_VX = 1 << 11, + HWCAP_S390_VXD = 1 << 12, + HWCAP_S390_VXE = 1 << 13, + HWCAP_S390_GS = 1 << 14, }; #define HWCAP_IMPORTANT (HWCAP_S390_ZARCH | HWCAP_S390_LDISP \ @@ -66,13 +69,6 @@ _dl_hwcap_string (int idx) return GLRO(dl_s390_cap_flags)[idx]; }; -static inline const char * -__attribute__ ((unused)) -_dl_platform_string (int idx) -{ - return GLRO(dl_s390_platforms)[idx - _DL_FIRST_PLATFORM]; -}; - static inline int __attribute__ ((unused, always_inline)) _dl_string_hwcap (const char *str) diff --git a/sysdeps/s390/dl-tls.h b/sysdeps/s390/dl-tls.h index 503048a622..7a843f29ad 100644 --- a/sysdeps/s390/dl-tls.h +++ b/sysdeps/s390/dl-tls.h @@ -1,5 +1,5 @@ /* Thread-local storage handling in the ELF dynamic linker. s390 version. - Copyright (C) 2003-2016 Free Software Foundation, Inc. + Copyright (C) 2003-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -102,6 +102,3 @@ extern void *__tls_get_addr_internal (tls_index *ti); + (unsigned long) __builtin_thread_pointer (); }) #endif - -/* Value used for dtv entries for which the allocation is delayed. */ -#define TLS_DTV_UNALLOCATED ((void *) -1l) diff --git a/sysdeps/s390/ffs.c b/sysdeps/s390/ffs.c index 7808185569..d46eec8e48 100644 --- a/sysdeps/s390/ffs.c +++ b/sysdeps/s390/ffs.c @@ -1,6 +1,6 @@ /* ffs -- find first set bit in a word, counted from least significant end. S/390 version. - Copyright (C) 2000-2016 Free Software Foundation, Inc. + Copyright (C) 2000-2018 Free Software Foundation, Inc. Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com). This file is part of the GNU C Library. diff --git a/sysdeps/s390/fix-fp-int-convert-overflow.h b/sysdeps/s390/fix-fp-int-convert-overflow.h index 61279edc19..b60d4c54ac 100644 --- a/sysdeps/s390/fix-fp-int-convert-overflow.h +++ b/sysdeps/s390/fix-fp-int-convert-overflow.h @@ -1,5 +1,5 @@ /* Fix for conversion of floating point to integer overflow. S390 version. - Copyright (C) 2016 Free Software Foundation, Inc. + Copyright (C) 2016-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or diff --git a/sysdeps/s390/fpu/bits/fenv.h b/sysdeps/s390/fpu/bits/fenv.h index 6de74b9939..079e71f3a5 100644 --- a/sysdeps/s390/fpu/bits/fenv.h +++ b/sysdeps/s390/fpu/bits/fenv.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2000-2016 Free Software Foundation, Inc. +/* Copyright (C) 2000-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Denis Joseph Barrow <djbarrow@de.ibm.com>. @@ -90,3 +90,11 @@ typedef struct /* Floating-point environment where none of the exceptions are masked. */ # define FE_NOMASK_ENV ((const fenv_t *) -2) #endif + +#if __GLIBC_USE (IEC_60559_BFP_EXT) +/* Type representing floating-point control modes. */ +typedef unsigned int femode_t; + +/* Default floating-point control modes. */ +# define FE_DFL_MODE ((const femode_t *) -1L) +#endif diff --git a/sysdeps/s390/fpu/bits/mathinline.h b/sysdeps/s390/fpu/bits/mathinline.h deleted file mode 100644 index 7c09a5c7da..0000000000 --- a/sysdeps/s390/fpu/bits/mathinline.h +++ /dev/null @@ -1,100 +0,0 @@ -/* Inline math functions for s390. - Copyright (C) 2004-2016 Free Software Foundation, Inc. - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, see - <http://www.gnu.org/licenses/>. */ - -#ifndef _MATH_H -# error "Never use <bits/mathinline.h> directly; include <math.h> instead." -#endif - -#ifndef __extern_inline -# define __MATH_INLINE __inline -#else -# define __MATH_INLINE __extern_inline -#endif - -#if (!defined __NO_MATH_INLINES || defined __LIBC_INTERNAL_MATH_INLINES) \ - && defined __OPTIMIZE__ - -#ifdef __USE_ISOC99 - -/* Test for negative number. Used in the signbit() macro. */ -__MATH_INLINE int -__NTH (__signbitf (float __x)) -{ - __extension__ union { float __f; int __i; } __u = { __f: __x }; - return __u.__i < 0; -} - -__MATH_INLINE int -__NTH (__signbit (double __x)) -{ - __extension__ union { double __d; long __i; } __u = { __d: __x }; - return __u.__i < 0; -} - -# ifndef __NO_LONG_DOUBLE_MATH -__MATH_INLINE int -__NTH (__signbitl (long double __x)) -{ - __extension__ union { long double __l; int __i[4]; } __u = { __l: __x }; - return __u.__i[0] < 0; -} -# else -__MATH_INLINE int -__NTH (__signbitl (long double __x)) -{ - return __signbit ((double) __x); -} -# endif - -#endif /* C99 */ - -/* This code is used internally in the GNU libc. */ -#ifdef __LIBC_INTERNAL_MATH_INLINES - -__MATH_INLINE double -__NTH (__ieee754_sqrt (double x)) -{ - double res; - - __asm__ ( "sqdbr %0,%1" : "=f" (res) : "f" (x) ); - return res; -} - -__MATH_INLINE float -__NTH (__ieee754_sqrtf (float x)) -{ - float res; - - __asm__ ( "sqebr %0,%1" : "=f" (res) : "f" (x) ); - return res; -} - -# if !defined __NO_LONG_DOUBLE_MATH -__MATH_INLINE long double -__NTH (sqrtl (long double __x)) -{ - long double res; - - __asm__ ( "sqxbr %0,%1" : "=f" (res) : "f" (__x) ); - return res; -} -# endif /* !__NO_LONG_DOUBLE_MATH */ - -#endif /* __LIBC_INTERNAL_MATH_INLINES */ - -#endif /* __NO_MATH_INLINES */ diff --git a/sysdeps/s390/fpu/e_sqrt.c b/sysdeps/s390/fpu/e_sqrt.c index efdb2865b9..b8b362a6bb 100644 --- a/sysdeps/s390/fpu/e_sqrt.c +++ b/sysdeps/s390/fpu/e_sqrt.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2004-2016 Free Software Foundation, Inc. +/* Copyright (C) 2004-2018 Free Software Foundation, Inc. Contributed by Martin Schwidefsky <schwidefsky@de.ibm.com>. This file is part of the GNU C Library. diff --git a/sysdeps/s390/fpu/e_sqrtf.c b/sysdeps/s390/fpu/e_sqrtf.c index 38160acc12..2c67e3e656 100644 --- a/sysdeps/s390/fpu/e_sqrtf.c +++ b/sysdeps/s390/fpu/e_sqrtf.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2004-2016 Free Software Foundation, Inc. +/* Copyright (C) 2004-2018 Free Software Foundation, Inc. Contributed by Martin Schwidefsky <schwidefsky@de.ibm.com>. This file is part of the GNU C Library. diff --git a/sysdeps/s390/fpu/e_sqrtl.c b/sysdeps/s390/fpu/e_sqrtl.c index add859a3a8..209242b516 100644 --- a/sysdeps/s390/fpu/e_sqrtl.c +++ b/sysdeps/s390/fpu/e_sqrtl.c @@ -1,5 +1,5 @@ /* Square root. S/390 FPU version. - Copyright (C) 2004-2016 Free Software Foundation, Inc. + Copyright (C) 2004-2018 Free Software Foundation, Inc. Contributed by Martin Schwidefsky <schwidefsky@de.ibm.com>. This file is part of the GNU C Library. diff --git a/sysdeps/s390/fpu/fclrexcpt.c b/sysdeps/s390/fpu/fclrexcpt.c index b19899a2eb..27b7255a79 100644 --- a/sysdeps/s390/fpu/fclrexcpt.c +++ b/sysdeps/s390/fpu/fclrexcpt.c @@ -1,5 +1,5 @@ /* Clear given exceptions in current floating-point environment. - Copyright (C) 2000-2016 Free Software Foundation, Inc. + Copyright (C) 2000-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or diff --git a/sysdeps/s390/fpu/fedisblxcpt.c b/sysdeps/s390/fpu/fedisblxcpt.c index d3b49789b9..fc0ac27cc3 100644 --- a/sysdeps/s390/fpu/fedisblxcpt.c +++ b/sysdeps/s390/fpu/fedisblxcpt.c @@ -1,5 +1,5 @@ /* Disable floating-point exceptions. - Copyright (C) 2000-2016 Free Software Foundation, Inc. + Copyright (C) 2000-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Denis Joseph Barrow (djbarrow@de.ibm.com). diff --git a/sysdeps/s390/fpu/feenablxcpt.c b/sysdeps/s390/fpu/feenablxcpt.c index b9aab5976a..067d8e9fa3 100644 --- a/sysdeps/s390/fpu/feenablxcpt.c +++ b/sysdeps/s390/fpu/feenablxcpt.c @@ -1,5 +1,5 @@ /* Enable floating-point exceptions. - Copyright (C) 2000-2016 Free Software Foundation, Inc. + Copyright (C) 2000-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Denis Joseph Barrow (djbarrow@de.ibm.com). diff --git a/sysdeps/s390/fpu/fegetenv.c b/sysdeps/s390/fpu/fegetenv.c index 3b912b66cf..709fbd9c19 100644 --- a/sysdeps/s390/fpu/fegetenv.c +++ b/sysdeps/s390/fpu/fegetenv.c @@ -1,5 +1,5 @@ /* Store current floating-point environment. - Copyright (C) 2000-2016 Free Software Foundation, Inc. + Copyright (C) 2000-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Denis Joseph Barrow (djbarrow@de.ibm.com). diff --git a/sysdeps/s390/fpu/fegetexcept.c b/sysdeps/s390/fpu/fegetexcept.c index dc5033c550..0fd39f14e4 100644 --- a/sysdeps/s390/fpu/fegetexcept.c +++ b/sysdeps/s390/fpu/fegetexcept.c @@ -1,5 +1,5 @@ /* Get enabled floating-point exceptions. - Copyright (C) 2000-2016 Free Software Foundation, Inc. + Copyright (C) 2000-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Denis Joseph Barrow (djbarrow@de.ibm.com). diff --git a/sysdeps/s390/nptl/pthread_spin_trylock.c b/sysdeps/s390/fpu/fegetmode.c index 4c00e0833f..d6a5feff3d 100644 --- a/sysdeps/s390/nptl/pthread_spin_trylock.c +++ b/sysdeps/s390/fpu/fegetmode.c @@ -1,6 +1,6 @@ -/* Copyright (C) 2003-2016 Free Software Foundation, Inc. +/* Store current floating-point control modes. S/390 version. + Copyright (C) 2016-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. - Contributed by Martin Schwidefsky <schwidefsky@de.ibm.com>, 2003. The GNU C Library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public @@ -16,17 +16,12 @@ License along with the GNU C Library; if not, see <http://www.gnu.org/licenses/>. */ -#include <errno.h> -#include "pthreadP.h" +#include <fenv.h> +#include <fpu_control.h> int -pthread_spin_trylock (pthread_spinlock_t *lock) +fegetmode (femode_t *modep) { - int old; - - __asm__ __volatile__ ("cs %0,%3,%1" - : "=d" (old), "=Q" (*lock) - : "0" (0), "d" (1), "m" (*lock) : "cc" ); - - return old != 0 ? EBUSY : 0; + _FPU_GETCW (*modep); + return 0; } diff --git a/sysdeps/s390/fpu/fegetround.c b/sysdeps/s390/fpu/fegetround.c index bca8517577..3c38bc9189 100644 --- a/sysdeps/s390/fpu/fegetround.c +++ b/sysdeps/s390/fpu/fegetround.c @@ -1,5 +1,5 @@ /* Return current rounding direction. - Copyright (C) 2000-2016 Free Software Foundation, Inc. + Copyright (C) 2000-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Denis Joseph Barrow (djbarrow@de.ibm.com). diff --git a/sysdeps/s390/fpu/feholdexcpt.c b/sysdeps/s390/fpu/feholdexcpt.c index 2700028016..5daee5675d 100644 --- a/sysdeps/s390/fpu/feholdexcpt.c +++ b/sysdeps/s390/fpu/feholdexcpt.c @@ -1,5 +1,5 @@ /* Store current floating-point environment and clear exceptions. - Copyright (C) 2000-2016 Free Software Foundation, Inc. + Copyright (C) 2000-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Denis Joseph Barrow (djbarrow@de.ibm.com). @@ -24,7 +24,7 @@ int __feholdexcept (fenv_t *envp) { fexcept_t fpc; /* Store the environment. */ - fegetenv (envp); + __fegetenv (envp); /* Clear the current sticky bits as more than one exception may be generated. */ fpc = envp->__fpc & ~(FPC_FLAGS_MASK | FPC_DXC_MASK); diff --git a/sysdeps/s390/fpu/fenv_libc.h b/sysdeps/s390/fpu/fenv_libc.h index dff8fd92e5..0b4b7aad99 100644 --- a/sysdeps/s390/fpu/fenv_libc.h +++ b/sysdeps/s390/fpu/fenv_libc.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2000-2016 Free Software Foundation, Inc. +/* Copyright (C) 2000-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Denis Joseph Barrow (djbarrow@de.ibm.com). diff --git a/sysdeps/s390/fpu/fesetenv.c b/sysdeps/s390/fpu/fesetenv.c index 694a538c1e..c6c275d79d 100644 --- a/sysdeps/s390/fpu/fesetenv.c +++ b/sysdeps/s390/fpu/fesetenv.c @@ -1,5 +1,5 @@ /* Install given floating-point environment. - Copyright (C) 2000-2016 Free Software Foundation, Inc. + Copyright (C) 2000-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Denis Joseph Barrow (djbarrow@de.ibm.com). @@ -20,8 +20,6 @@ #include <fenv_libc.h> #include <fpu_control.h> #include <stddef.h> -#include <asm/ptrace.h> -#include <sys/ptrace.h> #include <unistd.h> int diff --git a/sysdeps/s390/nptl/pthread_spin_lock.c b/sysdeps/s390/fpu/fesetexcept.c index def6a24275..e41853e25e 100644 --- a/sysdeps/s390/nptl/pthread_spin_lock.c +++ b/sysdeps/s390/fpu/fesetexcept.c @@ -1,6 +1,6 @@ -/* Copyright (C) 2003-2016 Free Software Foundation, Inc. +/* Set given exception flags. S/390 version. + Copyright (C) 2016-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. - Contributed by Martin Schwidefsky <schwidefsky@de.ibm.com>, 2003. The GNU C Library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public @@ -16,17 +16,18 @@ License along with the GNU C Library; if not, see <http://www.gnu.org/licenses/>. */ -#include "pthreadP.h" +#include <fenv.h> +#include <fpu_control.h> +#include <fenv_libc.h> int -pthread_spin_lock (pthread_spinlock_t *lock) +fesetexcept (int excepts) { - int oldval; + fexcept_t temp; + + _FPU_GETCW (temp); + temp |= (excepts & FE_ALL_EXCEPT) << FPC_FLAGS_SHIFT; + _FPU_SETCW (temp); - __asm__ __volatile__ ("0: lhi %0,0\n" - " cs %0,%2,%1\n" - " jl 0b" - : "=&d" (oldval), "=Q" (*lock) - : "d" (1), "m" (*lock) : "cc" ); return 0; } diff --git a/sysdeps/s390/nptl/pthread_spin_unlock.c b/sysdeps/s390/fpu/fesetmode.c index 0dcc2d0cb5..37ede8f115 100644 --- a/sysdeps/s390/nptl/pthread_spin_unlock.c +++ b/sysdeps/s390/fpu/fesetmode.c @@ -1,6 +1,6 @@ -/* Copyright (C) 2003-2016 Free Software Foundation, Inc. +/* Install given floating-point control modes. S/390 version. + Copyright (C) 2016-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. - Contributed by Martin Schwidefsky <schwidefsky@de.ibm.com>, 2003. The GNU C Library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public @@ -16,17 +16,24 @@ License along with the GNU C Library; if not, see <http://www.gnu.org/licenses/>. */ -/* Ugly hack to avoid the declaration of pthread_spin_init. */ -#define pthread_spin_init pthread_spin_init_XXX -#include "pthreadP.h" -#undef pthread_spin_init +#include <fenv.h> +#include <fpu_control.h> +#include <fenv_libc.h> + +#define FPC_STATUS (FPC_FLAGS_MASK | FPC_DXC_MASK) int -pthread_spin_unlock (pthread_spinlock_t *lock) +fesetmode (const femode_t *modep) { - __asm__ __volatile__ (" xc %O0(4,%R0),%0\n" - " bcr 15,0" - : "=Q" (*lock) : "m" (*lock) : "cc" ); + fpu_control_t fpc; + + _FPU_GETCW (fpc); + fpc &= FPC_STATUS; + if (modep == FE_DFL_MODE) + fpc |= _FPU_DEFAULT; + else + fpc |= *modep & ~FPC_STATUS; + _FPU_SETCW (fpc); + return 0; } -strong_alias (pthread_spin_unlock, pthread_spin_init) diff --git a/sysdeps/s390/fpu/fesetround.c b/sysdeps/s390/fpu/fesetround.c index 5b15a1973d..d8a84d2c96 100644 --- a/sysdeps/s390/fpu/fesetround.c +++ b/sysdeps/s390/fpu/fesetround.c @@ -1,5 +1,5 @@ /* Set current rounding direction. - Copyright (C) 2000-2016 Free Software Foundation, Inc. + Copyright (C) 2000-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Denis Joseph Barrow (djbarrow@de.ibm.com). diff --git a/sysdeps/s390/fpu/fetestexceptflag.c b/sysdeps/s390/fpu/fetestexceptflag.c new file mode 100644 index 0000000000..784d356f7b --- /dev/null +++ b/sysdeps/s390/fpu/fetestexceptflag.c @@ -0,0 +1,31 @@ +/* Test exception in saved exception state. S/390 version. + Copyright (C) 2016-2018 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <fenv.h> +#include <fenv_libc.h> + +int +fetestexceptflag (const fexcept_t *flagp, int excepts) +{ + /* As *flagp is obtained by an earlier call of fegetexceptflag the + bits 0-5 of dxc-byte are either zero or correspond to the + flag-bits. Evaluate flags and last dxc-exception-code. */ + return (((*flagp >> FPC_FLAGS_SHIFT) | (*flagp >> FPC_DXC_SHIFT)) + & excepts + & FE_ALL_EXCEPT); +} diff --git a/sysdeps/s390/fpu/feupdateenv.c b/sysdeps/s390/fpu/feupdateenv.c index 1aad35ec13..4888e1a864 100644 --- a/sysdeps/s390/fpu/feupdateenv.c +++ b/sysdeps/s390/fpu/feupdateenv.c @@ -1,5 +1,5 @@ /* Install given floating-point environment and raise exceptions. - Copyright (C) 2000-2016 Free Software Foundation, Inc. + Copyright (C) 2000-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Denis Joseph Barrow (djbarrow@de.ibm.com). diff --git a/sysdeps/s390/fpu/fgetexcptflg.c b/sysdeps/s390/fpu/fgetexcptflg.c index 09b7cfd99c..2a0f6dc77c 100644 --- a/sysdeps/s390/fpu/fgetexcptflg.c +++ b/sysdeps/s390/fpu/fgetexcptflg.c @@ -1,5 +1,5 @@ /* Store current representation for exceptions. - Copyright (C) 2000-2016 Free Software Foundation, Inc. + Copyright (C) 2000-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Denis Joseph Barrow (djbarrow@de.ibm.com). diff --git a/sysdeps/s390/fpu/fix-fp-int-compare-invalid.h b/sysdeps/s390/fpu/fix-fp-int-compare-invalid.h new file mode 100644 index 0000000000..2ad36817c7 --- /dev/null +++ b/sysdeps/s390/fpu/fix-fp-int-compare-invalid.h @@ -0,0 +1,36 @@ +/* Fix for missing "invalid" exceptions from floating-point + comparisons. s390 version. + Copyright (C) 2016-2018 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#ifndef FIX_FP_INT_COMPARE_INVALID_H +#define FIX_FP_INT_COMPARE_INVALID_H 1 + +/* GCC uses unordered comparison instructions like cebr (Short BFP COMPARE) + when it should use ordered comparison instructions like kebr + (Short BFP COMPARE AND SIGNAL) in order to raise invalid exceptions if + any operand is quiet (or signaling) NAN. See gcc bugzilla: + <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77918>. + There exists an equivalent gcc bugzilla for Intel: + <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=52451>. + Once the s390 gcc bug is fixed, the definition of FIX_COMPARE_INVALID + should have a __GNUC_PREREQ conditional added so that e.g. the workaround + to call feraiseexcept (FE_INVALID) in math/s_iseqsig_template.c can be + avoided. */ +#define FIX_COMPARE_INVALID 1 + +#endif /* fix-fp-int-compare-invalid.h */ diff --git a/sysdeps/s390/fpu/fpu_control.h b/sysdeps/s390/fpu/fpu_control.h index e0266a703e..cb8bca2c56 100644 --- a/sysdeps/s390/fpu/fpu_control.h +++ b/sysdeps/s390/fpu/fpu_control.h @@ -1,5 +1,5 @@ /* FPU control word definitions. Stub version. - Copyright (C) 2000-2016 Free Software Foundation, Inc. + Copyright (C) 2000-2018 Free Software Foundation, Inc. Contributed by Denis Joseph Barrow (djbarrow@de.ibm.com) and Martin Schwidefsky (schwidefsky@de.ibm.com). This file is part of the GNU C Library. diff --git a/sysdeps/s390/fpu/fraiseexcpt.c b/sysdeps/s390/fpu/fraiseexcpt.c index 92a1a7db68..c1edf7a732 100644 --- a/sysdeps/s390/fpu/fraiseexcpt.c +++ b/sysdeps/s390/fpu/fraiseexcpt.c @@ -1,5 +1,5 @@ /* Raise given exceptions. - Copyright (C) 2000-2016 Free Software Foundation, Inc. + Copyright (C) 2000-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Denis Joseph Barrow (djbarrow@de.ibm.com) and Martin Schwidefsky (schwidefsky@de.ibm.com). @@ -35,6 +35,23 @@ fexceptadd (float d, float e) __asm__ __volatile__ ("aebr %0,%1" : : "f" (d), "f" (e) ); } +#ifdef HAVE_S390_MIN_Z196_ZARCH_ASM_SUPPORT +static __inline__ void +fexceptround (double e) +{ + float d; + /* Load rounded from double to float with M3 = round toward 0, M4 = Suppress + IEEE-inexact exception. + In case of e=0x1p128 and the overflow-mask bit is zero, only the + IEEE-overflow flag is set. If overflow-mask bit is one, DXC field is set to + 0x20 "IEEE overflow, exact". + In case of e=0x1p-150 and the underflow-mask bit is zero, only the + IEEE-underflow flag is set. If underflow-mask bit is one, DXC field is set + to 0x10 "IEEE underflow, exact". + This instruction is available with a zarch machine >= z196. */ + __asm__ __volatile__ ("ledbra %0,5,%1,4" : "=f" (d) : "f" (e) ); +} +#endif int __feraiseexcept (int excepts) @@ -54,13 +71,29 @@ __feraiseexcept (int excepts) /* Next: overflow. */ if (FE_OVERFLOW & excepts) - /* I don't think we can do the same trick as intel so we will have - to live with inexact coming also. */ - fexceptadd (FLT_MAX, 1.0e32); + { +#ifdef HAVE_S390_MIN_Z196_ZARCH_ASM_SUPPORT + fexceptround (0x1p128); +#else + /* If overflow-mask bit is zero, both IEEE-overflow and IEEE-inexact flags + are set. If overflow-mask bit is one, DXC field is set to 0x2C "IEEE + overflow, inexact and incremented". */ + fexceptadd (FLT_MAX, 1.0e32); +#endif + } /* Next: underflow. */ if (FE_UNDERFLOW & excepts) - fexceptdiv (FLT_MIN, 3.0); + { +#ifdef HAVE_S390_MIN_Z196_ZARCH_ASM_SUPPORT + fexceptround (0x1p-150); +#else + /* If underflow-mask bit is zero, both IEEE-underflow and IEEE-inexact + flags are set. If underflow-mask bit is one, DXC field is set to 0x1C + "IEEE underflow, inexact and incremented". */ + fexceptdiv (FLT_MIN, 3.0); +#endif + } /* Last: inexact. */ if (FE_INEXACT & excepts) diff --git a/sysdeps/s390/fpu/fsetexcptflg.c b/sysdeps/s390/fpu/fsetexcptflg.c index 25ade854bd..e50684c574 100644 --- a/sysdeps/s390/fpu/fsetexcptflg.c +++ b/sysdeps/s390/fpu/fsetexcptflg.c @@ -1,5 +1,5 @@ /* Set floating-point environment exception handling. - Copyright (C) 2000-2016 Free Software Foundation, Inc. + Copyright (C) 2000-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Denis Joseph Barrow (djbarrow@de.ibm.com). @@ -45,8 +45,7 @@ fesetexceptflag (const fexcept_t *flagp, int excepts) & newexcepts; /* Store the new status word (along with the rest of the environment. - Possibly new exceptions are set but they won't get executed unless - the next floating-point instruction. */ + Possibly new exceptions are set but they won't get executed. */ _FPU_SETCW (temp); /* Success. */ diff --git a/sysdeps/s390/fpu/ftestexcept.c b/sysdeps/s390/fpu/ftestexcept.c index 45cfcb52d0..727b9b342d 100644 --- a/sysdeps/s390/fpu/ftestexcept.c +++ b/sysdeps/s390/fpu/ftestexcept.c @@ -1,5 +1,5 @@ /* Test exception in current environment. - Copyright (C) 2000-2016 Free Software Foundation, Inc. + Copyright (C) 2000-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Denis Joseph Barrow (djbarrow@de.ibm.com). diff --git a/sysdeps/s390/fpu/get-rounding-mode.h b/sysdeps/s390/fpu/get-rounding-mode.h index 5150b0ab25..ae40791af6 100644 --- a/sysdeps/s390/fpu/get-rounding-mode.h +++ b/sysdeps/s390/fpu/get-rounding-mode.h @@ -1,5 +1,5 @@ /* Determine floating-point rounding mode within libc. S/390 version. - Copyright (C) 2012-2016 Free Software Foundation, Inc. + Copyright (C) 2012-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or diff --git a/sysdeps/s390/fpu/libm-test-ulps b/sysdeps/s390/fpu/libm-test-ulps index bc5795b361..fec59c7d60 100644 --- a/sysdeps/s390/fpu/libm-test-ulps +++ b/sysdeps/s390/fpu/libm-test-ulps @@ -40,9 +40,9 @@ ildouble: 2 ldouble: 2 Function: "acosh_downward": -double: 1 +double: 2 float: 2 -idouble: 1 +idouble: 2 ifloat: 2 ildouble: 3 ldouble: 3 @@ -126,9 +126,7 @@ ildouble: 4 ldouble: 4 Function: "atan": -double: 1 float: 1 -idouble: 1 ifloat: 1 ildouble: 1 ldouble: 1 @@ -252,42 +250,42 @@ ildouble: 2 ldouble: 2 Function: Imaginary part of "cacos": -double: 1 +double: 2 float: 2 -idouble: 1 +idouble: 2 ifloat: 2 ildouble: 2 ldouble: 2 Function: Real part of "cacos_downward": -double: 2 +double: 3 float: 2 -idouble: 2 +idouble: 3 ifloat: 2 -ildouble: 2 -ldouble: 2 +ildouble: 3 +ldouble: 3 Function: Imaginary part of "cacos_downward": double: 5 float: 3 idouble: 5 ifloat: 3 -ildouble: 5 -ldouble: 5 +ildouble: 6 +ldouble: 6 Function: Real part of "cacos_towardzero": -double: 2 +double: 3 float: 2 -idouble: 2 +idouble: 3 ifloat: 2 -ildouble: 2 -ldouble: 2 +ildouble: 3 +ldouble: 3 Function: Imaginary part of "cacos_towardzero": -double: 5 -float: 3 -idouble: 5 -ifloat: 3 +double: 4 +float: 2 +idouble: 4 +ifloat: 2 ildouble: 5 ldouble: 5 @@ -300,17 +298,17 @@ ildouble: 3 ldouble: 3 Function: Imaginary part of "cacos_upward": -double: 4 -float: 4 -idouble: 4 -ifloat: 4 -ildouble: 5 -ldouble: 5 +double: 5 +float: 5 +idouble: 5 +ifloat: 5 +ildouble: 7 +ldouble: 7 Function: Real part of "cacosh": -double: 1 +double: 2 float: 2 -idouble: 1 +idouble: 2 ifloat: 2 ildouble: 2 ldouble: 2 @@ -324,57 +322,55 @@ ildouble: 2 ldouble: 2 Function: Real part of "cacosh_downward": -double: 5 -float: 3 -idouble: 5 -ifloat: 3 +double: 4 +float: 2 +idouble: 4 +ifloat: 2 ildouble: 5 ldouble: 5 Function: Imaginary part of "cacosh_downward": -double: 2 -float: 2 -idouble: 2 -ifloat: 2 -ildouble: 2 -ldouble: 2 - -Function: Real part of "cacosh_towardzero": -double: 5 +double: 3 float: 3 -idouble: 5 +idouble: 3 ifloat: 3 +ildouble: 4 +ldouble: 4 + +Function: Real part of "cacosh_towardzero": +double: 4 +float: 2 +idouble: 4 +ifloat: 2 ildouble: 5 ldouble: 5 Function: Imaginary part of "cacosh_towardzero": -double: 2 +double: 3 float: 2 -idouble: 2 +idouble: 3 ifloat: 2 -ildouble: 2 -ldouble: 2 +ildouble: 3 +ldouble: 3 Function: Real part of "cacosh_upward": double: 4 -float: 4 +float: 3 idouble: 4 -ifloat: 4 -ildouble: 5 -ldouble: 5 +ifloat: 3 +ildouble: 6 +ldouble: 6 Function: Imaginary part of "cacosh_upward": -double: 2 +double: 3 float: 2 -idouble: 2 +idouble: 3 ifloat: 2 -ildouble: 3 -ldouble: 3 +ildouble: 4 +ldouble: 4 Function: "carg": -double: 1 float: 1 -idouble: 1 ifloat: 1 ildouble: 2 ldouble: 2 @@ -412,18 +408,18 @@ ildouble: 2 ldouble: 2 Function: Imaginary part of "casin": -double: 1 +double: 2 float: 2 -idouble: 1 +idouble: 2 ifloat: 2 ildouble: 2 ldouble: 2 Function: Real part of "casin_downward": double: 3 -float: 1 +float: 2 idouble: 3 -ifloat: 1 +ifloat: 2 ildouble: 3 ldouble: 3 @@ -432,8 +428,8 @@ double: 5 float: 3 idouble: 5 ifloat: 3 -ildouble: 5 -ldouble: 5 +ildouble: 6 +ldouble: 6 Function: Real part of "casin_towardzero": double: 3 @@ -444,33 +440,33 @@ ildouble: 3 ldouble: 3 Function: Imaginary part of "casin_towardzero": -double: 5 -float: 3 -idouble: 5 -ifloat: 3 +double: 4 +float: 2 +idouble: 4 +ifloat: 2 ildouble: 5 ldouble: 5 Function: Real part of "casin_upward": -double: 2 -float: 1 -idouble: 2 -ifloat: 1 +double: 3 +float: 2 +idouble: 3 +ifloat: 2 ildouble: 3 ldouble: 3 Function: Imaginary part of "casin_upward": -double: 4 -float: 4 -idouble: 4 -ifloat: 4 -ildouble: 5 -ldouble: 5 +double: 5 +float: 5 +idouble: 5 +ifloat: 5 +ildouble: 7 +ldouble: 7 Function: Real part of "casinh": -double: 1 +double: 2 float: 2 -idouble: 1 +idouble: 2 ifloat: 2 ildouble: 2 ldouble: 2 @@ -488,22 +484,22 @@ double: 5 float: 3 idouble: 5 ifloat: 3 -ildouble: 5 -ldouble: 5 +ildouble: 6 +ldouble: 6 Function: Imaginary part of "casinh_downward": double: 3 -float: 1 +float: 2 idouble: 3 -ifloat: 1 +ifloat: 2 ildouble: 3 ldouble: 3 Function: Real part of "casinh_towardzero": -double: 5 -float: 3 -idouble: 5 -ifloat: 3 +double: 4 +float: 2 +idouble: 4 +ifloat: 2 ildouble: 5 ldouble: 5 @@ -516,23 +512,25 @@ ildouble: 3 ldouble: 3 Function: Real part of "casinh_upward": -double: 4 -float: 4 -idouble: 4 -ifloat: 4 -ildouble: 5 -ldouble: 5 +double: 5 +float: 5 +idouble: 5 +ifloat: 5 +ildouble: 7 +ldouble: 7 Function: Imaginary part of "casinh_upward": -double: 2 +double: 3 float: 2 -idouble: 2 +idouble: 3 ifloat: 2 ildouble: 3 ldouble: 3 Function: Real part of "catan": +double: 1 float: 1 +idouble: 1 ifloat: 1 ildouble: 1 ldouble: 1 @@ -547,9 +545,9 @@ ldouble: 1 Function: Real part of "catan_downward": double: 1 -float: 1 +float: 2 idouble: 1 -ifloat: 1 +ifloat: 2 ildouble: 2 ldouble: 2 @@ -558,36 +556,38 @@ double: 2 float: 2 idouble: 2 ifloat: 2 -ildouble: 3 -ldouble: 3 +ildouble: 2 +ldouble: 2 Function: Real part of "catan_towardzero": double: 1 -float: 1 +float: 2 idouble: 1 -ifloat: 1 +ifloat: 2 ildouble: 2 ldouble: 2 Function: Imaginary part of "catan_towardzero": double: 2 -float: 1 +float: 2 idouble: 2 -ifloat: 1 -ildouble: 3 -ldouble: 3 +ifloat: 2 +ildouble: 2 +ldouble: 2 Function: Real part of "catan_upward": +double: 1 float: 1 +idouble: 1 ifloat: 1 -ildouble: 1 -ldouble: 1 +ildouble: 2 +ldouble: 2 Function: Imaginary part of "catan_upward": -double: 3 -float: 3 -idouble: 3 -ifloat: 3 +double: 2 +float: 2 +idouble: 2 +ifloat: 2 ildouble: 3 ldouble: 3 @@ -600,7 +600,9 @@ ildouble: 1 ldouble: 1 Function: Imaginary part of "catanh": +double: 1 float: 1 +idouble: 1 ifloat: 1 ildouble: 1 ldouble: 1 @@ -610,8 +612,8 @@ double: 2 float: 2 idouble: 2 ifloat: 2 -ildouble: 3 -ldouble: 3 +ildouble: 2 +ldouble: 2 Function: Imaginary part of "catanh_downward": double: 1 @@ -623,11 +625,11 @@ ldouble: 2 Function: Real part of "catanh_towardzero": double: 2 -float: 1 +float: 2 idouble: 2 -ifloat: 1 -ildouble: 3 -ldouble: 3 +ifloat: 2 +ildouble: 2 +ldouble: 2 Function: Imaginary part of "catanh_towardzero": double: 1 @@ -639,17 +641,19 @@ ldouble: 2 Function: Real part of "catanh_upward": double: 4 -float: 3 +float: 4 idouble: 4 -ifloat: 3 +ifloat: 4 ildouble: 4 ldouble: 4 Function: Imaginary part of "catanh_upward": +double: 1 float: 1 +idouble: 1 ifloat: 1 -ildouble: 1 -ldouble: 1 +ildouble: 2 +ldouble: 2 Function: "cbrt": double: 3 @@ -765,9 +769,9 @@ ldouble: 1 Function: Real part of "ccosh_downward": double: 1 -float: 3 +float: 2 idouble: 1 -ifloat: 3 +ifloat: 2 ildouble: 2 ldouble: 2 @@ -884,9 +888,7 @@ ildouble: 2 ldouble: 2 Function: Imaginary part of "clog": -double: 1 float: 1 -idouble: 1 ifloat: 1 ildouble: 1 ldouble: 1 @@ -900,18 +902,18 @@ ildouble: 2 ldouble: 2 Function: Imaginary part of "clog10": -double: 1 +double: 2 float: 2 -idouble: 1 +idouble: 2 ifloat: 2 ildouble: 2 ldouble: 2 Function: Real part of "clog10_downward": double: 5 -float: 4 +float: 5 idouble: 5 -ifloat: 4 +ifloat: 5 ildouble: 3 ldouble: 3 @@ -1004,32 +1006,26 @@ ildouble: 2 ldouble: 2 Function: "cos": -float: 1 -ifloat: 1 +double: 1 +idouble: 1 ildouble: 1 ldouble: 1 Function: "cos_downward": double: 1 -float: 2 idouble: 1 -ifloat: 2 ildouble: 3 ldouble: 3 Function: "cos_towardzero": double: 1 -float: 1 idouble: 1 -ifloat: 1 ildouble: 1 ldouble: 1 Function: "cos_upward": double: 1 -float: 2 idouble: 1 -ifloat: 2 ildouble: 2 ldouble: 2 @@ -1203,9 +1199,9 @@ ldouble: 1 Function: Real part of "csinh_downward": double: 2 -float: 2 +float: 1 idouble: 2 -ifloat: 2 +ifloat: 1 ildouble: 2 ldouble: 2 @@ -1323,9 +1319,9 @@ ldouble: 3 Function: Imaginary part of "ctan": double: 2 -float: 1 +float: 2 idouble: 2 -ifloat: 1 +ifloat: 2 ildouble: 3 ldouble: 3 @@ -1339,9 +1335,9 @@ ldouble: 4 Function: Imaginary part of "ctan_downward": double: 2 -float: 1 +float: 2 idouble: 2 -ifloat: 1 +ifloat: 2 ildouble: 5 ldouble: 5 @@ -1363,17 +1359,17 @@ ldouble: 5 Function: Real part of "ctan_upward": double: 2 -float: 3 +float: 4 idouble: 2 -ifloat: 3 +ifloat: 4 ildouble: 5 ldouble: 5 Function: Imaginary part of "ctan_upward": double: 2 -float: 3 +float: 2 idouble: 2 -ifloat: 3 +ifloat: 2 ildouble: 5 ldouble: 5 @@ -1395,9 +1391,9 @@ ldouble: 3 Function: Real part of "ctanh_downward": double: 4 -float: 1 +float: 2 idouble: 4 -ifloat: 1 +ifloat: 2 ildouble: 5 ldouble: 5 @@ -1427,9 +1423,9 @@ ldouble: 3 Function: Real part of "ctanh_upward": double: 2 -float: 3 +float: 2 idouble: 2 -ifloat: 3 +ifloat: 2 ildouble: 5 ldouble: 5 @@ -1506,8 +1502,6 @@ ildouble: 5 ldouble: 5 Function: "exp": -float: 1 -ifloat: 1 ildouble: 1 ldouble: 1 @@ -1543,25 +1537,19 @@ ldouble: 3 Function: "exp2": double: 1 -float: 1 idouble: 1 -ifloat: 1 ildouble: 1 ldouble: 1 Function: "exp2_downward": double: 1 -float: 1 idouble: 1 -ifloat: 1 ildouble: 1 ldouble: 1 Function: "exp2_towardzero": double: 1 -float: 1 idouble: 1 -ifloat: 1 ildouble: 1 ldouble: 1 @@ -1575,15 +1563,21 @@ ldouble: 2 Function: "exp_downward": double: 1 +float: 1 idouble: 1 +ifloat: 1 Function: "exp_towardzero": double: 1 +float: 1 idouble: 1 +ifloat: 1 Function: "exp_upward": double: 1 +float: 1 idouble: 1 +ifloat: 1 Function: "expm1": double: 1 @@ -1619,9 +1613,9 @@ ldouble: 3 Function: "gamma": double: 3 -float: 4 +float: 3 idouble: 3 -ifloat: 4 +ifloat: 3 ildouble: 5 ldouble: 5 @@ -1683,9 +1677,9 @@ ldouble: 2 Function: "j0_downward": double: 2 -float: 3 +float: 4 idouble: 2 -ifloat: 3 +ifloat: 4 ildouble: 4 ldouble: 4 @@ -1771,9 +1765,9 @@ ldouble: 7 Function: "lgamma": double: 3 -float: 4 +float: 3 idouble: 3 -ifloat: 4 +ifloat: 3 ildouble: 5 ldouble: 5 @@ -1802,8 +1796,6 @@ ildouble: 8 ldouble: 8 Function: "log": -float: 1 -ifloat: 1 ildouble: 1 ldouble: 1 @@ -1825,9 +1817,9 @@ ldouble: 1 Function: "log10_towardzero": double: 2 -float: 2 +float: 1 idouble: 2 -ifloat: 2 +ifloat: 1 ildouble: 1 ldouble: 1 @@ -1881,84 +1873,40 @@ ldouble: 2 Function: "log2_downward": double: 3 -float: 3 idouble: 3 -ifloat: 3 ildouble: 3 ldouble: 3 Function: "log2_towardzero": double: 2 -float: 2 idouble: 2 -ifloat: 2 ildouble: 1 ldouble: 1 Function: "log2_upward": double: 3 -float: 3 idouble: 3 -ifloat: 3 ildouble: 1 ldouble: 1 Function: "log_downward": -float: 2 -ifloat: 2 ildouble: 1 ldouble: 1 Function: "log_towardzero": -float: 1 -ifloat: 1 ildouble: 2 ldouble: 2 Function: "log_upward": -double: 1 -float: 1 -idouble: 1 -ifloat: 1 ildouble: 1 ldouble: 1 Function: "pow": -float: 1 -ifloat: 1 -ildouble: 2 -ldouble: 2 - -Function: "pow10": -double: 2 -idouble: 2 +double: 1 +idouble: 1 ildouble: 2 ldouble: 2 -Function: "pow10_downward": -double: 2 -float: 1 -idouble: 2 -ifloat: 1 -ildouble: 3 -ldouble: 3 - -Function: "pow10_towardzero": -double: 2 -float: 1 -idouble: 2 -ifloat: 1 -ildouble: 3 -ldouble: 3 - -Function: "pow10_upward": -double: 2 -float: 1 -idouble: 2 -ifloat: 1 -ildouble: 3 -ldouble: 3 - Function: "pow_downward": double: 1 float: 1 @@ -1984,62 +1932,50 @@ ildouble: 2 ldouble: 2 Function: "sin": -float: 1 -ifloat: 1 +double: 1 +idouble: 1 ildouble: 1 ldouble: 1 Function: "sin_downward": double: 1 -float: 2 idouble: 1 -ifloat: 2 ildouble: 3 ldouble: 3 Function: "sin_towardzero": double: 1 -float: 1 idouble: 1 -ifloat: 1 ildouble: 2 ldouble: 2 Function: "sin_upward": double: 1 -float: 2 idouble: 1 -ifloat: 2 ildouble: 3 ldouble: 3 Function: "sincos": -float: 1 -ifloat: 1 +double: 1 +idouble: 1 ildouble: 1 ldouble: 1 Function: "sincos_downward": double: 1 -float: 2 idouble: 1 -ifloat: 2 ildouble: 3 ldouble: 3 Function: "sincos_towardzero": double: 1 -float: 1 idouble: 1 -ifloat: 1 ildouble: 2 ldouble: 2 Function: "sincos_upward": double: 1 -float: 2 idouble: 1 -ifloat: 2 ildouble: 3 ldouble: 3 @@ -2179,9 +2115,9 @@ ldouble: 3 Function: "y0_downward": double: 3 -float: 2 +float: 4 idouble: 3 -ifloat: 2 +ifloat: 4 ildouble: 4 ldouble: 4 @@ -2195,9 +2131,9 @@ ldouble: 3 Function: "y0_upward": double: 2 -float: 3 +float: 5 idouble: 2 -ifloat: 3 +ifloat: 5 ildouble: 3 ldouble: 3 @@ -2235,17 +2171,17 @@ ldouble: 5 Function: "yn": double: 3 -float: 2 +float: 3 idouble: 3 -ifloat: 2 +ifloat: 3 ildouble: 5 ldouble: 5 Function: "yn_downward": double: 3 -float: 2 +float: 4 idouble: 3 -ifloat: 2 +ifloat: 4 ildouble: 5 ldouble: 5 @@ -2259,9 +2195,9 @@ ldouble: 5 Function: "yn_upward": double: 4 -float: 3 +float: 5 idouble: 4 -ifloat: 3 +ifloat: 5 ildouble: 5 ldouble: 5 diff --git a/sysdeps/s390/fpu/libm-test-ulps-name b/sysdeps/s390/fpu/libm-test-ulps-name new file mode 100644 index 0000000000..4a55100a0e --- /dev/null +++ b/sysdeps/s390/fpu/libm-test-ulps-name @@ -0,0 +1 @@ +S/390 diff --git a/sysdeps/s390/fpu/s_fma.c b/sysdeps/s390/fpu/s_fma.c index 7d7e563b7e..93405d0662 100644 --- a/sysdeps/s390/fpu/s_fma.c +++ b/sysdeps/s390/fpu/s_fma.c @@ -1,5 +1,5 @@ /* Compute x * y + z as ternary operation. S/390 version. - Copyright (C) 2010-2016 Free Software Foundation, Inc. + Copyright (C) 2010-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Jakub Jelinek <jakub@redhat.com>, 2010. @@ -18,6 +18,7 @@ <http://www.gnu.org/licenses/>. */ #include <math.h> +#include <libm-alias-double.h> double __fma (double x, double y, double z) @@ -27,10 +28,5 @@ __fma (double x, double y, double z) return r; } #ifndef __fma -weak_alias (__fma, fma) -#endif - -#ifdef NO_LONG_DOUBLE -strong_alias (__fma, __fmal) -weak_alias (__fmal, fmal) +libm_alias_double (__fma, fma) #endif diff --git a/sysdeps/s390/fpu/s_fmaf.c b/sysdeps/s390/fpu/s_fmaf.c index 50af2bbc5b..0768495f16 100644 --- a/sysdeps/s390/fpu/s_fmaf.c +++ b/sysdeps/s390/fpu/s_fmaf.c @@ -1,5 +1,5 @@ /* Compute x * y + z as ternary operation. S/390 version. - Copyright (C) 2010-2016 Free Software Foundation, Inc. + Copyright (C) 2010-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Jakub Jelinek <jakub@redhat.com>, 2010. @@ -18,6 +18,7 @@ <http://www.gnu.org/licenses/>. */ #include <math.h> +#include <libm-alias-float.h> float __fmaf (float x, float y, float z) @@ -27,5 +28,5 @@ __fmaf (float x, float y, float z) return r; } #ifndef __fmaf -weak_alias (__fmaf, fmaf) +libm_alias_float (__fma, fma) #endif diff --git a/sysdeps/s390/gccframe.h b/sysdeps/s390/gccframe.h index ac0b6b9c4b..ad41f1f0ab 100644 --- a/sysdeps/s390/gccframe.h +++ b/sysdeps/s390/gccframe.h @@ -1,5 +1,5 @@ /* Definition of object in frame unwind info. s390 version. - Copyright (C) 2001-2016 Free Software Foundation, Inc. + Copyright (C) 2001-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or diff --git a/sysdeps/s390/gconv-modules b/sysdeps/s390/gconv-modules new file mode 100644 index 0000000000..c24b4571f5 --- /dev/null +++ b/sysdeps/s390/gconv-modules @@ -0,0 +1,50 @@ +# GNU libc iconv configuration. +# Copyright (C) 1997-2018 Free Software Foundation, Inc. +# This file is part of the GNU C Library. + +# The GNU C Library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. + +# The GNU C Library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. + +# You should have received a copy of the GNU Lesser General Public +# License along with the GNU C Library; if not, see +# <http://www.gnu.org/licenses/>. + +# All lines contain the following information: + +# If the lines start with `module' +# fromset: either a name triple or a regular expression triple. +# toset: a name triple or an expression with \N to get regular +# expression matching results. +# filename: filename of the module implementing the transformation. +# If it is not absolute the path is made absolute by prepending +# the directory the configuration file is found in. +# cost: optional cost of the transformation. Default is 1. + +# If the lines start with `alias' +# alias: alias name which is not really recognized. +# name: the real name of the character set + +# S/390 hardware accelerated modules +# from to module cost +module ISO-8859-1// IBM037// ISO-8859-1_CP037_Z900 1 +module IBM037// ISO-8859-1// ISO-8859-1_CP037_Z900 1 +module ISO-10646/UTF8/ UTF-32// UTF8_UTF32_Z9 1 +module UTF-32BE// ISO-10646/UTF8/ UTF8_UTF32_Z9 1 +module ISO-10646/UTF8/ UTF-32BE// UTF8_UTF32_Z9 1 +module UTF-16BE// UTF-32// UTF16_UTF32_Z9 1 +module UTF-32BE// UTF-16// UTF16_UTF32_Z9 1 +module INTERNAL UTF-16// UTF16_UTF32_Z9 1 +module UTF-32BE// UTF-16BE// UTF16_UTF32_Z9 1 +module INTERNAL UTF-16BE// UTF16_UTF32_Z9 1 +module UTF-16BE// UTF-32BE// UTF16_UTF32_Z9 1 +module UTF-16BE// INTERNAL UTF16_UTF32_Z9 1 +module UTF-16BE// ISO-10646/UTF8/ UTF8_UTF16_Z9 1 +module ISO-10646/UTF8/ UTF-16// UTF8_UTF16_Z9 1 +module ISO-10646/UTF8/ UTF-16BE// UTF8_UTF16_Z9 1 diff --git a/sysdeps/s390/gmp-mparam.h b/sysdeps/s390/gmp-mparam.h index 0f7ec7af0c..fe7d708b78 100644 --- a/sysdeps/s390/gmp-mparam.h +++ b/sysdeps/s390/gmp-mparam.h @@ -1,5 +1,5 @@ /* gmp-mparam.h -- Compiler/machine parameter header file. - Copyright (C) 2000-2016 Free Software Foundation, Inc. + Copyright (C) 2000-2018 Free Software Foundation, Inc. Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com). This file is part of the GNU MP Library. diff --git a/sysdeps/s390/s390-64/iso-8859-1_cp037_z900.c b/sysdeps/s390/iso-8859-1_cp037_z900.c index c59f87f18d..8428d77e57 100644 --- a/sysdeps/s390/s390-64/iso-8859-1_cp037_z900.c +++ b/sysdeps/s390/iso-8859-1_cp037_z900.c @@ -1,8 +1,7 @@ /* Conversion between ISO 8859-1 and IBM037. - This module uses the Z900 variant of the Translate One To One - instruction. - Copyright (C) 1997-2016 Free Software Foundation, Inc. + This module uses the translate instruction. + Copyright (C) 1997-2018 Free Software Foundation, Inc. Author: Andreas Krebbel <Andreas.Krebbel@de.ibm.com> Based on the work by Ulrich Drepper <drepper@cygnus.com>, 1997. @@ -176,50 +175,76 @@ __attribute__ ((aligned (8))) = #define MIN_NEEDED_FROM 1 #define MIN_NEEDED_TO 1 -/* The Z900 variant of troo forces us to always specify a test - character which ends the translation. So if we run into the - situation where the translation has been interrupted due to the - test character we translate the character by hand and jump back - into the instruction. */ +# if defined __s390x__ +# define BRANCH_ON_COUNT(REG,LBL) "brctg %" #REG "," #LBL "\n\t" +# else +# define BRANCH_ON_COUNT(REG,LBL) "brct %" #REG "," #LBL "\n\t" +# endif -#define TROO_LOOP(TABLE) \ +#define TR_LOOP(TABLE) \ { \ - register const unsigned char test __asm__ ("0") = 0; \ - register const unsigned char *pTable __asm__ ("1") = TABLE; \ - register unsigned char *pOutput __asm__ ("2") = outptr; \ - register uint64_t length __asm__ ("3"); \ - const unsigned char* pInput = inptr; \ - uint64_t tmp; \ + size_t length = (inend - inptr < outend - outptr \ + ? inend - inptr : outend - outptr); \ \ - length = (inend - inptr < outend - outptr \ - ? inend - inptr : outend - outptr); \ + /* Process in 256 byte blocks. */ \ + if (__builtin_expect (length >= 256, 0)) \ + { \ + size_t blocks = length / 256; \ + __asm__ __volatile__("0: mvc 0(256,%[R_OUT]),0(%[R_IN])\n\t" \ + " tr 0(256,%[R_OUT]),0(%[R_TBL])\n\t" \ + " la %[R_IN],256(%[R_IN])\n\t" \ + " la %[R_OUT],256(%[R_OUT])\n\t" \ + BRANCH_ON_COUNT ([R_LI], 0b) \ + : /* outputs */ [R_IN] "+a" (inptr) \ + , [R_OUT] "+a" (outptr), [R_LI] "+d" (blocks) \ + : /* inputs */ [R_TBL] "a" (TABLE) \ + : /* clobber list */ "memory" \ + ); \ + length = length % 256; \ + } \ \ - __asm__ volatile ("0: \n\t" \ - " troo %0,%1 \n\t" \ - " jz 1f \n\t" \ - " jo 0b \n\t" \ - " llgc %3,0(%1) \n\t" \ - " la %3,0(%3,%4) \n\t" \ - " mvc 0(1,%0),0(%3) \n\t" \ - " aghi %1,1 \n\t" \ - " aghi %0,1 \n\t" \ - " aghi %2,-1 \n\t" \ - " j 0b \n\t" \ - "1: \n" \ + /* Process remaining 0...248 bytes in 8byte blocks. */ \ + if (length >= 8) \ + { \ + size_t blocks = length / 8; \ + for (int i = 0; i < blocks; i++) \ + { \ + outptr[0] = TABLE[inptr[0]]; \ + outptr[1] = TABLE[inptr[1]]; \ + outptr[2] = TABLE[inptr[2]]; \ + outptr[3] = TABLE[inptr[3]]; \ + outptr[4] = TABLE[inptr[4]]; \ + outptr[5] = TABLE[inptr[5]]; \ + outptr[6] = TABLE[inptr[6]]; \ + outptr[7] = TABLE[inptr[7]]; \ + inptr += 8; \ + outptr += 8; \ + } \ + length = length % 8; \ + } \ \ - : "+a" (pOutput), "+a" (pInput), "+d" (length), "=&a" (tmp) \ - : "a" (pTable), "d" (test) \ - : "cc"); \ - \ - inptr = pInput; \ - outptr = pOutput; \ + /* Process remaining 0...7 bytes. */ \ + switch (length) \ + { \ + case 7: outptr[6] = TABLE[inptr[6]]; \ + case 6: outptr[5] = TABLE[inptr[5]]; \ + case 5: outptr[4] = TABLE[inptr[4]]; \ + case 4: outptr[3] = TABLE[inptr[3]]; \ + case 3: outptr[2] = TABLE[inptr[2]]; \ + case 2: outptr[1] = TABLE[inptr[1]]; \ + case 1: outptr[0] = TABLE[inptr[0]]; \ + case 0: break; \ + } \ + inptr += length; \ + outptr += length; \ } + /* First define the conversion function from ISO 8859-1 to CP037. */ #define MIN_NEEDED_INPUT MIN_NEEDED_FROM #define MIN_NEEDED_OUTPUT MIN_NEEDED_TO #define LOOPFCT FROM_LOOP -#define BODY TROO_LOOP (table_iso8859_1_to_cp037) +#define BODY TR_LOOP (table_iso8859_1_to_cp037) #include <iconv/loop.c> @@ -228,7 +253,7 @@ __attribute__ ((aligned (8))) = #define MIN_NEEDED_INPUT MIN_NEEDED_TO #define MIN_NEEDED_OUTPUT MIN_NEEDED_FROM #define LOOPFCT TO_LOOP -#define BODY TROO_LOOP (table_cp037_iso8859_1); +#define BODY TR_LOOP (table_cp037_iso8859_1); #include <iconv/loop.c> diff --git a/sysdeps/s390/jmpbuf-offsets.h b/sysdeps/s390/jmpbuf-offsets.h index bf23695cd2..7c6aafd8fa 100644 --- a/sysdeps/s390/jmpbuf-offsets.h +++ b/sysdeps/s390/jmpbuf-offsets.h @@ -1,5 +1,5 @@ /* Private macros for accessing __jmp_buf contents. S/390 version. - Copyright (C) 2006-2016 Free Software Foundation, Inc. + Copyright (C) 2006-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or diff --git a/sysdeps/s390/jmpbuf-unwind.h b/sysdeps/s390/jmpbuf-unwind.h index 1e1b4a8b6d..9d42f3056b 100644 --- a/sysdeps/s390/jmpbuf-unwind.h +++ b/sysdeps/s390/jmpbuf-unwind.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2003-2016 Free Software Foundation, Inc. +/* Copyright (C) 2003-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Jakub Jelinek <jakub@redhat.com>, 2003. diff --git a/sysdeps/s390/ldsodefs.h b/sysdeps/s390/ldsodefs.h index b22d364be4..e545d953fb 100644 --- a/sysdeps/s390/ldsodefs.h +++ b/sysdeps/s390/ldsodefs.h @@ -1,5 +1,5 @@ /* Run-time dynamic linker data structures for loaded ELF shared objects. - Copyright (C) 1995-2016 Free Software Foundation, Inc. + Copyright (C) 1995-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or diff --git a/sysdeps/s390/libc-tls.c b/sysdeps/s390/libc-tls.c index 1df435c1f4..85ede75275 100644 --- a/sysdeps/s390/libc-tls.c +++ b/sysdeps/s390/libc-tls.c @@ -1,5 +1,5 @@ /* Thread-local storage handling in the ELF dynamic linker. S390 version. - Copyright (C) 2003-2016 Free Software Foundation, Inc. + Copyright (C) 2003-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or diff --git a/sysdeps/s390/linkmap.h b/sysdeps/s390/linkmap.h index fc1fba363a..283615b99a 100644 --- a/sysdeps/s390/linkmap.h +++ b/sysdeps/s390/linkmap.h @@ -2,12 +2,12 @@ struct link_map_machine { Elf64_Addr plt; /* Address of .plt + 0x2e */ - Elf64_Addr gotplt; /* Address of .got + 0x18 */ + const Elf64_Rela *jmprel; /* Address of first JMP_SLOT reloc */ }; #else struct link_map_machine { Elf32_Addr plt; /* Address of .plt + 0x2c */ - Elf32_Addr gotplt; /* Address of .got + 0x0c */ + const Elf32_Rela *jmprel; /* Address of first JMP_SLOT reloc */ }; #endif diff --git a/sysdeps/s390/longjmp.c b/sysdeps/s390/longjmp.c index 25b0145933..e61cdba2a3 100644 --- a/sysdeps/s390/longjmp.c +++ b/sysdeps/s390/longjmp.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2014-2016 Free Software Foundation, Inc. +/* Copyright (C) 2014-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -33,7 +33,6 @@ but were reverted before 2.20. Thus both versions are the same function. */ strong_alias (__libc_siglongjmp, __libc_longjmp) -libc_hidden_def (__libc_longjmp) weak_alias (__libc_siglongjmp, __v1_longjmp) weak_alias (__libc_siglongjmp, __v2_longjmp) diff --git a/sysdeps/s390/machine-gmon.h b/sysdeps/s390/machine-gmon.h index 0c978754f6..a7b77c41ca 100644 --- a/sysdeps/s390/machine-gmon.h +++ b/sysdeps/s390/machine-gmon.h @@ -1,5 +1,5 @@ /* s390-specific implementation of profiling support. - Copyright (C) 2000-2016 Free Software Foundation, Inc. + Copyright (C) 2000-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or diff --git a/sysdeps/s390/nptl/pthread_spin_init.c b/sysdeps/s390/mempcpy.S index 7d3568fd6f..18ef29213e 100644 --- a/sysdeps/s390/nptl/pthread_spin_init.c +++ b/sysdeps/s390/mempcpy.S @@ -1,6 +1,6 @@ -/* Copyright (C) 2003-2016 Free Software Foundation, Inc. +/* CPU specific mempcpy without multiarch - 32/64 bit S/390 version. + Copyright (C) 2016-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. - Contributed by Martin Schwidefsky <schwidefsky@de.ibm.com>, 2003. The GNU C Library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public @@ -16,4 +16,4 @@ License along with the GNU C Library; if not, see <http://www.gnu.org/licenses/>. */ -/* Not needed. pthread_spin_init is an alias for pthread_spin_unlock. */ +/* mempcpy is implemented in memcpy.S. */ diff --git a/sysdeps/s390/memusage.h b/sysdeps/s390/memusage.h index 888d708b29..c408acd416 100644 --- a/sysdeps/s390/memusage.h +++ b/sysdeps/s390/memusage.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2000-2016 Free Software Foundation, Inc. +/* Copyright (C) 2000-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or diff --git a/sysdeps/s390/multiarch/8bit-generic.c b/sysdeps/s390/multiarch/8bit-generic.c new file mode 100644 index 0000000000..d608beaa62 --- /dev/null +++ b/sysdeps/s390/multiarch/8bit-generic.c @@ -0,0 +1,402 @@ +/* Generic conversion to and from 8bit charsets - S390 version. + Copyright (C) 2016-2018 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#if defined HAVE_S390_VX_ASM_SUPPORT + +# if defined HAVE_S390_VX_GCC_SUPPORT +# define ASM_CLOBBER_VR(NR) , NR +# else +# define ASM_CLOBBER_VR(NR) +# endif + +/* Generate the conversion loop routines without vector instructions as + fallback, if vector instructions aren't available at runtime. */ +# define IGNORE_ICONV_SKELETON +# define from_generic __from_generic_c +# define to_generic __to_generic_c +# include "iconvdata/8bit-generic.c" +# undef IGNORE_ICONV_SKELETON +# undef from_generic +# undef to_generic + +/* Generate the converion routines with vector instructions. The vector + routines can only be used with charsets where the maximum UCS4 value + fits in 1 byte size. Then the hardware translate-instruction is used + to translate between multiple generic characters and "1 byte UCS4" + characters at once. The vector instructions are used to convert between + the "1 byte UCS4" and UCS4. */ +# include <ifunc-resolve.h> + +# undef FROM_LOOP +# undef TO_LOOP +# define FROM_LOOP __from_generic_vx +# define TO_LOOP __to_generic_vx + +# define MIN_NEEDED_FROM 1 +# define MIN_NEEDED_TO 4 +# define ONE_DIRECTION 0 + +/* First define the conversion function from the 8bit charset to UCS4. */ +# define MIN_NEEDED_INPUT MIN_NEEDED_FROM +# define MIN_NEEDED_OUTPUT MIN_NEEDED_TO +# define LOOPFCT FROM_LOOP +# define BODY_FROM_ORIG \ + { \ + uint32_t ch = to_ucs4[*inptr]; \ + \ + if (HAS_HOLES && __builtin_expect (ch == L'\0', 0) && *inptr != '\0') \ + { \ + /* This is an illegal character. */ \ + STANDARD_FROM_LOOP_ERR_HANDLER (1); \ + } \ + \ + put32 (outptr, ch); \ + outptr += 4; \ + ++inptr; \ + } + +# define BODY \ + { \ + if (__builtin_expect (inend - inptr < 16, 1) \ + || outend - outptr < 64) \ + /* Convert remaining bytes with c code. */ \ + BODY_FROM_ORIG \ + else \ + { \ + /* Convert 16 ... 256 bytes at once with tr-instruction. */ \ + size_t index; \ + char buf[256]; \ + size_t loop_count = (inend - inptr) / 16; \ + if (loop_count > (outend - outptr) / 64) \ + loop_count = (outend - outptr) / 64; \ + if (loop_count > 16) \ + loop_count = 16; \ + __asm__ volatile (".machine push\n\t" \ + ".machine \"z13\"\n\t" \ + ".machinemode \"zarch_nohighgprs\"\n\t" \ + " sllk %[R_I],%[R_LI],4\n\t" \ + " ahi %[R_I],-1\n\t" \ + /* Execute mvc and tr with correct len. */ \ + " exrl %[R_I],21f\n\t" \ + " exrl %[R_I],22f\n\t" \ + /* Post-processing. */ \ + " lghi %[R_I],0\n\t" \ + " vzero %%v0\n\t" \ + "0: \n\t" \ + /* Find invalid character - value is zero. */ \ + " vl %%v16,0(%[R_I],%[R_BUF])\n\t" \ + " vceqbs %%v23,%%v0,%%v16\n\t" \ + " jle 10f\n\t" \ + "1: \n\t" \ + /* Enlarge to UCS4. */ \ + " vuplhb %%v17,%%v16\n\t" \ + " vupllb %%v18,%%v16\n\t" \ + " vuplhh %%v19,%%v17\n\t" \ + " vupllh %%v20,%%v17\n\t" \ + " vuplhh %%v21,%%v18\n\t" \ + " vupllh %%v22,%%v18\n\t" \ + /* Store 64bytes to buf_out. */ \ + " vstm %%v19,%%v22,0(%[R_OUT])\n\t" \ + " aghi %[R_I],16\n\t" \ + " la %[R_OUT],64(%[R_OUT])\n\t" \ + " brct %[R_LI],0b\n\t" \ + " la %[R_IN],0(%[R_I],%[R_IN])\n\t" \ + " j 20f\n\t" \ + "21: mvc 0(1,%[R_BUF]),0(%[R_IN])\n\t" \ + "22: tr 0(1,%[R_BUF]),0(%[R_TBL])\n\t" \ + /* Possibly invalid character found. */ \ + "10: \n\t" \ + /* Test if input was zero, too. */ \ + " vl %%v24,0(%[R_I],%[R_IN])\n\t" \ + " vceqb %%v24,%%v0,%%v24\n\t" \ + /* Zeros in buf (v23) and inptr (v24) are marked \ + with one bits. After xor, invalid characters \ + are marked as one bits. Proceed, if no \ + invalid characters are found. */ \ + " vx %%v24,%%v23,%%v24\n\t" \ + " vfenebs %%v24,%%v24,%%v0\n\t" \ + " jo 1b\n\t" \ + /* Found an invalid translation. \ + Store the preceding chars. */ \ + " la %[R_IN],0(%[R_I],%[R_IN])\n\t" \ + " vlgvb %[R_I],%%v24,7\n\t" \ + " la %[R_IN],0(%[R_I],%[R_IN])\n\t" \ + " sll %[R_I],2\n\t" \ + " ahi %[R_I],-1\n\t" \ + " jl 20f\n\t" \ + " lgr %[R_LI],%[R_I]\n\t" \ + " vuplhb %%v17,%%v16\n\t" \ + " vuplhh %%v19,%%v17\n\t" \ + " vstl %%v19,%[R_I],0(%[R_OUT])\n\t" \ + " ahi %[R_I],-16\n\t" \ + " jl 11f\n\t" \ + " vupllh %%v20,%%v17\n\t" \ + " vstl %%v20,%[R_I],16(%[R_OUT])\n\t" \ + " ahi %[R_I],-16\n\t" \ + " jl 11f\n\t" \ + " vupllb %%v18,%%v16\n\t" \ + " vuplhh %%v21,%%v18\n\t" \ + " vstl %%v21,%[R_I],32(%[R_OUT])\n\t" \ + " ahi %[R_I],-16\n\t" \ + " jl 11f\n\t" \ + " vupllh %%v22,%%v18\n\t" \ + " vstl %%v22,%[R_I],48(%[R_OUT])\n\t" \ + "11: \n\t" \ + " la %[R_OUT],1(%[R_LI],%[R_OUT])\n\t" \ + "20: \n\t" \ + ".machine pop" \ + : /* outputs */ [R_IN] "+a" (inptr) \ + , [R_OUT] "+a" (outptr), [R_I] "=&a" (index) \ + , [R_LI] "+a" (loop_count) \ + : /* inputs */ [R_BUF] "a" (buf) \ + , [R_TBL] "a" (to_ucs1) \ + : /* clobber list*/ "memory", "cc" \ + ASM_CLOBBER_VR ("v0") ASM_CLOBBER_VR ("v16") \ + ASM_CLOBBER_VR ("v17") ASM_CLOBBER_VR ("v18") \ + ASM_CLOBBER_VR ("v19") ASM_CLOBBER_VR ("v20") \ + ASM_CLOBBER_VR ("v21") ASM_CLOBBER_VR ("v22") \ + ASM_CLOBBER_VR ("v23") ASM_CLOBBER_VR ("v24") \ + ); \ + /* Error occured? */ \ + if (loop_count != 0) \ + { \ + /* Found an invalid character! */ \ + STANDARD_FROM_LOOP_ERR_HANDLER (1); \ + } \ + } \ + } + +# define LOOP_NEED_FLAGS +# include <iconv/loop.c> + +/* Next, define the other direction - from UCS4 to 8bit charset. */ +# define MIN_NEEDED_INPUT MIN_NEEDED_TO +# define MIN_NEEDED_OUTPUT MIN_NEEDED_FROM +# define LOOPFCT TO_LOOP +# define BODY_TO_ORIG \ + { \ + uint32_t ch = get32 (inptr); \ + \ + if (__builtin_expect (ch >= sizeof (from_ucs4) / sizeof (from_ucs4[0]), 0)\ + || (__builtin_expect (from_ucs4[ch], '\1') == '\0' && ch != 0)) \ + { \ + UNICODE_TAG_HANDLER (ch, 4); \ + \ + /* This is an illegal character. */ \ + STANDARD_TO_LOOP_ERR_HANDLER (4); \ + } \ + \ + *outptr++ = from_ucs4[ch]; \ + inptr += 4; \ + } +# define BODY \ + { \ + if (__builtin_expect (inend - inptr < 64, 1) \ + || outend - outptr < 16) \ + /* Convert remaining bytes with c code. */ \ + BODY_TO_ORIG \ + else \ + { \ + /* Convert 64 ... 1024 bytes at once with tr-instruction. */ \ + size_t index, tmp; \ + char buf[256]; \ + size_t loop_count = (inend - inptr) / 64; \ + uint32_t max = sizeof (from_ucs4) / sizeof (from_ucs4[0]); \ + if (loop_count > (outend - outptr) / 16) \ + loop_count = (outend - outptr) / 16; \ + if (loop_count > 16) \ + loop_count = 16; \ + size_t remaining_loop_count = loop_count; \ + /* Step 1: Check for ch>=max, ch == 0 and shorten to bytes. \ + (ch == 0 is no error, but is handled differently) */ \ + __asm__ volatile (".machine push\n\t" \ + ".machine \"z13\"\n\t" \ + ".machinemode \"zarch_nohighgprs\"\n\t" \ + /* Setup to check for ch >= max. */ \ + " vzero %%v21\n\t" \ + " vleih %%v21,-24576,0\n\t" /* element 0: > */ \ + " vleih %%v21,-8192,2\n\t" /* element 1: =<> */ \ + " vlvgf %%v20,%[R_MAX],0\n\t" /* element 0: val */ \ + /* Process in 64byte - 16 characters blocks. */ \ + " lghi %[R_I],0\n\t" \ + " lghi %[R_TMP],0\n\t" \ + "0: \n\t" \ + " vlm %%v16,%%v19,0(%[R_IN])\n\t" \ + /* Test for ch >= max and ch == 0. */ \ + " vstrczfs %%v22,%%v16,%%v20,%%v21\n\t" \ + " jno 10f\n\t" \ + " vstrczfs %%v22,%%v17,%%v20,%%v21\n\t" \ + " jno 11f\n\t" \ + " vstrczfs %%v22,%%v18,%%v20,%%v21\n\t" \ + " jno 12f\n\t" \ + " vstrczfs %%v22,%%v19,%%v20,%%v21\n\t" \ + " jno 13f\n\t" \ + /* Shorten to byte values. */ \ + " vpkf %%v16,%%v16,%%v17\n\t" \ + " vpkf %%v18,%%v18,%%v19\n\t" \ + " vpkh %%v16,%%v16,%%v18\n\t" \ + /* Store 16bytes to buf. */ \ + " vst %%v16,0(%[R_I],%[R_BUF])\n\t" \ + /* Loop until all blocks are processed. */ \ + " la %[R_IN],64(%[R_IN])\n\t" \ + " aghi %[R_I],16\n\t" \ + " brct %[R_LI],0b\n\t" \ + " j 20f\n\t" \ + /* Found error ch >= max or ch == 0. */ \ + "13: aghi %[R_TMP],4\n\t" \ + "12: aghi %[R_TMP],4\n\t" \ + "11: aghi %[R_TMP],4\n\t" \ + "10: vlgvb %[R_I],%%v22,7\n\t" \ + " srlg %[R_I],%[R_I],2\n\t" \ + " agr %[R_I],%[R_TMP]\n\t" \ + "20: \n\t" \ + ".machine pop" \ + : /* outputs */ [R_IN] "+a" (inptr) \ + , [R_I] "=&a" (index) \ + , [R_TMP] "=d" (tmp) \ + , [R_LI] "+d" (remaining_loop_count) \ + : /* inputs */ [R_BUF] "a" (buf) \ + , [R_MAX] "d" (max) \ + : /* clobber list*/ "memory", "cc" \ + ASM_CLOBBER_VR ("v16") ASM_CLOBBER_VR ("v17") \ + ASM_CLOBBER_VR ("v18") ASM_CLOBBER_VR ("v19") \ + ASM_CLOBBER_VR ("v20") ASM_CLOBBER_VR ("v21") \ + ASM_CLOBBER_VR ("v22") \ + ); \ + /* Error occured in step 1? An error (ch >= max || ch == 0) \ + occured, if remaining_loop_count > 0. The error occured \ + at character-index (index) after already processed blocks. */ \ + loop_count -= remaining_loop_count; \ + if (loop_count > 0) \ + { \ + /* Step 2: Translate already processed blocks in buf and \ + check for errors (from_ucs4[ch] == 0). */ \ + __asm__ volatile (".machine push\n\t" \ + ".machine \"z13\"\n\t" \ + ".machinemode \"zarch_nohighgprs\"\n\t" \ + " sllk %[R_I],%[R_LI],4\n\t" \ + " ahi %[R_I],-1\n\t" \ + /* Execute tr with correct len. */ \ + " exrl %[R_I],21f\n\t" \ + /* Post-processing. */ \ + " lghi %[R_I],0\n\t" \ + "0: \n\t" \ + /* Find invalid character - value == 0. */ \ + " vl %%v16,0(%[R_I],%[R_BUF])\n\t" \ + " vfenezbs %%v17,%%v16,%%v16\n\t" \ + " je 10f\n\t" \ + /* Store 16bytes to buf_out. */ \ + " vst %%v16,0(%[R_I],%[R_OUT])\n\t" \ + " aghi %[R_I],16\n\t" \ + " brct %[R_LI],0b\n\t" \ + " la %[R_OUT],0(%[R_I],%[R_OUT])\n\t" \ + " j 20f\n\t" \ + "21: tr 0(1,%[R_BUF]),0(%[R_TBL])\n\t" \ + /* Found an error: from_ucs4[ch] == 0. */ \ + "10: la %[R_OUT],0(%[R_I],%[R_OUT])\n\t" \ + " vlgvb %[R_I],%%v17,7\n\t" \ + "20: \n\t" \ + ".machine pop" \ + : /* outputs */ [R_OUT] "+a" (outptr) \ + , [R_I] "=&a" (tmp) \ + , [R_LI] "+d" (loop_count) \ + : /* inputs */ [R_BUF] "a" (buf) \ + , [R_TBL] "a" (from_ucs4) \ + : /* clobber list*/ "memory", "cc" \ + ASM_CLOBBER_VR ("v16") \ + ASM_CLOBBER_VR ("v17") \ + ); \ + /* Error occured in processed bytes of step 2? \ + Thus possible error in step 1 is obselete.*/ \ + if (tmp < 16) \ + { \ + index = tmp; \ + inptr -= loop_count * 64; \ + } \ + } \ + /* Error occured in step 1/2? */ \ + if (index < 16) \ + { \ + /* Found an invalid character (see step 2) or zero \ + (see step 1) at index! Convert the chars before index \ + manually. If there is a zero at index detected by step 1, \ + there could be invalid characters before this zero. */ \ + int i; \ + uint32_t ch; \ + for (i = 0; i < index; i++) \ + { \ + ch = get32 (inptr); \ + if (__builtin_expect (from_ucs4[ch], '\1') == '\0') \ + break; \ + *outptr++ = from_ucs4[ch]; \ + inptr += 4; \ + } \ + if (i == index) \ + { \ + ch = get32 (inptr); \ + if (ch == 0) \ + { \ + /* This is no error, but handled differently. */ \ + *outptr++ = from_ucs4[ch]; \ + inptr += 4; \ + continue; \ + } \ + } \ + \ + /* iconv/loop.c disables -Wmaybe-uninitialized for a false \ + positive warning in this code with -Os and has a \ + comment referencing this code accordingly. Updates in \ + one place may require updates in the other. */ \ + UNICODE_TAG_HANDLER (ch, 4); \ + \ + /* This is an illegal character. */ \ + STANDARD_TO_LOOP_ERR_HANDLER (4); \ + } \ + } \ + } + +# define LOOP_NEED_FLAGS +# include <iconv/loop.c> + + +/* Generate ifunc'ed loop function. */ +s390_libc_ifunc_expr (__from_generic_c, __from_generic, + (sizeof (from_ucs4) / sizeof (from_ucs4[0]) <= 256 + && hwcap & HWCAP_S390_VX) + ? __from_generic_vx + : __from_generic_c); + +s390_libc_ifunc_expr (__to_generic_c, __to_generic, + (sizeof (from_ucs4) / sizeof (from_ucs4[0]) <= 256 + && hwcap & HWCAP_S390_VX) + ? __to_generic_vx + : __to_generic_c); + +strong_alias (__to_generic_c_single, __to_generic_single) + +# undef FROM_LOOP +# undef TO_LOOP +# define FROM_LOOP __from_generic +# define TO_LOOP __to_generic +# include <iconv/skeleton.c> + +#else +/* Generate this module without ifunc if build environment lacks vector + support. Instead the common 8bit-generic.c is used. */ +# include "iconvdata/8bit-generic.c" +#endif /* !defined HAVE_S390_VX_ASM_SUPPORT */ diff --git a/sysdeps/s390/multiarch/Makefile b/sysdeps/s390/multiarch/Makefile index 0805b07984..c893ebc565 100644 --- a/sysdeps/s390/multiarch/Makefile +++ b/sysdeps/s390/multiarch/Makefile @@ -18,7 +18,8 @@ sysdep_routines += strlen strlen-vx strlen-c \ memchr memchr-vx \ rawmemchr rawmemchr-vx rawmemchr-c \ memccpy memccpy-vx memccpy-c \ - memrchr memrchr-vx memrchr-c + memrchr memrchr-vx memrchr-c \ + mempcpy endif ifeq ($(subdir),wcsmbs) @@ -42,3 +43,17 @@ sysdep_routines += wcslen wcslen-vx wcslen-c \ wmemset wmemset-vx wmemset-c \ wmemcmp wmemcmp-vx wmemcmp-c endif + +ifeq ($(subdir),iconvdata) +override define generate-8bit-table +$(make-target-directory) +LC_ALL=C $(SHELL) ./gen-8bit.sh $< > $(@:stmp=T) +LC_ALL=C $(SHELL) ../sysdeps/s390/multiarch/gen-8bit.sh $< >> $(@:stmp=T) +$(move-if-change) $(@:stmp=T) $(@:stmp=h) +touch $@ +endef +endif + +ifeq ($(subdir),iconv) +sysdep_routines += gconv_simple +endif diff --git a/sysdeps/s390/multiarch/gconv_simple.c b/sysdeps/s390/multiarch/gconv_simple.c new file mode 100644 index 0000000000..aaa1ebf74a --- /dev/null +++ b/sysdeps/s390/multiarch/gconv_simple.c @@ -0,0 +1,1266 @@ +/* Simple transformations functions - s390 version. + Copyright (C) 2016-2018 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#if defined HAVE_S390_VX_ASM_SUPPORT +# include <ifunc-resolve.h> + +# if defined HAVE_S390_VX_GCC_SUPPORT +# define ASM_CLOBBER_VR(NR) , NR +# else +# define ASM_CLOBBER_VR(NR) +# endif + +# define ICONV_C_NAME(NAME) __##NAME##_c +# define ICONV_VX_NAME(NAME) __##NAME##_vx +# define ICONV_VX_IFUNC(FUNC) \ + extern __typeof (ICONV_C_NAME (FUNC)) __##FUNC; \ + s390_vx_libc_ifunc (__##FUNC) \ + int FUNC (struct __gconv_step *step, struct __gconv_step_data *data, \ + const unsigned char **inptrp, const unsigned char *inend, \ + unsigned char **outbufstart, size_t *irreversible, \ + int do_flush, int consume_incomplete) \ + { \ + return __##FUNC (step, data, inptrp, inend,outbufstart, \ + irreversible, do_flush, consume_incomplete); \ + } +# define ICONV_VX_SINGLE(NAME) \ + static __typeof (NAME##_single) __##NAME##_vx_single __attribute__((alias(#NAME "_single"))); + +/* Generate the transformations which are used, if the target machine does not + support vector instructions. */ +# define __gconv_transform_ascii_internal \ + ICONV_C_NAME (__gconv_transform_ascii_internal) +# define __gconv_transform_internal_ascii \ + ICONV_C_NAME (__gconv_transform_internal_ascii) +# define __gconv_transform_internal_ucs4le \ + ICONV_C_NAME (__gconv_transform_internal_ucs4le) +# define __gconv_transform_ucs4_internal \ + ICONV_C_NAME (__gconv_transform_ucs4_internal) +# define __gconv_transform_ucs4le_internal \ + ICONV_C_NAME (__gconv_transform_ucs4le_internal) +# define __gconv_transform_ucs2_internal \ + ICONV_C_NAME (__gconv_transform_ucs2_internal) +# define __gconv_transform_ucs2reverse_internal \ + ICONV_C_NAME (__gconv_transform_ucs2reverse_internal) +# define __gconv_transform_internal_ucs2 \ + ICONV_C_NAME (__gconv_transform_internal_ucs2) +# define __gconv_transform_internal_ucs2reverse \ + ICONV_C_NAME (__gconv_transform_internal_ucs2reverse) + + +# include <iconv/gconv_simple.c> + +# undef __gconv_transform_ascii_internal +# undef __gconv_transform_internal_ascii +# undef __gconv_transform_internal_ucs4le +# undef __gconv_transform_ucs4_internal +# undef __gconv_transform_ucs4le_internal +# undef __gconv_transform_ucs2_internal +# undef __gconv_transform_ucs2reverse_internal +# undef __gconv_transform_internal_ucs2 +# undef __gconv_transform_internal_ucs2reverse + +/* Now define the functions with vector support. */ +# if defined __s390x__ +# define CONVERT_32BIT_SIZE_T(REG) +# else +# define CONVERT_32BIT_SIZE_T(REG) "llgfr %" #REG ",%" #REG "\n\t" +# endif + +/* Convert from ISO 646-IRV to the internal (UCS4-like) format. */ +# define DEFINE_INIT 0 +# define DEFINE_FINI 0 +# define MIN_NEEDED_FROM 1 +# define MIN_NEEDED_TO 4 +# define FROM_DIRECTION 1 +# define FROM_LOOP ICONV_VX_NAME (ascii_internal_loop) +# define TO_LOOP ICONV_VX_NAME (ascii_internal_loop) /* This is not used. */ +# define FUNCTION_NAME ICONV_VX_NAME (__gconv_transform_ascii_internal) +# define ONE_DIRECTION 1 + +# define MIN_NEEDED_INPUT MIN_NEEDED_FROM +# define MIN_NEEDED_OUTPUT MIN_NEEDED_TO +# define LOOPFCT FROM_LOOP +# define BODY_ORIG_ERROR \ + /* The value is too large. We don't try transliteration here since \ + this is not an error because of the lack of possibilities to \ + represent the result. This is a genuine bug in the input since \ + ASCII does not allow such values. */ \ + STANDARD_FROM_LOOP_ERR_HANDLER (1); + +# define BODY_ORIG \ + { \ + if (__glibc_unlikely (*inptr > '\x7f')) \ + { \ + BODY_ORIG_ERROR \ + } \ + else \ + { \ + /* It's an one byte sequence. */ \ + *((uint32_t *) outptr) = *inptr++; \ + outptr += sizeof (uint32_t); \ + } \ + } +# define BODY \ + { \ + size_t len = inend - inptr; \ + if (len > (outend - outptr) / 4) \ + len = (outend - outptr) / 4; \ + size_t loop_count, tmp; \ + __asm__ volatile (".machine push\n\t" \ + ".machine \"z13\"\n\t" \ + ".machinemode \"zarch_nohighgprs\"\n\t" \ + CONVERT_32BIT_SIZE_T ([R_LEN]) \ + " vrepib %%v30,0x7f\n\t" /* For compare > 0x7f. */ \ + " srlg %[R_LI],%[R_LEN],4\n\t" \ + " vrepib %%v31,0x20\n\t" \ + " clgije %[R_LI],0,1f\n\t" \ + "0: \n\t" /* Handle 16-byte blocks. */ \ + " vl %%v16,0(%[R_IN])\n\t" \ + /* Checking for values > 0x7f. */ \ + " vstrcbs %%v17,%%v16,%%v30,%%v31\n\t" \ + " jno 10f\n\t" \ + /* Enlarge to UCS4. */ \ + " vuplhb %%v17,%%v16\n\t" \ + " vupllb %%v18,%%v16\n\t" \ + " vuplhh %%v19,%%v17\n\t" \ + " vupllh %%v20,%%v17\n\t" \ + " vuplhh %%v21,%%v18\n\t" \ + " vupllh %%v22,%%v18\n\t" \ + /* Store 64bytes to buf_out. */ \ + " vstm %%v19,%%v22,0(%[R_OUT])\n\t" \ + " la %[R_IN],16(%[R_IN])\n\t" \ + " la %[R_OUT],64(%[R_OUT])\n\t" \ + " brctg %[R_LI],0b\n\t" \ + " lghi %[R_LI],15\n\t" \ + " ngr %[R_LEN],%[R_LI]\n\t" \ + " je 20f\n\t" /* Jump away if no remaining bytes. */ \ + /* Handle remaining bytes. */ \ + "1: aghik %[R_LI],%[R_LEN],-1\n\t" \ + " jl 20f\n\t" /* Jump away if no remaining bytes. */ \ + " vll %%v16,%[R_LI],0(%[R_IN])\n\t" \ + /* Checking for values > 0x7f. */ \ + " vstrcbs %%v17,%%v16,%%v30,%%v31\n\t" \ + " vlgvb %[R_TMP],%%v17,7\n\t" \ + " clr %[R_TMP],%[R_LI]\n\t" \ + " locrh %[R_TMP],%[R_LEN]\n\t" \ + " locghih %[R_LEN],0\n\t" \ + " j 12f\n\t" \ + "10:\n\t" \ + /* Found a value > 0x7f. \ + Store the preceding chars. */ \ + " vlgvb %[R_TMP],%%v17,7\n\t" \ + "12: la %[R_IN],0(%[R_TMP],%[R_IN])\n\t" \ + " sllk %[R_TMP],%[R_TMP],2\n\t" \ + " ahi %[R_TMP],-1\n\t" \ + " jl 20f\n\t" \ + " lgr %[R_LI],%[R_TMP]\n\t" \ + " vuplhb %%v17,%%v16\n\t" \ + " vuplhh %%v19,%%v17\n\t" \ + " vstl %%v19,%[R_LI],0(%[R_OUT])\n\t" \ + " ahi %[R_LI],-16\n\t" \ + " jl 11f\n\t" \ + " vupllh %%v20,%%v17\n\t" \ + " vstl %%v20,%[R_LI],16(%[R_OUT])\n\t" \ + " ahi %[R_LI],-16\n\t" \ + " jl 11f\n\t" \ + " vupllb %%v18,%%v16\n\t" \ + " vuplhh %%v21,%%v18\n\t" \ + " vstl %%v21,%[R_LI],32(%[R_OUT])\n\t" \ + " ahi %[R_LI],-16\n\t" \ + " jl 11f\n\t" \ + " vupllh %%v22,%%v18\n\t" \ + " vstl %%v22,%[R_LI],48(%[R_OUT])\n\t" \ + "11:\n\t" \ + " la %[R_OUT],1(%[R_TMP],%[R_OUT])\n\t" \ + "20:\n\t" \ + ".machine pop" \ + : /* outputs */ [R_OUT] "+a" (outptr) \ + , [R_IN] "+a" (inptr) \ + , [R_LEN] "+d" (len) \ + , [R_LI] "=d" (loop_count) \ + , [R_TMP] "=a" (tmp) \ + : /* inputs */ \ + : /* clobber list*/ "memory", "cc" \ + ASM_CLOBBER_VR ("v16") ASM_CLOBBER_VR ("v17") \ + ASM_CLOBBER_VR ("v18") ASM_CLOBBER_VR ("v19") \ + ASM_CLOBBER_VR ("v20") ASM_CLOBBER_VR ("v21") \ + ASM_CLOBBER_VR ("v22") ASM_CLOBBER_VR ("v30") \ + ASM_CLOBBER_VR ("v31") \ + ); \ + if (len > 0) \ + { \ + /* Found an invalid character at the next input byte. */ \ + BODY_ORIG_ERROR \ + } \ + } + +# define LOOP_NEED_FLAGS +# include <iconv/loop.c> +# include <iconv/skeleton.c> +# undef BODY_ORIG +# undef BODY_ORIG_ERROR +ICONV_VX_IFUNC (__gconv_transform_ascii_internal) + +/* Convert from the internal (UCS4-like) format to ISO 646-IRV. */ +# define DEFINE_INIT 0 +# define DEFINE_FINI 0 +# define MIN_NEEDED_FROM 4 +# define MIN_NEEDED_TO 1 +# define FROM_DIRECTION 1 +# define FROM_LOOP ICONV_VX_NAME (internal_ascii_loop) +# define TO_LOOP ICONV_VX_NAME (internal_ascii_loop) /* This is not used. */ +# define FUNCTION_NAME ICONV_VX_NAME (__gconv_transform_internal_ascii) +# define ONE_DIRECTION 1 + +# define MIN_NEEDED_INPUT MIN_NEEDED_FROM +# define MIN_NEEDED_OUTPUT MIN_NEEDED_TO +# define LOOPFCT FROM_LOOP +# define BODY_ORIG_ERROR \ + UNICODE_TAG_HANDLER (*((const uint32_t *) inptr), 4); \ + STANDARD_TO_LOOP_ERR_HANDLER (4); + +# define BODY_ORIG \ + { \ + if (__glibc_unlikely (*((const uint32_t *) inptr) > 0x7f)) \ + { \ + BODY_ORIG_ERROR \ + } \ + else \ + { \ + /* It's an one byte sequence. */ \ + *outptr++ = *((const uint32_t *) inptr); \ + inptr += sizeof (uint32_t); \ + } \ + } +# define BODY \ + { \ + size_t len = (inend - inptr) / 4; \ + if (len > outend - outptr) \ + len = outend - outptr; \ + size_t loop_count, tmp, tmp2; \ + __asm__ volatile (".machine push\n\t" \ + ".machine \"z13\"\n\t" \ + ".machinemode \"zarch_nohighgprs\"\n\t" \ + CONVERT_32BIT_SIZE_T ([R_LEN]) \ + /* Setup to check for ch > 0x7f. */ \ + " vzero %%v21\n\t" \ + " srlg %[R_LI],%[R_LEN],4\n\t" \ + " vleih %%v21,8192,0\n\t" /* element 0: > */ \ + " vleih %%v21,-8192,2\n\t" /* element 1: =<> */ \ + " vleif %%v20,127,0\n\t" /* element 0: 127 */ \ + " lghi %[R_TMP],0\n\t" \ + " clgije %[R_LI],0,1f\n\t" \ + "0:\n\t" \ + " vlm %%v16,%%v19,0(%[R_IN])\n\t" \ + /* Shorten to byte values. */ \ + " vpkf %%v23,%%v16,%%v17\n\t" \ + " vpkf %%v24,%%v18,%%v19\n\t" \ + " vpkh %%v23,%%v23,%%v24\n\t" \ + /* Checking for values > 0x7f. */ \ + " vstrcfs %%v22,%%v16,%%v20,%%v21\n\t" \ + " jno 10f\n\t" \ + " vstrcfs %%v22,%%v17,%%v20,%%v21\n\t" \ + " jno 11f\n\t" \ + " vstrcfs %%v22,%%v18,%%v20,%%v21\n\t" \ + " jno 12f\n\t" \ + " vstrcfs %%v22,%%v19,%%v20,%%v21\n\t" \ + " jno 13f\n\t" \ + /* Store 16bytes to outptr. */ \ + " vst %%v23,0(%[R_OUT])\n\t" \ + " la %[R_IN],64(%[R_IN])\n\t" \ + " la %[R_OUT],16(%[R_OUT])\n\t" \ + " brctg %[R_LI],0b\n\t" \ + " lghi %[R_LI],15\n\t" \ + " ngr %[R_LEN],%[R_LI]\n\t" \ + " je 20f\n\t" /* Jump away if no remaining bytes. */ \ + /* Handle remaining bytes. */ \ + "1: sllg %[R_LI],%[R_LEN],2\n\t" \ + " aghi %[R_LI],-1\n\t" \ + " jl 20f\n\t" /* Jump away if no remaining bytes. */ \ + /* Load remaining 1...63 bytes. */ \ + " vll %%v16,%[R_LI],0(%[R_IN])\n\t" \ + " ahi %[R_LI],-16\n\t" \ + " jl 2f\n\t" \ + " vll %%v17,%[R_LI],16(%[R_IN])\n\t" \ + " ahi %[R_LI],-16\n\t" \ + " jl 2f\n\t" \ + " vll %%v18,%[R_LI],32(%[R_IN])\n\t" \ + " ahi %[R_LI],-16\n\t" \ + " jl 2f\n\t" \ + " vll %%v19,%[R_LI],48(%[R_IN])\n\t" \ + "2:\n\t" \ + /* Shorten to byte values. */ \ + " vpkf %%v23,%%v16,%%v17\n\t" \ + " vpkf %%v24,%%v18,%%v19\n\t" \ + " vpkh %%v23,%%v23,%%v24\n\t" \ + " sllg %[R_LI],%[R_LEN],2\n\t" \ + " aghi %[R_LI],-16\n\t" \ + " jl 3f\n\t" /* v16 is not fully loaded. */ \ + " vstrcfs %%v22,%%v16,%%v20,%%v21\n\t" \ + " jno 10f\n\t" \ + " aghi %[R_LI],-16\n\t" \ + " jl 4f\n\t" /* v17 is not fully loaded. */ \ + " vstrcfs %%v22,%%v17,%%v20,%%v21\n\t" \ + " jno 11f\n\t" \ + " aghi %[R_LI],-16\n\t" \ + " jl 5f\n\t" /* v18 is not fully loaded. */ \ + " vstrcfs %%v22,%%v18,%%v20,%%v21\n\t" \ + " jno 12f\n\t" \ + " aghi %[R_LI],-16\n\t" \ + /* v19 is not fully loaded. */ \ + " lghi %[R_TMP],12\n\t" \ + " vstrcfs %%v22,%%v19,%%v20,%%v21\n\t" \ + "6: vlgvb %[R_I],%%v22,7\n\t" \ + " aghi %[R_LI],16\n\t" \ + " clrjl %[R_I],%[R_LI],14f\n\t" \ + " lgr %[R_I],%[R_LEN]\n\t" \ + " lghi %[R_LEN],0\n\t" \ + " j 15f\n\t" \ + "3: vstrcfs %%v22,%%v16,%%v20,%%v21\n\t" \ + " j 6b\n\t" \ + "4: vstrcfs %%v22,%%v17,%%v20,%%v21\n\t" \ + " lghi %[R_TMP],4\n\t" \ + " j 6b\n\t" \ + "5: vstrcfs %%v22,%%v17,%%v20,%%v21\n\t" \ + " lghi %[R_TMP],8\n\t" \ + " j 6b\n\t" \ + /* Found a value > 0x7f. */ \ + "13: ahi %[R_TMP],4\n\t" \ + "12: ahi %[R_TMP],4\n\t" \ + "11: ahi %[R_TMP],4\n\t" \ + "10: vlgvb %[R_I],%%v22,7\n\t" \ + "14: srlg %[R_I],%[R_I],2\n\t" \ + " agr %[R_I],%[R_TMP]\n\t" \ + " je 20f\n\t" \ + /* Store characters before invalid one... */ \ + "15: aghi %[R_I],-1\n\t" \ + " vstl %%v23,%[R_I],0(%[R_OUT])\n\t" \ + /* ... and update pointers. */ \ + " la %[R_OUT],1(%[R_I],%[R_OUT])\n\t" \ + " sllg %[R_I],%[R_I],2\n\t" \ + " la %[R_IN],4(%[R_I],%[R_IN])\n\t" \ + "20:\n\t" \ + ".machine pop" \ + : /* outputs */ [R_OUT] "+a" (outptr) \ + , [R_IN] "+a" (inptr) \ + , [R_LEN] "+d" (len) \ + , [R_LI] "=d" (loop_count) \ + , [R_I] "=a" (tmp2) \ + , [R_TMP] "=d" (tmp) \ + : /* inputs */ \ + : /* clobber list*/ "memory", "cc" \ + ASM_CLOBBER_VR ("v16") ASM_CLOBBER_VR ("v17") \ + ASM_CLOBBER_VR ("v18") ASM_CLOBBER_VR ("v19") \ + ASM_CLOBBER_VR ("v20") ASM_CLOBBER_VR ("v21") \ + ASM_CLOBBER_VR ("v22") ASM_CLOBBER_VR ("v23") \ + ASM_CLOBBER_VR ("v24") \ + ); \ + if (len > 0) \ + { \ + /* Found an invalid character > 0x7f at next character. */ \ + BODY_ORIG_ERROR \ + } \ + } +# define LOOP_NEED_FLAGS +# include <iconv/loop.c> +# include <iconv/skeleton.c> +# undef BODY_ORIG +# undef BODY_ORIG_ERROR +ICONV_VX_IFUNC (__gconv_transform_internal_ascii) + + +/* Convert from internal UCS4 to UCS4 little endian form. */ +# define DEFINE_INIT 0 +# define DEFINE_FINI 0 +# define MIN_NEEDED_FROM 4 +# define MIN_NEEDED_TO 4 +# define FROM_DIRECTION 1 +# define FROM_LOOP ICONV_VX_NAME (internal_ucs4le_loop) +# define TO_LOOP ICONV_VX_NAME (internal_ucs4le_loop) /* This is not used. */ +# define FUNCTION_NAME ICONV_VX_NAME (__gconv_transform_internal_ucs4le) +# define ONE_DIRECTION 0 + +static inline int +__attribute ((always_inline)) +ICONV_VX_NAME (internal_ucs4le_loop) (struct __gconv_step *step, + struct __gconv_step_data *step_data, + const unsigned char **inptrp, + const unsigned char *inend, + unsigned char **outptrp, + unsigned char *outend, + size_t *irreversible) +{ + const unsigned char *inptr = *inptrp; + unsigned char *outptr = *outptrp; + int result; + size_t len = MIN (inend - inptr, outend - outptr) / 4; + size_t loop_count; + __asm__ volatile (".machine push\n\t" + ".machine \"z13\"\n\t" + ".machinemode \"zarch_nohighgprs\"\n\t" + CONVERT_32BIT_SIZE_T ([R_LEN]) + " bras %[R_LI],1f\n\t" + /* Vector permute mask: */ + " .long 0x03020100,0x7060504,0x0B0A0908,0x0F0E0D0C\n\t" + "1: vl %%v20,0(%[R_LI])\n\t" + /* Process 64byte (16char) blocks. */ + " srlg %[R_LI],%[R_LEN],4\n\t" + " clgije %[R_LI],0,10f\n\t" + "0: vlm %%v16,%%v19,0(%[R_IN])\n\t" + " vperm %%v16,%%v16,%%v16,%%v20\n\t" + " vperm %%v17,%%v17,%%v17,%%v20\n\t" + " vperm %%v18,%%v18,%%v18,%%v20\n\t" + " vperm %%v19,%%v19,%%v19,%%v20\n\t" + " vstm %%v16,%%v19,0(%[R_OUT])\n\t" + " la %[R_IN],64(%[R_IN])\n\t" + " la %[R_OUT],64(%[R_OUT])\n\t" + " brctg %[R_LI],0b\n\t" + " llgfr %[R_LEN],%[R_LEN]\n\t" + " nilf %[R_LEN],15\n\t" + /* Process 16byte (4char) blocks. */ + "10: srlg %[R_LI],%[R_LEN],2\n\t" + " clgije %[R_LI],0,20f\n\t" + "11: vl %%v16,0(%[R_IN])\n\t" + " vperm %%v16,%%v16,%%v16,%%v20\n\t" + " vst %%v16,0(%[R_OUT])\n\t" + " la %[R_IN],16(%[R_IN])\n\t" + " la %[R_OUT],16(%[R_OUT])\n\t" + " brctg %[R_LI],11b\n\t" + " nill %[R_LEN],3\n\t" + /* Process <16bytes. */ + "20: sll %[R_LEN],2\n\t" + " ahi %[R_LEN],-1\n\t" + " jl 30f\n\t" + " vll %%v16,%[R_LEN],0(%[R_IN])\n\t" + " vperm %%v16,%%v16,%%v16,%%v20\n\t" + " vstl %%v16,%[R_LEN],0(%[R_OUT])\n\t" + " la %[R_IN],1(%[R_LEN],%[R_IN])\n\t" + " la %[R_OUT],1(%[R_LEN],%[R_OUT])\n\t" + "30: \n\t" + ".machine pop" + : /* outputs */ [R_OUT] "+a" (outptr) + , [R_IN] "+a" (inptr) + , [R_LI] "=a" (loop_count) + , [R_LEN] "+a" (len) + : /* inputs */ + : /* clobber list*/ "memory", "cc" + ASM_CLOBBER_VR ("v16") ASM_CLOBBER_VR ("v17") + ASM_CLOBBER_VR ("v18") ASM_CLOBBER_VR ("v19") + ASM_CLOBBER_VR ("v20") + ); + *inptrp = inptr; + *outptrp = outptr; + + /* Determine the status. */ + if (*inptrp == inend) + result = __GCONV_EMPTY_INPUT; + else if (*outptrp + 4 > outend) + result = __GCONV_FULL_OUTPUT; + else + result = __GCONV_INCOMPLETE_INPUT; + + return result; +} + +ICONV_VX_SINGLE (internal_ucs4le_loop) +# include <iconv/skeleton.c> +ICONV_VX_IFUNC (__gconv_transform_internal_ucs4le) + + +/* Transform from UCS4 to the internal, UCS4-like format. Unlike + for the other direction we have to check for correct values here. */ +# define DEFINE_INIT 0 +# define DEFINE_FINI 0 +# define MIN_NEEDED_FROM 4 +# define MIN_NEEDED_TO 4 +# define FROM_DIRECTION 1 +# define FROM_LOOP ICONV_VX_NAME (ucs4_internal_loop) +# define TO_LOOP ICONV_VX_NAME (ucs4_internal_loop) /* This is not used. */ +# define FUNCTION_NAME ICONV_VX_NAME (__gconv_transform_ucs4_internal) +# define ONE_DIRECTION 0 + + +static inline int +__attribute ((always_inline)) +ICONV_VX_NAME (ucs4_internal_loop) (struct __gconv_step *step, + struct __gconv_step_data *step_data, + const unsigned char **inptrp, + const unsigned char *inend, + unsigned char **outptrp, + unsigned char *outend, + size_t *irreversible) +{ + int flags = step_data->__flags; + const unsigned char *inptr = *inptrp; + unsigned char *outptr = *outptrp; + int result; + size_t len, loop_count; + do + { + len = MIN (inend - inptr, outend - outptr) / 4; + __asm__ volatile (".machine push\n\t" + ".machine \"z13\"\n\t" + ".machinemode \"zarch_nohighgprs\"\n\t" + CONVERT_32BIT_SIZE_T ([R_LEN]) + /* Setup to check for ch > 0x7fffffff. */ + " larl %[R_LI],9f\n\t" + " vlm %%v20,%%v21,0(%[R_LI])\n\t" + " srlg %[R_LI],%[R_LEN],2\n\t" + " clgije %[R_LI],0,1f\n\t" + /* Process 16byte (4char) blocks. */ + "0: vl %%v16,0(%[R_IN])\n\t" + " vstrcfs %%v22,%%v16,%%v20,%%v21\n\t" + " jno 10f\n\t" + " vst %%v16,0(%[R_OUT])\n\t" + " la %[R_IN],16(%[R_IN])\n\t" + " la %[R_OUT],16(%[R_OUT])\n\t" + " brctg %[R_LI],0b\n\t" + " llgfr %[R_LEN],%[R_LEN]\n\t" + " nilf %[R_LEN],3\n\t" + /* Process <16bytes. */ + "1: sll %[R_LEN],2\n\t" + " ahik %[R_LI],%[R_LEN],-1\n\t" + " jl 20f\n\t" /* No further bytes available. */ + " vll %%v16,%[R_LI],0(%[R_IN])\n\t" + " vstrcfs %%v22,%%v16,%%v20,%%v21\n\t" + " vlgvb %[R_LI],%%v22,7\n\t" + " clr %[R_LI],%[R_LEN]\n\t" + " locgrhe %[R_LI],%[R_LEN]\n\t" + " locghihe %[R_LEN],0\n\t" + " j 11f\n\t" + /* v20: Vector string range compare values. */ + "9: .long 0x7fffffff,0x0,0x0,0x0\n\t" + /* v21: Vector string range compare control-bits. + element 0: >; element 1: =<> (always true) */ + " .long 0x20000000,0xE0000000,0x0,0x0\n\t" + /* Found a value > 0x7fffffff. */ + "10: vlgvb %[R_LI],%%v22,7\n\t" + /* Store characters before invalid one. */ + "11: aghi %[R_LI],-1\n\t" + " jl 20f\n\t" + " vstl %%v16,%[R_LI],0(%[R_OUT])\n\t" + " la %[R_IN],1(%[R_LI],%[R_IN])\n\t" + " la %[R_OUT],1(%[R_LI],%[R_OUT])\n\t" + "20:\n\t" + ".machine pop" + : /* outputs */ [R_OUT] "+a" (outptr) + , [R_IN] "+a" (inptr) + , [R_LI] "=a" (loop_count) + , [R_LEN] "+d" (len) + : /* inputs */ + : /* clobber list*/ "memory", "cc" + ASM_CLOBBER_VR ("v16") ASM_CLOBBER_VR ("v20") + ASM_CLOBBER_VR ("v21") ASM_CLOBBER_VR ("v22") + ); + if (len > 0) + { + /* The value is too large. We don't try transliteration here since + this is not an error because of the lack of possibilities to + represent the result. This is a genuine bug in the input since + UCS4 does not allow such values. */ + if (irreversible == NULL) + /* We are transliterating, don't try to correct anything. */ + return __GCONV_ILLEGAL_INPUT; + + if (flags & __GCONV_IGNORE_ERRORS) + { + /* Just ignore this character. */ + ++*irreversible; + inptr += 4; + continue; + } + + *inptrp = inptr; + *outptrp = outptr; + return __GCONV_ILLEGAL_INPUT; + } + } + while (len > 0); + + *inptrp = inptr; + *outptrp = outptr; + + /* Determine the status. */ + if (*inptrp == inend) + result = __GCONV_EMPTY_INPUT; + else if (*outptrp + 4 > outend) + result = __GCONV_FULL_OUTPUT; + else + result = __GCONV_INCOMPLETE_INPUT; + + return result; +} + +ICONV_VX_SINGLE (ucs4_internal_loop) +# include <iconv/skeleton.c> +ICONV_VX_IFUNC (__gconv_transform_ucs4_internal) + + +/* Transform from UCS4-LE to the internal encoding. */ +# define DEFINE_INIT 0 +# define DEFINE_FINI 0 +# define MIN_NEEDED_FROM 4 +# define MIN_NEEDED_TO 4 +# define FROM_DIRECTION 1 +# define FROM_LOOP ICONV_VX_NAME (ucs4le_internal_loop) +# define TO_LOOP ICONV_VX_NAME (ucs4le_internal_loop) /* This is not used. */ +# define FUNCTION_NAME ICONV_VX_NAME (__gconv_transform_ucs4le_internal) +# define ONE_DIRECTION 0 + +static inline int +__attribute ((always_inline)) +ICONV_VX_NAME (ucs4le_internal_loop) (struct __gconv_step *step, + struct __gconv_step_data *step_data, + const unsigned char **inptrp, + const unsigned char *inend, + unsigned char **outptrp, + unsigned char *outend, + size_t *irreversible) +{ + int flags = step_data->__flags; + const unsigned char *inptr = *inptrp; + unsigned char *outptr = *outptrp; + int result; + size_t len, loop_count; + do + { + len = MIN (inend - inptr, outend - outptr) / 4; + __asm__ volatile (".machine push\n\t" + ".machine \"z13\"\n\t" + ".machinemode \"zarch_nohighgprs\"\n\t" + CONVERT_32BIT_SIZE_T ([R_LEN]) + /* Setup to check for ch > 0x7fffffff. */ + " larl %[R_LI],9f\n\t" + " vlm %%v20,%%v22,0(%[R_LI])\n\t" + " srlg %[R_LI],%[R_LEN],2\n\t" + " clgije %[R_LI],0,1f\n\t" + /* Process 16byte (4char) blocks. */ + "0: vl %%v16,0(%[R_IN])\n\t" + " vperm %%v16,%%v16,%%v16,%%v22\n\t" + " vstrcfs %%v23,%%v16,%%v20,%%v21\n\t" + " jno 10f\n\t" + " vst %%v16,0(%[R_OUT])\n\t" + " la %[R_IN],16(%[R_IN])\n\t" + " la %[R_OUT],16(%[R_OUT])\n\t" + " brctg %[R_LI],0b\n\t" + " llgfr %[R_LEN],%[R_LEN]\n\t" + " nilf %[R_LEN],3\n\t" + /* Process <16bytes. */ + "1: sll %[R_LEN],2\n\t" + " ahik %[R_LI],%[R_LEN],-1\n\t" + " jl 20f\n\t" /* No further bytes available. */ + " vll %%v16,%[R_LI],0(%[R_IN])\n\t" + " vperm %%v16,%%v16,%%v16,%%v22\n\t" + " vstrcfs %%v23,%%v16,%%v20,%%v21\n\t" + " vlgvb %[R_LI],%%v23,7\n\t" + " clr %[R_LI],%[R_LEN]\n\t" + " locgrhe %[R_LI],%[R_LEN]\n\t" + " locghihe %[R_LEN],0\n\t" + " j 11f\n\t" + /* v20: Vector string range compare values. */ + "9: .long 0x7fffffff,0x0,0x0,0x0\n\t" + /* v21: Vector string range compare control-bits. + element 0: >; element 1: =<> (always true) */ + " .long 0x20000000,0xE0000000,0x0,0x0\n\t" + /* v22: Vector permute mask. */ + " .long 0x03020100,0x7060504,0x0B0A0908,0x0F0E0D0C\n\t" + /* Found a value > 0x7fffffff. */ + "10: vlgvb %[R_LI],%%v23,7\n\t" + /* Store characters before invalid one. */ + "11: aghi %[R_LI],-1\n\t" + " jl 20f\n\t" + " vstl %%v16,%[R_LI],0(%[R_OUT])\n\t" + " la %[R_IN],1(%[R_LI],%[R_IN])\n\t" + " la %[R_OUT],1(%[R_LI],%[R_OUT])\n\t" + "20:\n\t" + ".machine pop" + : /* outputs */ [R_OUT] "+a" (outptr) + , [R_IN] "+a" (inptr) + , [R_LI] "=a" (loop_count) + , [R_LEN] "+d" (len) + : /* inputs */ + : /* clobber list*/ "memory", "cc" + ASM_CLOBBER_VR ("v16") ASM_CLOBBER_VR ("v20") + ASM_CLOBBER_VR ("v21") ASM_CLOBBER_VR ("v22") + ASM_CLOBBER_VR ("v23") + ); + if (len > 0) + { + /* The value is too large. We don't try transliteration here since + this is not an error because of the lack of possibilities to + represent the result. This is a genuine bug in the input since + UCS4 does not allow such values. */ + if (irreversible == NULL) + /* We are transliterating, don't try to correct anything. */ + return __GCONV_ILLEGAL_INPUT; + + if (flags & __GCONV_IGNORE_ERRORS) + { + /* Just ignore this character. */ + ++*irreversible; + inptr += 4; + continue; + } + + *inptrp = inptr; + *outptrp = outptr; + return __GCONV_ILLEGAL_INPUT; + } + } + while (len > 0); + + *inptrp = inptr; + *outptrp = outptr; + + /* Determine the status. */ + if (*inptrp == inend) + result = __GCONV_EMPTY_INPUT; + else if (*inptrp + 4 > inend) + result = __GCONV_INCOMPLETE_INPUT; + else + { + assert (*outptrp + 4 > outend); + result = __GCONV_FULL_OUTPUT; + } + + return result; +} +ICONV_VX_SINGLE (ucs4le_internal_loop) +# include <iconv/skeleton.c> +ICONV_VX_IFUNC (__gconv_transform_ucs4le_internal) + +/* Convert from UCS2 to the internal (UCS4-like) format. */ +# define DEFINE_INIT 0 +# define DEFINE_FINI 0 +# define MIN_NEEDED_FROM 2 +# define MIN_NEEDED_TO 4 +# define FROM_DIRECTION 1 +# define FROM_LOOP ICONV_VX_NAME (ucs2_internal_loop) +# define TO_LOOP ICONV_VX_NAME (ucs2_internal_loop) /* This is not used. */ +# define FUNCTION_NAME ICONV_VX_NAME (__gconv_transform_ucs2_internal) +# define ONE_DIRECTION 1 + +# define MIN_NEEDED_INPUT MIN_NEEDED_FROM +# define MIN_NEEDED_OUTPUT MIN_NEEDED_TO +# define LOOPFCT FROM_LOOP +# define BODY_ORIG_ERROR \ + /* Surrogate characters in UCS-2 input are not valid. Reject \ + them. (Catching this here is not security relevant.) */ \ + STANDARD_FROM_LOOP_ERR_HANDLER (2); +# define BODY_ORIG \ + { \ + uint16_t u1 = get16 (inptr); \ + \ + if (__glibc_unlikely (u1 >= 0xd800 && u1 < 0xe000)) \ + { \ + BODY_ORIG_ERROR \ + } \ + \ + *((uint32_t *) outptr) = u1; \ + outptr += sizeof (uint32_t); \ + inptr += 2; \ + } +# define BODY \ + { \ + size_t len, tmp, tmp2; \ + len = MIN ((inend - inptr) / 2, (outend - outptr) / 4); \ + __asm__ volatile (".machine push\n\t" \ + ".machine \"z13\"\n\t" \ + ".machinemode \"zarch_nohighgprs\"\n\t" \ + CONVERT_32BIT_SIZE_T ([R_LEN]) \ + /* Setup to check for ch >= 0xd800 && ch < 0xe000. */ \ + " larl %[R_TMP],9f\n\t" \ + " vlm %%v20,%%v21,0(%[R_TMP])\n\t" \ + " srlg %[R_TMP],%[R_LEN],3\n\t" \ + " clgije %[R_TMP],0,1f\n\t" \ + /* Process 16byte (8char) blocks. */ \ + "0: vl %%v16,0(%[R_IN])\n\t" \ + " vstrchs %%v19,%%v16,%%v20,%%v21\n\t" \ + /* Enlarge UCS2 to UCS4. */ \ + " vuplhh %%v17,%%v16\n\t" \ + " vupllh %%v18,%%v16\n\t" \ + " jno 10f\n\t" \ + /* Store 32bytes to buf_out. */ \ + " vstm %%v17,%%v18,0(%[R_OUT])\n\t" \ + " la %[R_IN],16(%[R_IN])\n\t" \ + " la %[R_OUT],32(%[R_OUT])\n\t" \ + " brctg %[R_TMP],0b\n\t" \ + " llgfr %[R_LEN],%[R_LEN]\n\t" \ + " nilf %[R_LEN],7\n\t" \ + /* Process <16bytes. */ \ + "1: sll %[R_LEN],1\n\t" \ + " ahik %[R_TMP],%[R_LEN],-1\n\t" \ + " jl 20f\n\t" /* No further bytes available. */ \ + " vll %%v16,%[R_TMP],0(%[R_IN])\n\t" \ + " vstrchs %%v19,%%v16,%%v20,%%v21\n\t" \ + /* Enlarge UCS2 to UCS4. */ \ + " vuplhh %%v17,%%v16\n\t" \ + " vupllh %%v18,%%v16\n\t" \ + " vlgvb %[R_TMP],%%v19,7\n\t" \ + " clr %[R_TMP],%[R_LEN]\n\t" \ + " locgrhe %[R_TMP],%[R_LEN]\n\t" \ + " locghihe %[R_LEN],0\n\t" \ + " j 11f\n\t" \ + /* v20: Vector string range compare values. */ \ + "9: .short 0xd800,0xe000,0x0,0x0,0x0,0x0,0x0,0x0\n\t" \ + /* v21: Vector string range compare control-bits. \ + element 0: =>; element 1: < */ \ + " .short 0xa000,0x4000,0x0,0x0,0x0,0x0,0x0,0x0\n\t" \ + /* Found an element: ch >= 0xd800 && ch < 0xe000 */ \ + "10: vlgvb %[R_TMP],%%v19,7\n\t" \ + "11: la %[R_IN],0(%[R_TMP],%[R_IN])\n\t" \ + " sll %[R_TMP],1\n\t" \ + " lgr %[R_TMP2],%[R_TMP]\n\t" \ + " ahi %[R_TMP],-1\n\t" \ + " jl 20f\n\t" \ + " vstl %%v17,%[R_TMP],0(%[R_OUT])\n\t" \ + " ahi %[R_TMP],-16\n\t" \ + " jl 19f\n\t" \ + " vstl %%v18,%[R_TMP],16(%[R_OUT])\n\t" \ + "19: la %[R_OUT],0(%[R_TMP2],%[R_OUT])\n\t" \ + "20: \n\t" \ + ".machine pop" \ + : /* outputs */ [R_OUT] "+a" (outptr) \ + , [R_IN] "+a" (inptr) \ + , [R_TMP] "=a" (tmp) \ + , [R_TMP2] "=a" (tmp2) \ + , [R_LEN] "+d" (len) \ + : /* inputs */ \ + : /* clobber list*/ "memory", "cc" \ + ASM_CLOBBER_VR ("v16") ASM_CLOBBER_VR ("v17") \ + ASM_CLOBBER_VR ("v18") ASM_CLOBBER_VR ("v19") \ + ASM_CLOBBER_VR ("v20") ASM_CLOBBER_VR ("v21") \ + ); \ + if (len > 0) \ + { \ + /* Found an invalid character at next input-char. */ \ + BODY_ORIG_ERROR \ + } \ + } + +# define LOOP_NEED_FLAGS +# include <iconv/loop.c> +# include <iconv/skeleton.c> +# undef BODY_ORIG +# undef BODY_ORIG_ERROR +ICONV_VX_IFUNC (__gconv_transform_ucs2_internal) + +/* Convert from UCS2 in other endianness to the internal (UCS4-like) format. */ +# define DEFINE_INIT 0 +# define DEFINE_FINI 0 +# define MIN_NEEDED_FROM 2 +# define MIN_NEEDED_TO 4 +# define FROM_DIRECTION 1 +# define FROM_LOOP ICONV_VX_NAME (ucs2reverse_internal_loop) +# define TO_LOOP ICONV_VX_NAME (ucs2reverse_internal_loop) /* This is not used.*/ +# define FUNCTION_NAME ICONV_VX_NAME (__gconv_transform_ucs2reverse_internal) +# define ONE_DIRECTION 1 + +# define MIN_NEEDED_INPUT MIN_NEEDED_FROM +# define MIN_NEEDED_OUTPUT MIN_NEEDED_TO +# define LOOPFCT FROM_LOOP +# define BODY_ORIG_ERROR \ + /* Surrogate characters in UCS-2 input are not valid. Reject \ + them. (Catching this here is not security relevant.) */ \ + if (! ignore_errors_p ()) \ + { \ + result = __GCONV_ILLEGAL_INPUT; \ + break; \ + } \ + inptr += 2; \ + ++*irreversible; \ + continue; + +# define BODY_ORIG \ + { \ + uint16_t u1 = bswap_16 (get16 (inptr)); \ + \ + if (__glibc_unlikely (u1 >= 0xd800 && u1 < 0xe000)) \ + { \ + BODY_ORIG_ERROR \ + } \ + \ + *((uint32_t *) outptr) = u1; \ + outptr += sizeof (uint32_t); \ + inptr += 2; \ + } +# define BODY \ + { \ + size_t len, tmp, tmp2; \ + len = MIN ((inend - inptr) / 2, (outend - outptr) / 4); \ + __asm__ volatile (".machine push\n\t" \ + ".machine \"z13\"\n\t" \ + ".machinemode \"zarch_nohighgprs\"\n\t" \ + CONVERT_32BIT_SIZE_T ([R_LEN]) \ + /* Setup to check for ch >= 0xd800 && ch < 0xe000. */ \ + " larl %[R_TMP],9f\n\t" \ + " vlm %%v20,%%v22,0(%[R_TMP])\n\t" \ + " srlg %[R_TMP],%[R_LEN],3\n\t" \ + " clgije %[R_TMP],0,1f\n\t" \ + /* Process 16byte (8char) blocks. */ \ + "0: vl %%v16,0(%[R_IN])\n\t" \ + " vperm %%v16,%%v16,%%v16,%%v22\n\t" \ + " vstrchs %%v19,%%v16,%%v20,%%v21\n\t" \ + /* Enlarge UCS2 to UCS4. */ \ + " vuplhh %%v17,%%v16\n\t" \ + " vupllh %%v18,%%v16\n\t" \ + " jno 10f\n\t" \ + /* Store 32bytes to buf_out. */ \ + " vstm %%v17,%%v18,0(%[R_OUT])\n\t" \ + " la %[R_IN],16(%[R_IN])\n\t" \ + " la %[R_OUT],32(%[R_OUT])\n\t" \ + " brctg %[R_TMP],0b\n\t" \ + " llgfr %[R_LEN],%[R_LEN]\n\t" \ + " nilf %[R_LEN],7\n\t" \ + /* Process <16bytes. */ \ + "1: sll %[R_LEN],1\n\t" \ + " ahik %[R_TMP],%[R_LEN],-1\n\t" \ + " jl 20f\n\t" /* No further bytes available. */ \ + " vll %%v16,%[R_TMP],0(%[R_IN])\n\t" \ + " vperm %%v16,%%v16,%%v16,%%v22\n\t" \ + " vstrchs %%v19,%%v16,%%v20,%%v21\n\t" \ + /* Enlarge UCS2 to UCS4. */ \ + " vuplhh %%v17,%%v16\n\t" \ + " vupllh %%v18,%%v16\n\t" \ + " vlgvb %[R_TMP],%%v19,7\n\t" \ + " clr %[R_TMP],%[R_LEN]\n\t" \ + " locgrhe %[R_TMP],%[R_LEN]\n\t" \ + " locghihe %[R_LEN],0\n\t" \ + " j 11f\n\t" \ + /* v20: Vector string range compare values. */ \ + "9: .short 0xd800,0xe000,0x0,0x0,0x0,0x0,0x0,0x0\n\t" \ + /* v21: Vector string range compare control-bits. \ + element 0: =>; element 1: < */ \ + " .short 0xa000,0x4000,0x0,0x0,0x0,0x0,0x0,0x0\n\t" \ + /* v22: Vector permute mask. */ \ + " .short 0x0100,0x0302,0x0504,0x0706\n\t" \ + " .short 0x0908,0x0b0a,0x0d0c,0x0f0e\n\t" \ + /* Found an element: ch >= 0xd800 && ch < 0xe000 */ \ + "10: vlgvb %[R_TMP],%%v19,7\n\t" \ + "11: la %[R_IN],0(%[R_TMP],%[R_IN])\n\t" \ + " sll %[R_TMP],1\n\t" \ + " lgr %[R_TMP2],%[R_TMP]\n\t" \ + " ahi %[R_TMP],-1\n\t" \ + " jl 20f\n\t" \ + " vstl %%v17,%[R_TMP],0(%[R_OUT])\n\t" \ + " ahi %[R_TMP],-16\n\t" \ + " jl 19f\n\t" \ + " vstl %%v18,%[R_TMP],16(%[R_OUT])\n\t" \ + "19: la %[R_OUT],0(%[R_TMP2],%[R_OUT])\n\t" \ + "20: \n\t" \ + ".machine pop" \ + : /* outputs */ [R_OUT] "+a" (outptr) \ + , [R_IN] "+a" (inptr) \ + , [R_TMP] "=a" (tmp) \ + , [R_TMP2] "=a" (tmp2) \ + , [R_LEN] "+d" (len) \ + : /* inputs */ \ + : /* clobber list*/ "memory", "cc" \ + ASM_CLOBBER_VR ("v16") ASM_CLOBBER_VR ("v17") \ + ASM_CLOBBER_VR ("v18") ASM_CLOBBER_VR ("v19") \ + ASM_CLOBBER_VR ("v20") ASM_CLOBBER_VR ("v21") \ + ASM_CLOBBER_VR ("v22") \ + ); \ + if (len > 0) \ + { \ + /* Found an invalid character at next input-char. */ \ + BODY_ORIG_ERROR \ + } \ + } +# define LOOP_NEED_FLAGS +# include <iconv/loop.c> +# include <iconv/skeleton.c> +# undef BODY_ORIG +# undef BODY_ORIG_ERROR +ICONV_VX_IFUNC (__gconv_transform_ucs2reverse_internal) + +/* Convert from the internal (UCS4-like) format to UCS2. */ +#define DEFINE_INIT 0 +#define DEFINE_FINI 0 +#define MIN_NEEDED_FROM 4 +#define MIN_NEEDED_TO 2 +#define FROM_DIRECTION 1 +#define FROM_LOOP ICONV_VX_NAME (internal_ucs2_loop) +#define TO_LOOP ICONV_VX_NAME (internal_ucs2_loop) /* This is not used. */ +#define FUNCTION_NAME ICONV_VX_NAME (__gconv_transform_internal_ucs2) +#define ONE_DIRECTION 1 + +#define MIN_NEEDED_INPUT MIN_NEEDED_FROM +#define MIN_NEEDED_OUTPUT MIN_NEEDED_TO +#define LOOPFCT FROM_LOOP +#define BODY_ORIG \ + { \ + uint32_t val = *((const uint32_t *) inptr); \ + \ + if (__glibc_unlikely (val >= 0x10000)) \ + { \ + UNICODE_TAG_HANDLER (val, 4); \ + STANDARD_TO_LOOP_ERR_HANDLER (4); \ + } \ + else if (__glibc_unlikely (val >= 0xd800 && val < 0xe000)) \ + { \ + /* Surrogate characters in UCS-4 input are not valid. \ + We must catch this, because the UCS-2 output might be \ + interpreted as UTF-16 by other programs. If we let \ + surrogates pass through, attackers could make a security \ + hole exploit by synthesizing any desired plane 1-16 \ + character. */ \ + result = __GCONV_ILLEGAL_INPUT; \ + if (! ignore_errors_p ()) \ + break; \ + inptr += 4; \ + ++*irreversible; \ + continue; \ + } \ + else \ + { \ + put16 (outptr, val); \ + outptr += sizeof (uint16_t); \ + inptr += 4; \ + } \ + } +# define BODY \ + { \ + if (__builtin_expect (inend - inptr < 32, 1) \ + || outend - outptr < 16) \ + /* Convert remaining bytes with c code. */ \ + BODY_ORIG \ + else \ + { \ + /* Convert in 32 byte blocks. */ \ + size_t loop_count = (inend - inptr) / 32; \ + size_t tmp, tmp2; \ + if (loop_count > (outend - outptr) / 16) \ + loop_count = (outend - outptr) / 16; \ + __asm__ volatile (".machine push\n\t" \ + ".machine \"z13\"\n\t" \ + ".machinemode \"zarch_nohighgprs\"\n\t" \ + CONVERT_32BIT_SIZE_T ([R_LI]) \ + " larl %[R_I],3f\n\t" \ + " vlm %%v20,%%v23,0(%[R_I])\n\t" \ + "0: \n\t" \ + " vlm %%v16,%%v17,0(%[R_IN])\n\t" \ + /* Shorten UCS4 to UCS2. */ \ + " vpkf %%v18,%%v16,%%v17\n\t" \ + " vstrcfs %%v19,%%v16,%%v20,%%v21\n\t" \ + " jno 11f\n\t" \ + "1: vstrcfs %%v19,%%v17,%%v20,%%v21\n\t" \ + " jno 10f\n\t" \ + /* Store 16bytes to buf_out. */ \ + "2: vst %%v18,0(%[R_OUT])\n\t" \ + " la %[R_IN],32(%[R_IN])\n\t" \ + " la %[R_OUT],16(%[R_OUT])\n\t" \ + " brctg %[R_LI],0b\n\t" \ + " j 20f\n\t" \ + /* Setup to check for ch >= 0xd800. (v20, v21) */ \ + "3: .long 0xd800,0xd800,0x0,0x0\n\t" \ + " .long 0xa0000000,0xa0000000,0x0,0x0\n\t" \ + /* Setup to check for ch >= 0xe000 \ + && ch < 0x10000. (v22,v23) */ \ + " .long 0xe000,0x10000,0x0,0x0\n\t" \ + " .long 0xa0000000,0x40000000,0x0,0x0\n\t" \ + /* v16 contains only valid chars. Check in v17: \ + ch >= 0xe000 && ch <= 0xffff. */ \ + "10: vstrcfs %%v19,%%v17,%%v22,%%v23,8\n\t" \ + " jo 2b\n\t" /* All ch's in this range, proceed. */ \ + " lghi %[R_TMP],16\n\t" \ + " j 12f\n\t" \ + /* Maybe v16 contains invalid chars. \ + Check ch >= 0xe000 && ch <= 0xffff. */ \ + "11: vstrcfs %%v19,%%v16,%%v22,%%v23,8\n\t" \ + " jo 1b\n\t" /* All ch's in this range, proceed. */ \ + " lghi %[R_TMP],0\n\t" \ + "12: vlgvb %[R_I],%%v19,7\n\t" \ + " agr %[R_I],%[R_TMP]\n\t" \ + " la %[R_IN],0(%[R_I],%[R_IN])\n\t" \ + " srl %[R_I],1\n\t" \ + " ahi %[R_I],-1\n\t" \ + " jl 20f\n\t" \ + " vstl %%v18,%[R_I],0(%[R_OUT])\n\t" \ + " la %[R_OUT],1(%[R_I],%[R_OUT])\n\t" \ + "20:\n\t" \ + ".machine pop" \ + : /* outputs */ [R_OUT] "+a" (outptr) \ + , [R_IN] "+a" (inptr) \ + , [R_LI] "+d" (loop_count) \ + , [R_I] "=a" (tmp2) \ + , [R_TMP] "=d" (tmp) \ + : /* inputs */ \ + : /* clobber list*/ "memory", "cc" \ + ASM_CLOBBER_VR ("v16") ASM_CLOBBER_VR ("v17") \ + ASM_CLOBBER_VR ("v18") ASM_CLOBBER_VR ("v19") \ + ASM_CLOBBER_VR ("v20") ASM_CLOBBER_VR ("v21") \ + ASM_CLOBBER_VR ("v22") ASM_CLOBBER_VR ("v23") \ + ); \ + if (loop_count > 0) \ + { \ + /* Found an invalid character at next character. */ \ + BODY_ORIG \ + } \ + } \ + } +#define LOOP_NEED_FLAGS +#include <iconv/loop.c> +#include <iconv/skeleton.c> +# undef BODY_ORIG +ICONV_VX_IFUNC (__gconv_transform_internal_ucs2) + +/* Convert from the internal (UCS4-like) format to UCS2 in other endianness. */ +#define DEFINE_INIT 0 +#define DEFINE_FINI 0 +#define MIN_NEEDED_FROM 4 +#define MIN_NEEDED_TO 2 +#define FROM_DIRECTION 1 +#define FROM_LOOP ICONV_VX_NAME (internal_ucs2reverse_loop) +#define TO_LOOP ICONV_VX_NAME (internal_ucs2reverse_loop)/* This is not used.*/ +#define FUNCTION_NAME ICONV_VX_NAME (__gconv_transform_internal_ucs2reverse) +#define ONE_DIRECTION 1 + +#define MIN_NEEDED_INPUT MIN_NEEDED_FROM +#define MIN_NEEDED_OUTPUT MIN_NEEDED_TO +#define LOOPFCT FROM_LOOP +#define BODY_ORIG \ + { \ + uint32_t val = *((const uint32_t *) inptr); \ + if (__glibc_unlikely (val >= 0x10000)) \ + { \ + UNICODE_TAG_HANDLER (val, 4); \ + STANDARD_TO_LOOP_ERR_HANDLER (4); \ + } \ + else if (__glibc_unlikely (val >= 0xd800 && val < 0xe000)) \ + { \ + /* Surrogate characters in UCS-4 input are not valid. \ + We must catch this, because the UCS-2 output might be \ + interpreted as UTF-16 by other programs. If we let \ + surrogates pass through, attackers could make a security \ + hole exploit by synthesizing any desired plane 1-16 \ + character. */ \ + if (! ignore_errors_p ()) \ + { \ + result = __GCONV_ILLEGAL_INPUT; \ + break; \ + } \ + inptr += 4; \ + ++*irreversible; \ + continue; \ + } \ + else \ + { \ + put16 (outptr, bswap_16 (val)); \ + outptr += sizeof (uint16_t); \ + inptr += 4; \ + } \ + } +# define BODY \ + { \ + if (__builtin_expect (inend - inptr < 32, 1) \ + || outend - outptr < 16) \ + /* Convert remaining bytes with c code. */ \ + BODY_ORIG \ + else \ + { \ + /* Convert in 32 byte blocks. */ \ + size_t loop_count = (inend - inptr) / 32; \ + size_t tmp, tmp2; \ + if (loop_count > (outend - outptr) / 16) \ + loop_count = (outend - outptr) / 16; \ + __asm__ volatile (".machine push\n\t" \ + ".machine \"z13\"\n\t" \ + ".machinemode \"zarch_nohighgprs\"\n\t" \ + CONVERT_32BIT_SIZE_T ([R_LI]) \ + " larl %[R_I],3f\n\t" \ + " vlm %%v20,%%v24,0(%[R_I])\n\t" \ + "0: \n\t" \ + " vlm %%v16,%%v17,0(%[R_IN])\n\t" \ + /* Shorten UCS4 to UCS2 and byteswap. */ \ + " vpkf %%v18,%%v16,%%v17\n\t" \ + " vperm %%v18,%%v18,%%v18,%%v24\n\t" \ + " vstrcfs %%v19,%%v16,%%v20,%%v21\n\t" \ + " jno 11f\n\t" \ + "1: vstrcfs %%v19,%%v17,%%v20,%%v21\n\t" \ + " jno 10f\n\t" \ + /* Store 16bytes to buf_out. */ \ + "2: vst %%v18,0(%[R_OUT])\n\t" \ + " la %[R_IN],32(%[R_IN])\n\t" \ + " la %[R_OUT],16(%[R_OUT])\n\t" \ + " brctg %[R_LI],0b\n\t" \ + " j 20f\n\t" \ + /* Setup to check for ch >= 0xd800. (v20, v21) */ \ + "3: .long 0xd800,0xd800,0x0,0x0\n\t" \ + " .long 0xa0000000,0xa0000000,0x0,0x0\n\t" \ + /* Setup to check for ch >= 0xe000 \ + && ch < 0x10000. (v22,v23) */ \ + " .long 0xe000,0x10000,0x0,0x0\n\t" \ + " .long 0xa0000000,0x40000000,0x0,0x0\n\t" \ + /* Vector permute mask (v24) */ \ + " .short 0x0100,0x0302,0x0504,0x0706\n\t" \ + " .short 0x0908,0x0b0a,0x0d0c,0x0f0e\n\t" \ + /* v16 contains only valid chars. Check in v17: \ + ch >= 0xe000 && ch <= 0xffff. */ \ + "10: vstrcfs %%v19,%%v17,%%v22,%%v23,8\n\t" \ + " jo 2b\n\t" /* All ch's in this range, proceed. */ \ + " lghi %[R_TMP],16\n\t" \ + " j 12f\n\t" \ + /* Maybe v16 contains invalid chars. \ + Check ch >= 0xe000 && ch <= 0xffff. */ \ + "11: vstrcfs %%v19,%%v16,%%v22,%%v23,8\n\t" \ + " jo 1b\n\t" /* All ch's in this range, proceed. */ \ + " lghi %[R_TMP],0\n\t" \ + "12: vlgvb %[R_I],%%v19,7\n\t" \ + " agr %[R_I],%[R_TMP]\n\t" \ + " la %[R_IN],0(%[R_I],%[R_IN])\n\t" \ + " srl %[R_I],1\n\t" \ + " ahi %[R_I],-1\n\t" \ + " jl 20f\n\t" \ + " vstl %%v18,%[R_I],0(%[R_OUT])\n\t" \ + " la %[R_OUT],1(%[R_I],%[R_OUT])\n\t" \ + "20:\n\t" \ + ".machine pop" \ + : /* outputs */ [R_OUT] "+a" (outptr) \ + , [R_IN] "+a" (inptr) \ + , [R_LI] "+d" (loop_count) \ + , [R_I] "=a" (tmp2) \ + , [R_TMP] "=d" (tmp) \ + : /* inputs */ \ + : /* clobber list*/ "memory", "cc" \ + ASM_CLOBBER_VR ("v16") ASM_CLOBBER_VR ("v17") \ + ASM_CLOBBER_VR ("v18") ASM_CLOBBER_VR ("v19") \ + ASM_CLOBBER_VR ("v20") ASM_CLOBBER_VR ("v21") \ + ASM_CLOBBER_VR ("v22") ASM_CLOBBER_VR ("v23") \ + ASM_CLOBBER_VR ("v24") \ + ); \ + if (loop_count > 0) \ + { \ + /* Found an invalid character at next character. */ \ + BODY_ORIG \ + } \ + } \ + } +#define LOOP_NEED_FLAGS +#include <iconv/loop.c> +#include <iconv/skeleton.c> +# undef BODY_ORIG +ICONV_VX_IFUNC (__gconv_transform_internal_ucs2reverse) + + +#else +/* Generate the internal transformations without ifunc if build environment + lacks vector support. Instead simply include the common version. */ +# include <iconv/gconv_simple.c> +#endif /* !defined HAVE_S390_VX_ASM_SUPPORT */ diff --git a/sysdeps/s390/multiarch/gen-8bit.sh b/sysdeps/s390/multiarch/gen-8bit.sh new file mode 100644 index 0000000000..6f88c4bd9d --- /dev/null +++ b/sysdeps/s390/multiarch/gen-8bit.sh @@ -0,0 +1,6 @@ +#!/bin/sh +echo "static const uint8_t to_ucs1[256] = {" +sed -ne '/^[^[:space:]]*[[:space:]]*.x00/d;/^END/q' \ + -e 's/^<U00\(..\)>[[:space:]]*.x\(..\).*/ [0x\2] = 0x\1,/p' \ + "$@" | sort -u +echo "};" diff --git a/sysdeps/s390/multiarch/iconv/skeleton.c b/sysdeps/s390/multiarch/iconv/skeleton.c new file mode 100644 index 0000000000..8774a536ca --- /dev/null +++ b/sysdeps/s390/multiarch/iconv/skeleton.c @@ -0,0 +1,21 @@ +/* Skeleton for a conversion module - S390 version. + Copyright (C) 2016-2018 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#ifndef IGNORE_ICONV_SKELETON +# include_next <iconv/skeleton.c> +#endif diff --git a/sysdeps/s390/multiarch/ifunc-impl-list.c b/sysdeps/s390/multiarch/ifunc-impl-list.c index 62a435983c..ec3373ae26 100644 --- a/sysdeps/s390/multiarch/ifunc-impl-list.c +++ b/sysdeps/s390/multiarch/ifunc-impl-list.c @@ -1,5 +1,5 @@ /* Enumerate available IFUNC implementations of a function. s390/s390x version. - Copyright (C) 2015-2016 Free Software Foundation, Inc. + Copyright (C) 2015-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -69,6 +69,13 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, S390_IS_Z10 (stfle_bits), __memcpy_z10) IFUNC_IMPL_ADD (array, i, memcpy, 1, __memcpy_default)) + IFUNC_IMPL (i, name, mempcpy, + IFUNC_IMPL_ADD (array, i, mempcpy, + S390_IS_Z196 (stfle_bits), ____mempcpy_z196) + IFUNC_IMPL_ADD (array, i, mempcpy, + S390_IS_Z10 (stfle_bits), ____mempcpy_z10) + IFUNC_IMPL_ADD (array, i, mempcpy, 1, ____mempcpy_default)) + #endif /* SHARED */ #ifdef HAVE_S390_VX_ASM_SUPPORT diff --git a/sysdeps/s390/multiarch/ifunc-resolve.h b/sysdeps/s390/multiarch/ifunc-resolve.h index 744a0d8d6d..b42ed922fd 100644 --- a/sysdeps/s390/multiarch/ifunc-resolve.h +++ b/sysdeps/s390/multiarch/ifunc-resolve.h @@ -1,6 +1,6 @@ /* IFUNC resolver function for CPU specific functions. 32/64 bit S/390 version. - Copyright (C) 2015-2016 Free Software Foundation, Inc. + Copyright (C) 2015-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -40,55 +40,51 @@ ".machine pop" "\n" \ : "=QS" (STFLE_BITS), "+d" (reg0) \ : : "cc"); +#define s390_libc_ifunc_init() \ + unsigned long long stfle_bits = 0ULL; \ + if (__glibc_likely((dl_hwcap & HWCAP_S390_STFLE) \ + && (dl_hwcap & HWCAP_S390_ZARCH) \ + && (dl_hwcap & HWCAP_S390_HIGH_GPRS))) \ + { \ + S390_STORE_STFLE (stfle_bits); \ + } -#define s390_libc_ifunc(FUNC) \ - __asm__ (".globl " #FUNC "\n\t" \ - ".type " #FUNC ",@gnu_indirect_function\n\t" \ - ".set " #FUNC ",__resolve_" #FUNC "\n\t" \ - ".globl __GI_" #FUNC "\n\t" \ - ".set __GI_" #FUNC "," #FUNC "\n"); \ - \ +#define s390_libc_ifunc(TYPE_FUNC, RESOLVERFUNC, FUNC) \ /* Make the declarations of the optimized functions hidden in order to prevent GOT slots being generated for them. */ \ - extern void *__##FUNC##_z196 attribute_hidden; \ - extern void *__##FUNC##_z10 attribute_hidden; \ - extern void *__##FUNC##_default attribute_hidden; \ - \ - void *__resolve_##FUNC (unsigned long int dl_hwcap) \ - { \ - if ((dl_hwcap & HWCAP_S390_STFLE) \ - && (dl_hwcap & HWCAP_S390_ZARCH) \ - && (dl_hwcap & HWCAP_S390_HIGH_GPRS)) \ - { \ - unsigned long long stfle_bits; \ - S390_STORE_STFLE (stfle_bits); \ - \ - if (S390_IS_Z196 (stfle_bits)) \ - return &__##FUNC##_z196; \ - else if (S390_IS_Z10 (stfle_bits)) \ - return &__##FUNC##_z10; \ - else \ - return &__##FUNC##_default; \ - } \ - else \ - return &__##FUNC##_default; \ - } + extern __typeof (TYPE_FUNC) RESOLVERFUNC##_z196 attribute_hidden; \ + extern __typeof (TYPE_FUNC) RESOLVERFUNC##_z10 attribute_hidden; \ + extern __typeof (TYPE_FUNC) RESOLVERFUNC##_default attribute_hidden; \ + __ifunc (TYPE_FUNC, FUNC, \ + __glibc_likely (S390_IS_Z196 (stfle_bits)) \ + ? RESOLVERFUNC##_z196 \ + : __glibc_likely (S390_IS_Z10 (stfle_bits)) \ + ? RESOLVERFUNC##_z10 \ + : RESOLVERFUNC##_default, \ + unsigned long int dl_hwcap, s390_libc_ifunc_init); #define s390_vx_libc_ifunc(FUNC) \ - s390_vx_libc_ifunc2(FUNC, FUNC) + s390_vx_libc_ifunc2_redirected(FUNC, FUNC, FUNC) + +#define s390_vx_libc_ifunc_redirected(TYPE_FUNC, FUNC) \ + s390_vx_libc_ifunc2_redirected(TYPE_FUNC, FUNC, FUNC) -#define s390_vx_libc_ifunc2(RESOLVERFUNC, FUNC) \ +#define s390_vx_libc_ifunc2(RESOLVERFUNC, FUNC) \ + s390_vx_libc_ifunc2_redirected(FUNC, RESOLVERFUNC, FUNC) + +#define s390_vx_libc_ifunc_init() +#define s390_vx_libc_ifunc2_redirected(TYPE_FUNC, RESOLVERFUNC, FUNC) \ /* Make the declarations of the optimized functions hidden in order to prevent GOT slots being generated for them. */ \ - extern __typeof (FUNC) RESOLVERFUNC##_vx attribute_hidden; \ - extern __typeof (FUNC) RESOLVERFUNC##_c attribute_hidden; \ - extern void *__resolve_##RESOLVERFUNC (unsigned long int) __asm__ (#FUNC); \ - \ - void *__resolve_##RESOLVERFUNC (unsigned long int dl_hwcap) \ - { \ - if (dl_hwcap & HWCAP_S390_VX) \ - return &RESOLVERFUNC##_vx; \ - else \ - return &RESOLVERFUNC##_c; \ - } \ - __asm__ (".type " #FUNC ", %gnu_indirect_function"); + extern __typeof (TYPE_FUNC) RESOLVERFUNC##_vx attribute_hidden; \ + extern __typeof (TYPE_FUNC) RESOLVERFUNC##_c attribute_hidden; \ + __ifunc (TYPE_FUNC, FUNC, \ + (dl_hwcap & HWCAP_S390_VX) \ + ? RESOLVERFUNC##_vx \ + : RESOLVERFUNC##_c, \ + unsigned long int dl_hwcap, s390_vx_libc_ifunc_init); + +#define s390_libc_ifunc_expr_init() +#define s390_libc_ifunc_expr(TYPE_FUNC, FUNC, EXPR) \ + __ifunc (TYPE_FUNC, FUNC, EXPR, unsigned long int hwcap, \ + s390_libc_ifunc_expr_init); diff --git a/sysdeps/s390/multiarch/memccpy-c.c b/sysdeps/s390/multiarch/memccpy-c.c index 9309bd108b..1f4c548199 100644 --- a/sysdeps/s390/multiarch/memccpy-c.c +++ b/sysdeps/s390/multiarch/memccpy-c.c @@ -1,5 +1,5 @@ /* Default memccpy implementation for S/390. - Copyright (C) 2015-2016 Free Software Foundation, Inc. + Copyright (C) 2015-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or diff --git a/sysdeps/s390/multiarch/memccpy-vx.S b/sysdeps/s390/multiarch/memccpy-vx.S index 2db9b2cef4..150aa0e4a4 100644 --- a/sysdeps/s390/multiarch/memccpy-vx.S +++ b/sysdeps/s390/multiarch/memccpy-vx.S @@ -1,5 +1,5 @@ /* Vector optimized 32/64 bit S/390 version of memccpy. - Copyright (C) 2015-2016 Free Software Foundation, Inc. + Copyright (C) 2015-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or diff --git a/sysdeps/s390/multiarch/memccpy.c b/sysdeps/s390/multiarch/memccpy.c index 0a0936e340..30aae82321 100644 --- a/sysdeps/s390/multiarch/memccpy.c +++ b/sysdeps/s390/multiarch/memccpy.c @@ -1,5 +1,5 @@ /* Multiple versions of memccpy. - Copyright (C) 2015-2016 Free Software Foundation, Inc. + Copyright (C) 2015-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or diff --git a/sysdeps/s390/multiarch/memchr-vx.S b/sysdeps/s390/multiarch/memchr-vx.S index 875eee2b43..77d31e0036 100644 --- a/sysdeps/s390/multiarch/memchr-vx.S +++ b/sysdeps/s390/multiarch/memchr-vx.S @@ -1,5 +1,5 @@ /* Vector optimized 32/64 bit S/390 version of memchr. - Copyright (C) 2015-2016 Free Software Foundation, Inc. + Copyright (C) 2015-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or diff --git a/sysdeps/s390/multiarch/memchr.c b/sysdeps/s390/multiarch/memchr.c index f80de1cc1f..3885ebaa4d 100644 --- a/sysdeps/s390/multiarch/memchr.c +++ b/sysdeps/s390/multiarch/memchr.c @@ -1,5 +1,5 @@ /* Multiple versions of memchr. - Copyright (C) 2015-2016 Free Software Foundation, Inc. + Copyright (C) 2015-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -17,8 +17,11 @@ <http://www.gnu.org/licenses/>. */ #if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) +# define memchr __redirect_memchr # include <string.h> +# undef memchr # include <ifunc-resolve.h> -s390_vx_libc_ifunc2 (__memchr, memchr) +s390_vx_libc_ifunc2_redirected (__redirect_memchr, __memchr, memchr) + #endif diff --git a/sysdeps/s390/multiarch/mempcpy.c b/sysdeps/s390/multiarch/mempcpy.c new file mode 100644 index 0000000000..363fe47aef --- /dev/null +++ b/sysdeps/s390/multiarch/mempcpy.c @@ -0,0 +1,32 @@ +/* Multiple versions of mempcpy. + Copyright (C) 2016-2018 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + + +#if defined SHARED && IS_IN (libc) +# define mempcpy __redirect_mempcpy +# define __mempcpy __redirect___mempcpy +# define __NO_STRING_INLINES +# define NO_MEMPCPY_STPCPY_REDIRECT +# include <string.h> +# undef mempcpy +# undef __mempcpy +# include <ifunc-resolve.h> + +s390_libc_ifunc (__redirect___mempcpy, ____mempcpy, __mempcpy) +weak_alias (__mempcpy, mempcpy); +#endif diff --git a/sysdeps/s390/multiarch/memrchr-c.c b/sysdeps/s390/multiarch/memrchr-c.c index af54097376..1e3c914a5d 100644 --- a/sysdeps/s390/multiarch/memrchr-c.c +++ b/sysdeps/s390/multiarch/memrchr-c.c @@ -1,5 +1,5 @@ /* Default memrchr implementation for S/390. - Copyright (C) 2015-2016 Free Software Foundation, Inc. + Copyright (C) 2015-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or diff --git a/sysdeps/s390/multiarch/memrchr-vx.S b/sysdeps/s390/multiarch/memrchr-vx.S index fdb8c30ebe..8e81f5ed75 100644 --- a/sysdeps/s390/multiarch/memrchr-vx.S +++ b/sysdeps/s390/multiarch/memrchr-vx.S @@ -1,5 +1,5 @@ /* Vector optimized 32/64 bit S/390 version of memrchr. - Copyright (C) 2015-2016 Free Software Foundation, Inc. + Copyright (C) 2015-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or diff --git a/sysdeps/s390/multiarch/memrchr.c b/sysdeps/s390/multiarch/memrchr.c index 7681890d01..43a44abcf6 100644 --- a/sysdeps/s390/multiarch/memrchr.c +++ b/sysdeps/s390/multiarch/memrchr.c @@ -1,5 +1,5 @@ /* Multiple versions of memrchr. - Copyright (C) 2015-2016 Free Software Foundation, Inc. + Copyright (C) 2015-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or diff --git a/sysdeps/s390/multiarch/rawmemchr-c.c b/sysdeps/s390/multiarch/rawmemchr-c.c index 20dcdb5a28..f43c883a76 100644 --- a/sysdeps/s390/multiarch/rawmemchr-c.c +++ b/sysdeps/s390/multiarch/rawmemchr-c.c @@ -1,5 +1,5 @@ /* Default rawmemchr implementation for S/390. - Copyright (C) 2015-2016 Free Software Foundation, Inc. + Copyright (C) 2015-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or diff --git a/sysdeps/s390/multiarch/rawmemchr-vx.S b/sysdeps/s390/multiarch/rawmemchr-vx.S index 5af2419e98..d5778be068 100644 --- a/sysdeps/s390/multiarch/rawmemchr-vx.S +++ b/sysdeps/s390/multiarch/rawmemchr-vx.S @@ -1,5 +1,5 @@ /* Vector optimized 32/64 bit S/390 version of rawmemchr. - Copyright (C) 2015-2016 Free Software Foundation, Inc. + Copyright (C) 2015-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or diff --git a/sysdeps/s390/multiarch/rawmemchr.c b/sysdeps/s390/multiarch/rawmemchr.c index 7186ccd9d4..5fdb2252df 100644 --- a/sysdeps/s390/multiarch/rawmemchr.c +++ b/sysdeps/s390/multiarch/rawmemchr.c @@ -1,5 +1,5 @@ /* Multiple versions of rawmemchr. - Copyright (C) 2015-2016 Free Software Foundation, Inc. + Copyright (C) 2015-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -17,10 +17,13 @@ <http://www.gnu.org/licenses/>. */ #if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) +# define __rawmemchr __redirect___rawmemchr # include <string.h> +# undef __rawmemchr # include <ifunc-resolve.h> -s390_vx_libc_ifunc (__rawmemchr) +s390_vx_libc_ifunc2_redirected (__redirect___rawmemchr, __rawmemchr + , __rawmemchr) weak_alias (__rawmemchr, rawmemchr) #else diff --git a/sysdeps/s390/multiarch/stpcpy-c.c b/sysdeps/s390/multiarch/stpcpy-c.c index 85a8a93c7f..4a1c3e5832 100644 --- a/sysdeps/s390/multiarch/stpcpy-c.c +++ b/sysdeps/s390/multiarch/stpcpy-c.c @@ -1,5 +1,5 @@ /* Default stpcpy implementation for S/390. - Copyright (C) 2015-2016 Free Software Foundation, Inc. + Copyright (C) 2015-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or diff --git a/sysdeps/s390/multiarch/stpcpy-vx.S b/sysdeps/s390/multiarch/stpcpy-vx.S index da9f2760de..6c17def0fc 100644 --- a/sysdeps/s390/multiarch/stpcpy-vx.S +++ b/sysdeps/s390/multiarch/stpcpy-vx.S @@ -1,5 +1,5 @@ /* Vector optimized 32/64 bit S/390 version of stpcpy. - Copyright (C) 2015-2016 Free Software Foundation, Inc. + Copyright (C) 2015-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or diff --git a/sysdeps/s390/multiarch/stpcpy.c b/sysdeps/s390/multiarch/stpcpy.c index dcde01278b..654f9dfbef 100644 --- a/sysdeps/s390/multiarch/stpcpy.c +++ b/sysdeps/s390/multiarch/stpcpy.c @@ -1,5 +1,5 @@ /* Multiple versions of stpcpy. - Copyright (C) 2015-2016 Free Software Foundation, Inc. + Copyright (C) 2015-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -17,13 +17,18 @@ <http://www.gnu.org/licenses/>. */ #if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) +# define stpcpy __redirect_stpcpy +# define __stpcpy __redirect___stpcpy +/* Omit the stpcpy inline definitions because it would redefine stpcpy. */ +# define __NO_STRING_INLINES # define NO_MEMPCPY_STPCPY_REDIRECT # include <string.h> +# undef stpcpy +# undef __stpcpy # include <ifunc-resolve.h> -s390_vx_libc_ifunc (__stpcpy) +s390_vx_libc_ifunc_redirected (__redirect___stpcpy, __stpcpy); weak_alias (__stpcpy, stpcpy) -libc_hidden_builtin_def (stpcpy) #else # include <string/stpcpy.c> diff --git a/sysdeps/s390/multiarch/stpncpy-c.c b/sysdeps/s390/multiarch/stpncpy-c.c index 32b61a8e3e..45e50aa9e7 100644 --- a/sysdeps/s390/multiarch/stpncpy-c.c +++ b/sysdeps/s390/multiarch/stpncpy-c.c @@ -1,5 +1,5 @@ /* Default stpncpy implementation for S/390. - Copyright (C) 2015-2016 Free Software Foundation, Inc. + Copyright (C) 2015-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or diff --git a/sysdeps/s390/multiarch/stpncpy-vx.S b/sysdeps/s390/multiarch/stpncpy-vx.S index 2e536d9e0f..922bd7a355 100644 --- a/sysdeps/s390/multiarch/stpncpy-vx.S +++ b/sysdeps/s390/multiarch/stpncpy-vx.S @@ -1,5 +1,5 @@ /* Vector optimized 32/64 bit S/390 version of stpncpy. - Copyright (C) 2015-2016 Free Software Foundation, Inc. + Copyright (C) 2015-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or diff --git a/sysdeps/s390/multiarch/stpncpy.c b/sysdeps/s390/multiarch/stpncpy.c index f5335b42ac..f7f9d51a50 100644 --- a/sysdeps/s390/multiarch/stpncpy.c +++ b/sysdeps/s390/multiarch/stpncpy.c @@ -1,5 +1,5 @@ /* Multiple versions of stpncpy. - Copyright (C) 2015-2016 Free Software Foundation, Inc. + Copyright (C) 2015-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -17,10 +17,14 @@ <http://www.gnu.org/licenses/>. */ #if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) +# define stpncpy __redirect_stpncpy +# define __stpncpy __redirect___stpncpy # include <string.h> +# undef stpncpy +# undef __stpncpy # include <ifunc-resolve.h> -s390_vx_libc_ifunc (__stpncpy) +s390_vx_libc_ifunc_redirected (__redirect___stpncpy, __stpncpy) weak_alias (__stpncpy, stpncpy) #else diff --git a/sysdeps/s390/multiarch/strcat-c.c b/sysdeps/s390/multiarch/strcat-c.c index ae7cc2149d..f871faa7b5 100644 --- a/sysdeps/s390/multiarch/strcat-c.c +++ b/sysdeps/s390/multiarch/strcat-c.c @@ -1,5 +1,5 @@ /* Default strcat implementation for S/390. - Copyright (C) 2015-2016 Free Software Foundation, Inc. + Copyright (C) 2015-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or diff --git a/sysdeps/s390/multiarch/strcat-vx.S b/sysdeps/s390/multiarch/strcat-vx.S index e77fc2aa2f..3abbbccced 100644 --- a/sysdeps/s390/multiarch/strcat-vx.S +++ b/sysdeps/s390/multiarch/strcat-vx.S @@ -1,5 +1,5 @@ /* Vector optimized 32/64 bit S/390 version of strcat. - Copyright (C) 2015-2016 Free Software Foundation, Inc. + Copyright (C) 2015-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or diff --git a/sysdeps/s390/multiarch/strcat.c b/sysdeps/s390/multiarch/strcat.c index c3b5e1c9d6..7d4126b44f 100644 --- a/sysdeps/s390/multiarch/strcat.c +++ b/sysdeps/s390/multiarch/strcat.c @@ -1,5 +1,5 @@ /* Multiple versions of strcat. - Copyright (C) 2015-2016 Free Software Foundation, Inc. + Copyright (C) 2015-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -17,10 +17,12 @@ <http://www.gnu.org/licenses/>. */ #if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) +# define strcat __redirect_strcat # include <string.h> +# undef strcat # include <ifunc-resolve.h> -s390_vx_libc_ifunc2 (__strcat, strcat) +s390_vx_libc_ifunc2_redirected (__redirect_strcat, __strcat, strcat) #else # include <string/strcat.c> diff --git a/sysdeps/s390/multiarch/strchr-c.c b/sysdeps/s390/multiarch/strchr-c.c index 2250dbbf5e..606cb56788 100644 --- a/sysdeps/s390/multiarch/strchr-c.c +++ b/sysdeps/s390/multiarch/strchr-c.c @@ -1,5 +1,5 @@ /* Default strchr implementation for S/390. - Copyright (C) 2015-2016 Free Software Foundation, Inc. + Copyright (C) 2015-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or diff --git a/sysdeps/s390/multiarch/strchr-vx.S b/sysdeps/s390/multiarch/strchr-vx.S index 4fe5dc0293..6e744fb82f 100644 --- a/sysdeps/s390/multiarch/strchr-vx.S +++ b/sysdeps/s390/multiarch/strchr-vx.S @@ -1,5 +1,5 @@ /* Vector optimized 32/64 bit S/390 version of strchr. - Copyright (C) 2015-2016 Free Software Foundation, Inc. + Copyright (C) 2015-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or diff --git a/sysdeps/s390/multiarch/strchr.c b/sysdeps/s390/multiarch/strchr.c index 3c8c7e4600..8aa33a51cc 100644 --- a/sysdeps/s390/multiarch/strchr.c +++ b/sysdeps/s390/multiarch/strchr.c @@ -1,5 +1,5 @@ /* Multiple versions of strchr. - Copyright (C) 2015-2016 Free Software Foundation, Inc. + Copyright (C) 2015-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -17,10 +17,14 @@ <http://www.gnu.org/licenses/>. */ #if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) +# define strchr __redirect_strchr +/* Omit the strchr inline definitions because it would redefine strchr. */ +# define __NO_STRING_INLINES # include <string.h> +# undef strchr # include <ifunc-resolve.h> -s390_vx_libc_ifunc2 (__strchr, strchr) +s390_vx_libc_ifunc2_redirected (__redirect_strchr, __strchr, strchr) weak_alias (strchr, index) #else diff --git a/sysdeps/s390/multiarch/strchrnul-c.c b/sysdeps/s390/multiarch/strchrnul-c.c index 1f77c40cea..020cebcf3e 100644 --- a/sysdeps/s390/multiarch/strchrnul-c.c +++ b/sysdeps/s390/multiarch/strchrnul-c.c @@ -1,5 +1,5 @@ /* Default strchrnul implementation for S/390. - Copyright (C) 2015-2016 Free Software Foundation, Inc. + Copyright (C) 2015-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or diff --git a/sysdeps/s390/multiarch/strchrnul-vx.S b/sysdeps/s390/multiarch/strchrnul-vx.S index 43ca29ead0..d561825e04 100644 --- a/sysdeps/s390/multiarch/strchrnul-vx.S +++ b/sysdeps/s390/multiarch/strchrnul-vx.S @@ -1,5 +1,5 @@ /* Vector optimized 32/64 bit S/390 version of strchrnul. - Copyright (C) 2015-2016 Free Software Foundation, Inc. + Copyright (C) 2015-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or diff --git a/sysdeps/s390/multiarch/strchrnul.c b/sysdeps/s390/multiarch/strchrnul.c index 627c084521..62dfc6bd90 100644 --- a/sysdeps/s390/multiarch/strchrnul.c +++ b/sysdeps/s390/multiarch/strchrnul.c @@ -1,5 +1,5 @@ /* Multiple versions of strchrnul. - Copyright (C) 2015-2016 Free Software Foundation, Inc. + Copyright (C) 2015-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or diff --git a/sysdeps/s390/multiarch/strcmp-vx.S b/sysdeps/s390/multiarch/strcmp-vx.S index edf557b5eb..bcaeb564d4 100644 --- a/sysdeps/s390/multiarch/strcmp-vx.S +++ b/sysdeps/s390/multiarch/strcmp-vx.S @@ -1,5 +1,5 @@ /* Vector optimized 32/64 bit S/390 version of strcmp. - Copyright (C) 2015-2016 Free Software Foundation, Inc. + Copyright (C) 2015-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or diff --git a/sysdeps/s390/multiarch/strcmp.c b/sysdeps/s390/multiarch/strcmp.c index c4ccd34420..7c8b17b304 100644 --- a/sysdeps/s390/multiarch/strcmp.c +++ b/sysdeps/s390/multiarch/strcmp.c @@ -1,5 +1,5 @@ /* Multiple versions of strcmp. - Copyright (C) 2015-2016 Free Software Foundation, Inc. + Copyright (C) 2015-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -17,10 +17,13 @@ <http://www.gnu.org/licenses/>. */ #if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) +# define strcmp __redirect_strcmp +/* Omit the strcmp inline definitions because it would redefine strcmp. */ +# define __NO_STRING_INLINES # include <string.h> # include <ifunc-resolve.h> +# undef strcmp +s390_vx_libc_ifunc2_redirected (__redirect_strcmp, __strcmp, strcmp) -# undef strcmp -s390_vx_libc_ifunc2 (__strcmp, strcmp) #endif diff --git a/sysdeps/s390/multiarch/strcpy-vx.S b/sysdeps/s390/multiarch/strcpy-vx.S index d3472b821d..52197f57f7 100644 --- a/sysdeps/s390/multiarch/strcpy-vx.S +++ b/sysdeps/s390/multiarch/strcpy-vx.S @@ -1,5 +1,5 @@ /* Vector optimized 32/64 bit S/390 version of strcpy. - Copyright (C) 2015-2016 Free Software Foundation, Inc. + Copyright (C) 2015-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or diff --git a/sysdeps/s390/multiarch/strcpy.c b/sysdeps/s390/multiarch/strcpy.c index f348199112..8f32a13f67 100644 --- a/sysdeps/s390/multiarch/strcpy.c +++ b/sysdeps/s390/multiarch/strcpy.c @@ -1,5 +1,5 @@ /* Multiple versions of strcpy. - Copyright (C) 2015-2016 Free Software Foundation, Inc. + Copyright (C) 2015-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -17,8 +17,11 @@ <http://www.gnu.org/licenses/>. */ #if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) +# define strcpy __redirect_strcpy # include <string.h> +# undef strcpy # include <ifunc-resolve.h> -s390_vx_libc_ifunc2 (__strcpy, strcpy) +s390_vx_libc_ifunc2_redirected (__redirect_strcpy, __strcpy, strcpy) + #endif diff --git a/sysdeps/s390/multiarch/strcspn-c.c b/sysdeps/s390/multiarch/strcspn-c.c index bc195b6625..7b454f5b56 100644 --- a/sysdeps/s390/multiarch/strcspn-c.c +++ b/sysdeps/s390/multiarch/strcspn-c.c @@ -1,5 +1,5 @@ /* Default strcspn implementation for S/390. - Copyright (C) 2015-2016 Free Software Foundation, Inc. + Copyright (C) 2015-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or diff --git a/sysdeps/s390/multiarch/strcspn-vx.S b/sysdeps/s390/multiarch/strcspn-vx.S index 1c6250661e..ea1668742b 100644 --- a/sysdeps/s390/multiarch/strcspn-vx.S +++ b/sysdeps/s390/multiarch/strcspn-vx.S @@ -1,5 +1,5 @@ /* Vector optimized 32/64 bit S/390 version of strcspn. - Copyright (C) 2015-2016 Free Software Foundation, Inc. + Copyright (C) 2015-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or diff --git a/sysdeps/s390/multiarch/strcspn.c b/sysdeps/s390/multiarch/strcspn.c index c23452a791..418ffcdded 100644 --- a/sysdeps/s390/multiarch/strcspn.c +++ b/sysdeps/s390/multiarch/strcspn.c @@ -1,5 +1,5 @@ /* Multiple versions of strcspn. - Copyright (C) 2015-2016 Free Software Foundation, Inc. + Copyright (C) 2015-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -17,10 +17,14 @@ <http://www.gnu.org/licenses/>. */ #if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) +# define strcspn __redirect_strcspn +/* Omit the strcspn inline definitions because it would redefine strcspn. */ +# define __NO_STRING_INLINES # include <string.h> +# undef strcspn # include <ifunc-resolve.h> -s390_vx_libc_ifunc2 (__strcspn, strcspn) +s390_vx_libc_ifunc2_redirected (__redirect_strcspn, __strcspn, strcspn) #else # include <string/strcspn.c> diff --git a/sysdeps/s390/multiarch/strlen-c.c b/sysdeps/s390/multiarch/strlen-c.c index 63c0d9e3e6..a2c8e43624 100644 --- a/sysdeps/s390/multiarch/strlen-c.c +++ b/sysdeps/s390/multiarch/strlen-c.c @@ -1,5 +1,5 @@ /* Default strlen implementation for S/390. - Copyright (C) 2015-2016 Free Software Foundation, Inc. + Copyright (C) 2015-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or diff --git a/sysdeps/s390/multiarch/strlen-vx.S b/sysdeps/s390/multiarch/strlen-vx.S index 3fe834a0c7..9308b33237 100644 --- a/sysdeps/s390/multiarch/strlen-vx.S +++ b/sysdeps/s390/multiarch/strlen-vx.S @@ -1,5 +1,5 @@ /* Vector optimized 32/64 bit S/390 version of strlen. - Copyright (C) 2015-2016 Free Software Foundation, Inc. + Copyright (C) 2015-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or diff --git a/sysdeps/s390/multiarch/strlen.c b/sysdeps/s390/multiarch/strlen.c index 098d4e1e58..0edf8b7d02 100644 --- a/sysdeps/s390/multiarch/strlen.c +++ b/sysdeps/s390/multiarch/strlen.c @@ -1,5 +1,5 @@ /* Multiple versions of strlen. - Copyright (C) 2015-2016 Free Software Foundation, Inc. + Copyright (C) 2015-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -17,10 +17,12 @@ <http://www.gnu.org/licenses/>. */ #if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) +# define strlen __redirect_strlen # include <string.h> # include <ifunc-resolve.h> +# undef strlen -s390_vx_libc_ifunc2 (__strlen, strlen) +s390_vx_libc_ifunc2_redirected (__redirect_strlen, __strlen, strlen) #else # include <string/strlen.c> diff --git a/sysdeps/s390/multiarch/strncat-c.c b/sysdeps/s390/multiarch/strncat-c.c index 538b1fa51e..9e6c245ccb 100644 --- a/sysdeps/s390/multiarch/strncat-c.c +++ b/sysdeps/s390/multiarch/strncat-c.c @@ -1,5 +1,5 @@ /* Default strncat implementation for S/390. - Copyright (C) 2015-2016 Free Software Foundation, Inc. + Copyright (C) 2015-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -18,6 +18,6 @@ #if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) # define STRNCAT __strncat_c - +# define STRNCAT_PRIMARY # include <string/strncat.c> #endif diff --git a/sysdeps/s390/multiarch/strncat-vx.S b/sysdeps/s390/multiarch/strncat-vx.S index b9857c1233..e6584d0f43 100644 --- a/sysdeps/s390/multiarch/strncat-vx.S +++ b/sysdeps/s390/multiarch/strncat-vx.S @@ -1,5 +1,5 @@ /* Vector optimized 32/64 bit S/390 version of strncat. - Copyright (C) 2015-2016 Free Software Foundation, Inc. + Copyright (C) 2015-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or diff --git a/sysdeps/s390/multiarch/strncat.c b/sysdeps/s390/multiarch/strncat.c index eb1410d5ac..94b8dffa85 100644 --- a/sysdeps/s390/multiarch/strncat.c +++ b/sysdeps/s390/multiarch/strncat.c @@ -1,5 +1,5 @@ /* Multiple versions of strncat. - Copyright (C) 2015-2016 Free Software Foundation, Inc. + Copyright (C) 2015-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or diff --git a/sysdeps/s390/multiarch/strncmp-c.c b/sysdeps/s390/multiarch/strncmp-c.c index e781aefbe3..e54277ec1b 100644 --- a/sysdeps/s390/multiarch/strncmp-c.c +++ b/sysdeps/s390/multiarch/strncmp-c.c @@ -1,5 +1,5 @@ /* Default strncmp implementation for S/390. - Copyright (C) 2015-2016 Free Software Foundation, Inc. + Copyright (C) 2015-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or diff --git a/sysdeps/s390/multiarch/strncmp-vx.S b/sysdeps/s390/multiarch/strncmp-vx.S index 9c4b207f41..168fd657da 100644 --- a/sysdeps/s390/multiarch/strncmp-vx.S +++ b/sysdeps/s390/multiarch/strncmp-vx.S @@ -1,5 +1,5 @@ /* Vector optimized 32/64 bit S/390 version of strncmp. - Copyright (C) 2015-2016 Free Software Foundation, Inc. + Copyright (C) 2015-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or diff --git a/sysdeps/s390/multiarch/strncmp.c b/sysdeps/s390/multiarch/strncmp.c index 9a72c79bfd..0ec472c3b0 100644 --- a/sysdeps/s390/multiarch/strncmp.c +++ b/sysdeps/s390/multiarch/strncmp.c @@ -1,5 +1,5 @@ /* Multiple versions of strncmp. - Copyright (C) 2015-2016 Free Software Foundation, Inc. + Copyright (C) 2015-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -17,13 +17,14 @@ <http://www.gnu.org/licenses/>. */ #if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) +# define strncmp __redirect_strncmp +/* Omit the strncmp inline definitions because it would redefine strncmp. */ +# define __NO_STRING_INLINES # include <string.h> +# undef strncmp # include <ifunc-resolve.h> - -# undef strcmp -extern __typeof (strncmp) __strncmp; -s390_vx_libc_ifunc2 (__strncmp, strncmp) +s390_vx_libc_ifunc2_redirected (__redirect_strncmp, __strncmp, strncmp) #else # include <string/strncmp.c> diff --git a/sysdeps/s390/multiarch/strncpy-vx.S b/sysdeps/s390/multiarch/strncpy-vx.S index 08a0b29e8b..2a37b7b84e 100644 --- a/sysdeps/s390/multiarch/strncpy-vx.S +++ b/sysdeps/s390/multiarch/strncpy-vx.S @@ -1,5 +1,5 @@ /* Vector optimized 32/64 bit S/390 version of strncpy. - Copyright (C) 2015-2016 Free Software Foundation, Inc. + Copyright (C) 2015-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or diff --git a/sysdeps/s390/multiarch/strncpy.c b/sysdeps/s390/multiarch/strncpy.c index 1464551875..2d4c456d96 100644 --- a/sysdeps/s390/multiarch/strncpy.c +++ b/sysdeps/s390/multiarch/strncpy.c @@ -1,5 +1,5 @@ /* Multiple versions of strncpy. - Copyright (C) 2015-2016 Free Software Foundation, Inc. + Copyright (C) 2015-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -17,8 +17,13 @@ <http://www.gnu.org/licenses/>. */ #if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) +# define strncpy __redirect_strncpy +/* Omit the strncpy inline definitions because it would redefine strncpy. */ +# define __NO_STRING_INLINES # include <string.h> +# undef strncpy # include <ifunc-resolve.h> -s390_vx_libc_ifunc2 (__strncpy, strncpy) +s390_vx_libc_ifunc2_redirected (__redirect_strncpy, __strncpy, strncpy); + #endif diff --git a/sysdeps/s390/multiarch/strnlen-c.c b/sysdeps/s390/multiarch/strnlen-c.c index 99ad65a103..353e83ed35 100644 --- a/sysdeps/s390/multiarch/strnlen-c.c +++ b/sysdeps/s390/multiarch/strnlen-c.c @@ -1,5 +1,5 @@ /* Default strnlen implementation for S/390. - Copyright (C) 2015-2016 Free Software Foundation, Inc. + Copyright (C) 2015-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or diff --git a/sysdeps/s390/multiarch/strnlen-vx.S b/sysdeps/s390/multiarch/strnlen-vx.S index 3e3a31dd9c..fc659a956c 100644 --- a/sysdeps/s390/multiarch/strnlen-vx.S +++ b/sysdeps/s390/multiarch/strnlen-vx.S @@ -1,5 +1,5 @@ /* Vector optimized 32/64 bit S/390 version of strnlen. - Copyright (C) 2015-2016 Free Software Foundation, Inc. + Copyright (C) 2015-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or diff --git a/sysdeps/s390/multiarch/strnlen.c b/sysdeps/s390/multiarch/strnlen.c index 48c3bb73e6..0f9cff5d69 100644 --- a/sysdeps/s390/multiarch/strnlen.c +++ b/sysdeps/s390/multiarch/strnlen.c @@ -1,5 +1,5 @@ /* Multiple versions of strnlen. - Copyright (C) 2015-2016 Free Software Foundation, Inc. + Copyright (C) 2015-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -17,12 +17,15 @@ <http://www.gnu.org/licenses/>. */ #if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) +# define strnlen __redirect_strnlen +# define __strnlen __redirect___strnlen # include <string.h> +# undef strnlen +# undef __strnlen # include <ifunc-resolve.h> -s390_vx_libc_ifunc (__strnlen) +s390_vx_libc_ifunc_redirected (__redirect___strnlen, __strnlen) weak_alias (__strnlen, strnlen) -libc_hidden_def (strnlen) #else # include <string/strnlen.c> diff --git a/sysdeps/s390/multiarch/strpbrk-c.c b/sysdeps/s390/multiarch/strpbrk-c.c index 49c5e1258b..2c0517aeb5 100644 --- a/sysdeps/s390/multiarch/strpbrk-c.c +++ b/sysdeps/s390/multiarch/strpbrk-c.c @@ -1,5 +1,5 @@ /* Default strpbrk implementation for S/390. - Copyright (C) 2015-2016 Free Software Foundation, Inc. + Copyright (C) 2015-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or diff --git a/sysdeps/s390/multiarch/strpbrk-vx.S b/sysdeps/s390/multiarch/strpbrk-vx.S index 6a0bbd9d19..e19c550ed4 100644 --- a/sysdeps/s390/multiarch/strpbrk-vx.S +++ b/sysdeps/s390/multiarch/strpbrk-vx.S @@ -1,5 +1,5 @@ /* Vector optimized 32/64 bit S/390 version of strpbrk. - Copyright (C) 2015-2016 Free Software Foundation, Inc. + Copyright (C) 2015-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or diff --git a/sysdeps/s390/multiarch/strpbrk.c b/sysdeps/s390/multiarch/strpbrk.c index cdc139929f..11afc268f7 100644 --- a/sysdeps/s390/multiarch/strpbrk.c +++ b/sysdeps/s390/multiarch/strpbrk.c @@ -1,5 +1,5 @@ /* Multiple versions of strpbrk. - Copyright (C) 2015-2016 Free Software Foundation, Inc. + Copyright (C) 2015-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -17,10 +17,14 @@ <http://www.gnu.org/licenses/>. */ #if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) +# define strpbrk __redirect_strpbrk +/* Omit the strpbrk inline definitions because it would redefine strpbrk. */ +# define __NO_STRING_INLINES # include <string.h> +# undef strpbrk # include <ifunc-resolve.h> -s390_vx_libc_ifunc2 (__strpbrk, strpbrk) +s390_vx_libc_ifunc2_redirected (__redirect_strpbrk, __strpbrk, strpbrk) #else # include <string/strpbrk.c> diff --git a/sysdeps/s390/multiarch/strrchr-c.c b/sysdeps/s390/multiarch/strrchr-c.c index 2513af956d..53ceb8086f 100644 --- a/sysdeps/s390/multiarch/strrchr-c.c +++ b/sysdeps/s390/multiarch/strrchr-c.c @@ -1,5 +1,5 @@ /* Default strrchr implementation for S/390. - Copyright (C) 2015-2016 Free Software Foundation, Inc. + Copyright (C) 2015-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or diff --git a/sysdeps/s390/multiarch/strrchr-vx.S b/sysdeps/s390/multiarch/strrchr-vx.S index 175d2cba3c..8b3b989631 100644 --- a/sysdeps/s390/multiarch/strrchr-vx.S +++ b/sysdeps/s390/multiarch/strrchr-vx.S @@ -1,5 +1,5 @@ /* Vector optimized 32/64 bit S/390 version of strrchr. - Copyright (C) 2015-2016 Free Software Foundation, Inc. + Copyright (C) 2015-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or diff --git a/sysdeps/s390/multiarch/strrchr.c b/sysdeps/s390/multiarch/strrchr.c index e515d6b6e6..e00e25a3a4 100644 --- a/sysdeps/s390/multiarch/strrchr.c +++ b/sysdeps/s390/multiarch/strrchr.c @@ -1,5 +1,5 @@ /* Multiple versions of strrchr. - Copyright (C) 2015-2016 Free Software Foundation, Inc. + Copyright (C) 2015-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -17,11 +17,13 @@ <http://www.gnu.org/licenses/>. */ #if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) +# define strrchr __redirect_strrchr # include <string.h> +# undef strrchr # include <ifunc-resolve.h> -s390_vx_libc_ifunc2 (__strrchr, strrchr) -weak_alias (strrchr, rindex) +s390_vx_libc_ifunc2_redirected (__redirect_strrchr, __strrchr, strrchr) +weak_alias (strrchr, rindex); #else # include <string/strrchr.c> diff --git a/sysdeps/s390/multiarch/strspn-c.c b/sysdeps/s390/multiarch/strspn-c.c index 8928d3cc24..0efe61bfb2 100644 --- a/sysdeps/s390/multiarch/strspn-c.c +++ b/sysdeps/s390/multiarch/strspn-c.c @@ -1,5 +1,5 @@ /* Default strspn implementation for S/390. - Copyright (C) 2015-2016 Free Software Foundation, Inc. + Copyright (C) 2015-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or diff --git a/sysdeps/s390/multiarch/strspn-vx.S b/sysdeps/s390/multiarch/strspn-vx.S index 65d295937a..6aa823e63b 100644 --- a/sysdeps/s390/multiarch/strspn-vx.S +++ b/sysdeps/s390/multiarch/strspn-vx.S @@ -1,5 +1,5 @@ /* Vector optimized 32/64 bit S/390 version of strspn. - Copyright (C) 2015-2016 Free Software Foundation, Inc. + Copyright (C) 2015-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or diff --git a/sysdeps/s390/multiarch/strspn.c b/sysdeps/s390/multiarch/strspn.c index 7c26af8ced..bedbe98cfc 100644 --- a/sysdeps/s390/multiarch/strspn.c +++ b/sysdeps/s390/multiarch/strspn.c @@ -1,5 +1,5 @@ /* Multiple versions of strspn. - Copyright (C) 2015-2016 Free Software Foundation, Inc. + Copyright (C) 2015-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -17,10 +17,14 @@ <http://www.gnu.org/licenses/>. */ #if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) +# define strspn __redirect_strspn +/* Omit the strspn inline definitions because it would redefine strspn. */ +# define __NO_STRING_INLINES # include <string.h> +# undef strspn # include <ifunc-resolve.h> -s390_vx_libc_ifunc2 (__strspn, strspn) +s390_vx_libc_ifunc2_redirected (__redirect_strspn, __strspn, strspn) #else # include <string/strspn.c> diff --git a/sysdeps/s390/multiarch/utf16-utf32-z9.c b/sysdeps/s390/multiarch/utf16-utf32-z9.c new file mode 100644 index 0000000000..46a23b09bf --- /dev/null +++ b/sysdeps/s390/multiarch/utf16-utf32-z9.c @@ -0,0 +1,48 @@ +/* Conversion between UTF-16 and UTF-32 BE/internal - multiarch s390 version. + + Copyright (C) 2017-2018 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <sysdeps/s390/utf16-utf32-z9.c> +#include <ifunc-resolve.h> + +#undef FROM_LOOP +#define FROM_LOOP __from_utf16_loop +#undef TO_LOOP +#define TO_LOOP __to_utf16_loop + +#define _SINGLE_NAME(NAME) NAME##_single +#define SINGLE_NAME(NAME) _SINGLE_NAME(NAME) +strong_alias (SINGLE_NAME (FROM_LOOP_DEFAULT), SINGLE_NAME (FROM_LOOP)) +strong_alias (SINGLE_NAME (TO_LOOP_DEFAULT), SINGLE_NAME (TO_LOOP)) + +/* Generate ifunc'ed loop functions for FROM/TO_LOOP. */ +s390_libc_ifunc_expr (FROM_LOOP_DEFAULT, FROM_LOOP, + (HAVE_FROM_VX_CU && (hwcap & HWCAP_S390_VXE)) + ? FROM_LOOP_VX_CU + : (HAVE_FROM_VX && (hwcap & HWCAP_S390_VX)) + ? FROM_LOOP_VX + : FROM_LOOP_DEFAULT); + +s390_libc_ifunc_expr (TO_LOOP_DEFAULT, TO_LOOP, + (HAVE_TO_VX_CU && (hwcap & HWCAP_S390_VXE)) + ? TO_LOOP_VX_CU + : (HAVE_TO_VX && (hwcap & HWCAP_S390_VX)) + ? TO_LOOP_VX + : TO_LOOP_DEFAULT); + +#include <iconv/skeleton.c> diff --git a/sysdeps/s390/multiarch/utf8-utf16-z9.c b/sysdeps/s390/multiarch/utf8-utf16-z9.c new file mode 100644 index 0000000000..ad9b3fbcea --- /dev/null +++ b/sysdeps/s390/multiarch/utf8-utf16-z9.c @@ -0,0 +1,50 @@ +/* Conversion between UTF-8 and UTF-16 - multiarch s390 version. + + Copyright (C) 2017-2018 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <sysdeps/s390/utf8-utf16-z9.c> +#include <ifunc-resolve.h> + +#undef FROM_LOOP +#define FROM_LOOP __from_utf8_loop +#undef TO_LOOP +#define TO_LOOP __to_utf8_loop + +#define _SINGLE_NAME(NAME) NAME##_single +#define SINGLE_NAME(NAME) _SINGLE_NAME(NAME) +strong_alias (SINGLE_NAME (FROM_LOOP_DEFAULT), SINGLE_NAME (FROM_LOOP)) +strong_alias (SINGLE_NAME (TO_LOOP_DEFAULT), SINGLE_NAME (TO_LOOP)) + +/* Generate ifunc'ed loop functions for FROM/TO_LOOP. */ +s390_libc_ifunc_expr (FROM_LOOP_DEFAULT, FROM_LOOP, + (HAVE_FROM_VX && (hwcap & HWCAP_S390_VX)) + ? FROM_LOOP_VX + : (HAVE_FROM_CU && (hwcap & HWCAP_S390_ZARCH + && hwcap & HWCAP_S390_HIGH_GPRS + && hwcap & HWCAP_S390_ETF3EH)) + ? FROM_LOOP_CU + : FROM_LOOP_DEFAULT); + +s390_libc_ifunc_expr (TO_LOOP_DEFAULT, TO_LOOP, + (HAVE_TO_VX_CU && (hwcap & HWCAP_S390_VXE)) + ? TO_LOOP_VX_CU + : (HAVE_TO_VX && (hwcap & HWCAP_S390_VX)) + ? TO_LOOP_VX + : TO_LOOP_DEFAULT); + +#include <iconv/skeleton.c> diff --git a/sysdeps/s390/multiarch/utf8-utf32-z9.c b/sysdeps/s390/multiarch/utf8-utf32-z9.c new file mode 100644 index 0000000000..011feeeea8 --- /dev/null +++ b/sysdeps/s390/multiarch/utf8-utf32-z9.c @@ -0,0 +1,50 @@ +/* Conversion between UTF-8 and UTF-32 - multiarch s390 version. + + Copyright (C) 2017-2018 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <sysdeps/s390/utf8-utf32-z9.c> +#include <ifunc-resolve.h> + +#undef FROM_LOOP +#define FROM_LOOP __from_utf8_loop +#undef TO_LOOP +#define TO_LOOP __to_utf8_loop + +#define _SINGLE_NAME(NAME) NAME##_single +#define SINGLE_NAME(NAME) _SINGLE_NAME(NAME) +strong_alias (SINGLE_NAME (FROM_LOOP_DEFAULT), SINGLE_NAME (FROM_LOOP)) +strong_alias (SINGLE_NAME (TO_LOOP_DEFAULT), SINGLE_NAME (TO_LOOP)) + +/* Generate ifunc'ed loop functions for FROM/TO_LOOP. */ +s390_libc_ifunc_expr (FROM_LOOP_DEFAULT, FROM_LOOP, + (HAVE_FROM_VX && (hwcap & HWCAP_S390_VX)) + ? FROM_LOOP_VX + : (HAVE_FROM_CU && (hwcap & HWCAP_S390_ZARCH + && hwcap & HWCAP_S390_HIGH_GPRS + && hwcap & HWCAP_S390_ETF3EH)) + ? FROM_LOOP_CU + : FROM_LOOP_DEFAULT); + +s390_libc_ifunc_expr (TO_LOOP_DEFAULT, TO_LOOP, + (HAVE_TO_VX_CU && (hwcap & HWCAP_S390_VXE)) + ? TO_LOOP_VX_CU + : (HAVE_TO_VX && (hwcap & HWCAP_S390_VX)) + ? TO_LOOP_VX + : TO_LOOP_DEFAULT); + +#include <iconv/skeleton.c> diff --git a/sysdeps/s390/multiarch/wcpcpy-c.c b/sysdeps/s390/multiarch/wcpcpy-c.c index b4849a3321..e3282fde19 100644 --- a/sysdeps/s390/multiarch/wcpcpy-c.c +++ b/sysdeps/s390/multiarch/wcpcpy-c.c @@ -1,5 +1,5 @@ /* Default wcslen implementation for S/390. - Copyright (C) 2015-2016 Free Software Foundation, Inc. + Copyright (C) 2015-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or diff --git a/sysdeps/s390/multiarch/wcpcpy-vx.S b/sysdeps/s390/multiarch/wcpcpy-vx.S index 8a466c6a37..bff6e85628 100644 --- a/sysdeps/s390/multiarch/wcpcpy-vx.S +++ b/sysdeps/s390/multiarch/wcpcpy-vx.S @@ -1,5 +1,5 @@ /* Vector optimized 32/64 bit S/390 version of wcpcpy. - Copyright (C) 2015-2016 Free Software Foundation, Inc. + Copyright (C) 2015-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or diff --git a/sysdeps/s390/multiarch/wcpcpy.c b/sysdeps/s390/multiarch/wcpcpy.c index 8afd98d7d4..f19d376d85 100644 --- a/sysdeps/s390/multiarch/wcpcpy.c +++ b/sysdeps/s390/multiarch/wcpcpy.c @@ -1,5 +1,5 @@ /* Multiple versions of wcpcpy. - Copyright (C) 2015-2016 Free Software Foundation, Inc. + Copyright (C) 2015-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or diff --git a/sysdeps/s390/multiarch/wcpncpy-c.c b/sysdeps/s390/multiarch/wcpncpy-c.c index 86db27b525..1f44bacea9 100644 --- a/sysdeps/s390/multiarch/wcpncpy-c.c +++ b/sysdeps/s390/multiarch/wcpncpy-c.c @@ -1,5 +1,5 @@ /* Default wcsncpy implementation for S/390. - Copyright (C) 2015-2016 Free Software Foundation, Inc. + Copyright (C) 2015-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or diff --git a/sysdeps/s390/multiarch/wcpncpy-vx.S b/sysdeps/s390/multiarch/wcpncpy-vx.S index ca0203f451..004f512e1f 100644 --- a/sysdeps/s390/multiarch/wcpncpy-vx.S +++ b/sysdeps/s390/multiarch/wcpncpy-vx.S @@ -1,5 +1,5 @@ /* Vector optimized 32/64 bit S/390 version of wcpncpy. - Copyright (C) 2015-2016 Free Software Foundation, Inc. + Copyright (C) 2015-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or diff --git a/sysdeps/s390/multiarch/wcpncpy.c b/sysdeps/s390/multiarch/wcpncpy.c index 13bc543a8a..b72265fbe9 100644 --- a/sysdeps/s390/multiarch/wcpncpy.c +++ b/sysdeps/s390/multiarch/wcpncpy.c @@ -1,5 +1,5 @@ /* Multiple versions of wcpncpy. - Copyright (C) 2015-2016 Free Software Foundation, Inc. + Copyright (C) 2015-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or diff --git a/sysdeps/s390/multiarch/wcscat-c.c b/sysdeps/s390/multiarch/wcscat-c.c index bceec55408..9a31c65a0b 100644 --- a/sysdeps/s390/multiarch/wcscat-c.c +++ b/sysdeps/s390/multiarch/wcscat-c.c @@ -1,5 +1,5 @@ /* Default wcscat implementation for S/390. - Copyright (C) 2015-2016 Free Software Foundation, Inc. + Copyright (C) 2015-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or diff --git a/sysdeps/s390/multiarch/wcscat-vx.S b/sysdeps/s390/multiarch/wcscat-vx.S index 8353caafa9..2164a8da41 100644 --- a/sysdeps/s390/multiarch/wcscat-vx.S +++ b/sysdeps/s390/multiarch/wcscat-vx.S @@ -1,5 +1,5 @@ /* Vector optimized 32/64 bit S/390 version of wcscat. - Copyright (C) 2015-2016 Free Software Foundation, Inc. + Copyright (C) 2015-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or diff --git a/sysdeps/s390/multiarch/wcscat.c b/sysdeps/s390/multiarch/wcscat.c index 8d71c2f1b9..33e4f6da3f 100644 --- a/sysdeps/s390/multiarch/wcscat.c +++ b/sysdeps/s390/multiarch/wcscat.c @@ -1,5 +1,5 @@ /* Multiple versions of wcscat. - Copyright (C) 2015-2016 Free Software Foundation, Inc. + Copyright (C) 2015-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or diff --git a/sysdeps/s390/multiarch/wcschr-c.c b/sysdeps/s390/multiarch/wcschr-c.c index 9ba1d5f861..8d6679c7f2 100644 --- a/sysdeps/s390/multiarch/wcschr-c.c +++ b/sysdeps/s390/multiarch/wcschr-c.c @@ -1,5 +1,5 @@ /* Default wcschr implementation for S/390. - Copyright (C) 2015-2016 Free Software Foundation, Inc. + Copyright (C) 2015-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or diff --git a/sysdeps/s390/multiarch/wcschr-vx.S b/sysdeps/s390/multiarch/wcschr-vx.S index ff7d1c4b4e..94e5df7f36 100644 --- a/sysdeps/s390/multiarch/wcschr-vx.S +++ b/sysdeps/s390/multiarch/wcschr-vx.S @@ -1,5 +1,5 @@ /* Vector optimized 32/64 bit S/390 version of wcschr. - Copyright (C) 2015-2016 Free Software Foundation, Inc. + Copyright (C) 2015-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or diff --git a/sysdeps/s390/multiarch/wcschr.c b/sysdeps/s390/multiarch/wcschr.c index fb51097cd6..f44138f771 100644 --- a/sysdeps/s390/multiarch/wcschr.c +++ b/sysdeps/s390/multiarch/wcschr.c @@ -1,5 +1,5 @@ /* Multiple versions of wcschr. - Copyright (C) 2015-2016 Free Software Foundation, Inc. + Copyright (C) 2015-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -17,12 +17,15 @@ <http://www.gnu.org/licenses/>. */ #if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) +# define wcschr __redirect_wcschr +# define __wcschr __redirect___wcschr # include <wchar.h> +# undef wcschr +# undef __wcschr # include <ifunc-resolve.h> -s390_vx_libc_ifunc (__wcschr) +s390_vx_libc_ifunc_redirected (__redirect___wcschr, __wcschr) weak_alias (__wcschr, wcschr) -libc_hidden_weak (wcschr) #else # include <wcsmbs/wcschr.c> diff --git a/sysdeps/s390/multiarch/wcschrnul-c.c b/sysdeps/s390/multiarch/wcschrnul-c.c index bbee3288fe..00e776a3ad 100644 --- a/sysdeps/s390/multiarch/wcschrnul-c.c +++ b/sysdeps/s390/multiarch/wcschrnul-c.c @@ -1,5 +1,5 @@ /* Default wcschrnul implementation for S/390. - Copyright (C) 2015-2016 Free Software Foundation, Inc. + Copyright (C) 2015-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or diff --git a/sysdeps/s390/multiarch/wcschrnul-vx.S b/sysdeps/s390/multiarch/wcschrnul-vx.S index e54e48d894..ebcd32b870 100644 --- a/sysdeps/s390/multiarch/wcschrnul-vx.S +++ b/sysdeps/s390/multiarch/wcschrnul-vx.S @@ -1,5 +1,5 @@ /* Vector optimized 32/64 bit S/390 version of wcschrnul. - Copyright (C) 2015-2016 Free Software Foundation, Inc. + Copyright (C) 2015-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or diff --git a/sysdeps/s390/multiarch/wcschrnul.c b/sysdeps/s390/multiarch/wcschrnul.c index 7436a596bd..807d7ee089 100644 --- a/sysdeps/s390/multiarch/wcschrnul.c +++ b/sysdeps/s390/multiarch/wcschrnul.c @@ -1,5 +1,5 @@ /* Multiple versions of wcschrnul. - Copyright (C) 2015-2016 Free Software Foundation, Inc. + Copyright (C) 2015-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or diff --git a/sysdeps/s390/multiarch/wcscmp-c.c b/sysdeps/s390/multiarch/wcscmp-c.c index 3add8e4095..ce0817ae97 100644 --- a/sysdeps/s390/multiarch/wcscmp-c.c +++ b/sysdeps/s390/multiarch/wcscmp-c.c @@ -1,5 +1,5 @@ /* Default wcscmp implementation for S/390. - Copyright (C) 2015-2016 Free Software Foundation, Inc. + Copyright (C) 2015-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or diff --git a/sysdeps/s390/multiarch/wcscmp-vx.S b/sysdeps/s390/multiarch/wcscmp-vx.S index 549ae3c733..14267dbfc7 100644 --- a/sysdeps/s390/multiarch/wcscmp-vx.S +++ b/sysdeps/s390/multiarch/wcscmp-vx.S @@ -1,5 +1,5 @@ /* Vector optimized 32/64 bit S/390 version of wcscmp. - Copyright (C) 2015-2016 Free Software Foundation, Inc. + Copyright (C) 2015-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or diff --git a/sysdeps/s390/multiarch/wcscmp.c b/sysdeps/s390/multiarch/wcscmp.c index 705ef4596e..5ee0fd4d88 100644 --- a/sysdeps/s390/multiarch/wcscmp.c +++ b/sysdeps/s390/multiarch/wcscmp.c @@ -1,5 +1,5 @@ /* Multiple versions of wcscmp. - Copyright (C) 2015-2016 Free Software Foundation, Inc. + Copyright (C) 2015-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -17,10 +17,12 @@ <http://www.gnu.org/licenses/>. */ #if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) +# define __wcscmp __redirect___wcscmp # include <wchar.h> +# undef __wcscmp # include <ifunc-resolve.h> -s390_vx_libc_ifunc (__wcscmp) +s390_vx_libc_ifunc_redirected (__redirect___wcscmp, __wcscmp) weak_alias (__wcscmp, wcscmp) #else diff --git a/sysdeps/s390/multiarch/wcscpy-c.c b/sysdeps/s390/multiarch/wcscpy-c.c index 3450c00048..4a510f466b 100644 --- a/sysdeps/s390/multiarch/wcscpy-c.c +++ b/sysdeps/s390/multiarch/wcscpy-c.c @@ -1,5 +1,5 @@ /* Default wcscpy implementation for S/390. - Copyright (C) 2015-2016 Free Software Foundation, Inc. + Copyright (C) 2015-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or diff --git a/sysdeps/s390/multiarch/wcscpy-vx.S b/sysdeps/s390/multiarch/wcscpy-vx.S index 2077893130..c2e81055be 100644 --- a/sysdeps/s390/multiarch/wcscpy-vx.S +++ b/sysdeps/s390/multiarch/wcscpy-vx.S @@ -1,5 +1,5 @@ /* Vector optimized 32/64 bit S/390 version of wcscpy. - Copyright (C) 2015-2016 Free Software Foundation, Inc. + Copyright (C) 2015-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or diff --git a/sysdeps/s390/multiarch/wcscpy.c b/sysdeps/s390/multiarch/wcscpy.c index 8c5f54910b..e69baa6c59 100644 --- a/sysdeps/s390/multiarch/wcscpy.c +++ b/sysdeps/s390/multiarch/wcscpy.c @@ -1,5 +1,5 @@ /* Multiple versions of wcscpy. - Copyright (C) 2015-2016 Free Software Foundation, Inc. + Copyright (C) 2015-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or diff --git a/sysdeps/s390/multiarch/wcscspn-c.c b/sysdeps/s390/multiarch/wcscspn-c.c index e8fd2a53d9..161e52e686 100644 --- a/sysdeps/s390/multiarch/wcscspn-c.c +++ b/sysdeps/s390/multiarch/wcscspn-c.c @@ -1,5 +1,5 @@ /* Default wcscscpn implementation for S/390. - Copyright (C) 2015-2016 Free Software Foundation, Inc. + Copyright (C) 2015-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or diff --git a/sysdeps/s390/multiarch/wcscspn-vx.S b/sysdeps/s390/multiarch/wcscspn-vx.S index b0b1066658..06bc4e25d0 100644 --- a/sysdeps/s390/multiarch/wcscspn-vx.S +++ b/sysdeps/s390/multiarch/wcscspn-vx.S @@ -1,5 +1,5 @@ /* Vector optimized 32/64 bit S/390 version of wcscspn. - Copyright (C) 2015-2016 Free Software Foundation, Inc. + Copyright (C) 2015-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or diff --git a/sysdeps/s390/multiarch/wcscspn.c b/sysdeps/s390/multiarch/wcscspn.c index ebd77734ac..707327522a 100644 --- a/sysdeps/s390/multiarch/wcscspn.c +++ b/sysdeps/s390/multiarch/wcscspn.c @@ -1,5 +1,5 @@ /* Multiple versions of wcscspn. - Copyright (C) 2015-2016 Free Software Foundation, Inc. + Copyright (C) 2015-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or diff --git a/sysdeps/s390/multiarch/wcslen-c.c b/sysdeps/s390/multiarch/wcslen-c.c index dcbe3094d9..32a23e206d 100644 --- a/sysdeps/s390/multiarch/wcslen-c.c +++ b/sysdeps/s390/multiarch/wcslen-c.c @@ -1,5 +1,5 @@ /* Default wcslen implementation for S/390. - Copyright (C) 2015-2016 Free Software Foundation, Inc. + Copyright (C) 2015-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or diff --git a/sysdeps/s390/multiarch/wcslen-vx.S b/sysdeps/s390/multiarch/wcslen-vx.S index dafb7b799d..337cbed6ec 100644 --- a/sysdeps/s390/multiarch/wcslen-vx.S +++ b/sysdeps/s390/multiarch/wcslen-vx.S @@ -1,5 +1,5 @@ /* Vector optimized 32/64 bit S/390 version of wcslen. - Copyright (C) 2015-2016 Free Software Foundation, Inc. + Copyright (C) 2015-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or diff --git a/sysdeps/s390/multiarch/wcslen.c b/sysdeps/s390/multiarch/wcslen.c index 540845f70a..3a1d1a32c9 100644 --- a/sysdeps/s390/multiarch/wcslen.c +++ b/sysdeps/s390/multiarch/wcslen.c @@ -1,5 +1,5 @@ /* Multiple versions of wcslen. - Copyright (C) 2015-2016 Free Software Foundation, Inc. + Copyright (C) 2015-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or diff --git a/sysdeps/s390/multiarch/wcsncat-c.c b/sysdeps/s390/multiarch/wcsncat-c.c index e8cc219eac..2cf1a76385 100644 --- a/sysdeps/s390/multiarch/wcsncat-c.c +++ b/sysdeps/s390/multiarch/wcsncat-c.c @@ -1,5 +1,5 @@ /* Default wcsncat implementation for S/390. - Copyright (C) 2015-2016 Free Software Foundation, Inc. + Copyright (C) 2015-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or diff --git a/sysdeps/s390/multiarch/wcsncat-vx.S b/sysdeps/s390/multiarch/wcsncat-vx.S index 4264f6d21d..1d3935690d 100644 --- a/sysdeps/s390/multiarch/wcsncat-vx.S +++ b/sysdeps/s390/multiarch/wcsncat-vx.S @@ -1,5 +1,5 @@ /* Vector optimized 32/64 bit S/390 version of wcsncat. - Copyright (C) 2015-2016 Free Software Foundation, Inc. + Copyright (C) 2015-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or diff --git a/sysdeps/s390/multiarch/wcsncat.c b/sysdeps/s390/multiarch/wcsncat.c index 62073321e8..c49b8ff786 100644 --- a/sysdeps/s390/multiarch/wcsncat.c +++ b/sysdeps/s390/multiarch/wcsncat.c @@ -1,5 +1,5 @@ /* Multiple versions of wcsncat. - Copyright (C) 2015-2016 Free Software Foundation, Inc. + Copyright (C) 2015-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or diff --git a/sysdeps/s390/multiarch/wcsncmp-c.c b/sysdeps/s390/multiarch/wcsncmp-c.c index 8f2573810d..92ab5e8b50 100644 --- a/sysdeps/s390/multiarch/wcsncmp-c.c +++ b/sysdeps/s390/multiarch/wcsncmp-c.c @@ -1,5 +1,5 @@ /* Default wcsncmp implementation for S/390. - Copyright (C) 2015-2016 Free Software Foundation, Inc. + Copyright (C) 2015-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or diff --git a/sysdeps/s390/multiarch/wcsncmp-vx.S b/sysdeps/s390/multiarch/wcsncmp-vx.S index e77f17dcaf..34c203bc90 100644 --- a/sysdeps/s390/multiarch/wcsncmp-vx.S +++ b/sysdeps/s390/multiarch/wcsncmp-vx.S @@ -1,5 +1,5 @@ /* Vector optimized 32/64 bit S/390 version of wcsncmp. - Copyright (C) 2015-2016 Free Software Foundation, Inc. + Copyright (C) 2015-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or diff --git a/sysdeps/s390/multiarch/wcsncmp.c b/sysdeps/s390/multiarch/wcsncmp.c index 3482d90e4e..ee5f08c1e4 100644 --- a/sysdeps/s390/multiarch/wcsncmp.c +++ b/sysdeps/s390/multiarch/wcsncmp.c @@ -1,5 +1,5 @@ /* Multiple versions of wcsncmp. - Copyright (C) 2015-2016 Free Software Foundation, Inc. + Copyright (C) 2015-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or diff --git a/sysdeps/s390/multiarch/wcsncpy-c.c b/sysdeps/s390/multiarch/wcsncpy-c.c index b63d86ef5f..6b89b8c14b 100644 --- a/sysdeps/s390/multiarch/wcsncpy-c.c +++ b/sysdeps/s390/multiarch/wcsncpy-c.c @@ -1,5 +1,5 @@ /* Default wcsncpy implementation for S/390. - Copyright (C) 2015-2016 Free Software Foundation, Inc. + Copyright (C) 2015-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or diff --git a/sysdeps/s390/multiarch/wcsncpy-vx.S b/sysdeps/s390/multiarch/wcsncpy-vx.S index 33cc33f28b..b3400d50d9 100644 --- a/sysdeps/s390/multiarch/wcsncpy-vx.S +++ b/sysdeps/s390/multiarch/wcsncpy-vx.S @@ -1,5 +1,5 @@ /* Vector optimized 32/64 bit S/390 version of wcsncpy. - Copyright (C) 2015-2016 Free Software Foundation, Inc. + Copyright (C) 2015-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or diff --git a/sysdeps/s390/multiarch/wcsncpy.c b/sysdeps/s390/multiarch/wcsncpy.c index eb225a97b4..7209c7d431 100644 --- a/sysdeps/s390/multiarch/wcsncpy.c +++ b/sysdeps/s390/multiarch/wcsncpy.c @@ -1,5 +1,5 @@ /* Multiple versions of wcsncpy. - Copyright (C) 2015-2016 Free Software Foundation, Inc. + Copyright (C) 2015-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or diff --git a/sysdeps/s390/multiarch/wcsnlen-c.c b/sysdeps/s390/multiarch/wcsnlen-c.c index 89984e9f18..8f43f5104f 100644 --- a/sysdeps/s390/multiarch/wcsnlen-c.c +++ b/sysdeps/s390/multiarch/wcsnlen-c.c @@ -1,5 +1,5 @@ /* Default wcsnlen implementation for S/390. - Copyright (C) 2015-2016 Free Software Foundation, Inc. + Copyright (C) 2015-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or diff --git a/sysdeps/s390/multiarch/wcsnlen-vx.S b/sysdeps/s390/multiarch/wcsnlen-vx.S index 1ba00c3cae..420f29fbc0 100644 --- a/sysdeps/s390/multiarch/wcsnlen-vx.S +++ b/sysdeps/s390/multiarch/wcsnlen-vx.S @@ -1,5 +1,5 @@ /* Vector optimized 32/64 bit S/390 version of wcsnlen. - Copyright (C) 2015-2016 Free Software Foundation, Inc. + Copyright (C) 2015-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or diff --git a/sysdeps/s390/multiarch/wcsnlen.c b/sysdeps/s390/multiarch/wcsnlen.c index 4308472a81..5234074b1f 100644 --- a/sysdeps/s390/multiarch/wcsnlen.c +++ b/sysdeps/s390/multiarch/wcsnlen.c @@ -1,5 +1,5 @@ /* Multiple versions of wcsnlen. - Copyright (C) 2015-2016 Free Software Foundation, Inc. + Copyright (C) 2015-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or diff --git a/sysdeps/s390/multiarch/wcspbrk-c.c b/sysdeps/s390/multiarch/wcspbrk-c.c index 8b74eaf017..6b6e7aade4 100644 --- a/sysdeps/s390/multiarch/wcspbrk-c.c +++ b/sysdeps/s390/multiarch/wcspbrk-c.c @@ -1,5 +1,5 @@ /* Default wcspbrk implementation for S/390. - Copyright (C) 2015-2016 Free Software Foundation, Inc. + Copyright (C) 2015-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or diff --git a/sysdeps/s390/multiarch/wcspbrk-vx.S b/sysdeps/s390/multiarch/wcspbrk-vx.S index 3e28e9aa90..5c89ec5d33 100644 --- a/sysdeps/s390/multiarch/wcspbrk-vx.S +++ b/sysdeps/s390/multiarch/wcspbrk-vx.S @@ -1,5 +1,5 @@ /* Vector optimized 32/64 bit S/390 version of wcspbrk. - Copyright (C) 2015-2016 Free Software Foundation, Inc. + Copyright (C) 2015-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or diff --git a/sysdeps/s390/multiarch/wcspbrk.c b/sysdeps/s390/multiarch/wcspbrk.c index 198144d2c5..97876328b5 100644 --- a/sysdeps/s390/multiarch/wcspbrk.c +++ b/sysdeps/s390/multiarch/wcspbrk.c @@ -1,5 +1,5 @@ /* Multiple versions of wcspbrk. - Copyright (C) 2015-2016 Free Software Foundation, Inc. + Copyright (C) 2015-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -17,10 +17,12 @@ <http://www.gnu.org/licenses/>. */ #if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) +# define wcspbrk __redirect_wcspbrk # include <wchar.h> +# undef wcspbrk # include <ifunc-resolve.h> -s390_vx_libc_ifunc2 (__wcspbrk, wcspbrk) +s390_vx_libc_ifunc2_redirected (__redirect_wcspbrk, __wcspbrk, wcspbrk) #else # include <wcsmbs/wcspbrk.c> diff --git a/sysdeps/s390/multiarch/wcsrchr-c.c b/sysdeps/s390/multiarch/wcsrchr-c.c index eac588b79e..615250358b 100644 --- a/sysdeps/s390/multiarch/wcsrchr-c.c +++ b/sysdeps/s390/multiarch/wcsrchr-c.c @@ -1,5 +1,5 @@ /* Default wcsrchr implementation for S/390. - Copyright (C) 2015-2016 Free Software Foundation, Inc. + Copyright (C) 2015-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or diff --git a/sysdeps/s390/multiarch/wcsrchr-vx.S b/sysdeps/s390/multiarch/wcsrchr-vx.S index 0b99edc7a5..e40a554e5d 100644 --- a/sysdeps/s390/multiarch/wcsrchr-vx.S +++ b/sysdeps/s390/multiarch/wcsrchr-vx.S @@ -1,5 +1,5 @@ /* Vector optimized 32/64 bit S/390 version of wcsrchr. - Copyright (C) 2015-2016 Free Software Foundation, Inc. + Copyright (C) 2015-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or diff --git a/sysdeps/s390/multiarch/wcsrchr.c b/sysdeps/s390/multiarch/wcsrchr.c index 9281e12898..aa0b8a8f82 100644 --- a/sysdeps/s390/multiarch/wcsrchr.c +++ b/sysdeps/s390/multiarch/wcsrchr.c @@ -1,5 +1,5 @@ /* Multiple versions of wcsrchr. - Copyright (C) 2015-2016 Free Software Foundation, Inc. + Copyright (C) 2015-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or diff --git a/sysdeps/s390/multiarch/wcsspn-c.c b/sysdeps/s390/multiarch/wcsspn-c.c index 54c2698bd8..2c0bd0f4e6 100644 --- a/sysdeps/s390/multiarch/wcsspn-c.c +++ b/sysdeps/s390/multiarch/wcsspn-c.c @@ -1,5 +1,5 @@ /* Default wcsspn implementation for S/390. - Copyright (C) 2015-2016 Free Software Foundation, Inc. + Copyright (C) 2015-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or diff --git a/sysdeps/s390/multiarch/wcsspn-vx.S b/sysdeps/s390/multiarch/wcsspn-vx.S index e1785ea7cf..548f2ad164 100644 --- a/sysdeps/s390/multiarch/wcsspn-vx.S +++ b/sysdeps/s390/multiarch/wcsspn-vx.S @@ -1,5 +1,5 @@ /* Vector optimized 32/64 bit S/390 version of wcsspn. - Copyright (C) 2015-2016 Free Software Foundation, Inc. + Copyright (C) 2015-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or diff --git a/sysdeps/s390/multiarch/wcsspn.c b/sysdeps/s390/multiarch/wcsspn.c index 167a881d13..7743144a8c 100644 --- a/sysdeps/s390/multiarch/wcsspn.c +++ b/sysdeps/s390/multiarch/wcsspn.c @@ -1,5 +1,5 @@ /* Multiple versions of wcsspn. - Copyright (C) 2015-2016 Free Software Foundation, Inc. + Copyright (C) 2015-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -17,10 +17,12 @@ <http://www.gnu.org/licenses/>. */ #if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) +# define wcsspn __redirect_wcsspn # include <wchar.h> +# undef wcsspn # include <ifunc-resolve.h> -s390_vx_libc_ifunc2 (__wcsspn, wcsspn) +s390_vx_libc_ifunc2_redirected (__redirect_wcsspn, __wcsspn, wcsspn) #else # include <wcsmbs/wcsspn.c> diff --git a/sysdeps/s390/multiarch/wmemchr-c.c b/sysdeps/s390/multiarch/wmemchr-c.c index 32dddc6c3d..089392b512 100644 --- a/sysdeps/s390/multiarch/wmemchr-c.c +++ b/sysdeps/s390/multiarch/wmemchr-c.c @@ -1,5 +1,5 @@ /* Default wmemchr implementation for S/390. - Copyright (C) 2015-2016 Free Software Foundation, Inc. + Copyright (C) 2015-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or diff --git a/sysdeps/s390/multiarch/wmemchr-vx.S b/sysdeps/s390/multiarch/wmemchr-vx.S index a729681341..db057b579a 100644 --- a/sysdeps/s390/multiarch/wmemchr-vx.S +++ b/sysdeps/s390/multiarch/wmemchr-vx.S @@ -1,5 +1,5 @@ /* Vector optimized 32/64 bit S/390 version of wmemchr. - Copyright (C) 2015-2016 Free Software Foundation, Inc. + Copyright (C) 2015-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or diff --git a/sysdeps/s390/multiarch/wmemchr.c b/sysdeps/s390/multiarch/wmemchr.c index f2bfe3c7a5..6b55c1d7fa 100644 --- a/sysdeps/s390/multiarch/wmemchr.c +++ b/sysdeps/s390/multiarch/wmemchr.c @@ -1,5 +1,5 @@ /* Multiple versions of wmemchr. - Copyright (C) 2015-2016 Free Software Foundation, Inc. + Copyright (C) 2015-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -17,12 +17,15 @@ <http://www.gnu.org/licenses/>. */ #if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) +# define wmemchr __redirect_wmemchr +# define __wmemchr __redirect___wmemchr # include <wchar.h> +# undef wmemchr +# undef __wmemchr # include <ifunc-resolve.h> -s390_vx_libc_ifunc (__wmemchr) +s390_vx_libc_ifunc_redirected (__redirect___wmemchr, __wmemchr) weak_alias (__wmemchr, wmemchr) -libc_hidden_weak (wmemchr) #else # include <wcsmbs/wmemchr.c> diff --git a/sysdeps/s390/multiarch/wmemcmp-c.c b/sysdeps/s390/multiarch/wmemcmp-c.c index 683385431e..2fd39d5013 100644 --- a/sysdeps/s390/multiarch/wmemcmp-c.c +++ b/sysdeps/s390/multiarch/wmemcmp-c.c @@ -1,5 +1,5 @@ /* Default wmemcmp implementation for S/390. - Copyright (C) 2015-2016 Free Software Foundation, Inc. + Copyright (C) 2015-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or diff --git a/sysdeps/s390/multiarch/wmemcmp-vx.S b/sysdeps/s390/multiarch/wmemcmp-vx.S index 761cc17771..e2fc21e419 100644 --- a/sysdeps/s390/multiarch/wmemcmp-vx.S +++ b/sysdeps/s390/multiarch/wmemcmp-vx.S @@ -1,5 +1,5 @@ /* Vector Optimized 32/64 bit S/390 version of wmemcmp. - Copyright (C) 2015-2016 Free Software Foundation, Inc. + Copyright (C) 2015-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or diff --git a/sysdeps/s390/multiarch/wmemcmp.c b/sysdeps/s390/multiarch/wmemcmp.c index 95106fcaf9..a4cb440c45 100644 --- a/sysdeps/s390/multiarch/wmemcmp.c +++ b/sysdeps/s390/multiarch/wmemcmp.c @@ -1,5 +1,5 @@ /* Multiple versions of wmemcmp. - Copyright (C) 2015-2016 Free Software Foundation, Inc. + Copyright (C) 2015-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or diff --git a/sysdeps/s390/multiarch/wmemset-c.c b/sysdeps/s390/multiarch/wmemset-c.c index 61ccd8fc09..1969cf93dc 100644 --- a/sysdeps/s390/multiarch/wmemset-c.c +++ b/sysdeps/s390/multiarch/wmemset-c.c @@ -1,5 +1,5 @@ /* Default wmemset implementation for S/390. - Copyright (C) 2015-2016 Free Software Foundation, Inc. + Copyright (C) 2015-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or diff --git a/sysdeps/s390/multiarch/wmemset-vx.S b/sysdeps/s390/multiarch/wmemset-vx.S index 7a28bb4ca6..0c2f6337b0 100644 --- a/sysdeps/s390/multiarch/wmemset-vx.S +++ b/sysdeps/s390/multiarch/wmemset-vx.S @@ -1,5 +1,5 @@ /* Vector Optimized 32/64 bit S/390 version of wmemset. - Copyright (C) 2015-2016 Free Software Foundation, Inc. + Copyright (C) 2015-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or diff --git a/sysdeps/s390/multiarch/wmemset.c b/sysdeps/s390/multiarch/wmemset.c index e9e695fc0a..149b481470 100644 --- a/sysdeps/s390/multiarch/wmemset.c +++ b/sysdeps/s390/multiarch/wmemset.c @@ -1,5 +1,5 @@ /* Multiple versions of wmemset. - Copyright (C) 2015-2016 Free Software Foundation, Inc. + Copyright (C) 2015-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -17,12 +17,15 @@ <http://www.gnu.org/licenses/>. */ #if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) +# define wmemset __redirect_wmemset +# define __wmemset __redirect___wmemset # include <wchar.h> +# undef wmemset +# undef __wmemset # include <ifunc-resolve.h> -s390_vx_libc_ifunc (__wmemset) +s390_vx_libc_ifunc_redirected (__redirect___wmemset, __wmemset) weak_alias (__wmemset, wmemset) -libc_hidden_weak (wmemset) #else # include <wcsmbs/wmemset.c> diff --git a/sysdeps/s390/nptl/Makefile b/sysdeps/s390/nptl/Makefile index 5734b983b0..2b0d392c06 100644 --- a/sysdeps/s390/nptl/Makefile +++ b/sysdeps/s390/nptl/Makefile @@ -1,4 +1,4 @@ -# Copyright (C) 2003-2016 Free Software Foundation, Inc. +# Copyright (C) 2003-2018 Free Software Foundation, Inc. # This file is part of the GNU C Library. # The GNU C Library is free software; you can redistribute it and/or @@ -20,5 +20,6 @@ gen-as-const-headers += tcb-offsets.sym endif ifeq ($(subdir),nptl) -libpthread-routines += ptw-sysdep +libpthread-routines += sysdep +libpthread-shared-only-routines += sysdep endif diff --git a/sysdeps/s390/nptl/bits/pthreadtypes-arch.h b/sysdeps/s390/nptl/bits/pthreadtypes-arch.h new file mode 100644 index 0000000000..20db42c8a0 --- /dev/null +++ b/sysdeps/s390/nptl/bits/pthreadtypes-arch.h @@ -0,0 +1,79 @@ +/* Copyright (C) 2003-2018 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#ifndef _BITS_PTHREADTYPES_ARCH_H +#define _BITS_PTHREADTYPES_ARCH_H 1 + +#include <bits/wordsize.h> + +#if __WORDSIZE == 64 +# define __SIZEOF_PTHREAD_ATTR_T 56 +# define __SIZEOF_PTHREAD_MUTEX_T 40 +# define __SIZEOF_PTHREAD_RWLOCK_T 56 +# define __SIZEOF_PTHREAD_BARRIER_T 32 +#else +# define __SIZEOF_PTHREAD_ATTR_T 36 +# define __SIZEOF_PTHREAD_MUTEX_T 24 +# define __SIZEOF_PTHREAD_RWLOCK_T 32 +# define __SIZEOF_PTHREAD_BARRIER_T 20 +#endif +#define __SIZEOF_PTHREAD_MUTEXATTR_T 4 +#define __SIZEOF_PTHREAD_CONDATTR_T 4 +#define __SIZEOF_PTHREAD_COND_T 48 +#define __SIZEOF_PTHREAD_RWLOCKATTR_T 8 +#define __SIZEOF_PTHREAD_BARRIERATTR_T 4 + +/* Definitions for internal mutex struct. */ +#define __PTHREAD_COMPAT_PADDING_MID +#define __PTHREAD_COMPAT_PADDING_END +#define __PTHREAD_MUTEX_LOCK_ELISION 1 +#define __PTHREAD_MUTEX_NUSERS_AFTER_KIND (__WORDSIZE != 64) +#define __PTHREAD_MUTEX_USE_UNION (__WORDSIZE != 64) + +#define __LOCK_ALIGNMENT +#define __ONCE_ALIGNMENT + +struct __pthread_rwlock_arch_t +{ + unsigned int __readers; + unsigned int __writers; + unsigned int __wrphase_futex; + unsigned int __writers_futex; + unsigned int __pad3; + unsigned int __pad4; +#if __WORDSIZE == 64 + int __cur_writer; + int __shared; + unsigned long int __pad1; + unsigned long int __pad2; + /* FLAGS must stay at this position in the structure to maintain + binary compatibility. */ + unsigned int __flags; +# else + unsigned char __pad1; + unsigned char __pad2; + unsigned char __shared; + /* FLAGS must stay at this position in the structure to maintain + binary compatibility. */ + unsigned char __flags; + int __cur_writer; +#endif +}; + +#define __PTHREAD_RWLOCK_ELISION_EXTRA 0 + +#endif /* bits/pthreadtypes.h */ diff --git a/sysdeps/s390/nptl/bits/pthreadtypes.h b/sysdeps/s390/nptl/bits/pthreadtypes.h deleted file mode 100644 index 40d10fea59..0000000000 --- a/sysdeps/s390/nptl/bits/pthreadtypes.h +++ /dev/null @@ -1,248 +0,0 @@ -/* Copyright (C) 2003-2016 Free Software Foundation, Inc. - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, see - <http://www.gnu.org/licenses/>. */ - -#ifndef _BITS_PTHREADTYPES_H -#define _BITS_PTHREADTYPES_H 1 - -#include <bits/wordsize.h> - -#if __WORDSIZE == 64 -# define __SIZEOF_PTHREAD_ATTR_T 56 -# define __SIZEOF_PTHREAD_MUTEX_T 40 -# define __SIZEOF_PTHREAD_MUTEXATTR_T 4 -# define __SIZEOF_PTHREAD_COND_T 48 -# define __SIZEOF_PTHREAD_CONDATTR_T 4 -# define __SIZEOF_PTHREAD_RWLOCK_T 56 -# define __SIZEOF_PTHREAD_RWLOCKATTR_T 8 -# define __SIZEOF_PTHREAD_BARRIER_T 32 -# define __SIZEOF_PTHREAD_BARRIERATTR_T 4 -#else -# define __SIZEOF_PTHREAD_ATTR_T 36 -# define __SIZEOF_PTHREAD_MUTEX_T 24 -# define __SIZEOF_PTHREAD_MUTEXATTR_T 4 -# define __SIZEOF_PTHREAD_COND_T 48 -# define __SIZEOF_PTHREAD_CONDATTR_T 4 -# define __SIZEOF_PTHREAD_RWLOCK_T 32 -# define __SIZEOF_PTHREAD_RWLOCKATTR_T 8 -# define __SIZEOF_PTHREAD_BARRIER_T 20 -# define __SIZEOF_PTHREAD_BARRIERATTR_T 4 -#endif - - -/* Thread identifiers. The structure of the attribute type is not - exposed on purpose. */ -typedef unsigned long int pthread_t; - - -union pthread_attr_t -{ - char __size[__SIZEOF_PTHREAD_ATTR_T]; - long int __align; -}; -#ifndef __have_pthread_attr_t -typedef union pthread_attr_t pthread_attr_t; -# define __have_pthread_attr_t 1 -#endif - - -#if __WORDSIZE == 64 -typedef struct __pthread_internal_list -{ - struct __pthread_internal_list *__prev; - struct __pthread_internal_list *__next; -} __pthread_list_t; -#else -typedef struct __pthread_internal_slist -{ - struct __pthread_internal_slist *__next; -} __pthread_slist_t; -#endif - - -/* Data structures for mutex handling. The structure of the attribute - type is not exposed on purpose. */ -typedef union -{ - struct __pthread_mutex_s - { - int __lock; - unsigned int __count; - int __owner; -#if __WORDSIZE == 64 - unsigned int __nusers; -#endif - /* KIND must stay at this position in the structure to maintain - binary compatibility. */ - int __kind; -#if __WORDSIZE == 64 -# ifdef ENABLE_LOCK_ELISION - short __spins; - short __elision; - /* Mutex __spins initializer used by PTHREAD_MUTEX_INITIALIZER. */ -# define __PTHREAD_SPINS 0, 0 -# else - int __spins; - /* Mutex __spins initializer used by PTHREAD_MUTEX_INITIALIZER. */ -# define __PTHREAD_SPINS 0 -# endif - __pthread_list_t __list; -# define __PTHREAD_MUTEX_HAVE_PREV 1 -#else - unsigned int __nusers; - __extension__ union - { -# ifdef ENABLE_LOCK_ELISION - struct - { - short __espins; - short __elision; - } _d; -# define __spins _d.__espins -# define __elision _d.__elision - /* Mutex __spins initializer used by PTHREAD_MUTEX_INITIALIZER. */ -# define __PTHREAD_SPINS { 0, 0 } -# else - int __spins; - /* Mutex __spins initializer used by PTHREAD_MUTEX_INITIALIZER. */ -# define __PTHREAD_SPINS 0 -# endif - __pthread_slist_t __list; - }; -#endif - } __data; - char __size[__SIZEOF_PTHREAD_MUTEX_T]; - long int __align; -} pthread_mutex_t; - - -typedef union -{ - char __size[__SIZEOF_PTHREAD_MUTEXATTR_T]; - int __align; -} pthread_mutexattr_t; - - -/* Data structure for conditional variable handling. The structure of - the attribute type is not exposed on purpose. */ -typedef union -{ - struct - { - int __lock; - unsigned int __futex; - __extension__ unsigned long long int __total_seq; - __extension__ unsigned long long int __wakeup_seq; - __extension__ unsigned long long int __woken_seq; - void *__mutex; - unsigned int __nwaiters; - unsigned int __broadcast_seq; - } __data; - char __size[__SIZEOF_PTHREAD_COND_T]; - __extension__ long long int __align; -} pthread_cond_t; - -typedef union -{ - char __size[__SIZEOF_PTHREAD_CONDATTR_T]; - int __align; -} pthread_condattr_t; - - -/* Keys for thread-specific data */ -typedef unsigned int pthread_key_t; - - -/* Once-only execution */ -typedef int pthread_once_t; - - -#if defined __USE_UNIX98 || defined __USE_XOPEN2K -/* Data structure for read-write lock variable handling. The - structure of the attribute type is not exposed on purpose. */ -typedef union -{ -# if __WORDSIZE == 64 - struct - { - int __lock; - unsigned int __nr_readers; - unsigned int __readers_wakeup; - unsigned int __writer_wakeup; - unsigned int __nr_readers_queued; - unsigned int __nr_writers_queued; - int __writer; - int __shared; - unsigned long int __pad1; - unsigned long int __pad2; - /* FLAGS must stay at this position in the structure to maintain - binary compatibility. */ - unsigned int __flags; - } __data; -# else - struct - { - int __lock; - unsigned int __nr_readers; - unsigned int __readers_wakeup; - unsigned int __writer_wakeup; - unsigned int __nr_readers_queued; - unsigned int __nr_writers_queued; - unsigned char __pad1; - unsigned char __pad2; - unsigned char __shared; - /* FLAGS must stay at this position in the structure to maintain - binary compatibility. */ - unsigned char __flags; - int __writer; - } __data; -# endif - char __size[__SIZEOF_PTHREAD_RWLOCK_T]; - long int __align; -} pthread_rwlock_t; - -#define __PTHREAD_RWLOCK_ELISION_EXTRA 0 - -typedef union -{ - char __size[__SIZEOF_PTHREAD_RWLOCKATTR_T]; - long int __align; -} pthread_rwlockattr_t; -#endif - - -#ifdef __USE_XOPEN2K -/* POSIX spinlock data type. */ -typedef volatile int pthread_spinlock_t; - - -/* POSIX barriers data type. The structure of the type is - deliberately not exposed. */ -typedef union -{ - char __size[__SIZEOF_PTHREAD_BARRIER_T]; - long int __align; -} pthread_barrier_t; - -typedef union -{ - char __size[__SIZEOF_PTHREAD_BARRIERATTR_T]; - int __align; -} pthread_barrierattr_t; -#endif - - -#endif /* bits/pthreadtypes.h */ diff --git a/sysdeps/s390/nptl/bits/semaphore.h b/sysdeps/s390/nptl/bits/semaphore.h index 0d756abc42..cb1b294922 100644 --- a/sysdeps/s390/nptl/bits/semaphore.h +++ b/sysdeps/s390/nptl/bits/semaphore.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2003-2016 Free Software Foundation, Inc. +/* Copyright (C) 2003-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Martin Schwidefsky <schwidefsky@de.ibm.com>, 2003. diff --git a/sysdeps/s390/nptl/pthread-offsets.h b/sysdeps/s390/nptl/pthread-offsets.h new file mode 100644 index 0000000000..bdda1f197e --- /dev/null +++ b/sysdeps/s390/nptl/pthread-offsets.h @@ -0,0 +1,15 @@ +#include <bits/wordsize.h> + +#if __WORDSIZE == 64 +# define __PTHREAD_MUTEX_NUSERS_OFFSET 12 +# define __PTHREAD_MUTEX_KIND_OFFSET 16 +# define __PTHREAD_MUTEX_SPINS_OFFSET 20 +# define __PTHREAD_MUTEX_ELISION_OFFSET 22 +# define __PTHREAD_MUTEX_LIST_OFFSET 24 +#else +# define __PTHREAD_MUTEX_NUSERS_OFFSET 16 +# define __PTHREAD_MUTEX_KIND_OFFSET 12 +# define __PTHREAD_MUTEX_SPINS_OFFSET 20 +# define __PTHREAD_MUTEX_ELISION_OFFSET 22 +# define __PTHREAD_MUTEX_LIST_OFFSET 20 +#endif diff --git a/sysdeps/s390/nptl/pthreaddef.h b/sysdeps/s390/nptl/pthreaddef.h index d483f11103..410ae7b896 100644 --- a/sysdeps/s390/nptl/pthreaddef.h +++ b/sysdeps/s390/nptl/pthreaddef.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2003-2016 Free Software Foundation, Inc. +/* Copyright (C) 2003-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or diff --git a/sysdeps/s390/nptl/tcb-offsets.sym b/sysdeps/s390/nptl/tcb-offsets.sym index 9cfae211e0..9c1c01f353 100644 --- a/sysdeps/s390/nptl/tcb-offsets.sym +++ b/sysdeps/s390/nptl/tcb-offsets.sym @@ -3,5 +3,4 @@ MULTIPLE_THREADS_OFFSET offsetof (tcbhead_t, multiple_threads) STACK_GUARD offsetof (tcbhead_t, stack_guard) -PID offsetof (struct pthread, pid) TID offsetof (struct pthread, tid) diff --git a/sysdeps/s390/nptl/tls.h b/sysdeps/s390/nptl/tls.h index e4c3ec7830..220bdfffb3 100644 --- a/sysdeps/s390/nptl/tls.h +++ b/sysdeps/s390/nptl/tls.h @@ -1,5 +1,5 @@ /* Definition for thread-local data handling. NPTL/s390 version. - Copyright (C) 2003-2016 Free Software Foundation, Inc. + Copyright (C) 2003-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -27,19 +27,7 @@ # include <stdlib.h> # include <list.h> # include <kernel-features.h> - - -/* Type for the dtv. */ -typedef union dtv -{ - size_t counter; - struct - { - void *val; - bool is_static; - } pointer; -} dtv_t; - +# include <dl-dtv.h> typedef struct { @@ -51,11 +39,7 @@ typedef struct uintptr_t sysinfo; uintptr_t stack_guard; int gscope_flag; -#ifndef __ASSUME_PRIVATE_FUTEX - int private_futex; -#else int __glibc_reserved1; -#endif /* GCC split stack support. */ void *__private_ss; } tcbhead_t; @@ -181,6 +165,7 @@ typedef struct #define THREAD_COPY_POINTER_GUARD(descr) /* Get and set the global scope generation counter in struct pthread. */ +#define THREAD_GSCOPE_IN_TCB 1 #define THREAD_GSCOPE_FLAG_UNUSED 0 #define THREAD_GSCOPE_FLAG_USED 1 #define THREAD_GSCOPE_FLAG_WAIT 2 diff --git a/sysdeps/s390/s390-32/Makefile b/sysdeps/s390/s390-32/Makefile index 057862d91b..a07f2986ae 100644 --- a/sysdeps/s390/s390-32/Makefile +++ b/sysdeps/s390/s390-32/Makefile @@ -1,5 +1,3 @@ -pic-ccflag = -fpic - ifeq ($(subdir),gmon) sysdep_routines += s390-mcount endif diff --git a/sysdeps/s390/s390-32/__longjmp.c b/sysdeps/s390/s390-32/__longjmp.c index 2631cfd32f..eb3f78b383 100644 --- a/sysdeps/s390/s390-32/__longjmp.c +++ b/sysdeps/s390/s390-32/__longjmp.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2000-2016 Free Software Foundation, Inc. +/* Copyright (C) 2000-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com). diff --git a/sysdeps/s390/s390-32/add_n.S b/sysdeps/s390/s390-32/add_n.S index b8e915712e..0232a1b31e 100644 --- a/sysdeps/s390/s390-32/add_n.S +++ b/sysdeps/s390/s390-32/add_n.S @@ -1,6 +1,6 @@ /* Add two limb vectors of the same length > 0 and store sum in a third limb vector. - Copyright (C) 2000-2016 Free Software Foundation, Inc. + Copyright (C) 2000-2018 Free Software Foundation, Inc. Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com). This file is part of the GNU MP Library. diff --git a/sysdeps/s390/s390-32/addmul_1.S b/sysdeps/s390/s390-32/addmul_1.S index 160c599d16..ff592cf34e 100644 --- a/sysdeps/s390/s390-32/addmul_1.S +++ b/sysdeps/s390/s390-32/addmul_1.S @@ -1,6 +1,6 @@ /* S390 __mpn_addmul_1 -- Multiply a limb vector with a limb and add the result to a second limb vector. - Copyright (C) 2000-2016 Free Software Foundation, Inc. + Copyright (C) 2000-2018 Free Software Foundation, Inc. Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com). This file is part of the GNU MP Library. diff --git a/sysdeps/s390/s390-32/backtrace.c b/sysdeps/s390/s390-32/backtrace.c index a8290ed86a..f9e85b26d9 100644 --- a/sysdeps/s390/s390-32/backtrace.c +++ b/sysdeps/s390/s390-32/backtrace.c @@ -1,5 +1,5 @@ /* Return backtrace of current program state. - Copyright (C) 2000-2016 Free Software Foundation, Inc. + Copyright (C) 2000-2018 Free Software Foundation, Inc. Contributed by Martin Schwidefsky <schwidefsky@de.ibm.com>. This file is part of the GNU C Library. diff --git a/sysdeps/s390/s390-32/bcopy.S b/sysdeps/s390/s390-32/bcopy.S index cc64cb9aa7..560e04fdee 100644 --- a/sysdeps/s390/s390-32/bcopy.S +++ b/sysdeps/s390/s390-32/bcopy.S @@ -1,6 +1,6 @@ /* bcopy -- copy a block from source to destination. S/390 version. This file is part of the GNU C Library. - Copyright (C) 2000-2016 Free Software Foundation, Inc. + Copyright (C) 2000-2018 Free Software Foundation, Inc. Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com). The GNU C Library is free software; you can redistribute it and/or diff --git a/sysdeps/s390/s390-32/bits/wordsize.h b/sysdeps/s390/s390-32/bits/wordsize.h index da791fa28e..129e47182b 100644 --- a/sysdeps/s390/s390-32/bits/wordsize.h +++ b/sysdeps/s390/s390-32/bits/wordsize.h @@ -5,15 +5,7 @@ #else # define __WORDSIZE 32 # define __WORDSIZE32_SIZE_ULONG 1 +# define __WORDSIZE32_PTRDIFF_LONG 0 #endif -#if !defined __NO_LONG_DOUBLE_MATH && !defined __LONG_DOUBLE_MATH_OPTIONAL - -/* Signal that we didn't used to have a `long double'. The changes all - the `long double' function variants to be redirects to the double - functions. */ -# define __LONG_DOUBLE_MATH_OPTIONAL 1 -# ifndef __LONG_DOUBLE_128__ -# define __NO_LONG_DOUBLE_MATH 1 -# endif -#endif +#define __WORDSIZE_TIME64_COMPAT32 0 diff --git a/sysdeps/s390/s390-32/bzero.S b/sysdeps/s390/s390-32/bzero.S index 4cbb62e06e..897aa2154a 100644 --- a/sysdeps/s390/s390-32/bzero.S +++ b/sysdeps/s390/s390-32/bzero.S @@ -1,6 +1,6 @@ /* bzero -- set a block of memory to zero. IBM S390 version This file is part of the GNU C Library. - Copyright (C) 2000-2016 Free Software Foundation, Inc. + Copyright (C) 2000-2018 Free Software Foundation, Inc. Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com). The GNU C Library is free software; you can redistribute it and/or diff --git a/sysdeps/s390/s390-32/crti.S b/sysdeps/s390/s390-32/crti.S index 5db5b1e900..44b1a704fd 100644 --- a/sysdeps/s390/s390-32/crti.S +++ b/sysdeps/s390/s390-32/crti.S @@ -1,5 +1,5 @@ /* Special .init and .fini section support for S/390. - Copyright (C) 2000-2016 Free Software Foundation, Inc. + Copyright (C) 2000-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -57,6 +57,7 @@ .section .init,"ax",@progbits .globl _init + .hidden _init .type _init,@function .align 4 _init: @@ -88,6 +89,7 @@ _init: .section .fini,"ax",@progbits .globl _fini + .hidden _fini .type _fini,@function .align 4 _fini: diff --git a/sysdeps/s390/s390-32/crtn.S b/sysdeps/s390/s390-32/crtn.S index 73677917dc..6cc476ea43 100644 --- a/sysdeps/s390/s390-32/crtn.S +++ b/sysdeps/s390/s390-32/crtn.S @@ -1,5 +1,5 @@ /* Special .init and .fini section support for S/390. - Copyright (C) 2000-2016 Free Software Foundation, Inc. + Copyright (C) 2000-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or diff --git a/sysdeps/s390/s390-32/dl-machine.h b/sysdeps/s390/s390-32/dl-machine.h index 14bde3b58d..ded41adff8 100644 --- a/sysdeps/s390/s390-32/dl-machine.h +++ b/sysdeps/s390/s390-32/dl-machine.h @@ -1,5 +1,5 @@ /* Machine-dependent ELF dynamic relocation inline functions. S390 Version. - Copyright (C) 2000-2016 Free Software Foundation, Inc. + Copyright (C) 2000-2018 Free Software Foundation, Inc. Contributed by Carl Pederson & Martin Schwidefsky. This file is part of the GNU C Library. @@ -89,6 +89,11 @@ elf_machine_runtime_setup (struct link_map *l, int lazy, int profile) { extern void _dl_runtime_resolve (Elf32_Word); extern void _dl_runtime_profile (Elf32_Word); +#if defined HAVE_S390_VX_ASM_SUPPORT + extern void _dl_runtime_resolve_vx (Elf32_Word); + extern void _dl_runtime_profile_vx (Elf32_Word); +#endif + if (l->l_info[DT_JMPREL] && lazy) { @@ -104,7 +109,7 @@ elf_machine_runtime_setup (struct link_map *l, int lazy, int profile) if (got[1]) { l->l_mach.plt = got[1] + l->l_addr; - l->l_mach.gotplt = (Elf32_Addr) &got[3]; + l->l_mach.jmprel = (const Elf32_Rela *) D_PTR (l, l_info[DT_JMPREL]); } got[1] = (Elf32_Addr) l; /* Identify this shared object. */ @@ -116,7 +121,14 @@ elf_machine_runtime_setup (struct link_map *l, int lazy, int profile) end in this function. */ if (__glibc_unlikely (profile)) { +#if defined HAVE_S390_VX_ASM_SUPPORT + if (GLRO(dl_hwcap) & HWCAP_S390_VX) + got[2] = (Elf32_Addr) &_dl_runtime_profile_vx; + else + got[2] = (Elf32_Addr) &_dl_runtime_profile; +#else got[2] = (Elf32_Addr) &_dl_runtime_profile; +#endif if (GLRO(dl_profile) != NULL && _dl_name_match_p (GLRO(dl_profile), l)) @@ -125,9 +137,18 @@ elf_machine_runtime_setup (struct link_map *l, int lazy, int profile) GL(dl_profile_map) = l; } else - /* This function will get called to fix up the GOT entry indicated by - the offset on the stack, and then jump to the resolved address. */ - got[2] = (Elf32_Addr) &_dl_runtime_resolve; + { + /* This function will get called to fix up the GOT entry indicated by + the offset on the stack, and then jump to the resolved address. */ +#if defined HAVE_S390_VX_ASM_SUPPORT + if (GLRO(dl_hwcap) & HWCAP_S390_VX) + got[2] = (Elf32_Addr) &_dl_runtime_resolve_vx; + else + got[2] = (Elf32_Addr) &_dl_runtime_resolve; +#else + got[2] = (Elf32_Addr) &_dl_runtime_resolve; +#endif + } } return lazy; @@ -273,6 +294,7 @@ dl_platform_init (void) static inline Elf32_Addr elf_machine_fixup_plt (struct link_map *map, lookup_t t, + const ElfW(Sym) *refsym, const ElfW(Sym) *sym, const Elf32_Rela *reloc, Elf32_Addr *reloc_addr, Elf32_Addr value) { @@ -336,7 +358,7 @@ elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc, const Elf32_Sym *const refsym = sym; #endif struct link_map *sym_map = RESOLVE_MAP (&sym, version, r_type); - Elf32_Addr value = sym == NULL ? 0 : sym_map->l_addr + sym->st_value; + Elf32_Addr value = SYMBOL_ADDRESS (sym_map, sym, true); if (sym != NULL && __builtin_expect (ELFW(ST_TYPE) (sym->st_info) == STT_GNU_IFUNC, 0) @@ -485,9 +507,7 @@ elf_machine_lazy_rel (struct link_map *map, if (__builtin_expect (map->l_mach.plt, 0) == 0) *reloc_addr += l_addr; else - *reloc_addr = - map->l_mach.plt - + (((Elf32_Addr) reloc_addr) - map->l_mach.gotplt) * 8; + *reloc_addr = map->l_mach.plt + (reloc - map->l_mach.jmprel) * 32; } else if (__glibc_likely (r_type == R_390_IRELATIVE)) { diff --git a/sysdeps/s390/s390-32/dl-sysdep.h b/sysdeps/s390/s390-32/dl-sysdep.h index d550d15985..b2e063ff09 100644 --- a/sysdeps/s390/s390-32/dl-sysdep.h +++ b/sysdeps/s390/s390-32/dl-sysdep.h @@ -1,5 +1,5 @@ /* System-specific settings for dynamic linker code. S/390 version. - Copyright (C) 2014-2016 Free Software Foundation, Inc. + Copyright (C) 2014-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or diff --git a/sysdeps/s390/s390-32/dl-trampoline.S b/sysdeps/s390/s390-32/dl-trampoline.S index 1645610383..1ec409bc56 100644 --- a/sysdeps/s390/s390-32/dl-trampoline.S +++ b/sysdeps/s390/s390-32/dl-trampoline.S @@ -1,5 +1,5 @@ /* PLT trampolines. s390 version. - Copyright (C) 2005-2016 Free Software Foundation, Inc. + Copyright (C) 2005-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -16,130 +16,18 @@ License along with the GNU C Library; if not, see <http://www.gnu.org/licenses/>. */ -/* This code is used in dl-runtime.c to call the `fixup' function - and then redirect to the address it returns. */ - -/* The PLT stubs will call _dl_runtime_resolve/_dl_runtime_profile - * with the following linkage: - * r2 - r6 : parameter registers - * f0, f2 : floating point parameter registers - * 24(r15), 28(r15) : PLT arguments PLT1, PLT2 - * 96(r15) : additional stack parameters - * The normal clobber rules for function calls apply: - * r0 - r5 : call clobbered - * r6 - r13 : call saved - * r14 : return address (call clobbered) - * r15 : stack pointer (call saved) - * f4, f6 : call saved - * f0 - f3, f5, f7 - f15 : call clobbered - */ - #include <sysdep.h> .text - .globl _dl_runtime_resolve - .type _dl_runtime_resolve, @function - cfi_startproc - .align 16 -_dl_runtime_resolve: - stm %r2,%r5,32(%r15) # save registers - st %r14,8(%r15) - cfi_offset (r14, -88) - lr %r0,%r15 # create stack frame - ahi %r15,-96 - cfi_adjust_cfa_offset (96) - st 0,0(%r15) - lm %r2,%r3,120(%r15) # load args saved by PLT - basr %r1,0 -0: l %r14,1f-0b(%r1) - bas %r14,0(%r14,%r1) # call resolver - lr %r1,%r2 # function addr returned in r2 - ahi %r15,96 # remove stack frame - cfi_adjust_cfa_offset (-96) - l %r14,8(15) # restore registers - lm %r2,%r5,32(%r15) - br %r1 -1: .long _dl_fixup - 0b - cfi_endproc - .size _dl_runtime_resolve, .-_dl_runtime_resolve - - -#ifndef PROF - .globl _dl_runtime_profile - .type _dl_runtime_profile, @function - cfi_startproc - .align 16 -_dl_runtime_profile: - stm %r2,%r6,32(%r15) # save registers - std %f0,56(%r15) - std %f2,64(%r15) - st %r6,8(%r15) - st %r12,12(%r15) - st %r14,16(%r15) - cfi_offset (r6, -64) - cfi_offset (f0, -40) - cfi_offset (f2, -32) - cfi_offset (r12, -84) - cfi_offset (r14, -80) - lr %r12,%r15 # create stack frame - cfi_def_cfa_register (12) - ahi %r15,-96 - st %r12,0(%r15) - lm %r2,%r3,24(%r12) # load arguments saved by PLT - lr %r4,%r14 # return address as third parameter - basr %r1,0 -0: l %r14,6f-0b(%r1) - la %r5,32(%r12) # pointer to struct La_s390_32_regs - la %r6,20(%r12) # long int * framesize - bas %r14,0(%r14,%r1) # call resolver - lr %r1,%r2 # function addr returned in r2 - icm %r0,15,20(%r12) # load & test framesize - jnm 2f - - lm %r2,%r6,32(%r12) - ld %f0,56(%r12) - ld %f2,64(%r12) - lr %r15,%r12 # remove stack frame - cfi_def_cfa_register (15) - l %r14,16(%r15) # restore registers - l %r12,12(%r15) - br %r1 # tail-call to the resolved function - - cfi_def_cfa_register (12) -2: jz 4f # framesize == 0 ? - ahi %r0,7 # align framesize to 8 - lhi %r2,-8 - nr %r0,%r2 - slr %r15,%r0 # make room for framesize bytes - st %r12,0(%r15) - la %r2,96(%r15) - la %r3,96(%r12) - srl %r0,3 -3: mvc 0(8,%r2),0(%r3) # copy additional parameters - la %r2,8(%r2) - la %r3,8(%r3) - brct %r0,3b -4: lm %r2,%r6,32(%r12) # load register parameters - ld %f0,56(%r12) - ld %f2,64(%r12) - basr %r14,%r1 # call resolved function - stm %r2,%r3,72(%r12) - std %f0,80(%r12) - lm %r2,%r3,24(%r12) # load arguments saved by PLT - basr %r1,0 -5: l %r14,7f-5b(%r1) - la %r4,32(%r12) # pointer to struct La_s390_32_regs - la %r5,72(%r12) # pointer to struct La_s390_32_retval - basr %r14,%r1 # call _dl_call_pltexit - - lr %r15,%r12 # remove stack frame - cfi_def_cfa_register (15) - l %r14,16(%r15) # restore registers - l %r12,12(%r15) - br %r14 - -6: .long _dl_profile_fixup - 0b -7: .long _dl_call_pltexit - 5b - cfi_endproc - .size _dl_runtime_profile, .-_dl_runtime_profile +/* Create variant of _dl_runtime_resolve/profile for machines before z13. + No vector registers are saved/restored. */ +#include <dl-trampoline.h> + +#if defined HAVE_S390_VX_ASM_SUPPORT +/* Create variant of _dl_runtime_resolve/profile for z13 and newer. + The vector registers are saved/restored, too.*/ +# define _dl_runtime_resolve _dl_runtime_resolve_vx +# define _dl_runtime_profile _dl_runtime_profile_vx +# define RESTORE_VRS +# include <dl-trampoline.h> #endif diff --git a/sysdeps/s390/s390-32/dl-trampoline.h b/sysdeps/s390/s390-32/dl-trampoline.h new file mode 100644 index 0000000000..d36c002743 --- /dev/null +++ b/sysdeps/s390/s390-32/dl-trampoline.h @@ -0,0 +1,230 @@ +/* PLT trampolines. s390 version. + Copyright (C) 2016-2018 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +/* This code is used in dl-runtime.c to call the `fixup' function + and then redirect to the address it returns. */ + +/* The PLT stubs will call _dl_runtime_resolve/_dl_runtime_profile + * with the following linkage: + * r2 - r6 : parameter registers + * f0, f2 : floating point parameter registers + * v24, v26, v28, v30, v25, v27, v29, v31 : vector parameter registers + * 24(r15), 28(r15) : PLT arguments PLT1, PLT2 + * 96(r15) : additional stack parameters + * The normal clobber rules for function calls apply: + * r0 - r5 : call clobbered + * r6 - r13 : call saved + * r14 : return address (call clobbered) + * r15 : stack pointer (call saved) + * f4, f6 : call saved + * f0 - f3, f5, f7 - f15 : call clobbered + * v0 - v3, v5, v7 - v15 : bytes 0-7 overlap with fprs: call clobbered + bytes 8-15: call clobbered + * v4, v6 : bytes 0-7 overlap with f4, f6: call saved + bytes 8-15: call clobbered + * v16 - v31 : call clobbered + */ + + + .globl _dl_runtime_resolve + .type _dl_runtime_resolve, @function + cfi_startproc + .align 16 +_dl_runtime_resolve: + stm %r2,%r5,32(%r15) # save registers + cfi_offset (r2, -64) + cfi_offset (r3, -60) + cfi_offset (r4, -56) + cfi_offset (r5, -52) + stm %r14,%r15,48(%r15) + cfi_offset (r14, -48) + cfi_offset (r15, -44) + std %f0,56(%r15) + cfi_offset (f0, -40) + std %f2,64(%r15) + cfi_offset (f2, -32) + lr %r0,%r15 + lm %r2,%r3,24(%r15) # load args saved by PLT +#ifdef RESTORE_VRS + ahi %r15,-224 # create stack frame + cfi_adjust_cfa_offset (224) + .machine push + .machine "z13" + .machinemode "zarch_nohighgprs" + vstm %v24,%v31,96(%r15) # store call-clobbered vr arguments + cfi_offset (v24, -224) + cfi_offset (v25, -208) + cfi_offset (v26, -192) + cfi_offset (v27, -176) + cfi_offset (v28, -160) + cfi_offset (v29, -144) + cfi_offset (v30, -128) + cfi_offset (v31, -112) + .machine pop +#else + ahi %r15,-96 # create stack frame + cfi_adjust_cfa_offset (96) +#endif + st %r0,0(%r15) # write backchain + basr %r1,0 +0: l %r14,1f-0b(%r1) + bas %r14,0(%r14,%r1) # call _dl_fixup + lr %r1,%r2 # function addr returned in r2 +#ifdef RESTORE_VRS + .machine push + .machine "z13" + .machinemode "zarch_nohighgprs" + vlm %v24,%v31,96(%r15) # restore vector registers + .machine pop + lm %r14,%r15,272(%r15)# remove stack frame and restore registers +#else + lm %r14,%r15,144(%r15)# remove stack frame and restore registers +#endif + cfi_def_cfa_offset (96) + ld %f0,56(%r15) + ld %f2,64(%r15) + lm %r2,%r5,32(%r15) + br %r1 +1: .long _dl_fixup - 0b + cfi_endproc + .size _dl_runtime_resolve, .-_dl_runtime_resolve + + +#ifndef PROF + .globl _dl_runtime_profile + .type _dl_runtime_profile, @function + cfi_startproc + .align 16 +_dl_runtime_profile: + st %r12,12(%r15) # r12 is used as backup of r15 + cfi_offset (r12, -84) + st %r14,16(%r15) + cfi_offset (r14, -80) + lr %r12,%r15 # backup stack pointer + cfi_def_cfa_register (12) + ahi %r15,-264 # create stack frame: + # 96 + sizeof(La_s390_32_regs) + st %r12,0(%r15) # save backchain + + stm %r2,%r6,96(%r15) # save registers + cfi_offset (r2, -264) # + r6 needed as arg for + cfi_offset (r3, -260) # _dl_profile_fixup + cfi_offset (r4, -256) + cfi_offset (r5, -252) + cfi_offset (r6, -248) + std %f0,120(%r15) + cfi_offset (f0, -240) + std %f2,128(%r15) + cfi_offset (f2, -232) +#ifdef RESTORE_VRS + .machine push + .machine "z13" + .machinemode "zarch_nohighgprs" + vstm %v24,%v31,136(%r15) # store call-clobbered vr arguments + cfi_offset (v24, -224) + cfi_offset (v25, -208) + cfi_offset (v26, -192) + cfi_offset (v27, -176) + cfi_offset (v28, -160) + cfi_offset (v29, -144) + cfi_offset (v30, -128) + cfi_offset (v31, -112) + .machine pop +#endif + + lm %r2,%r3,24(%r12) # load arguments saved by PLT + lr %r4,%r14 # return address as third parameter + basr %r1,0 +0: l %r14,6f-0b(%r1) + la %r5,96(%r15) # pointer to struct La_s390_32_regs + la %r6,20(%r12) # long int * framesize + bas %r14,0(%r14,%r1) # call resolver + lr %r1,%r2 # function addr returned in r2 + ld %f0,120(%r15) # restore call-clobbered arg fprs + ld %f2,128(%r15) +#ifdef RESTORE_VRS + .machine push + .machine "z13" + .machinemode "zarch_nohighgprs" + vlm %v24,%v31,136(%r15) # restore call-clobbered arg vrs + .machine pop +#endif + icm %r0,15,20(%r12) # load & test framesize + jnm 2f + + lm %r2,%r6,96(%r15) # framesize < 0 means no pltexit call + # so we can do a tail call without + # copying the arg overflow area + lr %r15,%r12 # remove stack frame + cfi_def_cfa_register (15) + l %r14,16(%r15) # restore registers + l %r12,12(%r15) + br %r1 # tail-call to the resolved function + + cfi_def_cfa_register (12) +2: la %r4,96(%r15) # pointer to struct La_s390_32_regs + st %r4,32(%r12) + jz 4f # framesize == 0 ? + ahi %r0,7 # align framesize to 8 + lhi %r2,-8 + nr %r0,%r2 + slr %r15,%r0 # make room for framesize bytes + st %r12,0(%r15) # save backchain + la %r2,96(%r15) + la %r3,96(%r12) + srl %r0,3 +3: mvc 0(8,%r2),0(%r3) # copy additional parameters + la %r2,8(%r2) + la %r3,8(%r3) + brct %r0,3b +4: lm %r2,%r6,0(%r4) # load register parameters + basr %r14,%r1 # call resolved function + stm %r2,%r3,40(%r12) # store return values r2, r3, f0 + std %f0,48(%r12) # to struct La_s390_32_retval +#ifdef RESTORE_VRS + .machine push + .machine "z13" + vst %v24,56(%r12) # store return value v24 + .machine pop +#endif + lm %r2,%r4,24(%r12) # r2, r3: load arguments saved by PLT + # r4: pointer to struct La_s390_32_regs + basr %r1,0 +5: l %r14,7f-5b(%r1) + la %r5,40(%r12) # pointer to struct La_s390_32_retval + bas %r14,0(%r14,%r1) # call _dl_call_pltexit + + lr %r15,%r12 # remove stack frame + cfi_def_cfa_register (15) + l %r14,16(%r15) # restore registers + l %r12,12(%r15) + lm %r2,%r3,40(%r15) # restore return values + ld %f0,48(%r15) +#ifdef RESTORE_VRS + .machine push + .machine "z13" + vl %v24,56(%r15) # restore return value v24 + .machine pop +#endif + br %r14 + +6: .long _dl_profile_fixup - 0b +7: .long _dl_call_pltexit - 5b + cfi_endproc + .size _dl_runtime_profile, .-_dl_runtime_profile +#endif diff --git a/sysdeps/s390/s390-32/memchr.S b/sysdeps/s390/s390-32/memchr.S index 5c82af4b90..54f9b85f57 100644 --- a/sysdeps/s390/s390-32/memchr.S +++ b/sysdeps/s390/s390-32/memchr.S @@ -1,5 +1,5 @@ /* Search a character in a block of memory. For IBM S390 - Copyright (C) 2000-2016 Free Software Foundation, Inc. + Copyright (C) 2000-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com). diff --git a/sysdeps/s390/s390-32/memcmp.S b/sysdeps/s390/s390-32/memcmp.S index 50ab61c77f..f9ad0bc745 100644 --- a/sysdeps/s390/s390-32/memcmp.S +++ b/sysdeps/s390/s390-32/memcmp.S @@ -1,5 +1,5 @@ /* memcmp - compare two memory blocks. 32 bit S/390 version. - Copyright (C) 2012-2016 Free Software Foundation, Inc. + Copyright (C) 2012-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or diff --git a/sysdeps/s390/s390-32/memcpy.S b/sysdeps/s390/s390-32/memcpy.S index 62ecbbf619..493cc18aba 100644 --- a/sysdeps/s390/s390-32/memcpy.S +++ b/sysdeps/s390/s390-32/memcpy.S @@ -1,5 +1,5 @@ /* memcpy - copy a block from source to destination. S/390 version. - Copyright (C) 2012-2016 Free Software Foundation, Inc. + Copyright (C) 2012-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -25,58 +25,65 @@ %r3 = address of source memory area %r4 = number of bytes to copy. */ -#ifdef USE_MULTIARCH -ENTRY(__memcpy_default) -#else -ENTRY(memcpy) + .text +ENTRY(__mempcpy) + .machine "g5" + lr %r1,%r2 # Use as dest + la %r2,0(%r4,%r2) # Return dest + n + j .L_G5_start +END(__mempcpy) +#ifndef USE_MULTIARCH +libc_hidden_def (__mempcpy) +weak_alias (__mempcpy, mempcpy) +libc_hidden_builtin_def (mempcpy) #endif + +ENTRY(memcpy) .machine "g5" - st %r13,52(%r15) - .cfi_offset 13, -44 - basr %r13,0 -.L_G5_16: + lr %r1,%r2 # r1: Use as dest ; r2: Return dest +.L_G5_start: ltr %r4,%r4 - je .L_G5_4 + je .L_G5_99 ahi %r4,-1 lr %r5,%r4 srl %r5,8 ltr %r5,%r5 - lr %r1,%r2 - jne .L_G5_12 - ex %r4,.L_G5_17-.L_G5_16(%r13) + jne .L_G5_13 .L_G5_4: - l %r13,52(%r15) + basr %r5,0 +.L_G5_16: + ex %r4,.L_G5_17-.L_G5_16(%r5) +.L_G5_99: br %r14 .L_G5_13: - chi %r5,4096 # Switch to mvcle for copies >1MB + chi %r5,4096 # Switch to mvcle for copies >1MB jh __memcpy_mvcle .L_G5_12: mvc 0(256,%r1),0(%r3) la %r1,256(%r1) la %r3,256(%r3) brct %r5,.L_G5_12 - ex %r4,.L_G5_17-.L_G5_16(%r13) j .L_G5_4 .L_G5_17: mvc 0(1,%r1),0(%r3) -#ifdef USE_MULTIARCH -END(__memcpy_default) -#else END(memcpy) +#ifndef USE_MULTIARCH libc_hidden_builtin_def (memcpy) #endif ENTRY(__memcpy_mvcle) - # Using as standalone function will result in unexpected - # results since the length field is incremented by 1 in order to - # compensate the changes already done in the functions above. - ahi %r4,1 # length + 1 - lr %r5,%r4 # source length - lr %r4,%r3 # source address - lr %r3,%r5 # destination length = source length + # Using as standalone function will result in unexpected + # results since the length field is incremented by 1 in order to + # compensate the changes already done in the functions above. + lr %r0,%r2 # backup return dest [ + n ] + ahi %r4,1 # length + 1 + lr %r5,%r4 # source length + lr %r4,%r3 # source address + lr %r2,%r1 # destination address + lr %r3,%r5 # destination length = source length .L_MVCLE_1: - mvcle %r2,%r4,0 # thats it, MVCLE is your friend - jo .L_MVCLE_1 - lr %r2,%r1 # return destination address - br %r14 + mvcle %r2,%r4,0 # thats it, MVCLE is your friend + jo .L_MVCLE_1 + lr %r2,%r0 # return destination address + br %r14 END(__memcpy_mvcle) diff --git a/sysdeps/s390/s390-32/memset.S b/sysdeps/s390/s390-32/memset.S index eca65d4a49..57f08e1cae 100644 --- a/sysdeps/s390/s390-32/memset.S +++ b/sysdeps/s390/s390-32/memset.S @@ -1,5 +1,5 @@ /* Set a block of memory to some byte value. For IBM S390 - Copyright (C) 2012-2016 Free Software Foundation, Inc. + Copyright (C) 2012-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or diff --git a/sysdeps/s390/s390-32/mul_1.S b/sysdeps/s390/s390-32/mul_1.S index 50df39c17f..6fa4fae437 100644 --- a/sysdeps/s390/s390-32/mul_1.S +++ b/sysdeps/s390/s390-32/mul_1.S @@ -1,6 +1,6 @@ /* __mpn_mul_1 -- Multiply a limb vector with a limb and store the result in a second limb vector. - Copyright (C) 2000-2016 Free Software Foundation, Inc. + Copyright (C) 2000-2018 Free Software Foundation, Inc. Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com). This file is part of the GNU MP Library. diff --git a/sysdeps/s390/s390-32/multiarch/memchr.c b/sysdeps/s390/s390-32/multiarch/memchr.c index 2281e43056..5e1610afa4 100644 --- a/sysdeps/s390/s390-32/multiarch/memchr.c +++ b/sysdeps/s390/s390-32/multiarch/memchr.c @@ -1,5 +1,5 @@ /* Multiple versions of memchr. - Copyright (C) 2015-2016 Free Software Foundation, Inc. + Copyright (C) 2015-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or diff --git a/sysdeps/s390/s390-32/multiarch/memcmp-s390.S b/sysdeps/s390/s390-32/multiarch/memcmp-s390.S index e9ee6d2270..e53b508c98 100644 --- a/sysdeps/s390/s390-32/multiarch/memcmp-s390.S +++ b/sysdeps/s390/s390-32/multiarch/memcmp-s390.S @@ -1,5 +1,5 @@ /* CPU specific memcmp implementations. 32 bit S/390 version. - Copyright (C) 2012-2016 Free Software Foundation, Inc. + Copyright (C) 2012-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -101,4 +101,7 @@ END(__memcmp_z10) .set memcmp,__memcmp_default .weak bcmp .set bcmp,__memcmp_default +#elif defined SHARED && IS_IN (libc) +.globl __GI_memcmp +.set __GI_memcmp,__memcmp_default #endif diff --git a/sysdeps/s390/s390-32/multiarch/memcmp.c b/sysdeps/s390/s390-32/multiarch/memcmp.c index 44f72dc8ca..1e6f31806e 100644 --- a/sysdeps/s390/s390-32/multiarch/memcmp.c +++ b/sysdeps/s390/s390-32/multiarch/memcmp.c @@ -1,5 +1,5 @@ /* Multiple versions of memcmp. - Copyright (C) 2015-2016 Free Software Foundation, Inc. + Copyright (C) 2015-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -17,8 +17,11 @@ <http://www.gnu.org/licenses/>. */ #if IS_IN (libc) +# define memcmp __redirect_memcmp +# include <string.h> +# undef memcmp # include <ifunc-resolve.h> -s390_libc_ifunc (memcmp) -__asm__(".weak bcmp ; bcmp = memcmp"); +s390_libc_ifunc (__redirect_memcmp, __memcmp, memcmp) +weak_alias (memcmp, bcmp); #endif diff --git a/sysdeps/s390/s390-32/multiarch/memcpy-s390.S b/sysdeps/s390/s390-32/multiarch/memcpy-s390.S index 4e30cdf6c6..aad13bd07c 100644 --- a/sysdeps/s390/s390-32/multiarch/memcpy-s390.S +++ b/sysdeps/s390/s390-32/multiarch/memcpy-s390.S @@ -1,5 +1,5 @@ /* CPU specific memcpy implementations. 32 bit S/390 version. - Copyright (C) 2012-2016 Free Software Foundation, Inc. + Copyright (C) 2012-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -29,14 +29,23 @@ #if defined SHARED && IS_IN (libc) +ENTRY(____mempcpy_z196) + .machine "z196" + .machinemode "zarch_nohighgprs" + lr %r1,%r2 # Use as dest + la %r2,0(%r4,%r2) # Return dest + n + j .L_Z196_start +END(____mempcpy_z196) + ENTRY(__memcpy_z196) .machine "z196" .machinemode "zarch_nohighgprs" + lr %r1,%r2 # r1: Use as dest ; r2: Return dest +.L_Z196_start: llgfr %r4,%r4 ltgr %r4,%r4 je .L_Z196_4 aghi %r4,-1 - lr %r1,%r2 srlg %r5,%r4,8 ltgr %r5,%r5 jne .L_Z196_5 @@ -60,13 +69,22 @@ ENTRY(__memcpy_z196) mvc 0(1,%r1),0(%r3) END(__memcpy_z196) +ENTRY(____mempcpy_z10) + .machine "z10" + .machinemode "zarch_nohighgprs" + lr %r1,%r2 # Use as dest + la %r2,0(%r4,%r2) # Return dest + n + j .L_Z10_start +END(____mempcpy_z10) + ENTRY(__memcpy_z10) .machine "z10" .machinemode "zarch_nohighgprs" + lr %r1,%r2 # r1: Use as dest ; r2: Return dest +.L_Z10_start: llgfr %r4,%r4 cgije %r4,0,.L_Z10_4 aghi %r4,-1 - lr %r1,%r2 srlg %r5,%r4,8 cgijlh %r5,0,.L_Z10_13 .L_Z10_3: @@ -88,11 +106,23 @@ ENTRY(__memcpy_z10) mvc 0(1,%r1),0(%r3) END(__memcpy_z10) +# define __mempcpy ____mempcpy_default #endif /* SHARED && IS_IN (libc) */ +#define memcpy __memcpy_default #include "../memcpy.S" +#undef memcpy -#if !defined SHARED || !IS_IN (libc) +#if defined SHARED && IS_IN (libc) +.globl __GI_memcpy +.set __GI_memcpy,__memcpy_default +.globl __GI_mempcpy +.set __GI_mempcpy,____mempcpy_default +.globl __GI___mempcpy +.set __GI___mempcpy,____mempcpy_default +#else .globl memcpy .set memcpy,__memcpy_default +.weak mempcpy +.set mempcpy,__mempcpy #endif diff --git a/sysdeps/s390/s390-32/multiarch/memcpy.c b/sysdeps/s390/s390-32/multiarch/memcpy.c index 2a98aa0b82..c9577a854a 100644 --- a/sysdeps/s390/s390-32/multiarch/memcpy.c +++ b/sysdeps/s390/s390-32/multiarch/memcpy.c @@ -1,5 +1,5 @@ /* Multiple versions of memcpy. - Copyright (C) 2015-2016 Free Software Foundation, Inc. + Copyright (C) 2015-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -18,7 +18,10 @@ /* In the static lib memcpy is needed before the reloc is resolved. */ #if defined SHARED && IS_IN (libc) +# define memcpy __redirect_memcpy +# include <string.h> +# undef memcpy # include <ifunc-resolve.h> -s390_libc_ifunc (memcpy) +s390_libc_ifunc (__redirect_memcpy, __memcpy, memcpy) #endif diff --git a/sysdeps/s390/s390-32/multiarch/memset-s390.S b/sysdeps/s390/s390-32/multiarch/memset-s390.S index 47277c13a6..b092073d6b 100644 --- a/sysdeps/s390/s390-32/multiarch/memset-s390.S +++ b/sysdeps/s390/s390-32/multiarch/memset-s390.S @@ -1,5 +1,5 @@ /* Set a block of memory to some byte value. 32 bit S/390 version. - Copyright (C) 2012-2016 Free Software Foundation, Inc. + Copyright (C) 2012-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -110,4 +110,7 @@ END(__memset_mvcle) #if !IS_IN (libc) .globl memset .set memset,__memset_default +#elif defined SHARED && IS_IN (libc) +.globl __GI_memset +.set __GI_memset,__memset_default #endif diff --git a/sysdeps/s390/s390-32/multiarch/memset.c b/sysdeps/s390/s390-32/multiarch/memset.c index 89b8102f2a..760b3e9df2 100644 --- a/sysdeps/s390/s390-32/multiarch/memset.c +++ b/sysdeps/s390/s390-32/multiarch/memset.c @@ -1,5 +1,5 @@ /* Multiple versions of memset. - Copyright (C) 2015-2016 Free Software Foundation, Inc. + Copyright (C) 2015-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -17,7 +17,10 @@ <http://www.gnu.org/licenses/>. */ #if IS_IN (libc) +# define memset __redirect_memset +# include <string.h> +# undef memset # include <ifunc-resolve.h> -s390_libc_ifunc (memset) +s390_libc_ifunc (__redirect_memset, __memset, memset) #endif diff --git a/sysdeps/s390/s390-32/multiarch/strcmp.c b/sysdeps/s390/s390-32/multiarch/strcmp.c index b7eebc017f..d06b0f3436 100644 --- a/sysdeps/s390/s390-32/multiarch/strcmp.c +++ b/sysdeps/s390/s390-32/multiarch/strcmp.c @@ -1,5 +1,5 @@ /* Multiple versions of strcmp. - Copyright (C) 2015-2016 Free Software Foundation, Inc. + Copyright (C) 2015-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or diff --git a/sysdeps/s390/s390-32/multiarch/strcpy.c b/sysdeps/s390/s390-32/multiarch/strcpy.c index ae140d22b7..6a22e31a03 100644 --- a/sysdeps/s390/s390-32/multiarch/strcpy.c +++ b/sysdeps/s390/s390-32/multiarch/strcpy.c @@ -1,5 +1,5 @@ /* Multiple versions of strcpy. - Copyright (C) 2015-2016 Free Software Foundation, Inc. + Copyright (C) 2015-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or diff --git a/sysdeps/s390/s390-32/multiarch/strncpy.c b/sysdeps/s390/s390-32/multiarch/strncpy.c index 28a2af72e4..57f9df18d1 100644 --- a/sysdeps/s390/s390-32/multiarch/strncpy.c +++ b/sysdeps/s390/s390-32/multiarch/strncpy.c @@ -1,5 +1,5 @@ /* Multiple versions of strncpy. - Copyright (C) 2015-2016 Free Software Foundation, Inc. + Copyright (C) 2015-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or diff --git a/sysdeps/s390/s390-32/s390-mcount.S b/sysdeps/s390/s390-32/s390-mcount.S index a27f434fbf..153777e1b8 100644 --- a/sysdeps/s390/s390-32/s390-mcount.S +++ b/sysdeps/s390/s390-32/s390-mcount.S @@ -1,5 +1,5 @@ -/* S/390-specific implemetation of profiling support. - Copyright (C) 2000-2016 Free Software Foundation, Inc. +/* S/390-specific implementation of profiling support. + Copyright (C) 2000-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com) diff --git a/sysdeps/s390/s390-32/setjmp.S b/sysdeps/s390/s390-32/setjmp.S index dbacb0fdf2..fd2f991682 100644 --- a/sysdeps/s390/s390-32/setjmp.S +++ b/sysdeps/s390/s390-32/setjmp.S @@ -1,5 +1,5 @@ /* setjmp for s390, ELF version. - Copyright (C) 2000-2016 Free Software Foundation, Inc. + Copyright (C) 2000-2018 Free Software Foundation, Inc. Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com). This file is part of the GNU C Library. @@ -24,17 +24,16 @@ #include <shlib-compat.h> #include <stap-probe.h> -#if !IS_IN (rtld) -# if defined SHARED && SHLIB_COMPAT (libc, GLIBC_2_19, GLIBC_2_20) - /* we need a unique name in case of symbol versioning. */ -# define setjmp __v1setjmp -# define _setjmp __v1_setjmp -# define __sigsetjmp __v1__sigsetjmp - -# undef libc_hidden_def -# define libc_hidden_def(name) strong_alias(_setjmp, __GI__setjmp) -# endif /* if defined SHARED && SHLIB_COMPAT (libc, GLIBC_2_19, GLIBC_2_20) */ -#endif /* !IS_IN (rtld) */ +#if !IS_IN (rtld) && defined SHARED \ + && SHLIB_COMPAT (libc, GLIBC_2_19, GLIBC_2_20) +# define NEED_COMPAT_SYMBOLS 1 +/* We need a unique name in case of symbol versioning. */ +# define setjmp __v1setjmp +# define _setjmp __v1_setjmp +# define __sigsetjmp __v1__sigsetjmp +#else +# define NEED_COMPAT_SYMBOLS 0 +#endif /* We include the BSD entry points here as well. */ ENTRY (setjmp) @@ -47,7 +46,11 @@ ENTRY(_setjmp) lhi %r3,0 /* second argument of zero */ j .Linternal_sigsetjmp /* branch relativ to __sigsetjmp */ END (_setjmp) +#if NEED_COMPAT_SYMBOLS +strong_alias (_setjmp, __GI__setjmp) +#else libc_hidden_def (_setjmp) +#endif ENTRY(__setjmp) lhi %r3,0 /* second argument of zero */ @@ -92,15 +95,19 @@ ENTRY(__sigsetjmp) .L1: .long __sigjmp_save #endif END (__sigsetjmp) +#if NEED_COMPAT_SYMBOLS +strong_alias (__sigsetjmp, __GI___sigsetjmp) +#else +libc_hidden_def (__sigsetjmp) +#endif -#if !IS_IN (rtld) -# if defined SHARED && SHLIB_COMPAT (libc, GLIBC_2_19, GLIBC_2_20) +#if NEED_COMPAT_SYMBOLS /* In glibc release 2.19 new versions of setjmp-functions were introduced, but were reverted before 2.20. Thus both versions are the same function. */ -# undef setjmp -# undef _setjmp -# undef __sigsetjmp +# undef setjmp +# undef _setjmp +# undef __sigsetjmp strong_alias (__v1setjmp, __v2setjmp); versioned_symbol (libc, __v1setjmp, setjmp, GLIBC_2_0); @@ -113,5 +120,4 @@ compat_symbol (libc, __v2_setjmp, _setjmp, GLIBC_2_19); strong_alias (__v1__sigsetjmp, __v2__sigsetjmp); versioned_symbol (libc, __v1__sigsetjmp, __sigsetjmp, GLIBC_2_0); compat_symbol (libc, __v2__sigsetjmp, __sigsetjmp, GLIBC_2_19); -# endif /* if defined SHARED && SHLIB_COMPAT (libc, GLIBC_2_19, GLIBC_2_20) */ -#endif /* if !IS_IN (rtld) */ +#endif /* NEED_COMPAT_SYMBOLS */ diff --git a/sysdeps/s390/s390-32/start.S b/sysdeps/s390/s390-32/start.S index 1fbc64d2e4..1483642985 100644 --- a/sysdeps/s390/s390-32/start.S +++ b/sysdeps/s390/s390-32/start.S @@ -1,5 +1,5 @@ /* Startup code compliant to the ELF s390 ABI. - Copyright (C) 2000-2016 Free Software Foundation, Inc. + Copyright (C) 2000-2018 Free Software Foundation, Inc. Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com). This file is part of the GNU C Library. @@ -34,6 +34,8 @@ License along with the GNU C Library; if not, see <http://www.gnu.org/licenses/>. */ +#include <sysdep.h> + /* This is the canonical entry point, usually the first thing in the text segment. Most registers' values are unspecified, except for: @@ -57,6 +59,10 @@ .globl _start .type _start,@function _start: + cfi_startproc + /* Mark r14 as undefined in order to stop unwinding here! */ + cfi_undefined (r14) + /* Check if the kernel provides highgprs facility if needed by the binary. */ @@ -188,6 +194,7 @@ _start: /* crash if __libc_start_main returns */ .word 0 + cfi_endproc .Llit: #ifndef PIC .L1: .long __libc_csu_init diff --git a/sysdeps/s390/s390-32/strcmp.S b/sysdeps/s390/s390-32/strcmp.S index 71f113ebab..3cf3f239fd 100644 --- a/sysdeps/s390/s390-32/strcmp.S +++ b/sysdeps/s390/s390-32/strcmp.S @@ -1,6 +1,6 @@ /* strcmp - compare two string. S/390 version. This file is part of the GNU C Library. - Copyright (C) 2001-2016 Free Software Foundation, Inc. + Copyright (C) 2001-2018 Free Software Foundation, Inc. Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com). The GNU C Library is free software; you can redistribute it and/or diff --git a/sysdeps/s390/s390-32/strcpy.S b/sysdeps/s390/s390-32/strcpy.S index 5cdc350f91..d49136ee92 100644 --- a/sysdeps/s390/s390-32/strcpy.S +++ b/sysdeps/s390/s390-32/strcpy.S @@ -1,6 +1,6 @@ /* strcpy - copy a string from source to destination. For IBM S390 This file is part of the GNU C Library. - Copyright (C) 2000-2016 Free Software Foundation, Inc. + Copyright (C) 2000-2018 Free Software Foundation, Inc. Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com). The GNU C Library is free software; you can redistribute it and/or diff --git a/sysdeps/s390/s390-32/strncpy.S b/sysdeps/s390/s390-32/strncpy.S index 75800b3ee6..9086eb1c70 100644 --- a/sysdeps/s390/s390-32/strncpy.S +++ b/sysdeps/s390/s390-32/strncpy.S @@ -1,7 +1,7 @@ /* strncpy - copy at most n characters from a string from source to destination. For IBM S390 This file is part of the GNU C Library. - Copyright (C) 2000-2016 Free Software Foundation, Inc. + Copyright (C) 2000-2018 Free Software Foundation, Inc. Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com). The GNU C Library is free software; you can redistribute it and/or diff --git a/sysdeps/s390/s390-32/sub_n.S b/sysdeps/s390/s390-32/sub_n.S index f8de2c2a5e..e7fdb604ff 100644 --- a/sysdeps/s390/s390-32/sub_n.S +++ b/sysdeps/s390/s390-32/sub_n.S @@ -1,6 +1,6 @@ /* __mpn_sub_n -- Add two limb vectors of the same length > 0 and store sum in a third limb vector. - Copyright (C) 2000-2016 Free Software Foundation, Inc. + Copyright (C) 2000-2018 Free Software Foundation, Inc. Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com). This file is part of the GNU MP Library. diff --git a/sysdeps/s390/s390-32/symbol-hacks.h b/sysdeps/s390/s390-32/symbol-hacks.h new file mode 100644 index 0000000000..879ce2f517 --- /dev/null +++ b/sysdeps/s390/s390-32/symbol-hacks.h @@ -0,0 +1,21 @@ +/* Hacks needed for symbol manipulation. s390 version. + Copyright (C) 2017-2018 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <sysdeps/wordsize-32/divdi3-symbol-hacks.h> + +#include_next "symbol-hacks.h" diff --git a/sysdeps/s390/s390-32/sysdep.h b/sysdeps/s390/s390-32/sysdep.h index 26e9285dbd..7e2763fe92 100644 --- a/sysdeps/s390/s390-32/sysdep.h +++ b/sysdeps/s390/s390-32/sysdep.h @@ -1,5 +1,5 @@ /* Assembler macros for s390. - Copyright (C) 2000-2016 Free Software Foundation, Inc. + Copyright (C) 2000-2018 Free Software Foundation, Inc. Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com). This file is part of the GNU C Library. @@ -82,14 +82,14 @@ lose: SYSCALL_PIC_SETUP \ END (name) #undef JUMPTARGET -#ifdef PIC +#ifdef SHARED #define JUMPTARGET(name) name##@PLT #define SYSCALL_PIC_SETUP \ - bras %r12,1f \ -0: .long _GLOBAL_OFFSET_TABLE_-0b \ + bras %r12,1f; \ +0: .long _GLOBAL_OFFSET_TABLE_-0b; \ 1: al %r12,0(%r12) #else -#define JUMPTARGET(name) name +#define JUMPTARGET(name) name #define SYSCALL_PIC_SETUP /* Nothing. */ #endif diff --git a/sysdeps/s390/s390-32/tls-macros.h b/sysdeps/s390/s390-32/tls-macros.h index 09b42aa37a..153523a4ae 100644 --- a/sysdeps/s390/s390-32/tls-macros.h +++ b/sysdeps/s390/s390-32/tls-macros.h @@ -8,15 +8,17 @@ #ifdef PIC # define TLS_IE(x) \ - ({ unsigned long __offset, __got; \ + ({ unsigned long __offset, __save12; \ __asm__ ("bras %0,1f\n" \ "0:\t.long _GLOBAL_OFFSET_TABLE_-0b\n\t" \ ".long " #x "@gotntpoff\n" \ - "1:\tl %1,0(%0)\n\t" \ - "la %1,0(%1,%0)\n\t" \ + "1:\tlr %1,%%r12\n\t" \ + "l %%r12,0(%0)\n\t" \ + "la %%r12,0(%0,%%r12)\n\t" \ "l %0,4(%0)\n\t" \ - "l %0,0(%0,%1):tls_load:" #x "\n" \ - : "=&a" (__offset), "=&a" (__got) : : "cc" ); \ + "l %0,0(%0,%%r12):tls_load:" #x "\n\t" \ + "lr %%r12,%1\n" \ + : "=&a" (__offset), "=&a" (__save12) : : "cc" ); \ (int *) (__builtin_thread_pointer() + __offset); }) #else # define TLS_IE(x) \ @@ -47,7 +49,7 @@ "alr %0,%%r2\n\t" \ "lr %%r12,%1" \ : "=&a" (__offset), "=&a" (__save12) \ - : : "cc", "0", "1", "2", "3", "4", "5" ); \ + : : "cc", "0", "1", "2", "3", "4", "5", "14"); \ (int *) (__builtin_thread_pointer() + __offset); }) #else # define TLS_LD(x) \ @@ -63,7 +65,8 @@ "bas %%r14,0(%%r1):tls_ldcall:" #x "\n\t" \ "l %0,12(%0)\n\t" \ "alr %0,%%r2" \ - : "=&a" (__offset) : : "cc", "0", "1", "2", "3", "4", "5", "12" ); \ + : "=&a" (__offset) \ + : : "cc", "0", "1", "2", "3", "4", "5", "12", "14"); \ (int *) (__builtin_thread_pointer() + __offset); }) #endif @@ -83,7 +86,7 @@ "lr %0,%%r2\n\t" \ "lr %%r12,%1" \ : "=&a" (__offset), "=&a" (__save12) \ - : : "cc", "0", "1", "2", "3", "4", "5" ); \ + : : "cc", "0", "1", "2", "3", "4", "5", "14"); \ (int *) (__builtin_thread_pointer() + __offset); }) #else # define TLS_GD(x) \ @@ -97,6 +100,7 @@ "l %%r2,8(%0)\n\t" \ "bas %%r14,0(%%r1):tls_gdcall:" #x "\n\t" \ "lr %0,%%r2" \ - : "=&a" (__offset) : : "cc", "0", "1", "2", "3", "4", "5", "12" ); \ + : "=&a" (__offset) \ + : : "cc", "0", "1", "2", "3", "4", "5", "12", "14"); \ (int *) (__builtin_thread_pointer() + __offset); }) #endif diff --git a/sysdeps/s390/s390-32/tst-audit.h b/sysdeps/s390/s390-32/tst-audit.h index 8908602cff..173b1ec40c 100644 --- a/sysdeps/s390/s390-32/tst-audit.h +++ b/sysdeps/s390/s390-32/tst-audit.h @@ -1,6 +1,6 @@ /* Definitions for testing PLT entry/exit auditing. S/390 32-bit version. - Copyright (C) 2012-2016 Free Software Foundation, Inc. + Copyright (C) 2012-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. diff --git a/sysdeps/s390/s390-64/Makefile b/sysdeps/s390/s390-64/Makefile index ce4f0c5c88..b4d793bb3d 100644 --- a/sysdeps/s390/s390-64/Makefile +++ b/sysdeps/s390/s390-64/Makefile @@ -1,5 +1,3 @@ -pic-ccflag = -fpic - ifeq ($(subdir),gmon) sysdep_routines += s390x-mcount endif @@ -9,84 +7,3 @@ CFLAGS-rtld.c += -Wno-uninitialized -Wno-unused CFLAGS-dl-load.c += -Wno-unused CFLAGS-dl-reloc.c += -Wno-unused endif - -ifeq ($(subdir),iconvdata) -ISO-8859-1_CP037_Z900-routines := iso-8859-1_cp037_z900 -ISO-8859-1_CP037_Z900-map := gconv.map - -UTF8_UTF32_Z9-routines := utf8-utf32-z9 -UTF8_UTF32_Z9-map := gconv.map - -UTF16_UTF32_Z9-routines := utf16-utf32-z9 -UTF16_UTF32_Z9-map := gconv.map - -UTF8_UTF16_Z9-routines := utf8-utf16-z9 -UTF8_UTF16_Z9-map := gconv.map - -s390x-iconv-modules = ISO-8859-1_CP037_Z900 UTF8_UTF16_Z9 UTF16_UTF32_Z9 UTF8_UTF32_Z9 - -extra-modules-left += $(s390x-iconv-modules) -include extra-module.mk - -cpp-srcs-left := $(foreach mod,$(s390x-iconv-modules),$($(mod)-routines)) -lib := iconvdata -include $(patsubst %,$(..)cppflags-iterator.mk,$(cpp-srcs-left)) - -extra-objs += $(addsuffix .so, $(s390x-iconv-modules)) -install-others += $(patsubst %, $(inst_gconvdir)/%.so, $(s390x-iconv-modules)) - -$(patsubst %, $(inst_gconvdir)/%.so, $(s390x-iconv-modules)) : \ -$(inst_gconvdir)/%.so: $(objpfx)%.so $(+force) - $(do-install-program) - -$(objpfx)gconv-modules-s390: gconv-modules $(+force) - cp $< $@ - echo >> $@ - echo "# S/390 hardware accelerated modules" >> $@ - echo -n "module ISO-8859-1// IBM037// " >> $@ - echo " ISO-8859-1_CP037_Z900 1" >> $@ - echo -n "module IBM037// ISO-8859-1// " >> $@ - echo " ISO-8859-1_CP037_Z900 1" >> $@ - echo -n "module ISO-10646/UTF8/ UTF-32// " >> $@ - echo " UTF8_UTF32_Z9 1" >> $@ - echo -n "module UTF-32BE// ISO-10646/UTF8/ " >> $@ - echo " UTF8_UTF32_Z9 1" >> $@ - echo -n "module ISO-10646/UTF8/ UTF-32BE// " >> $@ - echo " UTF8_UTF32_Z9 1" >> $@ - echo -n "module UTF-16BE// UTF-32// " >> $@ - echo " UTF16_UTF32_Z9 1" >> $@ - echo -n "module UTF-32BE// UTF-16// " >> $@ - echo " UTF16_UTF32_Z9 1" >> $@ - echo -n "module INTERNAL UTF-16// " >> $@ - echo " UTF16_UTF32_Z9 1" >> $@ - echo -n "module UTF-32BE// UTF-16BE// " >> $@ - echo " UTF16_UTF32_Z9 1" >> $@ - echo -n "module INTERNAL UTF-16BE// " >> $@ - echo " UTF16_UTF32_Z9 1" >> $@ - echo -n "module UTF-16BE// UTF-32BE// " >> $@ - echo " UTF16_UTF32_Z9 1" >> $@ - echo -n "module UTF-16BE// INTERNAL " >> $@ - echo " UTF16_UTF32_Z9 1" >> $@ - echo -n "module UTF-16BE// ISO-10646/UTF8/ " >> $@ - echo " UTF8_UTF16_Z9 1" >> $@ - echo -n "module ISO-10646/UTF8/ UTF-16// " >> $@ - echo " UTF8_UTF16_Z9 1" >> $@ - echo -n "module ISO-10646/UTF8/ UTF-16BE// " >> $@ - echo " UTF8_UTF16_Z9 1" >> $@ - -$(inst_gconvdir)/gconv-modules: $(objpfx)gconv-modules-s390 $(+force) - $(do-install) -ifeq (no,$(cross-compiling)) -# Update the $(prefix)/lib/gconv/gconv-modules.cache file. This is necessary -# if this libc has more gconv modules than the previously installed one. - if test -f "$(inst_gconvdir)/gconv-modules.cache"; then \ - LC_ALL=C \ - $(rtld-prefix) \ - $(common-objpfx)iconv/iconvconfig \ - $(addprefix --prefix=,$(install_root)); \ - fi -else - @echo '*@*@*@ You should recreate $(inst_gconvdir)/gconv-modules.cache' -endif - -endif diff --git a/sysdeps/s390/s390-64/__longjmp.c b/sysdeps/s390/s390-64/__longjmp.c index 66005b82ac..17aa0810e6 100644 --- a/sysdeps/s390/s390-64/__longjmp.c +++ b/sysdeps/s390/s390-64/__longjmp.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2016 Free Software Foundation, Inc. +/* Copyright (C) 2001-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com). diff --git a/sysdeps/s390/s390-64/add_n.S b/sysdeps/s390/s390-64/add_n.S index 11bc60170b..5cbc6d0d8e 100644 --- a/sysdeps/s390/s390-64/add_n.S +++ b/sysdeps/s390/s390-64/add_n.S @@ -1,6 +1,6 @@ /* Add two limb vectors of the same length > 0 and store sum in a third limb vector. - Copyright (C) 2001-2016 Free Software Foundation, Inc. + Copyright (C) 2001-2018 Free Software Foundation, Inc. Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com). This file is part of the GNU MP Library. diff --git a/sysdeps/s390/s390-64/backtrace.c b/sysdeps/s390/s390-64/backtrace.c index 5f8b7f8fff..3efcbe4096 100644 --- a/sysdeps/s390/s390-64/backtrace.c +++ b/sysdeps/s390/s390-64/backtrace.c @@ -1,5 +1,5 @@ /* Return backtrace of current program state. 64 bit S/390 version. - Copyright (C) 2001-2016 Free Software Foundation, Inc. + Copyright (C) 2001-2018 Free Software Foundation, Inc. Contributed by Martin Schwidefsky <schwidefsky@de.ibm.com>. This file is part of the GNU C Library. diff --git a/sysdeps/s390/s390-64/bcopy.S b/sysdeps/s390/s390-64/bcopy.S index 7eeeae499c..806dd15d02 100644 --- a/sysdeps/s390/s390-64/bcopy.S +++ b/sysdeps/s390/s390-64/bcopy.S @@ -1,6 +1,6 @@ /* bcopy -- copy a block from source to destination. 64 bit S/390 version. This file is part of the GNU C Library. - Copyright (C) 2000-2016 Free Software Foundation, Inc. + Copyright (C) 2000-2018 Free Software Foundation, Inc. Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com). The GNU C Library is free software; you can redistribute it and/or diff --git a/sysdeps/s390/s390-64/bits/wordsize.h b/sysdeps/s390/s390-64/bits/wordsize.h index da791fa28e..00e88b0628 100644 --- a/sysdeps/s390/s390-64/bits/wordsize.h +++ b/sysdeps/s390/s390-64/bits/wordsize.h @@ -5,15 +5,7 @@ #else # define __WORDSIZE 32 # define __WORDSIZE32_SIZE_ULONG 1 +# define __WORDSIZE32_PTRDIFF_LONG 0 #endif -#if !defined __NO_LONG_DOUBLE_MATH && !defined __LONG_DOUBLE_MATH_OPTIONAL - -/* Signal that we didn't used to have a `long double'. The changes all - the `long double' function variants to be redirects to the double - functions. */ -# define __LONG_DOUBLE_MATH_OPTIONAL 1 -# ifndef __LONG_DOUBLE_128__ -# define __NO_LONG_DOUBLE_MATH 1 -# endif -#endif +#define __WORDSIZE_TIME64_COMPAT32 0 diff --git a/sysdeps/s390/s390-64/bzero.S b/sysdeps/s390/s390-64/bzero.S index 891efc2d6e..b321665298 100644 --- a/sysdeps/s390/s390-64/bzero.S +++ b/sysdeps/s390/s390-64/bzero.S @@ -1,6 +1,6 @@ /* bzero -- set a block of memory to zero. 64 bit S/390 version. This file is part of the GNU C Library. - Copyright (C) 2001-2016 Free Software Foundation, Inc. + Copyright (C) 2001-2018 Free Software Foundation, Inc. Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com). The GNU C Library is free software; you can redistribute it and/or diff --git a/sysdeps/s390/s390-64/crti.S b/sysdeps/s390/s390-64/crti.S index 248ef83dbe..f676eb5259 100644 --- a/sysdeps/s390/s390-64/crti.S +++ b/sysdeps/s390/s390-64/crti.S @@ -1,5 +1,5 @@ /* Special .init and .fini section support for 64 bit S/390. - Copyright (C) 2001-2016 Free Software Foundation, Inc. + Copyright (C) 2001-2018 Free Software Foundation, Inc. Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com). This file is part of the GNU C Library. @@ -59,6 +59,7 @@ .section .init,"ax",@progbits .align 4 .globl _init + .hidden _init .type _init,@function _init: stmg %r6,%r15,48(%r15) @@ -81,6 +82,7 @@ _init: .section .fini,"ax",@progbits .align 4 .globl _fini + .hidden _fini .type _fini,@function _fini: stmg %r6,%r15,48(%r15) diff --git a/sysdeps/s390/s390-64/crtn.S b/sysdeps/s390/s390-64/crtn.S index ce906acffc..8ae6394b72 100644 --- a/sysdeps/s390/s390-64/crtn.S +++ b/sysdeps/s390/s390-64/crtn.S @@ -1,5 +1,5 @@ /* Special .init and .fini section support for 64 bit S/390. - Copyright (C) 2001-2016 Free Software Foundation, Inc. + Copyright (C) 2001-2018 Free Software Foundation, Inc. Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com). This file is part of the GNU C Library. diff --git a/sysdeps/s390/s390-64/dl-machine.h b/sysdeps/s390/s390-64/dl-machine.h index cb81aafc5d..f22db7860b 100644 --- a/sysdeps/s390/s390-64/dl-machine.h +++ b/sysdeps/s390/s390-64/dl-machine.h @@ -1,6 +1,6 @@ /* Machine-dependent ELF dynamic relocation inline functions. 64 bit S/390 Version. - Copyright (C) 2001-2016 Free Software Foundation, Inc. + Copyright (C) 2001-2018 Free Software Foundation, Inc. Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com). This file is part of the GNU C Library. @@ -26,6 +26,7 @@ #include <sys/param.h> #include <string.h> #include <link.h> +#include <sysdeps/s390/dl-procinfo.h> #include <dl-irel.h> #define ELF_MACHINE_IRELATIVE R_390_IRELATIVE @@ -78,6 +79,10 @@ elf_machine_runtime_setup (struct link_map *l, int lazy, int profile) { extern void _dl_runtime_resolve (Elf64_Word); extern void _dl_runtime_profile (Elf64_Word); +#if defined HAVE_S390_VX_ASM_SUPPORT + extern void _dl_runtime_resolve_vx (Elf64_Word); + extern void _dl_runtime_profile_vx (Elf64_Word); +#endif if (l->l_info[DT_JMPREL] && lazy) { @@ -93,7 +98,7 @@ elf_machine_runtime_setup (struct link_map *l, int lazy, int profile) if (got[1]) { l->l_mach.plt = got[1] + l->l_addr; - l->l_mach.gotplt = (Elf64_Addr) &got[3]; + l->l_mach.jmprel = (const Elf64_Rela *) D_PTR (l, l_info[DT_JMPREL]); } got[1] = (Elf64_Addr) l; /* Identify this shared object. */ @@ -105,7 +110,14 @@ elf_machine_runtime_setup (struct link_map *l, int lazy, int profile) end in this function. */ if (__glibc_unlikely (profile)) { +#if defined HAVE_S390_VX_ASM_SUPPORT + if (GLRO(dl_hwcap) & HWCAP_S390_VX) + got[2] = (Elf64_Addr) &_dl_runtime_profile_vx; + else + got[2] = (Elf64_Addr) &_dl_runtime_profile; +#else got[2] = (Elf64_Addr) &_dl_runtime_profile; +#endif if (GLRO(dl_profile) != NULL && _dl_name_match_p (GLRO(dl_profile), l)) @@ -114,9 +126,18 @@ elf_machine_runtime_setup (struct link_map *l, int lazy, int profile) GL(dl_profile_map) = l; } else - /* This function will get called to fix up the GOT entry indicated by - the offset on the stack, and then jump to the resolved address. */ - got[2] = (Elf64_Addr) &_dl_runtime_resolve; + { + /* This function will get called to fix up the GOT entry indicated by + the offset on the stack, and then jump to the resolved address. */ +#if defined HAVE_S390_VX_ASM_SUPPORT + if (GLRO(dl_hwcap) & HWCAP_S390_VX) + got[2] = (Elf64_Addr) &_dl_runtime_resolve_vx; + else + got[2] = (Elf64_Addr) &_dl_runtime_resolve; +#else + got[2] = (Elf64_Addr) &_dl_runtime_resolve; +#endif + } } return lazy; @@ -221,6 +242,7 @@ dl_platform_init (void) static inline Elf64_Addr elf_machine_fixup_plt (struct link_map *map, lookup_t t, + const ElfW(Sym) *refsym, const ElfW(Sym) *sym, const Elf64_Rela *reloc, Elf64_Addr *reloc_addr, Elf64_Addr value) { @@ -283,7 +305,7 @@ elf_machine_rela (struct link_map *map, const Elf64_Rela *reloc, const Elf64_Sym *const refsym = sym; #endif struct link_map *sym_map = RESOLVE_MAP (&sym, version, r_type); - Elf64_Addr value = sym == NULL ? 0 : sym_map->l_addr + sym->st_value; + Elf64_Addr value = SYMBOL_ADDRESS (sym_map, sym, true); if (sym != NULL && __builtin_expect (ELFW(ST_TYPE) (sym->st_info) == STT_GNU_IFUNC, @@ -439,9 +461,7 @@ elf_machine_lazy_rel (struct link_map *map, if (__builtin_expect (map->l_mach.plt, 0) == 0) *reloc_addr += l_addr; else - *reloc_addr = - map->l_mach.plt - + (((Elf64_Addr) reloc_addr) - map->l_mach.gotplt) * 4; + *reloc_addr = map->l_mach.plt + (reloc - map->l_mach.jmprel) * 32; } else if (__glibc_likely (r_type == R_390_IRELATIVE)) { diff --git a/sysdeps/s390/s390-64/dl-trampoline.S b/sysdeps/s390/s390-64/dl-trampoline.S index 6919ed0138..03c8f0415b 100644 --- a/sysdeps/s390/s390-64/dl-trampoline.S +++ b/sysdeps/s390/s390-64/dl-trampoline.S @@ -1,5 +1,5 @@ /* PLT trampolines. s390x version. - Copyright (C) 2005-2016 Free Software Foundation, Inc. + Copyright (C) 2005-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -16,126 +16,18 @@ License along with the GNU C Library; if not, see <http://www.gnu.org/licenses/>. */ -/* The PLT stubs will call _dl_runtime_resolve/_dl_runtime_profile - * with the following linkage: - * r2 - r6 : parameter registers - * f0, f2, f4, f6 : floating point parameter registers - * 48(r15), 56(r15) : PLT arguments PLT1, PLT2 - * 160(r15) : additional stack parameters - * The normal clobber rules for function calls apply: - * r0 - r5 : call clobbered - * r6 - r13 : call saved - * r14 : return address (call clobbered) - * r15 : stack pointer (call saved) - * f1, f3, f5, f7 : call saved - * f0 - f3, f5, f7 - f15 : call clobbered - */ - #include <sysdep.h> .text - .globl _dl_runtime_resolve - .type _dl_runtime_resolve, @function - cfi_startproc - .align 16 -_dl_runtime_resolve: - stmg %r2,%r5,64(15) # save call-clobbered argument registers - stg %r14,96(15) - cfi_offset (r14, -64) - lgr %r0,%r15 - aghi %r15,-160 # create stack frame - cfi_adjust_cfa_offset (160) - stg %r0,0(%r15) # write backchain - lmg %r2,%r3,208(%r15)# load args saved by PLT - brasl %r14,_dl_fixup # call fixup - lgr %r1,%r2 # function addr returned in r2 - aghi %r15,160 # remove stack frame - cfi_adjust_cfa_offset (-160) - lg %r14,96(15) # restore registers - lmg %r2,%r5,64(15) - br %r1 - cfi_endproc - .size _dl_runtime_resolve, .-_dl_runtime_resolve - - -#ifndef PROF - .globl _dl_runtime_profile - .type _dl_runtime_profile, @function - cfi_startproc - .align 16 -_dl_runtime_profile: - stmg %r2,%r6,64(%r15) # save call-clobbered arg regs - std %f0,104(%r15) # + r6 needed as arg for - std %f2,112(%r15) # _dl_profile_fixup - std %f4,120(%r15) - std %f6,128(%r15) - stg %r12,24(%r15) # r12 is used as backup of r15 - stg %r14,32(%r15) - cfi_offset (r6, -96) - cfi_offset (f0, -56) - cfi_offset (f2, -48) - cfi_offset (f4, -40) - cfi_offset (f6, -32) - cfi_offset (r12, -136) - cfi_offset (r14, -128) - lgr %r12,%r15 # backup stack pointer - cfi_def_cfa_register (12) - aghi %r15,-160 # create stack frame - stg %r12,0(%r15) # save backchain - lmg %r2,%r3,48(%r12) # load arguments saved by PLT - lgr %r4,%r14 # return address as third parameter - la %r5,64(%r12) # pointer to struct La_s390_32_regs - la %r6,40(%r12) # long int * framesize - brasl %r14,_dl_profile_fixup # call resolver - lgr %r1,%r2 # function addr returned in r2 - lg %r0,40(%r12) # load framesize - ltgr %r0,%r0 - jnm 1f - - lmg %r2,%r6,64(%r12) # framesize < 0 means no pltexit call - ld %f0,104(%r12) # so we can do a tail call without - ld %f2,112(%r12) # copying the arg overflow area - ld %f4,120(%r12) - ld %f6,128(%r12) - - lgr %r15,%r12 # remove stack frame - cfi_def_cfa_register (15) - lg %r14,32(%r15) # restore registers - lg %r12,24(%r15) - br %r1 # tail-call to resolved function - - cfi_def_cfa_register (12) -1: jz 4f # framesize == 0 ? - aghi %r0,7 # align framesize to 8 - nill %r0,0xfff8 - slgr %r15,%r0 # make room for framesize bytes - stg %r12,0(%r15) - la %r2,160(%r15) - la %r3,160(%r12) - srlg %r0,%r0,3 -3: mvc 0(8,%r2),0(%r3) # copy additional parameters - la %r2,8(%r2) - la %r3,8(%r3) - brctg %r0,3b -4: lmg %r2,%r6,64(%r12) # load register parameters - ld %f0,104(%r12) # restore call-clobbered arg regs - ld %f2,112(%r12) - ld %f4,120(%r12) - ld %f6,128(%r12) - basr %r14,%r1 # call resolved function - stg %r2,136(%r12) - std %f0,144(%r12) - lmg %r2,%r3,48(%r12) # load arguments saved by PLT - la %r4,32(%r12) # pointer to struct La_s390_32_regs - la %r5,72(%r12) # pointer to struct La_s390_32_retval - brasl %r14,_dl_call_pltexit - - lgr %r15,%r12 # remove stack frame - cfi_def_cfa_register (15) - lg %r14,32(%r15) # restore registers - lg %r12,24(%r15) - br %r14 - - cfi_endproc - .size _dl_runtime_profile, .-_dl_runtime_profile +/* Create variant of _dl_runtime_resolve/profile for machines before z13. + No vector registers are saved/restored. */ +#include <dl-trampoline.h> + +#if defined HAVE_S390_VX_ASM_SUPPORT +/* Create variant of _dl_runtime_resolve/profile for z13 and newer. + The vector registers are saved/restored, too.*/ +# define _dl_runtime_resolve _dl_runtime_resolve_vx +# define _dl_runtime_profile _dl_runtime_profile_vx +# define RESTORE_VRS +# include <dl-trampoline.h> #endif diff --git a/sysdeps/s390/s390-64/dl-trampoline.h b/sysdeps/s390/s390-64/dl-trampoline.h new file mode 100644 index 0000000000..d313fd521d --- /dev/null +++ b/sysdeps/s390/s390-64/dl-trampoline.h @@ -0,0 +1,224 @@ +/* PLT trampolines. s390x version. + Copyright (C) 2016-2018 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +/* The PLT stubs will call _dl_runtime_resolve/_dl_runtime_profile + * with the following linkage: + * r2 - r6 : parameter registers + * f0, f2, f4, f6 : floating point parameter registers + * v24, v26, v28, v30, v25, v27, v29, v31 : vector parameter registers + * 48(r15), 56(r15) : PLT arguments PLT1, PLT2 + * 160(r15) : additional stack parameters + * The normal clobber rules for function calls apply: + * r0 - r5 : call clobbered + * r6 - r13 : call saved + * r14 : return address (call clobbered) + * r15 : stack pointer (call saved) + * f0 - f7 : call clobbered + * f8 - f15 : call saved + * v0 - v7 : bytes 0-7 overlap with f0-f7: call clobbered + bytes 8-15: call clobbered + * v8 - v15 : bytes 0-7 overlap with f8-f15: call saved + bytes 8-15: call clobbered + * v16 - v31 : call clobbered + */ + + .globl _dl_runtime_resolve + .type _dl_runtime_resolve, @function + cfi_startproc + .align 16 +_dl_runtime_resolve: + stmg %r2,%r5,64(%r15) # save call-clobbered argument registers + cfi_offset (r2, -96) + cfi_offset (r3, -88) + cfi_offset (r4, -80) + cfi_offset (r5, -72) + stmg %r14,%r15,96(%r15) + cfi_offset (r14, -64) + cfi_offset (r15, -56) + std %f0,112(%r15) + cfi_offset (f0, -48) + std %f2,120(%r15) + cfi_offset (f2, -40) + std %f4,128(%r15) + cfi_offset (f4, -32) + std %f6,136(%r15) + cfi_offset (f6, -24) + lmg %r2,%r3,48(%r15) # load args for fixup saved by PLT + lgr %r0,%r15 +#ifdef RESTORE_VRS + aghi %r15,-288 # create stack frame + cfi_adjust_cfa_offset (288) + .machine push + .machine "z13" + vstm %v24,%v31,160(%r15)# store call-clobbered vector argument registers + cfi_offset (v24, -288) + cfi_offset (v25, -272) + cfi_offset (v26, -256) + cfi_offset (v27, -240) + cfi_offset (v28, -224) + cfi_offset (v29, -208) + cfi_offset (v30, -192) + cfi_offset (v31, -176) + .machine pop +#else + aghi %r15,-160 # create stack frame + cfi_adjust_cfa_offset (160) +#endif + stg %r0,0(%r15) # write backchain + brasl %r14,_dl_fixup # call _dl_fixup + lgr %r1,%r2 # function addr returned in r2 +#ifdef RESTORE_VRS + .machine push + .machine "z13" + vlm %v24,%v31,160(%r15)# restore vector registers + .machine pop + lmg %r14,%r15,384(%r15)# remove stack frame and restore registers +#else + lmg %r14,%r15,256(%r15)# remove stack frame and restore registers +#endif + cfi_def_cfa_offset (160) + ld %f0,112(%r15) + ld %f2,120(%r15) + ld %f4,128(%r15) + ld %f6,136(%r15) + lmg %r2,%r5,64(%r15) + br %r1 + cfi_endproc + .size _dl_runtime_resolve, .-_dl_runtime_resolve + + +#ifndef PROF + .globl _dl_runtime_profile + .type _dl_runtime_profile, @function + cfi_startproc + .align 16 +_dl_runtime_profile: + stg %r12,24(%r15) # r12 is used as backup of r15 + cfi_offset (r12, -136) + stg %r14,32(%r15) + cfi_offset (r14, -128) + lgr %r12,%r15 # backup stack pointer + cfi_def_cfa_register (12) + aghi %r15,-360 # create stack frame: + # 160 + sizeof(La_s390_64_regs) + stg %r12,0(%r15) # save backchain + + stmg %r2,%r6,160(%r15) # save call-clobbered arg regs + cfi_offset (r2, -360) # + r6 needed as arg for + cfi_offset (r3, -352) # _dl_profile_fixup + cfi_offset (r4, -344) + cfi_offset (r5, -336) + cfi_offset (r6, -328) + std %f0,200(%r15) + cfi_offset (f0, -320) + std %f2,208(%r15) + cfi_offset (f2, -312) + std %f4,216(%r15) + cfi_offset (f4, -304) + std %f6,224(%r15) + cfi_offset (f6, -296) +#ifdef RESTORE_VRS + .machine push + .machine "z13" + vstm %v24,%v31,232(%r15) # store call-clobbered vector arguments + cfi_offset (v24, -288) + cfi_offset (v25, -272) + cfi_offset (v26, -256) + cfi_offset (v27, -240) + cfi_offset (v28, -224) + cfi_offset (v29, -208) + cfi_offset (v30, -192) + cfi_offset (v31, -176) + .machine pop +#endif + lmg %r2,%r3,48(%r12) # load arguments saved by PLT + lgr %r4,%r14 # return address as third parameter + la %r5,160(%r15) # pointer to struct La_s390_64_regs + la %r6,40(%r12) # long int * framesize + brasl %r14,_dl_profile_fixup # call resolver + lgr %r1,%r2 # function addr returned in r2 + ld %f0,200(%r15) # restore call-clobbered arg fprs + ld %f2,208(%r15) + ld %f4,216(%r15) + ld %f6,224(%r15) +#ifdef RESTORE_VRS + .machine push + .machine "z13" + vlm %v24,%v31,232(%r15) # restore call-clobbered arg vrs + .machine pop +#endif + lg %r0,40(%r12) # load framesize + ltgr %r0,%r0 + jnm 1f + + lmg %r2,%r6,160(%r15) # framesize < 0 means no pltexit call + # so we can do a tail call without + # copying the arg overflow area + lgr %r15,%r12 # remove stack frame + cfi_def_cfa_register (15) + lg %r14,32(%r15) # restore registers + lg %r12,24(%r15) + br %r1 # tail-call to resolved function + + cfi_def_cfa_register (12) +1: la %r4,160(%r15) # pointer to struct La_s390_64_regs + stg %r4,64(%r12) + jz 4f # framesize == 0 ? + aghi %r0,7 # align framesize to 8 + nill %r0,0xfff8 + slgr %r15,%r0 # make room for framesize bytes + stg %r12,0(%r15) # save backchain + la %r2,160(%r15) + la %r3,160(%r12) + srlg %r0,%r0,3 +3: mvc 0(8,%r2),0(%r3) # copy additional parameters + la %r2,8(%r2) # depending on framesize + la %r3,8(%r3) + brctg %r0,3b +4: lmg %r2,%r6,0(%r4) # restore call-clobbered arg gprs + basr %r14,%r1 # call resolved function + stg %r2,72(%r12) # store return values r2, f0 + std %f0,80(%r12) # to struct La_s390_64_retval +#ifdef RESTORE_VRS + .machine push + .machine "z13" + vst %v24,88(%r12) # store return value v24 + .machine pop +#endif + lmg %r2,%r4,48(%r12) # r2, r3: load arguments saved by PLT + # r4: pointer to struct La_s390_64_regs + la %r5,72(%r12) # pointer to struct La_s390_64_retval + brasl %r14,_dl_call_pltexit + + lgr %r15,%r12 # remove stack frame + cfi_def_cfa_register (15) + lg %r14,32(%r15) # restore registers + lg %r12,24(%r15) + lg %r2,72(%r15) # restore return values + ld %f0,80(%r15) +#ifdef RESTORE_VRS + .machine push + .machine "z13" + vl %v24,88(%r15) # restore return value v24 + .machine pop +#endif + br %r14 # Jump back to caller + + cfi_endproc + .size _dl_runtime_profile, .-_dl_runtime_profile +#endif diff --git a/sysdeps/s390/s390-64/memchr.S b/sysdeps/s390/s390-64/memchr.S index 8d50dcfe86..a19fcafa14 100644 --- a/sysdeps/s390/s390-64/memchr.S +++ b/sysdeps/s390/s390-64/memchr.S @@ -1,5 +1,5 @@ /* Search a character in a block of memory. 64 bit S/390 version. - Copyright (C) 2001-2016 Free Software Foundation, Inc. + Copyright (C) 2001-2018 Free Software Foundation, Inc. Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com). This file is part of the GNU C Library. diff --git a/sysdeps/s390/s390-64/memcmp.S b/sysdeps/s390/s390-64/memcmp.S index 5e79d544bf..005b19de45 100644 --- a/sysdeps/s390/s390-64/memcmp.S +++ b/sysdeps/s390/s390-64/memcmp.S @@ -1,5 +1,5 @@ /* memcmp - compare two memory blocks. 64 bit S/390 version. - Copyright (C) 2012-2016 Free Software Foundation, Inc. + Copyright (C) 2012-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or diff --git a/sysdeps/s390/s390-64/memcpy.S b/sysdeps/s390/s390-64/memcpy.S index e84a3572cb..2e5490df23 100644 --- a/sysdeps/s390/s390-64/memcpy.S +++ b/sysdeps/s390/s390-64/memcpy.S @@ -1,5 +1,5 @@ /* memcpy - copy a block from source to destination. 64 bit S/390 version. - Copyright (C) 2012-2016 Free Software Foundation, Inc. + Copyright (C) 2012-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -27,19 +27,27 @@ .text +ENTRY(__mempcpy) + .machine "z900" + lgr %r1,%r2 # Use as dest + la %r2,0(%r4,%r2) # Return dest + n + j .L_Z900_start +END(__mempcpy) +#ifndef USE_MULTIARCH +libc_hidden_def (__mempcpy) +weak_alias (__mempcpy, mempcpy) +libc_hidden_builtin_def (mempcpy) +#endif -#ifdef USE_MULTIARCH -ENTRY(__memcpy_default) -#else ENTRY(memcpy) -#endif .machine "z900" + lgr %r1,%r2 # r1: Use as dest ; r2: Return dest +.L_Z900_start: ltgr %r4,%r4 je .L_Z900_4 aghi %r4,-1 srlg %r5,%r4,8 ltgr %r5,%r5 - lgr %r1,%r2 jne .L_Z900_13 .L_Z900_3: larl %r5,.L_Z900_15 @@ -47,7 +55,7 @@ ENTRY(memcpy) .L_Z900_4: br %r14 .L_Z900_13: - chi %r5,4096 # Switch to mvcle for copies >1MB + cghi %r5,4096 # Switch to mvcle for copies >1MB jh __memcpy_mvcle .L_Z900_12: mvc 0(256,%r1),0(%r3) @@ -57,25 +65,24 @@ ENTRY(memcpy) j .L_Z900_3 .L_Z900_15: mvc 0(1,%r1),0(%r3) - -#ifdef USE_MULTIARCH -END(__memcpy_default) -#else END(memcpy) +#ifndef USE_MULTIARCH libc_hidden_builtin_def (memcpy) #endif ENTRY(__memcpy_mvcle) - # Using as standalone function will result in unexpected - # results since the length field is incremented by 1 in order to - # compensate the changes already done in the functions above. - aghi %r4,1 # length + 1 - lgr %r5,%r4 # source length - lgr %r4,%r3 # source address - lgr %r3,%r5 # destination length = source length + # Using as standalone function will result in unexpected + # results since the length field is incremented by 1 in order to + # compensate the changes already done in the functions above. + lgr %r0,%r2 # backup return dest [ + n ] + aghi %r4,1 # length + 1 + lgr %r5,%r4 # source length + lgr %r4,%r3 # source address + lgr %r2,%r1 # destination address + lgr %r3,%r5 # destination length = source length .L_MVCLE_1: - mvcle %r2,%r4,0 # thats it, MVCLE is your friend - jo .L_MVCLE_1 - lgr %r2,%r1 # return destination address - br %r14 + mvcle %r2,%r4,0 # thats it, MVCLE is your friend + jo .L_MVCLE_1 + lgr %r2,%r0 # return destination address + br %r14 END(__memcpy_mvcle) diff --git a/sysdeps/s390/s390-64/memset.S b/sysdeps/s390/s390-64/memset.S index cab7855549..8799c6592c 100644 --- a/sysdeps/s390/s390-64/memset.S +++ b/sysdeps/s390/s390-64/memset.S @@ -1,5 +1,5 @@ /* Set a block of memory to some byte value. 64 bit S/390 version. - Copyright (C) 2001-2016 Free Software Foundation, Inc. + Copyright (C) 2001-2018 Free Software Foundation, Inc. Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com). This file is part of the GNU C Library. diff --git a/sysdeps/s390/s390-64/multiarch/memchr.c b/sysdeps/s390/s390-64/multiarch/memchr.c index 2281e43056..5e1610afa4 100644 --- a/sysdeps/s390/s390-64/multiarch/memchr.c +++ b/sysdeps/s390/s390-64/multiarch/memchr.c @@ -1,5 +1,5 @@ /* Multiple versions of memchr. - Copyright (C) 2015-2016 Free Software Foundation, Inc. + Copyright (C) 2015-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or diff --git a/sysdeps/s390/s390-64/multiarch/memcmp-s390x.S b/sysdeps/s390/s390-64/multiarch/memcmp-s390x.S index 2a4c0ae9a6..35f9bf9cf7 100644 --- a/sysdeps/s390/s390-64/multiarch/memcmp-s390x.S +++ b/sysdeps/s390/s390-64/multiarch/memcmp-s390x.S @@ -1,5 +1,5 @@ /* CPU specific memcmp implementations. 64 bit S/390 version. - Copyright (C) 2012-2016 Free Software Foundation, Inc. + Copyright (C) 2012-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -98,4 +98,7 @@ END(__memcmp_z10) .set memcmp,__memcmp_default .weak bcmp .set bcmp,__memcmp_default +#elif defined SHARED && IS_IN (libc) +.globl __GI_memcmp +.set __GI_memcmp,__memcmp_default #endif diff --git a/sysdeps/s390/s390-64/multiarch/memcmp.c b/sysdeps/s390/s390-64/multiarch/memcmp.c index 44f72dc8ca..1e6f31806e 100644 --- a/sysdeps/s390/s390-64/multiarch/memcmp.c +++ b/sysdeps/s390/s390-64/multiarch/memcmp.c @@ -1,5 +1,5 @@ /* Multiple versions of memcmp. - Copyright (C) 2015-2016 Free Software Foundation, Inc. + Copyright (C) 2015-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -17,8 +17,11 @@ <http://www.gnu.org/licenses/>. */ #if IS_IN (libc) +# define memcmp __redirect_memcmp +# include <string.h> +# undef memcmp # include <ifunc-resolve.h> -s390_libc_ifunc (memcmp) -__asm__(".weak bcmp ; bcmp = memcmp"); +s390_libc_ifunc (__redirect_memcmp, __memcmp, memcmp) +weak_alias (memcmp, bcmp); #endif diff --git a/sysdeps/s390/s390-64/multiarch/memcpy-s390x.S b/sysdeps/s390/s390-64/multiarch/memcpy-s390x.S index 69fa562060..6d60a70834 100644 --- a/sysdeps/s390/s390-64/multiarch/memcpy-s390x.S +++ b/sysdeps/s390/s390-64/multiarch/memcpy-s390x.S @@ -1,5 +1,5 @@ /* CPU specific memcpy implementations. 64 bit S/390 version. - Copyright (C) 2012-2016 Free Software Foundation, Inc. + Copyright (C) 2012-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -29,12 +29,20 @@ #if defined SHARED && IS_IN (libc) +ENTRY(____mempcpy_z196) + .machine "z196" + lgr %r1,%r2 # Use as dest + la %r2,0(%r4,%r2) # Return dest + n + j .L_Z196_start +END(____mempcpy_z196) + ENTRY(__memcpy_z196) .machine "z196" + lgr %r1,%r2 # r1: Use as dest ; r2: Return dest +.L_Z196_start: ltgr %r4,%r4 je .L_Z196_4 aghi %r4,-1 - lgr %r1,%r2 srlg %r5,%r4,8 ltgr %r5,%r5 jne .L_Z196_5 @@ -58,11 +66,19 @@ ENTRY(__memcpy_z196) mvc 0(1,%r1),0(%r3) END(__memcpy_z196) +ENTRY(____mempcpy_z10) + .machine "z10" + lgr %r1,%r2 # Use as dest + la %r2,0(%r4,%r2) # Return dest + n + j .L_Z10_start +END(____mempcpy_z10) + ENTRY(__memcpy_z10) .machine "z10" + lgr %r1,%r2 # r1: Use as dest ; r2: Return dest +.L_Z10_start: cgije %r4,0,.L_Z10_4 aghi %r4,-1 - lgr %r1,%r2 srlg %r5,%r4,8 cgijlh %r5,0,.L_Z10_13 .L_Z10_3: @@ -84,11 +100,23 @@ ENTRY(__memcpy_z10) mvc 0(1,%r1),0(%r3) END(__memcpy_z10) +# define __mempcpy ____mempcpy_default #endif /* SHARED && IS_IN (libc) */ +#define memcpy __memcpy_default #include "../memcpy.S" +#undef memcpy -#if !defined SHARED || !IS_IN (libc) +#if defined SHARED && IS_IN (libc) +.globl __GI_memcpy +.set __GI_memcpy,__memcpy_default +.globl __GI_mempcpy +.set __GI_mempcpy,____mempcpy_default +.globl __GI___mempcpy +.set __GI___mempcpy,____mempcpy_default +#else .globl memcpy .set memcpy,__memcpy_default +.weak mempcpy +.set mempcpy,__mempcpy #endif diff --git a/sysdeps/s390/s390-64/multiarch/memcpy.c b/sysdeps/s390/s390-64/multiarch/memcpy.c index 2a98aa0b82..c9577a854a 100644 --- a/sysdeps/s390/s390-64/multiarch/memcpy.c +++ b/sysdeps/s390/s390-64/multiarch/memcpy.c @@ -1,5 +1,5 @@ /* Multiple versions of memcpy. - Copyright (C) 2015-2016 Free Software Foundation, Inc. + Copyright (C) 2015-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -18,7 +18,10 @@ /* In the static lib memcpy is needed before the reloc is resolved. */ #if defined SHARED && IS_IN (libc) +# define memcpy __redirect_memcpy +# include <string.h> +# undef memcpy # include <ifunc-resolve.h> -s390_libc_ifunc (memcpy) +s390_libc_ifunc (__redirect_memcpy, __memcpy, memcpy) #endif diff --git a/sysdeps/s390/s390-64/multiarch/memset-s390x.S b/sysdeps/s390/s390-64/multiarch/memset-s390x.S index 05e068279d..0c5aaef34f 100644 --- a/sysdeps/s390/s390-64/multiarch/memset-s390x.S +++ b/sysdeps/s390/s390-64/multiarch/memset-s390x.S @@ -1,5 +1,5 @@ /* Set a block of memory to some byte value. 64 bit S/390 version. - Copyright (C) 2012-2016 Free Software Foundation, Inc. + Copyright (C) 2012-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -106,4 +106,7 @@ END(__memset_mvcle) #if !IS_IN (libc) .globl memset .set memset,__memset_default +#elif defined SHARED && IS_IN (libc) +.globl __GI_memset +.set __GI_memset,__memset_default #endif diff --git a/sysdeps/s390/s390-64/multiarch/memset.c b/sysdeps/s390/s390-64/multiarch/memset.c index 89b8102f2a..760b3e9df2 100644 --- a/sysdeps/s390/s390-64/multiarch/memset.c +++ b/sysdeps/s390/s390-64/multiarch/memset.c @@ -1,5 +1,5 @@ /* Multiple versions of memset. - Copyright (C) 2015-2016 Free Software Foundation, Inc. + Copyright (C) 2015-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -17,7 +17,10 @@ <http://www.gnu.org/licenses/>. */ #if IS_IN (libc) +# define memset __redirect_memset +# include <string.h> +# undef memset # include <ifunc-resolve.h> -s390_libc_ifunc (memset) +s390_libc_ifunc (__redirect_memset, __memset, memset) #endif diff --git a/sysdeps/s390/s390-64/multiarch/strcmp.c b/sysdeps/s390/s390-64/multiarch/strcmp.c index b7eebc017f..d06b0f3436 100644 --- a/sysdeps/s390/s390-64/multiarch/strcmp.c +++ b/sysdeps/s390/s390-64/multiarch/strcmp.c @@ -1,5 +1,5 @@ /* Multiple versions of strcmp. - Copyright (C) 2015-2016 Free Software Foundation, Inc. + Copyright (C) 2015-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or diff --git a/sysdeps/s390/s390-64/multiarch/strcpy.c b/sysdeps/s390/s390-64/multiarch/strcpy.c index ae140d22b7..6a22e31a03 100644 --- a/sysdeps/s390/s390-64/multiarch/strcpy.c +++ b/sysdeps/s390/s390-64/multiarch/strcpy.c @@ -1,5 +1,5 @@ /* Multiple versions of strcpy. - Copyright (C) 2015-2016 Free Software Foundation, Inc. + Copyright (C) 2015-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or diff --git a/sysdeps/s390/s390-64/multiarch/strncpy.c b/sysdeps/s390/s390-64/multiarch/strncpy.c index 28a2af72e4..57f9df18d1 100644 --- a/sysdeps/s390/s390-64/multiarch/strncpy.c +++ b/sysdeps/s390/s390-64/multiarch/strncpy.c @@ -1,5 +1,5 @@ /* Multiple versions of strncpy. - Copyright (C) 2015-2016 Free Software Foundation, Inc. + Copyright (C) 2015-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or diff --git a/sysdeps/s390/s390-64/s390x-mcount.S b/sysdeps/s390/s390-64/s390x-mcount.S index cb67ddb7ff..c6b5d65e17 100644 --- a/sysdeps/s390/s390-64/s390x-mcount.S +++ b/sysdeps/s390/s390-64/s390x-mcount.S @@ -1,5 +1,5 @@ -/* 64 bit S/390-specific implemetation of profiling support. - Copyright (C) 2001-2016 Free Software Foundation, Inc. +/* 64 bit S/390-specific implementation of profiling support. + Copyright (C) 2001-2018 Free Software Foundation, Inc. Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com) This file is part of the GNU C Library. diff --git a/sysdeps/s390/s390-64/setjmp.S b/sysdeps/s390/s390-64/setjmp.S index bbcb70db5f..f512589fb9 100644 --- a/sysdeps/s390/s390-64/setjmp.S +++ b/sysdeps/s390/s390-64/setjmp.S @@ -1,5 +1,5 @@ /* setjmp for 64 bit S/390, ELF version. - Copyright (C) 2001-2016 Free Software Foundation, Inc. + Copyright (C) 2001-2018 Free Software Foundation, Inc. Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com). This file is part of the GNU C Library. @@ -24,17 +24,16 @@ #include <shlib-compat.h> #include <stap-probe.h> -#if !IS_IN (rtld) -# if defined SHARED && SHLIB_COMPAT (libc, GLIBC_2_19, GLIBC_2_20) - /* we need a unique name in case of symbol versioning. */ -# define setjmp __v1setjmp -# define _setjmp __v1_setjmp -# define __sigsetjmp __v1__sigsetjmp - -# undef libc_hidden_def -# define libc_hidden_def(name) strong_alias(_setjmp, __GI__setjmp) -# endif /* if defined SHARED && SHLIB_COMPAT (libc, GLIBC_2_19, GLIBC_2_20) */ -#endif /* !IS_IN (rtld) */ +#if !IS_IN (rtld) && defined SHARED \ + && SHLIB_COMPAT (libc, GLIBC_2_19, GLIBC_2_20) +# define NEED_COMPAT_SYMBOLS 1 +/* We need a unique name in case of symbol versioning. */ +# define setjmp __v1setjmp +# define _setjmp __v1_setjmp +# define __sigsetjmp __v1__sigsetjmp +#else +# define NEED_COMPAT_SYMBOLS 0 +#endif /* We include the BSD entry points here as well. */ ENTRY (setjmp) @@ -47,7 +46,11 @@ ENTRY(_setjmp) slgr %r3,%r3 /* Second argument of zero. */ j .Linternal_sigsetjmp /* Branch relativ to __sigsetjmp. */ END (_setjmp) +#if NEED_COMPAT_SYMBOLS +strong_alias (_setjmp, __GI__setjmp) +#else libc_hidden_def (_setjmp) +#endif ENTRY(__setjmp) slgr %r3,%r3 /* Second argument of zero. */ @@ -87,15 +90,19 @@ ENTRY(__sigsetjmp) jg __sigjmp_save #endif END (__sigsetjmp) +#if NEED_COMPAT_SYMBOLS +strong_alias (__sigsetjmp, __GI___sigsetjmp) +#else +libc_hidden_def (__sigsetjmp) +#endif -#if !IS_IN (rtld) -# if defined SHARED && SHLIB_COMPAT (libc, GLIBC_2_19, GLIBC_2_20) +#if NEED_COMPAT_SYMBOLS /* In glibc release 2.19 new versions of setjmp-functions were introduced, but were reverted before 2.20. Thus both versions are the same function. */ -# undef setjmp -# undef _setjmp -# undef __sigsetjmp +# undef setjmp +# undef _setjmp +# undef __sigsetjmp strong_alias (__v1setjmp, __v2setjmp); versioned_symbol (libc, __v1setjmp, setjmp, GLIBC_2_0); @@ -108,5 +115,4 @@ compat_symbol (libc, __v2_setjmp, _setjmp, GLIBC_2_19); strong_alias (__v1__sigsetjmp, __v2__sigsetjmp); versioned_symbol (libc, __v1__sigsetjmp, __sigsetjmp, GLIBC_2_0); compat_symbol (libc, __v2__sigsetjmp, __sigsetjmp, GLIBC_2_19); -# endif /* if defined SHARED && SHLIB_COMPAT (libc, GLIBC_2_19, GLIBC_2_20) */ -#endif /* if !IS_IN (rtld) */ +#endif /* NEED_COMPAT_SYMBOLS */ diff --git a/sysdeps/s390/s390-64/start.S b/sysdeps/s390/s390-64/start.S index e261460dd5..79e7b69f1d 100644 --- a/sysdeps/s390/s390-64/start.S +++ b/sysdeps/s390/s390-64/start.S @@ -1,5 +1,5 @@ /* Startup code compliant to the 64 bit S/390 ELF ABI. - Copyright (C) 2001-2016 Free Software Foundation, Inc. + Copyright (C) 2001-2018 Free Software Foundation, Inc. Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com). This file is part of the GNU C Library. @@ -34,6 +34,8 @@ License along with the GNU C Library; if not, see <http://www.gnu.org/licenses/>. */ +#include <sysdep.h> + /* This is the canonical entry point, usually the first thing in the text segment. Most registers' values are unspecified, except for: @@ -57,6 +59,9 @@ .globl _start .type _start,@function _start: + cfi_startproc + /* Mark r14 as undefined in order to stop unwinding here! */ + cfi_undefined (r14) /* Load argc and argv from stack. */ la %r4,8(%r15) # get argv lg %r3,0(%r15) # get argc @@ -91,6 +96,8 @@ _start: /* Crash if __libc_start_main returns. */ .word 0 + cfi_endproc + /* Define a symbol for the first piece of initialized data. */ .data .globl __data_start diff --git a/sysdeps/s390/s390-64/strcmp.S b/sysdeps/s390/s390-64/strcmp.S index 245b54cc9d..6cf1addd8b 100644 --- a/sysdeps/s390/s390-64/strcmp.S +++ b/sysdeps/s390/s390-64/strcmp.S @@ -1,6 +1,6 @@ /* strcmp - compare two string. 64 bit S/390 version. This file is part of the GNU C Library. - Copyright (C) 2001-2016 Free Software Foundation, Inc. + Copyright (C) 2001-2018 Free Software Foundation, Inc. Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com). The GNU C Library is free software; you can redistribute it and/or diff --git a/sysdeps/s390/s390-64/strcpy.S b/sysdeps/s390/s390-64/strcpy.S index 9864e98b24..203c73c905 100644 --- a/sysdeps/s390/s390-64/strcpy.S +++ b/sysdeps/s390/s390-64/strcpy.S @@ -1,5 +1,5 @@ /* strcpy - copy a string from source to destination. 64 bit S/390 version. - Copyright (C) 2001-2016 Free Software Foundation, Inc. + Copyright (C) 2001-2018 Free Software Foundation, Inc. Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com). This file is part of the GNU C Library. diff --git a/sysdeps/s390/s390-64/strncpy.S b/sysdeps/s390/s390-64/strncpy.S index 56c8a526ae..be40aa32d5 100644 --- a/sysdeps/s390/s390-64/strncpy.S +++ b/sysdeps/s390/s390-64/strncpy.S @@ -1,6 +1,6 @@ /* strncpy - copy at most n characters from a string from source to destination. 64 bit S/390 version - Copyright (C) 2001-2016 Free Software Foundation, Inc. + Copyright (C) 2001-2018 Free Software Foundation, Inc. Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com). This file is part of the GNU C Library. diff --git a/sysdeps/s390/s390-64/sub_n.S b/sysdeps/s390/s390-64/sub_n.S index 7318836db9..ad5c7fc9ca 100644 --- a/sysdeps/s390/s390-64/sub_n.S +++ b/sysdeps/s390/s390-64/sub_n.S @@ -1,6 +1,6 @@ /* __mpn_sub_n -- Add two limb vectors of the same length > 0 and store sum in a third limb vector. 64 bit S/390 version. - Copyright (C) 2001-2016 Free Software Foundation, Inc. + Copyright (C) 2001-2018 Free Software Foundation, Inc. Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com). This file is part of the GNU MP Library. diff --git a/sysdeps/s390/s390-64/sysdep.h b/sysdeps/s390/s390-64/sysdep.h index 7fac89da51..a573e08e92 100644 --- a/sysdeps/s390/s390-64/sysdep.h +++ b/sysdeps/s390/s390-64/sysdep.h @@ -1,5 +1,5 @@ /* Assembler macros for 64 bit S/390. - Copyright (C) 2001-2016 Free Software Foundation, Inc. + Copyright (C) 2001-2018 Free Software Foundation, Inc. Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com). This file is part of the GNU C Library. @@ -77,7 +77,7 @@ lose: SYSCALL_PIC_SETUP \ END (name) #undef JUMPTARGET -#ifdef PIC +#ifdef SHARED #define JUMPTARGET(name) name##@PLT #define SYSCALL_PIC_SETUP \ larl %r12,_GLOBAL_OFFSET_TABLE_ diff --git a/sysdeps/s390/s390-64/tls-macros.h b/sysdeps/s390/s390-64/tls-macros.h index d70ea6ce0c..449a843d69 100644 --- a/sysdeps/s390/s390-64/tls-macros.h +++ b/sysdeps/s390/s390-64/tls-macros.h @@ -8,13 +8,15 @@ #ifdef PIC # define TLS_IE(x) \ - ({ unsigned long __offset, __got; \ + ({ unsigned long __offset, __save12; \ __asm__ ("bras %0,0f\n\t" \ ".quad " #x "@gotntpoff\n" \ - "0:\tlarl %1,_GLOBAL_OFFSET_TABLE_\n\t" \ + "0:\tlgr %1,%%r12\n\t" \ + "larl %%r12,_GLOBAL_OFFSET_TABLE_\n\t" \ "lg %0,0(%0)\n\t" \ - "lg %0,0(%0,%1):tls_load:" #x "\n" \ - : "=&a" (__offset), "=&a" (__got) : : "cc" ); \ + "lg %0,0(%0,%%r12):tls_load:" #x "\n\t" \ + "lgr %%r12,%1\n" \ + : "=&a" (__offset), "=&a" (__save12) : : "cc" ); \ (int *) (__builtin_thread_pointer() + __offset); }) #else # define TLS_IE(x) \ diff --git a/sysdeps/s390/s390-64/tst-audit.h b/sysdeps/s390/s390-64/tst-audit.h index 3283e95037..954373e24f 100644 --- a/sysdeps/s390/s390-64/tst-audit.h +++ b/sysdeps/s390/s390-64/tst-audit.h @@ -1,6 +1,6 @@ /* Definitions for testing PLT entry/exit auditing. S/390 64-bit version. - Copyright (C) 2012-2016 Free Software Foundation, Inc. + Copyright (C) 2012-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. diff --git a/sysdeps/s390/s390-64/utf16-utf32-z9.c b/sysdeps/s390/s390-64/utf16-utf32-z9.c deleted file mode 100644 index a3863ee244..0000000000 --- a/sysdeps/s390/s390-64/utf16-utf32-z9.c +++ /dev/null @@ -1,337 +0,0 @@ -/* Conversion between UTF-16 and UTF-32 BE/internal. - - This module uses the Z9-109 variants of the Convert Unicode - instructions. - Copyright (C) 1997-2016 Free Software Foundation, Inc. - - Author: Andreas Krebbel <Andreas.Krebbel@de.ibm.com> - Based on the work by Ulrich Drepper <drepper@cygnus.com>, 1997. - - Thanks to Daniel Appich who covered the relevant performance work - in his diploma thesis. - - This is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, see - <http://www.gnu.org/licenses/>. */ - -#include <dlfcn.h> -#include <stdint.h> -#include <unistd.h> -#include <dl-procinfo.h> -#include <gconv.h> - -/* UTF-32 big endian byte order mark. */ -#define BOM_UTF32 0x0000feffu - -/* UTF-16 big endian byte order mark. */ -#define BOM_UTF16 0xfeff - -#define DEFINE_INIT 0 -#define DEFINE_FINI 0 -#define MIN_NEEDED_FROM 2 -#define MAX_NEEDED_FROM 4 -#define MIN_NEEDED_TO 4 -#define FROM_LOOP from_utf16_loop -#define TO_LOOP to_utf16_loop -#define FROM_DIRECTION (dir == from_utf16) -#define ONE_DIRECTION 0 -#define PREPARE_LOOP \ - enum direction dir = ((struct utf16_data *) step->__data)->dir; \ - int emit_bom = ((struct utf16_data *) step->__data)->emit_bom; \ - \ - if (emit_bom && !data->__internal_use \ - && data->__invocation_counter == 0) \ - { \ - if (dir == to_utf16) \ - { \ - /* Emit the UTF-16 Byte Order Mark. */ \ - if (__glibc_unlikely (outbuf + 2 > outend)) \ - return __GCONV_FULL_OUTPUT; \ - \ - put16u (outbuf, BOM_UTF16); \ - outbuf += 2; \ - } \ - else \ - { \ - /* Emit the UTF-32 Byte Order Mark. */ \ - if (__glibc_unlikely (outbuf + 4 > outend)) \ - return __GCONV_FULL_OUTPUT; \ - \ - put32u (outbuf, BOM_UTF32); \ - outbuf += 4; \ - } \ - } - -/* Direction of the transformation. */ -enum direction -{ - illegal_dir, - to_utf16, - from_utf16 -}; - -struct utf16_data -{ - enum direction dir; - int emit_bom; -}; - - -extern int gconv_init (struct __gconv_step *step); -int -gconv_init (struct __gconv_step *step) -{ - /* Determine which direction. */ - struct utf16_data *new_data; - enum direction dir = illegal_dir; - int emit_bom; - int result; - - emit_bom = (__strcasecmp (step->__to_name, "UTF-32//") == 0 - || __strcasecmp (step->__to_name, "UTF-16//") == 0); - - if (__strcasecmp (step->__from_name, "UTF-16BE//") == 0 - && (__strcasecmp (step->__to_name, "UTF-32//") == 0 - || __strcasecmp (step->__to_name, "UTF-32BE//") == 0 - || __strcasecmp (step->__to_name, "INTERNAL") == 0)) - { - dir = from_utf16; - } - else if ((__strcasecmp (step->__to_name, "UTF-16//") == 0 - || __strcasecmp (step->__to_name, "UTF-16BE//") == 0) - && (__strcasecmp (step->__from_name, "UTF-32BE//") == 0 - || __strcasecmp (step->__from_name, "INTERNAL") == 0)) - { - dir = to_utf16; - } - - result = __GCONV_NOCONV; - if (dir != illegal_dir) - { - new_data = (struct utf16_data *) malloc (sizeof (struct utf16_data)); - - result = __GCONV_NOMEM; - if (new_data != NULL) - { - new_data->dir = dir; - new_data->emit_bom = emit_bom; - step->__data = new_data; - - if (dir == from_utf16) - { - step->__min_needed_from = MIN_NEEDED_FROM; - step->__max_needed_from = MIN_NEEDED_FROM; - step->__min_needed_to = MIN_NEEDED_TO; - step->__max_needed_to = MIN_NEEDED_TO; - } - else - { - step->__min_needed_from = MIN_NEEDED_TO; - step->__max_needed_from = MIN_NEEDED_TO; - step->__min_needed_to = MIN_NEEDED_FROM; - step->__max_needed_to = MIN_NEEDED_FROM; - } - - step->__stateful = 0; - - result = __GCONV_OK; - } - } - - return result; -} - - -extern void gconv_end (struct __gconv_step *data); -void -gconv_end (struct __gconv_step *data) -{ - free (data->__data); -} - -/* The macro for the hardware loop. This is used for both - directions. */ -#define HARDWARE_CONVERT(INSTRUCTION) \ - { \ - register const unsigned char* pInput __asm__ ("8") = inptr; \ - register unsigned long long inlen __asm__ ("9") = inend - inptr; \ - register unsigned char* pOutput __asm__ ("10") = outptr; \ - register unsigned long long outlen __asm__("11") = outend - outptr; \ - uint64_t cc = 0; \ - \ - __asm__ volatile (".machine push \n\t" \ - ".machine \"z9-109\" \n\t" \ - "0: " INSTRUCTION " \n\t" \ - ".machine pop \n\t" \ - " jo 0b \n\t" \ - " ipm %2 \n" \ - : "+a" (pOutput), "+a" (pInput), "+d" (cc), \ - "+d" (outlen), "+d" (inlen) \ - : \ - : "cc", "memory"); \ - \ - inptr = pInput; \ - outptr = pOutput; \ - cc >>= 28; \ - \ - if (cc == 1) \ - { \ - result = __GCONV_FULL_OUTPUT; \ - break; \ - } \ - else if (cc == 2) \ - { \ - result = __GCONV_ILLEGAL_INPUT; \ - break; \ - } \ - } - -/* Conversion function from UTF-16 to UTF-32 internal/BE. */ - -#define MIN_NEEDED_INPUT MIN_NEEDED_FROM -#define MAX_NEEDED_INPUT MAX_NEEDED_FROM -#define MIN_NEEDED_OUTPUT MIN_NEEDED_TO -#define LOOPFCT FROM_LOOP -/* The software routine is copied from utf-16.c (minus bytes - swapping). */ -#define BODY \ - { \ - /* The hardware instruction currently fails to report an error for \ - isolated low surrogates so we have to disable the instruction \ - until this gets resolved. */ \ - if (0) /* (GLRO (dl_hwcap) & HWCAP_S390_ETF3EH) */ \ - { \ - HARDWARE_CONVERT ("cu24 %0, %1, 1"); \ - if (inptr != inend) \ - { \ - /* Check if the third byte is \ - a valid start of a UTF-16 surrogate. */ \ - if (inend - inptr == 3 && (inptr[3] & 0xfc) != 0xdc) \ - STANDARD_FROM_LOOP_ERR_HANDLER (3); \ - \ - result = __GCONV_INCOMPLETE_INPUT; \ - break; \ - } \ - continue; \ - } \ - \ - uint16_t u1 = get16 (inptr); \ - \ - if (__builtin_expect (u1 < 0xd800, 1) || u1 > 0xdfff) \ - { \ - /* No surrogate. */ \ - put32 (outptr, u1); \ - inptr += 2; \ - } \ - else \ - { \ - /* An isolated low-surrogate was found. This has to be \ - considered ill-formed. */ \ - if (__glibc_unlikely (u1 >= 0xdc00)) \ - { \ - STANDARD_FROM_LOOP_ERR_HANDLER (2); \ - } \ - /* It's a surrogate character. At least the first word says \ - it is. */ \ - if (__glibc_unlikely (inptr + 4 > inend)) \ - { \ - /* We don't have enough input for another complete input \ - character. */ \ - result = __GCONV_INCOMPLETE_INPUT; \ - break; \ - } \ - \ - inptr += 2; \ - uint16_t u2 = get16 (inptr); \ - if (__builtin_expect (u2 < 0xdc00, 0) \ - || __builtin_expect (u2 > 0xdfff, 0)) \ - { \ - /* This is no valid second word for a surrogate. */ \ - inptr -= 2; \ - STANDARD_FROM_LOOP_ERR_HANDLER (2); \ - } \ - \ - put32 (outptr, ((u1 - 0xd7c0) << 10) + (u2 - 0xdc00)); \ - inptr += 2; \ - } \ - outptr += 4; \ - } -#define LOOP_NEED_FLAGS -#include <iconv/loop.c> - -/* Conversion from UTF-32 internal/BE to UTF-16. */ - -#define MIN_NEEDED_INPUT MIN_NEEDED_TO -#define MIN_NEEDED_OUTPUT MIN_NEEDED_FROM -#define MAX_NEEDED_OUTPUT MAX_NEEDED_FROM -#define LOOPFCT TO_LOOP -/* The software routine is copied from utf-16.c (minus bytes - swapping). */ -#define BODY \ - { \ - if (GLRO (dl_hwcap) & HWCAP_S390_ETF3EH) \ - { \ - HARDWARE_CONVERT ("cu42 %0, %1"); \ - \ - if (inptr != inend) \ - { \ - result = __GCONV_INCOMPLETE_INPUT; \ - break; \ - } \ - continue; \ - } \ - \ - uint32_t c = get32 (inptr); \ - \ - if (__builtin_expect (c <= 0xd7ff, 1) \ - || (c >=0xdc00 && c <= 0xffff)) \ - { \ - /* Two UTF-16 chars. */ \ - put16 (outptr, c); \ - } \ - else if (__builtin_expect (c >= 0x10000, 1) \ - && __builtin_expect (c <= 0x10ffff, 1)) \ - { \ - /* Four UTF-16 chars. */ \ - uint16_t zabcd = ((c & 0x1f0000) >> 16) - 1; \ - uint16_t out; \ - \ - /* Generate a surrogate character. */ \ - if (__glibc_unlikely (outptr + 4 > outend)) \ - { \ - /* Overflow in the output buffer. */ \ - result = __GCONV_FULL_OUTPUT; \ - break; \ - } \ - \ - out = 0xd800; \ - out |= (zabcd & 0xff) << 6; \ - out |= (c >> 10) & 0x3f; \ - put16 (outptr, out); \ - outptr += 2; \ - \ - out = 0xdc00; \ - out |= c & 0x3ff; \ - put16 (outptr, out); \ - } \ - else \ - { \ - STANDARD_TO_LOOP_ERR_HANDLER (4); \ - } \ - outptr += 2; \ - inptr += 4; \ - } -#define LOOP_NEED_FLAGS -#include <iconv/loop.c> - -#include <iconv/skeleton.c> diff --git a/sysdeps/s390/s390-64/utf8-utf16-z9.c b/sysdeps/s390/s390-64/utf8-utf16-z9.c deleted file mode 100644 index 4148ed796b..0000000000 --- a/sysdeps/s390/s390-64/utf8-utf16-z9.c +++ /dev/null @@ -1,471 +0,0 @@ -/* Conversion between UTF-16 and UTF-32 BE/internal. - - This module uses the Z9-109 variants of the Convert Unicode - instructions. - Copyright (C) 1997-2016 Free Software Foundation, Inc. - - Author: Andreas Krebbel <Andreas.Krebbel@de.ibm.com> - Based on the work by Ulrich Drepper <drepper@cygnus.com>, 1997. - - Thanks to Daniel Appich who covered the relevant performance work - in his diploma thesis. - - This is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, see - <http://www.gnu.org/licenses/>. */ - -#include <dlfcn.h> -#include <stdint.h> -#include <unistd.h> -#include <dl-procinfo.h> -#include <gconv.h> - -/* UTF-16 big endian byte order mark. */ -#define BOM_UTF16 0xfeff - -#define DEFINE_INIT 0 -#define DEFINE_FINI 0 -#define MIN_NEEDED_FROM 1 -#define MAX_NEEDED_FROM 4 -#define MIN_NEEDED_TO 2 -#define MAX_NEEDED_TO 4 -#define FROM_LOOP from_utf8_loop -#define TO_LOOP to_utf8_loop -#define FROM_DIRECTION (dir == from_utf8) -#define ONE_DIRECTION 0 -#define PREPARE_LOOP \ - enum direction dir = ((struct utf8_data *) step->__data)->dir; \ - int emit_bom = ((struct utf8_data *) step->__data)->emit_bom; \ - \ - if (emit_bom && !data->__internal_use \ - && data->__invocation_counter == 0) \ - { \ - /* Emit the UTF-16 Byte Order Mark. */ \ - if (__glibc_unlikely (outbuf + 2 > outend)) \ - return __GCONV_FULL_OUTPUT; \ - \ - put16u (outbuf, BOM_UTF16); \ - outbuf += 2; \ - } - -/* Direction of the transformation. */ -enum direction -{ - illegal_dir, - to_utf8, - from_utf8 -}; - -struct utf8_data -{ - enum direction dir; - int emit_bom; -}; - - -extern int gconv_init (struct __gconv_step *step); -int -gconv_init (struct __gconv_step *step) -{ - /* Determine which direction. */ - struct utf8_data *new_data; - enum direction dir = illegal_dir; - int emit_bom; - int result; - - emit_bom = (__strcasecmp (step->__to_name, "UTF-16//") == 0); - - if (__strcasecmp (step->__from_name, "ISO-10646/UTF8/") == 0 - && (__strcasecmp (step->__to_name, "UTF-16//") == 0 - || __strcasecmp (step->__to_name, "UTF-16BE//") == 0)) - { - dir = from_utf8; - } - else if (__strcasecmp (step->__from_name, "UTF-16BE//") == 0 - && __strcasecmp (step->__to_name, "ISO-10646/UTF8/") == 0) - { - dir = to_utf8; - } - - result = __GCONV_NOCONV; - if (dir != illegal_dir) - { - new_data = (struct utf8_data *) malloc (sizeof (struct utf8_data)); - - result = __GCONV_NOMEM; - if (new_data != NULL) - { - new_data->dir = dir; - new_data->emit_bom = emit_bom; - step->__data = new_data; - - if (dir == from_utf8) - { - step->__min_needed_from = MIN_NEEDED_FROM; - step->__max_needed_from = MIN_NEEDED_FROM; - step->__min_needed_to = MIN_NEEDED_TO; - step->__max_needed_to = MIN_NEEDED_TO; - } - else - { - step->__min_needed_from = MIN_NEEDED_TO; - step->__max_needed_from = MIN_NEEDED_TO; - step->__min_needed_to = MIN_NEEDED_FROM; - step->__max_needed_to = MIN_NEEDED_FROM; - } - - step->__stateful = 0; - - result = __GCONV_OK; - } - } - - return result; -} - - -extern void gconv_end (struct __gconv_step *data); -void -gconv_end (struct __gconv_step *data) -{ - free (data->__data); -} - -/* The macro for the hardware loop. This is used for both - directions. */ -#define HARDWARE_CONVERT(INSTRUCTION) \ - { \ - register const unsigned char* pInput __asm__ ("8") = inptr; \ - register unsigned long long inlen __asm__ ("9") = inend - inptr; \ - register unsigned char* pOutput __asm__ ("10") = outptr; \ - register unsigned long long outlen __asm__("11") = outend - outptr; \ - uint64_t cc = 0; \ - \ - __asm__ volatile (".machine push \n\t" \ - ".machine \"z9-109\" \n\t" \ - "0: " INSTRUCTION " \n\t" \ - ".machine pop \n\t" \ - " jo 0b \n\t" \ - " ipm %2 \n" \ - : "+a" (pOutput), "+a" (pInput), "+d" (cc), \ - "+d" (outlen), "+d" (inlen) \ - : \ - : "cc", "memory"); \ - \ - inptr = pInput; \ - outptr = pOutput; \ - cc >>= 28; \ - \ - if (cc == 1) \ - { \ - result = __GCONV_FULL_OUTPUT; \ - break; \ - } \ - else if (cc == 2) \ - { \ - result = __GCONV_ILLEGAL_INPUT; \ - break; \ - } \ - } - -/* Conversion function from UTF-8 to UTF-16. */ - -#define MIN_NEEDED_INPUT MIN_NEEDED_FROM -#define MAX_NEEDED_INPUT MAX_NEEDED_FROM -#define MIN_NEEDED_OUTPUT MIN_NEEDED_TO -#define MAX_NEEDED_OUTPUT MAX_NEEDED_TO -#define LOOPFCT FROM_LOOP -/* The software implementation is based on the code in gconv_simple.c. */ -#define BODY \ - { \ - if (GLRO (dl_hwcap) & HWCAP_S390_ETF3EH) \ - { \ - HARDWARE_CONVERT ("cu12 %0, %1, 1"); \ - \ - if (inptr != inend) \ - { \ - int i; \ - for (i = 1; inptr + i < inend; ++i) \ - if ((inptr[i] & 0xc0) != 0x80) \ - break; \ - \ - if (__glibc_likely (inptr + i == inend)) \ - { \ - result = __GCONV_INCOMPLETE_INPUT; \ - break; \ - } \ - STANDARD_FROM_LOOP_ERR_HANDLER (i); \ - } \ - continue; \ - } \ - \ - /* Next input byte. */ \ - uint16_t ch = *inptr; \ - \ - if (__glibc_likely (ch < 0x80)) \ - { \ - /* One byte sequence. */ \ - ++inptr; \ - } \ - else \ - { \ - uint_fast32_t cnt; \ - uint_fast32_t i; \ - \ - if (ch >= 0xc2 && ch < 0xe0) \ - { \ - /* We expect two bytes. The first byte cannot be 0xc0 \ - or 0xc1, otherwise the wide character could have been \ - represented using a single byte. */ \ - cnt = 2; \ - ch &= 0x1f; \ - } \ - else if (__glibc_likely ((ch & 0xf0) == 0xe0)) \ - { \ - /* We expect three bytes. */ \ - cnt = 3; \ - ch &= 0x0f; \ - } \ - else if (__glibc_likely ((ch & 0xf8) == 0xf0)) \ - { \ - /* We expect four bytes. */ \ - cnt = 4; \ - ch &= 0x07; \ - } \ - else \ - { \ - /* Search the end of this ill-formed UTF-8 character. This \ - is the next byte with (x & 0xc0) != 0x80. */ \ - i = 0; \ - do \ - ++i; \ - while (inptr + i < inend \ - && (*(inptr + i) & 0xc0) == 0x80 \ - && i < 5); \ - \ - errout: \ - STANDARD_FROM_LOOP_ERR_HANDLER (i); \ - } \ - \ - if (__glibc_unlikely (inptr + cnt > inend)) \ - { \ - /* We don't have enough input. But before we report \ - that check that all the bytes are correct. */ \ - for (i = 1; inptr + i < inend; ++i) \ - if ((inptr[i] & 0xc0) != 0x80) \ - break; \ - \ - if (__glibc_likely (inptr + i == inend)) \ - { \ - result = __GCONV_INCOMPLETE_INPUT; \ - break; \ - } \ - \ - goto errout; \ - } \ - \ - if (cnt == 4) \ - { \ - /* For 4 byte UTF-8 chars two UTF-16 chars (high and \ - low) are needed. */ \ - uint16_t zabcd, high, low; \ - \ - if (__glibc_unlikely (outptr + 4 > outend)) \ - { \ - /* Overflow in the output buffer. */ \ - result = __GCONV_FULL_OUTPUT; \ - break; \ - } \ - \ - /* See Principles of Operations cu12. */ \ - zabcd = (((inptr[0] & 0x7) << 2) | \ - ((inptr[1] & 0x30) >> 4)) - 1; \ - \ - /* z-bit must be zero after subtracting 1. */ \ - if (zabcd & 0x10) \ - STANDARD_FROM_LOOP_ERR_HANDLER (4) \ - \ - high = (uint16_t)(0xd8 << 8); /* high surrogate id */ \ - high |= zabcd << 6; /* abcd bits */ \ - high |= (inptr[1] & 0xf) << 2; /* efgh bits */ \ - high |= (inptr[2] & 0x30) >> 4; /* ij bits */ \ - \ - low = (uint16_t)(0xdc << 8); /* low surrogate id */ \ - low |= ((uint16_t)inptr[2] & 0xc) << 6; /* kl bits */ \ - low |= (inptr[2] & 0x3) << 6; /* mn bits */ \ - low |= inptr[3] & 0x3f; /* opqrst bits */ \ - \ - put16 (outptr, high); \ - outptr += 2; \ - put16 (outptr, low); \ - outptr += 2; \ - inptr += 4; \ - continue; \ - } \ - else \ - { \ - /* Read the possible remaining bytes. */ \ - for (i = 1; i < cnt; ++i) \ - { \ - uint16_t byte = inptr[i]; \ - \ - if ((byte & 0xc0) != 0x80) \ - /* This is an illegal encoding. */ \ - break; \ - \ - ch <<= 6; \ - ch |= byte & 0x3f; \ - } \ - inptr += cnt; \ - \ - } \ - } \ - /* Now adjust the pointers and store the result. */ \ - *((uint16_t *) outptr) = ch; \ - outptr += sizeof (uint16_t); \ - } - -#define LOOP_NEED_FLAGS -#include <iconv/loop.c> - -/* Conversion from UTF-16 to UTF-8. */ - -#define MIN_NEEDED_INPUT MIN_NEEDED_TO -#define MAX_NEEDED_INPUT MAX_NEEDED_TO -#define MIN_NEEDED_OUTPUT MIN_NEEDED_FROM -#define MAX_NEEDED_OUTPUT MAX_NEEDED_FROM -#define LOOPFCT TO_LOOP -/* The software routine is based on the functionality of the S/390 - hardware instruction (cu21) as described in the Principles of - Operation. */ -#define BODY \ - { \ - /* The hardware instruction currently fails to report an error for \ - isolated low surrogates so we have to disable the instruction \ - until this gets resolved. */ \ - if (0) /* (GLRO (dl_hwcap) & HWCAP_S390_ETF3EH) */ \ - { \ - HARDWARE_CONVERT ("cu21 %0, %1, 1"); \ - if (inptr != inend) \ - { \ - /* Check if the third byte is \ - a valid start of a UTF-16 surrogate. */ \ - if (inend - inptr == 3 && (inptr[3] & 0xfc) != 0xdc) \ - STANDARD_TO_LOOP_ERR_HANDLER (3); \ - \ - result = __GCONV_INCOMPLETE_INPUT; \ - break; \ - } \ - continue; \ - } \ - \ - uint16_t c = get16 (inptr); \ - \ - if (__glibc_likely (c <= 0x007f)) \ - { \ - /* Single byte UTF-8 char. */ \ - *outptr = c & 0xff; \ - outptr++; \ - } \ - else if (c >= 0x0080 && c <= 0x07ff) \ - { \ - /* Two byte UTF-8 char. */ \ - \ - if (__glibc_unlikely (outptr + 2 > outend)) \ - { \ - /* Overflow in the output buffer. */ \ - result = __GCONV_FULL_OUTPUT; \ - break; \ - } \ - \ - outptr[0] = 0xc0; \ - outptr[0] |= c >> 6; \ - \ - outptr[1] = 0x80; \ - outptr[1] |= c & 0x3f; \ - \ - outptr += 2; \ - } \ - else if ((c >= 0x0800 && c <= 0xd7ff) || c > 0xdfff) \ - { \ - /* Three byte UTF-8 char. */ \ - \ - if (__glibc_unlikely (outptr + 3 > outend)) \ - { \ - /* Overflow in the output buffer. */ \ - result = __GCONV_FULL_OUTPUT; \ - break; \ - } \ - outptr[0] = 0xe0; \ - outptr[0] |= c >> 12; \ - \ - outptr[1] = 0x80; \ - outptr[1] |= (c >> 6) & 0x3f; \ - \ - outptr[2] = 0x80; \ - outptr[2] |= c & 0x3f; \ - \ - outptr += 3; \ - } \ - else if (c >= 0xd800 && c <= 0xdbff) \ - { \ - /* Four byte UTF-8 char. */ \ - uint16_t low, uvwxy; \ - \ - if (__glibc_unlikely (outptr + 4 > outend)) \ - { \ - /* Overflow in the output buffer. */ \ - result = __GCONV_FULL_OUTPUT; \ - break; \ - } \ - inptr += 2; \ - if (__glibc_unlikely (inptr + 2 > inend)) \ - { \ - result = __GCONV_INCOMPLETE_INPUT; \ - break; \ - } \ - \ - low = get16 (inptr); \ - \ - if ((low & 0xfc00) != 0xdc00) \ - { \ - inptr -= 2; \ - STANDARD_TO_LOOP_ERR_HANDLER (2); \ - } \ - uvwxy = ((c >> 6) & 0xf) + 1; \ - outptr[0] = 0xf0; \ - outptr[0] |= uvwxy >> 2; \ - \ - outptr[1] = 0x80; \ - outptr[1] |= (uvwxy << 4) & 0x30; \ - outptr[1] |= (c >> 2) & 0x0f; \ - \ - outptr[2] = 0x80; \ - outptr[2] |= (c & 0x03) << 4; \ - outptr[2] |= (low >> 6) & 0x0f; \ - \ - outptr[3] = 0x80; \ - outptr[3] |= low & 0x3f; \ - \ - outptr += 4; \ - } \ - else \ - { \ - STANDARD_TO_LOOP_ERR_HANDLER (2); \ - } \ - inptr += 2; \ - } -#define LOOP_NEED_FLAGS -#include <iconv/loop.c> - -#include <iconv/skeleton.c> diff --git a/sysdeps/s390/s390-64/utf8-utf32-z9.c b/sysdeps/s390/s390-64/utf8-utf32-z9.c deleted file mode 100644 index defd47d251..0000000000 --- a/sysdeps/s390/s390-64/utf8-utf32-z9.c +++ /dev/null @@ -1,511 +0,0 @@ -/* Conversion between UTF-8 and UTF-32 BE/internal. - - This module uses the Z9-109 variants of the Convert Unicode - instructions. - Copyright (C) 1997-2016 Free Software Foundation, Inc. - - Author: Andreas Krebbel <Andreas.Krebbel@de.ibm.com> - Based on the work by Ulrich Drepper <drepper@cygnus.com>, 1997. - - Thanks to Daniel Appich who covered the relevant performance work - in his diploma thesis. - - This is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, see - <http://www.gnu.org/licenses/>. */ - -#include <dlfcn.h> -#include <stdint.h> -#include <unistd.h> -#include <dl-procinfo.h> -#include <gconv.h> - -/* UTF-32 big endian byte order mark. */ -#define BOM 0x0000feffu - -#define DEFINE_INIT 0 -#define DEFINE_FINI 0 -/* These definitions apply to the UTF-8 to UTF-32 direction. The - software implementation for UTF-8 still supports multibyte - characters up to 6 bytes whereas the hardware variant does not. */ -#define MIN_NEEDED_FROM 1 -#define MAX_NEEDED_FROM 6 -#define MIN_NEEDED_TO 4 -#define FROM_LOOP from_utf8_loop -#define TO_LOOP to_utf8_loop -#define FROM_DIRECTION (dir == from_utf8) -#define ONE_DIRECTION 0 -#define PREPARE_LOOP \ - enum direction dir = ((struct utf8_data *) step->__data)->dir; \ - int emit_bom = ((struct utf8_data *) step->__data)->emit_bom; \ - \ - if (emit_bom && !data->__internal_use \ - && data->__invocation_counter == 0) \ - { \ - /* Emit the Byte Order Mark. */ \ - if (__glibc_unlikely (outbuf + 4 > outend)) \ - return __GCONV_FULL_OUTPUT; \ - \ - put32u (outbuf, BOM); \ - outbuf += 4; \ - } - -/* Direction of the transformation. */ -enum direction -{ - illegal_dir, - to_utf8, - from_utf8 -}; - -struct utf8_data -{ - enum direction dir; - int emit_bom; -}; - - -extern int gconv_init (struct __gconv_step *step); -int -gconv_init (struct __gconv_step *step) -{ - /* Determine which direction. */ - struct utf8_data *new_data; - enum direction dir = illegal_dir; - int emit_bom; - int result; - - emit_bom = (__strcasecmp (step->__to_name, "UTF-32//") == 0); - - if (__strcasecmp (step->__from_name, "ISO-10646/UTF8/") == 0 - && (__strcasecmp (step->__to_name, "UTF-32//") == 0 - || __strcasecmp (step->__to_name, "UTF-32BE//") == 0 - || __strcasecmp (step->__to_name, "INTERNAL") == 0)) - { - dir = from_utf8; - } - else if (__strcasecmp (step->__to_name, "ISO-10646/UTF8/") == 0 - && (__strcasecmp (step->__from_name, "UTF-32BE//") == 0 - || __strcasecmp (step->__from_name, "INTERNAL") == 0)) - { - dir = to_utf8; - } - - result = __GCONV_NOCONV; - if (dir != illegal_dir) - { - new_data = (struct utf8_data *) malloc (sizeof (struct utf8_data)); - - result = __GCONV_NOMEM; - if (new_data != NULL) - { - new_data->dir = dir; - new_data->emit_bom = emit_bom; - step->__data = new_data; - - if (dir == from_utf8) - { - step->__min_needed_from = MIN_NEEDED_FROM; - step->__max_needed_from = MIN_NEEDED_FROM; - step->__min_needed_to = MIN_NEEDED_TO; - step->__max_needed_to = MIN_NEEDED_TO; - } - else - { - step->__min_needed_from = MIN_NEEDED_TO; - step->__max_needed_from = MIN_NEEDED_TO; - step->__min_needed_to = MIN_NEEDED_FROM; - step->__max_needed_to = MIN_NEEDED_FROM; - } - - step->__stateful = 0; - - result = __GCONV_OK; - } - } - - return result; -} - - -extern void gconv_end (struct __gconv_step *data); -void -gconv_end (struct __gconv_step *data) -{ - free (data->__data); -} - -/* The macro for the hardware loop. This is used for both - directions. */ -#define HARDWARE_CONVERT(INSTRUCTION) \ - { \ - register const unsigned char* pInput __asm__ ("8") = inptr; \ - register unsigned long long inlen __asm__ ("9") = inend - inptr; \ - register unsigned char* pOutput __asm__ ("10") = outptr; \ - register unsigned long long outlen __asm__("11") = outend - outptr; \ - uint64_t cc = 0; \ - \ - __asm__ volatile (".machine push \n\t" \ - ".machine \"z9-109\" \n\t" \ - "0: " INSTRUCTION " \n\t" \ - ".machine pop \n\t" \ - " jo 0b \n\t" \ - " ipm %2 \n" \ - : "+a" (pOutput), "+a" (pInput), "+d" (cc), \ - "+d" (outlen), "+d" (inlen) \ - : \ - : "cc", "memory"); \ - \ - inptr = pInput; \ - outptr = pOutput; \ - cc >>= 28; \ - \ - if (cc == 1) \ - { \ - result = __GCONV_FULL_OUTPUT; \ - break; \ - } \ - else if (cc == 2) \ - { \ - result = __GCONV_ILLEGAL_INPUT; \ - break; \ - } \ - } - -/* Conversion function from UTF-8 to UTF-32 internal/BE. */ - -#define MIN_NEEDED_INPUT MIN_NEEDED_FROM -#define MAX_NEEDED_INPUT MAX_NEEDED_FROM -#define MIN_NEEDED_OUTPUT MIN_NEEDED_TO -#define LOOPFCT FROM_LOOP -/* The software routine is copied from gconv_simple.c. */ -#define BODY \ - { \ - if (GLRO (dl_hwcap) & HWCAP_S390_ETF3EH) \ - { \ - HARDWARE_CONVERT ("cu14 %0, %1, 1"); \ - \ - if (inptr != inend) \ - { \ - int i; \ - for (i = 1; inptr + i < inend; ++i) \ - if ((inptr[i] & 0xc0) != 0x80) \ - break; \ - \ - if (__glibc_likely (inptr + i == inend)) \ - { \ - result = __GCONV_INCOMPLETE_INPUT; \ - break; \ - } \ - STANDARD_FROM_LOOP_ERR_HANDLER (i); \ - } \ - continue; \ - } \ - \ - /* Next input byte. */ \ - uint32_t ch = *inptr; \ - \ - if (__glibc_likely (ch < 0x80)) \ - { \ - /* One byte sequence. */ \ - ++inptr; \ - } \ - else \ - { \ - uint_fast32_t cnt; \ - uint_fast32_t i; \ - \ - if (ch >= 0xc2 && ch < 0xe0) \ - { \ - /* We expect two bytes. The first byte cannot be 0xc0 or \ - 0xc1, otherwise the wide character could have been \ - represented using a single byte. */ \ - cnt = 2; \ - ch &= 0x1f; \ - } \ - else if (__glibc_likely ((ch & 0xf0) == 0xe0)) \ - { \ - /* We expect three bytes. */ \ - cnt = 3; \ - ch &= 0x0f; \ - } \ - else if (__glibc_likely ((ch & 0xf8) == 0xf0)) \ - { \ - /* We expect four bytes. */ \ - cnt = 4; \ - ch &= 0x07; \ - } \ - else if (__glibc_likely ((ch & 0xfc) == 0xf8)) \ - { \ - /* We expect five bytes. */ \ - cnt = 5; \ - ch &= 0x03; \ - } \ - else if (__glibc_likely ((ch & 0xfe) == 0xfc)) \ - { \ - /* We expect six bytes. */ \ - cnt = 6; \ - ch &= 0x01; \ - } \ - else \ - { \ - /* Search the end of this ill-formed UTF-8 character. This \ - is the next byte with (x & 0xc0) != 0x80. */ \ - i = 0; \ - do \ - ++i; \ - while (inptr + i < inend \ - && (*(inptr + i) & 0xc0) == 0x80 \ - && i < 5); \ - \ - errout: \ - STANDARD_FROM_LOOP_ERR_HANDLER (i); \ - } \ - \ - if (__glibc_unlikely (inptr + cnt > inend)) \ - { \ - /* We don't have enough input. But before we report \ - that check that all the bytes are correct. */ \ - for (i = 1; inptr + i < inend; ++i) \ - if ((inptr[i] & 0xc0) != 0x80) \ - break; \ - \ - if (__glibc_likely (inptr + i == inend)) \ - { \ - result = __GCONV_INCOMPLETE_INPUT; \ - break; \ - } \ - \ - goto errout; \ - } \ - \ - /* Read the possible remaining bytes. */ \ - for (i = 1; i < cnt; ++i) \ - { \ - uint32_t byte = inptr[i]; \ - \ - if ((byte & 0xc0) != 0x80) \ - /* This is an illegal encoding. */ \ - break; \ - \ - ch <<= 6; \ - ch |= byte & 0x3f; \ - } \ - \ - /* If i < cnt, some trail byte was not >= 0x80, < 0xc0. \ - If cnt > 2 and ch < 2^(5*cnt-4), the wide character ch could \ - have been represented with fewer than cnt bytes. */ \ - if (i < cnt || (cnt > 2 && (ch >> (5 * cnt - 4)) == 0)) \ - { \ - /* This is an illegal encoding. */ \ - goto errout; \ - } \ - \ - inptr += cnt; \ - } \ - \ - /* Now adjust the pointers and store the result. */ \ - *((uint32_t *) outptr) = ch; \ - outptr += sizeof (uint32_t); \ - } -#define LOOP_NEED_FLAGS - -#define STORE_REST \ - { \ - /* We store the remaining bytes while converting them into the UCS4 \ - format. We can assume that the first byte in the buffer is \ - correct and that it requires a larger number of bytes than there \ - are in the input buffer. */ \ - wint_t ch = **inptrp; \ - size_t cnt, r; \ - \ - state->__count = inend - *inptrp; \ - \ - if (ch >= 0xc2 && ch < 0xe0) \ - { \ - /* We expect two bytes. The first byte cannot be 0xc0 or \ - 0xc1, otherwise the wide character could have been \ - represented using a single byte. */ \ - cnt = 2; \ - ch &= 0x1f; \ - } \ - else if (__glibc_likely ((ch & 0xf0) == 0xe0)) \ - { \ - /* We expect three bytes. */ \ - cnt = 3; \ - ch &= 0x0f; \ - } \ - else if (__glibc_likely ((ch & 0xf8) == 0xf0)) \ - { \ - /* We expect four bytes. */ \ - cnt = 4; \ - ch &= 0x07; \ - } \ - else if (__glibc_likely ((ch & 0xfc) == 0xf8)) \ - { \ - /* We expect five bytes. */ \ - cnt = 5; \ - ch &= 0x03; \ - } \ - else \ - { \ - /* We expect six bytes. */ \ - cnt = 6; \ - ch &= 0x01; \ - } \ - \ - /* The first byte is already consumed. */ \ - r = cnt - 1; \ - while (++(*inptrp) < inend) \ - { \ - ch <<= 6; \ - ch |= **inptrp & 0x3f; \ - --r; \ - } \ - \ - /* Shift for the so far missing bytes. */ \ - ch <<= r * 6; \ - \ - /* Store the number of bytes expected for the entire sequence. */ \ - state->__count |= cnt << 8; \ - \ - /* Store the value. */ \ - state->__value.__wch = ch; \ - } - -#define UNPACK_BYTES \ - { \ - static const unsigned char inmask[5] = { 0xc0, 0xe0, 0xf0, 0xf8, 0xfc }; \ - wint_t wch = state->__value.__wch; \ - size_t ntotal = state->__count >> 8; \ - \ - inlen = state->__count & 255; \ - \ - bytebuf[0] = inmask[ntotal - 2]; \ - \ - do \ - { \ - if (--ntotal < inlen) \ - bytebuf[ntotal] = 0x80 | (wch & 0x3f); \ - wch >>= 6; \ - } \ - while (ntotal > 1); \ - \ - bytebuf[0] |= wch; \ - } - -#define CLEAR_STATE \ - state->__count = 0 - -#include <iconv/loop.c> - -/* Conversion from UTF-32 internal/BE to UTF-8. */ - -#define MIN_NEEDED_INPUT MIN_NEEDED_TO -#define MIN_NEEDED_OUTPUT MIN_NEEDED_FROM -#define MAX_NEEDED_OUTPUT MAX_NEEDED_FROM -#define LOOPFCT TO_LOOP -/* The software routine mimics the S/390 cu41 instruction. */ -#define BODY \ - { \ - if (GLRO (dl_hwcap) & HWCAP_S390_ETF3EH) \ - { \ - HARDWARE_CONVERT ("cu41 %0, %1"); \ - \ - if (inptr != inend) \ - { \ - result = __GCONV_INCOMPLETE_INPUT; \ - break; \ - } \ - continue; \ - } \ - \ - uint32_t wc = *((const uint32_t *) inptr); \ - \ - if (__glibc_likely (wc <= 0x7f)) \ - { \ - /* Single UTF-8 char. */ \ - *outptr = (uint8_t)wc; \ - outptr++; \ - } \ - else if (wc <= 0x7ff) \ - { \ - /* Two UTF-8 chars. */ \ - if (__glibc_unlikely (outptr + 2 > outend)) \ - { \ - /* Overflow in the output buffer. */ \ - result = __GCONV_FULL_OUTPUT; \ - break; \ - } \ - \ - outptr[0] = 0xc0; \ - outptr[0] |= wc >> 6; \ - \ - outptr[1] = 0x80; \ - outptr[1] |= wc & 0x3f; \ - \ - outptr += 2; \ - } \ - else if (wc <= 0xffff) \ - { \ - /* Three UTF-8 chars. */ \ - if (__glibc_unlikely (outptr + 3 > outend)) \ - { \ - /* Overflow in the output buffer. */ \ - result = __GCONV_FULL_OUTPUT; \ - break; \ - } \ - outptr[0] = 0xe0; \ - outptr[0] |= wc >> 12; \ - \ - outptr[1] = 0x80; \ - outptr[1] |= (wc >> 6) & 0x3f; \ - \ - outptr[2] = 0x80; \ - outptr[2] |= wc & 0x3f; \ - \ - outptr += 3; \ - } \ - else if (wc <= 0x10ffff) \ - { \ - /* Four UTF-8 chars. */ \ - if (__glibc_unlikely (outptr + 4 > outend)) \ - { \ - /* Overflow in the output buffer. */ \ - result = __GCONV_FULL_OUTPUT; \ - break; \ - } \ - outptr[0] = 0xf0; \ - outptr[0] |= wc >> 18; \ - \ - outptr[1] = 0x80; \ - outptr[1] |= (wc >> 12) & 0x3f; \ - \ - outptr[2] = 0x80; \ - outptr[2] |= (wc >> 6) & 0x3f; \ - \ - outptr[3] = 0x80; \ - outptr[3] |= wc & 0x3f; \ - \ - outptr += 4; \ - } \ - else \ - { \ - STANDARD_TO_LOOP_ERR_HANDLER (4); \ - } \ - inptr += 4; \ - } -#define LOOP_NEED_FLAGS -#include <iconv/loop.c> - -#include <iconv/skeleton.c> diff --git a/sysdeps/s390/sotruss-lib.c b/sysdeps/s390/sotruss-lib.c index 8c53bc5b79..90b8f77e55 100644 --- a/sysdeps/s390/sotruss-lib.c +++ b/sysdeps/s390/sotruss-lib.c @@ -1,5 +1,5 @@ /* Override generic sotruss-lib.c to define actual functions for s390. - Copyright (C) 2012-2016 Free Software Foundation, Inc. + Copyright (C) 2012-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. diff --git a/sysdeps/s390/stackinfo.h b/sysdeps/s390/stackinfo.h index 0d4b70abd7..e429f361ae 100644 --- a/sysdeps/s390/stackinfo.h +++ b/sysdeps/s390/stackinfo.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2000-2016 Free Software Foundation, Inc. +/* Copyright (C) 2000-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or diff --git a/sysdeps/s390/string_private.h b/sysdeps/s390/string_private.h index 9e11eee3dc..32e40d3603 100644 --- a/sysdeps/s390/string_private.h +++ b/sysdeps/s390/string_private.h @@ -1,5 +1,5 @@ /* Define _STRING_ARCH_unaligned. S/390 version. - Copyright (C) 2016 Free Software Foundation, Inc. + Copyright (C) 2016-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or diff --git a/sysdeps/s390/utf16-utf32-z9.c b/sysdeps/s390/utf16-utf32-z9.c new file mode 100644 index 0000000000..27086d3e8a --- /dev/null +++ b/sysdeps/s390/utf16-utf32-z9.c @@ -0,0 +1,819 @@ +/* Conversion between UTF-16 and UTF-32 BE/internal. + + This module uses the Z9-109 variants of the Convert Unicode + instructions. + Copyright (C) 1997-2018 Free Software Foundation, Inc. + + Author: Andreas Krebbel <Andreas.Krebbel@de.ibm.com> + Based on the work by Ulrich Drepper <drepper@cygnus.com>, 1997. + + Thanks to Daniel Appich who covered the relevant performance work + in his diploma thesis. + + This is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <dlfcn.h> +#include <stdint.h> +#include <unistd.h> +#include <gconv.h> +#include <string.h> + +/* Select which versions should be defined depending on support + for multiarch, vector and used minimum architecture level. */ +#define HAVE_FROM_C 1 +#define FROM_LOOP_DEFAULT FROM_LOOP_C +#define HAVE_TO_C 1 +#define TO_LOOP_DEFAULT TO_LOOP_C + +#if defined HAVE_S390_VX_ASM_SUPPORT && defined USE_MULTIARCH +# define HAVE_FROM_VX 1 +# define HAVE_FROM_VX_CU 1 +# define HAVE_TO_VX 1 +# define HAVE_TO_VX_CU 1 +#else +# define HAVE_FROM_VX 0 +# define HAVE_FROM_VX_CU 0 +# define HAVE_TO_VX 0 +# define HAVE_TO_VX_CU 0 +#endif + +#if defined HAVE_S390_VX_GCC_SUPPORT +# define ASM_CLOBBER_VR(NR) , NR +#else +# define ASM_CLOBBER_VR(NR) +#endif + +#if defined __s390x__ +# define CONVERT_32BIT_SIZE_T(REG) +#else +# define CONVERT_32BIT_SIZE_T(REG) "llgfr %" #REG ",%" #REG "\n\t" +#endif + +/* UTF-32 big endian byte order mark. */ +#define BOM_UTF32 0x0000feffu + +/* UTF-16 big endian byte order mark. */ +#define BOM_UTF16 0xfeff + +#define DEFINE_INIT 0 +#define DEFINE_FINI 0 +#define MIN_NEEDED_FROM 2 +#define MAX_NEEDED_FROM 4 +#define MIN_NEEDED_TO 4 +#define FROM_LOOP FROM_LOOP_DEFAULT +#define TO_LOOP TO_LOOP_DEFAULT +#define FROM_DIRECTION (dir == from_utf16) +#define ONE_DIRECTION 0 + +/* Direction of the transformation. */ +enum direction +{ + illegal_dir, + to_utf16, + from_utf16 +}; + +struct utf16_data +{ + enum direction dir; + int emit_bom; +}; + + +extern int gconv_init (struct __gconv_step *step); +int +gconv_init (struct __gconv_step *step) +{ + /* Determine which direction. */ + struct utf16_data *new_data; + enum direction dir = illegal_dir; + int emit_bom; + int result; + + emit_bom = (__strcasecmp (step->__to_name, "UTF-32//") == 0 + || __strcasecmp (step->__to_name, "UTF-16//") == 0); + + if (__strcasecmp (step->__from_name, "UTF-16BE//") == 0 + && (__strcasecmp (step->__to_name, "UTF-32//") == 0 + || __strcasecmp (step->__to_name, "UTF-32BE//") == 0 + || __strcasecmp (step->__to_name, "INTERNAL") == 0)) + { + dir = from_utf16; + } + else if ((__strcasecmp (step->__to_name, "UTF-16//") == 0 + || __strcasecmp (step->__to_name, "UTF-16BE//") == 0) + && (__strcasecmp (step->__from_name, "UTF-32BE//") == 0 + || __strcasecmp (step->__from_name, "INTERNAL") == 0)) + { + dir = to_utf16; + } + + result = __GCONV_NOCONV; + if (dir != illegal_dir) + { + new_data = (struct utf16_data *) malloc (sizeof (struct utf16_data)); + + result = __GCONV_NOMEM; + if (new_data != NULL) + { + new_data->dir = dir; + new_data->emit_bom = emit_bom; + step->__data = new_data; + + if (dir == from_utf16) + { + step->__min_needed_from = MIN_NEEDED_FROM; + step->__max_needed_from = MIN_NEEDED_FROM; + step->__min_needed_to = MIN_NEEDED_TO; + step->__max_needed_to = MIN_NEEDED_TO; + } + else + { + step->__min_needed_from = MIN_NEEDED_TO; + step->__max_needed_from = MIN_NEEDED_TO; + step->__min_needed_to = MIN_NEEDED_FROM; + step->__max_needed_to = MIN_NEEDED_FROM; + } + + step->__stateful = 0; + + result = __GCONV_OK; + } + } + + return result; +} + + +extern void gconv_end (struct __gconv_step *data); +void +gconv_end (struct __gconv_step *data) +{ + free (data->__data); +} + +#define PREPARE_LOOP \ + enum direction dir = ((struct utf16_data *) step->__data)->dir; \ + int emit_bom = ((struct utf16_data *) step->__data)->emit_bom; \ + \ + if (emit_bom && !data->__internal_use \ + && data->__invocation_counter == 0) \ + { \ + if (dir == to_utf16) \ + { \ + /* Emit the UTF-16 Byte Order Mark. */ \ + if (__glibc_unlikely (outbuf + 2 > outend)) \ + return __GCONV_FULL_OUTPUT; \ + \ + put16u (outbuf, BOM_UTF16); \ + outbuf += 2; \ + } \ + else \ + { \ + /* Emit the UTF-32 Byte Order Mark. */ \ + if (__glibc_unlikely (outbuf + 4 > outend)) \ + return __GCONV_FULL_OUTPUT; \ + \ + put32u (outbuf, BOM_UTF32); \ + outbuf += 4; \ + } \ + } + +/* Conversion function from UTF-16 to UTF-32 internal/BE. */ + +#if HAVE_FROM_C == 1 +/* The software routine is copied from utf-16.c (minus bytes + swapping). */ +# define BODY_FROM_C \ + { \ + uint16_t u1 = get16 (inptr); \ + \ + if (__builtin_expect (u1 < 0xd800, 1) || u1 > 0xdfff) \ + { \ + /* No surrogate. */ \ + put32 (outptr, u1); \ + inptr += 2; \ + } \ + else \ + { \ + /* An isolated low-surrogate was found. This has to be \ + considered ill-formed. */ \ + if (__glibc_unlikely (u1 >= 0xdc00)) \ + { \ + STANDARD_FROM_LOOP_ERR_HANDLER (2); \ + } \ + /* It's a surrogate character. At least the first word says \ + it is. */ \ + if (__glibc_unlikely (inptr + 4 > inend)) \ + { \ + /* We don't have enough input for another complete input \ + character. */ \ + result = __GCONV_INCOMPLETE_INPUT; \ + break; \ + } \ + \ + inptr += 2; \ + uint16_t u2 = get16 (inptr); \ + if (__builtin_expect (u2 < 0xdc00, 0) \ + || __builtin_expect (u2 > 0xdfff, 0)) \ + { \ + /* This is no valid second word for a surrogate. */ \ + inptr -= 2; \ + STANDARD_FROM_LOOP_ERR_HANDLER (2); \ + } \ + \ + put32 (outptr, ((u1 - 0xd7c0) << 10) + (u2 - 0xdc00)); \ + inptr += 2; \ + } \ + outptr += 4; \ + } + + +/* Generate loop-function with software routing. */ +# define MIN_NEEDED_INPUT MIN_NEEDED_FROM +# define MAX_NEEDED_INPUT MAX_NEEDED_FROM +# define MIN_NEEDED_OUTPUT MIN_NEEDED_TO +# define FROM_LOOP_C __from_utf16_loop_c +# define LOOPFCT FROM_LOOP_C +# define LOOP_NEED_FLAGS +# define BODY BODY_FROM_C +# include <iconv/loop.c> +#else +# define FROM_LOOP_C NULL +#endif /* HAVE_FROM_C != 1 */ + +#if HAVE_FROM_VX == 1 +# define BODY_FROM_VX \ + { \ + size_t inlen = inend - inptr; \ + size_t outlen = outend - outptr; \ + unsigned long tmp, tmp2, tmp3; \ + asm volatile (".machine push\n\t" \ + ".machine \"z13\"\n\t" \ + ".machinemode \"zarch_nohighgprs\"\n\t" \ + /* Setup to check for surrogates. */ \ + " larl %[R_TMP],9f\n\t" \ + " vlm %%v30,%%v31,0(%[R_TMP])\n\t" \ + CONVERT_32BIT_SIZE_T ([R_INLEN]) \ + CONVERT_32BIT_SIZE_T ([R_OUTLEN]) \ + /* Loop which handles UTF-16 chars <0xd800, >0xdfff. */ \ + "0: clgijl %[R_INLEN],16,2f\n\t" \ + " clgijl %[R_OUTLEN],32,2f\n\t" \ + "1: vl %%v16,0(%[R_IN])\n\t" \ + /* Check for surrogate chars. */ \ + " vstrchs %%v19,%%v16,%%v30,%%v31\n\t" \ + " jno 10f\n\t" \ + /* Enlarge to UTF-32. */ \ + " vuplhh %%v17,%%v16\n\t" \ + " la %[R_IN],16(%[R_IN])\n\t" \ + " vupllh %%v18,%%v16\n\t" \ + " aghi %[R_INLEN],-16\n\t" \ + /* Store 32 bytes to buf_out. */ \ + " vstm %%v17,%%v18,0(%[R_OUT])\n\t" \ + " aghi %[R_OUTLEN],-32\n\t" \ + " la %[R_OUT],32(%[R_OUT])\n\t" \ + " clgijl %[R_INLEN],16,2f\n\t" \ + " clgijl %[R_OUTLEN],32,2f\n\t" \ + " j 1b\n\t" \ + /* Setup to check for ch >= 0xd800 && ch <= 0xdfff. (v30, v31) */ \ + "9: .short 0xd800,0xdfff,0x0,0x0,0x0,0x0,0x0,0x0\n\t" \ + " .short 0xa000,0xc000,0x0,0x0,0x0,0x0,0x0,0x0\n\t" \ + /* At least one uint16_t is in range of surrogates. \ + Store the preceding chars. */ \ + "10: vlgvb %[R_TMP],%%v19,7\n\t" \ + " vuplhh %%v17,%%v16\n\t" \ + " sllg %[R_TMP3],%[R_TMP],1\n\t" /* Number of out bytes. */ \ + " ahik %[R_TMP2],%[R_TMP3],-1\n\t" /* Highest index to store. */ \ + " jl 12f\n\t" \ + " vstl %%v17,%[R_TMP2],0(%[R_OUT])\n\t" \ + " vupllh %%v18,%%v16\n\t" \ + " ahi %[R_TMP2],-16\n\t" \ + " jl 11f\n\t" \ + " vstl %%v18,%[R_TMP2],16(%[R_OUT])\n\t" \ + "11: \n\t" /* Update pointers. */ \ + " la %[R_IN],0(%[R_TMP],%[R_IN])\n\t" \ + " slgr %[R_INLEN],%[R_TMP]\n\t" \ + " la %[R_OUT],0(%[R_TMP3],%[R_OUT])\n\t" \ + " slgr %[R_OUTLEN],%[R_TMP3]\n\t" \ + /* Calculate remaining uint16_t values in loaded vrs. */ \ + "12: lghi %[R_TMP2],16\n\t" \ + " slgr %[R_TMP2],%[R_TMP]\n\t" \ + " srl %[R_TMP2],1\n\t" \ + " llh %[R_TMP],0(%[R_IN])\n\t" \ + " aghi %[R_OUTLEN],-4\n\t" \ + " j 16f\n\t" \ + /* Handle remaining bytes. */ \ + "2: \n\t" \ + /* Zero, one or more bytes available? */ \ + " clgfi %[R_INLEN],1\n\t" \ + " je 97f\n\t" /* Only one byte available. */ \ + " jl 99f\n\t" /* End if no bytes available. */ \ + /* Calculate remaining uint16_t values in inptr. */ \ + " srlg %[R_TMP2],%[R_INLEN],1\n\t" \ + /* Handle remaining uint16_t values. */ \ + "13: llh %[R_TMP],0(%[R_IN])\n\t" \ + " slgfi %[R_OUTLEN],4\n\t" \ + " jl 96f \n\t" \ + " clfi %[R_TMP],0xd800\n\t" \ + " jhe 15f\n\t" \ + "14: st %[R_TMP],0(%[R_OUT])\n\t" \ + " la %[R_IN],2(%[R_IN])\n\t" \ + " aghi %[R_INLEN],-2\n\t" \ + " la %[R_OUT],4(%[R_OUT])\n\t" \ + " brctg %[R_TMP2],13b\n\t" \ + " j 0b\n\t" /* Switch to vx-loop. */ \ + /* Handle UTF-16 surrogate pair. */ \ + "15: clfi %[R_TMP],0xdfff\n\t" \ + " jh 14b\n\t" /* Jump away if ch > 0xdfff. */ \ + "16: clfi %[R_TMP],0xdc00\n\t" \ + " jhe 98f\n\t" /* Jump away in case of low-surrogate. */ \ + " slgfi %[R_INLEN],4\n\t" \ + " jl 97f\n\t" /* Big enough input? */ \ + " llh %[R_TMP3],2(%[R_IN])\n\t" /* Load low surrogate. */ \ + " slfi %[R_TMP],0xd7c0\n\t" \ + " sll %[R_TMP],10\n\t" \ + " risbgn %[R_TMP],%[R_TMP3],54,63,0\n\t" /* Insert klmnopqrst. */ \ + " nilf %[R_TMP3],0xfc00\n\t" \ + " clfi %[R_TMP3],0xdc00\n\t" /* Check if it starts with 0xdc00. */ \ + " jne 98f\n\t" \ + " st %[R_TMP],0(%[R_OUT])\n\t" \ + " la %[R_IN],4(%[R_IN])\n\t" \ + " la %[R_OUT],4(%[R_OUT])\n\t" \ + " aghi %[R_TMP2],-2\n\t" \ + " jh 13b\n\t" /* Handle remaining uint16_t values. */ \ + " j 0b\n\t" /* Switch to vx-loop. */ \ + "96: \n\t" /* Return full output. */ \ + " lghi %[R_RES],%[RES_OUT_FULL]\n\t" \ + " j 99f\n\t" \ + "97: \n\t" /* Return incomplete input. */ \ + " lghi %[R_RES],%[RES_IN_FULL]\n\t" \ + " j 99f\n\t" \ + "98:\n\t" /* Return Illegal character. */ \ + " lghi %[R_RES],%[RES_IN_ILL]\n\t" \ + "99:\n\t" \ + ".machine pop" \ + : /* outputs */ [R_IN] "+a" (inptr) \ + , [R_INLEN] "+d" (inlen), [R_OUT] "+a" (outptr) \ + , [R_OUTLEN] "+d" (outlen), [R_TMP] "=a" (tmp) \ + , [R_TMP2] "=d" (tmp2), [R_TMP3] "=a" (tmp3) \ + , [R_RES] "+d" (result) \ + : /* inputs */ \ + [RES_OUT_FULL] "i" (__GCONV_FULL_OUTPUT) \ + , [RES_IN_ILL] "i" (__GCONV_ILLEGAL_INPUT) \ + , [RES_IN_FULL] "i" (__GCONV_INCOMPLETE_INPUT) \ + : /* clobber list */ "memory", "cc" \ + ASM_CLOBBER_VR ("v16") ASM_CLOBBER_VR ("v17") \ + ASM_CLOBBER_VR ("v18") ASM_CLOBBER_VR ("v19") \ + ASM_CLOBBER_VR ("v30") ASM_CLOBBER_VR ("v31") \ + ); \ + if (__glibc_likely (inptr == inend) \ + || result != __GCONV_ILLEGAL_INPUT) \ + break; \ + \ + STANDARD_FROM_LOOP_ERR_HANDLER (2); \ + } + +/* Generate loop-function with hardware vector instructions. */ +# define MIN_NEEDED_INPUT MIN_NEEDED_FROM +# define MAX_NEEDED_INPUT MAX_NEEDED_FROM +# define MIN_NEEDED_OUTPUT MIN_NEEDED_TO +# define FROM_LOOP_VX __from_utf16_loop_vx +# define LOOPFCT FROM_LOOP_VX +# define LOOP_NEED_FLAGS +# define BODY BODY_FROM_VX +# include <iconv/loop.c> +#else +# define FROM_LOOP_VX NULL +#endif /* HAVE_FROM_VX != 1 */ + +#if HAVE_FROM_VX_CU == 1 +#define BODY_FROM_VX_CU \ + { \ + register const unsigned char* pInput asm ("8") = inptr; \ + register size_t inlen asm ("9") = inend - inptr; \ + register unsigned char* pOutput asm ("10") = outptr; \ + register size_t outlen asm ("11") = outend - outptr; \ + unsigned long tmp, tmp2, tmp3; \ + asm volatile (".machine push\n\t" \ + ".machine \"z13\"\n\t" \ + ".machinemode \"zarch_nohighgprs\"\n\t" \ + /* Setup to check for surrogates. */ \ + " larl %[R_TMP],9f\n\t" \ + " vlm %%v30,%%v31,0(%[R_TMP])\n\t" \ + CONVERT_32BIT_SIZE_T ([R_INLEN]) \ + CONVERT_32BIT_SIZE_T ([R_OUTLEN]) \ + /* Loop which handles UTF-16 chars <0xd800, >0xdfff. */ \ + "0: clgijl %[R_INLEN],16,20f\n\t" \ + " clgijl %[R_OUTLEN],32,20f\n\t" \ + "1: vl %%v16,0(%[R_IN])\n\t" \ + /* Check for surrogate chars. */ \ + " vstrchs %%v19,%%v16,%%v30,%%v31\n\t" \ + " jno 10f\n\t" \ + /* Enlarge to UTF-32. */ \ + " vuplhh %%v17,%%v16\n\t" \ + " la %[R_IN],16(%[R_IN])\n\t" \ + " vupllh %%v18,%%v16\n\t" \ + " aghi %[R_INLEN],-16\n\t" \ + /* Store 32 bytes to buf_out. */ \ + " vstm %%v17,%%v18,0(%[R_OUT])\n\t" \ + " aghi %[R_OUTLEN],-32\n\t" \ + " la %[R_OUT],32(%[R_OUT])\n\t" \ + " clgijl %[R_INLEN],16,20f\n\t" \ + " clgijl %[R_OUTLEN],32,20f\n\t" \ + " j 1b\n\t" \ + /* Setup to check for ch >= 0xd800 && ch <= 0xdfff. (v30, v31) */ \ + "9: .short 0xd800,0xdfff,0x0,0x0,0x0,0x0,0x0,0x0\n\t" \ + " .short 0xa000,0xc000,0x0,0x0,0x0,0x0,0x0,0x0\n\t" \ + /* At least one uint16_t is in range of surrogates. \ + Store the preceding chars. */ \ + "10: vlgvb %[R_TMP],%%v19,7\n\t" \ + " vuplhh %%v17,%%v16\n\t" \ + " sllg %[R_TMP3],%[R_TMP],1\n\t" /* Number of out bytes. */ \ + " ahik %[R_TMP2],%[R_TMP3],-1\n\t" /* Highest index to store. */ \ + " jl 20f\n\t" \ + " vstl %%v17,%[R_TMP2],0(%[R_OUT])\n\t" \ + " vupllh %%v18,%%v16\n\t" \ + " ahi %[R_TMP2],-16\n\t" \ + " jl 11f\n\t" \ + " vstl %%v18,%[R_TMP2],16(%[R_OUT])\n\t" \ + "11: \n\t" /* Update pointers. */ \ + " la %[R_IN],0(%[R_TMP],%[R_IN])\n\t" \ + " slgr %[R_INLEN],%[R_TMP]\n\t" \ + " la %[R_OUT],0(%[R_TMP3],%[R_OUT])\n\t" \ + " slgr %[R_OUTLEN],%[R_TMP3]\n\t" \ + /* Handles UTF16 surrogates with convert instruction. */ \ + "20: cu24 %[R_OUT],%[R_IN],1\n\t" \ + " jo 0b\n\t" /* Try vector implemenation again. */ \ + " lochil %[R_RES],%[RES_OUT_FULL]\n\t" /* cc == 1. */ \ + " lochih %[R_RES],%[RES_IN_ILL]\n\t" /* cc == 2. */ \ + ".machine pop" \ + : /* outputs */ [R_IN] "+a" (pInput) \ + , [R_INLEN] "+d" (inlen), [R_OUT] "+a" (pOutput) \ + , [R_OUTLEN] "+d" (outlen), [R_TMP] "=a" (tmp) \ + , [R_TMP2] "=d" (tmp2), [R_TMP3] "=a" (tmp3) \ + , [R_RES] "+d" (result) \ + : /* inputs */ \ + [RES_OUT_FULL] "i" (__GCONV_FULL_OUTPUT) \ + , [RES_IN_ILL] "i" (__GCONV_ILLEGAL_INPUT) \ + : /* clobber list */ "memory", "cc" \ + ASM_CLOBBER_VR ("v16") ASM_CLOBBER_VR ("v17") \ + ASM_CLOBBER_VR ("v18") ASM_CLOBBER_VR ("v19") \ + ASM_CLOBBER_VR ("v30") ASM_CLOBBER_VR ("v31") \ + ); \ + inptr = pInput; \ + outptr = pOutput; \ + \ + if (__glibc_likely (inlen == 0) \ + || result == __GCONV_FULL_OUTPUT) \ + break; \ + if (inlen == 1) \ + { \ + /* Input does not contain a complete utf16 character. */ \ + result = __GCONV_INCOMPLETE_INPUT; \ + break; \ + } \ + else if (result != __GCONV_ILLEGAL_INPUT) \ + { \ + /* Input is >= 2 and < 4 bytes (as cu24 would have processed \ + a possible next utf16 character) and not illegal. \ + => we have a single high surrogate at end of input. */ \ + result = __GCONV_INCOMPLETE_INPUT; \ + break; \ + } \ + \ + STANDARD_FROM_LOOP_ERR_HANDLER (2); \ + } + +/* Generate loop-function with hardware vector and utf-convert instructions. */ +# define MIN_NEEDED_INPUT MIN_NEEDED_FROM +# define MAX_NEEDED_INPUT MAX_NEEDED_FROM +# define MIN_NEEDED_OUTPUT MIN_NEEDED_TO +# define FROM_LOOP_VX_CU __from_utf16_loop_vx_cu +# define LOOPFCT FROM_LOOP_VX_CU +# define LOOP_NEED_FLAGS +# define BODY BODY_FROM_VX_CU +# include <iconv/loop.c> +#else +# define FROM_LOOP_VX_CU NULL +#endif /* HAVE_FROM_VX_CU != 1 */ + +/* Conversion from UTF-32 internal/BE to UTF-16. */ + +#if HAVE_TO_C == 1 +/* The software routine is copied from utf-16.c (minus bytes + swapping). */ +# define BODY_TO_C \ + { \ + uint32_t c = get32 (inptr); \ + \ + if (__builtin_expect (c <= 0xd7ff, 1) \ + || (c > 0xdfff && c <= 0xffff)) \ + { \ + /* Two UTF-16 chars. */ \ + put16 (outptr, c); \ + } \ + else if (__builtin_expect (c >= 0x10000, 1) \ + && __builtin_expect (c <= 0x10ffff, 1)) \ + { \ + /* Four UTF-16 chars. */ \ + uint16_t zabcd = ((c & 0x1f0000) >> 16) - 1; \ + uint16_t out; \ + \ + /* Generate a surrogate character. */ \ + if (__glibc_unlikely (outptr + 4 > outend)) \ + { \ + /* Overflow in the output buffer. */ \ + result = __GCONV_FULL_OUTPUT; \ + break; \ + } \ + \ + out = 0xd800; \ + out |= (zabcd & 0xff) << 6; \ + out |= (c >> 10) & 0x3f; \ + put16 (outptr, out); \ + outptr += 2; \ + \ + out = 0xdc00; \ + out |= c & 0x3ff; \ + put16 (outptr, out); \ + } \ + else \ + { \ + STANDARD_TO_LOOP_ERR_HANDLER (4); \ + } \ + outptr += 2; \ + inptr += 4; \ + } + +/* Generate loop-function with software routing. */ +# define MIN_NEEDED_INPUT MIN_NEEDED_TO +# define MIN_NEEDED_OUTPUT MIN_NEEDED_FROM +# define MAX_NEEDED_OUTPUT MAX_NEEDED_FROM +# define TO_LOOP_C __to_utf16_loop_c +# define LOOPFCT TO_LOOP_C +# define LOOP_NEED_FLAGS +# define BODY BODY_TO_C +# include <iconv/loop.c> +#else +# define TO_LOOP_C NULL +#endif /* HAVE_TO_C != 1 */ + +#if HAVE_TO_VX == 1 +# define BODY_TO_VX \ + { \ + size_t inlen = inend - inptr; \ + size_t outlen = outend - outptr; \ + unsigned long tmp, tmp2, tmp3; \ + asm volatile (".machine push\n\t" \ + ".machine \"z13\"\n\t" \ + ".machinemode \"zarch_nohighgprs\"\n\t" \ + /* Setup to check for surrogates. */ \ + " larl %[R_TMP],9f\n\t" \ + " vlm %%v30,%%v31,0(%[R_TMP])\n\t" \ + CONVERT_32BIT_SIZE_T ([R_INLEN]) \ + CONVERT_32BIT_SIZE_T ([R_OUTLEN]) \ + /* Loop which handles UTF-32 chars \ + ch < 0xd800 || (ch > 0xdfff && ch < 0x10000). */ \ + "0: clgijl %[R_INLEN],32,2f\n\t" \ + " clgijl %[R_OUTLEN],16,2f\n\t" \ + "1: vlm %%v16,%%v17,0(%[R_IN])\n\t" \ + " lghi %[R_TMP2],0\n\t" \ + /* Shorten to UTF-16. */ \ + " vpkf %%v18,%%v16,%%v17\n\t" \ + /* Check for surrogate chars. */ \ + " vstrcfs %%v19,%%v16,%%v30,%%v31\n\t" \ + " jno 10f\n\t" \ + " vstrcfs %%v19,%%v17,%%v30,%%v31\n\t" \ + " jno 11f\n\t" \ + /* Store 16 bytes to buf_out. */ \ + " vst %%v18,0(%[R_OUT])\n\t" \ + " la %[R_IN],32(%[R_IN])\n\t" \ + " aghi %[R_INLEN],-32\n\t" \ + " aghi %[R_OUTLEN],-16\n\t" \ + " la %[R_OUT],16(%[R_OUT])\n\t" \ + " clgijl %[R_INLEN],32,2f\n\t" \ + " clgijl %[R_OUTLEN],16,2f\n\t" \ + " j 1b\n\t" \ + /* Calculate remaining uint32_t values in inptr. */ \ + "2: \n\t" \ + " clgije %[R_INLEN],0,99f\n\t" \ + " clgijl %[R_INLEN],4,92f\n\t" \ + " srlg %[R_TMP2],%[R_INLEN],2\n\t" \ + " j 20f\n\t" \ + /* Setup to check for ch >= 0xd800 && ch <= 0xdfff \ + and check for ch >= 0x10000. (v30, v31) */ \ + "9: .long 0xd800,0xdfff,0x10000,0x10000\n\t" \ + " .long 0xa0000000,0xc0000000, 0xa0000000,0xa0000000\n\t" \ + /* At least on UTF32 char is in range of surrogates. \ + Store the preceding characters. */ \ + "11: ahi %[R_TMP2],16\n\t" \ + "10: vlgvb %[R_TMP],%%v19,7\n\t" \ + " agr %[R_TMP],%[R_TMP2]\n\t" \ + " srlg %[R_TMP3],%[R_TMP],1\n\t" /* Number of out bytes. */ \ + " ahik %[R_TMP2],%[R_TMP3],-1\n\t" /* Highest index to store. */ \ + " jl 12f\n\t" \ + " vstl %%v18,%[R_TMP2],0(%[R_OUT])\n\t" \ + /* Update pointers. */ \ + " la %[R_IN],0(%[R_TMP],%[R_IN])\n\t" \ + " slgr %[R_INLEN],%[R_TMP]\n\t" \ + " la %[R_OUT],0(%[R_TMP3],%[R_OUT])\n\t" \ + " slgr %[R_OUTLEN],%[R_TMP3]\n\t" \ + /* Calculate remaining uint32_t values in vrs. */ \ + "12: lghi %[R_TMP2],8\n\t" \ + " srlg %[R_TMP3],%[R_TMP3],1\n\t" \ + " slgr %[R_TMP2],%[R_TMP3]\n\t" \ + /* Handle remaining UTF-32 characters. */ \ + "20: l %[R_TMP],0(%[R_IN])\n\t" \ + " aghi %[R_INLEN],-4\n\t" \ + /* Test if ch is 2byte UTF-16 char. */ \ + " clfi %[R_TMP],0xffff\n\t" \ + " jh 21f\n\t" \ + /* Handle 2 byte UTF16 char. */ \ + " lgr %[R_TMP3],%[R_TMP]\n\t" \ + " nilf %[R_TMP],0xf800\n\t" \ + " clfi %[R_TMP],0xd800\n\t" \ + " je 91f\n\t" /* Do not accept UTF-16 surrogates. */ \ + " slgfi %[R_OUTLEN],2\n\t" \ + " jl 90f \n\t" \ + " sth %[R_TMP3],0(%[R_OUT])\n\t" \ + " la %[R_IN],4(%[R_IN])\n\t" \ + " la %[R_OUT],2(%[R_OUT])\n\t" \ + " brctg %[R_TMP2],20b\n\t" \ + " j 0b\n\t" /* Switch to vx-loop. */ \ + /* Test if ch is 4byte UTF-16 char. */ \ + "21: clfi %[R_TMP],0x10ffff\n\t" \ + " jh 91f\n\t" /* ch > 0x10ffff is not allowed! */ \ + /* Handle 4 byte UTF16 char. */ \ + " slgfi %[R_OUTLEN],4\n\t" \ + " jl 90f \n\t" \ + " slfi %[R_TMP],0x10000\n\t" /* zabcd = uvwxy - 1. */ \ + " llilf %[R_TMP3],0xd800dc00\n\t" \ + " la %[R_IN],4(%[R_IN])\n\t" \ + " risbgn %[R_TMP3],%[R_TMP],38,47,6\n\t" /* High surrogate. */ \ + " risbgn %[R_TMP3],%[R_TMP],54,63,0\n\t" /* Low surrogate. */ \ + " st %[R_TMP3],0(%[R_OUT])\n\t" \ + " la %[R_OUT],4(%[R_OUT])\n\t" \ + " brctg %[R_TMP2],20b\n\t" \ + " j 0b\n\t" /* Switch to vx-loop. */ \ + "92: lghi %[R_RES],%[RES_IN_FULL]\n\t" \ + " j 99f\n\t" \ + "91: lghi %[R_RES],%[RES_IN_ILL]\n\t" \ + " j 99f\n\t" \ + "90: lghi %[R_RES],%[RES_OUT_FULL]\n\t" \ + "99: \n\t" \ + ".machine pop" \ + : /* outputs */ [R_IN] "+a" (inptr) \ + , [R_INLEN] "+d" (inlen), [R_OUT] "+a" (outptr) \ + , [R_OUTLEN] "+d" (outlen), [R_TMP] "=a" (tmp) \ + , [R_TMP2] "=d" (tmp2), [R_TMP3] "=a" (tmp3) \ + , [R_RES] "+d" (result) \ + : /* inputs */ \ + [RES_OUT_FULL] "i" (__GCONV_FULL_OUTPUT) \ + , [RES_IN_ILL] "i" (__GCONV_ILLEGAL_INPUT) \ + , [RES_IN_FULL] "i" (__GCONV_INCOMPLETE_INPUT) \ + : /* clobber list */ "memory", "cc" \ + ASM_CLOBBER_VR ("v16") ASM_CLOBBER_VR ("v17") \ + ASM_CLOBBER_VR ("v18") ASM_CLOBBER_VR ("v19") \ + ASM_CLOBBER_VR ("v30") ASM_CLOBBER_VR ("v31") \ + ); \ + if (__glibc_likely (inptr == inend) \ + || result != __GCONV_ILLEGAL_INPUT) \ + break; \ + \ + STANDARD_TO_LOOP_ERR_HANDLER (4); \ + } + +/* Generate loop-function with hardware vector instructions. */ +# define MIN_NEEDED_INPUT MIN_NEEDED_TO +# define MIN_NEEDED_OUTPUT MIN_NEEDED_FROM +# define MAX_NEEDED_OUTPUT MAX_NEEDED_FROM +# define TO_LOOP_VX __to_utf16_loop_vx +# define LOOPFCT TO_LOOP_VX +# define LOOP_NEED_FLAGS +# define BODY BODY_TO_VX +# include <iconv/loop.c> +#else +# define TO_LOOP_VX NULL +#endif /* HAVE_TO_VX != 1 */ + +#if HAVE_TO_VX_CU == 1 +#define BODY_TO_VX_CU \ + { \ + register const unsigned char* pInput asm ("8") = inptr; \ + register size_t inlen asm ("9") = inend - inptr; \ + register unsigned char* pOutput asm ("10") = outptr; \ + register size_t outlen asm ("11") = outend - outptr; \ + unsigned long tmp, tmp2, tmp3; \ + asm volatile (".machine push\n\t" \ + ".machine \"z13\"\n\t" \ + ".machinemode \"zarch_nohighgprs\"\n\t" \ + /* Setup to check for surrogates. */ \ + " larl %[R_TMP],9f\n\t" \ + " vlm %%v30,%%v31,0(%[R_TMP])\n\t" \ + CONVERT_32BIT_SIZE_T ([R_INLEN]) \ + CONVERT_32BIT_SIZE_T ([R_OUTLEN]) \ + /* Loop which handles UTF-32 chars \ + ch < 0xd800 || (ch > 0xdfff && ch < 0x10000). */ \ + "0: clgijl %[R_INLEN],32,20f\n\t" \ + " clgijl %[R_OUTLEN],16,20f\n\t" \ + "1: vlm %%v16,%%v17,0(%[R_IN])\n\t" \ + " lghi %[R_TMP2],0\n\t" \ + /* Shorten to UTF-16. */ \ + " vpkf %%v18,%%v16,%%v17\n\t" \ + /* Check for surrogate chars. */ \ + " vstrcfs %%v19,%%v16,%%v30,%%v31\n\t" \ + " jno 10f\n\t" \ + " vstrcfs %%v19,%%v17,%%v30,%%v31\n\t" \ + " jno 11f\n\t" \ + /* Store 16 bytes to buf_out. */ \ + " vst %%v18,0(%[R_OUT])\n\t" \ + " la %[R_IN],32(%[R_IN])\n\t" \ + " aghi %[R_INLEN],-32\n\t" \ + " aghi %[R_OUTLEN],-16\n\t" \ + " la %[R_OUT],16(%[R_OUT])\n\t" \ + " clgijl %[R_INLEN],32,20f\n\t" \ + " clgijl %[R_OUTLEN],16,20f\n\t" \ + " j 1b\n\t" \ + /* Setup to check for ch >= 0xd800 && ch <= 0xdfff \ + and check for ch >= 0x10000. (v30, v31) */ \ + "9: .long 0xd800,0xdfff,0x10000,0x10000\n\t" \ + " .long 0xa0000000,0xc0000000, 0xa0000000,0xa0000000\n\t" \ + /* At least one UTF32 char is in range of surrogates. \ + Store the preceding characters. */ \ + "11: ahi %[R_TMP2],16\n\t" \ + "10: vlgvb %[R_TMP],%%v19,7\n\t" \ + " agr %[R_TMP],%[R_TMP2]\n\t" \ + " srlg %[R_TMP3],%[R_TMP],1\n\t" /* Number of out bytes. */ \ + " ahik %[R_TMP2],%[R_TMP3],-1\n\t" /* Highest index to store. */ \ + " jl 20f\n\t" \ + " vstl %%v18,%[R_TMP2],0(%[R_OUT])\n\t" \ + /* Update pointers. */ \ + " la %[R_IN],0(%[R_TMP],%[R_IN])\n\t" \ + " slgr %[R_INLEN],%[R_TMP]\n\t" \ + " la %[R_OUT],0(%[R_TMP3],%[R_OUT])\n\t" \ + " slgr %[R_OUTLEN],%[R_TMP3]\n\t" \ + /* Handles UTF16 surrogates with convert instruction. */ \ + "20: cu42 %[R_OUT],%[R_IN]\n\t" \ + " jo 0b\n\t" /* Try vector implemenation again. */ \ + " lochil %[R_RES],%[RES_OUT_FULL]\n\t" /* cc == 1. */ \ + " lochih %[R_RES],%[RES_IN_ILL]\n\t" /* cc == 2. */ \ + ".machine pop" \ + : /* outputs */ [R_IN] "+a" (pInput) \ + , [R_INLEN] "+d" (inlen), [R_OUT] "+a" (pOutput) \ + , [R_OUTLEN] "+d" (outlen), [R_TMP] "=a" (tmp) \ + , [R_TMP2] "=d" (tmp2), [R_TMP3] "=a" (tmp3) \ + , [R_RES] "+d" (result) \ + : /* inputs */ \ + [RES_OUT_FULL] "i" (__GCONV_FULL_OUTPUT) \ + , [RES_IN_ILL] "i" (__GCONV_ILLEGAL_INPUT) \ + : /* clobber list */ "memory", "cc" \ + ASM_CLOBBER_VR ("v16") ASM_CLOBBER_VR ("v17") \ + ASM_CLOBBER_VR ("v18") ASM_CLOBBER_VR ("v19") \ + ASM_CLOBBER_VR ("v30") ASM_CLOBBER_VR ("v31") \ + ); \ + inptr = pInput; \ + outptr = pOutput; \ + \ + if (__glibc_likely (inlen == 0) \ + || result == __GCONV_FULL_OUTPUT) \ + break; \ + if (inlen < 4) \ + { \ + result = __GCONV_INCOMPLETE_INPUT; \ + break; \ + } \ + \ + STANDARD_TO_LOOP_ERR_HANDLER (4); \ + } + +/* Generate loop-function with hardware vector and utf-convert instructions. */ +# define MIN_NEEDED_INPUT MIN_NEEDED_TO +# define MIN_NEEDED_OUTPUT MIN_NEEDED_FROM +# define MAX_NEEDED_OUTPUT MAX_NEEDED_FROM +# define TO_LOOP_VX_CU __to_utf16_loop_vx_cu +# define LOOPFCT TO_LOOP_VX_CU +# define LOOP_NEED_FLAGS +# define BODY BODY_TO_VX_CU +# include <iconv/loop.c> +#else +# define TO_LOOP_VX_CU NULL +#endif /* HAVE_TO_VX_CU != 1 */ + +/* This file also exists in sysdeps/s390/multiarch/ which + generates ifunc resolvers for FROM/TO_LOOP functions + and includes iconv/skeleton.c afterwards. */ +#if ! defined USE_MULTIARCH +# include <iconv/skeleton.c> +#endif diff --git a/sysdeps/s390/utf8-utf16-z9.c b/sysdeps/s390/utf8-utf16-z9.c new file mode 100644 index 0000000000..409d64c578 --- /dev/null +++ b/sysdeps/s390/utf8-utf16-z9.c @@ -0,0 +1,942 @@ +/* Conversion between UTF-8 and UTF-16 - s390 version. + + This module uses the Z9-109 variants of the Convert Unicode + instructions. + Copyright (C) 1997-2018 Free Software Foundation, Inc. + + Author: Andreas Krebbel <Andreas.Krebbel@de.ibm.com> + Based on the work by Ulrich Drepper <drepper@cygnus.com>, 1997. + + Thanks to Daniel Appich who covered the relevant performance work + in his diploma thesis. + + This is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <dlfcn.h> +#include <stdint.h> +#include <unistd.h> +#include <gconv.h> +#include <string.h> + +/* Select which versions should be defined depending on support + for multiarch, vector and used minimum architecture level. */ +#ifdef HAVE_S390_MIN_Z196_ZARCH_ASM_SUPPORT +# define HAVE_FROM_C 0 +# define FROM_LOOP_DEFAULT FROM_LOOP_CU +#else +# define HAVE_FROM_C 1 +# define FROM_LOOP_DEFAULT FROM_LOOP_C +#endif + +#define HAVE_TO_C 1 +#define TO_LOOP_DEFAULT TO_LOOP_C + +#if defined HAVE_S390_MIN_Z196_ZARCH_ASM_SUPPORT || defined USE_MULTIARCH +# define HAVE_FROM_CU 1 +#else +# define HAVE_FROM_CU 0 +#endif + +#if defined HAVE_S390_VX_ASM_SUPPORT && defined USE_MULTIARCH +# define HAVE_FROM_VX 1 +# define HAVE_TO_VX 1 +# define HAVE_TO_VX_CU 1 +#else +# define HAVE_FROM_VX 0 +# define HAVE_TO_VX 0 +# define HAVE_TO_VX_CU 0 +#endif + +#if defined HAVE_S390_VX_GCC_SUPPORT +# define ASM_CLOBBER_VR(NR) , NR +#else +# define ASM_CLOBBER_VR(NR) +#endif + +#if defined __s390x__ +# define CONVERT_32BIT_SIZE_T(REG) +#else +# define CONVERT_32BIT_SIZE_T(REG) "llgfr %" #REG ",%" #REG "\n\t" +#endif + +/* Defines for skeleton.c. */ +#define DEFINE_INIT 0 +#define DEFINE_FINI 0 +#define MIN_NEEDED_FROM 1 +#define MAX_NEEDED_FROM 4 +#define MIN_NEEDED_TO 2 +#define MAX_NEEDED_TO 4 +#define FROM_LOOP FROM_LOOP_DEFAULT +#define TO_LOOP TO_LOOP_DEFAULT +#define FROM_DIRECTION (dir == from_utf8) +#define ONE_DIRECTION 0 + + +/* UTF-16 big endian byte order mark. */ +#define BOM_UTF16 0xfeff + +/* Direction of the transformation. */ +enum direction +{ + illegal_dir, + to_utf8, + from_utf8 +}; + +struct utf8_data +{ + enum direction dir; + int emit_bom; +}; + + +extern int gconv_init (struct __gconv_step *step); +int +gconv_init (struct __gconv_step *step) +{ + /* Determine which direction. */ + struct utf8_data *new_data; + enum direction dir = illegal_dir; + int emit_bom; + int result; + + emit_bom = (__strcasecmp (step->__to_name, "UTF-16//") == 0); + + if (__strcasecmp (step->__from_name, "ISO-10646/UTF8/") == 0 + && (__strcasecmp (step->__to_name, "UTF-16//") == 0 + || __strcasecmp (step->__to_name, "UTF-16BE//") == 0)) + { + dir = from_utf8; + } + else if (__strcasecmp (step->__from_name, "UTF-16BE//") == 0 + && __strcasecmp (step->__to_name, "ISO-10646/UTF8/") == 0) + { + dir = to_utf8; + } + + result = __GCONV_NOCONV; + if (dir != illegal_dir) + { + new_data = (struct utf8_data *) malloc (sizeof (struct utf8_data)); + + result = __GCONV_NOMEM; + if (new_data != NULL) + { + new_data->dir = dir; + new_data->emit_bom = emit_bom; + step->__data = new_data; + + if (dir == from_utf8) + { + step->__min_needed_from = MIN_NEEDED_FROM; + step->__max_needed_from = MIN_NEEDED_FROM; + step->__min_needed_to = MIN_NEEDED_TO; + step->__max_needed_to = MIN_NEEDED_TO; + } + else + { + step->__min_needed_from = MIN_NEEDED_TO; + step->__max_needed_from = MIN_NEEDED_TO; + step->__min_needed_to = MIN_NEEDED_FROM; + step->__max_needed_to = MIN_NEEDED_FROM; + } + + step->__stateful = 0; + + result = __GCONV_OK; + } + } + + return result; +} + + +extern void gconv_end (struct __gconv_step *data); +void +gconv_end (struct __gconv_step *data) +{ + free (data->__data); +} + +/* The macro for the hardware loop. This is used for both + directions. */ +#define HARDWARE_CONVERT(INSTRUCTION) \ + { \ + register const unsigned char* pInput __asm__ ("8") = inptr; \ + register size_t inlen __asm__ ("9") = inend - inptr; \ + register unsigned char* pOutput __asm__ ("10") = outptr; \ + register size_t outlen __asm__("11") = outend - outptr; \ + unsigned long cc = 0; \ + \ + __asm__ __volatile__ (".machine push \n\t" \ + ".machine \"z9-109\" \n\t" \ + ".machinemode \"zarch_nohighgprs\"\n\t" \ + "0: " INSTRUCTION " \n\t" \ + ".machine pop \n\t" \ + " jo 0b \n\t" \ + " ipm %2 \n" \ + : "+a" (pOutput), "+a" (pInput), "+d" (cc), \ + "+d" (outlen), "+d" (inlen) \ + : \ + : "cc", "memory"); \ + \ + inptr = pInput; \ + outptr = pOutput; \ + cc >>= 28; \ + \ + if (cc == 1) \ + { \ + result = __GCONV_FULL_OUTPUT; \ + } \ + else if (cc == 2) \ + { \ + result = __GCONV_ILLEGAL_INPUT; \ + } \ + } + +#define PREPARE_LOOP \ + enum direction dir = ((struct utf8_data *) step->__data)->dir; \ + int emit_bom = ((struct utf8_data *) step->__data)->emit_bom; \ + \ + if (emit_bom && !data->__internal_use \ + && data->__invocation_counter == 0) \ + { \ + /* Emit the UTF-16 Byte Order Mark. */ \ + if (__glibc_unlikely (outbuf + 2 > outend)) \ + return __GCONV_FULL_OUTPUT; \ + \ + put16u (outbuf, BOM_UTF16); \ + outbuf += 2; \ + } + +/* Conversion function from UTF-8 to UTF-16. */ +#define BODY_FROM_HW(ASM) \ + { \ + ASM; \ + if (__glibc_likely (inptr == inend) \ + || result == __GCONV_FULL_OUTPUT) \ + break; \ + \ + int i; \ + for (i = 1; inptr + i < inend && i < 5; ++i) \ + if ((inptr[i] & 0xc0) != 0x80) \ + break; \ + \ + if (__glibc_likely (inptr + i == inend \ + && result == __GCONV_EMPTY_INPUT)) \ + { \ + result = __GCONV_INCOMPLETE_INPUT; \ + break; \ + } \ + STANDARD_FROM_LOOP_ERR_HANDLER (i); \ + } + +#if HAVE_FROM_VX == 1 +# define HW_FROM_VX \ + { \ + register const unsigned char* pInput asm ("8") = inptr; \ + register size_t inlen asm ("9") = inend - inptr; \ + register unsigned char* pOutput asm ("10") = outptr; \ + register size_t outlen asm("11") = outend - outptr; \ + unsigned long tmp, tmp2, tmp3; \ + asm volatile (".machine push\n\t" \ + ".machine \"z13\"\n\t" \ + ".machinemode \"zarch_nohighgprs\"\n\t" \ + " vrepib %%v30,0x7f\n\t" /* For compare > 0x7f. */ \ + " vrepib %%v31,0x20\n\t" \ + CONVERT_32BIT_SIZE_T ([R_INLEN]) \ + CONVERT_32BIT_SIZE_T ([R_OUTLEN]) \ + /* Loop which handles UTF-8 chars <=0x7f. */ \ + "0: clgijl %[R_INLEN],16,20f\n\t" \ + " clgijl %[R_OUTLEN],32,20f\n\t" \ + "1: vl %%v16,0(%[R_IN])\n\t" \ + " vstrcbs %%v17,%%v16,%%v30,%%v31\n\t" \ + " jno 10f\n\t" /* Jump away if not all bytes are 1byte \ + UTF8 chars. */ \ + /* Enlarge to UTF-16. */ \ + " vuplhb %%v18,%%v16\n\t" \ + " la %[R_IN],16(%[R_IN])\n\t" \ + " vupllb %%v19,%%v16\n\t" \ + " aghi %[R_INLEN],-16\n\t" \ + /* Store 32 bytes to buf_out. */ \ + " vstm %%v18,%%v19,0(%[R_OUT])\n\t" \ + " aghi %[R_OUTLEN],-32\n\t" \ + " la %[R_OUT],32(%[R_OUT])\n\t" \ + " clgijl %[R_INLEN],16,20f\n\t" \ + " clgijl %[R_OUTLEN],32,20f\n\t" \ + " j 1b\n\t" \ + "10:\n\t" \ + /* At least one byte is > 0x7f. \ + Store the preceding 1-byte chars. */ \ + " vlgvb %[R_TMP],%%v17,7\n\t" \ + " sllk %[R_TMP2],%[R_TMP],1\n\t" /* Compute highest \ + index to store. */ \ + " llgfr %[R_TMP3],%[R_TMP2]\n\t" \ + " ahi %[R_TMP2],-1\n\t" \ + " jl 20f\n\t" \ + " vuplhb %%v18,%%v16\n\t" \ + " vstl %%v18,%[R_TMP2],0(%[R_OUT])\n\t" \ + " ahi %[R_TMP2],-16\n\t" \ + " jl 11f\n\t" \ + " vupllb %%v19,%%v16\n\t" \ + " vstl %%v19,%[R_TMP2],16(%[R_OUT])\n\t" \ + "11: \n\t" /* Update pointers. */ \ + " la %[R_IN],0(%[R_TMP],%[R_IN])\n\t" \ + " slgr %[R_INLEN],%[R_TMP]\n\t" \ + " la %[R_OUT],0(%[R_TMP3],%[R_OUT])\n\t" \ + " slgr %[R_OUTLEN],%[R_TMP3]\n\t" \ + /* Handle multibyte utf8-char with convert instruction. */ \ + "20: cu12 %[R_OUT],%[R_IN],1\n\t" \ + " jo 0b\n\t" /* Try vector implemenation again. */ \ + " lochil %[R_RES],%[RES_OUT_FULL]\n\t" /* cc == 1. */ \ + " lochih %[R_RES],%[RES_IN_ILL]\n\t" /* cc == 2. */ \ + ".machine pop" \ + : /* outputs */ [R_IN] "+a" (pInput) \ + , [R_INLEN] "+d" (inlen), [R_OUT] "+a" (pOutput) \ + , [R_OUTLEN] "+d" (outlen), [R_TMP] "=a" (tmp) \ + , [R_TMP2] "=d" (tmp2), [R_TMP3] "=a" (tmp3) \ + , [R_RES] "+d" (result) \ + : /* inputs */ \ + [RES_OUT_FULL] "i" (__GCONV_FULL_OUTPUT) \ + , [RES_IN_ILL] "i" (__GCONV_ILLEGAL_INPUT) \ + : /* clobber list */ "memory", "cc" \ + ASM_CLOBBER_VR ("v16") ASM_CLOBBER_VR ("v17") \ + ASM_CLOBBER_VR ("v18") ASM_CLOBBER_VR ("v19") \ + ASM_CLOBBER_VR ("v30") ASM_CLOBBER_VR ("v31") \ + ); \ + inptr = pInput; \ + outptr = pOutput; \ + } +# define BODY_FROM_VX BODY_FROM_HW (HW_FROM_VX) + +/* Generate loop-function with hardware vector and utf-convert instructions. */ +# define MIN_NEEDED_INPUT MIN_NEEDED_FROM +# define MAX_NEEDED_INPUT MAX_NEEDED_FROM +# define MIN_NEEDED_OUTPUT MIN_NEEDED_TO +# define MAX_NEEDED_OUTPUT MAX_NEEDED_TO +# define FROM_LOOP_VX __from_utf8_loop_vx +# define LOOPFCT FROM_LOOP_VX +# define LOOP_NEED_FLAGS +# define BODY BODY_FROM_VX +# include <iconv/loop.c> +#else +# define FROM_LOOP_VX NULL +#endif /* HAVE_FROM_VX != 1 */ + +#if HAVE_FROM_CU == 1 +# define BODY_FROM_ETF3EH BODY_FROM_HW (HARDWARE_CONVERT ("cu12 %0, %1, 1")) + +/* Generate loop-function with hardware utf-convert instruction. */ +# define MIN_NEEDED_INPUT MIN_NEEDED_FROM +# define MAX_NEEDED_INPUT MAX_NEEDED_FROM +# define MIN_NEEDED_OUTPUT MIN_NEEDED_TO +# define MAX_NEEDED_OUTPUT MAX_NEEDED_TO +# define FROM_LOOP_CU __from_utf8_loop_etf3eh +# define LOOPFCT FROM_LOOP_CU +# define LOOP_NEED_FLAGS +# define BODY BODY_FROM_ETF3EH +# include <iconv/loop.c> +#else +# define FROM_LOOP_CU NULL +#endif /* HAVE_FROM_CU != 1 */ + +#if HAVE_FROM_C == 1 +/* The software implementation is based on the code in gconv_simple.c. */ +# define BODY_FROM_C \ + { \ + /* Next input byte. */ \ + uint16_t ch = *inptr; \ + \ + if (__glibc_likely (ch < 0x80)) \ + { \ + /* One byte sequence. */ \ + ++inptr; \ + } \ + else \ + { \ + uint_fast32_t cnt; \ + uint_fast32_t i; \ + \ + if (ch >= 0xc2 && ch < 0xe0) \ + { \ + /* We expect two bytes. The first byte cannot be 0xc0 \ + or 0xc1, otherwise the wide character could have been \ + represented using a single byte. */ \ + cnt = 2; \ + ch &= 0x1f; \ + } \ + else if (__glibc_likely ((ch & 0xf0) == 0xe0)) \ + { \ + /* We expect three bytes. */ \ + cnt = 3; \ + ch &= 0x0f; \ + } \ + else if (__glibc_likely ((ch & 0xf8) == 0xf0)) \ + { \ + /* We expect four bytes. */ \ + cnt = 4; \ + ch &= 0x07; \ + } \ + else \ + { \ + /* Search the end of this ill-formed UTF-8 character. This \ + is the next byte with (x & 0xc0) != 0x80. */ \ + i = 0; \ + do \ + ++i; \ + while (inptr + i < inend \ + && (*(inptr + i) & 0xc0) == 0x80 \ + && i < 5); \ + \ + errout: \ + STANDARD_FROM_LOOP_ERR_HANDLER (i); \ + } \ + \ + if (__glibc_unlikely (inptr + cnt > inend)) \ + { \ + /* We don't have enough input. But before we report \ + that check that all the bytes are correct. */ \ + for (i = 1; inptr + i < inend; ++i) \ + if ((inptr[i] & 0xc0) != 0x80) \ + break; \ + \ + if (__glibc_likely (inptr + i == inend)) \ + { \ + result = __GCONV_INCOMPLETE_INPUT; \ + break; \ + } \ + \ + goto errout; \ + } \ + \ + if (cnt == 4) \ + { \ + /* For 4 byte UTF-8 chars two UTF-16 chars (high and \ + low) are needed. */ \ + uint16_t zabcd, high, low; \ + \ + if (__glibc_unlikely (outptr + 4 > outend)) \ + { \ + /* Overflow in the output buffer. */ \ + result = __GCONV_FULL_OUTPUT; \ + break; \ + } \ + \ + /* Check if tail-bytes >= 0x80, < 0xc0. */ \ + for (i = 1; i < cnt; ++i) \ + { \ + if ((inptr[i] & 0xc0) != 0x80) \ + /* This is an illegal encoding. */ \ + goto errout; \ + } \ + \ + /* See Principles of Operations cu12. */ \ + zabcd = (((inptr[0] & 0x7) << 2) | \ + ((inptr[1] & 0x30) >> 4)) - 1; \ + \ + /* z-bit must be zero after subtracting 1. */ \ + if (zabcd & 0x10) \ + STANDARD_FROM_LOOP_ERR_HANDLER (4) \ + \ + high = (uint16_t)(0xd8 << 8); /* high surrogate id */ \ + high |= zabcd << 6; /* abcd bits */ \ + high |= (inptr[1] & 0xf) << 2; /* efgh bits */ \ + high |= (inptr[2] & 0x30) >> 4; /* ij bits */ \ + \ + low = (uint16_t)(0xdc << 8); /* low surrogate id */ \ + low |= ((uint16_t)inptr[2] & 0xc) << 6; /* kl bits */ \ + low |= (inptr[2] & 0x3) << 6; /* mn bits */ \ + low |= inptr[3] & 0x3f; /* opqrst bits */ \ + \ + put16 (outptr, high); \ + outptr += 2; \ + put16 (outptr, low); \ + outptr += 2; \ + inptr += 4; \ + continue; \ + } \ + else \ + { \ + /* Read the possible remaining bytes. */ \ + for (i = 1; i < cnt; ++i) \ + { \ + uint16_t byte = inptr[i]; \ + \ + if ((byte & 0xc0) != 0x80) \ + /* This is an illegal encoding. */ \ + break; \ + \ + ch <<= 6; \ + ch |= byte & 0x3f; \ + } \ + \ + /* If i < cnt, some trail byte was not >= 0x80, < 0xc0. \ + If cnt > 2 and ch < 2^(5*cnt-4), the wide character ch could \ + have been represented with fewer than cnt bytes. */ \ + if (i < cnt || (cnt > 2 && (ch >> (5 * cnt - 4)) == 0) \ + /* Do not accept UTF-16 surrogates. */ \ + || (ch >= 0xd800 && ch <= 0xdfff)) \ + { \ + /* This is an illegal encoding. */ \ + goto errout; \ + } \ + \ + inptr += cnt; \ + } \ + } \ + /* Now adjust the pointers and store the result. */ \ + *((uint16_t *) outptr) = ch; \ + outptr += sizeof (uint16_t); \ + } + +/* Generate loop-function with software implementation. */ +# define MIN_NEEDED_INPUT MIN_NEEDED_FROM +# define MAX_NEEDED_INPUT MAX_NEEDED_FROM +# define MIN_NEEDED_OUTPUT MIN_NEEDED_TO +# define MAX_NEEDED_OUTPUT MAX_NEEDED_TO +# define FROM_LOOP_C __from_utf8_loop_c +# define LOOPFCT FROM_LOOP_C +# define LOOP_NEED_FLAGS +# define BODY BODY_FROM_C +# include <iconv/loop.c> +#else +# define FROM_LOOP_C NULL +#endif /* HAVE_FROM_C != 1 */ + +/* Conversion from UTF-16 to UTF-8. */ + +#if HAVE_TO_C == 1 +/* The software routine is based on the functionality of the S/390 + hardware instruction (cu21) as described in the Principles of + Operation. */ +# define BODY_TO_C \ + { \ + uint16_t c = get16 (inptr); \ + \ + if (__glibc_likely (c <= 0x007f)) \ + { \ + /* Single byte UTF-8 char. */ \ + *outptr = c & 0xff; \ + outptr++; \ + } \ + else if (c >= 0x0080 && c <= 0x07ff) \ + { \ + /* Two byte UTF-8 char. */ \ + \ + if (__glibc_unlikely (outptr + 2 > outend)) \ + { \ + /* Overflow in the output buffer. */ \ + result = __GCONV_FULL_OUTPUT; \ + break; \ + } \ + \ + outptr[0] = 0xc0; \ + outptr[0] |= c >> 6; \ + \ + outptr[1] = 0x80; \ + outptr[1] |= c & 0x3f; \ + \ + outptr += 2; \ + } \ + else if ((c >= 0x0800 && c <= 0xd7ff) || c > 0xdfff) \ + { \ + /* Three byte UTF-8 char. */ \ + \ + if (__glibc_unlikely (outptr + 3 > outend)) \ + { \ + /* Overflow in the output buffer. */ \ + result = __GCONV_FULL_OUTPUT; \ + break; \ + } \ + outptr[0] = 0xe0; \ + outptr[0] |= c >> 12; \ + \ + outptr[1] = 0x80; \ + outptr[1] |= (c >> 6) & 0x3f; \ + \ + outptr[2] = 0x80; \ + outptr[2] |= c & 0x3f; \ + \ + outptr += 3; \ + } \ + else if (c >= 0xd800 && c <= 0xdbff) \ + { \ + /* Four byte UTF-8 char. */ \ + uint16_t low, uvwxy; \ + \ + if (__glibc_unlikely (outptr + 4 > outend)) \ + { \ + /* Overflow in the output buffer. */ \ + result = __GCONV_FULL_OUTPUT; \ + break; \ + } \ + if (__glibc_unlikely (inptr + 4 > inend)) \ + { \ + result = __GCONV_INCOMPLETE_INPUT; \ + break; \ + } \ + \ + inptr += 2; \ + low = get16 (inptr); \ + \ + if ((low & 0xfc00) != 0xdc00) \ + { \ + inptr -= 2; \ + STANDARD_TO_LOOP_ERR_HANDLER (2); \ + } \ + uvwxy = ((c >> 6) & 0xf) + 1; \ + outptr[0] = 0xf0; \ + outptr[0] |= uvwxy >> 2; \ + \ + outptr[1] = 0x80; \ + outptr[1] |= (uvwxy << 4) & 0x30; \ + outptr[1] |= (c >> 2) & 0x0f; \ + \ + outptr[2] = 0x80; \ + outptr[2] |= (c & 0x03) << 4; \ + outptr[2] |= (low >> 6) & 0x0f; \ + \ + outptr[3] = 0x80; \ + outptr[3] |= low & 0x3f; \ + \ + outptr += 4; \ + } \ + else \ + { \ + STANDARD_TO_LOOP_ERR_HANDLER (2); \ + } \ + inptr += 2; \ + } + +/* Generate loop-function with software implementation. */ +# define MIN_NEEDED_INPUT MIN_NEEDED_TO +# define MAX_NEEDED_INPUT MAX_NEEDED_TO +# define MIN_NEEDED_OUTPUT MIN_NEEDED_FROM +# define MAX_NEEDED_OUTPUT MAX_NEEDED_FROM +# define TO_LOOP_C __to_utf8_loop_c +# define LOOPFCT TO_LOOP_C +# define BODY BODY_TO_C +# define LOOP_NEED_FLAGS +# include <iconv/loop.c> +#else +# define TO_LOOP_C NULL +#endif /* HAVE_TO_C != 1 */ + +#if HAVE_TO_VX == 1 +# define BODY_TO_VX \ + { \ + size_t inlen = inend - inptr; \ + size_t outlen = outend - outptr; \ + unsigned long tmp, tmp2, tmp3; \ + asm volatile (".machine push\n\t" \ + ".machine \"z13\"\n\t" \ + ".machinemode \"zarch_nohighgprs\"\n\t" \ + /* Setup to check for values <= 0x7f. */ \ + " larl %[R_TMP],9f\n\t" \ + " vlm %%v30,%%v31,0(%[R_TMP])\n\t" \ + CONVERT_32BIT_SIZE_T ([R_INLEN]) \ + CONVERT_32BIT_SIZE_T ([R_OUTLEN]) \ + /* Loop which handles UTF-16 chars <=0x7f. */ \ + "0: clgijl %[R_INLEN],32,2f\n\t" \ + " clgijl %[R_OUTLEN],16,2f\n\t" \ + "1: vlm %%v16,%%v17,0(%[R_IN])\n\t" \ + " lghi %[R_TMP2],0\n\t" \ + /* Check for > 1byte UTF-8 chars. */ \ + " vstrchs %%v19,%%v16,%%v30,%%v31\n\t" \ + " jno 10f\n\t" /* Jump away if not all bytes are 1byte \ + UTF8 chars. */ \ + " vstrchs %%v19,%%v17,%%v30,%%v31\n\t" \ + " jno 11f\n\t" /* Jump away if not all bytes are 1byte \ + UTF8 chars. */ \ + /* Shorten to UTF-8. */ \ + " vpkh %%v18,%%v16,%%v17\n\t" \ + " la %[R_IN],32(%[R_IN])\n\t" \ + " aghi %[R_INLEN],-32\n\t" \ + /* Store 16 bytes to buf_out. */ \ + " vst %%v18,0(%[R_OUT])\n\t" \ + " aghi %[R_OUTLEN],-16\n\t" \ + " la %[R_OUT],16(%[R_OUT])\n\t" \ + " clgijl %[R_INLEN],32,2f\n\t" \ + " clgijl %[R_OUTLEN],16,2f\n\t" \ + " j 1b\n\t" \ + /* Setup to check for ch > 0x7f. (v30, v31) */ \ + "9: .short 0x7f,0x7f,0x0,0x0,0x0,0x0,0x0,0x0\n\t" \ + " .short 0x2000,0x2000,0x0,0x0,0x0,0x0,0x0,0x0\n\t" \ + /* At least one byte is > 0x7f. \ + Store the preceding 1-byte chars. */ \ + "11: lghi %[R_TMP2],16\n\t" /* match was found in v17. */ \ + "10:\n\t" \ + " vlgvb %[R_TMP],%%v19,7\n\t" \ + /* Shorten to UTF-8. */ \ + " vpkh %%v18,%%v16,%%v17\n\t" \ + " ar %[R_TMP],%[R_TMP2]\n\t" /* Number of in bytes. */ \ + " srlg %[R_TMP3],%[R_TMP],1\n\t" /* Number of out bytes. */ \ + " ahik %[R_TMP2],%[R_TMP3],-1\n\t" /* Highest index to store. */ \ + " jl 13f\n\t" \ + " vstl %%v18,%[R_TMP2],0(%[R_OUT])\n\t" \ + /* Update pointers. */ \ + " la %[R_IN],0(%[R_TMP],%[R_IN])\n\t" \ + " slgr %[R_INLEN],%[R_TMP]\n\t" \ + " la %[R_OUT],0(%[R_TMP3],%[R_OUT])\n\t" \ + " slgr %[R_OUTLEN],%[R_TMP3]\n\t" \ + "13: \n\t" \ + /* Calculate remaining uint16_t values in loaded vrs. */ \ + " lghi %[R_TMP2],16\n\t" \ + " slgr %[R_TMP2],%[R_TMP3]\n\t" \ + " llh %[R_TMP],0(%[R_IN])\n\t" \ + " aghi %[R_INLEN],-2\n\t" \ + " j 22f\n\t" \ + /* Handle remaining bytes. */ \ + "2: \n\t" \ + /* Zero, one or more bytes available? */ \ + " clgfi %[R_INLEN],1\n\t" \ + " locghie %[R_RES],%[RES_IN_FULL]\n\t" /* Only one byte. */ \ + " jle 99f\n\t" /* End if less than two bytes. */ \ + /* Calculate remaining uint16_t values in inptr. */ \ + " srlg %[R_TMP2],%[R_INLEN],1\n\t" \ + /* Handle multibyte utf8-char. */ \ + "20: llh %[R_TMP],0(%[R_IN])\n\t" \ + " aghi %[R_INLEN],-2\n\t" \ + /* Test if ch is 1-byte UTF-8 char. */ \ + "21: clijh %[R_TMP],0x7f,22f\n\t" \ + /* Handle 1-byte UTF-8 char. */ \ + "31: slgfi %[R_OUTLEN],1\n\t" \ + " jl 90f \n\t" \ + " stc %[R_TMP],0(%[R_OUT])\n\t" \ + " la %[R_IN],2(%[R_IN])\n\t" \ + " la %[R_OUT],1(%[R_OUT])\n\t" \ + " brctg %[R_TMP2],20b\n\t" \ + " j 0b\n\t" /* Switch to vx-loop. */ \ + /* Test if ch is 2-byte UTF-8 char. */ \ + "22: clfi %[R_TMP],0x7ff\n\t" \ + " jh 23f\n\t" \ + /* Handle 2-byte UTF-8 char. */ \ + "32: slgfi %[R_OUTLEN],2\n\t" \ + " jl 90f \n\t" \ + " llill %[R_TMP3],0xc080\n\t" \ + " la %[R_IN],2(%[R_IN])\n\t" \ + " risbgn %[R_TMP3],%[R_TMP],51,55,2\n\t" /* 1. byte. */ \ + " risbgn %[R_TMP3],%[R_TMP],58,63,0\n\t" /* 2. byte. */ \ + " sth %[R_TMP3],0(%[R_OUT])\n\t" \ + " la %[R_OUT],2(%[R_OUT])\n\t" \ + " brctg %[R_TMP2],20b\n\t" \ + " j 0b\n\t" /* Switch to vx-loop. */ \ + /* Test if ch is 3-byte UTF-8 char. */ \ + "23: clfi %[R_TMP],0xd7ff\n\t" \ + " jh 24f\n\t" \ + /* Handle 3-byte UTF-8 char. */ \ + "33: slgfi %[R_OUTLEN],3\n\t" \ + " jl 90f \n\t" \ + " llilf %[R_TMP3],0xe08080\n\t" \ + " la %[R_IN],2(%[R_IN])\n\t" \ + " risbgn %[R_TMP3],%[R_TMP],44,47,4\n\t" /* 1. byte. */ \ + " risbgn %[R_TMP3],%[R_TMP],50,55,2\n\t" /* 2. byte. */ \ + " risbgn %[R_TMP3],%[R_TMP],58,63,0\n\t" /* 3. byte. */ \ + " stcm %[R_TMP3],7,0(%[R_OUT])\n\t" \ + " la %[R_OUT],3(%[R_OUT])\n\t" \ + " brctg %[R_TMP2],20b\n\t" \ + " j 0b\n\t" /* Switch to vx-loop. */ \ + /* Test if ch is 4-byte UTF-8 char. */ \ + "24: clfi %[R_TMP],0xdfff\n\t" \ + " jh 33b\n\t" /* Handle this 3-byte UTF-8 char. */ \ + " clfi %[R_TMP],0xdbff\n\t" \ + " locghih %[R_RES],%[RES_IN_ILL]\n\t" \ + " jh 99f\n\t" /* Jump away if this is a low surrogate \ + without a preceding high surrogate. */ \ + /* Handle 4-byte UTF-8 char. */ \ + "34: slgfi %[R_OUTLEN],4\n\t" \ + " jl 90f \n\t" \ + " slgfi %[R_INLEN],2\n\t" \ + " locghil %[R_RES],%[RES_IN_FULL]\n\t" \ + " jl 99f\n\t" /* Jump away if low surrogate is missing. */ \ + " llilf %[R_TMP3],0xf0808080\n\t" \ + " aghi %[R_TMP],0x40\n\t" \ + " risbgn %[R_TMP3],%[R_TMP],37,39,16\n\t" /* 1. byte: uvw */ \ + " risbgn %[R_TMP3],%[R_TMP],42,43,14\n\t" /* 2. byte: xy */ \ + " risbgn %[R_TMP3],%[R_TMP],44,47,14\n\t" /* 2. byte: efgh */ \ + " risbgn %[R_TMP3],%[R_TMP],50,51,12\n\t" /* 3. byte: ij */ \ + " llh %[R_TMP],2(%[R_IN])\n\t" /* Load low surrogate. */ \ + " risbgn %[R_TMP3],%[R_TMP],52,55,2\n\t" /* 3. byte: klmn */ \ + " risbgn %[R_TMP3],%[R_TMP],58,63,0\n\t" /* 4. byte: opqrst */ \ + " nilf %[R_TMP],0xfc00\n\t" \ + " clfi %[R_TMP],0xdc00\n\t" /* Check if it starts with 0xdc00. */ \ + " locghine %[R_RES],%[RES_IN_ILL]\n\t" \ + " jne 99f\n\t" /* Jump away if low surrogate is invalid. */ \ + " st %[R_TMP3],0(%[R_OUT])\n\t" \ + " la %[R_IN],4(%[R_IN])\n\t" \ + " la %[R_OUT],4(%[R_OUT])\n\t" \ + " aghi %[R_TMP2],-2\n\t" \ + " jh 20b\n\t" \ + " j 0b\n\t" /* Switch to vx-loop. */ \ + /* Exit with __GCONV_FULL_OUTPUT. */ \ + "90: lghi %[R_RES],%[RES_OUT_FULL]\n\t" \ + "99: \n\t" \ + ".machine pop" \ + : /* outputs */ [R_IN] "+a" (inptr) \ + , [R_INLEN] "+d" (inlen), [R_OUT] "+a" (outptr) \ + , [R_OUTLEN] "+d" (outlen), [R_TMP] "=a" (tmp) \ + , [R_TMP2] "=d" (tmp2), [R_TMP3] "=a" (tmp3) \ + , [R_RES] "+d" (result) \ + : /* inputs */ \ + [RES_OUT_FULL] "i" (__GCONV_FULL_OUTPUT) \ + , [RES_IN_ILL] "i" (__GCONV_ILLEGAL_INPUT) \ + , [RES_IN_FULL] "i" (__GCONV_INCOMPLETE_INPUT) \ + : /* clobber list */ "memory", "cc" \ + ASM_CLOBBER_VR ("v16") ASM_CLOBBER_VR ("v17") \ + ASM_CLOBBER_VR ("v18") ASM_CLOBBER_VR ("v19") \ + ASM_CLOBBER_VR ("v30") ASM_CLOBBER_VR ("v31") \ + ); \ + if (__glibc_likely (inptr == inend) \ + || result != __GCONV_ILLEGAL_INPUT) \ + break; \ + \ + STANDARD_TO_LOOP_ERR_HANDLER (2); \ + } + +/* Generate loop-function with vector implementation. */ +# define MIN_NEEDED_INPUT MIN_NEEDED_TO +# define MAX_NEEDED_INPUT MAX_NEEDED_TO +# define MIN_NEEDED_OUTPUT MIN_NEEDED_FROM +# define MAX_NEEDED_OUTPUT MAX_NEEDED_FROM +# define TO_LOOP_VX __to_utf8_loop_vx +# define LOOPFCT TO_LOOP_VX +# define BODY BODY_TO_VX +# define LOOP_NEED_FLAGS +# include <iconv/loop.c> +#else +# define TO_LOOP_VX NULL +#endif /* HAVE_TO_VX != 1 */ + +#if HAVE_TO_VX_CU == 1 +#define BODY_TO_VX_CU \ + { \ + register const unsigned char* pInput asm ("8") = inptr; \ + register size_t inlen asm ("9") = inend - inptr; \ + register unsigned char* pOutput asm ("10") = outptr; \ + register size_t outlen asm ("11") = outend - outptr; \ + unsigned long tmp, tmp2, tmp3; \ + asm volatile (".machine push\n\t" \ + ".machine \"z13\"\n\t" \ + ".machinemode \"zarch_nohighgprs\"\n\t" \ + /* Setup to check for values <= 0x7f. */ \ + " larl %[R_TMP],9f\n\t" \ + " vlm %%v30,%%v31,0(%[R_TMP])\n\t" \ + CONVERT_32BIT_SIZE_T ([R_INLEN]) \ + CONVERT_32BIT_SIZE_T ([R_OUTLEN]) \ + /* Loop which handles UTF-16 chars <=0x7f. */ \ + "0: clgijl %[R_INLEN],32,20f\n\t" \ + " clgijl %[R_OUTLEN],16,20f\n\t" \ + "1: vlm %%v16,%%v17,0(%[R_IN])\n\t" \ + " lghi %[R_TMP2],0\n\t" \ + /* Check for > 1byte UTF-8 chars. */ \ + " vstrchs %%v19,%%v16,%%v30,%%v31\n\t" \ + " jno 10f\n\t" /* Jump away if not all bytes are 1byte \ + UTF8 chars. */ \ + " vstrchs %%v19,%%v17,%%v30,%%v31\n\t" \ + " jno 11f\n\t" /* Jump away if not all bytes are 1byte \ + UTF8 chars. */ \ + /* Shorten to UTF-8. */ \ + " vpkh %%v18,%%v16,%%v17\n\t" \ + " la %[R_IN],32(%[R_IN])\n\t" \ + " aghi %[R_INLEN],-32\n\t" \ + /* Store 16 bytes to buf_out. */ \ + " vst %%v18,0(%[R_OUT])\n\t" \ + " aghi %[R_OUTLEN],-16\n\t" \ + " la %[R_OUT],16(%[R_OUT])\n\t" \ + " clgijl %[R_INLEN],32,20f\n\t" \ + " clgijl %[R_OUTLEN],16,20f\n\t" \ + " j 1b\n\t" \ + /* Setup to check for ch > 0x7f. (v30, v31) */ \ + "9: .short 0x7f,0x7f,0x0,0x0,0x0,0x0,0x0,0x0\n\t" \ + " .short 0x2000,0x2000,0x0,0x0,0x0,0x0,0x0,0x0\n\t" \ + /* At least one byte is > 0x7f. \ + Store the preceding 1-byte chars. */ \ + "11: lghi %[R_TMP2],16\n\t" /* match was found in v17. */ \ + "10: vlgvb %[R_TMP],%%v19,7\n\t" \ + /* Shorten to UTF-8. */ \ + " vpkh %%v18,%%v16,%%v17\n\t" \ + " ar %[R_TMP],%[R_TMP2]\n\t" /* Number of in bytes. */ \ + " srlg %[R_TMP3],%[R_TMP],1\n\t" /* Number of out bytes. */ \ + " ahik %[R_TMP2],%[R_TMP3],-1\n\t" /* Highest index to store. */ \ + " jl 20f\n\t" \ + " vstl %%v18,%[R_TMP2],0(%[R_OUT])\n\t" \ + /* Update pointers. */ \ + " la %[R_IN],0(%[R_TMP],%[R_IN])\n\t" \ + " slgr %[R_INLEN],%[R_TMP]\n\t" \ + " la %[R_OUT],0(%[R_TMP3],%[R_OUT])\n\t" \ + " slgr %[R_OUTLEN],%[R_TMP3]\n\t" \ + /* Handles UTF16 surrogates with convert instruction. */ \ + "20: cu21 %[R_OUT],%[R_IN],1\n\t" \ + " jo 0b\n\t" /* Try vector implemenation again. */ \ + " lochil %[R_RES],%[RES_OUT_FULL]\n\t" /* cc == 1. */ \ + " lochih %[R_RES],%[RES_IN_ILL]\n\t" /* cc == 2. */ \ + ".machine pop" \ + : /* outputs */ [R_IN] "+a" (pInput) \ + , [R_INLEN] "+d" (inlen), [R_OUT] "+a" (pOutput) \ + , [R_OUTLEN] "+d" (outlen), [R_TMP] "=a" (tmp) \ + , [R_TMP2] "=d" (tmp2), [R_TMP3] "=a" (tmp3) \ + , [R_RES] "+d" (result) \ + : /* inputs */ \ + [RES_OUT_FULL] "i" (__GCONV_FULL_OUTPUT) \ + , [RES_IN_ILL] "i" (__GCONV_ILLEGAL_INPUT) \ + : /* clobber list */ "memory", "cc" \ + ASM_CLOBBER_VR ("v16") ASM_CLOBBER_VR ("v17") \ + ASM_CLOBBER_VR ("v18") ASM_CLOBBER_VR ("v19") \ + ASM_CLOBBER_VR ("v30") ASM_CLOBBER_VR ("v31") \ + ); \ + inptr = pInput; \ + outptr = pOutput; \ + \ + if (__glibc_likely (inlen == 0) \ + || result == __GCONV_FULL_OUTPUT) \ + break; \ + if (inlen == 1) \ + { \ + /* Input does not contain a complete utf16 character. */ \ + result = __GCONV_INCOMPLETE_INPUT; \ + break; \ + } \ + else if (result != __GCONV_ILLEGAL_INPUT) \ + { \ + /* Input is >= 2 and < 4 bytes (as cu21 would have processed \ + a possible next utf16 character) and not illegal. \ + => we have a single high surrogate at end of input. */ \ + result = __GCONV_INCOMPLETE_INPUT; \ + break; \ + } \ + \ + STANDARD_TO_LOOP_ERR_HANDLER (2); \ + } + +/* Generate loop-function with vector and utf-convert instructions. */ +# define MIN_NEEDED_INPUT MIN_NEEDED_TO +# define MAX_NEEDED_INPUT MAX_NEEDED_TO +# define MIN_NEEDED_OUTPUT MIN_NEEDED_FROM +# define MAX_NEEDED_OUTPUT MAX_NEEDED_FROM +# define TO_LOOP_VX_CU __to_utf8_loop_vx_cu +# define LOOPFCT TO_LOOP_VX_CU +# define BODY BODY_TO_VX_CU +# define LOOP_NEED_FLAGS +# include <iconv/loop.c> +#else +# define TO_LOOP_VX_CU NULL +#endif /* HAVE_TO_VX_CU != 1 */ + +/* This file also exists in sysdeps/s390/multiarch/ which + generates ifunc resolvers for FROM/TO_LOOP functions + and includes iconv/skeleton.c afterwards. */ +#if ! defined USE_MULTIARCH +# include <iconv/skeleton.c> +#endif diff --git a/sysdeps/s390/utf8-utf32-z9.c b/sysdeps/s390/utf8-utf32-z9.c new file mode 100644 index 0000000000..c09d9b5bbd --- /dev/null +++ b/sysdeps/s390/utf8-utf32-z9.c @@ -0,0 +1,983 @@ +/* Conversion between UTF-8 and UTF-32 BE/internal. + + This module uses the Z9-109 variants of the Convert Unicode + instructions. + Copyright (C) 1997-2018 Free Software Foundation, Inc. + + Author: Andreas Krebbel <Andreas.Krebbel@de.ibm.com> + Based on the work by Ulrich Drepper <drepper@cygnus.com>, 1997. + + Thanks to Daniel Appich who covered the relevant performance work + in his diploma thesis. + + This is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <dlfcn.h> +#include <stdint.h> +#include <unistd.h> +#include <gconv.h> +#include <string.h> + +/* Select which versions should be defined depending on support + for multiarch, vector and used minimum architecture level. */ +#ifdef HAVE_S390_MIN_Z196_ZARCH_ASM_SUPPORT +# define HAVE_FROM_C 0 +# define FROM_LOOP_DEFAULT FROM_LOOP_CU +#else +# define HAVE_FROM_C 1 +# define FROM_LOOP_DEFAULT FROM_LOOP_C +#endif + +#define HAVE_TO_C 1 +#define TO_LOOP_DEFAULT TO_LOOP_C + +#if defined HAVE_S390_MIN_Z196_ZARCH_ASM_SUPPORT || defined USE_MULTIARCH +# define HAVE_FROM_CU 1 +#else +# define HAVE_FROM_CU 0 +#endif + +#if defined HAVE_S390_VX_ASM_SUPPORT && defined USE_MULTIARCH +# define HAVE_FROM_VX 1 +# define HAVE_TO_VX 1 +# define HAVE_TO_VX_CU 1 +#else +# define HAVE_FROM_VX 0 +# define HAVE_TO_VX 0 +# define HAVE_TO_VX_CU 0 +#endif + +#if defined HAVE_S390_VX_GCC_SUPPORT +# define ASM_CLOBBER_VR(NR) , NR +#else +# define ASM_CLOBBER_VR(NR) +#endif + +#if defined __s390x__ +# define CONVERT_32BIT_SIZE_T(REG) +#else +# define CONVERT_32BIT_SIZE_T(REG) "llgfr %" #REG ",%" #REG "\n\t" +#endif + +/* Defines for skeleton.c. */ +#define DEFINE_INIT 0 +#define DEFINE_FINI 0 +#define MIN_NEEDED_FROM 1 +#define MAX_NEEDED_FROM 6 +#define MIN_NEEDED_TO 4 +#define FROM_LOOP FROM_LOOP_DEFAULT +#define TO_LOOP TO_LOOP_DEFAULT +#define FROM_DIRECTION (dir == from_utf8) +#define ONE_DIRECTION 0 + +/* UTF-32 big endian byte order mark. */ +#define BOM 0x0000feffu + +/* Direction of the transformation. */ +enum direction +{ + illegal_dir, + to_utf8, + from_utf8 +}; + +struct utf8_data +{ + enum direction dir; + int emit_bom; +}; + + +extern int gconv_init (struct __gconv_step *step); +int +gconv_init (struct __gconv_step *step) +{ + /* Determine which direction. */ + struct utf8_data *new_data; + enum direction dir = illegal_dir; + int emit_bom; + int result; + + emit_bom = (__strcasecmp (step->__to_name, "UTF-32//") == 0); + + if (__strcasecmp (step->__from_name, "ISO-10646/UTF8/") == 0 + && (__strcasecmp (step->__to_name, "UTF-32//") == 0 + || __strcasecmp (step->__to_name, "UTF-32BE//") == 0 + || __strcasecmp (step->__to_name, "INTERNAL") == 0)) + { + dir = from_utf8; + } + else if (__strcasecmp (step->__to_name, "ISO-10646/UTF8/") == 0 + && (__strcasecmp (step->__from_name, "UTF-32BE//") == 0 + || __strcasecmp (step->__from_name, "INTERNAL") == 0)) + { + dir = to_utf8; + } + + result = __GCONV_NOCONV; + if (dir != illegal_dir) + { + new_data = (struct utf8_data *) malloc (sizeof (struct utf8_data)); + + result = __GCONV_NOMEM; + if (new_data != NULL) + { + new_data->dir = dir; + new_data->emit_bom = emit_bom; + step->__data = new_data; + + if (dir == from_utf8) + { + step->__min_needed_from = MIN_NEEDED_FROM; + step->__max_needed_from = MIN_NEEDED_FROM; + step->__min_needed_to = MIN_NEEDED_TO; + step->__max_needed_to = MIN_NEEDED_TO; + } + else + { + step->__min_needed_from = MIN_NEEDED_TO; + step->__max_needed_from = MIN_NEEDED_TO; + step->__min_needed_to = MIN_NEEDED_FROM; + step->__max_needed_to = MIN_NEEDED_FROM; + } + + step->__stateful = 0; + + result = __GCONV_OK; + } + } + + return result; +} + + +extern void gconv_end (struct __gconv_step *data); +void +gconv_end (struct __gconv_step *data) +{ + free (data->__data); +} + +/* The macro for the hardware loop. This is used for both + directions. */ +#define HARDWARE_CONVERT(INSTRUCTION) \ + { \ + register const unsigned char* pInput __asm__ ("8") = inptr; \ + register size_t inlen __asm__ ("9") = inend - inptr; \ + register unsigned char* pOutput __asm__ ("10") = outptr; \ + register size_t outlen __asm__("11") = outend - outptr; \ + unsigned long cc = 0; \ + \ + __asm__ __volatile__ (".machine push \n\t" \ + ".machine \"z9-109\" \n\t" \ + ".machinemode \"zarch_nohighgprs\"\n\t" \ + "0: " INSTRUCTION " \n\t" \ + ".machine pop \n\t" \ + " jo 0b \n\t" \ + " ipm %2 \n" \ + : "+a" (pOutput), "+a" (pInput), "+d" (cc), \ + "+d" (outlen), "+d" (inlen) \ + : \ + : "cc", "memory"); \ + \ + inptr = pInput; \ + outptr = pOutput; \ + cc >>= 28; \ + \ + if (cc == 1) \ + { \ + result = __GCONV_FULL_OUTPUT; \ + } \ + else if (cc == 2) \ + { \ + result = __GCONV_ILLEGAL_INPUT; \ + } \ + } + +#define PREPARE_LOOP \ + enum direction dir = ((struct utf8_data *) step->__data)->dir; \ + int emit_bom = ((struct utf8_data *) step->__data)->emit_bom; \ + \ + if (emit_bom && !data->__internal_use \ + && data->__invocation_counter == 0) \ + { \ + /* Emit the Byte Order Mark. */ \ + if (__glibc_unlikely (outbuf + 4 > outend)) \ + return __GCONV_FULL_OUTPUT; \ + \ + put32u (outbuf, BOM); \ + outbuf += 4; \ + } + +/* Conversion function from UTF-8 to UTF-32 internal/BE. */ + +#define STORE_REST_COMMON \ + { \ + /* We store the remaining bytes while converting them into the UCS4 \ + format. We can assume that the first byte in the buffer is \ + correct and that it requires a larger number of bytes than there \ + are in the input buffer. */ \ + wint_t ch = **inptrp; \ + size_t cnt, r; \ + \ + state->__count = inend - *inptrp; \ + \ + assert (ch != 0xc0 && ch != 0xc1); \ + if (ch >= 0xc2 && ch < 0xe0) \ + { \ + /* We expect two bytes. The first byte cannot be 0xc0 or \ + 0xc1, otherwise the wide character could have been \ + represented using a single byte. */ \ + cnt = 2; \ + ch &= 0x1f; \ + } \ + else if (__glibc_likely ((ch & 0xf0) == 0xe0)) \ + { \ + /* We expect three bytes. */ \ + cnt = 3; \ + ch &= 0x0f; \ + } \ + else if (__glibc_likely ((ch & 0xf8) == 0xf0)) \ + { \ + /* We expect four bytes. */ \ + cnt = 4; \ + ch &= 0x07; \ + } \ + else if (__glibc_likely ((ch & 0xfc) == 0xf8)) \ + { \ + /* We expect five bytes. */ \ + cnt = 5; \ + ch &= 0x03; \ + } \ + else \ + { \ + /* We expect six bytes. */ \ + cnt = 6; \ + ch &= 0x01; \ + } \ + \ + /* The first byte is already consumed. */ \ + r = cnt - 1; \ + while (++(*inptrp) < inend) \ + { \ + ch <<= 6; \ + ch |= **inptrp & 0x3f; \ + --r; \ + } \ + \ + /* Shift for the so far missing bytes. */ \ + ch <<= r * 6; \ + \ + /* Store the number of bytes expected for the entire sequence. */ \ + state->__count |= cnt << 8; \ + \ + /* Store the value. */ \ + state->__value.__wch = ch; \ + } + +#define UNPACK_BYTES_COMMON \ + { \ + static const unsigned char inmask[5] = { 0xc0, 0xe0, 0xf0, 0xf8, 0xfc }; \ + wint_t wch = state->__value.__wch; \ + size_t ntotal = state->__count >> 8; \ + \ + inlen = state->__count & 255; \ + \ + bytebuf[0] = inmask[ntotal - 2]; \ + \ + do \ + { \ + if (--ntotal < inlen) \ + bytebuf[ntotal] = 0x80 | (wch & 0x3f); \ + wch >>= 6; \ + } \ + while (ntotal > 1); \ + \ + bytebuf[0] |= wch; \ + } + +#define CLEAR_STATE_COMMON \ + state->__count = 0 + +#define BODY_FROM_HW(ASM) \ + { \ + ASM; \ + if (__glibc_likely (inptr == inend) \ + || result == __GCONV_FULL_OUTPUT) \ + break; \ + \ + int i; \ + for (i = 1; inptr + i < inend && i < 5; ++i) \ + if ((inptr[i] & 0xc0) != 0x80) \ + break; \ + \ + if (__glibc_likely (inptr + i == inend \ + && result == __GCONV_EMPTY_INPUT)) \ + { \ + result = __GCONV_INCOMPLETE_INPUT; \ + break; \ + } \ + STANDARD_FROM_LOOP_ERR_HANDLER (i); \ + } + +#if HAVE_FROM_C == 1 +/* The software routine is copied from gconv_simple.c. */ +# define BODY_FROM_C \ + { \ + /* Next input byte. */ \ + uint32_t ch = *inptr; \ + \ + if (__glibc_likely (ch < 0x80)) \ + { \ + /* One byte sequence. */ \ + ++inptr; \ + } \ + else \ + { \ + uint_fast32_t cnt; \ + uint_fast32_t i; \ + \ + if (ch >= 0xc2 && ch < 0xe0) \ + { \ + /* We expect two bytes. The first byte cannot be 0xc0 or \ + 0xc1, otherwise the wide character could have been \ + represented using a single byte. */ \ + cnt = 2; \ + ch &= 0x1f; \ + } \ + else if (__glibc_likely ((ch & 0xf0) == 0xe0)) \ + { \ + /* We expect three bytes. */ \ + cnt = 3; \ + ch &= 0x0f; \ + } \ + else if (__glibc_likely ((ch & 0xf8) == 0xf0)) \ + { \ + /* We expect four bytes. */ \ + cnt = 4; \ + ch &= 0x07; \ + } \ + else \ + { \ + /* Search the end of this ill-formed UTF-8 character. This \ + is the next byte with (x & 0xc0) != 0x80. */ \ + i = 0; \ + do \ + ++i; \ + while (inptr + i < inend \ + && (*(inptr + i) & 0xc0) == 0x80 \ + && i < 5); \ + \ + errout: \ + STANDARD_FROM_LOOP_ERR_HANDLER (i); \ + } \ + \ + if (__glibc_unlikely (inptr + cnt > inend)) \ + { \ + /* We don't have enough input. But before we report \ + that check that all the bytes are correct. */ \ + for (i = 1; inptr + i < inend; ++i) \ + if ((inptr[i] & 0xc0) != 0x80) \ + break; \ + \ + if (__glibc_likely (inptr + i == inend)) \ + { \ + result = __GCONV_INCOMPLETE_INPUT; \ + break; \ + } \ + \ + goto errout; \ + } \ + \ + /* Read the possible remaining bytes. */ \ + for (i = 1; i < cnt; ++i) \ + { \ + uint32_t byte = inptr[i]; \ + \ + if ((byte & 0xc0) != 0x80) \ + /* This is an illegal encoding. */ \ + break; \ + \ + ch <<= 6; \ + ch |= byte & 0x3f; \ + } \ + \ + /* If i < cnt, some trail byte was not >= 0x80, < 0xc0. \ + If cnt > 2 and ch < 2^(5*cnt-4), the wide character ch could \ + have been represented with fewer than cnt bytes. */ \ + if (i < cnt || (cnt > 2 && (ch >> (5 * cnt - 4)) == 0) \ + /* Do not accept UTF-16 surrogates. */ \ + || (ch >= 0xd800 && ch <= 0xdfff) \ + || (ch > 0x10ffff)) \ + { \ + /* This is an illegal encoding. */ \ + goto errout; \ + } \ + \ + inptr += cnt; \ + } \ + \ + /* Now adjust the pointers and store the result. */ \ + *((uint32_t *) outptr) = ch; \ + outptr += sizeof (uint32_t); \ + } + +/* These definitions apply to the UTF-8 to UTF-32 direction. The + software implementation for UTF-8 still supports multibyte + characters up to 6 bytes whereas the hardware variant does not. */ +# define MIN_NEEDED_INPUT MIN_NEEDED_FROM +# define MAX_NEEDED_INPUT MAX_NEEDED_FROM +# define MIN_NEEDED_OUTPUT MIN_NEEDED_TO +# define FROM_LOOP_C __from_utf8_loop_c +# define LOOPFCT FROM_LOOP_C + +# define LOOP_NEED_FLAGS + +# define STORE_REST STORE_REST_COMMON +# define UNPACK_BYTES UNPACK_BYTES_COMMON +# define CLEAR_STATE CLEAR_STATE_COMMON +# define BODY BODY_FROM_C +# include <iconv/loop.c> +#else +# define FROM_LOOP_C NULL +#endif /* HAVE_FROM_C != 1 */ + +#if HAVE_FROM_CU == 1 +/* This hardware routine uses the Convert UTF8 to UTF32 (cu14) instruction. */ +# define BODY_FROM_ETF3EH BODY_FROM_HW (HARDWARE_CONVERT ("cu14 %0, %1, 1")) + +/* Generate loop-function with hardware utf-convert instruction. */ +# define MIN_NEEDED_INPUT MIN_NEEDED_FROM +# define MAX_NEEDED_INPUT MAX_NEEDED_FROM +# define MIN_NEEDED_OUTPUT MIN_NEEDED_TO +# define FROM_LOOP_CU __from_utf8_loop_etf3eh +# define LOOPFCT FROM_LOOP_CU + +# define LOOP_NEED_FLAGS + +# define STORE_REST STORE_REST_COMMON +# define UNPACK_BYTES UNPACK_BYTES_COMMON +# define CLEAR_STATE CLEAR_STATE_COMMON +# define BODY BODY_FROM_ETF3EH +# include <iconv/loop.c> +#else +# define FROM_LOOP_CU NULL +#endif /* HAVE_FROM_CU != 1 */ + +#if HAVE_FROM_VX == 1 +# define HW_FROM_VX \ + { \ + register const unsigned char* pInput asm ("8") = inptr; \ + register size_t inlen asm ("9") = inend - inptr; \ + register unsigned char* pOutput asm ("10") = outptr; \ + register size_t outlen asm("11") = outend - outptr; \ + unsigned long tmp, tmp2, tmp3; \ + asm volatile (".machine push\n\t" \ + ".machine \"z13\"\n\t" \ + ".machinemode \"zarch_nohighgprs\"\n\t" \ + " vrepib %%v30,0x7f\n\t" /* For compare > 0x7f. */ \ + " vrepib %%v31,0x20\n\t" \ + CONVERT_32BIT_SIZE_T ([R_INLEN]) \ + CONVERT_32BIT_SIZE_T ([R_OUTLEN]) \ + /* Loop which handles UTF-8 chars <=0x7f. */ \ + "0: clgijl %[R_INLEN],16,20f\n\t" \ + " clgijl %[R_OUTLEN],64,20f\n\t" \ + "1: vl %%v16,0(%[R_IN])\n\t" \ + " vstrcbs %%v17,%%v16,%%v30,%%v31\n\t" \ + " jno 10f\n\t" /* Jump away if not all bytes are 1byte \ + UTF8 chars. */ \ + /* Enlarge to UCS4. */ \ + " vuplhb %%v18,%%v16\n\t" \ + " vupllb %%v19,%%v16\n\t" \ + " la %[R_IN],16(%[R_IN])\n\t" \ + " vuplhh %%v20,%%v18\n\t" \ + " aghi %[R_INLEN],-16\n\t" \ + " vupllh %%v21,%%v18\n\t" \ + " aghi %[R_OUTLEN],-64\n\t" \ + " vuplhh %%v22,%%v19\n\t" \ + " vupllh %%v23,%%v19\n\t" \ + /* Store 64 bytes to buf_out. */ \ + " vstm %%v20,%%v23,0(%[R_OUT])\n\t" \ + " la %[R_OUT],64(%[R_OUT])\n\t" \ + " clgijl %[R_INLEN],16,20f\n\t" \ + " clgijl %[R_OUTLEN],64,20f\n\t" \ + " j 1b\n\t" \ + "10: \n\t" \ + /* At least one byte is > 0x7f. \ + Store the preceding 1-byte chars. */ \ + " vlgvb %[R_TMP],%%v17,7\n\t" \ + " sllk %[R_TMP2],%[R_TMP],2\n\t" /* Compute highest \ + index to store. */ \ + " llgfr %[R_TMP3],%[R_TMP2]\n\t" \ + " ahi %[R_TMP2],-1\n\t" \ + " jl 20f\n\t" \ + " vuplhb %%v18,%%v16\n\t" \ + " vuplhh %%v20,%%v18\n\t" \ + " vstl %%v20,%[R_TMP2],0(%[R_OUT])\n\t" \ + " ahi %[R_TMP2],-16\n\t" \ + " jl 11f\n\t" \ + " vupllh %%v21,%%v18\n\t" \ + " vstl %%v21,%[R_TMP2],16(%[R_OUT])\n\t" \ + " ahi %[R_TMP2],-16\n\t" \ + " jl 11f\n\t" \ + " vupllb %%v19,%%v16\n\t" \ + " vuplhh %%v22,%%v19\n\t" \ + " vstl %%v22,%[R_TMP2],32(%[R_OUT])\n\t" \ + " ahi %[R_TMP2],-16\n\t" \ + " jl 11f\n\t" \ + " vupllh %%v23,%%v19\n\t" \ + " vstl %%v23,%[R_TMP2],48(%[R_OUT])\n\t" \ + "11: \n\t" \ + /* Update pointers. */ \ + " la %[R_IN],0(%[R_TMP],%[R_IN])\n\t" \ + " slgr %[R_INLEN],%[R_TMP]\n\t" \ + " la %[R_OUT],0(%[R_TMP3],%[R_OUT])\n\t" \ + " slgr %[R_OUTLEN],%[R_TMP3]\n\t" \ + /* Handle multibyte utf8-char with convert instruction. */ \ + "20: cu14 %[R_OUT],%[R_IN],1\n\t" \ + " jo 0b\n\t" /* Try vector implemenation again. */ \ + " lochil %[R_RES],%[RES_OUT_FULL]\n\t" /* cc == 1. */ \ + " lochih %[R_RES],%[RES_IN_ILL]\n\t" /* cc == 2. */ \ + ".machine pop" \ + : /* outputs */ [R_IN] "+a" (pInput) \ + , [R_INLEN] "+d" (inlen), [R_OUT] "+a" (pOutput) \ + , [R_OUTLEN] "+d" (outlen), [R_TMP] "=a" (tmp) \ + , [R_TMP2] "=d" (tmp2), [R_TMP3] "=a" (tmp3) \ + , [R_RES] "+d" (result) \ + : /* inputs */ \ + [RES_OUT_FULL] "i" (__GCONV_FULL_OUTPUT) \ + , [RES_IN_ILL] "i" (__GCONV_ILLEGAL_INPUT) \ + : /* clobber list */ "memory", "cc" \ + ASM_CLOBBER_VR ("v16") ASM_CLOBBER_VR ("v17") \ + ASM_CLOBBER_VR ("v18") ASM_CLOBBER_VR ("v19") \ + ASM_CLOBBER_VR ("v20") ASM_CLOBBER_VR ("v21") \ + ASM_CLOBBER_VR ("v22") ASM_CLOBBER_VR ("v30") \ + ASM_CLOBBER_VR ("v31") \ + ); \ + inptr = pInput; \ + outptr = pOutput; \ + } +# define BODY_FROM_VX BODY_FROM_HW (HW_FROM_VX) + +/* Generate loop-function with hardware vector and utf-convert instructions. */ +# define MIN_NEEDED_INPUT MIN_NEEDED_FROM +# define MAX_NEEDED_INPUT MAX_NEEDED_FROM +# define MIN_NEEDED_OUTPUT MIN_NEEDED_TO +# define FROM_LOOP_VX __from_utf8_loop_vx +# define LOOPFCT FROM_LOOP_VX + +# define LOOP_NEED_FLAGS + +# define STORE_REST STORE_REST_COMMON +# define UNPACK_BYTES UNPACK_BYTES_COMMON +# define CLEAR_STATE CLEAR_STATE_COMMON +# define BODY BODY_FROM_VX +# include <iconv/loop.c> +#else +# define FROM_LOOP_VX NULL +#endif /* HAVE_FROM_VX != 1 */ + +#if HAVE_TO_C == 1 +/* The software routine mimics the S/390 cu41 instruction. */ +# define BODY_TO_C \ + { \ + uint32_t wc = *((const uint32_t *) inptr); \ + \ + if (__glibc_likely (wc <= 0x7f)) \ + { \ + /* Single UTF-8 char. */ \ + *outptr = (uint8_t)wc; \ + outptr++; \ + } \ + else if (wc <= 0x7ff) \ + { \ + /* Two UTF-8 chars. */ \ + if (__glibc_unlikely (outptr + 2 > outend)) \ + { \ + /* Overflow in the output buffer. */ \ + result = __GCONV_FULL_OUTPUT; \ + break; \ + } \ + \ + outptr[0] = 0xc0; \ + outptr[0] |= wc >> 6; \ + \ + outptr[1] = 0x80; \ + outptr[1] |= wc & 0x3f; \ + \ + outptr += 2; \ + } \ + else if (wc <= 0xffff) \ + { \ + /* Three UTF-8 chars. */ \ + if (__glibc_unlikely (outptr + 3 > outend)) \ + { \ + /* Overflow in the output buffer. */ \ + result = __GCONV_FULL_OUTPUT; \ + break; \ + } \ + if (wc >= 0xd800 && wc <= 0xdfff) \ + { \ + /* Do not accept UTF-16 surrogates. */ \ + result = __GCONV_ILLEGAL_INPUT; \ + STANDARD_TO_LOOP_ERR_HANDLER (4); \ + } \ + outptr[0] = 0xe0; \ + outptr[0] |= wc >> 12; \ + \ + outptr[1] = 0x80; \ + outptr[1] |= (wc >> 6) & 0x3f; \ + \ + outptr[2] = 0x80; \ + outptr[2] |= wc & 0x3f; \ + \ + outptr += 3; \ + } \ + else if (wc <= 0x10ffff) \ + { \ + /* Four UTF-8 chars. */ \ + if (__glibc_unlikely (outptr + 4 > outend)) \ + { \ + /* Overflow in the output buffer. */ \ + result = __GCONV_FULL_OUTPUT; \ + break; \ + } \ + outptr[0] = 0xf0; \ + outptr[0] |= wc >> 18; \ + \ + outptr[1] = 0x80; \ + outptr[1] |= (wc >> 12) & 0x3f; \ + \ + outptr[2] = 0x80; \ + outptr[2] |= (wc >> 6) & 0x3f; \ + \ + outptr[3] = 0x80; \ + outptr[3] |= wc & 0x3f; \ + \ + outptr += 4; \ + } \ + else \ + { \ + STANDARD_TO_LOOP_ERR_HANDLER (4); \ + } \ + inptr += 4; \ + } + +/* Generate loop-function with software routing. */ +# define MIN_NEEDED_INPUT MIN_NEEDED_TO +# define MIN_NEEDED_OUTPUT MIN_NEEDED_FROM +# define MAX_NEEDED_OUTPUT MAX_NEEDED_FROM +# define TO_LOOP_C __to_utf8_loop_c +# define LOOPFCT TO_LOOP_C +# define BODY BODY_TO_C +# define LOOP_NEED_FLAGS +# include <iconv/loop.c> +#else +# define TO_LOOP_C NULL +#endif /* HAVE_TO_C != 1 */ + +#if HAVE_TO_VX == 1 +/* The hardware routine uses the S/390 vector instructions. */ +# define BODY_TO_VX \ + { \ + size_t inlen = inend - inptr; \ + size_t outlen = outend - outptr; \ + unsigned long tmp, tmp2, tmp3; \ + asm volatile (".machine push\n\t" \ + ".machine \"z13\"\n\t" \ + ".machinemode \"zarch_nohighgprs\"\n\t" \ + " vleif %%v20,127,0\n\t" /* element 0: 127 */ \ + " vzero %%v21\n\t" \ + " vleih %%v21,8192,0\n\t" /* element 0: > */ \ + " vleih %%v21,-8192,2\n\t" /* element 1: =<> */ \ + CONVERT_32BIT_SIZE_T ([R_INLEN]) \ + CONVERT_32BIT_SIZE_T ([R_OUTLEN]) \ + /* Loop which handles UTF-32 chars <=0x7f. */ \ + "0: clgijl %[R_INLEN],64,2f\n\t" \ + " clgijl %[R_OUTLEN],16,2f\n\t" \ + "1: vlm %%v16,%%v19,0(%[R_IN])\n\t" \ + " lghi %[R_TMP2],0\n\t" \ + /* Shorten to byte values. */ \ + " vpkf %%v23,%%v16,%%v17\n\t" \ + " vpkf %%v24,%%v18,%%v19\n\t" \ + " vpkh %%v23,%%v23,%%v24\n\t" \ + /* Checking for values > 0x7f. */ \ + " vstrcfs %%v22,%%v16,%%v20,%%v21\n\t" \ + " jno 10f\n\t" \ + " vstrcfs %%v22,%%v17,%%v20,%%v21\n\t" \ + " jno 11f\n\t" \ + " vstrcfs %%v22,%%v18,%%v20,%%v21\n\t" \ + " jno 12f\n\t" \ + " vstrcfs %%v22,%%v19,%%v20,%%v21\n\t" \ + " jno 13f\n\t" \ + /* Store 16bytes to outptr. */ \ + " vst %%v23,0(%[R_OUT])\n\t" \ + " aghi %[R_INLEN],-64\n\t" \ + " aghi %[R_OUTLEN],-16\n\t" \ + " la %[R_IN],64(%[R_IN])\n\t" \ + " la %[R_OUT],16(%[R_OUT])\n\t" \ + " clgijl %[R_INLEN],64,2f\n\t" \ + " clgijl %[R_OUTLEN],16,2f\n\t" \ + " j 1b\n\t" \ + /* Found a value > 0x7f. */ \ + "13: ahi %[R_TMP2],4\n\t" \ + "12: ahi %[R_TMP2],4\n\t" \ + "11: ahi %[R_TMP2],4\n\t" \ + "10: vlgvb %[R_TMP],%%v22,7\n\t" \ + " srlg %[R_TMP],%[R_TMP],2\n\t" \ + " agr %[R_TMP],%[R_TMP2]\n\t" \ + " je 16f\n\t" \ + /* Store characters before invalid one... */ \ + " slgr %[R_OUTLEN],%[R_TMP]\n\t" \ + "15: aghi %[R_TMP],-1\n\t" \ + " vstl %%v23,%[R_TMP],0(%[R_OUT])\n\t" \ + /* ... and update pointers. */ \ + " aghi %[R_TMP],1\n\t" \ + " la %[R_OUT],0(%[R_TMP],%[R_OUT])\n\t" \ + " sllg %[R_TMP2],%[R_TMP],2\n\t" \ + " la %[R_IN],0(%[R_TMP2],%[R_IN])\n\t" \ + " slgr %[R_INLEN],%[R_TMP2]\n\t" \ + /* Calculate remaining uint32_t values in loaded vrs. */ \ + "16: lghi %[R_TMP2],16\n\t" \ + " sgr %[R_TMP2],%[R_TMP]\n\t" \ + " l %[R_TMP],0(%[R_IN])\n\t" \ + " aghi %[R_INLEN],-4\n\t" \ + " j 22f\n\t" \ + /* Handle remaining bytes. */ \ + "2: clgije %[R_INLEN],0,99f\n\t" \ + " clgijl %[R_INLEN],4,92f\n\t" \ + /* Calculate remaining uint32_t values in inptr. */ \ + " srlg %[R_TMP2],%[R_INLEN],2\n\t" \ + /* Handle multibyte utf8-char. */ \ + "20: l %[R_TMP],0(%[R_IN])\n\t" \ + " aghi %[R_INLEN],-4\n\t" \ + /* Test if ch is 1byte UTF-8 char. */ \ + "21: clijh %[R_TMP],0x7f,22f\n\t" \ + /* Handle 1-byte UTF-8 char. */ \ + "31: slgfi %[R_OUTLEN],1\n\t" \ + " jl 90f \n\t" \ + " stc %[R_TMP],0(%[R_OUT])\n\t" \ + " la %[R_IN],4(%[R_IN])\n\t" \ + " la %[R_OUT],1(%[R_OUT])\n\t" \ + " brctg %[R_TMP2],20b\n\t" \ + " j 0b\n\t" /* Switch to vx-loop. */ \ + /* Test if ch is 2byte UTF-8 char. */ \ + "22: clfi %[R_TMP],0x7ff\n\t" \ + " jh 23f\n\t" \ + /* Handle 2-byte UTF-8 char. */ \ + "32: slgfi %[R_OUTLEN],2\n\t" \ + " jl 90f \n\t" \ + " llill %[R_TMP3],0xc080\n\t" \ + " risbgn %[R_TMP3],%[R_TMP],51,55,2\n\t" /* 1. byte. */ \ + " risbgn %[R_TMP3],%[R_TMP],58,63,0\n\t" /* 2. byte. */ \ + " sth %[R_TMP3],0(%[R_OUT])\n\t" \ + " la %[R_IN],4(%[R_IN])\n\t" \ + " la %[R_OUT],2(%[R_OUT])\n\t" \ + " brctg %[R_TMP2],20b\n\t" \ + " j 0b\n\t" /* Switch to vx-loop. */ \ + /* Test if ch is 3-byte UTF-8 char. */ \ + "23: clfi %[R_TMP],0xffff\n\t" \ + " jh 24f\n\t" \ + /* Handle 3-byte UTF-8 char. */ \ + "33: slgfi %[R_OUTLEN],3\n\t" \ + " jl 90f \n\t" \ + " llilf %[R_TMP3],0xe08080\n\t" \ + " risbgn %[R_TMP3],%[R_TMP],44,47,4\n\t" /* 1. byte. */ \ + " risbgn %[R_TMP3],%[R_TMP],50,55,2\n\t" /* 2. byte. */ \ + " risbgn %[R_TMP3],%[R_TMP],58,63,0\n\t" /* 3. byte. */ \ + /* Test if ch is a UTF-16 surrogate: ch & 0xf800 == 0xd800 */ \ + " nilf %[R_TMP],0xf800\n\t" \ + " clfi %[R_TMP],0xd800\n\t" \ + " je 91f\n\t" /* Do not accept UTF-16 surrogates. */ \ + " stcm %[R_TMP3],7,0(%[R_OUT])\n\t" \ + " la %[R_IN],4(%[R_IN])\n\t" \ + " la %[R_OUT],3(%[R_OUT])\n\t" \ + " brctg %[R_TMP2],20b\n\t" \ + " j 0b\n\t" /* Switch to vx-loop. */ \ + /* Test if ch is 4-byte UTF-8 char. */ \ + "24: clfi %[R_TMP],0x10ffff\n\t" \ + " jh 91f\n\t" /* ch > 0x10ffff is not allowed! */ \ + /* Handle 4-byte UTF-8 char. */ \ + "34: slgfi %[R_OUTLEN],4\n\t" \ + " jl 90f \n\t" \ + " llilf %[R_TMP3],0xf0808080\n\t" \ + " risbgn %[R_TMP3],%[R_TMP],37,39,6\n\t" /* 1. byte. */ \ + " risbgn %[R_TMP3],%[R_TMP],42,47,4\n\t" /* 2. byte. */ \ + " risbgn %[R_TMP3],%[R_TMP],50,55,2\n\t" /* 3. byte. */ \ + " risbgn %[R_TMP3],%[R_TMP],58,63,0\n\t" /* 4. byte. */ \ + " st %[R_TMP3],0(%[R_OUT])\n\t" \ + " la %[R_IN],4(%[R_IN])\n\t" \ + " la %[R_OUT],4(%[R_OUT])\n\t" \ + " brctg %[R_TMP2],20b\n\t" \ + " j 0b\n\t" /* Switch to vx-loop. */ \ + "92: lghi %[R_RES],%[RES_IN_FULL]\n\t" \ + " j 99f\n\t" \ + "91: lghi %[R_RES],%[RES_IN_ILL]\n\t" \ + " j 99f\n\t" \ + "90: lghi %[R_RES],%[RES_OUT_FULL]\n\t" \ + "99: \n\t" \ + ".machine pop" \ + : /* outputs */ [R_IN] "+a" (inptr) \ + , [R_INLEN] "+d" (inlen), [R_OUT] "+a" (outptr) \ + , [R_OUTLEN] "+d" (outlen), [R_TMP] "=a" (tmp) \ + , [R_TMP2] "=a" (tmp2), [R_TMP3] "=d" (tmp3) \ + , [R_RES] "+d" (result) \ + : /* inputs */ \ + [RES_OUT_FULL] "i" (__GCONV_FULL_OUTPUT) \ + , [RES_IN_ILL] "i" (__GCONV_ILLEGAL_INPUT) \ + , [RES_IN_FULL] "i" (__GCONV_INCOMPLETE_INPUT) \ + : /* clobber list */ "memory", "cc" \ + ASM_CLOBBER_VR ("v16") ASM_CLOBBER_VR ("v17") \ + ASM_CLOBBER_VR ("v18") ASM_CLOBBER_VR ("v19") \ + ASM_CLOBBER_VR ("v20") ASM_CLOBBER_VR ("v21") \ + ASM_CLOBBER_VR ("v22") ASM_CLOBBER_VR ("v23") \ + ASM_CLOBBER_VR ("v24") \ + ); \ + if (__glibc_likely (inptr == inend) \ + || result != __GCONV_ILLEGAL_INPUT) \ + break; \ + \ + STANDARD_TO_LOOP_ERR_HANDLER (4); \ + } + +/* Generate loop-function with hardware vector instructions. */ +# define MIN_NEEDED_INPUT MIN_NEEDED_TO +# define MIN_NEEDED_OUTPUT MIN_NEEDED_FROM +# define MAX_NEEDED_OUTPUT MAX_NEEDED_FROM +# define TO_LOOP_VX __to_utf8_loop_vx +# define LOOPFCT TO_LOOP_VX +# define BODY BODY_TO_VX +# define LOOP_NEED_FLAGS +# include <iconv/loop.c> +#else +# define TO_LOOP_VX NULL +#endif /* HAVE_TO_VX != 1 */ + +#if HAVE_TO_VX_CU == 1 +#define BODY_TO_VX_CU \ + { \ + register const unsigned char* pInput asm ("8") = inptr; \ + register size_t inlen asm ("9") = inend - inptr; \ + register unsigned char* pOutput asm ("10") = outptr; \ + register size_t outlen asm ("11") = outend - outptr; \ + unsigned long tmp, tmp2; \ + asm volatile (".machine push\n\t" \ + ".machine \"z13\"\n\t" \ + ".machinemode \"zarch_nohighgprs\"\n\t" \ + " vleif %%v20,127,0\n\t" /* element 0: 127 */ \ + " vzero %%v21\n\t" \ + " vleih %%v21,8192,0\n\t" /* element 0: > */ \ + " vleih %%v21,-8192,2\n\t" /* element 1: =<> */ \ + CONVERT_32BIT_SIZE_T ([R_INLEN]) \ + CONVERT_32BIT_SIZE_T ([R_OUTLEN]) \ + /* Loop which handles UTF-32 chars <= 0x7f. */ \ + "0: clgijl %[R_INLEN],64,20f\n\t" \ + " clgijl %[R_OUTLEN],16,20f\n\t" \ + "1: vlm %%v16,%%v19,0(%[R_IN])\n\t" \ + " lghi %[R_TMP],0\n\t" \ + /* Shorten to byte values. */ \ + " vpkf %%v23,%%v16,%%v17\n\t" \ + " vpkf %%v24,%%v18,%%v19\n\t" \ + " vpkh %%v23,%%v23,%%v24\n\t" \ + /* Checking for values > 0x7f. */ \ + " vstrcfs %%v22,%%v16,%%v20,%%v21\n\t" \ + " jno 10f\n\t" \ + " vstrcfs %%v22,%%v17,%%v20,%%v21\n\t" \ + " jno 11f\n\t" \ + " vstrcfs %%v22,%%v18,%%v20,%%v21\n\t" \ + " jno 12f\n\t" \ + " vstrcfs %%v22,%%v19,%%v20,%%v21\n\t" \ + " jno 13f\n\t" \ + /* Store 16bytes to outptr. */ \ + " vst %%v23,0(%[R_OUT])\n\t" \ + " aghi %[R_INLEN],-64\n\t" \ + " aghi %[R_OUTLEN],-16\n\t" \ + " la %[R_IN],64(%[R_IN])\n\t" \ + " la %[R_OUT],16(%[R_OUT])\n\t" \ + " clgijl %[R_INLEN],64,20f\n\t" \ + " clgijl %[R_OUTLEN],16,20f\n\t" \ + " j 1b\n\t" \ + /* Found a value > 0x7f. */ \ + "13: ahi %[R_TMP],4\n\t" \ + "12: ahi %[R_TMP],4\n\t" \ + "11: ahi %[R_TMP],4\n\t" \ + "10: vlgvb %[R_I],%%v22,7\n\t" \ + " srlg %[R_I],%[R_I],2\n\t" \ + " agr %[R_I],%[R_TMP]\n\t" \ + " je 20f\n\t" \ + /* Store characters before invalid one... */ \ + " slgr %[R_OUTLEN],%[R_I]\n\t" \ + "15: aghi %[R_I],-1\n\t" \ + " vstl %%v23,%[R_I],0(%[R_OUT])\n\t" \ + /* ... and update pointers. */ \ + " aghi %[R_I],1\n\t" \ + " la %[R_OUT],0(%[R_I],%[R_OUT])\n\t" \ + " sllg %[R_I],%[R_I],2\n\t" \ + " la %[R_IN],0(%[R_I],%[R_IN])\n\t" \ + " slgr %[R_INLEN],%[R_I]\n\t" \ + /* Handle multibyte utf8-char with convert instruction. */ \ + "20: cu41 %[R_OUT],%[R_IN]\n\t" \ + " jo 0b\n\t" /* Try vector implemenation again. */ \ + " lochil %[R_RES],%[RES_OUT_FULL]\n\t" /* cc == 1. */ \ + " lochih %[R_RES],%[RES_IN_ILL]\n\t" /* cc == 2. */ \ + ".machine pop" \ + : /* outputs */ [R_IN] "+a" (pInput) \ + , [R_INLEN] "+d" (inlen), [R_OUT] "+a" (pOutput) \ + , [R_OUTLEN] "+d" (outlen), [R_TMP] "=d" (tmp) \ + , [R_I] "=a" (tmp2) \ + , [R_RES] "+d" (result) \ + : /* inputs */ \ + [RES_OUT_FULL] "i" (__GCONV_FULL_OUTPUT) \ + , [RES_IN_ILL] "i" (__GCONV_ILLEGAL_INPUT) \ + : /* clobber list */ "memory", "cc" \ + ASM_CLOBBER_VR ("v16") ASM_CLOBBER_VR ("v17") \ + ASM_CLOBBER_VR ("v18") ASM_CLOBBER_VR ("v19") \ + ASM_CLOBBER_VR ("v20") ASM_CLOBBER_VR ("v21") \ + ASM_CLOBBER_VR ("v22") ASM_CLOBBER_VR ("v23") \ + ASM_CLOBBER_VR ("v24") \ + ); \ + inptr = pInput; \ + outptr = pOutput; \ + \ + if (__glibc_likely (inptr == inend) \ + || result == __GCONV_FULL_OUTPUT) \ + break; \ + if (inptr + 4 > inend) \ + { \ + result = __GCONV_INCOMPLETE_INPUT; \ + break; \ + } \ + STANDARD_TO_LOOP_ERR_HANDLER (4); \ + } + +/* Generate loop-function with hardware vector and utf-convert instructions. */ +# define MIN_NEEDED_INPUT MIN_NEEDED_TO +# define MIN_NEEDED_OUTPUT MIN_NEEDED_FROM +# define MAX_NEEDED_OUTPUT MAX_NEEDED_FROM +# define TO_LOOP_VX_CU __to_utf8_loop_vx_cu +# define LOOPFCT TO_LOOP_VX_CU +# define BODY BODY_TO_VX_CU +# define LOOP_NEED_FLAGS +# include <iconv/loop.c> +#else +# define TO_LOOP_VX_CU NULL +#endif /* HAVE_TO_VX_CU != 1 */ + +/* This file also exists in sysdeps/s390/multiarch/ which + generates ifunc resolvers for FROM/TO_LOOP functions + and includes iconv/skeleton.c afterwards. */ +#if ! defined USE_MULTIARCH +# include <iconv/skeleton.c> +#endif |