114 lines
		
	
	
	
		
			2.6 KiB
			
		
	
	
	
		
			ArmAsm
		
	
	
	
	
	
		
		
			
		
	
	
			114 lines
		
	
	
	
		
			2.6 KiB
			
		
	
	
	
		
			ArmAsm
		
	
	
	
	
	
| 
								 | 
							
								/*
							 | 
						||
| 
								 | 
							
								 * arch/alpha/lib/clear_user.S
							 | 
						||
| 
								 | 
							
								 * Contributed by Richard Henderson <rth@tamu.edu>
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * Zero user space, handling exceptions as we go.
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * We have to make sure that $0 is always up-to-date and contains the
							 | 
						||
| 
								 | 
							
								 * right "bytes left to zero" value (and that it is updated only _after_
							 | 
						||
| 
								 | 
							
								 * a successful copy).  There is also some rather minor exception setup
							 | 
						||
| 
								 | 
							
								 * stuff.
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * NOTE! This is not directly C-callable, because the calling semantics
							 | 
						||
| 
								 | 
							
								 * are different:
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * Inputs:
							 | 
						||
| 
								 | 
							
								 *	length in $0
							 | 
						||
| 
								 | 
							
								 *	destination address in $6
							 | 
						||
| 
								 | 
							
								 *	exception pointer in $7
							 | 
						||
| 
								 | 
							
								 *	return address in $28 (exceptions expect it there)
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * Outputs:
							 | 
						||
| 
								 | 
							
								 *	bytes left to copy in $0
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * Clobbers:
							 | 
						||
| 
								 | 
							
								 *	$1,$2,$3,$4,$5,$6
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/* Allow an exception for an insn; exit if we get one.  */
							 | 
						||
| 
								 | 
							
								#define EX(x,y...)			\
							 | 
						||
| 
								 | 
							
									99: x,##y;			\
							 | 
						||
| 
								 | 
							
									.section __ex_table,"a";	\
							 | 
						||
| 
								 | 
							
									.long 99b - .;			\
							 | 
						||
| 
								 | 
							
									lda $31, $exception-99b($31); 	\
							 | 
						||
| 
								 | 
							
									.previous
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									.set noat
							 | 
						||
| 
								 | 
							
									.set noreorder
							 | 
						||
| 
								 | 
							
									.align 4
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									.globl __do_clear_user
							 | 
						||
| 
								 | 
							
									.ent __do_clear_user
							 | 
						||
| 
								 | 
							
									.frame	$30, 0, $28
							 | 
						||
| 
								 | 
							
									.prologue 0
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								$loop:
							 | 
						||
| 
								 | 
							
									and	$1, 3, $4	# e0    :
							 | 
						||
| 
								 | 
							
									beq	$4, 1f		# .. e1 :
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								0:	EX( stq_u $31, 0($6) )	# e0    : zero one word
							 | 
						||
| 
								 | 
							
									subq	$0, 8, $0	# .. e1 :
							 | 
						||
| 
								 | 
							
									subq	$4, 1, $4	# e0    :
							 | 
						||
| 
								 | 
							
									addq	$6, 8, $6	# .. e1 :
							 | 
						||
| 
								 | 
							
									bne	$4, 0b		# e1    :
							 | 
						||
| 
								 | 
							
									unop			#       :
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								1:	bic	$1, 3, $1	# e0    :
							 | 
						||
| 
								 | 
							
									beq	$1, $tail	# .. e1 :
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								2:	EX( stq_u $31, 0($6) )	# e0    : zero four words
							 | 
						||
| 
								 | 
							
									subq	$0, 8, $0	# .. e1 :
							 | 
						||
| 
								 | 
							
									EX( stq_u $31, 8($6) )	# e0    :
							 | 
						||
| 
								 | 
							
									subq	$0, 8, $0	# .. e1 :
							 | 
						||
| 
								 | 
							
									EX( stq_u $31, 16($6) )	# e0    :
							 | 
						||
| 
								 | 
							
									subq	$0, 8, $0	# .. e1 :
							 | 
						||
| 
								 | 
							
									EX( stq_u $31, 24($6) )	# e0    :
							 | 
						||
| 
								 | 
							
									subq	$0, 8, $0	# .. e1 :
							 | 
						||
| 
								 | 
							
									subq	$1, 4, $1	# e0    :
							 | 
						||
| 
								 | 
							
									addq	$6, 32, $6	# .. e1 :
							 | 
						||
| 
								 | 
							
									bne	$1, 2b		# e1    :
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								$tail:
							 | 
						||
| 
								 | 
							
									bne	$2, 1f		# e1    : is there a tail to do?
							 | 
						||
| 
								 | 
							
									ret	$31, ($28), 1	# .. e1 :
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								1:	EX( ldq_u $5, 0($6) )	# e0    :
							 | 
						||
| 
								 | 
							
									clr	$0		# .. e1 :
							 | 
						||
| 
								 | 
							
									nop			# e1    :
							 | 
						||
| 
								 | 
							
									mskqh	$5, $0, $5	# e0    :
							 | 
						||
| 
								 | 
							
									EX( stq_u $5, 0($6) )	# e0    :
							 | 
						||
| 
								 | 
							
									ret	$31, ($28), 1	# .. e1 :
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								__do_clear_user:
							 | 
						||
| 
								 | 
							
									and	$6, 7, $4	# e0    : find dest misalignment
							 | 
						||
| 
								 | 
							
									beq	$0, $zerolength # .. e1 :
							 | 
						||
| 
								 | 
							
									addq	$0, $4, $1	# e0    : bias counter
							 | 
						||
| 
								 | 
							
									and	$1, 7, $2	# e1    : number of bytes in tail
							 | 
						||
| 
								 | 
							
									srl	$1, 3, $1	# e0    :
							 | 
						||
| 
								 | 
							
									beq	$4, $loop	# .. e1 :
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									EX( ldq_u $5, 0($6) )	# e0    : load dst word to mask back in
							 | 
						||
| 
								 | 
							
									beq	$1, $oneword	# .. e1 : sub-word store?
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									mskql	$5, $6, $5	# e0    : take care of misaligned head
							 | 
						||
| 
								 | 
							
									addq	$6, 8, $6	# .. e1 :
							 | 
						||
| 
								 | 
							
									EX( stq_u $5, -8($6) )	# e0    :
							 | 
						||
| 
								 | 
							
									addq	$0, $4, $0	# .. e1 : bytes left -= 8 - misalignment
							 | 
						||
| 
								 | 
							
									subq	$1, 1, $1	# e0    :
							 | 
						||
| 
								 | 
							
									subq	$0, 8, $0	# .. e1 :
							 | 
						||
| 
								 | 
							
									br	$loop		# e1    :
							 | 
						||
| 
								 | 
							
									unop			#       :
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								$oneword:
							 | 
						||
| 
								 | 
							
									mskql	$5, $6, $4	# e0    :
							 | 
						||
| 
								 | 
							
									mskqh	$5, $2, $5	# e0    :
							 | 
						||
| 
								 | 
							
									or	$5, $4, $5	# e1    :
							 | 
						||
| 
								 | 
							
									EX( stq_u $5, 0($6) )	# e0    :
							 | 
						||
| 
								 | 
							
									clr	$0		# .. e1 :
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								$zerolength:
							 | 
						||
| 
								 | 
							
								$exception:
							 | 
						||
| 
								 | 
							
									ret	$31, ($28), 1	# .. e1 :
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									.end __do_clear_user
							 |