patch-2.1.73 linux/arch/mips/lib/copy_user.S

Next file: linux/arch/mips/lib/io.c
Previous file: linux/arch/mips/lib/checksum.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.1.72/linux/arch/mips/lib/copy_user.S linux/arch/mips/lib/copy_user.S
@@ -1,13 +1,15 @@
 /*
- * arch/mips/mips1/memcpy.S
+ * arch/mips/lib/copy_user.S
  *
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (c) 1996 by Ralf Baechle
+ * Copyright (c) 1996, 1997 by Ralf Baechle
  *
- * Less stupid memcpy/user_copy implementation for 32 bit MIPS CPUs.
+ * Less stupid user_copy implementation for 32 bit MIPS CPUs.
+ *
+ * $Id: copy_user.S,v 1.2 1997/08/11 04:26:12 ralf Exp $
  */
 #include <asm/asm.h>
 #include <asm/regdef.h>
@@ -34,11 +36,11 @@
  */
 not_even_the_same_alignment:
 		LONG_SUBU	v1,zero,a1
-		andi		v1,a1,3
+		andi		v1,3
 		sltu		t0,v0,v1
 		MOVN(v1,v0,t0)
-		beqz		v1,align4		# -> finished
-		LONG_ADDU	v1,a0			# delay slot
+		beqz		v1,src_aligned
+		 LONG_ADDU	v1,a0
 1:		lb		$1,(a1)
 		EX(1b, fault)
 		LONG_ADDIU	a1,1
@@ -46,7 +48,8 @@
 		EX(2b, fault)
 		LONG_ADDIU	a0,1
 		bne		a0,v1,1b
-		LONG_SUBU	v0,1			# delay slot
+		 LONG_SUBU	v0,1
+src_aligned:
 
 /*
  * Ok.  We've fixed the alignment of the copy src for this case.
@@ -54,12 +57,13 @@
  * stores.
  * XXX Align the destination address.  This is better if the __copy_user
  *     encounters an access fault because we never have to deal with an
- *     only partially modified destination word.
+ *     only partially modified destination word.  This is required to
+ *     keep the semantics of the result of copy_*_user().
  */
 		ori		v1,v0,BLOCK_SIZE-1
 		xori		v1,BLOCK_SIZE-1
 		beqz		v1,copy_left_over
-		nop				# delay slot
+		 nop
 		LONG_SUBU	v0,v1
 		LONG_ADDU	v1,a0
 
@@ -81,16 +85,16 @@
 		UEX(2b, fault_plus_12)
 		LONG_ADDIU	a0,BLOCK_SIZE
 		bne		a0,v1,1b
-		LONG_ADDIU	a1,BLOCK_SIZE	# delay slot
+		 LONG_ADDIU	a1,BLOCK_SIZE
 9:
 		b		copy_left_over	# < BLOCK_SIZE bytes left
-		nop				# delay slot
+		 nop
 
 /* ---------------------------------------------------------------------- */
 
 not_w_aligned:
 /*
- * Ok, src or destination are not 8-byte aligned.
+ * Ok, src or destination are not 4-byte aligned.
  * Try to fix that.  Do at least both addresses have the same alignment?
  */
 		xor		t0,a0,a1
@@ -107,8 +111,8 @@
 		andi		v1,3
 		sltu		t0,v0,v1
 		MOVN(v1,v0,t0)
-		beqz		v1,3f			# -> finished
-		LONG_ADDU	v1,a0			# delay slot
+		beqz		v1,__copy_user
+		 LONG_ADDU	v1,a0
 1:		lb		$1,(a1)
 		EX(1b, fault)
 		LONG_ADDIU	a1,1
@@ -116,24 +120,23 @@
 		EX(2b, fault)
 		LONG_ADDIU	a0,1
 		bne		a0,v1,1b
-		LONG_SUBU	v0,1			# delay slot
+		 LONG_SUBU	v0,1
 		b		align4
-		nop					# delay slot
-3:
+		 nop
 
 /* ---------------------------------------------------------------------- */
 
 LEAF(__copy_user)
 		or		t1,a0,a1
 		andi		t1,3
-		bnez		t1,not_w_aligned
-		move		v0,a2			# delay slot
+		bnez		t1,not_w_aligned	# not word alignment
+		 move		v0,a2
 
 align4:
 		ori		v1,v0,BLOCK_SIZE-1
 		xori		v1,BLOCK_SIZE-1
 		beqz		v1,copy_left_over
-		nop				# delay slot
+		 nop
 		LONG_SUBU	v0,v1
 		LONG_ADDU	v1,a0
 
@@ -155,7 +158,7 @@
 		EX(2b, fault_plus_12)
 		LONG_ADDIU	a0,BLOCK_SIZE
 		bne		a0,v1,1b
-		LONG_ADDIU	a1,BLOCK_SIZE	# delay slot
+		 LONG_ADDIU	a1,BLOCK_SIZE
 9:
 
 /*
@@ -163,7 +166,7 @@
  */
 copy_left_over:
 		beqz		v0,3f
-		nop					# delay slot
+		 nop
 1:		lb		$1,(a1)
 		EX(1b, fault)
 		LONG_ADDIU	a1,1
@@ -171,9 +174,11 @@
 		EX(2b, fault)
 		LONG_SUBU	v0,1
 		bnez		v0,1b
-		LONG_ADDIU	a0,1
-3:		jr		ra
-		nop				# delay slot
+		 LONG_ADDIU	a0,1
+3:
+
+done:		jr		ra
+		 nop
 
 		END(__copy_user)
 		.set		at
@@ -194,14 +199,3 @@
 			jr	ra
 fault_plus_12:		LONG_ADDIU	v0,12
 			jr	ra
-
-/* ---------------------------------------------------------------------- */
-
-/*
- * For now we use __copy_user for __memcpy, too.  This is effizient (one
- * instruction penatly) and smaller but adds unwanted error checking we don't
- * need.  This hopefully doesn't cover any bugs.  The memcpy() wrapper in
- * <asm/string.h> takes care of the return value in a way GCC can optimize.
- */
-		.globl	__memcpy
-__memcpy	=	__copy_user

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov