]>
Commit | Line | Data |
---|---|---|
f0b264f1 AZ |
1 | /* Optimized strcasecmp implementation for PowerPC32. |
2 | Copyright (C) 2011 Free Software Foundation, Inc. | |
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> | |
20 | #include <bp-sym.h> | |
21 | #include <bp-asm.h> | |
22 | #include <locale-defines.h> | |
23 | ||
24 | /* int [r3] strcasecmp (const char *s1 [r3], const char *s2 [r4] ) | |
25 | ||
26 | or if defined USE_IN_EXTENDED_LOCALE_MODEL: | |
27 | ||
28 | int [r3] strcasecmp_l (const char *s1 [r3], const char *s2 [r4], | |
29 | __locale_t loc [r5]) */ | |
30 | ||
31 | #ifndef STRCMP | |
32 | # define __STRCMP __strcasecmp | |
33 | # define STRCMP strcasecmp | |
34 | #endif | |
35 | ||
36 | ENTRY (BP_SYM (__STRCMP)) | |
37 | ||
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 */ | |
51 | ||
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 | |
78 | ||
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. */ | |
82 | ||
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)) | |
129 | ||
130 | weak_alias (BP_SYM (__STRCMP), BP_SYM (STRCMP)) | |
131 | libc_hidden_builtin_def (__STRCMP) |