141809Sbostic/*- 2*61123Sbostic * Copyright (c) 1990, 1993 3*61123Sbostic * The Regents of the University of California. All rights reserved. 441809Sbostic * 541809Sbostic * This code is derived from software contributed to Berkeley by 641809Sbostic * the Systems Programming Group of the University of Utah Computer 741809Sbostic * Science Department. 841809Sbostic * 941809Sbostic * %sccs.include.redist.c% 1041809Sbostic */ 1141809Sbostic 1241809Sbostic#if defined(LIBC_SCCS) && !defined(lint) 13*61123Sbostic .asciz "@(#)bcopy.s 8.1 (Berkeley) 06/04/93" 1441809Sbostic#endif /* LIBC_SCCS and not lint */ 1541809Sbostic 1641809Sbostic#include "DEFS.h" 1741809Sbostic 1841809Sbostic/* 1941809Sbostic * This is probably not the best we can do, but it is still 2-10 times 2041809Sbostic * faster than the C version in the portable gen directory. 2141809Sbostic * 2241809Sbostic * Things that might help: 2341809Sbostic * - unroll the longword copy loop (might not be good for a 68020) 2441809Sbostic * - longword align when possible (only on the 68020) 2541809Sbostic * - use nested DBcc instructions or use one and limit size to 64K 2641809Sbostic */ 2741809SbosticENTRY(bcopy) 2841809Sbostic movl sp@(12),d1 /* check count */ 2941809Sbostic jle bcdone /* <= 0, don't do anything */ 3041809Sbostic movl sp@(4),a0 /* src address */ 3141809Sbostic movl sp@(8),a1 /* dest address */ 3241809Sbostic cmpl a1,a0 /* src after dest? */ 3341809Sbostic jlt bcback /* yes, must copy backwards */ 3441809Sbostic movl a0,d0 3541809Sbostic btst #0,d0 /* src address odd? */ 3641809Sbostic jeq bcfeven /* no, skip alignment */ 3741809Sbostic movb a0@+,a1@+ /* yes, copy a byte */ 3841809Sbostic subql #1,d1 /* adjust count */ 3941809Sbostic jeq bcdone /* count 0, all done */ 4041809Sbosticbcfeven: 4141809Sbostic movl a1,d0 4241809Sbostic btst #0,d0 /* dest address odd? */ 4341809Sbostic jne bcfbloop /* yes, no hope for alignment, copy bytes */ 4441809Sbostic movl d1,d0 /* no, both even */ 4541809Sbostic lsrl #2,d0 /* convert count to longword count */ 4641809Sbostic jeq bcfbloop /* count 0, skip longword loop */ 4741809Sbosticbcflloop: 4841809Sbostic movl a0@+,a1@+ /* copy a longword */ 4941809Sbostic subql #1,d0 /* adjust count */ 5041809Sbostic jne bcflloop /* still more, keep copying */ 5141809Sbostic andl #3,d1 /* what remains */ 5241809Sbostic jeq bcdone /* nothing, all done */ 5341809Sbosticbcfbloop: 5441809Sbostic movb a0@+,a1@+ /* copy a byte */ 5541809Sbostic subql #1,d1 /* adjust count */ 5641809Sbostic jne bcfbloop /* still more, keep going */ 5741809Sbosticbcdone: 5841809Sbostic rts 5941809Sbosticbcback: 6041809Sbostic addl d1,a0 /* src pointer to end */ 6141809Sbostic addl d1,a1 /* dest pointer to end */ 6241809Sbostic movl a0,d0 6341809Sbostic btst #0,d0 /* src address odd? */ 6441809Sbostic jeq bcbeven /* no, skip alignment */ 6541809Sbostic movb a0@-,a1@- /* yes, copy a byte */ 6641809Sbostic subql #1,d1 /* adjust count */ 6741809Sbostic jeq bcdone /* count 0, all done */ 6841809Sbosticbcbeven: 6941809Sbostic movl a1,d0 7041809Sbostic btst #0,d0 /* dest address odd? */ 7141809Sbostic jne bcbbloop /* yes, no hope for alignment, copy bytes */ 7241809Sbostic movl d1,d0 /* no, both even */ 7341809Sbostic lsrl #2,d0 /* convert count to longword count */ 7441809Sbostic jeq bcbbloop /* count 0, skip longword loop */ 7541809Sbosticbcblloop: 7641809Sbostic movl a0@-,a1@- /* copy a longword */ 7741809Sbostic subql #1,d0 /* adjust count */ 7841809Sbostic jne bcblloop /* still more, keep copying */ 7941809Sbostic andl #3,d1 /* what remains */ 8041809Sbostic jeq bcdone /* nothing, all done */ 8141809Sbosticbcbbloop: 8241809Sbostic movb a0@-,a1@- /* copy a byte */ 8341809Sbostic subql #1,d1 /* adjust count */ 8441809Sbostic jne bcbbloop /* still more, keep going */ 8541809Sbostic rts 8641809Sbostic 87