• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/* SPDX-License-Identifier: GPL-2.0-only */
2/*
3 * linux/arch/unicore32/lib/copy_template.S
4 *
5 * Code specific to PKUnity SoC and UniCore ISA
6 *
7 * Copyright (C) 2001-2010 GUAN Xue-tao
8 */
9
10/*
11 * Theory of operation
12 * -------------------
13 *
14 * This file provides the core code for a forward memory copy used in
15 * the implementation of memcopy(), copy_to_user() and copy_from_user().
16 *
17 * The including file must define the following accessor macros
18 * according to the need of the given function:
19 *
20 * ldr1w ptr reg abort
21 *
22 *	This loads one word from 'ptr', stores it in 'reg' and increments
23 *	'ptr' to the next word. The 'abort' argument is used for fixup tables.
24 *
25 * ldr4w ptr reg1 reg2 reg3 reg4 abort
26 * ldr8w ptr, reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 abort
27 *
28 *	This loads four or eight words starting from 'ptr', stores them
29 *	in provided registers and increments 'ptr' past those words.
30 *	The'abort' argument is used for fixup tables.
31 *
32 * ldr1b ptr reg cond abort
33 *
34 *	Similar to ldr1w, but it loads a byte and increments 'ptr' one byte.
35 *	It also must apply the condition code if provided, otherwise the
36 *	"al" condition is assumed by default.
37 *
38 * str1w ptr reg abort
39 * str8w ptr reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 abort
40 * str1b ptr reg cond abort
41 *
42 *	Same as their ldr* counterparts, but data is stored to 'ptr' location
43 *	rather than being loaded.
44 *
45 * enter
46 *
47 *	Preserve the provided registers on the stack plus any additional
48 *	data as needed by the implementation including this code. Called
49 *	upon code entry.
50 *
51 * exit
52 *
53 *	Restore registers with the values previously saved with the
54 *	'preserv' macro. Called upon code termination.
55 */
56
57
58		enter
59
60		sub.a	r2, r2, #4
61		bsl	8f
62		and.a	ip, r0, #3
63		bne	9f
64		and.a	ip, r1, #3
65		bne	10f
66
671:		sub.a	r2, r2, #(28)
68		stm.w	(r5 - r8), [sp-]
69		bsl	5f
70
713:
724:		ldr8w	r1, r3, r4, r5, r6, r7, r8, r10, r11, abort=20f
73		sub.a	r2, r2, #32
74		str8w	r0, r3, r4, r5, r6, r7, r8, r10, r11, abort=20f
75		beg	3b
76
775:		and.a	ip, r2, #28
78		rsub	ip, ip, #32
79		beq	7f
80		add	pc, pc, ip		@ C is always clear here
81		nop
82
83		ldr1w	r1, r3, abort=20f
84		ldr1w	r1, r4, abort=20f
85		ldr1w	r1, r5, abort=20f
86		ldr1w	r1, r6, abort=20f
87		ldr1w	r1, r7, abort=20f
88		ldr1w	r1, r8, abort=20f
89		ldr1w	r1, r11, abort=20f
90
91		add	pc, pc, ip
92		nop
93
94		str1w	r0, r3, abort=20f
95		str1w	r0, r4, abort=20f
96		str1w	r0, r5, abort=20f
97		str1w	r0, r6, abort=20f
98		str1w	r0, r7, abort=20f
99		str1w	r0, r8, abort=20f
100		str1w	r0, r11, abort=20f
101
1027:		ldm.w	(r5 - r8), [sp]+
103
1048:		mov.a	r2, r2 << #31
105		ldr1b	r1, r3, ne, abort=21f
106		ldr1b	r1, r4, ea, abort=21f
107		ldr1b	r1, r10, ea, abort=21f
108		str1b	r0, r3, ne, abort=21f
109		str1b	r0, r4, ea, abort=21f
110		str1b	r0, r10, ea, abort=21f
111
112		exit
113
1149:		rsub	ip, ip, #4
115		csub.a	ip, #2
116		ldr1b	r1, r3, sg, abort=21f
117		ldr1b	r1, r4, eg, abort=21f
118		ldr1b	r1, r11, abort=21f
119		str1b	r0, r3, sg, abort=21f
120		str1b	r0, r4, eg, abort=21f
121		sub.a	r2, r2, ip
122		str1b	r0, r11, abort=21f
123		bsl	8b
124		and.a	ip, r1, #3
125		beq	1b
126
12710:		andn	r1, r1, #3
128		csub.a	ip, #2
129		ldr1w	r1, r11, abort=21f
130		beq	17f
131		bsg	18f
132
133
134		.macro	forward_copy_shift a b
135
136		sub.a	r2, r2, #28
137		bsl	14f
138
13911:		stm.w	(r5 - r9), [sp-]
140
14112:
142		ldr4w	r1, r4, r5, r6, r7, abort=19f
143		mov	r3, r11 pull #\a
144		sub.a	r2, r2, #32
145		ldr4w	r1, r8, r9, r10, r11, abort=19f
146		or	r3, r3, r4 push #\b
147		mov	r4, r4 pull #\a
148		or	r4, r4, r5 push #\b
149		mov	r5, r5 pull #\a
150		or	r5, r5, r6 push #\b
151		mov	r6, r6 pull #\a
152		or	r6, r6, r7 push #\b
153		mov	r7, r7 pull #\a
154		or	r7, r7, r8 push #\b
155		mov	r8, r8 pull #\a
156		or	r8, r8, r9 push #\b
157		mov	r9, r9 pull #\a
158		or	r9, r9, r10 push #\b
159		mov	r10, r10 pull #\a
160		or	r10, r10, r11 push #\b
161		str8w	r0, r3, r4, r5, r6, r7, r8, r9, r10, , abort=19f
162		beg	12b
163
164		ldm.w	(r5 - r9), [sp]+
165
16614:		and.a	ip, r2, #28
167		beq	16f
168
16915:		mov	r3, r11 pull #\a
170		ldr1w	r1, r11, abort=21f
171		sub.a	ip, ip, #4
172		or	r3, r3, r11 push #\b
173		str1w	r0, r3, abort=21f
174		bsg	15b
175
17616:		sub	r1, r1, #(\b / 8)
177		b	8b
178
179		.endm
180
181
182		forward_copy_shift	a=8	b=24
183
18417:		forward_copy_shift	a=16	b=16
185
18618:		forward_copy_shift	a=24	b=8
187
188
189/*
190 * Abort preamble and completion macros.
191 * If a fixup handler is required then those macros must surround it.
192 * It is assumed that the fixup code will handle the private part of
193 * the exit macro.
194 */
195
196	.macro	copy_abort_preamble
19719:	ldm.w	(r5 - r9), [sp]+
198	b	21f
199299:	.word	0			@ store lr
200					@ to avoid function call in fixup
20120:	ldm.w	(r5 - r8), [sp]+
20221:
203	adr	r1, 299b
204	stw	lr, [r1]
205	.endm
206
207	.macro	copy_abort_end
208	adr	lr, 299b
209	ldw	pc, [lr]
210	.endm
211
212