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
27ENTRY(__raw_readsw)
28		teq	r2, #0
29		reteq	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
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}
131ENDPROC(__raw_readsw)
132