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 | |