blob: 228c176a94d1e4b5d5d27e79da6817ba732f15a9 [file] [log] [blame]
Thomas Gleixnerd2912cb2019-06-04 10:11:33 +02001/* SPDX-License-Identifier: GPL-2.0-only */
Linus Torvalds1da177e2005-04-16 15:20:36 -07002/*
3 * linux/arch/arm/lib/io-readsw-armv4.S
4 *
5 * Copyright (C) 1995-2000 Russell King
Linus Torvalds1da177e2005-04-16 15:20:36 -07006 */
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
Nicolas Pitrea9c48142005-11-11 21:51:48 +000018.Linsw_align: movs ip, r1, lsl #31
19 bne .Linsw_noalign
Linus Torvalds1da177e2005-04-16 15:20:36 -070020 ldrh ip, [r0]
21 sub r2, r2, #1
22 strh ip, [r1], #2
23
24ENTRY(__raw_readsw)
25 teq r2, #0
Russell King6ebbf2c2014-06-30 16:29:12 +010026 reteq lr
Linus Torvalds1da177e2005-04-16 15:20:36 -070027 tst r1, #3
Nicolas Pitrea9c48142005-11-11 21:51:48 +000028 bne .Linsw_align
Linus Torvalds1da177e2005-04-16 15:20:36 -070029
30 stmfd sp!, {r4, r5, lr}
31
32 subs r2, r2, #8
Nicolas Pitrea9c48142005-11-11 21:51:48 +000033 bmi .Lno_insw_8
Linus Torvalds1da177e2005-04-16 15:20:36 -070034
Nicolas Pitrea9c48142005-11-11 21:51:48 +000035.Linsw_8_lp: ldrh r3, [r0]
Linus Torvalds1da177e2005-04-16 15:20:36 -070036 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}
Nicolas Pitrea9c48142005-11-11 21:51:48 +000053 bpl .Linsw_8_lp
Linus Torvalds1da177e2005-04-16 15:20:36 -070054
Nicolas Pitrea9c48142005-11-11 21:51:48 +000055.Lno_insw_8: tst r2, #4
56 beq .Lno_insw_4
Linus Torvalds1da177e2005-04-16 15:20:36 -070057
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
Nicolas Pitrea9c48142005-11-11 21:51:48 +000068.Lno_insw_4: movs r2, r2, lsl #31
69 bcc .Lno_insw_2
Linus Torvalds1da177e2005-04-16 15:20:36 -070070
71 ldrh r3, [r0]
72 ldrh ip, [r0]
73 pack r3, r3, ip
74 str r3, [r1], #4
75
Stefan Agnere44fc382019-02-18 00:57:38 +010076.Lno_insw_2: ldrhne r3, [r0]
77 strhne r3, [r1]
Linus Torvalds1da177e2005-04-16 15:20:36 -070078
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
Nicolas Pitrea9c48142005-11-11 21:51:48 +000093.Linsw_noalign: stmfd sp!, {r4, lr}
Stefan Agnere44fc382019-02-18 00:57:38 +010094 ldrbcc ip, [r1, #-1]!
Linus Torvalds1da177e2005-04-16 15:20:36 -070095 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
1041: subs r2, r2, #2
105 bmi 3f
106 _BE_ONLY_( mov ip, ip, lsl #24 )
107
1082: 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
1193: tst r2, #1
120 strb ip, [r1], #1
Stefan Agnere44fc382019-02-18 00:57:38 +0100121 ldrhne ip, [r0]
Linus Torvalds1da177e2005-04-16 15:20:36 -0700122 _BE_ONLY_( movne ip, ip, ror #8 )
Stefan Agnere44fc382019-02-18 00:57:38 +0100123 strbne ip, [r1], #1
Linus Torvalds1da177e2005-04-16 15:20:36 -0700124 _LE_ONLY_( movne ip, ip, lsr #8 )
125 _BE_ONLY_( movne ip, ip, lsr #24 )
Stefan Agnere44fc382019-02-18 00:57:38 +0100126 strbne ip, [r1]
Linus Torvalds1da177e2005-04-16 15:20:36 -0700127 ldmfd sp!, {r4, pc}
Catalin Marinas93ed3972008-08-28 11:22:32 +0100128ENDPROC(__raw_readsw)