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