stdio-common: Add tests for formatted vsnprintf output specifiers
[glibc.git] / sysdeps / powerpc / powerpc32 / power7 / strcasecmp.S
blob1130bfd0c9692e14337bc2270ea88c8cd2b78f25
1 /* Optimized strcasecmp implementation for PowerPC32.
2    Copyright (C) 2011-2024 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 <sysdep.h>
20 #include <locale-defines.h>
22 /* int [r3] strcasecmp (const char *s1 [r3], const char *s2 [r4] )
24    or if defined USE_IN_EXTENDED_LOCALE_MODEL:
26    int [r3] strcasecmp_l (const char *s1 [r3], const char *s2 [r4],
27                           locale_t loc [r5]) */
29 #ifndef STRCMP
30 # define __STRCMP __strcasecmp
31 # define STRCMP   strcasecmp
32 #endif
34 ENTRY (__STRCMP)
36 #define rRTN    r3      /* Return value */
37 #define rSTR1   r5      /* 1st string */
38 #define rSTR2   r4      /* 2nd string */
39 #define rLOCARG r5      /* 3rd argument: locale_t */
40 #define rCHAR1  r6      /* Byte read from 1st string */
41 #define rCHAR2  r7      /* Byte read from 2nd string */
42 #define rADDR1  r8      /* Address of tolower(rCHAR1) */
43 #define rADDR2  r12     /* Address of tolower(rCHAR2) */
44 #define rLWR1   r8      /* Byte tolower(rCHAR1) */
45 #define rLWR2   r12     /* Byte tolower(rCHAR2) */
46 #define rTMP    r0
47 #define rGOT    r9      /* Address of the Global Offset Table */
48 #define rLOC    r11     /* Default locale address */
50         cmpw    cr7, r3, r4
51 #ifndef USE_IN_EXTENDED_LOCALE_MODEL
52 # ifdef SHARED
53         mflr    rTMP
54         bcl     20,31,.L1
55 .L1:    mflr    rGOT
56         addis   rGOT, rGOT, _GLOBAL_OFFSET_TABLE_-.L1@ha
57         addi    rGOT, rGOT, _GLOBAL_OFFSET_TABLE_-.L1@l
58         lwz     rLOC, __libc_tsd_LOCALE@got@tprel(rGOT)
59         add     rLOC, rLOC, __libc_tsd_LOCALE@tls
60         lwz     rLOC, 0(rLOC)
61         mtlr    rTMP
62 # else
63         lis     rTMP,_GLOBAL_OFFSET_TABLE_@ha
64         la      rLOC,_GLOBAL_OFFSET_TABLE_@l(rTMP)
65         lwz     rLOC, __libc_tsd_LOCALE@got@tprel(rGOT)
66         add     rLOC, rLOC, __libc_tsd_LOCALE@tls
67         lwz     rLOC, 0(rLOC)
68 # endif /* SHARED */
69 #else
70         mr      rLOC, rLOCARG
71 #endif
72         mr      rSTR1, rRTN
73         lwz     rLOC, LOCALE_CTYPE_TOLOWER(rLOC)
74         li      rRTN, 0
75         beqlr   cr7
77         /* Unrolling loop for POWER: loads are done with 'lbz' plus
78         offset and string descriptors are only updated in the end
79         of loop unrolling. */
81 L(loop):
82         lbz     rCHAR1, 0(rSTR1)        /* Load char from s1 */
83         lbz     rCHAR2, 0(rSTR2)        /* Load char from s2 */
84         sldi    rADDR1, rCHAR1, 2       /* Calculate address for tolower(*s1) */
85         sldi    rADDR2, rCHAR2, 2       /* Calculate address for tolower(*s2) */
86         lwzx    rLWR1, rLOC, rADDR1     /* Load tolower(*s1) */
87         lwzx    rLWR2, rLOC, rADDR2     /* Load tolower(*s2) */
88         cmpwi   cr7, rCHAR1, 0          /* *s1 == '\0' ? */
89         subf.   r3, rLWR2, rLWR1
90         bnelr
91         beqlr   cr7
92         lbz     rCHAR1, 1(rSTR1)
93         lbz     rCHAR2, 1(rSTR2)
94         sldi    rADDR1, rCHAR1, 2
95         sldi    rADDR2, rCHAR2, 2
96         lwzx    rLWR1, rLOC, rADDR1
97         lwzx    rLWR2, rLOC, rADDR2
98         cmpwi   cr7, rCHAR1, 0
99         subf.   r3, rLWR2, rLWR1
100         bnelr
101         beqlr   cr7
102         lbz     rCHAR1, 2(rSTR1)
103         lbz     rCHAR2, 2(rSTR2)
104         sldi    rADDR1, rCHAR1, 2
105         sldi    rADDR2, rCHAR2, 2
106         lwzx    rLWR1, rLOC, rADDR1
107         lwzx    rLWR2, rLOC, rADDR2
108         cmpwi   cr7, rCHAR1, 0
109         subf.   r3, rLWR2, rLWR1
110         bnelr
111         beqlr   cr7
112         lbz     rCHAR1, 3(rSTR1)
113         lbz     rCHAR2, 3(rSTR2)
114         /* Increment both string descriptors */
115         addi    rSTR1, rSTR1, 4
116         addi    rSTR2, rSTR2, 4
117         sldi    rADDR1, rCHAR1, 2
118         sldi    rADDR2, rCHAR2, 2
119         lwzx    rLWR1, rLOC, rADDR1
120         lwzx    rLWR2, rLOC, rADDR2
121         cmpwi   cr7, rCHAR1, 0
122         subf.   r3, rLWR2, rLWR1
123         bnelr
124         bne     cr7,L(loop)
125         blr
126 END (__STRCMP)
128 weak_alias (__STRCMP, STRCMP)
129 libc_hidden_builtin_def (__STRCMP)