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