Back to index

glibc  2.9
string.h
Go to the documentation of this file.
00001 /* Optimized, inlined string functions.  S/390 version.
00002    Copyright (C) 2000, 2001, 2007 Free Software Foundation, Inc.
00003    Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com).
00004    This file is part of the GNU C Library.
00005 
00006    The GNU C Library is free software; you can redistribute it and/or
00007    modify it under the terms of the GNU Lesser General Public
00008    License as published by the Free Software Foundation; either
00009    version 2.1 of the License, or (at your option) any later version.
00010 
00011    The GNU C Library is distributed in the hope that it will be useful,
00012    but WITHOUT ANY WARRANTY; without even the implied warranty of
00013    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014    Lesser General Public License for more details.
00015 
00016    You should have received a copy of the GNU Lesser General Public
00017    License along with the GNU C Library; if not, write to the Free
00018    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
00019    02111-1307 USA.  */
00020 
00021 #ifndef _STRING_H
00022 # error "Never use <bits/string.h> directly; include <string.h> instead."
00023 #endif
00024 
00025 /* The s390 processors can access unaligned multi-byte variables.  */
00026 #define _STRING_ARCH_unaligned     1
00027 
00028 /* We only provide optimizations if the user selects them and if
00029    GNU CC is used.  */
00030 #if !defined __NO_STRING_INLINES && defined __USE_STRING_INLINES \
00031     && defined __GNUC__ && __GNUC__ >= 2
00032 
00033 #ifndef __STRING_INLINE
00034 # ifndef __extern_inline
00035 #  define __STRING_INLINE inline
00036 # else
00037 #  define __STRING_INLINE __extern_inline
00038 # endif
00039 #endif
00040 
00041 #define _HAVE_STRING_ARCH_strlen 1
00042 #ifndef _FORCE_INLINES
00043 #define strlen(str) __strlen_g ((str))
00044 
00045 __STRING_INLINE size_t __strlen_g (__const char *) __asm__ ("strlen");
00046 
00047 __STRING_INLINE size_t
00048 __strlen_g (__const char *__str)
00049 {
00050     char *__ptr, *__tmp;
00051 
00052     __ptr = (char *) 0;
00053     __tmp = (char *) __str;
00054     __asm__ __volatile__ ("   la    0,0\n"
00055                        "0: srst  %0,%1\n"
00056                        "   jo    0b\n"
00057                        : "+&a" (__ptr), "+&a" (__tmp) : 
00058                        : "cc", "memory", "0" );
00059     return (size_t) (__ptr - __str);
00060 }
00061 #endif
00062 
00063 /* Copy SRC to DEST.  */
00064 #define _HAVE_STRING_ARCH_strcpy 1
00065 #ifndef _FORCE_INLINES
00066 #define strcpy(dest, src) __strcpy_g ((dest), (src))
00067 
00068 __STRING_INLINE char *__strcpy_g (char *, __const char *) __asm ("strcpy");
00069 
00070 __STRING_INLINE char *
00071 __strcpy_g (char *__dest, __const char *__src)
00072 {
00073     char *tmp = __dest;
00074 
00075     __asm__ __volatile__ ("   la    0,0\n"
00076                        "0: mvst  %0,%1\n"
00077                        "   jo    0b"
00078                        : "+&a" (__dest), "+&a" (__src) :
00079                        : "cc", "memory", "0" );
00080     return tmp;
00081 }
00082 #endif
00083 
00084 #define _HAVE_STRING_ARCH_strncpy 1
00085 #ifndef _FORCE_INLINES
00086 #define strncpy(dest, src, n) __strncpy_g ((dest), (src), (n))
00087 
00088 __STRING_INLINE char *__strncpy_g (char *, __const char *, size_t)
00089      __asm__ ("strncpy");
00090 
00091 __STRING_INLINE char *
00092 __strncpy_g (char *__dest, __const char *__src, size_t __n)
00093 {
00094     char *__ret = __dest;
00095     char *__ptr;
00096     size_t __diff;
00097 
00098     if (__n > 0) {
00099       __diff = (size_t) (__dest - __src);
00100       __ptr = (char *) __src;
00101       __asm__ __volatile__ ("   j     1f\n"
00102                             "0: la    %0,1(%0)\n"
00103                             "1: icm   0,1,0(%0)\n"
00104                             "   stc   0,0(%2,%0)\n"
00105                             "   jz    3f\n"
00106 #if defined(__s390x__)
00107                             "   brctg %1,0b\n"
00108 #else
00109                             "   brct  %1,0b\n"
00110 #endif
00111                             "   j     4f\n"
00112                             "2: la    %0,1(%0)\n"
00113                             "   stc   0,0(%2,%0)\n"
00114 #if defined(__s390x__)
00115                             "3: brctg %1,2b\n"
00116 #else
00117                             "3: brct  %1,2b\n"
00118 #endif
00119                             "4:"
00120                             : "+&a" (__ptr), "+&a" (__n) : "a" (__diff)
00121                             : "cc", "memory", "0" );
00122     }
00123     return __ret;
00124 }
00125 #endif
00126 
00127 /* Append SRC onto DEST.  */
00128 #define _HAVE_STRING_ARCH_strcat 1
00129 #ifndef _FORCE_INLINES
00130 #define strcat(dest, src) __strcat_g ((dest), (src))
00131 
00132 __STRING_INLINE char *__strcat_g (char *, __const char *) __asm__ ("strcat");
00133 
00134 __STRING_INLINE char *
00135 __strcat_g (char *__dest, __const char *__src)
00136 {
00137     char *__ret = __dest;
00138     char *__ptr, *__tmp;
00139 
00140     /* Move __ptr to the end of __dest.  */
00141     __ptr = (char *) 0;
00142     __tmp = __dest;
00143     __asm__ __volatile__ ("   la    0,0\n"
00144                        "0: srst  %0,%1\n"
00145                        "   jo    0b\n"
00146                        : "+&a" (__ptr), "+&a" (__tmp) :
00147                        : "cc", "0" );
00148 
00149     /* Now do the copy.  */
00150     __asm__ __volatile__ ("   la    0,0\n"
00151                        "0: mvst  %0,%1\n"
00152                        "   jo    0b"
00153                        : "+&a" (__ptr), "+&a" (__src) :
00154                        : "cc", "memory", "0" );
00155     return __ret;
00156 }
00157 #endif
00158 
00159 /* Append no more than N characters from SRC onto DEST.  */
00160 #define _HAVE_STRING_ARCH_strncat 1
00161 #ifndef _FORCE_INLINES
00162 #define strncat(dest, src, n) __strncat_g ((dest), (src), (n))
00163 
00164 __STRING_INLINE char *__strncat_g (char *, __const char *, size_t)
00165      __asm__ ("strncat");
00166 
00167 __STRING_INLINE char *
00168 __strncat_g (char *__dest, __const char *__src, size_t __n)
00169 {
00170     char *__ret = __dest;
00171     char *__ptr, *__tmp;
00172     size_t __diff;
00173 
00174     if (__n > 0) {
00175       /* Move __ptr to the end of __dest.  */
00176       __ptr = (char *) 0;
00177       __tmp = __dest;
00178       __asm__ __volatile__ ("   la    0,0\n"
00179                          "0: srst  %0,%1\n"
00180                        "   jo    0b\n"
00181                          : "+&a" (__ptr), "+&a" (__tmp) :
00182                          : "cc", "memory", "0" );
00183 
00184       __diff = (size_t) (__ptr - __src);
00185       __tmp = (char *) __src;
00186       __asm__ __volatile__ ("   j     1f\n"
00187                             "0: la    %0,1(%0)\n"
00188                             "1: icm   0,1,0(%0)\n"
00189                             "   stc   0,0(%2,%0)\n"
00190                             "   jz    2f\n"
00191 #if defined(__s390x__)
00192                             "   brctg %1,0b\n"
00193 #else
00194                             "   brct  %1,0b\n"
00195 #endif
00196                          "   slr   0,0\n"
00197                             "   stc   0,1(%2,%0)\n"
00198                          "2:"
00199                             : "+&a" (__tmp), "+&a" (__n) : "a" (__diff)
00200                             : "cc", "memory", "0" );
00201 
00202     }
00203     return __ret;
00204 }
00205 #endif
00206 
00207 /* Search N bytes of S for C.  */
00208 #define _HAVE_STRING_ARCH_memchr 1
00209 #ifndef _FORCE_INLINES
00210 __STRING_INLINE void *
00211 memchr (__const void *__str, int __c, size_t __n)
00212 {
00213     char *__ptr, *__tmp;
00214 
00215     __tmp = (char *) __str;
00216     __ptr = (char *) __tmp + __n;
00217     __asm__ __volatile__ ("   lhi   0,0xff\n"
00218                        "   nr    0,%2\n"
00219                        "0: srst  %0,%1\n"
00220                        "   jo    0b\n"
00221                           "   brc   13,1f\n"
00222                           "   la    %0,0\n"
00223                           "1:"
00224                        : "+&a" (__ptr), "+&a" (__tmp) : "d" (__c)
00225                        : "cc", "memory", "0" );
00226     return __ptr;
00227 }
00228 #endif
00229 
00230 /* Search N bytes of S for C.  */
00231 #define _HAVE_STRING_ARCH_memchr 1
00232 #ifndef _FORCE_INLINES
00233 __STRING_INLINE int
00234 strcmp (__const char *__s1, __const char *__s2)
00235 {
00236     char *__p1, *__p2;
00237     int __ret;
00238 
00239     __p1 = (char *) __s1;
00240     __p2 = (char *) __s2;
00241     __asm__ __volatile__ ("   slr   0,0\n"
00242                           "0: clst  %1,%2\n"
00243                        "   jo    0b\n"
00244                        "   ipm   %0\n"
00245                        "   srl   %0,28"
00246                        : "=d" (__ret), "+&a" (__p1), "+&a" (__p2) : 
00247                        : "cc", "memory", "0" );
00248     __ret = (__ret == 0) ? 0 : (__ret == 1) ? -1 : 1;
00249     return __ret;
00250 }
00251 #endif
00252 
00253 #endif /* Use string inlines && GNU CC.  */