1129202Scognet/*	$NetBSD: memcpy_xscale.S,v 1.1 2003/10/14 07:51:45 scw Exp $	*/
2129202Scognet
3129202Scognet/*
4129202Scognet * Copyright 2003 Wasabi Systems, Inc.
5129202Scognet * All rights reserved.
6129202Scognet *
7129202Scognet * Written by Steve C. Woodford for Wasabi Systems, Inc.
8129202Scognet *
9129202Scognet * Redistribution and use in source and binary forms, with or without
10129202Scognet * modification, are permitted provided that the following conditions
11129202Scognet * are met:
12129202Scognet * 1. Redistributions of source code must retain the above copyright
13129202Scognet *    notice, this list of conditions and the following disclaimer.
14129202Scognet * 2. Redistributions in binary form must reproduce the above copyright
15129202Scognet *    notice, this list of conditions and the following disclaimer in the
16129202Scognet *    documentation and/or other materials provided with the distribution.
17129202Scognet * 3. All advertising materials mentioning features or use of this software
18129202Scognet *    must display the following acknowledgement:
19129202Scognet *      This product includes software developed for the NetBSD Project by
20129202Scognet *      Wasabi Systems, Inc.
21129202Scognet * 4. The name of Wasabi Systems, Inc. may not be used to endorse
22129202Scognet *    or promote products derived from this software without specific prior
23129202Scognet *    written permission.
24129202Scognet *
25129202Scognet * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND
26129202Scognet * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
27129202Scognet * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
28129202Scognet * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL WASABI SYSTEMS, INC
29129202Scognet * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
30129202Scognet * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
31129202Scognet * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
32129202Scognet * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
33129202Scognet * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
34129202Scognet * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
35129202Scognet * POSSIBILITY OF SUCH DAMAGE.
36129202Scognet */
37129202Scognet
38129202Scognet#include <machine/asm.h>
39129202Scognet__FBSDID("$FreeBSD$");
40129202Scognet
41275256Sandrew.syntax	unified
42275256Sandrew
43129202Scognet/* LINTSTUB: Func: void *memcpy(void *dst, const void *src, size_t len) */
44129202ScognetENTRY(memcpy)
45129202Scognet	pld	[r1]
46129202Scognet	cmp	r2, #0x0c
47129202Scognet	ble	.Lmemcpy_short		/* <= 12 bytes */
48129202Scognet	mov	r3, r0			/* We must not clobber r0 */
49129202Scognet
50129202Scognet	/* Word-align the destination buffer */
51129202Scognet	ands	ip, r3, #0x03		/* Already word aligned? */
52129202Scognet	beq	.Lmemcpy_wordaligned	/* Yup */
53129202Scognet	cmp	ip, #0x02
54129202Scognet	ldrb	ip, [r1], #0x01
55129202Scognet	sub	r2, r2, #0x01
56129202Scognet	strb	ip, [r3], #0x01
57275256Sandrew	ldrble	ip, [r1], #0x01
58129202Scognet	suble	r2, r2, #0x01
59275256Sandrew	strble	ip, [r3], #0x01
60275256Sandrew	ldrblt	ip, [r1], #0x01
61129202Scognet	sublt	r2, r2, #0x01
62275256Sandrew	strblt	ip, [r3], #0x01
63129202Scognet
64129202Scognet	/* Destination buffer is now word aligned */
65129202Scognet.Lmemcpy_wordaligned:
66129202Scognet	ands	ip, r1, #0x03		/* Is src also word-aligned? */
67129202Scognet	bne	.Lmemcpy_bad_align	/* Nope. Things just got bad */
68129202Scognet
69129202Scognet	/* Quad-align the destination buffer */
70129202Scognet	tst	r3, #0x07		/* Already quad aligned? */
71129202Scognet	ldrne	ip, [r1], #0x04
72129202Scognet	stmfd	sp!, {r4-r9}		/* Free up some registers */
73129202Scognet	subne	r2, r2, #0x04
74129202Scognet	strne	ip, [r3], #0x04
75129202Scognet
76129202Scognet	/* Destination buffer quad aligned, source is at least word aligned */
77129202Scognet	subs	r2, r2, #0x80
78129202Scognet	blt	.Lmemcpy_w_lessthan128
79129202Scognet
80129202Scognet	/* Copy 128 bytes at a time */
81129202Scognet.Lmemcpy_w_loop128:
82129202Scognet	ldr	r4, [r1], #0x04		/* LD:00-03 */
83129202Scognet	ldr	r5, [r1], #0x04		/* LD:04-07 */
84129202Scognet	pld	[r1, #0x18]		/* Prefetch 0x20 */
85129202Scognet	ldr	r6, [r1], #0x04		/* LD:08-0b */
86129202Scognet	ldr	r7, [r1], #0x04		/* LD:0c-0f */
87129202Scognet	ldr	r8, [r1], #0x04		/* LD:10-13 */
88129202Scognet	ldr	r9, [r1], #0x04		/* LD:14-17 */
89129202Scognet	strd	r4, [r3], #0x08		/* ST:00-07 */
90129202Scognet	ldr	r4, [r1], #0x04		/* LD:18-1b */
91129202Scognet	ldr	r5, [r1], #0x04		/* LD:1c-1f */
92129202Scognet	strd	r6, [r3], #0x08		/* ST:08-0f */
93129202Scognet	ldr	r6, [r1], #0x04		/* LD:20-23 */
94129202Scognet	ldr	r7, [r1], #0x04		/* LD:24-27 */
95129202Scognet	pld	[r1, #0x18]		/* Prefetch 0x40 */
96129202Scognet	strd	r8, [r3], #0x08		/* ST:10-17 */
97129202Scognet	ldr	r8, [r1], #0x04		/* LD:28-2b */
98129202Scognet	ldr	r9, [r1], #0x04		/* LD:2c-2f */
99129202Scognet	strd	r4, [r3], #0x08		/* ST:18-1f */
100129202Scognet	ldr	r4, [r1], #0x04		/* LD:30-33 */
101129202Scognet	ldr	r5, [r1], #0x04		/* LD:34-37 */
102129202Scognet	strd	r6, [r3], #0x08		/* ST:20-27 */
103129202Scognet	ldr	r6, [r1], #0x04		/* LD:38-3b */
104129202Scognet	ldr	r7, [r1], #0x04		/* LD:3c-3f */
105129202Scognet	strd	r8, [r3], #0x08		/* ST:28-2f */
106129202Scognet	ldr	r8, [r1], #0x04		/* LD:40-43 */
107129202Scognet	ldr	r9, [r1], #0x04		/* LD:44-47 */
108129202Scognet	pld	[r1, #0x18]		/* Prefetch 0x60 */
109129202Scognet	strd	r4, [r3], #0x08		/* ST:30-37 */
110129202Scognet	ldr	r4, [r1], #0x04		/* LD:48-4b */
111129202Scognet	ldr	r5, [r1], #0x04		/* LD:4c-4f */
112129202Scognet	strd	r6, [r3], #0x08		/* ST:38-3f */
113129202Scognet	ldr	r6, [r1], #0x04		/* LD:50-53 */
114129202Scognet	ldr	r7, [r1], #0x04		/* LD:54-57 */
115129202Scognet	strd	r8, [r3], #0x08		/* ST:40-47 */
116129202Scognet	ldr	r8, [r1], #0x04		/* LD:58-5b */
117129202Scognet	ldr	r9, [r1], #0x04		/* LD:5c-5f */
118129202Scognet	strd	r4, [r3], #0x08		/* ST:48-4f */
119129202Scognet	ldr	r4, [r1], #0x04		/* LD:60-63 */
120129202Scognet	ldr	r5, [r1], #0x04		/* LD:64-67 */
121129202Scognet	pld	[r1, #0x18]		/* Prefetch 0x80 */
122129202Scognet	strd	r6, [r3], #0x08		/* ST:50-57 */
123129202Scognet	ldr	r6, [r1], #0x04		/* LD:68-6b */
124129202Scognet	ldr	r7, [r1], #0x04		/* LD:6c-6f */
125129202Scognet	strd	r8, [r3], #0x08		/* ST:58-5f */
126129202Scognet	ldr	r8, [r1], #0x04		/* LD:70-73 */
127129202Scognet	ldr	r9, [r1], #0x04		/* LD:74-77 */
128129202Scognet	strd	r4, [r3], #0x08		/* ST:60-67 */
129129202Scognet	ldr	r4, [r1], #0x04		/* LD:78-7b */
130129202Scognet	ldr	r5, [r1], #0x04		/* LD:7c-7f */
131129202Scognet	strd	r6, [r3], #0x08		/* ST:68-6f */
132129202Scognet	strd	r8, [r3], #0x08		/* ST:70-77 */
133129202Scognet	subs	r2, r2, #0x80
134129202Scognet	strd	r4, [r3], #0x08		/* ST:78-7f */
135129202Scognet	bge	.Lmemcpy_w_loop128
136129202Scognet
137129202Scognet.Lmemcpy_w_lessthan128:
138129202Scognet	adds	r2, r2, #0x80		/* Adjust for extra sub */
139275256Sandrew	ldmfdeq	sp!, {r4-r9}
140135683Scognet	bxeq	lr			/* Return now if done */
141129202Scognet	subs	r2, r2, #0x20
142129202Scognet	blt	.Lmemcpy_w_lessthan32
143129202Scognet
144129202Scognet	/* Copy 32 bytes at a time */
145129202Scognet.Lmemcpy_w_loop32:
146129202Scognet	ldr	r4, [r1], #0x04
147129202Scognet	ldr	r5, [r1], #0x04
148129202Scognet	pld	[r1, #0x18]
149129202Scognet	ldr	r6, [r1], #0x04
150129202Scognet	ldr	r7, [r1], #0x04
151129202Scognet	ldr	r8, [r1], #0x04
152129202Scognet	ldr	r9, [r1], #0x04
153129202Scognet	strd	r4, [r3], #0x08
154129202Scognet	ldr	r4, [r1], #0x04
155129202Scognet	ldr	r5, [r1], #0x04
156129202Scognet	strd	r6, [r3], #0x08
157129202Scognet	strd	r8, [r3], #0x08
158129202Scognet	subs	r2, r2, #0x20
159129202Scognet	strd	r4, [r3], #0x08
160129202Scognet	bge	.Lmemcpy_w_loop32
161129202Scognet
162129202Scognet.Lmemcpy_w_lessthan32:
163129202Scognet	adds	r2, r2, #0x20		/* Adjust for extra sub */
164275256Sandrew	ldmfdeq	sp!, {r4-r9}
165135683Scognet	bxeq	lr			/* Return now if done */
166129202Scognet
167129202Scognet	and	r4, r2, #0x18
168129202Scognet	rsbs	r4, r4, #0x18
169129202Scognet	addne	pc, pc, r4, lsl #1
170129202Scognet	nop
171129202Scognet
172129202Scognet	/* At least 24 bytes remaining */
173129202Scognet	ldr	r4, [r1], #0x04
174129202Scognet	ldr	r5, [r1], #0x04
175129202Scognet	sub	r2, r2, #0x08
176129202Scognet	strd	r4, [r3], #0x08
177129202Scognet
178129202Scognet	/* At least 16 bytes remaining */
179129202Scognet	ldr	r4, [r1], #0x04
180129202Scognet	ldr	r5, [r1], #0x04
181129202Scognet	sub	r2, r2, #0x08
182129202Scognet	strd	r4, [r3], #0x08
183129202Scognet
184129202Scognet	/* At least 8 bytes remaining */
185129202Scognet	ldr	r4, [r1], #0x04
186129202Scognet	ldr	r5, [r1], #0x04
187129202Scognet	subs	r2, r2, #0x08
188129202Scognet	strd	r4, [r3], #0x08
189129202Scognet
190129202Scognet	/* Less than 8 bytes remaining */
191129202Scognet	ldmfd	sp!, {r4-r9}
192135683Scognet	bxeq	lr			/* Return now if done */
193129202Scognet	subs	r2, r2, #0x04
194129202Scognet	ldrge	ip, [r1], #0x04
195129202Scognet	strge	ip, [r3], #0x04
196135683Scognet	bxeq	lr			/* Return now if done */
197129202Scognet	addlt	r2, r2, #0x04
198129202Scognet	ldrb	ip, [r1], #0x01
199129202Scognet	cmp	r2, #0x02
200275256Sandrew	ldrbge	r2, [r1], #0x01
201129202Scognet	strb	ip, [r3], #0x01
202275256Sandrew	ldrbgt	ip, [r1]
203275256Sandrew	strbge	r2, [r3], #0x01
204275256Sandrew	strbgt	ip, [r3]
205135683Scognet	bx	lr
206129202Scognet
207129202Scognet
208129202Scognet/*
209129202Scognet * At this point, it has not been possible to word align both buffers.
210129202Scognet * The destination buffer is word aligned, but the source buffer is not.
211129202Scognet */
212129202Scognet.Lmemcpy_bad_align:
213129202Scognet	stmfd	sp!, {r4-r7}
214129202Scognet	bic	r1, r1, #0x03
215129202Scognet	cmp	ip, #2
216129202Scognet	ldr	ip, [r1], #0x04
217129202Scognet	bgt	.Lmemcpy_bad3
218129202Scognet	beq	.Lmemcpy_bad2
219129202Scognet	b	.Lmemcpy_bad1
220129202Scognet
221129202Scognet.Lmemcpy_bad1_loop16:
222129202Scognet#ifdef __ARMEB__
223129202Scognet	mov	r4, ip, lsl #8
224129202Scognet#else
225129202Scognet	mov	r4, ip, lsr #8
226129202Scognet#endif
227129202Scognet	ldr	r5, [r1], #0x04
228129202Scognet	pld	[r1, #0x018]
229129202Scognet	ldr	r6, [r1], #0x04
230129202Scognet	ldr	r7, [r1], #0x04
231129202Scognet	ldr	ip, [r1], #0x04
232129202Scognet#ifdef __ARMEB__
233129202Scognet	orr	r4, r4, r5, lsr #24
234129202Scognet	mov	r5, r5, lsl #8
235129202Scognet	orr	r5, r5, r6, lsr #24
236129202Scognet	mov	r6, r6, lsl #8
237129202Scognet	orr	r6, r6, r7, lsr #24
238129202Scognet	mov	r7, r7, lsl #8
239129202Scognet	orr	r7, r7, ip, lsr #24
240129202Scognet#else
241129202Scognet	orr	r4, r4, r5, lsl #24
242129202Scognet	mov	r5, r5, lsr #8
243129202Scognet	orr	r5, r5, r6, lsl #24
244129202Scognet	mov	r6, r6, lsr #8
245129202Scognet	orr	r6, r6, r7, lsl #24
246129202Scognet	mov	r7, r7, lsr #8
247129202Scognet	orr	r7, r7, ip, lsl #24
248129202Scognet#endif
249129202Scognet	str	r4, [r3], #0x04
250129202Scognet	str	r5, [r3], #0x04
251129202Scognet	str	r6, [r3], #0x04
252129202Scognet	str	r7, [r3], #0x04
253129202Scognet.Lmemcpy_bad1:
254129202Scognet	subs	r2, r2, #0x10
255129202Scognet	bge	.Lmemcpy_bad1_loop16
256129202Scognet
257129202Scognet	adds	r2, r2, #0x10
258275256Sandrew	ldmfdeq	sp!, {r4-r7}
259135683Scognet	bxeq	lr			/* Return now if done */
260129202Scognet	subs	r2, r2, #0x04
261129202Scognet	sublt	r1, r1, #0x03
262129202Scognet	blt	.Lmemcpy_bad_done
263129202Scognet
264129202Scognet.Lmemcpy_bad1_loop4:
265129202Scognet#ifdef __ARMEB__
266129202Scognet	mov	r4, ip, lsl #8
267129202Scognet#else
268129202Scognet	mov	r4, ip, lsr #8
269129202Scognet#endif
270129202Scognet	ldr	ip, [r1], #0x04
271129202Scognet	subs	r2, r2, #0x04
272129202Scognet#ifdef __ARMEB__
273129202Scognet	orr	r4, r4, ip, lsr #24
274129202Scognet#else
275129202Scognet	orr	r4, r4, ip, lsl #24
276129202Scognet#endif
277129202Scognet	str	r4, [r3], #0x04
278129202Scognet	bge	.Lmemcpy_bad1_loop4
279129202Scognet	sub	r1, r1, #0x03
280129202Scognet	b	.Lmemcpy_bad_done
281129202Scognet
282129202Scognet.Lmemcpy_bad2_loop16:
283129202Scognet#ifdef __ARMEB__
284129202Scognet	mov	r4, ip, lsl #16
285129202Scognet#else
286129202Scognet	mov	r4, ip, lsr #16
287129202Scognet#endif
288129202Scognet	ldr	r5, [r1], #0x04
289129202Scognet	pld	[r1, #0x018]
290129202Scognet	ldr	r6, [r1], #0x04
291129202Scognet	ldr	r7, [r1], #0x04
292129202Scognet	ldr	ip, [r1], #0x04
293129202Scognet#ifdef __ARMEB__
294129202Scognet	orr	r4, r4, r5, lsr #16
295129202Scognet	mov	r5, r5, lsl #16
296129202Scognet	orr	r5, r5, r6, lsr #16
297129202Scognet	mov	r6, r6, lsl #16
298129202Scognet	orr	r6, r6, r7, lsr #16
299129202Scognet	mov	r7, r7, lsl #16
300129202Scognet	orr	r7, r7, ip, lsr #16
301129202Scognet#else
302129202Scognet	orr	r4, r4, r5, lsl #16
303129202Scognet	mov	r5, r5, lsr #16
304129202Scognet	orr	r5, r5, r6, lsl #16
305129202Scognet	mov	r6, r6, lsr #16
306129202Scognet	orr	r6, r6, r7, lsl #16
307129202Scognet	mov	r7, r7, lsr #16
308129202Scognet	orr	r7, r7, ip, lsl #16
309129202Scognet#endif
310129202Scognet	str	r4, [r3], #0x04
311129202Scognet	str	r5, [r3], #0x04
312129202Scognet	str	r6, [r3], #0x04
313129202Scognet	str	r7, [r3], #0x04
314129202Scognet.Lmemcpy_bad2:
315129202Scognet	subs	r2, r2, #0x10
316129202Scognet	bge	.Lmemcpy_bad2_loop16
317129202Scognet
318129202Scognet	adds	r2, r2, #0x10
319275256Sandrew	ldmfdeq	sp!, {r4-r7}
320135683Scognet	bxeq	lr			/* Return now if done */
321129202Scognet	subs	r2, r2, #0x04
322129202Scognet	sublt	r1, r1, #0x02
323129202Scognet	blt	.Lmemcpy_bad_done
324129202Scognet
325129202Scognet.Lmemcpy_bad2_loop4:
326129202Scognet#ifdef __ARMEB__
327129202Scognet	mov	r4, ip, lsl #16
328129202Scognet#else
329129202Scognet	mov	r4, ip, lsr #16
330129202Scognet#endif
331129202Scognet	ldr	ip, [r1], #0x04
332129202Scognet	subs	r2, r2, #0x04
333129202Scognet#ifdef __ARMEB__
334129202Scognet	orr	r4, r4, ip, lsr #16
335129202Scognet#else
336129202Scognet	orr	r4, r4, ip, lsl #16
337129202Scognet#endif
338129202Scognet	str	r4, [r3], #0x04
339129202Scognet	bge	.Lmemcpy_bad2_loop4
340129202Scognet	sub	r1, r1, #0x02
341129202Scognet	b	.Lmemcpy_bad_done
342129202Scognet
343129202Scognet.Lmemcpy_bad3_loop16:
344129202Scognet#ifdef __ARMEB__
345129202Scognet	mov	r4, ip, lsl #24
346129202Scognet#else
347129202Scognet	mov	r4, ip, lsr #24
348129202Scognet#endif
349129202Scognet	ldr	r5, [r1], #0x04
350129202Scognet	pld	[r1, #0x018]
351129202Scognet	ldr	r6, [r1], #0x04
352129202Scognet	ldr	r7, [r1], #0x04
353129202Scognet	ldr	ip, [r1], #0x04
354129202Scognet#ifdef __ARMEB__
355129202Scognet	orr	r4, r4, r5, lsr #8
356129202Scognet	mov	r5, r5, lsl #24
357129202Scognet	orr	r5, r5, r6, lsr #8
358129202Scognet	mov	r6, r6, lsl #24
359129202Scognet	orr	r6, r6, r7, lsr #8
360129202Scognet	mov	r7, r7, lsl #24
361129202Scognet	orr	r7, r7, ip, lsr #8
362129202Scognet#else
363129202Scognet	orr	r4, r4, r5, lsl #8
364129202Scognet	mov	r5, r5, lsr #24
365129202Scognet	orr	r5, r5, r6, lsl #8
366129202Scognet	mov	r6, r6, lsr #24
367129202Scognet	orr	r6, r6, r7, lsl #8
368129202Scognet	mov	r7, r7, lsr #24
369129202Scognet	orr	r7, r7, ip, lsl #8
370129202Scognet#endif
371129202Scognet	str	r4, [r3], #0x04
372129202Scognet	str	r5, [r3], #0x04
373129202Scognet	str	r6, [r3], #0x04
374129202Scognet	str	r7, [r3], #0x04
375129202Scognet.Lmemcpy_bad3:
376129202Scognet	subs	r2, r2, #0x10
377129202Scognet	bge	.Lmemcpy_bad3_loop16
378129202Scognet
379129202Scognet	adds	r2, r2, #0x10
380275256Sandrew	ldmfdeq	sp!, {r4-r7}
381135683Scognet	bxeq	lr			/* Return now if done */
382129202Scognet	subs	r2, r2, #0x04
383129202Scognet	sublt	r1, r1, #0x01
384129202Scognet	blt	.Lmemcpy_bad_done
385129202Scognet
386129202Scognet.Lmemcpy_bad3_loop4:
387129202Scognet#ifdef __ARMEB__
388129202Scognet	mov	r4, ip, lsl #24
389129202Scognet#else
390129202Scognet	mov	r4, ip, lsr #24
391129202Scognet#endif
392129202Scognet	ldr	ip, [r1], #0x04
393129202Scognet	subs	r2, r2, #0x04
394129202Scognet#ifdef __ARMEB__
395129202Scognet	orr	r4, r4, ip, lsr #8
396129202Scognet#else
397129202Scognet	orr	r4, r4, ip, lsl #8
398129202Scognet#endif
399129202Scognet	str	r4, [r3], #0x04
400129202Scognet	bge	.Lmemcpy_bad3_loop4
401129202Scognet	sub	r1, r1, #0x01
402129202Scognet
403129202Scognet.Lmemcpy_bad_done:
404129202Scognet	ldmfd	sp!, {r4-r7}
405129202Scognet	adds	r2, r2, #0x04
406135683Scognet	bxeq	lr
407129202Scognet	ldrb	ip, [r1], #0x01
408129202Scognet	cmp	r2, #0x02
409275256Sandrew	ldrbge	r2, [r1], #0x01
410129202Scognet	strb	ip, [r3], #0x01
411275256Sandrew	ldrbgt	ip, [r1]
412275256Sandrew	strbge	r2, [r3], #0x01
413275256Sandrew	strbgt	ip, [r3]
414135683Scognet	bx	lr
415129202Scognet
416129202Scognet
417129202Scognet/*
418129202Scognet * Handle short copies (less than 16 bytes), possibly misaligned.
419129202Scognet * Some of these are *very* common, thanks to the network stack,
420129202Scognet * and so are handled specially.
421129202Scognet */
422129202Scognet.Lmemcpy_short:
423129202Scognet#ifndef _STANDALONE
424129202Scognet	add	pc, pc, r2, lsl #2
425129202Scognet	nop
426135683Scognet	bx	lr			/* 0x00 */
427129202Scognet	b	.Lmemcpy_bytewise	/* 0x01 */
428129202Scognet	b	.Lmemcpy_bytewise	/* 0x02 */
429129202Scognet	b	.Lmemcpy_bytewise	/* 0x03 */
430129202Scognet	b	.Lmemcpy_4		/* 0x04 */
431129202Scognet	b	.Lmemcpy_bytewise	/* 0x05 */
432129202Scognet	b	.Lmemcpy_6		/* 0x06 */
433129202Scognet	b	.Lmemcpy_bytewise	/* 0x07 */
434129202Scognet	b	.Lmemcpy_8		/* 0x08 */
435129202Scognet	b	.Lmemcpy_bytewise	/* 0x09 */
436129202Scognet	b	.Lmemcpy_bytewise	/* 0x0a */
437129202Scognet	b	.Lmemcpy_bytewise	/* 0x0b */
438129202Scognet	b	.Lmemcpy_c		/* 0x0c */
439129202Scognet#endif
440129202Scognet.Lmemcpy_bytewise:
441129202Scognet	mov	r3, r0			/* We must not clobber r0 */
442129202Scognet	ldrb	ip, [r1], #0x01
443129202Scognet1:	subs	r2, r2, #0x01
444129202Scognet	strb	ip, [r3], #0x01
445275256Sandrew	ldrbne	ip, [r1], #0x01
446129202Scognet	bne	1b
447135683Scognet	bx	lr
448129202Scognet
449129202Scognet#ifndef _STANDALONE
450129202Scognet/******************************************************************************
451129202Scognet * Special case for 4 byte copies
452129202Scognet */
453129202Scognet#define	LMEMCPY_4_LOG2	6	/* 64 bytes */
454129202Scognet#define	LMEMCPY_4_PAD	.align LMEMCPY_4_LOG2
455129202Scognet	LMEMCPY_4_PAD
456129202Scognet.Lmemcpy_4:
457129202Scognet	and	r2, r1, #0x03
458129202Scognet	orr	r2, r2, r0, lsl #2
459129202Scognet	ands	r2, r2, #0x0f
460129202Scognet	sub	r3, pc, #0x14
461129202Scognet	addne	pc, r3, r2, lsl #LMEMCPY_4_LOG2
462129202Scognet
463129202Scognet/*
464129202Scognet * 0000: dst is 32-bit aligned, src is 32-bit aligned
465129202Scognet */
466129202Scognet	ldr	r2, [r1]
467129202Scognet	str	r2, [r0]
468135683Scognet	bx	lr
469129202Scognet	LMEMCPY_4_PAD
470129202Scognet
471129202Scognet/*
472129202Scognet * 0001: dst is 32-bit aligned, src is 8-bit aligned
473129202Scognet */
474129202Scognet	ldr	r3, [r1, #-1]		/* BE:r3 = x012  LE:r3 = 210x */
475129202Scognet	ldr	r2, [r1, #3]		/* BE:r2 = 3xxx  LE:r2 = xxx3 */
476129202Scognet#ifdef __ARMEB__
477129202Scognet	mov	r3, r3, lsl #8		/* r3 = 012. */
478129202Scognet	orr	r3, r3, r2, lsr #24	/* r3 = 0123 */
479129202Scognet#else
480129202Scognet	mov	r3, r3, lsr #8		/* r3 = .210 */
481129202Scognet	orr	r3, r3, r2, lsl #24	/* r3 = 3210 */
482129202Scognet#endif
483129202Scognet	str	r3, [r0]
484135683Scognet	bx	lr
485129202Scognet	LMEMCPY_4_PAD
486129202Scognet
487129202Scognet/*
488129202Scognet * 0010: dst is 32-bit aligned, src is 16-bit aligned
489129202Scognet */
490129202Scognet#ifdef __ARMEB__
491129202Scognet	ldrh	r3, [r1]
492129202Scognet	ldrh	r2, [r1, #0x02]
493129202Scognet#else
494129202Scognet	ldrh	r3, [r1, #0x02]
495129202Scognet	ldrh	r2, [r1]
496129202Scognet#endif
497129202Scognet	orr	r3, r2, r3, lsl #16
498129202Scognet	str	r3, [r0]
499135683Scognet	bx	lr
500129202Scognet	LMEMCPY_4_PAD
501129202Scognet
502129202Scognet/*
503129202Scognet * 0011: dst is 32-bit aligned, src is 8-bit aligned
504129202Scognet */
505129202Scognet	ldr	r3, [r1, #-3]		/* BE:r3 = xxx0  LE:r3 = 0xxx */
506129202Scognet	ldr	r2, [r1, #1]		/* BE:r2 = 123x  LE:r2 = x321 */
507129202Scognet#ifdef __ARMEB__
508129202Scognet	mov	r3, r3, lsl #24		/* r3 = 0... */
509129202Scognet	orr	r3, r3, r2, lsr #8	/* r3 = 0123 */
510129202Scognet#else
511129202Scognet	mov	r3, r3, lsr #24		/* r3 = ...0 */
512129202Scognet	orr	r3, r3, r2, lsl #8	/* r3 = 3210 */
513129202Scognet#endif
514129202Scognet	str	r3, [r0]
515135683Scognet	bx	lr
516129202Scognet	LMEMCPY_4_PAD
517129202Scognet
518129202Scognet/*
519129202Scognet * 0100: dst is 8-bit aligned, src is 32-bit aligned
520129202Scognet */
521129202Scognet	ldr	r2, [r1]
522129202Scognet#ifdef __ARMEB__
523129202Scognet	strb	r2, [r0, #0x03]
524129202Scognet	mov	r3, r2, lsr #8
525129202Scognet	mov	r1, r2, lsr #24
526129202Scognet	strb	r1, [r0]
527129202Scognet#else
528129202Scognet	strb	r2, [r0]
529129202Scognet	mov	r3, r2, lsr #8
530129202Scognet	mov	r1, r2, lsr #24
531129202Scognet	strb	r1, [r0, #0x03]
532129202Scognet#endif
533129202Scognet	strh	r3, [r0, #0x01]
534135683Scognet	bx	lr
535129202Scognet	LMEMCPY_4_PAD
536129202Scognet
537129202Scognet/*
538129202Scognet * 0101: dst is 8-bit aligned, src is 8-bit aligned
539129202Scognet */
540129202Scognet	ldrb	r2, [r1]
541129202Scognet	ldrh	r3, [r1, #0x01]
542129202Scognet	ldrb	r1, [r1, #0x03]
543129202Scognet	strb	r2, [r0]
544129202Scognet	strh	r3, [r0, #0x01]
545129202Scognet	strb	r1, [r0, #0x03]
546135683Scognet	bx	lr
547129202Scognet	LMEMCPY_4_PAD
548129202Scognet
549129202Scognet/*
550129202Scognet * 0110: dst is 8-bit aligned, src is 16-bit aligned
551129202Scognet */
552129202Scognet	ldrh	r2, [r1]		/* BE:r2 = ..01  LE:r2 = ..10 */
553129202Scognet	ldrh	r3, [r1, #0x02]		/* LE:r3 = ..23  LE:r3 = ..32 */
554129202Scognet#ifdef __ARMEB__
555129202Scognet	mov	r1, r2, lsr #8		/* r1 = ...0 */
556129202Scognet	strb	r1, [r0]
557129202Scognet	mov	r2, r2, lsl #8		/* r2 = .01. */
558129202Scognet	orr	r2, r2, r3, lsr #8	/* r2 = .012 */
559129202Scognet#else
560129202Scognet	strb	r2, [r0]
561129202Scognet	mov	r2, r2, lsr #8		/* r2 = ...1 */
562129202Scognet	orr	r2, r2, r3, lsl #8	/* r2 = .321 */
563129202Scognet	mov	r3, r3, lsr #8		/* r3 = ...3 */
564129202Scognet#endif
565129202Scognet	strh	r2, [r0, #0x01]
566129202Scognet	strb	r3, [r0, #0x03]
567135683Scognet	bx	lr
568129202Scognet	LMEMCPY_4_PAD
569129202Scognet
570129202Scognet/*
571129202Scognet * 0111: dst is 8-bit aligned, src is 8-bit aligned
572129202Scognet */
573129202Scognet	ldrb	r2, [r1]
574129202Scognet	ldrh	r3, [r1, #0x01]
575129202Scognet	ldrb	r1, [r1, #0x03]
576129202Scognet	strb	r2, [r0]
577129202Scognet	strh	r3, [r0, #0x01]
578129202Scognet	strb	r1, [r0, #0x03]
579135683Scognet	bx	lr
580129202Scognet	LMEMCPY_4_PAD
581129202Scognet
582129202Scognet/*
583129202Scognet * 1000: dst is 16-bit aligned, src is 32-bit aligned
584129202Scognet */
585129202Scognet	ldr	r2, [r1]
586129202Scognet#ifdef __ARMEB__
587129202Scognet	strh	r2, [r0, #0x02]
588129202Scognet	mov	r3, r2, lsr #16
589129202Scognet	strh	r3, [r0]
590129202Scognet#else
591129202Scognet	strh	r2, [r0]
592129202Scognet	mov	r3, r2, lsr #16
593129202Scognet	strh	r3, [r0, #0x02]
594129202Scognet#endif
595135683Scognet	bx	 lr
596129202Scognet	LMEMCPY_4_PAD
597129202Scognet
598129202Scognet/*
599129202Scognet * 1001: dst is 16-bit aligned, src is 8-bit aligned
600129202Scognet */
601129202Scognet	ldr	r2, [r1, #-1]		/* BE:r2 = x012  LE:r2 = 210x */
602129202Scognet	ldr	r3, [r1, #3]		/* BE:r3 = 3xxx  LE:r3 = xxx3 */
603129202Scognet	mov	r1, r2, lsr #8		/* BE:r1 = .x01  LE:r1 = .210 */
604129202Scognet	strh	r1, [r0]
605129202Scognet#ifdef __ARMEB__
606129202Scognet	mov	r2, r2, lsl #8		/* r2 = 012. */
607129202Scognet	orr	r2, r2, r3, lsr #24	/* r2 = 0123 */
608129202Scognet#else
609129202Scognet	mov	r2, r2, lsr #24		/* r2 = ...2 */
610129202Scognet	orr	r2, r2, r3, lsl #8	/* r2 = xx32 */
611129202Scognet#endif
612129202Scognet	strh	r2, [r0, #0x02]
613135683Scognet	bx	lr
614129202Scognet	LMEMCPY_4_PAD
615129202Scognet
616129202Scognet/*
617129202Scognet * 1010: dst is 16-bit aligned, src is 16-bit aligned
618129202Scognet */
619129202Scognet	ldrh	r2, [r1]
620129202Scognet	ldrh	r3, [r1, #0x02]
621129202Scognet	strh	r2, [r0]
622129202Scognet	strh	r3, [r0, #0x02]
623135683Scognet	bx	lr
624129202Scognet	LMEMCPY_4_PAD
625129202Scognet
626129202Scognet/*
627129202Scognet * 1011: dst is 16-bit aligned, src is 8-bit aligned
628129202Scognet */
629129202Scognet	ldr	r3, [r1, #1]		/* BE:r3 = 123x  LE:r3 = x321 */
630129202Scognet	ldr	r2, [r1, #-3]		/* BE:r2 = xxx0  LE:r2 = 0xxx */
631129202Scognet	mov	r1, r3, lsr #8		/* BE:r1 = .123  LE:r1 = .x32 */
632129202Scognet	strh	r1, [r0, #0x02]
633129202Scognet#ifdef __ARMEB__
634129202Scognet	mov	r3, r3, lsr #24		/* r3 = ...1 */
635129202Scognet	orr	r3, r3, r2, lsl #8	/* r3 = xx01 */
636129202Scognet#else
637129202Scognet	mov	r3, r3, lsl #8		/* r3 = 321. */
638129202Scognet	orr	r3, r3, r2, lsr #24	/* r3 = 3210 */
639129202Scognet#endif
640129202Scognet	strh	r3, [r0]
641135683Scognet	bx	lr
642129202Scognet	LMEMCPY_4_PAD
643129202Scognet
644129202Scognet/*
645129202Scognet * 1100: dst is 8-bit aligned, src is 32-bit aligned
646129202Scognet */
647129202Scognet	ldr	r2, [r1]		/* BE:r2 = 0123  LE:r2 = 3210 */
648129202Scognet#ifdef __ARMEB__
649129202Scognet	strb	r2, [r0, #0x03]
650129202Scognet	mov	r3, r2, lsr #8
651129202Scognet	mov	r1, r2, lsr #24
652129202Scognet	strh	r3, [r0, #0x01]
653129202Scognet	strb	r1, [r0]
654129202Scognet#else
655129202Scognet	strb	r2, [r0]
656129202Scognet	mov	r3, r2, lsr #8
657129202Scognet	mov	r1, r2, lsr #24
658129202Scognet	strh	r3, [r0, #0x01]
659129202Scognet	strb	r1, [r0, #0x03]
660129202Scognet#endif
661135683Scognet	bx	lr
662129202Scognet	LMEMCPY_4_PAD
663129202Scognet
664129202Scognet/*
665129202Scognet * 1101: dst is 8-bit aligned, src is 8-bit aligned
666129202Scognet */
667129202Scognet	ldrb	r2, [r1]
668129202Scognet	ldrh	r3, [r1, #0x01]
669129202Scognet	ldrb	r1, [r1, #0x03]
670129202Scognet	strb	r2, [r0]
671129202Scognet	strh	r3, [r0, #0x01]
672129202Scognet	strb	r1, [r0, #0x03]
673135683Scognet	bx	lr
674129202Scognet	LMEMCPY_4_PAD
675129202Scognet
676129202Scognet/*
677129202Scognet * 1110: dst is 8-bit aligned, src is 16-bit aligned
678129202Scognet */
679129202Scognet#ifdef __ARMEB__
680129202Scognet	ldrh	r3, [r1, #0x02]		/* BE:r3 = ..23  LE:r3 = ..32 */
681129202Scognet	ldrh	r2, [r1]		/* BE:r2 = ..01  LE:r2 = ..10 */
682129202Scognet	strb	r3, [r0, #0x03]
683129202Scognet	mov	r3, r3, lsr #8		/* r3 = ...2 */
684129202Scognet	orr	r3, r3, r2, lsl #8	/* r3 = ..12 */
685129202Scognet	strh	r3, [r0, #0x01]
686129202Scognet	mov	r2, r2, lsr #8		/* r2 = ...0 */
687129202Scognet	strb	r2, [r0]
688129202Scognet#else
689129202Scognet	ldrh	r2, [r1]		/* BE:r2 = ..01  LE:r2 = ..10 */
690129202Scognet	ldrh	r3, [r1, #0x02]		/* BE:r3 = ..23  LE:r3 = ..32 */
691129202Scognet	strb	r2, [r0]
692129202Scognet	mov	r2, r2, lsr #8		/* r2 = ...1 */
693129202Scognet	orr	r2, r2, r3, lsl #8	/* r2 = .321 */
694129202Scognet	strh	r2, [r0, #0x01]
695129202Scognet	mov	r3, r3, lsr #8		/* r3 = ...3 */
696129202Scognet	strb	r3, [r0, #0x03]
697129202Scognet#endif
698135683Scognet	bx	lr
699129202Scognet	LMEMCPY_4_PAD
700129202Scognet
701129202Scognet/*
702129202Scognet * 1111: dst is 8-bit aligned, src is 8-bit aligned
703129202Scognet */
704129202Scognet	ldrb	r2, [r1]
705129202Scognet	ldrh	r3, [r1, #0x01]
706129202Scognet	ldrb	r1, [r1, #0x03]
707129202Scognet	strb	r2, [r0]
708129202Scognet	strh	r3, [r0, #0x01]
709129202Scognet	strb	r1, [r0, #0x03]
710135683Scognet	bx	lr
711129202Scognet	LMEMCPY_4_PAD
712129202Scognet
713129202Scognet
714129202Scognet/******************************************************************************
715129202Scognet * Special case for 6 byte copies
716129202Scognet */
717129202Scognet#define	LMEMCPY_6_LOG2	6	/* 64 bytes */
718129202Scognet#define	LMEMCPY_6_PAD	.align LMEMCPY_6_LOG2
719129202Scognet	LMEMCPY_6_PAD
720129202Scognet.Lmemcpy_6:
721129202Scognet	and	r2, r1, #0x03
722129202Scognet	orr	r2, r2, r0, lsl #2
723129202Scognet	ands	r2, r2, #0x0f
724129202Scognet	sub	r3, pc, #0x14
725129202Scognet	addne	pc, r3, r2, lsl #LMEMCPY_6_LOG2
726129202Scognet
727129202Scognet/*
728129202Scognet * 0000: dst is 32-bit aligned, src is 32-bit aligned
729129202Scognet */
730129202Scognet	ldr	r2, [r1]
731129202Scognet	ldrh	r3, [r1, #0x04]
732129202Scognet	str	r2, [r0]
733129202Scognet	strh	r3, [r0, #0x04]
734135683Scognet	bx	lr
735129202Scognet	LMEMCPY_6_PAD
736129202Scognet
737129202Scognet/*
738129202Scognet * 0001: dst is 32-bit aligned, src is 8-bit aligned
739129202Scognet */
740129202Scognet	ldr	r2, [r1, #-1]		/* BE:r2 = x012  LE:r2 = 210x */
741129202Scognet	ldr	r3, [r1, #0x03]		/* BE:r3 = 345x  LE:r3 = x543 */
742129202Scognet#ifdef __ARMEB__
743129202Scognet	mov	r2, r2, lsl #8		/* r2 = 012. */
744129202Scognet	orr	r2, r2, r3, lsr #24	/* r2 = 0123 */
745129202Scognet#else
746129202Scognet	mov	r2, r2, lsr #8		/* r2 = .210 */
747129202Scognet	orr	r2, r2, r3, lsl #24	/* r2 = 3210 */
748129202Scognet#endif
749129202Scognet	mov	r3, r3, lsr #8		/* BE:r3 = .345  LE:r3 = .x54 */
750129202Scognet	str	r2, [r0]
751129202Scognet	strh	r3, [r0, #0x04]
752135683Scognet	bx	lr
753129202Scognet	LMEMCPY_6_PAD
754129202Scognet
755129202Scognet/*
756129202Scognet * 0010: dst is 32-bit aligned, src is 16-bit aligned
757129202Scognet */
758129202Scognet	ldr	r3, [r1, #0x02]		/* BE:r3 = 2345  LE:r3 = 5432 */
759129202Scognet	ldrh	r2, [r1]		/* BE:r2 = ..01  LE:r2 = ..10 */
760129202Scognet#ifdef __ARMEB__
761129202Scognet	mov	r1, r3, lsr #16		/* r1 = ..23 */
762129202Scognet	orr	r1, r1, r2, lsl #16	/* r1 = 0123 */
763129202Scognet	str	r1, [r0]
764129202Scognet	strh	r3, [r0, #0x04]
765129202Scognet#else
766129202Scognet	mov	r1, r3, lsr #16		/* r1 = ..54 */
767129202Scognet	orr	r2, r2, r3, lsl #16	/* r2 = 3210 */
768129202Scognet	str	r2, [r0]
769129202Scognet	strh	r1, [r0, #0x04]
770129202Scognet#endif
771135683Scognet	bx	lr
772129202Scognet	LMEMCPY_6_PAD
773129202Scognet
774129202Scognet/*
775129202Scognet * 0011: dst is 32-bit aligned, src is 8-bit aligned
776129202Scognet */
777129202Scognet	ldr	r2, [r1, #-3]		/* BE:r2 = xxx0  LE:r2 = 0xxx */
778129202Scognet	ldr	r3, [r1, #1]		/* BE:r3 = 1234  LE:r3 = 4321 */
779129202Scognet	ldr	r1, [r1, #5]		/* BE:r1 = 5xxx  LE:r3 = xxx5 */
780129202Scognet#ifdef __ARMEB__
781129202Scognet	mov	r2, r2, lsl #24		/* r2 = 0... */
782129202Scognet	orr	r2, r2, r3, lsr #8	/* r2 = 0123 */
783129202Scognet	mov	r3, r3, lsl #8		/* r3 = 234. */
784129202Scognet	orr	r1, r3, r1, lsr #24	/* r1 = 2345 */
785129202Scognet#else
786129202Scognet	mov	r2, r2, lsr #24		/* r2 = ...0 */
787129202Scognet	orr	r2, r2, r3, lsl #8	/* r2 = 3210 */
788129202Scognet	mov	r1, r1, lsl #8		/* r1 = xx5. */
789129202Scognet	orr	r1, r1, r3, lsr #24	/* r1 = xx54 */
790129202Scognet#endif
791129202Scognet	str	r2, [r0]
792129202Scognet	strh	r1, [r0, #0x04]
793135683Scognet	bx	lr
794129202Scognet	LMEMCPY_6_PAD
795129202Scognet
796129202Scognet/*
797129202Scognet * 0100: dst is 8-bit aligned, src is 32-bit aligned
798129202Scognet */
799129202Scognet	ldr	r3, [r1]		/* BE:r3 = 0123  LE:r3 = 3210 */
800129202Scognet	ldrh	r2, [r1, #0x04]		/* BE:r2 = ..45  LE:r2 = ..54 */
801129202Scognet	mov	r1, r3, lsr #8		/* BE:r1 = .012  LE:r1 = .321 */
802129202Scognet	strh	r1, [r0, #0x01]
803129202Scognet#ifdef __ARMEB__
804129202Scognet	mov	r1, r3, lsr #24		/* r1 = ...0 */
805129202Scognet	strb	r1, [r0]
806129202Scognet	mov	r3, r3, lsl #8		/* r3 = 123. */
807129202Scognet	orr	r3, r3, r2, lsr #8	/* r3 = 1234 */
808129202Scognet#else
809129202Scognet	strb	r3, [r0]
810129202Scognet	mov	r3, r3, lsr #24		/* r3 = ...3 */
811129202Scognet	orr	r3, r3, r2, lsl #8	/* r3 = .543 */
812129202Scognet	mov	r2, r2, lsr #8		/* r2 = ...5 */
813129202Scognet#endif
814129202Scognet	strh	r3, [r0, #0x03]
815129202Scognet	strb	r2, [r0, #0x05]
816135683Scognet	bx	lr
817129202Scognet	LMEMCPY_6_PAD
818129202Scognet
819129202Scognet/*
820129202Scognet * 0101: dst is 8-bit aligned, src is 8-bit aligned
821129202Scognet */
822129202Scognet	ldrb	r2, [r1]
823129202Scognet	ldrh	r3, [r1, #0x01]
824129202Scognet	ldrh	ip, [r1, #0x03]
825129202Scognet	ldrb	r1, [r1, #0x05]
826129202Scognet	strb	r2, [r0]
827129202Scognet	strh	r3, [r0, #0x01]
828129202Scognet	strh	ip, [r0, #0x03]
829129202Scognet	strb	r1, [r0, #0x05]
830135683Scognet	bx	lr
831129202Scognet	LMEMCPY_6_PAD
832129202Scognet
833129202Scognet/*
834129202Scognet * 0110: dst is 8-bit aligned, src is 16-bit aligned
835129202Scognet */
836129202Scognet	ldrh	r2, [r1]		/* BE:r2 = ..01  LE:r2 = ..10 */
837129202Scognet	ldr	r1, [r1, #0x02]		/* BE:r1 = 2345  LE:r1 = 5432 */
838129202Scognet#ifdef __ARMEB__
839129202Scognet	mov	r3, r2, lsr #8		/* r3 = ...0 */
840129202Scognet	strb	r3, [r0]
841129202Scognet	strb	r1, [r0, #0x05]
842129202Scognet	mov	r3, r1, lsr #8		/* r3 = .234 */
843129202Scognet	strh	r3, [r0, #0x03]
844129202Scognet	mov	r3, r2, lsl #8		/* r3 = .01. */
845129202Scognet	orr	r3, r3, r1, lsr #24	/* r3 = .012 */
846129202Scognet	strh	r3, [r0, #0x01]
847129202Scognet#else
848129202Scognet	strb	r2, [r0]
849129202Scognet	mov	r3, r1, lsr #24
850129202Scognet	strb	r3, [r0, #0x05]
851129202Scognet	mov	r3, r1, lsr #8		/* r3 = .543 */
852129202Scognet	strh	r3, [r0, #0x03]
853129202Scognet	mov	r3, r2, lsr #8		/* r3 = ...1 */
854129202Scognet	orr	r3, r3, r1, lsl #8	/* r3 = 4321 */
855129202Scognet	strh	r3, [r0, #0x01]
856129202Scognet#endif
857135683Scognet	bx	lr
858129202Scognet	LMEMCPY_6_PAD
859129202Scognet
860129202Scognet/*
861129202Scognet * 0111: dst is 8-bit aligned, src is 8-bit aligned
862129202Scognet */
863129202Scognet	ldrb	r2, [r1]
864129202Scognet	ldrh	r3, [r1, #0x01]
865129202Scognet	ldrh	ip, [r1, #0x03]
866129202Scognet	ldrb	r1, [r1, #0x05]
867129202Scognet	strb	r2, [r0]
868129202Scognet	strh	r3, [r0, #0x01]
869129202Scognet	strh	ip, [r0, #0x03]
870129202Scognet	strb	r1, [r0, #0x05]
871135683Scognet	bx	lr
872129202Scognet	LMEMCPY_6_PAD
873129202Scognet
874129202Scognet/*
875129202Scognet * 1000: dst is 16-bit aligned, src is 32-bit aligned
876129202Scognet */
877129202Scognet#ifdef __ARMEB__
878129202Scognet	ldr	r2, [r1]		/* r2 = 0123 */
879129202Scognet	ldrh	r3, [r1, #0x04]		/* r3 = ..45 */
880129202Scognet	mov	r1, r2, lsr #16		/* r1 = ..01 */
881129202Scognet	orr	r3, r3, r2, lsl#16	/* r3 = 2345 */
882129202Scognet	strh	r1, [r0]
883129202Scognet	str	r3, [r0, #0x02]
884129202Scognet#else
885129202Scognet	ldrh	r2, [r1, #0x04]		/* r2 = ..54 */
886129202Scognet	ldr	r3, [r1]		/* r3 = 3210 */
887129202Scognet	mov	r2, r2, lsl #16		/* r2 = 54.. */
888129202Scognet	orr	r2, r2, r3, lsr #16	/* r2 = 5432 */
889129202Scognet	strh	r3, [r0]
890129202Scognet	str	r2, [r0, #0x02]
891129202Scognet#endif
892135683Scognet	bx	lr
893129202Scognet	LMEMCPY_6_PAD
894129202Scognet
895129202Scognet/*
896129202Scognet * 1001: dst is 16-bit aligned, src is 8-bit aligned
897129202Scognet */
898129202Scognet	ldr	r3, [r1, #-1]		/* BE:r3 = x012  LE:r3 = 210x */
899129202Scognet	ldr	r2, [r1, #3]		/* BE:r2 = 345x  LE:r2 = x543 */
900129202Scognet	mov	r1, r3, lsr #8		/* BE:r1 = .x01  LE:r1 = .210 */
901129202Scognet#ifdef __ARMEB__
902129202Scognet	mov	r2, r2, lsr #8		/* r2 = .345 */
903129202Scognet	orr	r2, r2, r3, lsl #24	/* r2 = 2345 */
904129202Scognet#else
905129202Scognet	mov	r2, r2, lsl #8		/* r2 = 543. */
906129202Scognet	orr	r2, r2, r3, lsr #24	/* r2 = 5432 */
907129202Scognet#endif
908129202Scognet	strh	r1, [r0]
909129202Scognet	str	r2, [r0, #0x02]
910135683Scognet	bx	lr
911129202Scognet	LMEMCPY_6_PAD
912129202Scognet
913129202Scognet/*
914129202Scognet * 1010: dst is 16-bit aligned, src is 16-bit aligned
915129202Scognet */
916129202Scognet	ldrh	r2, [r1]
917129202Scognet	ldr	r3, [r1, #0x02]
918129202Scognet	strh	r2, [r0]
919129202Scognet	str	r3, [r0, #0x02]
920135683Scognet	bx	lr
921129202Scognet	LMEMCPY_6_PAD
922129202Scognet
923129202Scognet/*
924129202Scognet * 1011: dst is 16-bit aligned, src is 8-bit aligned
925129202Scognet */
926129202Scognet	ldrb	r3, [r1]		/* r3 = ...0 */
927129202Scognet	ldr	r2, [r1, #0x01]		/* BE:r2 = 1234  LE:r2 = 4321 */
928129202Scognet	ldrb	r1, [r1, #0x05]		/* r1 = ...5 */
929129202Scognet#ifdef __ARMEB__
930129202Scognet	mov	r3, r3, lsl #8		/* r3 = ..0. */
931129202Scognet	orr	r3, r3, r2, lsr #24	/* r3 = ..01 */
932129202Scognet	orr	r1, r1, r2, lsl #8	/* r1 = 2345 */
933129202Scognet#else
934129202Scognet	orr	r3, r3, r2, lsl #8	/* r3 = 3210 */
935129202Scognet	mov	r1, r1, lsl #24		/* r1 = 5... */
936129202Scognet	orr	r1, r1, r2, lsr #8	/* r1 = 5432 */
937129202Scognet#endif
938129202Scognet	strh	r3, [r0]
939129202Scognet	str	r1, [r0, #0x02]
940135683Scognet	bx	lr
941129202Scognet	LMEMCPY_6_PAD
942129202Scognet
943129202Scognet/*
944129202Scognet * 1100: dst is 8-bit aligned, src is 32-bit aligned
945129202Scognet */
946129202Scognet	ldr	r2, [r1]		/* BE:r2 = 0123  LE:r2 = 3210 */
947129202Scognet	ldrh	r1, [r1, #0x04]		/* BE:r1 = ..45  LE:r1 = ..54 */
948129202Scognet#ifdef __ARMEB__
949129202Scognet	mov	r3, r2, lsr #24		/* r3 = ...0 */
950129202Scognet	strb	r3, [r0]
951129202Scognet	mov	r2, r2, lsl #8		/* r2 = 123. */
952129202Scognet	orr	r2, r2, r1, lsr #8	/* r2 = 1234 */
953129202Scognet#else
954129202Scognet	strb	r2, [r0]
955129202Scognet	mov	r2, r2, lsr #8		/* r2 = .321 */
956129202Scognet	orr	r2, r2, r1, lsl #24	/* r2 = 4321 */
957129202Scognet	mov	r1, r1, lsr #8		/* r1 = ...5 */
958129202Scognet#endif
959129202Scognet	str	r2, [r0, #0x01]
960129202Scognet	strb	r1, [r0, #0x05]
961135683Scognet	bx	lr
962129202Scognet	LMEMCPY_6_PAD
963129202Scognet
964129202Scognet/*
965129202Scognet * 1101: dst is 8-bit aligned, src is 8-bit aligned
966129202Scognet */
967129202Scognet	ldrb	r2, [r1]
968129202Scognet	ldrh	r3, [r1, #0x01]
969129202Scognet	ldrh	ip, [r1, #0x03]
970129202Scognet	ldrb	r1, [r1, #0x05]
971129202Scognet	strb	r2, [r0]
972129202Scognet	strh	r3, [r0, #0x01]
973129202Scognet	strh	ip, [r0, #0x03]
974129202Scognet	strb	r1, [r0, #0x05]
975135683Scognet	bx	lr
976129202Scognet	LMEMCPY_6_PAD
977129202Scognet
978129202Scognet/*
979129202Scognet * 1110: dst is 8-bit aligned, src is 16-bit aligned
980129202Scognet */
981129202Scognet	ldrh	r2, [r1]		/* BE:r2 = ..01  LE:r2 = ..10 */
982129202Scognet	ldr	r1, [r1, #0x02]		/* BE:r1 = 2345  LE:r1 = 5432 */
983129202Scognet#ifdef __ARMEB__
984129202Scognet	mov	r3, r2, lsr #8		/* r3 = ...0 */
985129202Scognet	strb	r3, [r0]
986129202Scognet	mov	r2, r2, lsl #24		/* r2 = 1... */
987129202Scognet	orr	r2, r2, r1, lsr #8	/* r2 = 1234 */
988129202Scognet#else
989129202Scognet	strb	r2, [r0]
990129202Scognet	mov	r2, r2, lsr #8		/* r2 = ...1 */
991129202Scognet	orr	r2, r2, r1, lsl #8	/* r2 = 4321 */
992129202Scognet	mov	r1, r1, lsr #24		/* r1 = ...5 */
993129202Scognet#endif
994129202Scognet	str	r2, [r0, #0x01]
995129202Scognet	strb	r1, [r0, #0x05]
996135683Scognet	bx	lr
997129202Scognet	LMEMCPY_6_PAD
998129202Scognet
999129202Scognet/*
1000129202Scognet * 1111: dst is 8-bit aligned, src is 8-bit aligned
1001129202Scognet */
1002129202Scognet	ldrb	r2, [r1]
1003129202Scognet	ldr	r3, [r1, #0x01]
1004129202Scognet	ldrb	r1, [r1, #0x05]
1005129202Scognet	strb	r2, [r0]
1006129202Scognet	str	r3, [r0, #0x01]
1007129202Scognet	strb	r1, [r0, #0x05]
1008135683Scognet	bx	lr
1009129202Scognet	LMEMCPY_6_PAD
1010129202Scognet
1011129202Scognet
1012129202Scognet/******************************************************************************
1013129202Scognet * Special case for 8 byte copies
1014129202Scognet */
1015129202Scognet#define	LMEMCPY_8_LOG2	6	/* 64 bytes */
1016129202Scognet#define	LMEMCPY_8_PAD	.align LMEMCPY_8_LOG2
1017129202Scognet	LMEMCPY_8_PAD
1018129202Scognet.Lmemcpy_8:
1019129202Scognet	and	r2, r1, #0x03
1020129202Scognet	orr	r2, r2, r0, lsl #2
1021129202Scognet	ands	r2, r2, #0x0f
1022129202Scognet	sub	r3, pc, #0x14
1023129202Scognet	addne	pc, r3, r2, lsl #LMEMCPY_8_LOG2
1024129202Scognet
1025129202Scognet/*
1026129202Scognet * 0000: dst is 32-bit aligned, src is 32-bit aligned
1027129202Scognet */
1028129202Scognet	ldr	r2, [r1]
1029129202Scognet	ldr	r3, [r1, #0x04]
1030129202Scognet	str	r2, [r0]
1031129202Scognet	str	r3, [r0, #0x04]
1032135683Scognet	bx	lr
1033129202Scognet	LMEMCPY_8_PAD
1034129202Scognet
1035129202Scognet/*
1036129202Scognet * 0001: dst is 32-bit aligned, src is 8-bit aligned
1037129202Scognet */
1038129202Scognet	ldr	r3, [r1, #-1]		/* BE:r3 = x012  LE:r3 = 210x */
1039129202Scognet	ldr	r2, [r1, #0x03]		/* BE:r2 = 3456  LE:r2 = 6543 */
1040129202Scognet	ldrb	r1, [r1, #0x07]		/* r1 = ...7 */
1041129202Scognet#ifdef __ARMEB__
1042129202Scognet	mov	r3, r3, lsl #8		/* r3 = 012. */
1043129202Scognet	orr	r3, r3, r2, lsr #24	/* r3 = 0123 */
1044129202Scognet	orr	r2, r1, r2, lsl #8	/* r2 = 4567 */
1045129202Scognet#else
1046129202Scognet	mov	r3, r3, lsr #8		/* r3 = .210 */
1047129202Scognet	orr	r3, r3, r2, lsl #24	/* r3 = 3210 */
1048129202Scognet	mov	r1, r1, lsl #24		/* r1 = 7... */
1049129202Scognet	orr	r2, r1, r2, lsr #8	/* r2 = 7654 */
1050129202Scognet#endif
1051129202Scognet	str	r3, [r0]
1052129202Scognet	str	r2, [r0, #0x04]
1053135683Scognet	bx	lr
1054129202Scognet	LMEMCPY_8_PAD
1055129202Scognet
1056129202Scognet/*
1057129202Scognet * 0010: dst is 32-bit aligned, src is 16-bit aligned
1058129202Scognet */
1059129202Scognet	ldrh	r2, [r1]		/* BE:r2 = ..01  LE:r2 = ..10 */
1060129202Scognet	ldr	r3, [r1, #0x02]		/* BE:r3 = 2345  LE:r3 = 5432 */
1061129202Scognet	ldrh	r1, [r1, #0x06]		/* BE:r1 = ..67  LE:r1 = ..76 */
1062129202Scognet#ifdef __ARMEB__
1063129202Scognet	mov	r2, r2, lsl #16		/* r2 = 01.. */
1064129202Scognet	orr	r2, r2, r3, lsr #16	/* r2 = 0123 */
1065129202Scognet	orr	r3, r1, r3, lsl #16	/* r3 = 4567 */
1066129202Scognet#else
1067129202Scognet	orr	r2, r2, r3, lsl #16	/* r2 = 3210 */
1068129202Scognet	mov	r3, r3, lsr #16		/* r3 = ..54 */
1069129202Scognet	orr	r3, r3, r1, lsl #16	/* r3 = 7654 */
1070129202Scognet#endif
1071129202Scognet	str	r2, [r0]
1072129202Scognet	str	r3, [r0, #0x04]
1073135683Scognet	bx	lr
1074129202Scognet	LMEMCPY_8_PAD
1075129202Scognet
1076129202Scognet/*
1077129202Scognet * 0011: dst is 32-bit aligned, src is 8-bit aligned
1078129202Scognet */
1079129202Scognet	ldrb	r3, [r1]		/* r3 = ...0 */
1080129202Scognet	ldr	r2, [r1, #0x01]		/* BE:r2 = 1234  LE:r2 = 4321 */
1081129202Scognet	ldr	r1, [r1, #0x05]		/* BE:r1 = 567x  LE:r1 = x765 */
1082129202Scognet#ifdef __ARMEB__
1083129202Scognet	mov	r3, r3, lsl #24		/* r3 = 0... */
1084129202Scognet	orr	r3, r3, r2, lsr #8	/* r3 = 0123 */
1085129202Scognet	mov	r2, r2, lsl #24		/* r2 = 4... */
1086129202Scognet	orr	r2, r2, r1, lsr #8	/* r2 = 4567 */
1087129202Scognet#else
1088129202Scognet	orr	r3, r3, r2, lsl #8	/* r3 = 3210 */
1089129202Scognet	mov	r2, r2, lsr #24		/* r2 = ...4 */
1090129202Scognet	orr	r2, r2, r1, lsl #8	/* r2 = 7654 */
1091129202Scognet#endif
1092129202Scognet	str	r3, [r0]
1093129202Scognet	str	r2, [r0, #0x04]
1094135683Scognet	bx	lr
1095129202Scognet	LMEMCPY_8_PAD
1096129202Scognet
1097129202Scognet/*
1098129202Scognet * 0100: dst is 8-bit aligned, src is 32-bit aligned
1099129202Scognet */
1100129202Scognet	ldr	r3, [r1]		/* BE:r3 = 0123  LE:r3 = 3210 */
1101129202Scognet	ldr	r2, [r1, #0x04]		/* BE:r2 = 4567  LE:r2 = 7654 */
1102129202Scognet#ifdef __ARMEB__
1103129202Scognet	mov	r1, r3, lsr #24		/* r1 = ...0 */
1104129202Scognet	strb	r1, [r0]
1105129202Scognet	mov	r1, r3, lsr #8		/* r1 = .012 */
1106129202Scognet	strb	r2, [r0, #0x07]
1107129202Scognet	mov	r3, r3, lsl #24		/* r3 = 3... */
1108129202Scognet	orr	r3, r3, r2, lsr #8	/* r3 = 3456 */
1109129202Scognet#else
1110129202Scognet	strb	r3, [r0]
1111129202Scognet	mov	r1, r2, lsr #24		/* r1 = ...7 */
1112129202Scognet	strb	r1, [r0, #0x07]
1113129202Scognet	mov	r1, r3, lsr #8		/* r1 = .321 */
1114129202Scognet	mov	r3, r3, lsr #24		/* r3 = ...3 */
1115129202Scognet	orr	r3, r3, r2, lsl #8	/* r3 = 6543 */
1116129202Scognet#endif
1117129202Scognet	strh	r1, [r0, #0x01]
1118129202Scognet	str	r3, [r0, #0x03]
1119135683Scognet	bx	lr
1120129202Scognet	LMEMCPY_8_PAD
1121129202Scognet
1122129202Scognet/*
1123129202Scognet * 0101: dst is 8-bit aligned, src is 8-bit aligned
1124129202Scognet */
1125129202Scognet	ldrb	r2, [r1]
1126129202Scognet	ldrh	r3, [r1, #0x01]
1127129202Scognet	ldr	ip, [r1, #0x03]
1128129202Scognet	ldrb	r1, [r1, #0x07]
1129129202Scognet	strb	r2, [r0]
1130129202Scognet	strh	r3, [r0, #0x01]
1131129202Scognet	str	ip, [r0, #0x03]
1132129202Scognet	strb	r1, [r0, #0x07]
1133135683Scognet	bx	lr
1134129202Scognet	LMEMCPY_8_PAD
1135129202Scognet
1136129202Scognet/*
1137129202Scognet * 0110: dst is 8-bit aligned, src is 16-bit aligned
1138129202Scognet */
1139129202Scognet	ldrh	r2, [r1]		/* BE:r2 = ..01  LE:r2 = ..10 */
1140129202Scognet	ldr	r3, [r1, #0x02]		/* BE:r3 = 2345  LE:r3 = 5432 */
1141129202Scognet	ldrh	r1, [r1, #0x06]		/* BE:r1 = ..67  LE:r1 = ..76 */
1142129202Scognet#ifdef __ARMEB__
1143129202Scognet	mov	ip, r2, lsr #8		/* ip = ...0 */
1144129202Scognet	strb	ip, [r0]
1145129202Scognet	mov	ip, r2, lsl #8		/* ip = .01. */
1146129202Scognet	orr	ip, ip, r3, lsr #24	/* ip = .012 */
1147129202Scognet	strb	r1, [r0, #0x07]
1148129202Scognet	mov	r3, r3, lsl #8		/* r3 = 345. */
1149129202Scognet	orr	r3, r3, r1, lsr #8	/* r3 = 3456 */
1150129202Scognet#else
1151129202Scognet	strb	r2, [r0]		/* 0 */
1152129202Scognet	mov	ip, r1, lsr #8		/* ip = ...7 */
1153129202Scognet	strb	ip, [r0, #0x07]		/* 7 */
1154129202Scognet	mov	ip, r2, lsr #8		/* ip = ...1 */
1155129202Scognet	orr	ip, ip, r3, lsl #8	/* ip = 4321 */
1156129202Scognet	mov	r3, r3, lsr #8		/* r3 = .543 */
1157129202Scognet	orr	r3, r3, r1, lsl #24	/* r3 = 6543 */
1158129202Scognet#endif
1159129202Scognet	strh	ip, [r0, #0x01]
1160129202Scognet	str	r3, [r0, #0x03]
1161135683Scognet	bx	lr
1162129202Scognet	LMEMCPY_8_PAD
1163129202Scognet
1164129202Scognet/*
1165129202Scognet * 0111: dst is 8-bit aligned, src is 8-bit aligned
1166129202Scognet */
1167129202Scognet	ldrb	r3, [r1]		/* r3 = ...0 */
1168129202Scognet	ldr	ip, [r1, #0x01]		/* BE:ip = 1234  LE:ip = 4321 */
1169129202Scognet	ldrh	r2, [r1, #0x05]		/* BE:r2 = ..56  LE:r2 = ..65 */
1170129202Scognet	ldrb	r1, [r1, #0x07]		/* r1 = ...7 */
1171129202Scognet	strb	r3, [r0]
1172129202Scognet	mov	r3, ip, lsr #16		/* BE:r3 = ..12  LE:r3 = ..43 */
1173129202Scognet#ifdef __ARMEB__
1174129202Scognet	strh	r3, [r0, #0x01]
1175129202Scognet	orr	r2, r2, ip, lsl #16	/* r2 = 3456 */
1176129202Scognet#else
1177129202Scognet	strh	ip, [r0, #0x01]
1178129202Scognet	orr	r2, r3, r2, lsl #16	/* r2 = 6543 */
1179129202Scognet#endif
1180129202Scognet	str	r2, [r0, #0x03]
1181129202Scognet	strb	r1, [r0, #0x07]
1182135683Scognet	bx	lr
1183129202Scognet	LMEMCPY_8_PAD
1184129202Scognet
1185129202Scognet/*
1186129202Scognet * 1000: dst is 16-bit aligned, src is 32-bit aligned
1187129202Scognet */
1188129202Scognet	ldr	r2, [r1]		/* BE:r2 = 0123  LE:r2 = 3210 */
1189129202Scognet	ldr	r3, [r1, #0x04]		/* BE:r3 = 4567  LE:r3 = 7654 */
1190129202Scognet	mov	r1, r2, lsr #16		/* BE:r1 = ..01  LE:r1 = ..32 */
1191129202Scognet#ifdef __ARMEB__
1192129202Scognet	strh	r1, [r0]
1193129202Scognet	mov	r1, r3, lsr #16		/* r1 = ..45 */
1194129202Scognet	orr	r2, r1 ,r2, lsl #16	/* r2 = 2345 */
1195129202Scognet#else
1196129202Scognet	strh	r2, [r0]
1197129202Scognet	orr	r2, r1, r3, lsl #16	/* r2 = 5432 */
1198129202Scognet	mov	r3, r3, lsr #16		/* r3 = ..76 */
1199129202Scognet#endif
1200129202Scognet	str	r2, [r0, #0x02]
1201129202Scognet	strh	r3, [r0, #0x06]
1202135683Scognet	bx	lr
1203129202Scognet	LMEMCPY_8_PAD
1204129202Scognet
1205129202Scognet/*
1206129202Scognet * 1001: dst is 16-bit aligned, src is 8-bit aligned
1207129202Scognet */
1208129202Scognet	ldr	r2, [r1, #-1]		/* BE:r2 = x012  LE:r2 = 210x */
1209129202Scognet	ldr	r3, [r1, #0x03]		/* BE:r3 = 3456  LE:r3 = 6543 */
1210129202Scognet	ldrb	ip, [r1, #0x07]		/* ip = ...7 */
1211129202Scognet	mov	r1, r2, lsr #8		/* BE:r1 = .x01  LE:r1 = .210 */
1212129202Scognet	strh	r1, [r0]
1213129202Scognet#ifdef __ARMEB__
1214129202Scognet	mov	r1, r2, lsl #24		/* r1 = 2... */
1215129202Scognet	orr	r1, r1, r3, lsr #8	/* r1 = 2345 */
1216129202Scognet	orr	r3, ip, r3, lsl #8	/* r3 = 4567 */
1217129202Scognet#else
1218129202Scognet	mov	r1, r2, lsr #24		/* r1 = ...2 */
1219129202Scognet	orr	r1, r1, r3, lsl #8	/* r1 = 5432 */
1220129202Scognet	mov	r3, r3, lsr #24		/* r3 = ...6 */
1221129202Scognet	orr	r3, r3, ip, lsl #8	/* r3 = ..76 */
1222129202Scognet#endif
1223129202Scognet	str	r1, [r0, #0x02]
1224129202Scognet	strh	r3, [r0, #0x06]
1225135683Scognet	bx	lr
1226129202Scognet	LMEMCPY_8_PAD
1227129202Scognet
1228129202Scognet/*
1229129202Scognet * 1010: dst is 16-bit aligned, src is 16-bit aligned
1230129202Scognet */
1231129202Scognet	ldrh	r2, [r1]
1232129202Scognet	ldr	ip, [r1, #0x02]
1233129202Scognet	ldrh	r3, [r1, #0x06]
1234129202Scognet	strh	r2, [r0]
1235129202Scognet	str	ip, [r0, #0x02]
1236129202Scognet	strh	r3, [r0, #0x06]
1237135683Scognet	bx	lr
1238129202Scognet	LMEMCPY_8_PAD
1239129202Scognet
1240129202Scognet/*
1241129202Scognet * 1011: dst is 16-bit aligned, src is 8-bit aligned
1242129202Scognet */
1243129202Scognet	ldr	r3, [r1, #0x05]		/* BE:r3 = 567x  LE:r3 = x765 */
1244129202Scognet	ldr	r2, [r1, #0x01]		/* BE:r2 = 1234  LE:r2 = 4321 */
1245129202Scognet	ldrb	ip, [r1]		/* ip = ...0 */
1246129202Scognet	mov	r1, r3, lsr #8		/* BE:r1 = .567  LE:r1 = .x76 */
1247129202Scognet	strh	r1, [r0, #0x06]
1248129202Scognet#ifdef __ARMEB__
1249129202Scognet	mov	r3, r3, lsr #24		/* r3 = ...5 */
1250129202Scognet	orr	r3, r3, r2, lsl #8	/* r3 = 2345 */
1251129202Scognet	mov	r2, r2, lsr #24		/* r2 = ...1 */
1252129202Scognet	orr	r2, r2, ip, lsl #8	/* r2 = ..01 */
1253129202Scognet#else
1254129202Scognet	mov	r3, r3, lsl #24		/* r3 = 5... */
1255129202Scognet	orr	r3, r3, r2, lsr #8	/* r3 = 5432 */
1256129202Scognet	orr	r2, ip, r2, lsl #8	/* r2 = 3210 */
1257129202Scognet#endif
1258129202Scognet	str	r3, [r0, #0x02]
1259129202Scognet	strh	r2, [r0]
1260135683Scognet	bx	lr
1261129202Scognet	LMEMCPY_8_PAD
1262129202Scognet
1263129202Scognet/*
1264129202Scognet * 1100: dst is 8-bit aligned, src is 32-bit aligned
1265129202Scognet */
1266129202Scognet	ldr	r3, [r1, #0x04]		/* BE:r3 = 4567  LE:r3 = 7654 */
1267129202Scognet	ldr	r2, [r1]		/* BE:r2 = 0123  LE:r2 = 3210 */
1268129202Scognet	mov	r1, r3, lsr #8		/* BE:r1 = .456  LE:r1 = .765 */
1269129202Scognet	strh	r1, [r0, #0x05]
1270129202Scognet#ifdef __ARMEB__
1271129202Scognet	strb	r3, [r0, #0x07]
1272129202Scognet	mov	r1, r2, lsr #24		/* r1 = ...0 */
1273129202Scognet	strb	r1, [r0]
1274129202Scognet	mov	r2, r2, lsl #8		/* r2 = 123. */
1275129202Scognet	orr	r2, r2, r3, lsr #24	/* r2 = 1234 */
1276129202Scognet	str	r2, [r0, #0x01]
1277129202Scognet#else
1278129202Scognet	strb	r2, [r0]
1279129202Scognet	mov	r1, r3, lsr #24		/* r1 = ...7 */
1280129202Scognet	strb	r1, [r0, #0x07]
1281129202Scognet	mov	r2, r2, lsr #8		/* r2 = .321 */
1282129202Scognet	orr	r2, r2, r3, lsl #24	/* r2 = 4321 */
1283129202Scognet	str	r2, [r0, #0x01]
1284129202Scognet#endif
1285135683Scognet	bx	 lr
1286129202Scognet	LMEMCPY_8_PAD
1287129202Scognet
1288129202Scognet/*
1289129202Scognet * 1101: dst is 8-bit aligned, src is 8-bit aligned
1290129202Scognet */
1291129202Scognet	ldrb	r3, [r1]		/* r3 = ...0 */
1292129202Scognet	ldrh	r2, [r1, #0x01]		/* BE:r2 = ..12  LE:r2 = ..21 */
1293129202Scognet	ldr	ip, [r1, #0x03]		/* BE:ip = 3456  LE:ip = 6543 */
1294129202Scognet	ldrb	r1, [r1, #0x07]		/* r1 = ...7 */
1295129202Scognet	strb	r3, [r0]
1296129202Scognet	mov	r3, ip, lsr #16		/* BE:r3 = ..34  LE:r3 = ..65 */
1297129202Scognet#ifdef __ARMEB__
1298129202Scognet	strh	ip, [r0, #0x05]
1299129202Scognet	orr	r2, r3, r2, lsl #16	/* r2 = 1234 */
1300129202Scognet#else
1301129202Scognet	strh	r3, [r0, #0x05]
1302129202Scognet	orr	r2, r2, ip, lsl #16	/* r2 = 4321 */
1303129202Scognet#endif
1304129202Scognet	str	r2, [r0, #0x01]
1305129202Scognet	strb	r1, [r0, #0x07]
1306135683Scognet	bx	lr
1307129202Scognet	LMEMCPY_8_PAD
1308129202Scognet
1309129202Scognet/*
1310129202Scognet * 1110: dst is 8-bit aligned, src is 16-bit aligned
1311129202Scognet */
1312129202Scognet	ldrh	r2, [r1]		/* BE:r2 = ..01  LE:r2 = ..10 */
1313129202Scognet	ldr	r3, [r1, #0x02]		/* BE:r3 = 2345  LE:r3 = 5432 */
1314129202Scognet	ldrh	r1, [r1, #0x06]		/* BE:r1 = ..67  LE:r1 = ..76 */
1315129202Scognet#ifdef __ARMEB__
1316129202Scognet	mov	ip, r2, lsr #8		/* ip = ...0 */
1317129202Scognet	strb	ip, [r0]
1318129202Scognet	mov	ip, r2, lsl #24		/* ip = 1... */
1319129202Scognet	orr	ip, ip, r3, lsr #8	/* ip = 1234 */
1320129202Scognet	strb	r1, [r0, #0x07]
1321129202Scognet	mov	r1, r1, lsr #8		/* r1 = ...6 */
1322129202Scognet	orr	r1, r1, r3, lsl #8	/* r1 = 3456 */
1323129202Scognet#else
1324129202Scognet	strb	r2, [r0]
1325129202Scognet	mov	ip, r2, lsr #8		/* ip = ...1 */
1326129202Scognet	orr	ip, ip, r3, lsl #8	/* ip = 4321 */
1327129202Scognet	mov	r2, r1, lsr #8		/* r2 = ...7 */
1328129202Scognet	strb	r2, [r0, #0x07]
1329129202Scognet	mov	r1, r1, lsl #8		/* r1 = .76. */
1330129202Scognet	orr	r1, r1, r3, lsr #24	/* r1 = .765 */
1331129202Scognet#endif
1332129202Scognet	str	ip, [r0, #0x01]
1333129202Scognet	strh	r1, [r0, #0x05]
1334135683Scognet	bx	lr
1335129202Scognet	LMEMCPY_8_PAD
1336129202Scognet
1337129202Scognet/*
1338129202Scognet * 1111: dst is 8-bit aligned, src is 8-bit aligned
1339129202Scognet */
1340129202Scognet	ldrb	r2, [r1]
1341129202Scognet	ldr	ip, [r1, #0x01]
1342129202Scognet	ldrh	r3, [r1, #0x05]
1343129202Scognet	ldrb	r1, [r1, #0x07]
1344129202Scognet	strb	r2, [r0]
1345129202Scognet	str	ip, [r0, #0x01]
1346129202Scognet	strh	r3, [r0, #0x05]
1347129202Scognet	strb	r1, [r0, #0x07]
1348135683Scognet	bx	lr
1349129202Scognet	LMEMCPY_8_PAD
1350129202Scognet
1351129202Scognet/******************************************************************************
1352129202Scognet * Special case for 12 byte copies
1353129202Scognet */
1354129202Scognet#define	LMEMCPY_C_LOG2	7	/* 128 bytes */
1355129202Scognet#define	LMEMCPY_C_PAD	.align LMEMCPY_C_LOG2
1356129202Scognet	LMEMCPY_C_PAD
1357129202Scognet.Lmemcpy_c:
1358129202Scognet	and	r2, r1, #0x03
1359129202Scognet	orr	r2, r2, r0, lsl #2
1360129202Scognet	ands	r2, r2, #0x0f
1361129202Scognet	sub	r3, pc, #0x14
1362129202Scognet	addne	pc, r3, r2, lsl #LMEMCPY_C_LOG2
1363129202Scognet
1364129202Scognet/*
1365129202Scognet * 0000: dst is 32-bit aligned, src is 32-bit aligned
1366129202Scognet */
1367129202Scognet	ldr	r2, [r1]
1368129202Scognet	ldr	r3, [r1, #0x04]
1369129202Scognet	ldr	r1, [r1, #0x08]
1370129202Scognet	str	r2, [r0]
1371129202Scognet	str	r3, [r0, #0x04]
1372129202Scognet	str	r1, [r0, #0x08]
1373135683Scognet	bx	lr
1374129202Scognet	LMEMCPY_C_PAD
1375129202Scognet
1376129202Scognet/*
1377129202Scognet * 0001: dst is 32-bit aligned, src is 8-bit aligned
1378129202Scognet */
1379129202Scognet	ldrb	r2, [r1, #0xb]		/* r2 = ...B */
1380129202Scognet	ldr	ip, [r1, #0x07]		/* BE:ip = 789A  LE:ip = A987 */
1381129202Scognet	ldr	r3, [r1, #0x03]		/* BE:r3 = 3456  LE:r3 = 6543 */
1382129202Scognet	ldr	r1, [r1, #-1]		/* BE:r1 = x012  LE:r1 = 210x */
1383129202Scognet#ifdef __ARMEB__
1384129202Scognet	orr	r2, r2, ip, lsl #8	/* r2 = 89AB */
1385129202Scognet	str	r2, [r0, #0x08]
1386129202Scognet	mov	r2, ip, lsr #24		/* r2 = ...7 */
1387129202Scognet	orr	r2, r2, r3, lsl #8	/* r2 = 4567 */
1388129202Scognet	mov	r1, r1, lsl #8		/* r1 = 012. */
1389129202Scognet	orr	r1, r1, r3, lsr #24	/* r1 = 0123 */
1390129202Scognet#else
1391129202Scognet	mov	r2, r2, lsl #24		/* r2 = B... */
1392129202Scognet	orr	r2, r2, ip, lsr #8	/* r2 = BA98 */
1393129202Scognet	str	r2, [r0, #0x08]
1394129202Scognet	mov	r2, ip, lsl #24		/* r2 = 7... */
1395129202Scognet	orr	r2, r2, r3, lsr #8	/* r2 = 7654 */
1396129202Scognet	mov	r1, r1, lsr #8		/* r1 = .210 */
1397129202Scognet	orr	r1, r1, r3, lsl #24	/* r1 = 3210 */
1398129202Scognet#endif
1399129202Scognet	str	r2, [r0, #0x04]
1400129202Scognet	str	r1, [r0]
1401135683Scognet	bx	lr
1402129202Scognet	LMEMCPY_C_PAD
1403129202Scognet
1404129202Scognet/*
1405129202Scognet * 0010: dst is 32-bit aligned, src is 16-bit aligned
1406129202Scognet */
1407129202Scognet	ldrh	r2, [r1]		/* BE:r2 = ..01  LE:r2 = ..10 */
1408129202Scognet	ldr	r3, [r1, #0x02]		/* BE:r3 = 2345  LE:r3 = 5432 */
1409129202Scognet	ldr	ip, [r1, #0x06]		/* BE:ip = 6789  LE:ip = 9876 */
1410129202Scognet	ldrh	r1, [r1, #0x0a]		/* BE:r1 = ..AB  LE:r1 = ..BA */
1411129202Scognet#ifdef __ARMEB__
1412129202Scognet	mov	r2, r2, lsl #16		/* r2 = 01.. */
1413129202Scognet	orr	r2, r2, r3, lsr #16	/* r2 = 0123 */
1414129202Scognet	str	r2, [r0]
1415129202Scognet	mov	r3, r3, lsl #16		/* r3 = 45.. */
1416129202Scognet	orr	r3, r3, ip, lsr #16	/* r3 = 4567 */
1417129202Scognet	orr	r1, r1, ip, lsl #16	/* r1 = 89AB */
1418129202Scognet#else
1419129202Scognet	orr	r2, r2, r3, lsl #16	/* r2 = 3210 */
1420129202Scognet	str	r2, [r0]
1421129202Scognet	mov	r3, r3, lsr #16		/* r3 = ..54 */
1422129202Scognet	orr	r3, r3, ip, lsl #16	/* r3 = 7654 */
1423129202Scognet	mov	r1, r1, lsl #16		/* r1 = BA.. */
1424129202Scognet	orr	r1, r1, ip, lsr #16	/* r1 = BA98 */
1425129202Scognet#endif
1426129202Scognet	str	r3, [r0, #0x04]
1427129202Scognet	str	r1, [r0, #0x08]
1428135683Scognet	bx	lr
1429129202Scognet	LMEMCPY_C_PAD
1430129202Scognet
1431129202Scognet/*
1432129202Scognet * 0011: dst is 32-bit aligned, src is 8-bit aligned
1433129202Scognet */
1434129202Scognet	ldrb	r2, [r1]		/* r2 = ...0 */
1435129202Scognet	ldr	r3, [r1, #0x01]		/* BE:r3 = 1234  LE:r3 = 4321 */
1436129202Scognet	ldr	ip, [r1, #0x05]		/* BE:ip = 5678  LE:ip = 8765 */
1437129202Scognet	ldr	r1, [r1, #0x09]		/* BE:r1 = 9ABx  LE:r1 = xBA9 */
1438129202Scognet#ifdef __ARMEB__
1439129202Scognet	mov	r2, r2, lsl #24		/* r2 = 0... */
1440129202Scognet	orr	r2, r2, r3, lsr #8	/* r2 = 0123 */
1441129202Scognet	str	r2, [r0]
1442129202Scognet	mov	r3, r3, lsl #24		/* r3 = 4... */
1443129202Scognet	orr	r3, r3, ip, lsr #8	/* r3 = 4567 */
1444129202Scognet	mov	r1, r1, lsr #8		/* r1 = .9AB */
1445129202Scognet	orr	r1, r1, ip, lsl #24	/* r1 = 89AB */
1446129202Scognet#else
1447129202Scognet	orr	r2, r2, r3, lsl #8	/* r2 = 3210 */
1448129202Scognet	str	r2, [r0]
1449129202Scognet	mov	r3, r3, lsr #24		/* r3 = ...4 */
1450129202Scognet	orr	r3, r3, ip, lsl #8	/* r3 = 7654 */
1451129202Scognet	mov	r1, r1, lsl #8		/* r1 = BA9. */
1452129202Scognet	orr	r1, r1, ip, lsr #24	/* r1 = BA98 */
1453129202Scognet#endif
1454129202Scognet	str	r3, [r0, #0x04]
1455129202Scognet	str	r1, [r0, #0x08]
1456135683Scognet	bx	lr
1457129202Scognet	LMEMCPY_C_PAD
1458129202Scognet
1459129202Scognet/*
1460129202Scognet * 0100: dst is 8-bit aligned (byte 1), src is 32-bit aligned
1461129202Scognet */
1462129202Scognet	ldr	r2, [r1]		/* BE:r2 = 0123  LE:r2 = 3210 */
1463129202Scognet	ldr	r3, [r1, #0x04]		/* BE:r3 = 4567  LE:r3 = 7654 */
1464129202Scognet	ldr	ip, [r1, #0x08]		/* BE:ip = 89AB  LE:ip = BA98 */
1465129202Scognet	mov	r1, r2, lsr #8		/* BE:r1 = .012  LE:r1 = .321 */
1466129202Scognet	strh	r1, [r0, #0x01]
1467129202Scognet#ifdef __ARMEB__
1468129202Scognet	mov	r1, r2, lsr #24		/* r1 = ...0 */
1469129202Scognet	strb	r1, [r0]
1470129202Scognet	mov	r1, r2, lsl #24		/* r1 = 3... */
1471129202Scognet	orr	r2, r1, r3, lsr #8	/* r1 = 3456 */
1472129202Scognet	mov	r1, r3, lsl #24		/* r1 = 7... */
1473129202Scognet	orr	r1, r1, ip, lsr #8	/* r1 = 789A */
1474129202Scognet#else
1475129202Scognet	strb	r2, [r0]
1476129202Scognet	mov	r1, r2, lsr #24		/* r1 = ...3 */
1477129202Scognet	orr	r2, r1, r3, lsl #8	/* r1 = 6543 */
1478129202Scognet	mov	r1, r3, lsr #24		/* r1 = ...7 */
1479129202Scognet	orr	r1, r1, ip, lsl #8	/* r1 = A987 */
1480129202Scognet	mov	ip, ip, lsr #24		/* ip = ...B */
1481129202Scognet#endif
1482129202Scognet	str	r2, [r0, #0x03]
1483129202Scognet	str	r1, [r0, #0x07]
1484129202Scognet	strb	ip, [r0, #0x0b]
1485135683Scognet	bx	lr
1486129202Scognet	LMEMCPY_C_PAD
1487129202Scognet
1488129202Scognet/*
1489129202Scognet * 0101: dst is 8-bit aligned (byte 1), src is 8-bit aligned (byte 1)
1490129202Scognet */
1491129202Scognet	ldrb	r2, [r1]
1492129202Scognet	ldrh	r3, [r1, #0x01]
1493129202Scognet	ldr	ip, [r1, #0x03]
1494129202Scognet	strb	r2, [r0]
1495129202Scognet	ldr	r2, [r1, #0x07]
1496129202Scognet	ldrb	r1, [r1, #0x0b]
1497129202Scognet	strh	r3, [r0, #0x01]
1498129202Scognet	str	ip, [r0, #0x03]
1499129202Scognet	str	r2, [r0, #0x07]
1500129202Scognet	strb	r1, [r0, #0x0b]
1501135683Scognet	bx	lr
1502129202Scognet	LMEMCPY_C_PAD
1503129202Scognet
1504129202Scognet/*
1505129202Scognet * 0110: dst is 8-bit aligned (byte 1), src is 16-bit aligned
1506129202Scognet */
1507129202Scognet	ldrh	r2, [r1]		/* BE:r2 = ..01  LE:r2 = ..10 */
1508129202Scognet	ldr	r3, [r1, #0x02]		/* BE:r3 = 2345  LE:r3 = 5432 */
1509129202Scognet	ldr	ip, [r1, #0x06]		/* BE:ip = 6789  LE:ip = 9876 */
1510129202Scognet	ldrh	r1, [r1, #0x0a]		/* BE:r1 = ..AB  LE:r1 = ..BA */
1511129202Scognet#ifdef __ARMEB__
1512129202Scognet	mov	r2, r2, ror #8		/* r2 = 1..0 */
1513129202Scognet	strb	r2, [r0]
1514129202Scognet	mov	r2, r2, lsr #16		/* r2 = ..1. */
1515129202Scognet	orr	r2, r2, r3, lsr #24	/* r2 = ..12 */
1516129202Scognet	strh	r2, [r0, #0x01]
1517129202Scognet	mov	r2, r3, lsl #8		/* r2 = 345. */
1518129202Scognet	orr	r3, r2, ip, lsr #24	/* r3 = 3456 */
1519129202Scognet	mov	r2, ip, lsl #8		/* r2 = 789. */
1520129202Scognet	orr	r2, r2, r1, lsr #8	/* r2 = 789A */
1521129202Scognet#else
1522129202Scognet	strb	r2, [r0]
1523129202Scognet	mov	r2, r2, lsr #8		/* r2 = ...1 */
1524129202Scognet	orr	r2, r2, r3, lsl #8	/* r2 = 4321 */
1525129202Scognet	strh	r2, [r0, #0x01]
1526129202Scognet	mov	r2, r3, lsr #8		/* r2 = .543 */
1527129202Scognet	orr	r3, r2, ip, lsl #24	/* r3 = 6543 */
1528129202Scognet	mov	r2, ip, lsr #8		/* r2 = .987 */
1529129202Scognet	orr	r2, r2, r1, lsl #24	/* r2 = A987 */
1530129202Scognet	mov	r1, r1, lsr #8		/* r1 = ...B */
1531129202Scognet#endif
1532129202Scognet	str	r3, [r0, #0x03]
1533129202Scognet	str	r2, [r0, #0x07]
1534129202Scognet	strb	r1, [r0, #0x0b]
1535135683Scognet	bx	lr
1536129202Scognet	LMEMCPY_C_PAD
1537129202Scognet
1538129202Scognet/*
1539129202Scognet * 0111: dst is 8-bit aligned (byte 1), src is 8-bit aligned (byte 3)
1540129202Scognet */
1541129202Scognet	ldrb	r2, [r1]
1542129202Scognet	ldr	r3, [r1, #0x01]		/* BE:r3 = 1234  LE:r3 = 4321 */
1543129202Scognet	ldr	ip, [r1, #0x05]		/* BE:ip = 5678  LE:ip = 8765 */
1544129202Scognet	ldr	r1, [r1, #0x09]		/* BE:r1 = 9ABx  LE:r1 = xBA9 */
1545129202Scognet	strb	r2, [r0]
1546129202Scognet#ifdef __ARMEB__
1547129202Scognet	mov	r2, r3, lsr #16		/* r2 = ..12 */
1548129202Scognet	strh	r2, [r0, #0x01]
1549129202Scognet	mov	r3, r3, lsl #16		/* r3 = 34.. */
1550129202Scognet	orr	r3, r3, ip, lsr #16	/* r3 = 3456 */
1551129202Scognet	mov	ip, ip, lsl #16		/* ip = 78.. */
1552129202Scognet	orr	ip, ip, r1, lsr #16	/* ip = 789A */
1553129202Scognet	mov	r1, r1, lsr #8		/* r1 = .9AB */
1554129202Scognet#else
1555129202Scognet	strh	r3, [r0, #0x01]
1556129202Scognet	mov	r3, r3, lsr #16		/* r3 = ..43 */
1557129202Scognet	orr	r3, r3, ip, lsl #16	/* r3 = 6543 */
1558129202Scognet	mov	ip, ip, lsr #16		/* ip = ..87 */
1559129202Scognet	orr	ip, ip, r1, lsl #16	/* ip = A987 */
1560129202Scognet	mov	r1, r1, lsr #16		/* r1 = ..xB */
1561129202Scognet#endif
1562129202Scognet	str	r3, [r0, #0x03]
1563129202Scognet	str	ip, [r0, #0x07]
1564129202Scognet	strb	r1, [r0, #0x0b]
1565135683Scognet	bx	lr
1566129202Scognet	LMEMCPY_C_PAD
1567129202Scognet
1568129202Scognet/*
1569129202Scognet * 1000: dst is 16-bit aligned, src is 32-bit aligned
1570129202Scognet */
1571129202Scognet	ldr	ip, [r1]		/* BE:ip = 0123  LE:ip = 3210 */
1572129202Scognet	ldr	r3, [r1, #0x04]		/* BE:r3 = 4567  LE:r3 = 7654 */
1573129202Scognet	ldr	r2, [r1, #0x08]		/* BE:r2 = 89AB  LE:r2 = BA98 */
1574129202Scognet	mov	r1, ip, lsr #16		/* BE:r1 = ..01  LE:r1 = ..32 */
1575129202Scognet#ifdef __ARMEB__
1576129202Scognet	strh	r1, [r0]
1577129202Scognet	mov	r1, ip, lsl #16		/* r1 = 23.. */
1578129202Scognet	orr	r1, r1, r3, lsr #16	/* r1 = 2345 */
1579129202Scognet	mov	r3, r3, lsl #16		/* r3 = 67.. */
1580129202Scognet	orr	r3, r3, r2, lsr #16	/* r3 = 6789 */
1581129202Scognet#else
1582129202Scognet	strh	ip, [r0]
1583129202Scognet	orr	r1, r1, r3, lsl #16	/* r1 = 5432 */
1584129202Scognet	mov	r3, r3, lsr #16		/* r3 = ..76 */
1585129202Scognet	orr	r3, r3, r2, lsl #16	/* r3 = 9876 */
1586129202Scognet	mov	r2, r2, lsr #16		/* r2 = ..BA */
1587129202Scognet#endif
1588129202Scognet	str	r1, [r0, #0x02]
1589129202Scognet	str	r3, [r0, #0x06]
1590129202Scognet	strh	r2, [r0, #0x0a]
1591135683Scognet	bx	lr
1592129202Scognet	LMEMCPY_C_PAD
1593129202Scognet
1594129202Scognet/*
1595129202Scognet * 1001: dst is 16-bit aligned, src is 8-bit aligned (byte 1)
1596129202Scognet */
1597129202Scognet	ldr	r2, [r1, #-1]		/* BE:r2 = x012  LE:r2 = 210x */
1598129202Scognet	ldr	r3, [r1, #0x03]		/* BE:r3 = 3456  LE:r3 = 6543 */
1599129202Scognet	mov	ip, r2, lsr #8		/* BE:ip = .x01  LE:ip = .210 */
1600129202Scognet	strh	ip, [r0]
1601129202Scognet	ldr	ip, [r1, #0x07]		/* BE:ip = 789A  LE:ip = A987 */
1602129202Scognet	ldrb	r1, [r1, #0x0b]		/* r1 = ...B */
1603129202Scognet#ifdef __ARMEB__
1604129202Scognet	mov	r2, r2, lsl #24		/* r2 = 2... */
1605129202Scognet	orr	r2, r2, r3, lsr #8	/* r2 = 2345 */
1606129202Scognet	mov	r3, r3, lsl #24		/* r3 = 6... */
1607129202Scognet	orr	r3, r3, ip, lsr #8	/* r3 = 6789 */
1608129202Scognet	orr	r1, r1, ip, lsl #8	/* r1 = 89AB */
1609129202Scognet#else
1610129202Scognet	mov	r2, r2, lsr #24		/* r2 = ...2 */
1611129202Scognet	orr	r2, r2, r3, lsl #8	/* r2 = 5432 */
1612129202Scognet	mov	r3, r3, lsr #24		/* r3 = ...6 */
1613129202Scognet	orr	r3, r3, ip, lsl #8	/* r3 = 9876 */
1614129202Scognet	mov	r1, r1, lsl #8		/* r1 = ..B. */
1615129202Scognet	orr	r1, r1, ip, lsr #24	/* r1 = ..BA */
1616129202Scognet#endif
1617129202Scognet	str	r2, [r0, #0x02]
1618129202Scognet	str	r3, [r0, #0x06]
1619129202Scognet	strh	r1, [r0, #0x0a]
1620135683Scognet	bx	lr
1621129202Scognet	LMEMCPY_C_PAD
1622129202Scognet
1623129202Scognet/*
1624129202Scognet * 1010: dst is 16-bit aligned, src is 16-bit aligned
1625129202Scognet */
1626129202Scognet	ldrh	r2, [r1]
1627129202Scognet	ldr	r3, [r1, #0x02]
1628129202Scognet	ldr	ip, [r1, #0x06]
1629129202Scognet	ldrh	r1, [r1, #0x0a]
1630129202Scognet	strh	r2, [r0]
1631129202Scognet	str	r3, [r0, #0x02]
1632129202Scognet	str	ip, [r0, #0x06]
1633129202Scognet	strh	r1, [r0, #0x0a]
1634135683Scognet	bx	lr
1635129202Scognet	LMEMCPY_C_PAD
1636129202Scognet
1637129202Scognet/*
1638129202Scognet * 1011: dst is 16-bit aligned, src is 8-bit aligned (byte 3)
1639129202Scognet */
1640129202Scognet	ldr	r2, [r1, #0x09]		/* BE:r2 = 9ABx  LE:r2 = xBA9 */
1641129202Scognet	ldr	r3, [r1, #0x05]		/* BE:r3 = 5678  LE:r3 = 8765 */
1642129202Scognet	mov	ip, r2, lsr #8		/* BE:ip = .9AB  LE:ip = .xBA */
1643129202Scognet	strh	ip, [r0, #0x0a]
1644129202Scognet	ldr	ip, [r1, #0x01]		/* BE:ip = 1234  LE:ip = 4321 */
1645129202Scognet	ldrb	r1, [r1]		/* r1 = ...0 */
1646129202Scognet#ifdef __ARMEB__
1647129202Scognet	mov	r2, r2, lsr #24		/* r2 = ...9 */
1648129202Scognet	orr	r2, r2, r3, lsl #8	/* r2 = 6789 */
1649129202Scognet	mov	r3, r3, lsr #24		/* r3 = ...5 */
1650129202Scognet	orr	r3, r3, ip, lsl #8	/* r3 = 2345 */
1651129202Scognet	mov	r1, r1, lsl #8		/* r1 = ..0. */
1652129202Scognet	orr	r1, r1, ip, lsr #24	/* r1 = ..01 */
1653129202Scognet#else
1654129202Scognet	mov	r2, r2, lsl #24		/* r2 = 9... */
1655129202Scognet	orr	r2, r2, r3, lsr #8	/* r2 = 9876 */
1656129202Scognet	mov	r3, r3, lsl #24		/* r3 = 5... */
1657129202Scognet	orr	r3, r3, ip, lsr #8	/* r3 = 5432 */
1658129202Scognet	orr	r1, r1, ip, lsl #8	/* r1 = 3210 */
1659129202Scognet#endif
1660129202Scognet	str	r2, [r0, #0x06]
1661129202Scognet	str	r3, [r0, #0x02]
1662129202Scognet	strh	r1, [r0]
1663135683Scognet	bx	lr
1664129202Scognet	LMEMCPY_C_PAD
1665129202Scognet
1666129202Scognet/*
1667129202Scognet * 1100: dst is 8-bit aligned (byte 3), src is 32-bit aligned
1668129202Scognet */
1669129202Scognet	ldr	r2, [r1]		/* BE:r2 = 0123  LE:r2 = 3210 */
1670129202Scognet	ldr	ip, [r1, #0x04]		/* BE:ip = 4567  LE:ip = 7654 */
1671129202Scognet	ldr	r1, [r1, #0x08]		/* BE:r1 = 89AB  LE:r1 = BA98 */
1672129202Scognet#ifdef __ARMEB__
1673129202Scognet	mov	r3, r2, lsr #24		/* r3 = ...0 */
1674129202Scognet	strb	r3, [r0]
1675129202Scognet	mov	r2, r2, lsl #8		/* r2 = 123. */
1676129202Scognet	orr	r2, r2, ip, lsr #24	/* r2 = 1234 */
1677129202Scognet	str	r2, [r0, #0x01]
1678129202Scognet	mov	r2, ip, lsl #8		/* r2 = 567. */
1679129202Scognet	orr	r2, r2, r1, lsr #24	/* r2 = 5678 */
1680129202Scognet	str	r2, [r0, #0x05]
1681129202Scognet	mov	r2, r1, lsr #8		/* r2 = ..9A */
1682129202Scognet	strh	r2, [r0, #0x09]
1683129202Scognet	strb	r1, [r0, #0x0b]
1684129202Scognet#else
1685129202Scognet	strb	r2, [r0]
1686129202Scognet	mov	r3, r2, lsr #8		/* r3 = .321 */
1687129202Scognet	orr	r3, r3, ip, lsl #24	/* r3 = 4321 */
1688129202Scognet	str	r3, [r0, #0x01]
1689129202Scognet	mov	r3, ip, lsr #8		/* r3 = .765 */
1690129202Scognet	orr	r3, r3, r1, lsl #24	/* r3 = 8765 */
1691129202Scognet	str	r3, [r0, #0x05]
1692129202Scognet	mov	r1, r1, lsr #8		/* r1 = .BA9 */
1693129202Scognet	strh	r1, [r0, #0x09]
1694129202Scognet	mov	r1, r1, lsr #16		/* r1 = ...B */
1695129202Scognet	strb	r1, [r0, #0x0b]
1696129202Scognet#endif
1697135683Scognet	bx	lr
1698129202Scognet	LMEMCPY_C_PAD
1699129202Scognet
1700129202Scognet/*
1701129202Scognet * 1101: dst is 8-bit aligned (byte 3), src is 8-bit aligned (byte 1)
1702129202Scognet */
1703129202Scognet	ldrb	r2, [r1, #0x0b]		/* r2 = ...B */
1704129202Scognet	ldr	r3, [r1, #0x07]		/* BE:r3 = 789A  LE:r3 = A987 */
1705129202Scognet	ldr	ip, [r1, #0x03]		/* BE:ip = 3456  LE:ip = 6543 */
1706129202Scognet	ldr	r1, [r1, #-1]		/* BE:r1 = x012  LE:r1 = 210x */
1707129202Scognet	strb	r2, [r0, #0x0b]
1708129202Scognet#ifdef __ARMEB__
1709129202Scognet	strh	r3, [r0, #0x09]
1710129202Scognet	mov	r3, r3, lsr #16		/* r3 = ..78 */
1711129202Scognet	orr	r3, r3, ip, lsl #16	/* r3 = 5678 */
1712129202Scognet	mov	ip, ip, lsr #16		/* ip = ..34 */
1713129202Scognet	orr	ip, ip, r1, lsl #16	/* ip = 1234 */
1714129202Scognet	mov	r1, r1, lsr #16		/* r1 = ..x0 */
1715129202Scognet#else
1716129202Scognet	mov	r2, r3, lsr #16		/* r2 = ..A9 */
1717129202Scognet	strh	r2, [r0, #0x09]
1718129202Scognet	mov	r3, r3, lsl #16		/* r3 = 87.. */
1719129202Scognet	orr	r3, r3, ip, lsr #16	/* r3 = 8765 */
1720129202Scognet	mov	ip, ip, lsl #16		/* ip = 43.. */
1721129202Scognet	orr	ip, ip, r1, lsr #16	/* ip = 4321 */
1722129202Scognet	mov	r1, r1, lsr #8		/* r1 = .210 */
1723129202Scognet#endif
1724129202Scognet	str	r3, [r0, #0x05]
1725129202Scognet	str	ip, [r0, #0x01]
1726129202Scognet	strb	r1, [r0]
1727135683Scognet	bx	lr
1728129202Scognet	LMEMCPY_C_PAD
1729129202Scognet
1730129202Scognet/*
1731129202Scognet * 1110: dst is 8-bit aligned (byte 3), src is 16-bit aligned
1732129202Scognet */
1733129202Scognet#ifdef __ARMEB__
1734129202Scognet	ldrh	r2, [r1, #0x0a]		/* r2 = ..AB */
1735129202Scognet	ldr	ip, [r1, #0x06]		/* ip = 6789 */
1736129202Scognet	ldr	r3, [r1, #0x02]		/* r3 = 2345 */
1737129202Scognet	ldrh	r1, [r1]		/* r1 = ..01 */
1738129202Scognet	strb	r2, [r0, #0x0b]
1739129202Scognet	mov	r2, r2, lsr #8		/* r2 = ...A */
1740129202Scognet	orr	r2, r2, ip, lsl #8	/* r2 = 789A */
1741129202Scognet	mov	ip, ip, lsr #8		/* ip = .678 */
1742129202Scognet	orr	ip, ip, r3, lsl #24	/* ip = 5678 */
1743129202Scognet	mov	r3, r3, lsr #8		/* r3 = .234 */
1744129202Scognet	orr	r3, r3, r1, lsl #24	/* r3 = 1234 */
1745129202Scognet	mov	r1, r1, lsr #8		/* r1 = ...0 */
1746129202Scognet	strb	r1, [r0]
1747129202Scognet	str	r3, [r0, #0x01]
1748129202Scognet	str	ip, [r0, #0x05]
1749129202Scognet	strh	r2, [r0, #0x09]
1750129202Scognet#else
1751129202Scognet	ldrh	r2, [r1]		/* r2 = ..10 */
1752129202Scognet	ldr	r3, [r1, #0x02]		/* r3 = 5432 */
1753129202Scognet	ldr	ip, [r1, #0x06]		/* ip = 9876 */
1754129202Scognet	ldrh	r1, [r1, #0x0a]		/* r1 = ..BA */
1755129202Scognet	strb	r2, [r0]
1756129202Scognet	mov	r2, r2, lsr #8		/* r2 = ...1 */
1757129202Scognet	orr	r2, r2, r3, lsl #8	/* r2 = 4321 */
1758129202Scognet	mov	r3, r3, lsr #24		/* r3 = ...5 */
1759129202Scognet	orr	r3, r3, ip, lsl #8	/* r3 = 8765 */
1760129202Scognet	mov	ip, ip, lsr #24		/* ip = ...9 */
1761129202Scognet	orr	ip, ip, r1, lsl #8	/* ip = .BA9 */
1762129202Scognet	mov	r1, r1, lsr #8		/* r1 = ...B */
1763129202Scognet	str	r2, [r0, #0x01]
1764129202Scognet	str	r3, [r0, #0x05]
1765129202Scognet	strh	ip, [r0, #0x09]
1766129202Scognet	strb	r1, [r0, #0x0b]
1767129202Scognet#endif
1768135683Scognet	bx	lr
1769129202Scognet	LMEMCPY_C_PAD
1770129202Scognet
1771129202Scognet/*
1772129202Scognet * 1111: dst is 8-bit aligned (byte 3), src is 8-bit aligned (byte 3)
1773129202Scognet */
1774129202Scognet	ldrb	r2, [r1]
1775129202Scognet	ldr	r3, [r1, #0x01]
1776129202Scognet	ldr	ip, [r1, #0x05]
1777129202Scognet	strb	r2, [r0]
1778129202Scognet	ldrh	r2, [r1, #0x09]
1779129202Scognet	ldrb	r1, [r1, #0x0b]
1780129202Scognet	str	r3, [r0, #0x01]
1781129202Scognet	str	ip, [r0, #0x05]
1782129202Scognet	strh	r2, [r0, #0x09]
1783129202Scognet	strb	r1, [r0, #0x0b]
1784135683Scognet	bx	lr
1785129202Scognet#endif	/* !_STANDALONE */
1786270882SianEND(memcpy)
1787288373Skib
1788288373Skib	.section .note.GNU-stack,"",%progbits
1789