summaryrefslogtreecommitdiffstats
path: root/arch/mips/lib
diff options
context:
space:
mode:
Diffstat (limited to 'arch/mips/lib')
-rw-r--r--arch/mips/lib/csum_partial.S275
-rw-r--r--arch/mips/lib/memcpy-inatomic.S141
-rw-r--r--arch/mips/lib/memcpy.S250
-rw-r--r--arch/mips/lib/memset.S44
-rw-r--r--arch/mips/lib/strlen_user.S6
-rw-r--r--arch/mips/lib/strncpy_user.S15
-rw-r--r--arch/mips/lib/strnlen_user.S7
-rw-r--r--arch/mips/lib/uncached.c12
8 files changed, 433 insertions, 317 deletions
diff --git a/arch/mips/lib/csum_partial.S b/arch/mips/lib/csum_partial.S
index c0a77fe038be..8d7784122c14 100644
--- a/arch/mips/lib/csum_partial.S
+++ b/arch/mips/lib/csum_partial.S
@@ -7,6 +7,7 @@
*
* Copyright (C) 1998, 1999 Ralf Baechle
* Copyright (C) 1999 Silicon Graphics, Inc.
+ * Copyright (C) 2007 Maciej W. Rozycki
*/
#include <linux/errno.h>
#include <asm/asm.h>
@@ -52,9 +53,12 @@
#define UNIT(unit) ((unit)*NBYTES)
#define ADDC(sum,reg) \
+ .set push; \
+ .set noat; \
ADD sum, reg; \
sltu v1, sum, reg; \
- ADD sum, v1
+ ADD sum, v1; \
+ .set pop
#define CSUM_BIGCHUNK1(src, offset, sum, _t0, _t1, _t2, _t3) \
LOAD _t0, (offset + UNIT(0))(src); \
@@ -92,13 +96,13 @@ LEAF(csum_partial)
move t7, zero
sltiu t8, a1, 0x8
- bnez t8, small_csumcpy /* < 8 bytes to copy */
+ bnez t8, .Lsmall_csumcpy /* < 8 bytes to copy */
move t2, a1
andi t7, src, 0x1 /* odd buffer? */
-hword_align:
- beqz t7, word_align
+.Lhword_align:
+ beqz t7, .Lword_align
andi t8, src, 0x2
lbu t0, (src)
@@ -110,8 +114,8 @@ hword_align:
PTR_ADDU src, src, 0x1
andi t8, src, 0x2
-word_align:
- beqz t8, dword_align
+.Lword_align:
+ beqz t8, .Ldword_align
sltiu t8, a1, 56
lhu t0, (src)
@@ -120,12 +124,12 @@ word_align:
sltiu t8, a1, 56
PTR_ADDU src, src, 0x2
-dword_align:
- bnez t8, do_end_words
+.Ldword_align:
+ bnez t8, .Ldo_end_words
move t8, a1
andi t8, src, 0x4
- beqz t8, qword_align
+ beqz t8, .Lqword_align
andi t8, src, 0x8
lw t0, 0x00(src)
@@ -134,8 +138,8 @@ dword_align:
PTR_ADDU src, src, 0x4
andi t8, src, 0x8
-qword_align:
- beqz t8, oword_align
+.Lqword_align:
+ beqz t8, .Loword_align
andi t8, src, 0x10
#ifdef USE_DOUBLE
@@ -152,8 +156,8 @@ qword_align:
PTR_ADDU src, src, 0x8
andi t8, src, 0x10
-oword_align:
- beqz t8, begin_movement
+.Loword_align:
+ beqz t8, .Lbegin_movement
LONG_SRL t8, a1, 0x7
#ifdef USE_DOUBLE
@@ -168,51 +172,55 @@ oword_align:
PTR_ADDU src, src, 0x10
LONG_SRL t8, a1, 0x7
-begin_movement:
+.Lbegin_movement:
beqz t8, 1f
andi t2, a1, 0x40
-move_128bytes:
+.Lmove_128bytes:
CSUM_BIGCHUNK(src, 0x00, sum, t0, t1, t3, t4)
CSUM_BIGCHUNK(src, 0x20, sum, t0, t1, t3, t4)
CSUM_BIGCHUNK(src, 0x40, sum, t0, t1, t3, t4)
CSUM_BIGCHUNK(src, 0x60, sum, t0, t1, t3, t4)
LONG_SUBU t8, t8, 0x01
- bnez t8, move_128bytes
- PTR_ADDU src, src, 0x80
+ .set reorder /* DADDI_WAR */
+ PTR_ADDU src, src, 0x80
+ bnez t8, .Lmove_128bytes
+ .set noreorder
1:
beqz t2, 1f
andi t2, a1, 0x20
-move_64bytes:
+.Lmove_64bytes:
CSUM_BIGCHUNK(src, 0x00, sum, t0, t1, t3, t4)
CSUM_BIGCHUNK(src, 0x20, sum, t0, t1, t3, t4)
PTR_ADDU src, src, 0x40
1:
- beqz t2, do_end_words
+ beqz t2, .Ldo_end_words
andi t8, a1, 0x1c
-move_32bytes:
+.Lmove_32bytes:
CSUM_BIGCHUNK(src, 0x00, sum, t0, t1, t3, t4)
andi t8, a1, 0x1c
PTR_ADDU src, src, 0x20
-do_end_words:
- beqz t8, small_csumcpy
+.Ldo_end_words:
+ beqz t8, .Lsmall_csumcpy
andi t2, a1, 0x3
LONG_SRL t8, t8, 0x2
-end_words:
+.Lend_words:
lw t0, (src)
LONG_SUBU t8, t8, 0x1
ADDC(sum, t0)
- bnez t8, end_words
- PTR_ADDU src, src, 0x4
+ .set reorder /* DADDI_WAR */
+ PTR_ADDU src, src, 0x4
+ bnez t8, .Lend_words
+ .set noreorder
/* unknown src alignment and < 8 bytes to go */
-small_csumcpy:
+.Lsmall_csumcpy:
move a1, t2
andi t0, a1, 4
@@ -246,6 +254,8 @@ small_csumcpy:
1: ADDC(sum, t1)
/* fold checksum */
+ .set push
+ .set noat
#ifdef USE_DOUBLE
dsll32 v1, sum, 0
daddu sum, v1
@@ -266,6 +276,7 @@ small_csumcpy:
srl sum, sum, 8
or sum, v1
andi sum, 0xffff
+ .set pop
1:
.set reorder
/* Add the passed partial csum. */
@@ -373,7 +384,11 @@ small_csumcpy:
#define ADDRMASK (NBYTES-1)
+#ifndef CONFIG_CPU_DADDI_WORKAROUNDS
.set noat
+#else
+ .set at=v1
+#endif
LEAF(__csum_partial_copy_user)
PTR_ADDU AT, src, len /* See (1) above. */
@@ -398,95 +413,101 @@ FEXPORT(csum_partial_copy_nocheck)
*/
sltu t2, len, NBYTES
and t1, dst, ADDRMASK
- bnez t2, copy_bytes_checklen
+ bnez t2, .Lcopy_bytes_checklen
and t0, src, ADDRMASK
andi odd, dst, 0x1 /* odd buffer? */
- bnez t1, dst_unaligned
+ bnez t1, .Ldst_unaligned
nop
- bnez t0, src_unaligned_dst_aligned
+ bnez t0, .Lsrc_unaligned_dst_aligned
/*
* use delay slot for fall-through
* src and dst are aligned; need to compute rem
*/
-both_aligned:
+.Lboth_aligned:
SRL t0, len, LOG_NBYTES+3 # +3 for 8 units/iter
- beqz t0, cleanup_both_aligned # len < 8*NBYTES
+ beqz t0, .Lcleanup_both_aligned # len < 8*NBYTES
nop
SUB len, 8*NBYTES # subtract here for bgez loop
.align 4
1:
-EXC( LOAD t0, UNIT(0)(src), l_exc)
-EXC( LOAD t1, UNIT(1)(src), l_exc_copy)
-EXC( LOAD t2, UNIT(2)(src), l_exc_copy)
-EXC( LOAD t3, UNIT(3)(src), l_exc_copy)
-EXC( LOAD t4, UNIT(4)(src), l_exc_copy)
-EXC( LOAD t5, UNIT(5)(src), l_exc_copy)
-EXC( LOAD t6, UNIT(6)(src), l_exc_copy)
-EXC( LOAD t7, UNIT(7)(src), l_exc_copy)
+EXC( LOAD t0, UNIT(0)(src), .Ll_exc)
+EXC( LOAD t1, UNIT(1)(src), .Ll_exc_copy)
+EXC( LOAD t2, UNIT(2)(src), .Ll_exc_copy)
+EXC( LOAD t3, UNIT(3)(src), .Ll_exc_copy)
+EXC( LOAD t4, UNIT(4)(src), .Ll_exc_copy)
+EXC( LOAD t5, UNIT(5)(src), .Ll_exc_copy)
+EXC( LOAD t6, UNIT(6)(src), .Ll_exc_copy)
+EXC( LOAD t7, UNIT(7)(src), .Ll_exc_copy)
SUB len, len, 8*NBYTES
ADD src, src, 8*NBYTES
-EXC( STORE t0, UNIT(0)(dst), s_exc)
+EXC( STORE t0, UNIT(0)(dst), .Ls_exc)
ADDC(sum, t0)
-EXC( STORE t1, UNIT(1)(dst), s_exc)
+EXC( STORE t1, UNIT(1)(dst), .Ls_exc)
ADDC(sum, t1)
-EXC( STORE t2, UNIT(2)(dst), s_exc)
+EXC( STORE t2, UNIT(2)(dst), .Ls_exc)
ADDC(sum, t2)
-EXC( STORE t3, UNIT(3)(dst), s_exc)
+EXC( STORE t3, UNIT(3)(dst), .Ls_exc)
ADDC(sum, t3)
-EXC( STORE t4, UNIT(4)(dst), s_exc)
+EXC( STORE t4, UNIT(4)(dst), .Ls_exc)
ADDC(sum, t4)
-EXC( STORE t5, UNIT(5)(dst), s_exc)
+EXC( STORE t5, UNIT(5)(dst), .Ls_exc)
ADDC(sum, t5)
-EXC( STORE t6, UNIT(6)(dst), s_exc)
+EXC( STORE t6, UNIT(6)(dst), .Ls_exc)
ADDC(sum, t6)
-EXC( STORE t7, UNIT(7)(dst), s_exc)
+EXC( STORE t7, UNIT(7)(dst), .Ls_exc)
ADDC(sum, t7)
+ .set reorder /* DADDI_WAR */
+ ADD dst, dst, 8*NBYTES
bgez len, 1b
- ADD dst, dst, 8*NBYTES
+ .set noreorder
ADD len, 8*NBYTES # revert len (see above)
/*
* len == the number of bytes left to copy < 8*NBYTES
*/
-cleanup_both_aligned:
+.Lcleanup_both_aligned:
#define rem t7
- beqz len, done
+ beqz len, .Ldone
sltu t0, len, 4*NBYTES
- bnez t0, less_than_4units
+ bnez t0, .Lless_than_4units
and rem, len, (NBYTES-1) # rem = len % NBYTES
/*
* len >= 4*NBYTES
*/
-EXC( LOAD t0, UNIT(0)(src), l_exc)
-EXC( LOAD t1, UNIT(1)(src), l_exc_copy)
-EXC( LOAD t2, UNIT(2)(src), l_exc_copy)
-EXC( LOAD t3, UNIT(3)(src), l_exc_copy)
+EXC( LOAD t0, UNIT(0)(src), .Ll_exc)
+EXC( LOAD t1, UNIT(1)(src), .Ll_exc_copy)
+EXC( LOAD t2, UNIT(2)(src), .Ll_exc_copy)
+EXC( LOAD t3, UNIT(3)(src), .Ll_exc_copy)
SUB len, len, 4*NBYTES
ADD src, src, 4*NBYTES
-EXC( STORE t0, UNIT(0)(dst), s_exc)
+EXC( STORE t0, UNIT(0)(dst), .Ls_exc)
ADDC(sum, t0)
-EXC( STORE t1, UNIT(1)(dst), s_exc)
+EXC( STORE t1, UNIT(1)(dst), .Ls_exc)
ADDC(sum, t1)
-EXC( STORE t2, UNIT(2)(dst), s_exc)
+EXC( STORE t2, UNIT(2)(dst), .Ls_exc)
ADDC(sum, t2)
-EXC( STORE t3, UNIT(3)(dst), s_exc)
+EXC( STORE t3, UNIT(3)(dst), .Ls_exc)
ADDC(sum, t3)
- beqz len, done
- ADD dst, dst, 4*NBYTES
-less_than_4units:
+ .set reorder /* DADDI_WAR */
+ ADD dst, dst, 4*NBYTES
+ beqz len, .Ldone
+ .set noreorder
+.Lless_than_4units:
/*
* rem = len % NBYTES
*/
- beq rem, len, copy_bytes
+ beq rem, len, .Lcopy_bytes
nop
1:
-EXC( LOAD t0, 0(src), l_exc)
+EXC( LOAD t0, 0(src), .Ll_exc)
ADD src, src, NBYTES
SUB len, len, NBYTES
-EXC( STORE t0, 0(dst), s_exc)
+EXC( STORE t0, 0(dst), .Ls_exc)
ADDC(sum, t0)
+ .set reorder /* DADDI_WAR */
+ ADD dst, dst, NBYTES
bne rem, len, 1b
- ADD dst, dst, NBYTES
+ .set noreorder
/*
* src and dst are aligned, need to copy rem bytes (rem < NBYTES)
@@ -500,20 +521,20 @@ EXC( STORE t0, 0(dst), s_exc)
* more instruction-level parallelism.
*/
#define bits t2
- beqz len, done
+ beqz len, .Ldone
ADD t1, dst, len # t1 is just past last byte of dst
li bits, 8*NBYTES
SLL rem, len, 3 # rem = number of bits to keep
-EXC( LOAD t0, 0(src), l_exc)
+EXC( LOAD t0, 0(src), .Ll_exc)
SUB bits, bits, rem # bits = number of bits to discard
SHIFT_DISCARD t0, t0, bits
-EXC( STREST t0, -1(t1), s_exc)
+EXC( STREST t0, -1(t1), .Ls_exc)
SHIFT_DISCARD_REVERT t0, t0, bits
.set reorder
ADDC(sum, t0)
- b done
+ b .Ldone
.set noreorder
-dst_unaligned:
+.Ldst_unaligned:
/*
* dst is unaligned
* t0 = src & ADDRMASK
@@ -524,25 +545,25 @@ dst_unaligned:
* Set match = (src and dst have same alignment)
*/
#define match rem
-EXC( LDFIRST t3, FIRST(0)(src), l_exc)
+EXC( LDFIRST t3, FIRST(0)(src), .Ll_exc)
ADD t2, zero, NBYTES
-EXC( LDREST t3, REST(0)(src), l_exc_copy)
+EXC( LDREST t3, REST(0)(src), .Ll_exc_copy)
SUB t2, t2, t1 # t2 = number of bytes copied
xor match, t0, t1
-EXC( STFIRST t3, FIRST(0)(dst), s_exc)
+EXC( STFIRST t3, FIRST(0)(dst), .Ls_exc)
SLL t4, t1, 3 # t4 = number of bits to discard
SHIFT_DISCARD t3, t3, t4
/* no SHIFT_DISCARD_REVERT to handle odd buffer properly */
ADDC(sum, t3)
- beq len, t2, done
+ beq len, t2, .Ldone
SUB len, len, t2
ADD dst, dst, t2
- beqz match, both_aligned
+ beqz match, .Lboth_aligned
ADD src, src, t2
-src_unaligned_dst_aligned:
+.Lsrc_unaligned_dst_aligned:
SRL t0, len, LOG_NBYTES+2 # +2 for 4 units/iter
- beqz t0, cleanup_src_unaligned
+ beqz t0, .Lcleanup_src_unaligned
and rem, len, (4*NBYTES-1) # rem = len % 4*NBYTES
1:
/*
@@ -551,49 +572,53 @@ src_unaligned_dst_aligned:
* It's OK to load FIRST(N+1) before REST(N) because the two addresses
* are to the same unit (unless src is aligned, but it's not).
*/
-EXC( LDFIRST t0, FIRST(0)(src), l_exc)
-EXC( LDFIRST t1, FIRST(1)(src), l_exc_copy)
+EXC( LDFIRST t0, FIRST(0)(src), .Ll_exc)
+EXC( LDFIRST t1, FIRST(1)(src), .Ll_exc_copy)
SUB len, len, 4*NBYTES
-EXC( LDREST t0, REST(0)(src), l_exc_copy)
-EXC( LDREST t1, REST(1)(src), l_exc_copy)
-EXC( LDFIRST t2, FIRST(2)(src), l_exc_copy)
-EXC( LDFIRST t3, FIRST(3)(src), l_exc_copy)
-EXC( LDREST t2, REST(2)(src), l_exc_copy)
-EXC( LDREST t3, REST(3)(src), l_exc_copy)
+EXC( LDREST t0, REST(0)(src), .Ll_exc_copy)
+EXC( LDREST t1, REST(1)(src), .Ll_exc_copy)
+EXC( LDFIRST t2, FIRST(2)(src), .Ll_exc_copy)
+EXC( LDFIRST t3, FIRST(3)(src), .Ll_exc_copy)
+EXC( LDREST t2, REST(2)(src), .Ll_exc_copy)
+EXC( LDREST t3, REST(3)(src), .Ll_exc_copy)
ADD src, src, 4*NBYTES
#ifdef CONFIG_CPU_SB1
nop # improves slotting
#endif
-EXC( STORE t0, UNIT(0)(dst), s_exc)
+EXC( STORE t0, UNIT(0)(dst), .Ls_exc)
ADDC(sum, t0)
-EXC( STORE t1, UNIT(1)(dst), s_exc)
+EXC( STORE t1, UNIT(1)(dst), .Ls_exc)
ADDC(sum, t1)
-EXC( STORE t2, UNIT(2)(dst), s_exc)
+EXC( STORE t2, UNIT(2)(dst), .Ls_exc)
ADDC(sum, t2)
-EXC( STORE t3, UNIT(3)(dst), s_exc)
+EXC( STORE t3, UNIT(3)(dst), .Ls_exc)
ADDC(sum, t3)
+ .set reorder /* DADDI_WAR */
+ ADD dst, dst, 4*NBYTES
bne len, rem, 1b
- ADD dst, dst, 4*NBYTES
+ .set noreorder
-cleanup_src_unaligned:
- beqz len, done
+.Lcleanup_src_unaligned:
+ beqz len, .Ldone
and rem, len, NBYTES-1 # rem = len % NBYTES
- beq rem, len, copy_bytes
+ beq rem, len, .Lcopy_bytes
nop
1:
-EXC( LDFIRST t0, FIRST(0)(src), l_exc)
-EXC( LDREST t0, REST(0)(src), l_exc_copy)
+EXC( LDFIRST t0, FIRST(0)(src), .Ll_exc)
+EXC( LDREST t0, REST(0)(src), .Ll_exc_copy)
ADD src, src, NBYTES
SUB len, len, NBYTES
-EXC( STORE t0, 0(dst), s_exc)
+EXC( STORE t0, 0(dst), .Ls_exc)
ADDC(sum, t0)
+ .set reorder /* DADDI_WAR */
+ ADD dst, dst, NBYTES
bne len, rem, 1b
- ADD dst, dst, NBYTES
+ .set noreorder
-copy_bytes_checklen:
- beqz len, done
+.Lcopy_bytes_checklen:
+ beqz len, .Ldone
nop
-copy_bytes:
+.Lcopy_bytes:
/* 0 < len < NBYTES */
#ifdef CONFIG_CPU_LITTLE_ENDIAN
#define SHIFT_START 0
@@ -604,14 +629,14 @@ copy_bytes:
#endif
move t2, zero # partial word
li t3, SHIFT_START # shift
-/* use l_exc_copy here to return correct sum on fault */
+/* use .Ll_exc_copy here to return correct sum on fault */
#define COPY_BYTE(N) \
-EXC( lbu t0, N(src), l_exc_copy); \
+EXC( lbu t0, N(src), .Ll_exc_copy); \
SUB len, len, 1; \
-EXC( sb t0, N(dst), s_exc); \
+EXC( sb t0, N(dst), .Ls_exc); \
SLLV t0, t0, t3; \
addu t3, SHIFT_INC; \
- beqz len, copy_bytes_done; \
+ beqz len, .Lcopy_bytes_done; \
or t2, t0
COPY_BYTE(0)
@@ -622,15 +647,17 @@ EXC( sb t0, N(dst), s_exc); \
COPY_BYTE(4)
COPY_BYTE(5)
#endif
-EXC( lbu t0, NBYTES-2(src), l_exc_copy)
+EXC( lbu t0, NBYTES-2(src), .Ll_exc_copy)
SUB len, len, 1
-EXC( sb t0, NBYTES-2(dst), s_exc)
+EXC( sb t0, NBYTES-2(dst), .Ls_exc)
SLLV t0, t0, t3
or t2, t0
-copy_bytes_done:
+.Lcopy_bytes_done:
ADDC(sum, t2)
-done:
+.Ldone:
/* fold checksum */
+ .set push
+ .set noat
#ifdef USE_DOUBLE
dsll32 v1, sum, 0
daddu sum, v1
@@ -651,13 +678,14 @@ done:
srl sum, sum, 8
or sum, v1
andi sum, 0xffff
+ .set pop
1:
.set reorder
ADDC(sum, psum)
jr ra
.set noreorder
-l_exc_copy:
+.Ll_exc_copy:
/*
* Copy bytes from src until faulting load address (or until a
* lb faults)
@@ -672,15 +700,17 @@ l_exc_copy:
li t2, SHIFT_START
LOAD t0, THREAD_BUADDR(t0)
1:
-EXC( lbu t1, 0(src), l_exc)
+EXC( lbu t1, 0(src), .Ll_exc)
ADD src, src, 1
sb t1, 0(dst) # can't fault -- we're copy_from_user
SLLV t1, t1, t2
addu t2, SHIFT_INC
ADDC(sum, t1)
+ .set reorder /* DADDI_WAR */
+ ADD dst, dst, 1
bne src, t0, 1b
- ADD dst, dst, 1
-l_exc:
+ .set noreorder
+.Ll_exc:
LOAD t0, TI_TASK($28)
nop
LOAD t0, THREAD_BUADDR(t0) # t0 is just past last good address
@@ -697,19 +727,30 @@ l_exc:
* Clear len bytes starting at dst. Can't call __bzero because it
* might modify len. An inefficient loop for these rare times...
*/
- beqz len, done
- SUB src, len, 1
+ .set reorder /* DADDI_WAR */
+ SUB src, len, 1
+ beqz len, .Ldone
+ .set noreorder
1: sb zero, 0(dst)
ADD dst, dst, 1
+ .set push
+ .set noat
+#ifndef CONFIG_CPU_DADDI_WORKAROUNDS
bnez src, 1b
SUB src, src, 1
+#else
+ li v1, 1
+ bnez src, 1b
+ SUB src, src, v1
+#endif
li v1, -EFAULT
- b done
+ b .Ldone
sw v1, (errptr)
-s_exc:
+.Ls_exc:
li v0, -1 /* invalid checksum */
li v1, -EFAULT
jr ra
sw v1, (errptr)
+ .set pop
END(__csum_partial_copy_user)
diff --git a/arch/mips/lib/memcpy-inatomic.S b/arch/mips/lib/memcpy-inatomic.S
index 3a534b2baa0f..736d0fb56a94 100644
--- a/arch/mips/lib/memcpy-inatomic.S
+++ b/arch/mips/lib/memcpy-inatomic.S
@@ -9,6 +9,7 @@
* Copyright (C) 1999, 2000, 01, 2002 Silicon Graphics, Inc.
* Copyright (C) 2002 Broadcom, Inc.
* memcpy/copy_user author: Mark Vandevoorde
+ * Copyright (C) 2007 Maciej W. Rozycki
*
* Mnemonic names for arguments to memcpy/__copy_user
*/
@@ -175,7 +176,11 @@
.text
.set noreorder
+#ifndef CONFIG_CPU_DADDI_WORKAROUNDS
.set noat
+#else
+ .set at=v1
+#endif
/*
* A combined memcpy/__copy_user
@@ -204,36 +209,36 @@ LEAF(__copy_user_inatomic)
and t1, dst, ADDRMASK
PREF( 0, 1*32(src) )
PREF( 1, 1*32(dst) )
- bnez t2, copy_bytes_checklen
+ bnez t2, .Lcopy_bytes_checklen
and t0, src, ADDRMASK
PREF( 0, 2*32(src) )
PREF( 1, 2*32(dst) )
- bnez t1, dst_unaligned
+ bnez t1, .Ldst_unaligned
nop
- bnez t0, src_unaligned_dst_aligned
+ bnez t0, .Lsrc_unaligned_dst_aligned
/*
* use delay slot for fall-through
* src and dst are aligned; need to compute rem
*/
-both_aligned:
- SRL t0, len, LOG_NBYTES+3 # +3 for 8 units/iter
- beqz t0, cleanup_both_aligned # len < 8*NBYTES
- and rem, len, (8*NBYTES-1) # rem = len % (8*NBYTES)
+.Lboth_aligned:
+ SRL t0, len, LOG_NBYTES+3 # +3 for 8 units/iter
+ beqz t0, .Lcleanup_both_aligned # len < 8*NBYTES
+ and rem, len, (8*NBYTES-1) # rem = len % (8*NBYTES)
PREF( 0, 3*32(src) )
PREF( 1, 3*32(dst) )
.align 4
1:
-EXC( LOAD t0, UNIT(0)(src), l_exc)
-EXC( LOAD t1, UNIT(1)(src), l_exc_copy)
-EXC( LOAD t2, UNIT(2)(src), l_exc_copy)
-EXC( LOAD t3, UNIT(3)(src), l_exc_copy)
+EXC( LOAD t0, UNIT(0)(src), .Ll_exc)
+EXC( LOAD t1, UNIT(1)(src), .Ll_exc_copy)
+EXC( LOAD t2, UNIT(2)(src), .Ll_exc_copy)
+EXC( LOAD t3, UNIT(3)(src), .Ll_exc_copy)
SUB len, len, 8*NBYTES
-EXC( LOAD t4, UNIT(4)(src), l_exc_copy)
-EXC( LOAD t7, UNIT(5)(src), l_exc_copy)
+EXC( LOAD t4, UNIT(4)(src), .Ll_exc_copy)
+EXC( LOAD t7, UNIT(5)(src), .Ll_exc_copy)
STORE t0, UNIT(0)(dst)
STORE t1, UNIT(1)(dst)
-EXC( LOAD t0, UNIT(6)(src), l_exc_copy)
-EXC( LOAD t1, UNIT(7)(src), l_exc_copy)
+EXC( LOAD t0, UNIT(6)(src), .Ll_exc_copy)
+EXC( LOAD t1, UNIT(7)(src), .Ll_exc_copy)
ADD src, src, 8*NBYTES
ADD dst, dst, 8*NBYTES
STORE t2, UNIT(-6)(dst)
@@ -250,39 +255,43 @@ EXC( LOAD t1, UNIT(7)(src), l_exc_copy)
/*
* len == rem == the number of bytes left to copy < 8*NBYTES
*/
-cleanup_both_aligned:
- beqz len, done
+.Lcleanup_both_aligned:
+ beqz len, .Ldone
sltu t0, len, 4*NBYTES
- bnez t0, less_than_4units
+ bnez t0, .Lless_than_4units
and rem, len, (NBYTES-1) # rem = len % NBYTES
/*
* len >= 4*NBYTES
*/
-EXC( LOAD t0, UNIT(0)(src), l_exc)
-EXC( LOAD t1, UNIT(1)(src), l_exc_copy)
-EXC( LOAD t2, UNIT(2)(src), l_exc_copy)
-EXC( LOAD t3, UNIT(3)(src), l_exc_copy)
+EXC( LOAD t0, UNIT(0)(src), .Ll_exc)
+EXC( LOAD t1, UNIT(1)(src), .Ll_exc_copy)
+EXC( LOAD t2, UNIT(2)(src), .Ll_exc_copy)
+EXC( LOAD t3, UNIT(3)(src), .Ll_exc_copy)
SUB len, len, 4*NBYTES
ADD src, src, 4*NBYTES
STORE t0, UNIT(0)(dst)
STORE t1, UNIT(1)(dst)
STORE t2, UNIT(2)(dst)
STORE t3, UNIT(3)(dst)
- beqz len, done
- ADD dst, dst, 4*NBYTES
-less_than_4units:
+ .set reorder /* DADDI_WAR */
+ ADD dst, dst, 4*NBYTES
+ beqz len, .Ldone
+ .set noreorder
+.Lless_than_4units:
/*
* rem = len % NBYTES
*/
- beq rem, len, copy_bytes
+ beq rem, len, .Lcopy_bytes
nop
1:
-EXC( LOAD t0, 0(src), l_exc)
+EXC( LOAD t0, 0(src), .Ll_exc)
ADD src, src, NBYTES
SUB len, len, NBYTES
STORE t0, 0(dst)
+ .set reorder /* DADDI_WAR */
+ ADD dst, dst, NBYTES
bne rem, len, 1b
- ADD dst, dst, NBYTES
+ .set noreorder
/*
* src and dst are aligned, need to copy rem bytes (rem < NBYTES)
@@ -296,17 +305,17 @@ EXC( LOAD t0, 0(src), l_exc)
* more instruction-level parallelism.
*/
#define bits t2
- beqz len, done
+ beqz len, .Ldone
ADD t1, dst, len # t1 is just past last byte of dst
li bits, 8*NBYTES
SLL rem, len, 3 # rem = number of bits to keep
-EXC( LOAD t0, 0(src), l_exc)
+EXC( LOAD t0, 0(src), .Ll_exc)
SUB bits, bits, rem # bits = number of bits to discard
SHIFT_DISCARD t0, t0, bits
STREST t0, -1(t1)
jr ra
move len, zero
-dst_unaligned:
+.Ldst_unaligned:
/*
* dst is unaligned
* t0 = src & ADDRMASK
@@ -317,22 +326,22 @@ dst_unaligned:
* Set match = (src and dst have same alignment)
*/
#define match rem
-EXC( LDFIRST t3, FIRST(0)(src), l_exc)
+EXC( LDFIRST t3, FIRST(0)(src), .Ll_exc)
ADD t2, zero, NBYTES
-EXC( LDREST t3, REST(0)(src), l_exc_copy)
+EXC( LDREST t3, REST(0)(src), .Ll_exc_copy)
SUB t2, t2, t1 # t2 = number of bytes copied
xor match, t0, t1
STFIRST t3, FIRST(0)(dst)
- beq len, t2, done
+ beq len, t2, .Ldone
SUB len, len, t2
ADD dst, dst, t2
- beqz match, both_aligned
+ beqz match, .Lboth_aligned
ADD src, src, t2
-src_unaligned_dst_aligned:
+.Lsrc_unaligned_dst_aligned:
SRL t0, len, LOG_NBYTES+2 # +2 for 4 units/iter
PREF( 0, 3*32(src) )
- beqz t0, cleanup_src_unaligned
+ beqz t0, .Lcleanup_src_unaligned
and rem, len, (4*NBYTES-1) # rem = len % 4*NBYTES
PREF( 1, 3*32(dst) )
1:
@@ -342,15 +351,15 @@ src_unaligned_dst_aligned:
* It's OK to load FIRST(N+1) before REST(N) because the two addresses
* are to the same unit (unless src is aligned, but it's not).
*/
-EXC( LDFIRST t0, FIRST(0)(src), l_exc)
-EXC( LDFIRST t1, FIRST(1)(src), l_exc_copy)
+EXC( LDFIRST t0, FIRST(0)(src), .Ll_exc)
+EXC( LDFIRST t1, FIRST(1)(src), .Ll_exc_copy)
SUB len, len, 4*NBYTES
-EXC( LDREST t0, REST(0)(src), l_exc_copy)
-EXC( LDREST t1, REST(1)(src), l_exc_copy)
-EXC( LDFIRST t2, FIRST(2)(src), l_exc_copy)
-EXC( LDFIRST t3, FIRST(3)(src), l_exc_copy)
-EXC( LDREST t2, REST(2)(src), l_exc_copy)
-EXC( LDREST t3, REST(3)(src), l_exc_copy)
+EXC( LDREST t0, REST(0)(src), .Ll_exc_copy)
+EXC( LDREST t1, REST(1)(src), .Ll_exc_copy)
+EXC( LDFIRST t2, FIRST(2)(src), .Ll_exc_copy)
+EXC( LDFIRST t3, FIRST(3)(src), .Ll_exc_copy)
+EXC( LDREST t2, REST(2)(src), .Ll_exc_copy)
+EXC( LDREST t3, REST(3)(src), .Ll_exc_copy)
PREF( 0, 9*32(src) ) # 0 is PREF_LOAD (not streamed)
ADD src, src, 4*NBYTES
#ifdef CONFIG_CPU_SB1
@@ -361,32 +370,36 @@ EXC( LDREST t3, REST(3)(src), l_exc_copy)
STORE t2, UNIT(2)(dst)
STORE t3, UNIT(3)(dst)
PREF( 1, 9*32(dst) ) # 1 is PREF_STORE (not streamed)
+ .set reorder /* DADDI_WAR */
+ ADD dst, dst, 4*NBYTES
bne len, rem, 1b
- ADD dst, dst, 4*NBYTES
+ .set noreorder
-cleanup_src_unaligned:
- beqz len, done
+.Lcleanup_src_unaligned:
+ beqz len, .Ldone
and rem, len, NBYTES-1 # rem = len % NBYTES
- beq rem, len, copy_bytes
+ beq rem, len, .Lcopy_bytes
nop
1:
-EXC( LDFIRST t0, FIRST(0)(src), l_exc)
-EXC( LDREST t0, REST(0)(src), l_exc_copy)
+EXC( LDFIRST t0, FIRST(0)(src), .Ll_exc)
+EXC( LDREST t0, REST(0)(src), .Ll_exc_copy)
ADD src, src, NBYTES
SUB len, len, NBYTES
STORE t0, 0(dst)
+ .set reorder /* DADDI_WAR */
+ ADD dst, dst, NBYTES
bne len, rem, 1b
- ADD dst, dst, NBYTES
+ .set noreorder
-copy_bytes_checklen:
- beqz len, done
+.Lcopy_bytes_checklen:
+ beqz len, .Ldone
nop
-copy_bytes:
+.Lcopy_bytes:
/* 0 < len < NBYTES */
#define COPY_BYTE(N) \
-EXC( lb t0, N(src), l_exc); \
+EXC( lb t0, N(src), .Ll_exc); \
SUB len, len, 1; \
- beqz len, done; \
+ beqz len, .Ldone; \
sb t0, N(dst)
COPY_BYTE(0)
@@ -397,16 +410,16 @@ EXC( lb t0, N(src), l_exc); \
COPY_BYTE(4)
COPY_BYTE(5)
#endif
-EXC( lb t0, NBYTES-2(src), l_exc)
+EXC( lb t0, NBYTES-2(src), .Ll_exc)
SUB len, len, 1
jr ra
sb t0, NBYTES-2(dst)
-done:
+.Ldone:
jr ra
nop
END(__copy_user_inatomic)
-l_exc_copy:
+.Ll_exc_copy:
/*
* Copy bytes from src until faulting load address (or until a
* lb faults)
@@ -421,12 +434,14 @@ l_exc_copy:
nop
LOAD t0, THREAD_BUADDR(t0)
1:
-EXC( lb t1, 0(src), l_exc)
+EXC( lb t1, 0(src), .Ll_exc)
ADD src, src, 1
sb t1, 0(dst) # can't fault -- we're copy_from_user
+ .set reorder /* DADDI_WAR */
+ ADD dst, dst, 1
bne src, t0, 1b
- ADD dst, dst, 1
-l_exc:
+ .set noreorder
+.Ll_exc:
LOAD t0, TI_TASK($28)
nop
LOAD t0, THREAD_BUADDR(t0) # t0 is just past last good address
diff --git a/arch/mips/lib/memcpy.S b/arch/mips/lib/memcpy.S
index a526c62cb76a..c06cccf60bec 100644
--- a/arch/mips/lib/memcpy.S
+++ b/arch/mips/lib/memcpy.S
@@ -9,6 +9,7 @@
* Copyright (C) 1999, 2000, 01, 2002 Silicon Graphics, Inc.
* Copyright (C) 2002 Broadcom, Inc.
* memcpy/copy_user author: Mark Vandevoorde
+ * Copyright (C) 2007 Maciej W. Rozycki
*
* Mnemonic names for arguments to memcpy/__copy_user
*/
@@ -175,7 +176,11 @@
.text
.set noreorder
+#ifndef CONFIG_CPU_DADDI_WORKAROUNDS
.set noat
+#else
+ .set at=v1
+#endif
/*
* A combined memcpy/__copy_user
@@ -186,7 +191,7 @@
.align 5
LEAF(memcpy) /* a0=dst a1=src a2=len */
move v0, dst /* return value */
-__memcpy:
+.L__memcpy:
FEXPORT(__copy_user)
/*
* Note: dst & src may be unaligned, len may be 0
@@ -194,6 +199,7 @@ FEXPORT(__copy_user)
*/
#define rem t8
+ R10KCBARRIER(0(ra))
/*
* The "issue break"s below are very approximate.
* Issue delays for dcache fills will perturb the schedule, as will
@@ -207,44 +213,45 @@ FEXPORT(__copy_user)
and t1, dst, ADDRMASK
PREF( 0, 1*32(src) )
PREF( 1, 1*32(dst) )
- bnez t2, copy_bytes_checklen
+ bnez t2, .Lcopy_bytes_checklen
and t0, src, ADDRMASK
PREF( 0, 2*32(src) )
PREF( 1, 2*32(dst) )
- bnez t1, dst_unaligned
+ bnez t1, .Ldst_unaligned
nop
- bnez t0, src_unaligned_dst_aligned
+ bnez t0, .Lsrc_unaligned_dst_aligned
/*
* use delay slot for fall-through
* src and dst are aligned; need to compute rem
*/
-both_aligned:
+.Lboth_aligned:
SRL t0, len, LOG_NBYTES+3 # +3 for 8 units/iter
- beqz t0, cleanup_both_aligned # len < 8*NBYTES
+ beqz t0, .Lcleanup_both_aligned # len < 8*NBYTES
and rem, len, (8*NBYTES-1) # rem = len % (8*NBYTES)
PREF( 0, 3*32(src) )
PREF( 1, 3*32(dst) )
.align 4
1:
-EXC( LOAD t0, UNIT(0)(src), l_exc)
-EXC( LOAD t1, UNIT(1)(src), l_exc_copy)
-EXC( LOAD t2, UNIT(2)(src), l_exc_copy)
-EXC( LOAD t3, UNIT(3)(src), l_exc_copy)
+ R10KCBARRIER(0(ra))
+EXC( LOAD t0, UNIT(0)(src), .Ll_exc)
+EXC( LOAD t1, UNIT(1)(src), .Ll_exc_copy)
+EXC( LOAD t2, UNIT(2)(src), .Ll_exc_copy)
+EXC( LOAD t3, UNIT(3)(src), .Ll_exc_copy)
SUB len, len, 8*NBYTES
-EXC( LOAD t4, UNIT(4)(src), l_exc_copy)
-EXC( LOAD t7, UNIT(5)(src), l_exc_copy)
-EXC( STORE t0, UNIT(0)(dst), s_exc_p8u)
-EXC( STORE t1, UNIT(1)(dst), s_exc_p7u)
-EXC( LOAD t0, UNIT(6)(src), l_exc_copy)
-EXC( LOAD t1, UNIT(7)(src), l_exc_copy)
+EXC( LOAD t4, UNIT(4)(src), .Ll_exc_copy)
+EXC( LOAD t7, UNIT(5)(src), .Ll_exc_copy)
+EXC( STORE t0, UNIT(0)(dst), .Ls_exc_p8u)
+EXC( STORE t1, UNIT(1)(dst), .Ls_exc_p7u)
+EXC( LOAD t0, UNIT(6)(src), .Ll_exc_copy)
+EXC( LOAD t1, UNIT(7)(src), .Ll_exc_copy)
ADD src, src, 8*NBYTES
ADD dst, dst, 8*NBYTES
-EXC( STORE t2, UNIT(-6)(dst), s_exc_p6u)
-EXC( STORE t3, UNIT(-5)(dst), s_exc_p5u)
-EXC( STORE t4, UNIT(-4)(dst), s_exc_p4u)
-EXC( STORE t7, UNIT(-3)(dst), s_exc_p3u)
-EXC( STORE t0, UNIT(-2)(dst), s_exc_p2u)
-EXC( STORE t1, UNIT(-1)(dst), s_exc_p1u)
+EXC( STORE t2, UNIT(-6)(dst), .Ls_exc_p6u)
+EXC( STORE t3, UNIT(-5)(dst), .Ls_exc_p5u)
+EXC( STORE t4, UNIT(-4)(dst), .Ls_exc_p4u)
+EXC( STORE t7, UNIT(-3)(dst), .Ls_exc_p3u)
+EXC( STORE t0, UNIT(-2)(dst), .Ls_exc_p2u)
+EXC( STORE t1, UNIT(-1)(dst), .Ls_exc_p1u)
PREF( 0, 8*32(src) )
PREF( 1, 8*32(dst) )
bne len, rem, 1b
@@ -253,39 +260,45 @@ EXC( STORE t1, UNIT(-1)(dst), s_exc_p1u)
/*
* len == rem == the number of bytes left to copy < 8*NBYTES
*/
-cleanup_both_aligned:
- beqz len, done
+.Lcleanup_both_aligned:
+ beqz len, .Ldone
sltu t0, len, 4*NBYTES
- bnez t0, less_than_4units
+ bnez t0, .Lless_than_4units
and rem, len, (NBYTES-1) # rem = len % NBYTES
/*
* len >= 4*NBYTES
*/
-EXC( LOAD t0, UNIT(0)(src), l_exc)
-EXC( LOAD t1, UNIT(1)(src), l_exc_copy)
-EXC( LOAD t2, UNIT(2)(src), l_exc_copy)
-EXC( LOAD t3, UNIT(3)(src), l_exc_copy)
+EXC( LOAD t0, UNIT(0)(src), .Ll_exc)
+EXC( LOAD t1, UNIT(1)(src), .Ll_exc_copy)
+EXC( LOAD t2, UNIT(2)(src), .Ll_exc_copy)
+EXC( LOAD t3, UNIT(3)(src), .Ll_exc_copy)
SUB len, len, 4*NBYTES
ADD src, src, 4*NBYTES
-EXC( STORE t0, UNIT(0)(dst), s_exc_p4u)
-EXC( STORE t1, UNIT(1)(dst), s_exc_p3u)
-EXC( STORE t2, UNIT(2)(dst), s_exc_p2u)
-EXC( STORE t3, UNIT(3)(dst), s_exc_p1u)
- beqz len, done
- ADD dst, dst, 4*NBYTES
-less_than_4units:
+ R10KCBARRIER(0(ra))
+EXC( STORE t0, UNIT(0)(dst), .Ls_exc_p4u)
+EXC( STORE t1, UNIT(1)(dst), .Ls_exc_p3u)
+EXC( STORE t2, UNIT(2)(dst), .Ls_exc_p2u)
+EXC( STORE t3, UNIT(3)(dst), .Ls_exc_p1u)
+ .set reorder /* DADDI_WAR */
+ ADD dst, dst, 4*NBYTES
+ beqz len, .Ldone
+ .set noreorder
+.Lless_than_4units:
/*
* rem = len % NBYTES
*/
- beq rem, len, copy_bytes
+ beq rem, len, .Lcopy_bytes
nop
1:
-EXC( LOAD t0, 0(src), l_exc)
+ R10KCBARRIER(0(ra))
+EXC( LOAD t0, 0(src), .Ll_exc)
ADD src, src, NBYTES
SUB len, len, NBYTES
-EXC( STORE t0, 0(dst), s_exc_p1u)
+EXC( STORE t0, 0(dst), .Ls_exc_p1u)
+ .set reorder /* DADDI_WAR */
+ ADD dst, dst, NBYTES
bne rem, len, 1b
- ADD dst, dst, NBYTES
+ .set noreorder
/*
* src and dst are aligned, need to copy rem bytes (rem < NBYTES)
@@ -299,17 +312,17 @@ EXC( STORE t0, 0(dst), s_exc_p1u)
* more instruction-level parallelism.
*/
#define bits t2
- beqz len, done
+ beqz len, .Ldone
ADD t1, dst, len # t1 is just past last byte of dst
li bits, 8*NBYTES
SLL rem, len, 3 # rem = number of bits to keep
-EXC( LOAD t0, 0(src), l_exc)
+EXC( LOAD t0, 0(src), .Ll_exc)
SUB bits, bits, rem # bits = number of bits to discard
SHIFT_DISCARD t0, t0, bits
-EXC( STREST t0, -1(t1), s_exc)
+EXC( STREST t0, -1(t1), .Ls_exc)
jr ra
move len, zero
-dst_unaligned:
+.Ldst_unaligned:
/*
* dst is unaligned
* t0 = src & ADDRMASK
@@ -320,22 +333,23 @@ dst_unaligned:
* Set match = (src and dst have same alignment)
*/
#define match rem
-EXC( LDFIRST t3, FIRST(0)(src), l_exc)
+EXC( LDFIRST t3, FIRST(0)(src), .Ll_exc)
ADD t2, zero, NBYTES
-EXC( LDREST t3, REST(0)(src), l_exc_copy)
+EXC( LDREST t3, REST(0)(src), .Ll_exc_copy)
SUB t2, t2, t1 # t2 = number of bytes copied
xor match, t0, t1
-EXC( STFIRST t3, FIRST(0)(dst), s_exc)
- beq len, t2, done
+ R10KCBARRIER(0(ra))
+EXC( STFIRST t3, FIRST(0)(dst), .Ls_exc)
+ beq len, t2, .Ldone
SUB len, len, t2
ADD dst, dst, t2
- beqz match, both_aligned
+ beqz match, .Lboth_aligned
ADD src, src, t2
-src_unaligned_dst_aligned:
+.Lsrc_unaligned_dst_aligned:
SRL t0, len, LOG_NBYTES+2 # +2 for 4 units/iter
PREF( 0, 3*32(src) )
- beqz t0, cleanup_src_unaligned
+ beqz t0, .Lcleanup_src_unaligned
and rem, len, (4*NBYTES-1) # rem = len % 4*NBYTES
PREF( 1, 3*32(dst) )
1:
@@ -345,52 +359,59 @@ src_unaligned_dst_aligned:
* It's OK to load FIRST(N+1) before REST(N) because the two addresses
* are to the same unit (unless src is aligned, but it's not).
*/
-EXC( LDFIRST t0, FIRST(0)(src), l_exc)
-EXC( LDFIRST t1, FIRST(1)(src), l_exc_copy)
+ R10KCBARRIER(0(ra))
+EXC( LDFIRST t0, FIRST(0)(src), .Ll_exc)
+EXC( LDFIRST t1, FIRST(1)(src), .Ll_exc_copy)
SUB len, len, 4*NBYTES
-EXC( LDREST t0, REST(0)(src), l_exc_copy)
-EXC( LDREST t1, REST(1)(src), l_exc_copy)
-EXC( LDFIRST t2, FIRST(2)(src), l_exc_copy)
-EXC( LDFIRST t3, FIRST(3)(src), l_exc_copy)
-EXC( LDREST t2, REST(2)(src), l_exc_copy)
-EXC( LDREST t3, REST(3)(src), l_exc_copy)
+EXC( LDREST t0, REST(0)(src), .Ll_exc_copy)
+EXC( LDREST t1, REST(1)(src), .Ll_exc_copy)
+EXC( LDFIRST t2, FIRST(2)(src), .Ll_exc_copy)
+EXC( LDFIRST t3, FIRST(3)(src), .Ll_exc_copy)
+EXC( LDREST t2, REST(2)(src), .Ll_exc_copy)
+EXC( LDREST t3, REST(3)(src), .Ll_exc_copy)
PREF( 0, 9*32(src) ) # 0 is PREF_LOAD (not streamed)
ADD src, src, 4*NBYTES
#ifdef CONFIG_CPU_SB1
nop # improves slotting
#endif
-EXC( STORE t0, UNIT(0)(dst), s_exc_p4u)
-EXC( STORE t1, UNIT(1)(dst), s_exc_p3u)
-EXC( STORE t2, UNIT(2)(dst), s_exc_p2u)
-EXC( STORE t3, UNIT(3)(dst), s_exc_p1u)
+EXC( STORE t0, UNIT(0)(dst), .Ls_exc_p4u)
+EXC( STORE t1, UNIT(1)(dst), .Ls_exc_p3u)
+EXC( STORE t2, UNIT(2)(dst), .Ls_exc_p2u)
+EXC( STORE t3, UNIT(3)(dst), .Ls_exc_p1u)
PREF( 1, 9*32(dst) ) # 1 is PREF_STORE (not streamed)
+ .set reorder /* DADDI_WAR */
+ ADD dst, dst, 4*NBYTES
bne len, rem, 1b
- ADD dst, dst, 4*NBYTES
+ .set noreorder
-cleanup_src_unaligned:
- beqz len, done
+.Lcleanup_src_unaligned:
+ beqz len, .Ldone
and rem, len, NBYTES-1 # rem = len % NBYTES
- beq rem, len, copy_bytes
+ beq rem, len, .Lcopy_bytes
nop
1:
-EXC( LDFIRST t0, FIRST(0)(src), l_exc)
-EXC( LDREST t0, REST(0)(src), l_exc_copy)
+ R10KCBARRIER(0(ra))
+EXC( LDFIRST t0, FIRST(0)(src), .Ll_exc)
+EXC( LDREST t0, REST(0)(src), .Ll_exc_copy)
ADD src, src, NBYTES
SUB len, len, NBYTES
-EXC( STORE t0, 0(dst), s_exc_p1u)
+EXC( STORE t0, 0(dst), .Ls_exc_p1u)
+ .set reorder /* DADDI_WAR */
+ ADD dst, dst, NBYTES
bne len, rem, 1b
- ADD dst, dst, NBYTES
+ .set noreorder
-copy_bytes_checklen:
- beqz len, done
+.Lcopy_bytes_checklen:
+ beqz len, .Ldone
nop
-copy_bytes:
+.Lcopy_bytes:
/* 0 < len < NBYTES */
+ R10KCBARRIER(0(ra))
#define COPY_BYTE(N) \
-EXC( lb t0, N(src), l_exc); \
+EXC( lb t0, N(src), .Ll_exc); \
SUB len, len, 1; \
- beqz len, done; \
-EXC( sb t0, N(dst), s_exc_p1)
+ beqz len, .Ldone; \
+EXC( sb t0, N(dst), .Ls_exc_p1)
COPY_BYTE(0)
COPY_BYTE(1)
@@ -400,16 +421,16 @@ EXC( sb t0, N(dst), s_exc_p1)
COPY_BYTE(4)
COPY_BYTE(5)
#endif
-EXC( lb t0, NBYTES-2(src), l_exc)
+EXC( lb t0, NBYTES-2(src), .Ll_exc)
SUB len, len, 1
jr ra
-EXC( sb t0, NBYTES-2(dst), s_exc_p1)
-done:
+EXC( sb t0, NBYTES-2(dst), .Ls_exc_p1)
+.Ldone:
jr ra
nop
END(memcpy)
-l_exc_copy:
+.Ll_exc_copy:
/*
* Copy bytes from src until faulting load address (or until a
* lb faults)
@@ -424,12 +445,14 @@ l_exc_copy:
nop
LOAD t0, THREAD_BUADDR(t0)
1:
-EXC( lb t1, 0(src), l_exc)
+EXC( lb t1, 0(src), .Ll_exc)
ADD src, src, 1
sb t1, 0(dst) # can't fault -- we're copy_from_user
+ .set reorder /* DADDI_WAR */
+ ADD dst, dst, 1
bne src, t0, 1b
- ADD dst, dst, 1
-l_exc:
+ .set noreorder
+.Ll_exc:
LOAD t0, TI_TASK($28)
nop
LOAD t0, THREAD_BUADDR(t0) # t0 is just past last good address
@@ -446,20 +469,33 @@ l_exc:
* Clear len bytes starting at dst. Can't call __bzero because it
* might modify len. An inefficient loop for these rare times...
*/
- beqz len, done
- SUB src, len, 1
+ .set reorder /* DADDI_WAR */
+ SUB src, len, 1
+ beqz len, .Ldone
+ .set noreorder
1: sb zero, 0(dst)
ADD dst, dst, 1
+#ifndef CONFIG_CPU_DADDI_WORKAROUNDS
bnez src, 1b
SUB src, src, 1
+#else
+ .set push
+ .set noat
+ li v1, 1
+ bnez src, 1b
+ SUB src, src, v1
+ .set pop
+#endif
jr ra
nop
-#define SEXC(n) \
-s_exc_p ## n ## u: \
- jr ra; \
- ADD len, len, n*NBYTES
+#define SEXC(n) \
+ .set reorder; /* DADDI_WAR */ \
+.Ls_exc_p ## n ## u: \
+ ADD len, len, n*NBYTES; \
+ jr ra; \
+ .set noreorder
SEXC(8)
SEXC(7)
@@ -470,10 +506,12 @@ SEXC(3)
SEXC(2)
SEXC(1)
-s_exc_p1:
+.Ls_exc_p1:
+ .set reorder /* DADDI_WAR */
+ ADD len, len, 1
jr ra
- ADD len, len, 1
-s_exc:
+ .set noreorder
+.Ls_exc:
jr ra
nop
@@ -484,38 +522,44 @@ LEAF(memmove)
sltu t0, a1, t0 # dst + len <= src -> memcpy
sltu t1, a0, t1 # dst >= src + len -> memcpy
and t0, t1
- beqz t0, __memcpy
+ beqz t0, .L__memcpy
move v0, a0 /* return value */
- beqz a2, r_out
+ beqz a2, .Lr_out
END(memmove)
/* fall through to __rmemcpy */
LEAF(__rmemcpy) /* a0=dst a1=src a2=len */
sltu t0, a1, a0
- beqz t0, r_end_bytes_up # src >= dst
+ beqz t0, .Lr_end_bytes_up # src >= dst
nop
ADD a0, a2 # dst = dst + len
ADD a1, a2 # src = src + len
-r_end_bytes:
+.Lr_end_bytes:
+ R10KCBARRIER(0(ra))
lb t0, -1(a1)
SUB a2, a2, 0x1
sb t0, -1(a0)
SUB a1, a1, 0x1
- bnez a2, r_end_bytes
- SUB a0, a0, 0x1
+ .set reorder /* DADDI_WAR */
+ SUB a0, a0, 0x1
+ bnez a2, .Lr_end_bytes
+ .set noreorder
-r_out:
+.Lr_out:
jr ra
move a2, zero
-r_end_bytes_up:
+.Lr_end_bytes_up:
+ R10KCBARRIER(0(ra))
lb t0, (a1)
SUB a2, a2, 0x1
sb t0, (a0)
ADD a1, a1, 0x1
- bnez a2, r_end_bytes_up
- ADD a0, a0, 0x1
+ .set reorder /* DADDI_WAR */
+ ADD a0, a0, 0x1
+ bnez a2, .Lr_end_bytes_up
+ .set noreorder
jr ra
move a2, zero
diff --git a/arch/mips/lib/memset.S b/arch/mips/lib/memset.S
index 3f8b8b3d0b23..77dc3b20110a 100644
--- a/arch/mips/lib/memset.S
+++ b/arch/mips/lib/memset.S
@@ -5,6 +5,7 @@
*
* Copyright (C) 1998, 1999, 2000 by Ralf Baechle
* Copyright (C) 1999, 2000 Silicon Graphics, Inc.
+ * Copyright (C) 2007 Maciej W. Rozycki
*/
#include <asm/asm.h>
#include <asm/asm-offsets.h>
@@ -71,34 +72,45 @@ LEAF(memset)
FEXPORT(__bzero)
sltiu t0, a2, LONGSIZE /* very small region? */
- bnez t0, small_memset
+ bnez t0, .Lsmall_memset
andi t0, a0, LONGMASK /* aligned? */
+#ifndef CONFIG_CPU_DADDI_WORKAROUNDS
beqz t0, 1f
PTR_SUBU t0, LONGSIZE /* alignment in bytes */
+#else
+ .set noat
+ li AT, LONGSIZE
+ beqz t0, 1f
+ PTR_SUBU t0, AT /* alignment in bytes */
+ .set at
+#endif
+ R10KCBARRIER(0(ra))
#ifdef __MIPSEB__
- EX(LONG_S_L, a1, (a0), first_fixup) /* make word/dword aligned */
+ EX(LONG_S_L, a1, (a0), .Lfirst_fixup) /* make word/dword aligned */
#endif
#ifdef __MIPSEL__
- EX(LONG_S_R, a1, (a0), first_fixup) /* make word/dword aligned */
+ EX(LONG_S_R, a1, (a0), .Lfirst_fixup) /* make word/dword aligned */
#endif
PTR_SUBU a0, t0 /* long align ptr */
PTR_ADDU a2, t0 /* correct size */
1: ori t1, a2, 0x3f /* # of full blocks */
xori t1, 0x3f
- beqz t1, memset_partial /* no block to fill */
+ beqz t1, .Lmemset_partial /* no block to fill */
andi t0, a2, 0x40-LONGSIZE
PTR_ADDU t1, a0 /* end address */
.set reorder
1: PTR_ADDIU a0, 64
- f_fill64 a0, -64, a1, fwd_fixup
+ R10KCBARRIER(0(ra))
+ f_fill64 a0, -64, a1, .Lfwd_fixup
bne t1, a0, 1b
.set noreorder
-memset_partial:
+.Lmemset_partial:
+ R10KCBARRIER(0(ra))
PTR_LA t1, 2f /* where to start */
#if LONGSIZE == 4
PTR_SUBU t1, t0
@@ -106,7 +118,7 @@ memset_partial:
.set noat
LONG_SRL AT, t0, 1
PTR_SUBU t1, AT
- .set noat
+ .set at
#endif
jr t1
PTR_ADDU a0, t0 /* dest ptr */
@@ -114,26 +126,28 @@ memset_partial:
.set push
.set noreorder
.set nomacro
- f_fill64 a0, -64, a1, partial_fixup /* ... but first do longs ... */
+ f_fill64 a0, -64, a1, .Lpartial_fixup /* ... but first do longs ... */
2: .set pop
andi a2, LONGMASK /* At most one long to go */
beqz a2, 1f
PTR_ADDU a0, a2 /* What's left */
+ R10KCBARRIER(0(ra))
#ifdef __MIPSEB__
- EX(LONG_S_R, a1, -1(a0), last_fixup)
+ EX(LONG_S_R, a1, -1(a0), .Llast_fixup)
#endif
#ifdef __MIPSEL__
- EX(LONG_S_L, a1, -1(a0), last_fixup)
+ EX(LONG_S_L, a1, -1(a0), .Llast_fixup)
#endif
1: jr ra
move a2, zero
-small_memset:
+.Lsmall_memset:
beqz a2, 2f
PTR_ADDU t1, a0, a2
1: PTR_ADDIU a0, 1 /* fill bytewise */
+ R10KCBARRIER(0(ra))
bne t1, a0, 1b
sb a1, -1(a0)
@@ -141,11 +155,11 @@ small_memset:
move a2, zero
END(memset)
-first_fixup:
+.Lfirst_fixup:
jr ra
nop
-fwd_fixup:
+.Lfwd_fixup:
PTR_L t0, TI_TASK($28)
LONG_L t0, THREAD_BUADDR(t0)
andi a2, 0x3f
@@ -153,7 +167,7 @@ fwd_fixup:
jr ra
LONG_SUBU a2, t0
-partial_fixup:
+.Lpartial_fixup:
PTR_L t0, TI_TASK($28)
LONG_L t0, THREAD_BUADDR(t0)
andi a2, LONGMASK
@@ -161,6 +175,6 @@ partial_fixup:
jr ra
LONG_SUBU a2, t0
-last_fixup:
+.Llast_fixup:
jr ra
andi v1, a2, LONGMASK
diff --git a/arch/mips/lib/strlen_user.S b/arch/mips/lib/strlen_user.S
index eca558d83a37..fdbb970f670d 100644
--- a/arch/mips/lib/strlen_user.S
+++ b/arch/mips/lib/strlen_user.S
@@ -24,16 +24,16 @@
LEAF(__strlen_user_asm)
LONG_L v0, TI_ADDR_LIMIT($28) # pointer ok?
and v0, a0
- bnez v0, fault
+ bnez v0, .Lfault
FEXPORT(__strlen_user_nocheck_asm)
move v0, a0
-1: EX(lb, t0, (v0), fault)
+1: EX(lb, t0, (v0), .Lfault)
PTR_ADDIU v0, 1
bnez t0, 1b
PTR_SUBU v0, a0
jr ra
END(__strlen_user_asm)
-fault: move v0, zero
+.Lfault: move v0, zero
jr ra
diff --git a/arch/mips/lib/strncpy_user.S b/arch/mips/lib/strncpy_user.S
index d16c76fbfac7..7201b2ff08c8 100644
--- a/arch/mips/lib/strncpy_user.S
+++ b/arch/mips/lib/strncpy_user.S
@@ -30,29 +30,30 @@
LEAF(__strncpy_from_user_asm)
LONG_L v0, TI_ADDR_LIMIT($28) # pointer ok?
and v0, a1
- bnez v0, fault
+ bnez v0, .Lfault
FEXPORT(__strncpy_from_user_nocheck_asm)
move v0, zero
move v1, a1
.set noreorder
-1: EX(lbu, t0, (v1), fault)
+1: EX(lbu, t0, (v1), .Lfault)
PTR_ADDIU v1, 1
+ R10KCBARRIER(0(ra))
beqz t0, 2f
sb t0, (a0)
PTR_ADDIU v0, 1
- bne v0, a2, 1b
- PTR_ADDIU a0, 1
.set reorder
+ PTR_ADDIU a0, 1
+ bne v0, a2, 1b
2: PTR_ADDU t0, a1, v0
xor t0, a1
- bltz t0, fault
+ bltz t0, .Lfault
jr ra # return n
END(__strncpy_from_user_asm)
-fault: li v0, -EFAULT
+.Lfault: li v0, -EFAULT
jr ra
.section __ex_table,"a"
- PTR 1b, fault
+ PTR 1b, .Lfault
.previous
diff --git a/arch/mips/lib/strnlen_user.S b/arch/mips/lib/strnlen_user.S
index c0ea15194a0e..c768e3000616 100644
--- a/arch/mips/lib/strnlen_user.S
+++ b/arch/mips/lib/strnlen_user.S
@@ -28,18 +28,19 @@
LEAF(__strnlen_user_asm)
LONG_L v0, TI_ADDR_LIMIT($28) # pointer ok?
and v0, a0
- bnez v0, fault
+ bnez v0, .Lfault
FEXPORT(__strnlen_user_nocheck_asm)
move v0, a0
PTR_ADDU a1, a0 # stop pointer
1: beq v0, a1, 1f # limit reached?
- EX(lb, t0, (v0), fault)
+ EX(lb, t0, (v0), .Lfault)
PTR_ADDU v0, 1
bnez t0, 1b
1: PTR_SUBU v0, a0
jr ra
END(__strnlen_user_asm)
-fault: move v0, zero
+.Lfault:
+ move v0, zero
jr ra
diff --git a/arch/mips/lib/uncached.c b/arch/mips/lib/uncached.c
index 58d14f4d9349..27b012d4341c 100644
--- a/arch/mips/lib/uncached.c
+++ b/arch/mips/lib/uncached.c
@@ -46,9 +46,9 @@ unsigned long __init run_uncached(void *func)
if (sp >= (long)CKSEG0 && sp < (long)CKSEG2)
usp = CKSEG1ADDR(sp);
#ifdef CONFIG_64BIT
- else if ((long long)sp >= (long long)PHYS_TO_XKPHYS(0LL, 0) &&
- (long long)sp < (long long)PHYS_TO_XKPHYS(8LL, 0))
- usp = PHYS_TO_XKPHYS((long long)K_CALG_UNCACHED,
+ else if ((long long)sp >= (long long)PHYS_TO_XKPHYS(0, 0) &&
+ (long long)sp < (long long)PHYS_TO_XKPHYS(8, 0))
+ usp = PHYS_TO_XKPHYS(K_CALG_UNCACHED,
XKPHYS_TO_PHYS((long long)sp));
#endif
else {
@@ -58,9 +58,9 @@ unsigned long __init run_uncached(void *func)
if (lfunc >= (long)CKSEG0 && lfunc < (long)CKSEG2)
ufunc = CKSEG1ADDR(lfunc);
#ifdef CONFIG_64BIT
- else if ((long long)lfunc >= (long long)PHYS_TO_XKPHYS(0LL, 0) &&
- (long long)lfunc < (long long)PHYS_TO_XKPHYS(8LL, 0))
- ufunc = PHYS_TO_XKPHYS((long long)K_CALG_UNCACHED,
+ else if ((long long)lfunc >= (long long)PHYS_TO_XKPHYS(0, 0) &&
+ (long long)lfunc < (long long)PHYS_TO_XKPHYS(8, 0))
+ ufunc = PHYS_TO_XKPHYS(K_CALG_UNCACHED,
XKPHYS_TO_PHYS((long long)lfunc));
#endif
else {
OpenPOWER on IntegriCloud