1/*
2 * memcmp routine for Z8000
3 * Copyright (C) 2004 Christian Groessler <chris@groessler.org>
4 *
5 * Permission to use, copy, modify, and distribute this file
6 * for any purpose is hereby granted without fee, provided that
7 * the above copyright notice and this notice appears in all
8 * copies.
9 *
10 * This file is distributed WITHOUT ANY WARRANTY; without even the implied
11 * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12 */
13
14/* int memcmp(const void *b1, const void *b2, size_t length);
15 */
16
17#include <picolibc.h>
18
19	name	"memcmp.S"
20
21	.text
22	even
23global	_memcmp
24
25_memcmp:
26
27#ifdef __Z8001__
28	segm
29
30#ifdef __STD_CALL__
31	ldl	rr6,rr14(#4)
32	ldl	rr4,rr14(#8)
33	ldl	rr2,rr14(#12)
34#endif
35
36/* rr2  - length	(high word ignored)
37 * rr4  - b2
38 * rr6  - b1
39 */
40
41	clr	r1		/* initialize return value */
42	testl	rr2
43	jr	z,finish
44
45	bitb	rl7,#0		/* odd b1? */
46	jr	nz,testb2
47	bitb	rl5,#0		/* odd b2? */
48	jr	nz,odd_cmp	/* b1 even, b2 odd */
49	jr	t,even_cmp
50
51testb2:
52	bitb	rl5,#0
53	jr	z,odd_cmp	/* b2 even, b1 odd */
54
55	cpsib	@rr6,@rr4,r3,eq
56	jr	z,beq		/* bytes are the same */
57	jr	t,byte_diff
58
59beq:	jr	ov,finish	/* jump if r3 is zero now */
60
61/* compare words */
62even_cmp:
63	ld	r2,r3		/* remember length */
64	srl	r3,#1
65	jr	z,no_words
66
67	cpsir	@rr6,@rr4,r3,ne
68	jr	nz,no_words
69
70	dec	r7,#2
71	dec	r5,#2		/* point to different bytes */
72	ldk	r3,#2
73	jr	t,odd_cmp
74
75no_words:
76	bitb	rl2,#0		/* odd length? */
77	jr	z,finish
78
79	cpsib	@rr6,@rr4,r3,eq
80	jr	z,finish	/* last bytes are the same */
81	jr	t,byte_diff
82
83/* compare bytes */
84odd_cmp:
85	cpsirb	@rr6,@rr4,r3,ne
86	jr	nz,finish
87
88byte_diff:
89	dec	r7,#1
90	dec	r5,#1		/* point to different bytes */
91
92	ldb	rl1,@rr6
93	clr	r0
94	ldb	rl0,@rr4
95	sub	r1,r0
96
97finish:				/* set return value */
98#ifdef __STD_CALL__
99	ld	r7,r1
100#else
101	ld	r2,r1
102#endif
103
104
105#else		/* above Z8001, below Z8002 */
106
107
108	unsegm
109
110#ifdef __STD_CALL__
111	ld	r7,r15(#2)
112	ld	r6,r15(#4)
113	ld	r5,r15(#6)
114#endif
115
116/* r5  - length
117 * r6  - b2
118 * r7  - b1
119 */
120
121	clr	r1		/* initialize return value */
122	test	r5
123	jr	z,finish
124
125	bitb	rl7,#0		/* odd destination address? */
126	jr	nz,testb2
127	bitb	rl6,#0		/* odd source address? */
128	jr	nz,odd_cmp	/* b1 even, b2 odd */
129	jr	t,even_cmp
130
131testb2:
132	bitb	rl6,#0
133	jr	z,odd_cmp	/* b2 even, b1 odd */
134
135	cpsib	@r7,@r6,r5,eq
136	jr	z,beq		/* bytes are the same */
137	jr	t,byte_diff
138
139beq:	jr	ov,finish	/* jump if r3 is zero now */
140
141/* compare words */
142even_cmp:
143	ld	r4,r5		/* remember length */
144	srl	r5,#1
145	jr	z,no_words
146
147	cpsir	@r7,@r6,r5,ne
148	jr	nz,no_words
149
150	dec	r7,#2
151	dec	r6,#2		/* point to different bytes */
152	ldk	r5,#2
153	jr	t,odd_cmp
154
155no_words:
156	bitb	rl4,#0		/* odd length? */
157	jr	z,finish
158
159	cpsib	@r7,@r6,r4,eq
160	jr	z,finish	/* last bytes are the same */
161	jr	t,byte_diff
162
163/* compare bytes */
164odd_cmp:
165	cpsirb	@r7,@r6,r5,ne
166	jr	nz,finish
167
168byte_diff:
169	dec	r7,#1
170	dec	r6,#1		/* point to different bytes */
171
172	ldb	rl1,@r7
173	clr	r0
174	ldb	rl0,@r6
175	sub	r1,r0
176
177finish:
178#ifdef __STD_CALL__
179	ld	r7,r1
180#else
181	ld	r2,r1
182#endif
183
184#endif	/* Z8002 */
185
186	ret
187	.end
188