blob: d9a45e9692aee3ad1de5dea37653a65cd8c18da4 [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/*
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
Nicolas Pitrea9c48142005-11-11 21:51:48 +000021.Linsw_align: movs ip, r1, lsl #31
22 bne .Linsw_noalign
Linus Torvalds1da177e2005-04-16 15:20:36 -070023 ldrh ip, [r0]
24 sub r2, r2, #1
25 strh ip, [r1], #2
26
27ENTRY(__raw_readsw)
28 teq r2, #0
Russell King6ebbf2c2014-06-30 16:29:12 +010029 reteq lr
Linus Torvalds1da177e2005-04-16 15:20:36 -070030 tst r1, #3
Nicolas Pitrea9c48142005-11-11 21:51:48 +000031 bne .Linsw_align
Linus Torvalds1da177e2005-04-16 15:20:36 -070032
33 stmfd sp!, {r4, r5, lr}
34
35 subs r2, r2, #8
Nicolas Pitrea9c48142005-11-11 21:51:48 +000036 bmi .Lno_insw_8
Linus Torvalds1da177e2005-04-16 15:20:36 -070037
Nicolas Pitrea9c48142005-11-11 21:51:48 +000038.Linsw_8_lp: ldrh r3, [r0]
Linus Torvalds1da177e2005-04-16 15:20:36 -070039 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}
Nicolas Pitrea9c48142005-11-11 21:51:48 +000056 bpl .Linsw_8_lp
Linus Torvalds1da177e2005-04-16 15:20:36 -070057
Nicolas Pitrea9c48142005-11-11 21:51:48 +000058.Lno_insw_8: tst r2, #4
59 beq .Lno_insw_4
Linus Torvalds1da177e2005-04-16 15:20:36 -070060
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
Nicolas Pitrea9c48142005-11-11 21:51:48 +000071.Lno_insw_4: movs r2, r2, lsl #31
72 bcc .Lno_insw_2
Linus Torvalds1da177e2005-04-16 15:20:36 -070073
74 ldrh r3, [r0]
75 ldrh ip, [r0]
76 pack r3, r3, ip
77 str r3, [r1], #4
78
Nicolas Pitrea9c48142005-11-11 21:51:48 +000079.Lno_insw_2: ldrneh r3, [r0]
Linus Torvalds1da177e2005-04-16 15:20:36 -070080 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
Nicolas Pitrea9c48142005-11-11 21:51:48 +000096.Linsw_noalign: stmfd sp!, {r4, lr}
Linus Torvalds1da177e2005-04-16 15:20:36 -070097 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
1071: subs r2, r2, #2
108 bmi 3f
109 _BE_ONLY_( mov ip, ip, lsl #24 )
110
1112: 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
1223: 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}
Catalin Marinas93ed3972008-08-28 11:22:32 +0100131ENDPROC(__raw_readsw)