xref: /linux/arch/arm/lib/io-readsb.S (revision f3a8b6645dc2e60d11f20c1c23afd964ff4e55ae)
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#include <asm/export.h>
13
14.Linsb_align:	rsb	ip, ip, #4
15		cmp	ip, r2
16		movgt	ip, r2
17		cmp	ip, #2
18		ldrb	r3, [r0]
19		strb	r3, [r1], #1
20		ldrgeb	r3, [r0]
21		strgeb	r3, [r1], #1
22		ldrgtb	r3, [r0]
23		strgtb	r3, [r1], #1
24		subs	r2, r2, ip
25		bne	.Linsb_aligned
26
27ENTRY(__raw_readsb)
28		teq	r2, #0		@ do we have to check for the zero len?
29		reteq	lr
30		ands	ip, r1, #3
31		bne	.Linsb_align
32
33.Linsb_aligned:	stmfd	sp!, {r4 - r6, lr}
34
35		subs	r2, r2, #16
36		bmi	.Linsb_no_16
37
38.Linsb_16_lp:	ldrb	r3, [r0]
39		ldrb	r4, [r0]
40		ldrb	r5, [r0]
41		mov	r3, r3,     put_byte_0
42		ldrb	r6, [r0]
43		orr	r3, r3, r4, put_byte_1
44		ldrb	r4, [r0]
45		orr	r3, r3, r5, put_byte_2
46		ldrb	r5, [r0]
47		orr	r3, r3, r6, put_byte_3
48		ldrb	r6, [r0]
49		mov	r4, r4,     put_byte_0
50		ldrb	ip, [r0]
51		orr	r4, r4, r5, put_byte_1
52		ldrb	r5, [r0]
53		orr	r4, r4, r6, put_byte_2
54		ldrb	r6, [r0]
55		orr	r4, r4, ip, put_byte_3
56		ldrb	ip, [r0]
57		mov	r5, r5,     put_byte_0
58		ldrb	lr, [r0]
59		orr	r5, r5, r6, put_byte_1
60		ldrb	r6, [r0]
61		orr	r5, r5, ip, put_byte_2
62		ldrb	ip, [r0]
63		orr	r5, r5, lr, put_byte_3
64		ldrb	lr, [r0]
65		mov	r6, r6,     put_byte_0
66		orr	r6, r6, ip, put_byte_1
67		ldrb	ip, [r0]
68		orr	r6, r6, lr, put_byte_2
69		orr	r6, r6, ip, put_byte_3
70		stmia	r1!, {r3 - r6}
71
72		subs	r2, r2, #16
73		bpl	.Linsb_16_lp
74
75		tst	r2, #15
76		ldmeqfd	sp!, {r4 - r6, pc}
77
78.Linsb_no_16:	tst	r2, #8
79		beq	.Linsb_no_8
80
81		ldrb	r3, [r0]
82		ldrb	r4, [r0]
83		ldrb	r5, [r0]
84		mov	r3, r3,     put_byte_0
85		ldrb	r6, [r0]
86		orr	r3, r3, r4, put_byte_1
87		ldrb	r4, [r0]
88		orr	r3, r3, r5, put_byte_2
89		ldrb	r5, [r0]
90		orr	r3, r3, r6, put_byte_3
91		ldrb	r6, [r0]
92		mov	r4, r4,     put_byte_0
93		ldrb	ip, [r0]
94		orr	r4, r4, r5, put_byte_1
95		orr	r4, r4, r6, put_byte_2
96		orr	r4, r4, ip, put_byte_3
97		stmia	r1!, {r3, r4}
98
99.Linsb_no_8:	tst	r2, #4
100		beq	.Linsb_no_4
101
102		ldrb	r3, [r0]
103		ldrb	r4, [r0]
104		ldrb	r5, [r0]
105		ldrb	r6, [r0]
106		mov	r3, r3,     put_byte_0
107		orr	r3, r3, r4, put_byte_1
108		orr	r3, r3, r5, put_byte_2
109		orr	r3, r3, r6, put_byte_3
110		str	r3, [r1], #4
111
112.Linsb_no_4:	ands	r2, r2, #3
113		ldmeqfd	sp!, {r4 - r6, pc}
114
115		cmp	r2, #2
116		ldrb	r3, [r0]
117		strb	r3, [r1], #1
118		ldrgeb	r3, [r0]
119		strgeb	r3, [r1], #1
120		ldrgtb	r3, [r0]
121		strgtb	r3, [r1]
122
123		ldmfd	sp!, {r4 - r6, pc}
124ENDPROC(__raw_readsb)
125EXPORT_SYMBOL(__raw_readsb)
126