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/* memcmp(s1, s2, n) */
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#ifndef _NAMESPACE_CLEAN
25#define NOSECDEF   /* prevents _memcmp from becoming primary entry */
26#endif
27
28#include "DEFS.h"
29
30#define s1 26
31#define s2 25
32#define tmp1 19
33#define s2word 20
34#define tmp3 21
35#define tmp7 22
36#define s1word 29
37#define save 1
38#define tmp6 23
39#define tmp5 28
40#define count 24
41
42ENTRY(memcmp)
43	combt,<,n	r0,count,search	/*N <= 0 yields equality */
44	b	done			/**/
45	copy	0,ret0			/*return 0 (DELAY SLOT) */
46search:	combf,=,n 	s1,s2,findout 	/*s1 != s2? */
47        b	done
48        copy 	0,ret0			/*return 0 (delay slot) 	 */
49findout:
50        comibf,=,n 	0,s1,checks1	/*s1 == NULL? 	 */
51	ldbs	0(0,s2),ret0		/**/
52        b	done 			/*quit	 */
53	sub	0,ret0,ret0		/*ret0 <- -*s2 */
54checks1:
55        comibf,=,n 	0,s2,checkitout	/*s2 == NULL? 	 */
56        b	done 			/* quit	 */
57        ldbs 	0(0,s1),28 		/* return *s1 */
58
59checkitout:
60        extru	s2,31,2,tmp1		/* Extract the low two bits of the s2. */
61        extru	s1,31,2,tmp5		/* Extract the low two bits of the s1 */
62        sub,=	tmp5,tmp1,tmp3		/* Are s1 & s2 aligned with each other? */
63	b	not_aligned		/* It's more complicated (not_aligned) */
64	dep	0,31,2,s1		/* Compute word address of s1 (DELAY SLOT) */
65	dep	0,31,2,s2		/* Compute word address of s2 */
66	ldwm	4(0,s1),s1word		/* get next s1 word  s1+=4 */
67	combt,=	tmp5,r0,skipmask	/* skip masking, if we can */
68	ldwm	4(0,s2),s2word		/* get next s2 word  s2+=4 (DELAY SLOT) */
69	add	tmp5,count,count	/* bump count by the number of bytes */
70					/*  we are going to mask */
71	sh3add	tmp5,r0,save		/* save now has number of bits to mask */
72	mtctl	save,11
73	zvdepi	-2,32,save		/* load save with proper mask */
74	or	save,s1word,s1word	/* mask s1word (s1) */
75	or	save,s2word,s2word	/* mask s2word (s2) */
76
77
78skipmask:
79	combt,=,n	s1word,s2word,checkN	/* We may be done */
80
81checkbyte:
82	extru	s1word,7,8,tmp3		/* get first byte (character) */
83ckbyte2:	extru	s2word,7,8,tmp7		/* get first byte (character) */
84	combf,=	tmp3,tmp7,done		/* quit if first byte is not equal */
85	sub	tmp3,tmp7,ret0		/* return difference (delay slot) */
86	addibt,<=,n	-1,count,done	/* have we checked N chars? ret0 == 0 */
87	extru	s1word,15,8,tmp3	/* get second byte (character) */
88	extru	s2word,15,8,tmp7	/* get second byte (character)	 */
89	combf,=	tmp3,tmp7,done		/* quit if second byte is not equal */
90	sub	tmp3,tmp7,ret0		/* return difference (delay slot) */
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	addibt,<=,n	-1,count,done	/* have we checked N chars? */
97	extru	s1word,31,8,tmp3	/* get last byte (character) */
98	extru	s2word,31,8,tmp7	/* get last byte (character)	 */
99	b	done			/* if we reach this point we know that */
100	sub	tmp3,tmp7,ret0		/*  the last character in the word is */
101					/*   where the  difference is, so return */
102					/*    the difference and we're outta here */
103
104
105checkN:
106	addibt,<=,n	-4,count,zero	/* have we checked N chars? */
107	ldwm	4(0,s2),s2word		/* get next s2 word  s2+=4 */
108	b	skipmask		/* keep checking */
109	ldwm	4(0,s1),s1word		/* get next s1 word  s1+=4 */
110
111
112not_aligned:
113	dep	r0,31,2,s2		/* Compute word address of s2 */
114	combt,<,n	r0,tmp3,shifts1	/* Do we shift s1 or s2 */
115	sh3add	tmp3,r0,tmp3		/* eight bits per byte so mul by 8 */
116	ldwm	4(0,s1),s1word		/* get first word of s1 */
117	ldwm	4(0,s2),s2word		/* get first word or s2 */
118	combt,=,n	r0,tmp5,masks2	/* Do we need to mask beginning of s1 */
119	add	tmp5,count,count	/* bump count by the number of bytes */
120					/*  we are going to mask */
121	sh3add	tmp5,r0,save		/* save now has number of bits to mask */
122	mtctl	save,11
123	zvdepi	-2,32,save		/* load save with proper mask */
124	or	save,s1word,s1word	/**/
125masks2:	sh3add	tmp1,r0,save		/* save now has number of bits to mask */
126	mtctl	save,11
127	zvdepi	-2,32,save		/* load save with proper mask */
128	or	save,s2word,s2word	/**/
129	subi	4,tmp1,tmp1		/* tmp1 now has the number of byte that */
130					/* are valid in s2word before the vshd */
131	mtctl	tmp3,11			/* Move shift amount to CR11 */
132more:	combt,<=,n	count,tmp1,chunk1	/* Can we do the vshd? */
133	ldwm	4(0,s2),tmp7		/* load second word to enable us to shift */
134	vshd	s2word,tmp7,s2word	/**/
135	combf,=,n	s1word,s2word,ckbyte2	/**/
136	extru	s1word,7,8,tmp3		/* get first byte (DELAY SLOT) */
137	addibt,<=,n	-4,count,zero	/* have we checked N chars? */
138	copy	tmp7,s2word		/**/
139	b	more			/* keep checking */
140	ldwm	4(0,s1),s1word		/* get next s1 (DELAY SLOT) */
141
142chunk1:
143	vshd	s2word,r0,s2word	/* do an arithmetic shift left to position data */
144	b	ckbyte2			/**/
145	extru	s1word,7,8,tmp3		/**/
146
147
148shifts1:
149	sh3add	tmp3,r0,tmp3		/* eight bits per byte so mul by 8 */
150	sub	r0,tmp3,tmp3		/* Get negative value for left shift */
151	dep	r0,31,2,s2		/* Compute word address of s2 */
152	ldwm	4(0,s2),s2word		/* get first word of s2 */
153	ldwm	4(0,s1),s1word		/* get first word or s1 */
154	combt,=,n	r0,tmp1,masks1	/*Do we need to mask beginning of s2 */
155	add	tmp1,count,count	/*bump count by the number of bytes */
156					/* we are going to mask */
157	sh3add	tmp1,r0,save		/*save now has number of bits to mask */
158	mtctl	save,11
159	zvdepi	-2,32,save		/*load save with proper mask */
160	or	save,s2word,s2word	/**/
161masks1:	sh3add	tmp5,r0,save		/*save now has number of bits to mask */
162	mtctl	save,11
163	zvdepi	-2,32,save		/*load save with proper mask */
164	or	save,s1word,s1word	/**/
165	subi	4,tmp5,tmp5		/*tmp5 now has the number of byte that */
166					/*are valid in s1word before the vshd */
167	mtctl	tmp3,11			/*Move shift amount to CR11 */
168more1:	combt,<=,n	count,tmp5,chunk2	/*Can we do the vshd? */
169	ldwm	4(0,s1),tmp7		/*load second word to enable us to shift */
170	vshd	s1word,tmp7,s1word	/**/
171	combf,=,n	s2word,s1word,ckbyte2	/**/
172	extru	s1word,7,8,tmp3		/*get first byte (DELAY SLOT) */
173	addibt,<=,n	-4,count,zero	/*have we checked N chars? */
174	copy	tmp7,s1word		/**/
175	b	more1			/*keep checking */
176	ldwm	4(0,s2),s2word		/*get next s2 (DELAY SLOT) */
177
178chunk2:
179	vshd	s1word,r0,s1word	/**/
180	b	ckbyte2			/**/
181	extru	s1word,7,8,tmp3		/**/
182
183zero:	copy 	r0,ret0
184done:
185EXIT(memcmp)
186