[net.sources] bcopy, bcmp, bzero for 4.1BSD

chris@eneevax.UUCP (Chris Torek) (08/18/84)

I've received (justified) complaints for not explaining bcmp(),
bcopy(), and bzero() in my mdbm source posting.  This is one of those
4.2 dependencies I warned about.  Anyway, here are implementations of
bcopy, bcmp, and bzero in Vax assembly and in C.  WARNING: I haven't
tested the Vax assembly version of bcmp (nor any of the C routines but
who needs to test those?).  Also, the assembly routines won't work
under VMS, which (I believe) needs r2-r11 saved; you'd have to change
the entry masks.

If you're running 4.2 you should already have these in your C library,
so in that case, ignore this posting.  (Otherwise, why not rewrite
these for your particular machine and *install* it in your C library?)

--Chris Torek, U of MD CS/EE, seismo!umcp-cs!chris, chris@maryland.ARPA,
  chris@umcp-cs.CSNet  (I don't have my regular .signature installed on
  this machine)
-------------------------------------------
: Run this shell script with "sh" not "csh"
PATH=:/bin:/usr/bin:/usr/ucb
export PATH
/bin/echo 'Extracting bcmp.c'
sed 's/^X//' <<'//go.sysin dd *' >bcmp.c
/*
 * bcmp
 *
 * compare count bytes at s1 and s2; return 0 iff equal
 *
 * N.B.: Beware large counts (>32767) on machines with 16 bit `int's.
 * (This routine should really be rewritten for those.)
 */
bcmp (s1, s2, count)
register char *s1, *s2;
register int count;
{
    while (--count >= 0)
	if (*s1++ != *s2++)
	    return 1;		/* or ``return *--s1 - *--s2;'' */
    return 0;
}
//go.sysin dd *
/bin/chmod 644 bcmp.c
/bin/echo -n '	'; /bin/ls -ld bcmp.c
/bin/echo 'Extracting bcmp.s'
sed 's/^X//' <<'//go.sysin dd *' >bcmp.s
# bcmp (s1, s2, count) char *s1, *s2; int count;
#
# Compare "count" bytes at "s1" with those at "s2"; return 0 iff equal

	.align	2
	.globl	_bcopy
_bcopy:
	.word	0
	movl	4(ap),r1		# r1 = s1
	movl	8(ap),r3		# r3 = s2
	brb	2f
1:
	subl2	r0,12(ap)		# count-=65535 (bytes compared)
	cmpc3	r0,(r1),(r3)		# r1, r3 magically point to next 65K
	bneq	3f
2:
	movzwl	$65535,r0
	cmpl	12(ap),r0		# <= 65535 bytes to compare?
	jgtr	1b			# brif not, do 65535 and try again
	cmpc3	12(ap),(r1),(r3)	# compare up to 65535 bytes
3:
	ret
//go.sysin dd *
/bin/chmod 644 bcmp.s
/bin/echo -n '	'; /bin/ls -ld bcmp.s
/bin/echo 'Extracting bcopy.c'
sed 's/^X//' <<'//go.sysin dd *' >bcopy.c
/*
 * bcopy - copy count bytes from "from" to "to" - not guaranteed to work
 * if "from" and "to" overlap
 *
 * N.B.: Beware large counts (>32767) on machines with 16 bit `int's.
 * (This routine should really be rewritten for those.)
 */
bcopy (from, to, count)
register char *from, *to;
register int count;
{
    while (--count >= 0)
	*to++ = *from++;
}
//go.sysin dd *
/bin/chmod 644 bcopy.c
/bin/echo -n '	'; /bin/ls -ld bcopy.c
/bin/echo 'Extracting bcopy.s'
sed 's/^X//' <<'//go.sysin dd *' >bcopy.s
# bcopy (from, to, count) char *from, *to; int count;
#
# Copy "count" bytes from "from" to "to"; not guaranteed to
# work if "from" and "to" overlap.

	.align	2
	.globl	_bcopy
_bcopy:
	.word	0
	movl	4(ap),r1		# r1 = from
	movl	8(ap),r3		# r3 = to
	brb	2f
1:
	subl2	r0,12(ap)		# count-=65535 (bytes moved this time)
	movc3	r0,(r1),(r3)		# r1, r3 magically point to next 65K
2:
	movzwl	$65535,r0
	cmpl	12(ap),r0		# <= 65535 bytes to move?
	jgtr	1b			# brif not, move 65535 and try again
	movc3	12(ap),(r1),(r3)	# move up to 65535 bytes
	ret
//go.sysin dd *
/bin/chmod 644 bcopy.s
/bin/echo -n '	'; /bin/ls -ld bcopy.s
/bin/echo 'Extracting bzero.c'
sed 's/^X//' <<'//go.sysin dd *' >bzero.c
/*
 * bzero - zero count bytes at address addr
 *
 * N.B.: Beware large counts (>32767) on machines with 16 bit `int's.
 * (This routine should really be rewritten for those.)
 */
bzero (addr, count)
register char *addr;
register int count;
{
    while (--count >= 0)
	*addr++ = 0;
}
//go.sysin dd *
/bin/chmod 644 bzero.c
/bin/echo -n '	'; /bin/ls -ld bzero.c
/bin/echo 'Extracting bzero.s'
sed 's/^X//' <<'//go.sysin dd *' >bzero.s
# bzero (addr, count) char *addr; int count;
#
# Zero "count" bytes at address "addr"

	.align	2
	.globl	_bzero
_bzero:
	.word	0
	movl	4(ap),r3		# r3 = addr
	brb	2f
1:
	subl2	r0,8(ap)		# count-=65535 (bytes zeroed this time)
	movc5	$0,(sp),$0,r0,(r3)	# r3 magically points to next 65K
2:
	movzwl	$65535,r0
	cmpl	8(ap),r0		# <= 65535 bytes to zero?
	jgtr	1b			# brif not, zero 65535 and try again
	movc5	$0,(sp),$0,8(ap),(r3)	# zero up to 65535 bytes
	ret
//go.sysin dd *
/bin/chmod 644 bzero.s
/bin/echo -n '	'; /bin/ls -ld bzero.s

hansen@pegasus.UUCP (Tony L. Hansen) (08/25/84)

<					(Otherwise, why not rewrite
< these for your particular machine and *install* it in your C library?)
< --Chris Torek, U of MD CS/EE, seismo!umcp-cs!chris, chris@maryland.ARPA,

Why not instead install the standard System V routines memcpy, memcmp and
memset? There was even a public domain version of those routines posted not
too many months ago. (Beware the switched operands in bcopy.)

#define bcmp(s1, s2, count)	memcmp((s1), (s2), (n))
#define bcopy(from, to, count)	memcpy((to), (from), (count))
#define bzero(addr, count)	memset((addr), 0, (count))

					Tony Hansen
					pegasus!hansen