ARM: 6945/1: Add unwinding support for division functions
[pandora-kernel.git] / arch / arm / lib / io-readsw-armv4.S
1 /*
2  *  linux/arch/arm/lib/io-readsw-armv4.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                 .macro  pack, rd, hw1, hw2
14 #ifndef __ARMEB__
15                 orr     \rd, \hw1, \hw2, lsl #16
16 #else
17                 orr     \rd, \hw2, \hw1, lsl #16
18 #endif
19                 .endm
20
21 .Linsw_align:   movs    ip, r1, lsl #31
22                 bne     .Linsw_noalign
23                 ldrh    ip, [r0]
24                 sub     r2, r2, #1
25                 strh    ip, [r1], #2
26
27 ENTRY(__raw_readsw)
28                 teq     r2, #0
29                 moveq   pc, lr
30                 tst     r1, #3
31                 bne     .Linsw_align
32
33                 stmfd   sp!, {r4, r5, lr}
34
35                 subs    r2, r2, #8
36                 bmi     .Lno_insw_8
37
38 .Linsw_8_lp:    ldrh    r3, [r0]
39                 ldrh    r4, [r0]
40                 pack    r3, r3, r4
41
42                 ldrh    r4, [r0]
43                 ldrh    r5, [r0]
44                 pack    r4, r4, r5
45
46                 ldrh    r5, [r0]
47                 ldrh    ip, [r0]
48                 pack    r5, r5, ip
49
50                 ldrh    ip, [r0]
51                 ldrh    lr, [r0]
52                 pack    ip, ip, lr
53
54                 subs    r2, r2, #8
55                 stmia   r1!, {r3 - r5, ip}
56                 bpl     .Linsw_8_lp
57
58 .Lno_insw_8:    tst     r2, #4
59                 beq     .Lno_insw_4
60
61                 ldrh    r3, [r0]
62                 ldrh    r4, [r0]
63                 pack    r3, r3, r4
64
65                 ldrh    r4, [r0]
66                 ldrh    ip, [r0]
67                 pack    r4, r4, ip
68
69                 stmia   r1!, {r3, r4}
70
71 .Lno_insw_4:    movs    r2, r2, lsl #31
72                 bcc     .Lno_insw_2
73
74                 ldrh    r3, [r0]
75                 ldrh    ip, [r0]
76                 pack    r3, r3, ip
77                 str     r3, [r1], #4
78
79 .Lno_insw_2:    ldrneh  r3, [r0]
80                 strneh  r3, [r1]
81
82                 ldmfd   sp!, {r4, r5, pc}
83
84 #ifdef __ARMEB__
85 #define _BE_ONLY_(code...)      code
86 #define _LE_ONLY_(code...)
87 #define push_hbyte0             lsr #8
88 #define pull_hbyte1             lsl #24
89 #else
90 #define _BE_ONLY_(code...)
91 #define _LE_ONLY_(code...) code
92 #define push_hbyte0             lsl #24
93 #define pull_hbyte1             lsr #8
94 #endif
95
96 .Linsw_noalign: stmfd   sp!, {r4, lr}
97                 ldrccb  ip, [r1, #-1]!
98                 bcc     1f
99
100                 ldrh    ip, [r0]
101                 sub     r2, r2, #1
102    _BE_ONLY_(   mov     ip, ip, ror #8          )
103                 strb    ip, [r1], #1
104    _LE_ONLY_(   mov     ip, ip, lsr #8          )
105    _BE_ONLY_(   mov     ip, ip, lsr #24         )
106
107 1:              subs    r2, r2, #2
108                 bmi     3f
109    _BE_ONLY_(   mov     ip, ip, lsl #24         )
110
111 2:              ldrh    r3, [r0]
112                 ldrh    r4, [r0]
113                 subs    r2, r2, #2
114                 orr     ip, ip, r3, lsl #8
115                 orr     ip, ip, r4, push_hbyte0
116                 str     ip, [r1], #4
117                 mov     ip, r4, pull_hbyte1
118                 bpl     2b
119
120    _BE_ONLY_(   mov     ip, ip, lsr #24         )
121
122 3:              tst     r2, #1
123                 strb    ip, [r1], #1
124                 ldrneh  ip, [r0]
125    _BE_ONLY_(   movne   ip, ip, ror #8          )
126                 strneb  ip, [r1], #1
127    _LE_ONLY_(   movne   ip, ip, lsr #8          )
128    _BE_ONLY_(   movne   ip, ip, lsr #24         )
129                 strneb  ip, [r1]
130                 ldmfd   sp!, {r4, pc}
131 ENDPROC(__raw_readsw)