1/*
2 *  linux/arch/arm/lib/io-readsb.S
3 *
4 *  Copyright (C) 1995-2000 Russell King
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10#include <linux/linkage.h>
11#include <asm/assembler.h>
12
13.Linsb_align:	rsb	ip, ip, #4
14		cmp	ip, r2
15		movgt	ip, r2
16		cmp	ip, #2
17		ldrb	r3, [r0]
18		strb	r3, [r1], #1
19		ldrgeb	r3, [r0]
20		strgeb	r3, [r1], #1
21		ldrgtb	r3, [r0]
22		strgtb	r3, [r1], #1
23		subs	r2, r2, ip
24		bne	.Linsb_aligned
25
26ENTRY(__raw_readsb)
27		teq	r2, #0		@ do we have to check for the zero len?
28		reteq	lr
29		ands	ip, r1, #3
30		bne	.Linsb_align
31
32.Linsb_aligned:	stmfd	sp!, {r4 - r6, lr}
33
34		subs	r2, r2, #16
35		bmi	.Linsb_no_16
36
37.Linsb_16_lp:	ldrb	r3, [r0]
38		ldrb	r4, [r0]
39		ldrb	r5, [r0]
40		mov	r3, r3,     put_byte_0
41		ldrb	r6, [r0]
42		orr	r3, r3, r4, put_byte_1
43		ldrb	r4, [r0]
44		orr	r3, r3, r5, put_byte_2
45		ldrb	r5, [r0]
46		orr	r3, r3, r6, put_byte_3
47		ldrb	r6, [r0]
48		mov	r4, r4,     put_byte_0
49		ldrb	ip, [r0]
50		orr	r4, r4, r5, put_byte_1
51		ldrb	r5, [r0]
52		orr	r4, r4, r6, put_byte_2
53		ldrb	r6, [r0]
54		orr	r4, r4, ip, put_byte_3
55		ldrb	ip, [r0]
56		mov	r5, r5,     put_byte_0
57		ldrb	lr, [r0]
58		orr	r5, r5, r6, put_byte_1
59		ldrb	r6, [r0]
60		orr	r5, r5, ip, put_byte_2
61		ldrb	ip, [r0]
62		orr	r5, r5, lr, put_byte_3
63		ldrb	lr, [r0]
64		mov	r6, r6,     put_byte_0
65		orr	r6, r6, ip, put_byte_1
66		ldrb	ip, [r0]
67		orr	r6, r6, lr, put_byte_2
68		orr	r6, r6, ip, put_byte_3
69		stmia	r1!, {r3 - r6}
70
71		subs	r2, r2, #16
72		bpl	.Linsb_16_lp
73
74		tst	r2, #15
75		ldmeqfd	sp!, {r4 - r6, pc}
76
77.Linsb_no_16:	tst	r2, #8
78		beq	.Linsb_no_8
79
80		ldrb	r3, [r0]
81		ldrb	r4, [r0]
82		ldrb	r5, [r0]
83		mov	r3, r3,     put_byte_0
84		ldrb	r6, [r0]
85		orr	r3, r3, r4, put_byte_1
86		ldrb	r4, [r0]
87		orr	r3, r3, r5, put_byte_2
88		ldrb	r5, [r0]
89		orr	r3, r3, r6, put_byte_3
90		ldrb	r6, [r0]
91		mov	r4, r4,     put_byte_0
92		ldrb	ip, [r0]
93		orr	r4, r4, r5, put_byte_1
94		orr	r4, r4, r6, put_byte_2
95		orr	r4, r4, ip, put_byte_3
96		stmia	r1!, {r3, r4}
97
98.Linsb_no_8:	tst	r2, #4
99		beq	.Linsb_no_4
100
101		ldrb	r3, [r0]
102		ldrb	r4, [r0]
103		ldrb	r5, [r0]
104		ldrb	r6, [r0]
105		mov	r3, r3,     put_byte_0
106		orr	r3, r3, r4, put_byte_1
107		orr	r3, r3, r5, put_byte_2
108		orr	r3, r3, r6, put_byte_3
109		str	r3, [r1], #4
110
111.Linsb_no_4:	ands	r2, r2, #3
112		ldmeqfd	sp!, {r4 - r6, pc}
113
114		cmp	r2, #2
115		ldrb	r3, [r0]
116		strb	r3, [r1], #1
117		ldrgeb	r3, [r0]
118		strgeb	r3, [r1], #1
119		ldrgtb	r3, [r0]
120		strgtb	r3, [r1]
121
122		ldmfd	sp!, {r4 - r6, pc}
123ENDPROC(__raw_readsb)
124