Linux-libre 5.7.3-gnu
[librecmc/linux-libre.git] / arch / arm / lib / io-readsw-armv4.S
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 /*
3  *  linux/arch/arm/lib/io-readsw-armv4.S
4  *
5  *  Copyright (C) 1995-2000 Russell King
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)