1/*
2 *  (c) Copyright 1986 HEWLETT-PACKARD COMPANY
3 *
4 *  To anyone who acknowledges that this file is provided "AS IS"
5 *  without any express or implied warranty:
6 *      permission to use, copy, modify, and distribute this file
7 *  for any purpose is hereby granted without fee, provided that
8 *  the above copyright notice and this notice appears in all
9 *  copies, and that the name of Hewlett-Packard Company not be
10 *  used in advertising or publicity pertaining to distribution
11 *  of the software without specific, written prior permission.
12 *  Hewlett-Packard Company makes no representations about the
13 *  suitability of this software for any purpose.
14 */
15
16/* strcmp(s1, s2) */
17/* returns integer: < 0 iff s1 lexicographically less than s2 */
18/* 		    > 0 iff s1 lexicographically greater than s2 */
19/* 		    = 0 iff s1 lexicographically equal to s2 */
20/*  		    = 0 iff s1 lexicographically equal to s2 */
21/*		    quit after n charachters */
22#include <picolibc.h>
23
24#include "DEFS.h"
25
26#define s1   	  26
27#define s2  	  25
28#define tmp1	  19
29#define s2word    20
30#define tmp3      21
31#define tmp7      22
32#define s1word	  29
33#define save	   1
34#define tmp6	  23
35#define tmp5	  28
36#define count	  24
37
38ENTRY(strncmp)
39	combt,<,n	r0,count,search	/* N <= 0 yields equality */
40	bv	r0(rp)			/* */
41	copy	0,ret0			/* return 0 (DELAY SLOT) */
42search:	combf,=,n 	s1,s2,findout 	/* s1 != s2? */
43	bv	r0(rp)			/* */
44        copy 	0,ret0			/* return 0 (delay slot) 	 */
45findout:
46        comibf,=,n 	0,s1,checks1	/* s1 == NULL? 	 */
47	ldbs	0(0,s2),ret0		/* */
48	bv	r0(rp)			/* */
49	subi	0,ret0,ret0		/* ret0 <- -*s2 */
50checks1:
51        comibf,=,n 	0,s2,checkitout	/* s2 == NULL? 	 */
52	bv	r0(rp)			/* */
53        ldbs 	0(0,s1),28 		/* return *s1 */
54
55checkitout:
56        extru	s2,31,2,tmp1		/* Extract the low two bits of the s2. */
57        extru	s1,31,2,tmp5		/* Extract the low two bits of the s1 */
58        sub,=	tmp5,tmp1,tmp3		/* Are s1 & s2 aligned with each other? */
59	b	not_aligned		/* It's more complicated (not_aligned) */
60	dep	0,31,2,s1		/* Compute word address of s1 (DELAY SLOT) */
61	dep	0,31,2,s2		/* Compute word address of s2 */
62	ldwm	4(0,s1),s1word		/* get next s1 word  s1+=4 */
63	combt,=	tmp5,r0,skipmask	/* skip masking, if we can */
64	ldwm	4(0,s2),s2word		/* get next s2 word  s2+=4 (DELAY SLOT) */
65	add	tmp5,count,count	/* bump count by the number of bytes */
66					/*  we are going to mask */
67	sh3add	tmp5,r0,save		/* save now has number of bits to mask */
68	mtctl	save,11
69	zvdepi	-2,32,save		/* load save with proper mask */
70	or	save,s1word,s1word	/* mask s1word (s1) */
71	or	save,s2word,s2word	/* mask s2word (s2) */
72
73
74skipmask:
75	combt,=,n	s1word,s2word,chknulls	/* are these words equal? */
76
77checkbyte:
78	extru	s1word,7,8,tmp3		/* get first byte (character) */
79ckbyte2:	extru	s2word,7,8,tmp7		/* get first byte (character) */
80	combf,=	tmp3,tmp7,done		/* quit if first byte is not equal */
81	sub	tmp3,tmp7,ret0		/* return difference (delay slot) */
82	comibt,=,n	0,tmp3,done	/* have we reached the end of string */
83					/* if so done ret0 already has zero */
84	addibt,<=,n	-1,count,done	/* have we checked N chars? ret0 == 0 */
85	extru	s1word,15,8,tmp3	/* get second byte (character) */
86	extru	s2word,15,8,tmp7	/* get second byte (character)	 */
87	combf,=	tmp3,tmp7,done		/* quit if second byte is not equal */
88	sub	tmp3,tmp7,ret0		/* return difference (delay slot) */
89	comibt,=,n	0,tmp3,done	/* have we reached the end of string */
90					/* if so done ret0 already has zero */
91	addibt,<=,n	-1,count,done	/* have we checked N chars? */
92	extru	s1word,23,8,tmp3	/* get third byte (character) */
93	extru	s2word,23,8,tmp7	/* get third byte (character)	 */
94	combf,=	tmp3,tmp7,done		/* done if third byte is not equal */
95	sub	tmp3,tmp7,ret0		/* return difference (delay slot) */
96	comibt,=,n	0,tmp3,done	/* have we reached the end of string */
97					/* if so done ret0 already has zero */
98	addibt,<=,n	-1,count,done	/* have we checked N chars? */
99	extru	s1word,31,8,tmp3	/* get last byte (character) */
100	extru	s2word,31,8,tmp7	/* get last byte (character)	 */
101	bv	r0(rp)			/* */
102	sub	tmp3,tmp7,ret0		/*  the last characters in the word is */
103					/*   where the  difference is, so return */
104					/*    the difference and we're outta here */
105
106
107chknulls:
108	addibt,<=,n	-4,count,zero	/* have we checked N chars? */
109	uxor,nbz	s1word,0,0	/* don't have to check s2   Just quit */
110	bv	r0(rp)			/* */
111	copy	0,28			/* return 0 */
112	ldwm	4(0,s2),s2word		/* get next s2 word  s2+=4 */
113	b	skipmask		/* keep checking */
114	ldwm	4(0,s1),s1word		/* get next s1 word  s1+=4 */
115
116
117not_aligned:
118	dep	r0,31,2,s2		/* Compute word address of s2 */
119	combt,<,n	r0,tmp3,shifts1	/* Do we shift s1 or s2 */
120	sh3add	tmp3,r0,tmp3		/* eight bits per byte so mul by 8 */
121	ldwm	4(0,s1),s1word		/* get first word of s1 */
122	ldwm	4(0,s2),s2word		/* get first word or s2 */
123	combt,=,n	r0,tmp5,masks2	/* Do we need to mask beginning of s1 */
124	add	tmp5,count,count	/* bump count by the number of bytes */
125					/*  we are going to mask */
126	sh3add	tmp5,r0,save		/* save now has number of bits to mask */
127	mtctl	save,11
128	zvdepi	-2,32,save		/* load save with proper mask */
129	or	save,s1word,s1word	/* */
130masks2:	sh3add	tmp1,r0,save		/* save now has number of bits to mask */
131	mtctl	save,11
132	zvdepi	-2,32,save		/* load save with proper mask */
133	or	save,s2word,s2word	/* */
134	mtctl	tmp3,11			/* Move shift amount to CR11 */
135more:	uxor,nbz	s2word,r0,r0		/* Is there a null in first word	 */
136	b,n	chunk1			/* */
137	ldwm	4(0,s2),tmp7		/* load second word to enable us to shift */
138	vshd	s2word,tmp7,s2word	/* */
139	combf,=,n	s1word,s2word,ckbyte2	/* */
140	extru	s1word,7,8,tmp3		/* get first byte (DELAY SLOT) */
141	addibt,<=,n	-4,count,zero	/* have we checked N chars? */
142	uxor,nbz	s1word,0,0	/* even though they're equal we could be done */
143	b,n	zero
144	copy	tmp7,s2word		/* */
145	b	more			/* keep checking */
146	ldwm	4(0,s1),s1word		/* get next s1 (DELAY SLOT) */
147
148chunk1:
149	vshd	s2word,r0,s2word	/* */
150	b	ckbyte2			/* */
151	extru	s1word,7,8,tmp3		/* */
152
153
154shifts1:
155	sh3add	tmp3,r0,tmp3		/* eight bits per byte so mul by 4 */
156	sub	r0,tmp3,tmp3		/* Get negative value for left shift */
157	ldwm	4(0,s2),s2word		/* get first word of s2 */
158	ldwm	4(0,s1),s1word		/* get first word or s1 */
159	combt,=,n	r0,tmp1,masks1	/* Do we need to mask beginning of s2 */
160	add	tmp1,count,count	/* bump count by the number of bytes */
161					/*  we are going to mask */
162	sh3add	tmp1,r0,save		/* save now has number of bits to mask */
163	mtctl	save,11
164	zvdepi	-2,32,save		/* load save with proper mask */
165	or	save,s2word,s2word	/* */
166masks1:	sh3add	tmp5,r0,save		/* save now has number of bits to mask */
167	mtctl	save,11
168	zvdepi	-2,32,save		/* load save with proper mask */
169	or	save,s1word,s1word	/* */
170	mtctl	tmp3,11			/* Move shift amount to CR11 */
171more1:	uxor,nbz	s1word,r0,r0		/* Is there a null in first byte	 */
172	b,n	chunk2			/* */
173	ldwm	4(0,s1),tmp7		/* load second word to enable us to shift */
174	vshd	s1word,tmp7,s1word	/* */
175	combf,=,n	s2word,s1word,ckbyte2	/* */
176	extru	s1word,7,8,tmp3		/* get first byte (DELAY SLOT) */
177	addibt,<=,n	-4,count,zero	/* have we checked N chars? */
178	uxor,nbz	s2word,0,0	/* even though they're equal we could be done */
179	b,n	zero			/* zero ret0 and quit */
180	copy	tmp7,s1word		/* */
181	b	more1			/* keep checking */
182	ldwm	4(0,s2),s2word		/* get next s2 (DELAY SLOT) */
183
184chunk2:
185	vshd	s1word,r0,s1word	/* */
186	b	ckbyte2			/* */
187	extru	s1word,7,8,tmp3		/* */
188
189zero:	copy 	r0,ret0
190done:
191EXIT(strncmp)
192