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