Welcome to mirror list, hosted at ThFree Co, Russian Federation.

strcmp.S « hppa « machine « libc « newlib - cygwin.com/git/newlib-cygwin.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: 007a648492d0e0f08d2e6b886c244d50418132bf (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
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
/*
 *  (c) Copyright 1986 HEWLETT-PACKARD COMPANY
 *
 *  To anyone who acknowledges that this file is provided "AS IS"
 *  without any express or implied warranty:
 *      permission to use, copy, modify, and distribute this file
 *  for any purpose is hereby granted without fee, provided that
 *  the above copyright notice and this notice appears in all
 *  copies, and that the name of Hewlett-Packard Company not be
 *  used in advertising or publicity pertaining to distribution
 *  of the software without specific, written prior permission.
 *  Hewlett-Packard Company makes no representations about the
 *  suitability of this software for any purpose.
 */

/*

	strcmp

	Jerry Huck
	Edgar Circenis

*/
/* 
 * strcmp(s1, s2)
 *
 * returns integer: < 0 iff s1 lexicographically less than s2
 * 		    > 0 iff s1 lexicographically greater than s2
 * 		    = 0 iff s1 lexicographically equal to s2
 */

#include "DEFS.h"

#define s1	 26
#define s2	 25
#define tmp1     19
#define s2word   20
#define tmp3     21
#define tmp7     22
#define s1word	 23
#define save	  1
#define tmp6	 24
#define tmp5	 28

ENTRY(strcmp)
	comb,=,n   s1,s2,samestring
	comib,=,n  0,s1,s1isnull
        comib,=,n  0,s2,s2isnull
/* Hope for word alignment.  Pick up low two bits of each adress */
        extru,<>   s1,31,2,tmp1
        ldwm       4(s1),s1word
        dep,=      s2,29,2,tmp1
        b,n        case_analysis

/* Start looping until null is found in s1 or they mis-compare */
loop:
        ldwm       4(s2),s2word
loop_plus:
        uxor,nbz   s1word,r0,r0   /* Null in this? */
        b,n        nullins1
        comb,=,n   s1word,s2word,loop
        ldwm       4(s1),s1word

/* The words do not compare equal and s1 does not have a null.
   Need to treat words as unsigned and generate either a positive
   or negative return value */
wordcomparereturn:
        comclr,>>  s1word,s2word,ret0    /*Set ret0 to 0 and skip if greater*/
        ldi        -2,ret0           /*Set ret0 to -2 when less */
        bv         r0(rp)
        addi       1,ret0,ret0           /*Fix return value to be -1 or +1 */

/* s1 has a null.  s2 has not been checked. */
nullins1:
        /*If s2 has no nulls this is simple, but assume that it might
          and fix up s1 to allow the word comparision to work by
          scanning s1 and duplicating all the bytes in s2 below that byte into
          the remainder of s1.  A remainder only exists if the zero byte
          is found in the upper three bytes */
        extru,<>   s1word,7,8,r0         /*in the first byte? */
        dep,tr     s2word,31,24,s1word   /*copy low 3 bytes of *s2 into *s1 */
        extru,<>   s1word,15,8,r0         /*in the second byte? */
        dep,tr     s2word,31,16,s1word   /*copy low 2 bytes of *s2 into *s1 */
        extru,<>   s1word,23,8,r0         /*in the third byte? */
        dep        s2word,31,8,s1word   /*copy low 1 byte of *s2 into *s1 */
        /* Do the normal unsigned compare and return */
        comclr,<>  s1word,s2word,ret0    /*Set ret0 to 0 and skip if not equal */
	bv,n	   r0(rp)
        comclr,>>  s1word,s2word,ret0    /*Set ret0 to 0 and skip if greater*/
        ldi        -2,ret0           /*Set ret0 to -2 when less */
        bv         r0(rp)
        addi       1,ret0,ret0           /*Fix return value to be -1 or +1 */

/* s1 and s2 are the same string and therefore equal */
samestring:
        bv      r0(rp)
        copy    r0,ret0
/* s1 is null.  Treat as string of nulls.  Therefore return
   the negative of s2's first byte.  s2 cannot be zero. */
s1isnull:
	ldbs	0(0,s2),ret0
        bv      r0(rp)
	sub	0,ret0,ret0
/* s2 is null.  Treat as string of nulls.  Therefore return 
   s1's first byte.  s1 cannot be zero. */
s2isnull:
        bv      r0(rp)
	ldbs	0(0,s1),ret0

case_analysis:
	blr	tmp1,r0
	nop

	/*
	   Case statement for non-aligned cases (we've already
	   checked the aligned case.
	   NOTE: for non-aligned cases, the absolute shift value
	   gets loaded into tmp3.
	*/

				/* S2 S1 */
	nop			/* 00 00 can't happen */
	nop
	b	shifts2		/* 00 01 */
	ldi	8,tmp3		/* load shift count (delay slot) */
	b	shifts2		/* 00 10 */
	ldi	16,tmp3		/* load shift count (delay slot) */
	b	shifts2		/* 00 11 */
	ldi	24,tmp3		/* load shift count (delay slot) */
	b	shifts1_0	/* 01 00 */
	ldi	8,tmp3		/* load shift count (delay slot) */
	b	eq_align1	/* 01 01 */
	ldbs,ma	1(s1),s1word
	b	shifts2		/* 01 10 */
	ldi	8,tmp3		/* load shift count (delay slot) */
	b	shifts2		/* 01 11 */
	ldi	16,tmp3		/* load shift count (delay slot) */
	b	shifts1_0	/* 10 00 */
	ldi	16,tmp3		/* load shift count (delay slot) */
	b	shifts1		/* 10 01 */
	ldi	8,tmp3		/* load shift count (delay slot) */
	b	eq_align2	/* 10 10 */
	ldhs,ma	2(s1),s1word
	b	shifts2		/* 10 11 */
	ldi	8,tmp3		/* load shift count (delay slot) */
	b	shifts1_0	/* 11 00 */
	ldi	24,tmp3		/* load shift count (delay slot) */
	b	shifts1		/* 11 01 */
	ldi	16,tmp3		/* load shift count (delay slot) */
	b	shifts1		/* 11 10 */
	ldi	8,tmp3		/* load shift count (delay slot) */
	ldbs,ma	1(s1),s1word	/* 11 11 */
	ldbs,ma 1(s2),s2word
	sub,=	s1word,s2word,ret0	/* if not equal, we can return now */
	bv,n	r0(rp)
	comclr,<>	s1word,r0,ret0
	bv,n	r0(rp)			
	b	loop			/* fall into main loop */
	ldwm	4(s1),s1word

eq_align1:
	ldbs,ma 1(s2),s2word
	sub,=	s1word,s2word,ret0	/* if not equal, we can return now */
	bv,n	r0(rp)
	comclr,<>	s1word,r0,ret0
	bv,n	r0(rp)			
	/* fall through to half-word aligned case */
	ldhs,ma	2(s1),s1word		/* load next halfword */
eq_align2:
	ldhs,ma	2(s2),s2word		/* load next halfword */
	/* form the mask: 0xffff0000 and mask leading nulls in s1word and s2word
	   so that we can fall into the main loop with word aligned data */
	ldi	16,save	
	mtctl	save,r11
	zvdepi	-2,32,save
	or	save,s1word,s1word
	b	loop_plus		/* fall into main loop */
	or	save,s2word,s2word

/* s2's alignment is greater than s1's alignment, so we will shift s1 */
shifts1_0:
	addi	-4,s1,s1		/* fix up s1 due to earlier read */
shifts1:
        extru   s1,31,2,tmp1
        extru   s2,31,2,tmp5
	dep	r0,31,2,s1		/* Compute word address of s1 */
	dep	r0,31,2,s2		/* Compute word address of s2 */
	ldwm	4(s1),s1word		/* get first word of s1 */
	ldwm	4(s2),s2word		/* get first word of s2 */
	combt,=,n	r0,tmp1,masks2	/* Do we need to mask beginning of s1 */
	sh3add	tmp1,r0,save		/* save now has number of bits to mask */
	mtctl	save,r11
	zvdepi	-2,32,save		/* load save with proper mask */
	or	save,s1word,s1word
masks2:
	sh3add	tmp5,r0,save		/* save now has number of bits to mask */
	mtctl	save,r11
	zvdepi	-2,32,save		/* load save with proper mask */
	or	save,s2word,s2word
	ldi	-1,tmp7			/* load tmp7 with 0xffffffff */
	mtctl	tmp3,r11		/* Move shift amount to CR11 */
more:	uxor,nbz	s1word,r0,r0	/* Is there a null in s1? */
	b	ends1
	vshd	tmp7,s1word,save
	combf,=,n	save,s2word,cmps1
	ldwm	4(s1),tmp7
	ldwm	4(s2),s2word
	uxor,nbz	tmp7,r0,r0	/* is there a null in s1? */
	b	ends1_0
	vshd	s1word,tmp7,save
	combf,=,n	save,s2word,cmps1
	ldwm	4(s1),s1word
	b	more
	ldwm	4(s2),s2word

cmps1:	movb,tr		save,s1word,wordcomparereturn
	nop

ends1_0:
	copy	tmp7,s1word			/* move tmp7 to s1word */
ends1:
	combf,=,n	save,s2word,nullins1	/* branch if no match */
	copy	save,s1word			/* delay slot */
/* At this point, we know that we've read a null */
/* from s1, so we can't read more from s1 */
	uxor,nbz	save,r0,r0		/* are the strings equal? */
	b,n	samestring
	vshd	s1word,r0,s1word
	b	nullins1
	ldwm	4(s2),s2word

/* s1's alignment is greater than s2's alignment, so we will shift s2 */
shifts2:
        extru   s1,31,2,tmp1
        extru   s2,31,2,tmp5
	dep	r0,31,2,s1		/* Compute word address of s1 */
	dep	r0,31,2,s2		/* Compute word address of s2 */
	ldwm	4(s2),s2word		/* get first word of s2 */
	ldwm	4(s1),s1word		/* get first word of s1 */
	combt,=,n	r0,tmp5,masks1	/* Do we need to mask beginning of s2 */
	sh3add	tmp5,r0,save		/* save now has number of bits to mask */
	mtctl	save,r11
	zvdepi	-2,32,save		/* load save with proper mask */
	or	save,s2word,s2word
masks1:
	sh3add	tmp1,r0,save		/* save now has number of bits to mask */
	mtctl	save,r11
	zvdepi	-2,32,save		/* load save with proper mask */
	or	save,s1word,s1word
	ldi	-1,tmp7			/* load tmp7 with 0xffffffff */
	mtctl	tmp3,r11		/* Move shift amount to CR11 */
more1:	uxor,nbz	s2word,r0,r0	/* is there a null in s2? */
	b	ends2
	vshd	tmp7,s2word,save
	combf,=,n	s1word,save,cmps2
	ldwm	4(s2),tmp7
	ldwm	4(s1),s1word
	uxor,nbz	tmp7,r0,r0	/* is there a null in s2? */
	b	ends2_0
	vshd	s2word,tmp7,save
	combf,=,n	s1word,save,cmps2
	ldwm	4(s2),s2word
	b	more1
	ldwm	4(s1),s1word

cmps2:	movb,tr		save,s2word,wordcomparereturn
	nop

ends2_0:
	copy	tmp7,s2word			/* move tmp7 to s2word */
ends2:
	combf,=,n	s1word,save,nullins1	/* branch if no match */
	copy	save,s2word			/* delay slot */
/* At this point, we know that we've read a null */
/* from s2, so we can't read more from s2 */
	uxor,nbz	save,r0,r0		/* are the strings equal? */
	b,n	samestring
	vshd	s2word,r0,s2word
	b	nullins1
	ldwm	4(s1),s1word

EXIT(strcmp)