powerpc: refactor strchr, strchrnul, and strrchr IFUNC.
[glibc.git] / sysdeps / powerpc / powerpc64 / power7 / strcasecmp.S
blobe856b8a5930f4590571f0688150c3ff073d2bac7
1 /* Optimized strcasecmp implementation for PowerPC64.
2    Copyright (C) 2011-2017 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    <http://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)
35 #ifndef USE_IN_EXTENDED_LOCALE_MODEL
36         CALL_MCOUNT 2
37 #else
38         CALL_MCOUNT 3
39 #endif
41 #define rRTN    r3      /* Return value */
42 #define rSTR1   r5      /* 1st string */
43 #define rSTR2   r4      /* 2nd string */
44 #define rLOCARG r5      /* 3rd argument: locale_t */
45 #define rCHAR1  r6      /* Byte read from 1st string */
46 #define rCHAR2  r7      /* Byte read from 2nd string */
47 #define rADDR1  r8      /* Address of tolower(rCHAR1) */
48 #define rADDR2  r12     /* Address of tolower(rCHAR2) */
49 #define rLWR1   r8      /* Word tolower(rCHAR1) */
50 #define rLWR2   r12     /* Word tolower(rCHAR2) */
51 #define rTMP    r9
52 #define rLOC    r11     /* Default locale address */
54         cmpd    cr7, r3, r4
55 #ifndef USE_IN_EXTENDED_LOCALE_MODEL
56         ld      rTMP, __libc_tsd_LOCALE@got@tprel(r2)
57         add     rLOC, rTMP, __libc_tsd_LOCALE@tls
58         ld      rLOC, 0(rLOC)
59 #else
60         mr      rLOC, rLOCARG
61 #endif
62         ld      rLOC, LOCALE_CTYPE_TOLOWER(rLOC)
63         mr      rSTR1, rRTN
64         li      rRTN, 0
65         beqlr   cr7
68         /* Unrolling loop for POWER: loads are done with 'lbz' plus
69         offset and string descriptors are only updated in the end
70         of loop unrolling. */
72         lbz     rCHAR1, 0(rSTR1)        /* Load char from s1 */
73         lbz     rCHAR2, 0(rSTR2)        /* Load char from s2 */
74 L(loop):
75         cmpdi   rCHAR1, 0               /* *s1 == '\0' ? */
76         sldi    rADDR1, rCHAR1, 2       /* Calculate address for tolower(*s1) */
77         sldi    rADDR2, rCHAR2, 2       /* Calculate address for tolower(*s2) */
78         lwzx    rLWR1, rLOC, rADDR1     /* Load tolower(*s1) */
79         lwzx    rLWR2, rLOC, rADDR2     /* Load tolower(*s2) */
80         cmpw    cr1, rLWR1, rLWR2       /* r = tolower(*s1) == tolower(*s2) ? */
81         crorc   4*cr1+eq,eq,4*cr1+eq    /* (*s1 != '\0') || (r == 1) */
82         beq     cr1, L(done)
83         lbz     rCHAR1, 1(rSTR1)
84         lbz     rCHAR2, 1(rSTR2)
85         cmpdi   rCHAR1, 0
86         sldi    rADDR1, rCHAR1, 2
87         sldi    rADDR2, rCHAR2, 2
88         lwzx    rLWR1, rLOC, rADDR1
89         lwzx    rLWR2, rLOC, rADDR2
90         cmpw    cr1, rLWR1, rLWR2
91         crorc   4*cr1+eq,eq,4*cr1+eq
92         beq     cr1, L(done)
93         lbz     rCHAR1, 2(rSTR1)
94         lbz     rCHAR2, 2(rSTR2)
95         cmpdi   rCHAR1, 0
96         sldi    rADDR1, rCHAR1, 2
97         sldi    rADDR2, rCHAR2, 2
98         lwzx    rLWR1, rLOC, rADDR1
99         lwzx    rLWR2, rLOC, rADDR2
100         cmpw    cr1, rLWR1, rLWR2
101         crorc   4*cr1+eq,eq,4*cr1+eq
102         beq     cr1, L(done)
103         lbz     rCHAR1, 3(rSTR1)
104         lbz     rCHAR2, 3(rSTR2)
105         cmpdi   rCHAR1, 0
106         /* Increment both string descriptors */
107         addi    rSTR1, rSTR1, 4
108         addi    rSTR2, rSTR2, 4
109         sldi    rADDR1, rCHAR1, 2
110         sldi    rADDR2, rCHAR2, 2
111         lwzx    rLWR1, rLOC, rADDR1
112         lwzx    rLWR2, rLOC, rADDR2
113         cmpw    cr1, rLWR1, rLWR2
114         crorc   4*cr1+eq,eq,4*cr1+eq
115         beq     cr1,L(done)
116         lbz     rCHAR1, 0(rSTR1)        /* Load char from s1 */
117         lbz     rCHAR2, 0(rSTR2)        /* Load char from s2 */
118         b       L(loop)
119 L(done):
120         subf    r0, rLWR2, rLWR1
121         extsw   rRTN, r0
122         blr
123 END (__STRCMP)
125 weak_alias (__STRCMP, STRCMP)
126 libc_hidden_builtin_def (__STRCMP)