Linux-2.6.12-rc2
[linux-3.10.git] / arch / arm / lib / io-readsb.S
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 .insb_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     .insb_aligned
25
26 ENTRY(__raw_readsb)
27                 teq     r2, #0          @ do we have to check for the zero len?
28                 moveq   pc, lr
29                 ands    ip, r1, #3
30                 bne     .insb_align
31
32 .insb_aligned:  stmfd   sp!, {r4 - r6, lr}
33
34                 subs    r2, r2, #16
35                 bmi     .insb_no_16
36
37 .insb_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     .insb_16_lp
73
74                 tst     r2, #15
75                 LOADREGS(eqfd, sp!, {r4 - r6, pc})
76
77 .insb_no_16:    tst     r2, #8
78                 beq     .insb_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 .insb_no_8:     tst     r2, #4
99                 beq     .insb_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 .insb_no_4:     ands    r2, r2, #3
112                 LOADREGS(eqfd, 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                 LOADREGS(fd, sp!, {r4 - r6, pc})