Use memcpy() in kcopy(), copyin(), and copyout(). XXX This means we have

to burn 3 insns to swap the arguments.  Need to change the interface to
these routines to match memcpy().

G/C bcopy() from here.  We'll let it be provided by libkern (which is
what provides memcpy()) until bcopy() is exorcised completely.
This commit is contained in:
thorpej 2001-07-13 00:06:06 +00:00
parent ac8a2539c1
commit d819792e68

View File

@ -1,4 +1,4 @@
/* $NetBSD: locore.s,v 1.96 2001/05/30 15:24:27 lukem Exp $ */
/* $NetBSD: locore.s,v 1.97 2001/07/13 00:06:06 thorpej Exp $ */
/*-
* Copyright (c) 1999, 2000 The NetBSD Foundation, Inc.
@ -73,7 +73,7 @@
#include <machine/asm.h>
__KERNEL_RCSID(0, "$NetBSD: locore.s,v 1.96 2001/05/30 15:24:27 lukem Exp $");
__KERNEL_RCSID(0, "$NetBSD: locore.s,v 1.97 2001/07/13 00:06:06 thorpej Exp $");
#include "assym.h"
@ -1090,237 +1090,6 @@ NESTED(copyoutstr, 4, 16, ra, IM_RA|IM_S0, 0)
RET /* v0 left over from copystr */
END(copyoutstr)
/*
* Copy a bytes within the kernel's address space.
*
* Although bcopy() is not specified to handle overlapping regions,
* this version does do so.
*
* void bcopy(char *from, char *to, size_t len);
*/
LEAF(bcopy,3)
/* Check for negative length */
ble a2,bcopy_done
/* Check for overlap */
subq a1,a0,t5
cmpult t5,a2,t5
bne t5,bcopy_overlap
/* a3 = end address */
addq a0,a2,a3
/* Get the first word */
ldq_u t2,0(a0)
/* Do they have the same alignment? */
xor a0,a1,t0
and t0,7,t0
and a1,7,t1
bne t0,bcopy_different_alignment
/* src & dst have same alignment */
beq t1,bcopy_all_aligned
ldq_u t3,0(a1)
addq a2,t1,a2
mskqh t2,a0,t2
mskql t3,a0,t3
or t2,t3,t2
/* Dst is 8-byte aligned */
bcopy_all_aligned:
/* If less than 8 bytes,skip loop */
subq a2,1,t0
and a2,7,a2
bic t0,7,t0
beq t0,bcopy_samealign_lp_end
bcopy_samealign_lp:
stq_u t2,0(a1)
addq a1,8,a1
ldq_u t2,8(a0)
subq t0,8,t0
addq a0,8,a0
bne t0,bcopy_samealign_lp
bcopy_samealign_lp_end:
/* If we're done, exit */
bne a2,bcopy_small_left
stq_u t2,0(a1)
RET
bcopy_small_left:
mskql t2,a2,t4
ldq_u t3,0(a1)
mskqh t3,a2,t3
or t4,t3,t4
stq_u t4,0(a1)
RET
bcopy_different_alignment:
/*
* this is the fun part
*/
addq a0,a2,a3
cmpule a2,8,t0
bne t0,bcopy_da_finish
beq t1,bcopy_da_noentry
/* Do the initial partial word */
subq zero,a1,t0
and t0,7,t0
ldq_u t3,7(a0)
extql t2,a0,t2
extqh t3,a0,t3
or t2,t3,t5
insql t5,a1,t5
ldq_u t6,0(a1)
mskql t6,a1,t6
or t5,t6,t5
stq_u t5,0(a1)
addq a0,t0,a0
addq a1,t0,a1
subq a2,t0,a2
ldq_u t2,0(a0)
bcopy_da_noentry:
subq a2,1,t0
bic t0,7,t0
and a2,7,a2
beq t0,bcopy_da_finish2
bcopy_da_lp:
ldq_u t3,7(a0)
addq a0,8,a0
extql t2,a0,t4
extqh t3,a0,t5
subq t0,8,t0
or t4,t5,t5
stq t5,0(a1)
addq a1,8,a1
beq t0,bcopy_da_finish1
ldq_u t2,7(a0)
addq a0,8,a0
extql t3,a0,t4
extqh t2,a0,t5
subq t0,8,t0
or t4,t5,t5
stq t5,0(a1)
addq a1,8,a1
bne t0,bcopy_da_lp
bcopy_da_finish2:
/* Do the last new word */
mov t2,t3
bcopy_da_finish1:
/* Do the last partial word */
ldq_u t2,-1(a3)
extql t3,a0,t3
extqh t2,a0,t2
or t2,t3,t2
br zero,bcopy_samealign_lp_end
bcopy_da_finish:
/* Do the last word in the next source word */
ldq_u t3,-1(a3)
extql t2,a0,t2
extqh t3,a0,t3
or t2,t3,t2
insqh t2,a1,t3
insql t2,a1,t2
lda t4,-1(zero)
mskql t4,a2,t5
cmovne t5,t5,t4
insqh t4,a1,t5
insql t4,a1,t4
addq a1,a2,a4
ldq_u t6,0(a1)
ldq_u t7,-1(a4)
bic t6,t4,t6
bic t7,t5,t7
and t2,t4,t2
and t3,t5,t3
or t2,t6,t2
or t3,t7,t3
stq_u t3,-1(a4)
stq_u t2,0(a1)
RET
bcopy_overlap:
/*
* Basically equivalent to previous case, only backwards.
* Not quite as highly optimized
*/
addq a0,a2,a3
addq a1,a2,a4
/* less than 8 bytes - don't worry about overlap */
cmpule a2,8,t0
bne t0,bcopy_ov_short
/* Possibly do a partial first word */
and a4,7,t4
beq t4,bcopy_ov_nostart2
subq a3,t4,a3
subq a4,t4,a4
ldq_u t1,0(a3)
subq a2,t4,a2
ldq_u t2,7(a3)
ldq t3,0(a4)
extql t1,a3,t1
extqh t2,a3,t2
or t1,t2,t1
mskqh t3,t4,t3
mskql t1,t4,t1
or t1,t3,t1
stq t1,0(a4)
bcopy_ov_nostart2:
bic a2,7,t4
and a2,7,a2
beq t4,bcopy_ov_lp_end
bcopy_ov_lp:
/* This could be more pipelined, but it doesn't seem worth it */
ldq_u t0,-8(a3)
subq a4,8,a4
ldq_u t1,-1(a3)
subq a3,8,a3
extql t0,a3,t0
extqh t1,a3,t1
subq t4,8,t4
or t0,t1,t0
stq t0,0(a4)
bne t4,bcopy_ov_lp
bcopy_ov_lp_end:
beq a2,bcopy_done
ldq_u t0,0(a0)
ldq_u t1,7(a0)
ldq_u t2,0(a1)
extql t0,a0,t0
extqh t1,a0,t1
or t0,t1,t0
insql t0,a1,t0
mskql t2,a1,t2
or t2,t0,t2
stq_u t2,0(a1)
bcopy_done:
RET
bcopy_ov_short:
ldq_u t2,0(a0)
br zero,bcopy_da_finish
END(bcopy)
/*
* kcopy(const void *src, void *dst, size_t len);
*
@ -1337,6 +1106,10 @@ NESTED(kcopy, 3, 32, ra, IM_RA|IM_S0|IM_S1, 0)
stq ra, (32-8)(sp) /* save ra */
stq s0, (32-16)(sp) /* save s0 */
stq s1, (32-24)(sp) /* save s1 */
/* Swap a0, a1, for call to memcpy(). */
mov a1, v0
mov a0, a1
mov v0, a0
/* Note: GET_CURPROC clobbers v0, t0, t8...t11. */
GET_CURPROC
ldq s1, 0(v0) /* s1 = curproc */
@ -1346,7 +1119,7 @@ NESTED(kcopy, 3, 32, ra, IM_RA|IM_S0|IM_S1, 0)
ldq s0, U_PCB_ONFAULT(at_reg) /* save old handler. */
stq v0, U_PCB_ONFAULT(at_reg)
.set at
CALL(bcopy) /* do the copy. */
CALL(memcpy) /* do the copy. */
.set noat
ldq at_reg, P_ADDR(s1) /* restore the old handler. */
stq s0, U_PCB_ONFAULT(at_reg)
@ -1381,6 +1154,10 @@ NESTED(copyin, 3, 16, ra, IM_RA|IM_S0, 0)
ldiq t0, VM_MAX_ADDRESS /* make sure that src addr */
cmpult a0, t0, t1 /* is in user space. */
beq t1, copyerr /* if it's not, error out. */
/* Swap a0, a1, for call to memcpy(). */
mov a1, v0
mov a0, a1
mov v0, a0
/* Note: GET_CURPROC clobbers v0, t0, t8...t11. */
GET_CURPROC
ldq s0, 0(v0) /* s0 = curproc */
@ -1389,7 +1166,7 @@ NESTED(copyin, 3, 16, ra, IM_RA|IM_S0, 0)
ldq at_reg, P_ADDR(s0)
stq v0, U_PCB_ONFAULT(at_reg)
.set at
CALL(bcopy) /* do the copy. */
CALL(memcpy) /* do the copy. */
.set noat
ldq at_reg, P_ADDR(s0) /* kill the fault handler. */
stq zero, U_PCB_ONFAULT(at_reg)
@ -1409,6 +1186,10 @@ NESTED(copyout, 3, 16, ra, IM_RA|IM_S0, 0)
ldiq t0, VM_MAX_ADDRESS /* make sure that dest addr */
cmpult a1, t0, t1 /* is in user space. */
beq t1, copyerr /* if it's not, error out. */
/* Swap a0, a1, for call to memcpy(). */
mov a1, v0
mov a0, a1
mov v0, a0
/* Note: GET_CURPROC clobbers v0, t0, t8...t11. */
GET_CURPROC
ldq s0, 0(v0) /* s0 = curproc */
@ -1417,7 +1198,7 @@ NESTED(copyout, 3, 16, ra, IM_RA|IM_S0, 0)
ldq at_reg, P_ADDR(s0)
stq v0, U_PCB_ONFAULT(at_reg)
.set at
CALL(bcopy) /* do the copy. */
CALL(memcpy) /* do the copy. */
.set noat
ldq at_reg, P_ADDR(s0) /* kill the fault handler. */
stq zero, U_PCB_ONFAULT(at_reg)