aboutsummaryrefslogtreecommitdiff
blob: 52d73d9f893147724d15b86e9fa77aa846f63de7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
/* Optimized strcasecmp implementation for PowerPC32.
   Copyright (C) 2011-2013 Free Software Foundation, Inc.
   This file is part of the GNU C Library.

   The GNU C Library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Lesser General Public
   License as published by the Free Software Foundation; either
   version 2.1 of the License, or (at your option) any later version.

   The GNU C Library is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   Lesser General Public License for more details.

   You should have received a copy of the GNU Lesser General Public
   License along with the GNU C Library; if not, see
   <http://www.gnu.org/licenses/>.  */

#include <sysdep.h>
#include <bp-sym.h>
#include <bp-asm.h>
#include <locale-defines.h>

/* int [r3] strcasecmp (const char *s1 [r3], const char *s2 [r4] )

   or if defined USE_IN_EXTENDED_LOCALE_MODEL:

   int [r3] strcasecmp_l (const char *s1 [r3], const char *s2 [r4],
                          __locale_t loc [r5]) */

#ifndef STRCMP
# define __STRCMP __strcasecmp
# define STRCMP   strcasecmp
#endif

ENTRY (BP_SYM (__STRCMP))

#define rRTN	r3	/* Return value */
#define rSTR1	r5	/* 1st string */
#define rSTR2	r4	/* 2nd string */
#define rLOCARG	r5	/* 3rd argument: locale_t */
#define rCHAR1	r6	/* Byte read from 1st string */
#define rCHAR2	r7	/* Byte read from 2nd string */
#define rADDR1	r8	/* Address of tolower(rCHAR1) */
#define rADDR2	r12	/* Address of tolower(rCHAR2) */
#define rLWR1	r8	/* Byte tolower(rCHAR1) */
#define rLWR2	r12	/* Byte tolower(rCHAR2) */
#define rTMP	r0
#define rGOT	r9	/* Address of the Global Offset Table */
#define rLOC	r11	/* Default locale address */

	cmpw    cr7, r3, r4
#ifndef USE_IN_EXTENDED_LOCALE_MODEL
# ifdef SHARED
	mflr	rTMP
	bcl	20,31,.L1
.L1:	mflr	rGOT
	addis	rGOT, rGOT, _GLOBAL_OFFSET_TABLE_-.L1@ha
	addi 	rGOT, rGOT, _GLOBAL_OFFSET_TABLE_-.L1@l
	lwz	rLOC, __libc_tsd_LOCALE@got@tprel(rGOT)
	add 	rLOC, rLOC, __libc_tsd_LOCALE@tls
	lwz	rLOC, 0(rLOC)
	mtlr	rTMP
# else
	lis	rTMP,_GLOBAL_OFFSET_TABLE_@ha
	la	rLOC,_GLOBAL_OFFSET_TABLE_@l(rTMP)
	lwz	rLOC, __libc_tsd_LOCALE@got@tprel(rGOT)
	add	rLOC, rLOC, __libc_tsd_LOCALE@tls
	lwz	rLOC, 0(rLOC)
# endif /* SHARED */
#else
	mr	rLOC, rLOCARG
#endif
	mr	rSTR1, rRTN
	lwz	rLOC, LOCALE_CTYPE_TOLOWER(rLOC)
	li	rRTN, 0
	beqlr	cr7

	/* Unrolling loop for POWER: loads are done with 'lbz' plus
	offset and string descriptors are only updated in the end
	of loop unrolling. */

L(loop):
	lbz	rCHAR1, 0(rSTR1)	/* Load char from s1 */
	lbz	rCHAR2, 0(rSTR2)	/* Load char from s2 */
	sldi	rADDR1, rCHAR1, 2	/* Calculate address for tolower(*s1) */
	sldi	rADDR2, rCHAR2, 2	/* Calculate address for tolower(*s2) */
	lwzx	rLWR1, rLOC, rADDR1	/* Load tolower(*s1) */
	lwzx	rLWR2, rLOC, rADDR2	/* Load tolower(*s2) */
	cmpwi	cr7, rCHAR1, 0		/* *s1 == '\0' ? */
	subf.	r3, rLWR2, rLWR1
	bnelr
	beqlr	cr7
	lbz	rCHAR1, 1(rSTR1)
	lbz	rCHAR2, 1(rSTR2)
	sldi	rADDR1, rCHAR1, 2
	sldi	rADDR2, rCHAR2, 2
	lwzx	rLWR1, rLOC, rADDR1
	lwzx	rLWR2, rLOC, rADDR2
	cmpwi	cr7, rCHAR1, 0
	subf.	r3, rLWR2, rLWR1
	bnelr
	beqlr	cr7
	lbz	rCHAR1, 2(rSTR1)
	lbz	rCHAR2, 2(rSTR2)
	sldi	rADDR1, rCHAR1, 2
	sldi	rADDR2, rCHAR2, 2
	lwzx	rLWR1, rLOC, rADDR1
	lwzx	rLWR2, rLOC, rADDR2
	cmpwi	cr7, rCHAR1, 0
	subf.	r3, rLWR2, rLWR1
	bnelr
	beqlr	cr7
	lbz	rCHAR1, 3(rSTR1)
	lbz	rCHAR2, 3(rSTR2)
	/* Increment both string descriptors */
	addi	rSTR1, rSTR1, 4
	addi	rSTR2, rSTR2, 4
	sldi	rADDR1, rCHAR1, 2
	sldi	rADDR2, rCHAR2, 2
	lwzx	rLWR1, rLOC, rADDR1
	lwzx	rLWR2, rLOC, rADDR2
	cmpwi	cr7, rCHAR1, 0
	subf.	r3, rLWR2, rLWR1
	bnelr
	bne	cr7,L(loop)
	blr
END (BP_SYM (__STRCMP))

weak_alias (BP_SYM (__STRCMP), BP_SYM (STRCMP))
libc_hidden_builtin_def (__STRCMP)