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