]>
Commit | Line | Data |
---|---|---|
f0b264f1 | 1 | /* Optimized strcasecmp implementation for PowerPC64. |
f7a9f785 | 2 | Copyright (C) 2011-2016 Free Software Foundation, Inc. |
f0b264f1 AZ |
3 | This file is part of the GNU C Library. |
4 | ||
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. | |
9 | ||
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. | |
14 | ||
15 | You should have received a copy of the GNU Lesser General Public | |
59ba27a6 PE |
16 | License along with the GNU C Library; if not, see |
17 | <http://www.gnu.org/licenses/>. */ | |
f0b264f1 AZ |
18 | |
19 | #include <sysdep.h> | |
f0b264f1 AZ |
20 | #include <locale-defines.h> |
21 | ||
22 | /* int [r3] strcasecmp (const char *s1 [r3], const char *s2 [r4] ) | |
23 | ||
24 | or if defined USE_IN_EXTENDED_LOCALE_MODEL: | |
25 | ||
26 | int [r3] strcasecmp_l (const char *s1 [r3], const char *s2 [r4], | |
27 | __locale_t loc [r5]) */ | |
28 | ||
29 | #ifndef STRCMP | |
30 | # define __STRCMP __strcasecmp | |
31 | # define STRCMP strcasecmp | |
32 | #endif | |
33 | ||
2d67d91a | 34 | ENTRY (__STRCMP) |
83f5c32d | 35 | #ifndef USE_IN_EXTENDED_LOCALE_MODEL |
f0b264f1 | 36 | CALL_MCOUNT 2 |
83f5c32d AS |
37 | #else |
38 | CALL_MCOUNT 3 | |
39 | #endif | |
f0b264f1 AZ |
40 | |
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 */ | |
2ccdea26 AB |
45 | #define rCHAR1 r6 /* Byte read from 1st string */ |
46 | #define rCHAR2 r7 /* Byte read from 2nd string */ | |
f0b264f1 AZ |
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 */ | |
53 | ||
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 | |
66 | ||
67 | ||
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. */ | |
71 | ||
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 | |
2d67d91a | 123 | END (__STRCMP) |
f0b264f1 | 124 | |
2d67d91a | 125 | weak_alias (__STRCMP, STRCMP) |
f0b264f1 | 126 | libc_hidden_builtin_def (__STRCMP) |