xref: /linux/arch/arm/lib/io-readsw-armv3.S (revision 75bf465f0bc33e9b776a46d6a1b9b990f5fb7c37)
1/* SPDX-License-Identifier: GPL-2.0-only */
2/*
3 *  linux/arch/arm/lib/io-readsw-armv3.S
4 *
5 *  Copyright (C) 1995-2000 Russell King
6 */
7#include <linux/linkage.h>
8#include <asm/assembler.h>
9
10.Linsw_bad_alignment:
11		adr	r0, .Linsw_bad_align_msg
12		mov	r2, lr
13		b	panic
14.Linsw_bad_align_msg:
15		.asciz	"insw: bad buffer alignment (0x%p, lr=0x%08lX)\n"
16		.align
17
18.Linsw_align:	tst	r1, #1
19		bne	.Linsw_bad_alignment
20
21		ldr	r3, [r0]
22		strb	r3, [r1], #1
23		mov	r3, r3, lsr #8
24		strb	r3, [r1], #1
25
26		subs	r2, r2, #1
27		reteq	lr
28
29ENTRY(__raw_readsw)
30		teq	r2, #0		@ do we have to check for the zero len?
31		reteq	lr
32		tst	r1, #3
33		bne	.Linsw_align
34
35.Linsw_aligned:	mov	ip, #0xff
36		orr	ip, ip, ip, lsl #8
37		stmfd	sp!, {r4, r5, r6, lr}
38
39		subs	r2, r2, #8
40		bmi	.Lno_insw_8
41
42.Linsw_8_lp:	ldr	r3, [r0]
43		and	r3, r3, ip
44		ldr	r4, [r0]
45		orr	r3, r3, r4, lsl #16
46
47		ldr	r4, [r0]
48		and	r4, r4, ip
49		ldr	r5, [r0]
50		orr	r4, r4, r5, lsl #16
51
52		ldr	r5, [r0]
53		and	r5, r5, ip
54		ldr	r6, [r0]
55		orr	r5, r5, r6, lsl #16
56
57		ldr	r6, [r0]
58		and	r6, r6, ip
59		ldr	lr, [r0]
60		orr	r6, r6, lr, lsl #16
61
62		stmia	r1!, {r3 - r6}
63
64		subs	r2, r2, #8
65		bpl	.Linsw_8_lp
66
67		tst	r2, #7
68		ldmfdeq	sp!, {r4, r5, r6, pc}
69
70.Lno_insw_8:	tst	r2, #4
71		beq	.Lno_insw_4
72
73		ldr	r3, [r0]
74		and	r3, r3, ip
75		ldr	r4, [r0]
76		orr	r3, r3, r4, lsl #16
77
78		ldr	r4, [r0]
79		and	r4, r4, ip
80		ldr	r5, [r0]
81		orr	r4, r4, r5, lsl #16
82
83		stmia	r1!, {r3, r4}
84
85.Lno_insw_4:	tst	r2, #2
86		beq	.Lno_insw_2
87
88		ldr	r3, [r0]
89		and	r3, r3, ip
90		ldr	r4, [r0]
91		orr	r3, r3, r4, lsl #16
92
93		str	r3, [r1], #4
94
95.Lno_insw_2:	tst	r2, #1
96		ldrne	r3, [r0]
97		strbne	r3, [r1], #1
98		movne	r3, r3, lsr #8
99		strbne	r3, [r1]
100
101		ldmfd	sp!, {r4, r5, r6, pc}
102
103
104