stdlib: Simplify getenv
[glibc.git] / sysdeps / s390 / wcscmp-vx.S
blobc397eb0631661ade05032e8cc438ba3eefc301f0
1 /* Vector optimized 32/64 bit S/390 version of wcscmp.
2    Copyright (C) 2015-2023 Free Software Foundation, Inc.
3    This file is part of the GNU C Library.
5    The GNU C Library is free software; you can redistribute it and/or
6    modify it under the terms of the GNU Lesser General Public
7    License as published by the Free Software Foundation; either
8    version 2.1 of the License, or (at your option) any later version.
10    The GNU C Library is distributed in the hope that it will be useful,
11    but WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13    Lesser General Public License for more details.
15    You should have received a copy of the GNU Lesser General Public
16    License along with the GNU C Library; if not, see
17    <https://www.gnu.org/licenses/>.  */
19 #include <ifunc-wcscmp.h>
20 #if HAVE_WCSCMP_Z13
22 # include "sysdep.h"
23 # include "asm-syntax.h"
25         .text
27 /* int wcscmp (const wchar_t *s1, const wchar_t *s2)
28    Compare two strings
30    Register usage:
31    -r1=loaded byte count s1
32    -r2=s1
33    -r3=s2
34    -r4=loaded byte coutn s2, tmp
35    -r5=current_len
36    -v16=part of s1
37    -v17=part of s2
38    -v18=index of unequal
40 ENTRY(WCSCMP_Z13)
41         .machine "z13"
42         .machinemode "zarch_nohighgprs"
44         lghi    %r5,0           /* current_len = 0.  */
46 .Lloop:
47         vlbb    %v16,0(%r5,%r2),6 /* Load s1 to block boundary.  */
48         vlbb    %v17,0(%r5,%r3),6 /* Load s2 to block boundary.  */
49         lcbb    %r1,0(%r5,%r2),6 /* Get loaded byte count of s1.  */
50         jo      .Llt16_1        /* Jump away if vr is not fully loaded.  */
51         lcbb    %r4,0(%r5,%r3),6
52         jo      .Llt16_2        /* Jump away if vr is not fully loaded.  */
53         /* Both vrs are fully loaded.  */
54         aghi    %r5,16
55         vfenezfs %v18,%v16,%v17 /* Compare not equal with zero search.  */
56         jno     .Lfound
58         vlbb    %v16,0(%r5,%r2),6
59         vlbb    %v17,0(%r5,%r3),6
60         lcbb    %r1,0(%r5,%r2),6
61         jo      .Llt16_1
62         lcbb    %r4,0(%r5,%r3),6
63         jo      .Llt16_2
64         aghi    %r5,16
65         vfenezfs %v18,%v16,%v17
66         jno     .Lfound
68         vlbb    %v16,0(%r5,%r2),6
69         vlbb    %v17,0(%r5,%r3),6
70         lcbb    %r1,0(%r5,%r2),6
71         jo      .Llt16_1
72         lcbb    %r4,0(%r5,%r3),6
73         jo      .Llt16_2
74         aghi    %r5,16
75         vfenezfs %v18,%v16,%v17
76         jno     .Lfound
78         vlbb    %v16,0(%r5,%r2),6
79         vlbb    %v17,0(%r5,%r3),6
80         lcbb    %r1,0(%r5,%r2),6
81         jo      .Llt16_1
82         lcbb    %r4,0(%r5,%r3),6
83         jo      .Llt16_2
84         aghi    %r5,16
85         vfenezfs %v18,%v16,%v17
86         jno     .Lfound
87         j       .Lloop
89 .Lcmp_one_char:
90         /* At least one of both strings is not 4-byte aligned
91            and there is no full character before next block-boundary.
92            Compare one character to get over the boundary and
93            proceed with normal loop!  */
94         vlef    %v16,0(%r5,%r2),0 /* Load one character.  */
95         vlef    %v17,0(%r5,%r3),0
96         lghi    %r1,4           /* Loaded byte count is 4.  */
97         j       .Llt_cmp        /* Proceed with comparision.  */
99 .Llt16_1:
100         lcbb    %r4,0(%r5,%r3),6 /* Get loaded byte count of s2.  */
101 .Llt16_2:
102         clr     %r1,%r4
103         locrh   %r1,%r4         /* Get minimum of bytes loaded in s1/2.  */
104         nill    %r1,65532       /* Align bytes loaded to full characters.  */
105         jz      .Lcmp_one_char  /* Jump away if no full char is available.  */
106 .Llt_cmp:
107         algfr   %r5,%r1         /* Add smallest loaded bytes to current_len.  */
108         vfenezfs %v18,%v16,%v17 /* Compare not equal with zero search.  */
109         vlgvb   %r4,%v18,7      /* Get not equal index or 16 if all equal.  */
110         clrjl   %r4,%r1,.Lfound /* Jump away if miscompare is within loaded
111                                     bytes.  */
112         j       .Lloop
114 .Lfound:
115         /* vfenezf found an unequal element or zero.
116            This instruction compares unsigned words, but wchar_t is signed.
117            Thus we have to compare the found element again.  */
118         vlgvb   %r4,%v18,7      /* Extract not equal byte-index,  */
119         srl     %r4,2           /* Convert it to character-index.  */
120         vlgvf   %r3,%v16,0(%r4) /* Load character-values.  */
121         vlgvf   %r4,%v17,0(%r4)
122         cr      %r3,%r4
123         je      .Lend_equal
124         lghi    %r2,1
125         lghi    %r1,-1
126         locgrl  %r2,%r1
127         br      %r14
128 .Lend_equal:
129         lghi    %r2,0
130         br      %r14
131 END(WCSCMP_Z13)
133 # if ! HAVE_WCSCMP_IFUNC
134 strong_alias (WCSCMP_Z13, __wcscmp)
135 weak_alias (__wcscmp, wcscmp)
136 # endif
138 # if ! HAVE_WCSCMP_C && defined SHARED && IS_IN (libc)
139 strong_alias (WCSCMP_Z13, __GI___wcscmp)
140 # endif
141 #endif