215 lines
		
	
	
	
		
			4.6 KiB
			
		
	
	
	
		
			ArmAsm
		
	
	
	
	
	
		
		
			
		
	
	
			215 lines
		
	
	
	
		
			4.6 KiB
			
		
	
	
	
		
			ArmAsm
		
	
	
	
	
	
| 
								 | 
							
								/*
							 | 
						||
| 
								 | 
							
								 * linux/arch/unicore32/lib/copy_template.S
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * Code specific to PKUnity SoC and UniCore ISA
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * Copyright (C) 2001-2010 GUAN Xue-tao
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * This program is free software; you can redistribute it and/or modify
							 | 
						||
| 
								 | 
							
								 * it under the terms of the GNU General Public License version 2 as
							 | 
						||
| 
								 | 
							
								 * published by the Free Software Foundation.
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/*
							 | 
						||
| 
								 | 
							
								 * Theory of operation
							 | 
						||
| 
								 | 
							
								 * -------------------
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * This file provides the core code for a forward memory copy used in
							 | 
						||
| 
								 | 
							
								 * the implementation of memcopy(), copy_to_user() and copy_from_user().
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * The including file must define the following accessor macros
							 | 
						||
| 
								 | 
							
								 * according to the need of the given function:
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * ldr1w ptr reg abort
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 *	This loads one word from 'ptr', stores it in 'reg' and increments
							 | 
						||
| 
								 | 
							
								 *	'ptr' to the next word. The 'abort' argument is used for fixup tables.
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * ldr4w ptr reg1 reg2 reg3 reg4 abort
							 | 
						||
| 
								 | 
							
								 * ldr8w ptr, reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 abort
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 *	This loads four or eight words starting from 'ptr', stores them
							 | 
						||
| 
								 | 
							
								 *	in provided registers and increments 'ptr' past those words.
							 | 
						||
| 
								 | 
							
								 *	The'abort' argument is used for fixup tables.
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * ldr1b ptr reg cond abort
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 *	Similar to ldr1w, but it loads a byte and increments 'ptr' one byte.
							 | 
						||
| 
								 | 
							
								 *	It also must apply the condition code if provided, otherwise the
							 | 
						||
| 
								 | 
							
								 *	"al" condition is assumed by default.
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * str1w ptr reg abort
							 | 
						||
| 
								 | 
							
								 * str8w ptr reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 abort
							 | 
						||
| 
								 | 
							
								 * str1b ptr reg cond abort
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 *	Same as their ldr* counterparts, but data is stored to 'ptr' location
							 | 
						||
| 
								 | 
							
								 *	rather than being loaded.
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * enter
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 *	Preserve the provided registers on the stack plus any additional
							 | 
						||
| 
								 | 
							
								 *	data as needed by the implementation including this code. Called
							 | 
						||
| 
								 | 
							
								 *	upon code entry.
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * exit
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 *	Restore registers with the values previously saved with the
							 | 
						||
| 
								 | 
							
								 *	'preserv' macro. Called upon code termination.
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										enter
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										sub.a	r2, r2, #4
							 | 
						||
| 
								 | 
							
										bsl	8f
							 | 
						||
| 
								 | 
							
										and.a	ip, r0, #3
							 | 
						||
| 
								 | 
							
										bne	9f
							 | 
						||
| 
								 | 
							
										and.a	ip, r1, #3
							 | 
						||
| 
								 | 
							
										bne	10f
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								1:		sub.a	r2, r2, #(28)
							 | 
						||
| 
								 | 
							
										stm.w	(r5 - r8), [sp-]
							 | 
						||
| 
								 | 
							
										bsl	5f
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								3:
							 | 
						||
| 
								 | 
							
								4:		ldr8w	r1, r3, r4, r5, r6, r7, r8, r10, r11, abort=20f
							 | 
						||
| 
								 | 
							
										sub.a	r2, r2, #32
							 | 
						||
| 
								 | 
							
										str8w	r0, r3, r4, r5, r6, r7, r8, r10, r11, abort=20f
							 | 
						||
| 
								 | 
							
										beg	3b
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								5:		and.a	ip, r2, #28
							 | 
						||
| 
								 | 
							
										rsub	ip, ip, #32
							 | 
						||
| 
								 | 
							
										beq	7f
							 | 
						||
| 
								 | 
							
										add	pc, pc, ip		@ C is always clear here
							 | 
						||
| 
								 | 
							
										nop
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										ldr1w	r1, r3, abort=20f
							 | 
						||
| 
								 | 
							
										ldr1w	r1, r4, abort=20f
							 | 
						||
| 
								 | 
							
										ldr1w	r1, r5, abort=20f
							 | 
						||
| 
								 | 
							
										ldr1w	r1, r6, abort=20f
							 | 
						||
| 
								 | 
							
										ldr1w	r1, r7, abort=20f
							 | 
						||
| 
								 | 
							
										ldr1w	r1, r8, abort=20f
							 | 
						||
| 
								 | 
							
										ldr1w	r1, r11, abort=20f
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										add	pc, pc, ip
							 | 
						||
| 
								 | 
							
										nop
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										str1w	r0, r3, abort=20f
							 | 
						||
| 
								 | 
							
										str1w	r0, r4, abort=20f
							 | 
						||
| 
								 | 
							
										str1w	r0, r5, abort=20f
							 | 
						||
| 
								 | 
							
										str1w	r0, r6, abort=20f
							 | 
						||
| 
								 | 
							
										str1w	r0, r7, abort=20f
							 | 
						||
| 
								 | 
							
										str1w	r0, r8, abort=20f
							 | 
						||
| 
								 | 
							
										str1w	r0, r11, abort=20f
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								7:		ldm.w	(r5 - r8), [sp]+
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								8:		mov.a	r2, r2 << #31
							 | 
						||
| 
								 | 
							
										ldr1b	r1, r3, ne, abort=21f
							 | 
						||
| 
								 | 
							
										ldr1b	r1, r4, ea, abort=21f
							 | 
						||
| 
								 | 
							
										ldr1b	r1, r10, ea, abort=21f
							 | 
						||
| 
								 | 
							
										str1b	r0, r3, ne, abort=21f
							 | 
						||
| 
								 | 
							
										str1b	r0, r4, ea, abort=21f
							 | 
						||
| 
								 | 
							
										str1b	r0, r10, ea, abort=21f
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										exit
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								9:		rsub	ip, ip, #4
							 | 
						||
| 
								 | 
							
										csub.a	ip, #2
							 | 
						||
| 
								 | 
							
										ldr1b	r1, r3, sg, abort=21f
							 | 
						||
| 
								 | 
							
										ldr1b	r1, r4, eg, abort=21f
							 | 
						||
| 
								 | 
							
										ldr1b	r1, r11, abort=21f
							 | 
						||
| 
								 | 
							
										str1b	r0, r3, sg, abort=21f
							 | 
						||
| 
								 | 
							
										str1b	r0, r4, eg, abort=21f
							 | 
						||
| 
								 | 
							
										sub.a	r2, r2, ip
							 | 
						||
| 
								 | 
							
										str1b	r0, r11, abort=21f
							 | 
						||
| 
								 | 
							
										bsl	8b
							 | 
						||
| 
								 | 
							
										and.a	ip, r1, #3
							 | 
						||
| 
								 | 
							
										beq	1b
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								10:		andn	r1, r1, #3
							 | 
						||
| 
								 | 
							
										csub.a	ip, #2
							 | 
						||
| 
								 | 
							
										ldr1w	r1, r11, abort=21f
							 | 
						||
| 
								 | 
							
										beq	17f
							 | 
						||
| 
								 | 
							
										bsg	18f
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										.macro	forward_copy_shift a b
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										sub.a	r2, r2, #28
							 | 
						||
| 
								 | 
							
										bsl	14f
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								11:		stm.w	(r5 - r9), [sp-]
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								12:
							 | 
						||
| 
								 | 
							
										ldr4w	r1, r4, r5, r6, r7, abort=19f
							 | 
						||
| 
								 | 
							
										mov	r3, r11 pull #\a
							 | 
						||
| 
								 | 
							
										sub.a	r2, r2, #32
							 | 
						||
| 
								 | 
							
										ldr4w	r1, r8, r9, r10, r11, abort=19f
							 | 
						||
| 
								 | 
							
										or	r3, r3, r4 push #\b
							 | 
						||
| 
								 | 
							
										mov	r4, r4 pull #\a
							 | 
						||
| 
								 | 
							
										or	r4, r4, r5 push #\b
							 | 
						||
| 
								 | 
							
										mov	r5, r5 pull #\a
							 | 
						||
| 
								 | 
							
										or	r5, r5, r6 push #\b
							 | 
						||
| 
								 | 
							
										mov	r6, r6 pull #\a
							 | 
						||
| 
								 | 
							
										or	r6, r6, r7 push #\b
							 | 
						||
| 
								 | 
							
										mov	r7, r7 pull #\a
							 | 
						||
| 
								 | 
							
										or	r7, r7, r8 push #\b
							 | 
						||
| 
								 | 
							
										mov	r8, r8 pull #\a
							 | 
						||
| 
								 | 
							
										or	r8, r8, r9 push #\b
							 | 
						||
| 
								 | 
							
										mov	r9, r9 pull #\a
							 | 
						||
| 
								 | 
							
										or	r9, r9, r10 push #\b
							 | 
						||
| 
								 | 
							
										mov	r10, r10 pull #\a
							 | 
						||
| 
								 | 
							
										or	r10, r10, r11 push #\b
							 | 
						||
| 
								 | 
							
										str8w	r0, r3, r4, r5, r6, r7, r8, r9, r10, , abort=19f
							 | 
						||
| 
								 | 
							
										beg	12b
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										ldm.w	(r5 - r9), [sp]+
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								14:		and.a	ip, r2, #28
							 | 
						||
| 
								 | 
							
										beq	16f
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								15:		mov	r3, r11 pull #\a
							 | 
						||
| 
								 | 
							
										ldr1w	r1, r11, abort=21f
							 | 
						||
| 
								 | 
							
										sub.a	ip, ip, #4
							 | 
						||
| 
								 | 
							
										or	r3, r3, r11 push #\b
							 | 
						||
| 
								 | 
							
										str1w	r0, r3, abort=21f
							 | 
						||
| 
								 | 
							
										bsg	15b
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								16:		sub	r1, r1, #(\b / 8)
							 | 
						||
| 
								 | 
							
										b	8b
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										.endm
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										forward_copy_shift	a=8	b=24
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								17:		forward_copy_shift	a=16	b=16
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								18:		forward_copy_shift	a=24	b=8
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/*
							 | 
						||
| 
								 | 
							
								 * Abort preamble and completion macros.
							 | 
						||
| 
								 | 
							
								 * If a fixup handler is required then those macros must surround it.
							 | 
						||
| 
								 | 
							
								 * It is assumed that the fixup code will handle the private part of
							 | 
						||
| 
								 | 
							
								 * the exit macro.
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									.macro	copy_abort_preamble
							 | 
						||
| 
								 | 
							
								19:	ldm.w	(r5 - r9), [sp]+
							 | 
						||
| 
								 | 
							
									b	21f
							 | 
						||
| 
								 | 
							
								299:	.word	0			@ store lr
							 | 
						||
| 
								 | 
							
													@ to avoid function call in fixup
							 | 
						||
| 
								 | 
							
								20:	ldm.w	(r5 - r8), [sp]+
							 | 
						||
| 
								 | 
							
								21:
							 | 
						||
| 
								 | 
							
									adr	r1, 299b
							 | 
						||
| 
								 | 
							
									stw	lr, [r1]
							 | 
						||
| 
								 | 
							
									.endm
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									.macro	copy_abort_end
							 | 
						||
| 
								 | 
							
									adr	lr, 299b
							 | 
						||
| 
								 | 
							
									ldw	pc, [lr]
							 | 
						||
| 
								 | 
							
									.endm
							 | 
						||
| 
								 | 
							
								
							 |