summaryrefslogtreecommitdiffstats
path: root/arch/mips/mips3/memcpy.S
diff options
context:
space:
mode:
Diffstat (limited to 'arch/mips/mips3/memcpy.S')
-rw-r--r--arch/mips/mips3/memcpy.S185
1 files changed, 0 insertions, 185 deletions
diff --git a/arch/mips/mips3/memcpy.S b/arch/mips/mips3/memcpy.S
deleted file mode 100644
index 6f03032a6..000000000
--- a/arch/mips/mips3/memcpy.S
+++ /dev/null
@@ -1,185 +0,0 @@
-/*
- * arch/mips/mips3/memcpy.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
- *
- * Less stupid memcpy/user_copy implementation for 64 bit MIPS CPUs.
- * Much faster than the old memcpy but definately work in progress.
- * The list of tricks for a good memcpy is long ...
- */
-#include <asm/asm.h>
-#include <asm/regdef.h>
-#include <asm/mipsregs.h>
-
-#define BLOCK_SIZE (SZREG*4)
-
-#define SWAP(x,y) \
- subu x,x,y; \
- addu y,x,y; \
- subu x,y,x
-
-#define EX(addr,handler) \
- .section __ex_table,"a"; \
- PTR addr, handler; \
- .text
-#define UEX(addr,handler) \
- EX(addr,handler); \
- EX(addr+4,handler)
-
- .set noreorder
- .set noat
-
-/* ---------------------------------------------------------------------- */
-
-not_dw_aligned:
-/*
- * At least one address is missaligned.
- * Let's see if we can fix the alignment.
- */
- LONG_SUBU v1,zero,a0
- andi v1,SZREG-1
- sltu t0,v0,v1
- MOVN(v1,v0,t0)
- beqz v1,still_not_aligned
- LONG_ADDU v1,a0 # delay slot
-1: lb $1,(a1)
- EX(1b, fault)
- LONG_ADDIU a1,1
-2: sb $1,(a0)
- EX(2b, fault)
- LONG_ADDIU a0,1
- bne a0,v1,1b
- LONG_SUBU v0,1 # delay slot
-
-/*
- * Ok, now the destination address is 8-byte aligned.
- * Is the source also aligned?
- */
- andi t0,a1,SZREG-1
- beqz t0,align8 # fine ...
-
-/*
- * Bad. We could only fix the alignment of the destination address.
- * Now let's copy in the usual BLOCK_SIZE byte blocks using unaligned
- * load and aligned stores.
- */
-still_not_aligned:
- ori v1,v0,BLOCK_SIZE-1 # delay slot
- xori v1,BLOCK_SIZE-1
- beqz v1,copy_left_over
- nop # delay slot
- LONG_SUBU v0,v1
- LONG_ADDU v1,a0
-
-1: uld t0,(a1)
- UEX(1b, fault)
-2: uld t1,8(a1)
- UEX(2b, fault)
-2: uld t2,16(a1)
- UEX(2b, fault)
-2: uld t3,24(a1)
- UEX(2b, fault)
-2: sd t0,(a0)
- EX(2b, fault)
-2: sd t1,8(a0)
- EX(2b, fault_plus_one_reg)
-2: sd t2,16(a0)
- EX(2b, fault_plus_two_reg)
-2: sd t3,24(a0)
- EX(2b, fault_plus_three_reg)
- LONG_ADDIU a0,BLOCK_SIZE
- bne a0,v1,1b
- LONG_ADDIU a1,BLOCK_SIZE # delay slot
-9:
- b copy_left_over # < BLOCK_SIZE bytes left
- nop # delay slot
-
-/* ---------------------------------------------------------------------- */
-
-LEAF(__copy_user)
-
- or t1,a0,a1
- andi t1,SZREG-1
- bnez t1,not_dw_aligned
- move v0,a2 # delay slot
-
-align8:
- ori v1,v0,BLOCK_SIZE-1
- xori v1,BLOCK_SIZE-1
- beqz v1,copy_left_over
- nop # delay slot
- LONG_SUBU v0,v1
- LONG_ADDU v1,a0
-
-1: ld t0,(a1)
- EX(1b, fault)
-2: ld t1,8(a1)
- EX(2b, fault)
-2: ld t2,16(a1)
- EX(2b, fault)
-2: ld t3,24(a1)
- EX(2b, fault)
-2: sd t0,(a0)
- EX(2b, fault)
-2: sd t1,8(a0)
- EX(2b, fault_plus_one_reg)
-2: sd t2,16(a0)
- EX(2b, fault_plus_two_reg)
-2: sd t3,24(a0)
- EX(2b, fault_plus_three_reg)
- LONG_ADDIU a0,BLOCK_SIZE
- bne a0,v1,1b
- LONG_ADDIU a1,BLOCK_SIZE # delay slot
-9:
-
-/*
- * We've got upto 31 bytes left to copy ...
- */
-copy_left_over:
- beqz v0,3f
- nop # delay slot
-1: lb $1,(a1)
- EX(1b, fault)
- LONG_ADDIU a1,1
-2: sb $1,(a0)
- EX(2b, fault)
- LONG_SUBU v0,1
- bnez v0,1b
- LONG_ADDIU a0,1
-3: jr ra
- nop # delay slot
-
- END(__copy_user)
- .set at
- .set reorder
-
-/* ---------------------------------------------------------------------- */
-
-/*
- * Access fault. The number of not copied bytes is in v0. We have to
- * correct the number of the not copied bytes in v0 in case of a access
- * fault in an unrolled loop, then return.
- */
-
-fault: jr ra
-fault_plus_one_reg: LONG_ADDIU v0,SZREG
- jr ra
-fault_plus_two_reg: LONG_ADDIU v0,SZREG*2
- jr ra
-fault_plus_three_reg: LONG_ADDIU v0,SZREG*3
- jr ra
-
-/* ---------------------------------------------------------------------- */
-
-/*
- * For now we use __copy_user for __memcpy, too. This is efficient (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