1*41809Sbostic/*- 2*41809Sbostic * Copyright (c) 1990 The Regents of the University of California. 3*41809Sbostic * All rights reserved. 4*41809Sbostic * 5*41809Sbostic * This code is derived from software contributed to Berkeley by 6*41809Sbostic * the Systems Programming Group of the University of Utah Computer 7*41809Sbostic * Science Department. 8*41809Sbostic * 9*41809Sbostic * %sccs.include.redist.c% 10*41809Sbostic */ 11*41809Sbostic 12*41809Sbostic#if defined(LIBC_SCCS) && !defined(lint) 13*41809Sbostic .asciz "@(#)bcopy.s 5.1 (Berkeley) 05/12/90" 14*41809Sbostic#endif /* LIBC_SCCS and not lint */ 15*41809Sbostic 16*41809Sbostic#include "DEFS.h" 17*41809Sbostic 18*41809Sbostic/* 19*41809Sbostic * This is probably not the best we can do, but it is still 2-10 times 20*41809Sbostic * faster than the C version in the portable gen directory. 21*41809Sbostic * 22*41809Sbostic * Things that might help: 23*41809Sbostic * - unroll the longword copy loop (might not be good for a 68020) 24*41809Sbostic * - longword align when possible (only on the 68020) 25*41809Sbostic * - use nested DBcc instructions or use one and limit size to 64K 26*41809Sbostic */ 27*41809SbosticENTRY(bcopy) 28*41809Sbostic movl sp@(12),d1 /* check count */ 29*41809Sbostic jle bcdone /* <= 0, don't do anything */ 30*41809Sbostic movl sp@(4),a0 /* src address */ 31*41809Sbostic movl sp@(8),a1 /* dest address */ 32*41809Sbostic cmpl a1,a0 /* src after dest? */ 33*41809Sbostic jlt bcback /* yes, must copy backwards */ 34*41809Sbostic movl a0,d0 35*41809Sbostic btst #0,d0 /* src address odd? */ 36*41809Sbostic jeq bcfeven /* no, skip alignment */ 37*41809Sbostic movb a0@+,a1@+ /* yes, copy a byte */ 38*41809Sbostic subql #1,d1 /* adjust count */ 39*41809Sbostic jeq bcdone /* count 0, all done */ 40*41809Sbosticbcfeven: 41*41809Sbostic movl a1,d0 42*41809Sbostic btst #0,d0 /* dest address odd? */ 43*41809Sbostic jne bcfbloop /* yes, no hope for alignment, copy bytes */ 44*41809Sbostic movl d1,d0 /* no, both even */ 45*41809Sbostic lsrl #2,d0 /* convert count to longword count */ 46*41809Sbostic jeq bcfbloop /* count 0, skip longword loop */ 47*41809Sbosticbcflloop: 48*41809Sbostic movl a0@+,a1@+ /* copy a longword */ 49*41809Sbostic subql #1,d0 /* adjust count */ 50*41809Sbostic jne bcflloop /* still more, keep copying */ 51*41809Sbostic andl #3,d1 /* what remains */ 52*41809Sbostic jeq bcdone /* nothing, all done */ 53*41809Sbosticbcfbloop: 54*41809Sbostic movb a0@+,a1@+ /* copy a byte */ 55*41809Sbostic subql #1,d1 /* adjust count */ 56*41809Sbostic jne bcfbloop /* still more, keep going */ 57*41809Sbosticbcdone: 58*41809Sbostic rts 59*41809Sbosticbcback: 60*41809Sbostic addl d1,a0 /* src pointer to end */ 61*41809Sbostic addl d1,a1 /* dest pointer to end */ 62*41809Sbostic movl a0,d0 63*41809Sbostic btst #0,d0 /* src address odd? */ 64*41809Sbostic jeq bcbeven /* no, skip alignment */ 65*41809Sbostic movb a0@-,a1@- /* yes, copy a byte */ 66*41809Sbostic subql #1,d1 /* adjust count */ 67*41809Sbostic jeq bcdone /* count 0, all done */ 68*41809Sbosticbcbeven: 69*41809Sbostic movl a1,d0 70*41809Sbostic btst #0,d0 /* dest address odd? */ 71*41809Sbostic jne bcbbloop /* yes, no hope for alignment, copy bytes */ 72*41809Sbostic movl d1,d0 /* no, both even */ 73*41809Sbostic lsrl #2,d0 /* convert count to longword count */ 74*41809Sbostic jeq bcbbloop /* count 0, skip longword loop */ 75*41809Sbosticbcblloop: 76*41809Sbostic movl a0@-,a1@- /* copy a longword */ 77*41809Sbostic subql #1,d0 /* adjust count */ 78*41809Sbostic jne bcblloop /* still more, keep copying */ 79*41809Sbostic andl #3,d1 /* what remains */ 80*41809Sbostic jeq bcdone /* nothing, all done */ 81*41809Sbosticbcbbloop: 82*41809Sbostic movb a0@-,a1@- /* copy a byte */ 83*41809Sbostic subql #1,d1 /* adjust count */ 84*41809Sbostic jne bcbbloop /* still more, keep going */ 85*41809Sbostic rts 86*41809Sbostic 87