xref: /csrg-svn/lib/libc/mips/string/bcopy.s (revision 61146)
152714Sbostic/*-
2*61146Sbostic * Copyright (c) 1991, 1993
3*61146Sbostic *	The Regents of the University of California.  All rights reserved.
452714Sbostic *
552714Sbostic * This code is derived from software contributed to Berkeley by
652714Sbostic * Ralph Campbell.
752714Sbostic *
852714Sbostic * %sccs.include.redist.c%
952714Sbostic */
1052714Sbostic
1155708Sralph#include <machine/machAsmDefs.h>
1252737Sbostic
1352714Sbostic#if defined(LIBC_SCCS) && !defined(lint)
14*61146Sbostic	ASMSTR("@(#)bcopy.s	8.1 (Berkeley) 06/04/93")
1552714Sbostic#endif /* LIBC_SCCS and not lint */
1652714Sbostic
1752714Sbostic/* bcopy(s1, s2, n) */
1852714Sbostic
1958124Sralph#ifdef MIPSEL
2054155Sralph#	define	LWHI	lwr
2154155Sralph#	define	LWLO	lwl
2254155Sralph#	define	SWHI	swr
2354155Sralph#	define	SWLO	swl
2454155Sralph#endif
2558124Sralph#ifdef MIPSEB
2654155Sralph#	define	LWHI	lwl
2754155Sralph#	define	LWLO	lwr
2854155Sralph#	define	SWHI	swl
2954155Sralph#	define	SWLO	swr
3054155Sralph#endif
3154155Sralph
3252714SbosticLEAF(bcopy)
3352714Sbostic	.set	noreorder
3452714Sbostic	addu	t0, a0, a2		# t0 = end of s1 region
3552714Sbostic	sltu	t1, a1, t0
3652714Sbostic	sltu	t2, a0, a1
3752714Sbostic	and	t1, t1, t2		# t1 = true if from < to < (from+len)
3852714Sbostic	beq	t1, zero, forward	# non overlapping, do forward copy
3952714Sbostic	slt	t2, a2, 12		# check for small copy
4052714Sbostic
4152714Sbostic	ble	a2, zero, 2f
4252714Sbostic	addu	t1, a1, a2		# t1 = end of to region
4352714Sbostic1:
4452714Sbostic	lb	v0, -1(t0)		# copy bytes backwards,
4557857Sralph	subu	t0, t0, 1		#   doesnt happen often so do slow way
4652714Sbostic	subu	t1, t1, 1
4752714Sbostic	bne	t0, a0, 1b
4852714Sbostic	sb	v0, 0(t1)
4952714Sbostic2:
5052714Sbostic	j	ra
5152714Sbostic	nop
5252714Sbosticforward:
5352714Sbostic	bne	t2, zero, smallcpy	# do a small bcopy
5452714Sbostic	xor	v0, a0, a1		# compare low two bits of addresses
5552714Sbostic	and	v0, v0, 3
5652714Sbostic	subu	a3, zero, a1		# compute # bytes to word align address
5752714Sbostic	beq	v0, zero, aligned	# addresses can be word aligned
5852714Sbostic	and	a3, a3, 3
5952714Sbostic
6052714Sbostic	beq	a3, zero, 1f
6152714Sbostic	subu	a2, a2, a3		# subtract from remaining count
6254155Sralph	LWHI	v0, 0(a0)		# get next 4 bytes (unaligned)
6354155Sralph	LWLO	v0, 3(a0)
6452714Sbostic	addu	a0, a0, a3
6554155Sralph	SWHI	v0, 0(a1)		# store 1, 2, or 3 bytes to align a1
6652714Sbostic	addu	a1, a1, a3
6752714Sbostic1:
6852714Sbostic	and	v0, a2, 3		# compute number of words left
6952714Sbostic	subu	a3, a2, v0
7052714Sbostic	move	a2, v0
7152714Sbostic	addu	a3, a3, a0		# compute ending address
7252714Sbostic2:
7354155Sralph	LWHI	v0, 0(a0)		# copy words a0 unaligned, a1 aligned
7454155Sralph	LWLO	v0, 3(a0)
7552714Sbostic	addu	a0, a0, 4
7652714Sbostic	addu	a1, a1, 4
7752714Sbostic	bne	a0, a3, 2b
7852714Sbostic	sw	v0, -4(a1)
7952714Sbostic	b	smallcpy
8052714Sbostic	nop
8152714Sbosticaligned:
8252714Sbostic	beq	a3, zero, 1f
8352714Sbostic	subu	a2, a2, a3		# subtract from remaining count
8454155Sralph	LWHI	v0, 0(a0)		# copy 1, 2, or 3 bytes to align
8552714Sbostic	addu	a0, a0, a3
8654155Sralph	SWHI	v0, 0(a1)
8752714Sbostic	addu	a1, a1, a3
8852714Sbostic1:
8952714Sbostic	and	v0, a2, 3		# compute number of whole words left
9052714Sbostic	subu	a3, a2, v0
9152714Sbostic	move	a2, v0
9252714Sbostic	addu	a3, a3, a0		# compute ending address
9352714Sbostic2:
9452714Sbostic	lw	v0, 0(a0)		# copy words
9552714Sbostic	addu	a0, a0, 4
9652714Sbostic	addu	a1, a1, 4
9752714Sbostic	bne	a0, a3, 2b
9852714Sbostic	sw	v0, -4(a1)
9952714Sbosticsmallcpy:
10052714Sbostic	ble	a2, zero, 2f
10152714Sbostic	addu	a3, a2, a0		# compute ending address
10252714Sbostic1:
10352714Sbostic	lbu	v0, 0(a0)		# copy bytes
10452714Sbostic	addu	a0, a0, 1
10552714Sbostic	addu	a1, a1, 1
10652714Sbostic	bne	a0, a3, 1b
10752714Sbostic	sb	v0, -1(a1)
10852714Sbostic2:
10952714Sbostic	j	ra
11052714Sbostic	nop
11152714Sbostic	.set	reorder
11252714SbosticEND(bcopy)
113