1/* SPDX-License-Identifier: GPL-2.0-only */
2/*
3 *  linux/arch/arm/lib/io-writesw-armv3.S
4 *
5 *  Copyright (C) 1995-2000 Russell King
6 */
7#include <linux/linkage.h>
8#include <asm/assembler.h>
9
10.Loutsw_bad_alignment:
11		adr	r0, .Loutsw_bad_align_msg
12		mov	r2, lr
13		b	panic
14.Loutsw_bad_align_msg:
15		.asciz	"outsw: bad buffer alignment (0x%p, lr=0x%08lX)\n"
16		.align
17
18.Loutsw_align:	tst	r1, #1
19		bne	.Loutsw_bad_alignment
20
21		add	r1, r1, #2
22
23		ldr	r3, [r1, #-4]
24		mov	r3, r3, lsr #16
25		orr	r3, r3, r3, lsl #16
26		str	r3, [r0]
27		subs	r2, r2, #1
28		reteq	lr
29
30ENTRY(__raw_writesw)
31		teq	r2, #0		@ do we have to check for the zero len?
32		reteq	lr
33		tst	r1, #3
34		bne	.Loutsw_align
35
36		stmfd	sp!, {r4, r5, r6, lr}
37
38		subs	r2, r2, #8
39		bmi	.Lno_outsw_8
40
41.Loutsw_8_lp:	ldmia	r1!, {r3, r4, r5, r6}
42
43		mov	ip, r3, lsl #16
44		orr	ip, ip, ip, lsr #16
45		str	ip, [r0]
46
47		mov	ip, r3, lsr #16
48		orr	ip, ip, ip, lsl #16
49		str	ip, [r0]
50
51		mov	ip, r4, lsl #16
52		orr	ip, ip, ip, lsr #16
53		str	ip, [r0]
54
55		mov	ip, r4, lsr #16
56		orr	ip, ip, ip, lsl #16
57		str	ip, [r0]
58
59		mov	ip, r5, lsl #16
60		orr	ip, ip, ip, lsr #16
61		str	ip, [r0]
62
63		mov	ip, r5, lsr #16
64		orr	ip, ip, ip, lsl #16
65		str	ip, [r0]
66
67		mov	ip, r6, lsl #16
68		orr	ip, ip, ip, lsr #16
69		str	ip, [r0]
70
71		mov	ip, r6, lsr #16
72		orr	ip, ip, ip, lsl #16
73		str	ip, [r0]
74
75		subs	r2, r2, #8
76		bpl	.Loutsw_8_lp
77
78		tst	r2, #7
79		ldmfdeq	sp!, {r4, r5, r6, pc}
80
81.Lno_outsw_8:	tst	r2, #4
82		beq	.Lno_outsw_4
83
84		ldmia	r1!, {r3, r4}
85
86		mov	ip, r3, lsl #16
87		orr	ip, ip, ip, lsr #16
88		str	ip, [r0]
89
90		mov	ip, r3, lsr #16
91		orr	ip, ip, ip, lsl #16
92		str	ip, [r0]
93
94		mov	ip, r4, lsl #16
95		orr	ip, ip, ip, lsr #16
96		str	ip, [r0]
97
98		mov	ip, r4, lsr #16
99		orr	ip, ip, ip, lsl #16
100		str	ip, [r0]
101
102.Lno_outsw_4:	tst	r2, #2
103		beq	.Lno_outsw_2
104
105		ldr	r3, [r1], #4
106
107		mov	ip, r3, lsl #16
108		orr	ip, ip, ip, lsr #16
109		str	ip, [r0]
110
111		mov	ip, r3, lsr #16
112		orr	ip, ip, ip, lsl #16
113		str	ip, [r0]
114
115.Lno_outsw_2:	tst	r2, #1
116
117		ldrne	r3, [r1]
118
119		movne	ip, r3, lsl #16
120		orrne	ip, ip, ip, lsr #16
121		strne	ip, [r0]
122
123		ldmfd	sp!, {r4, r5, r6, pc}
124