!  MoveAndFillWords.s
  !
  !  Russell R Atkinson, September 24, 1992
  !
  !
	.seg	"text"
	.proc	12
	.global	←Basics←FillWords
←Basics←FillWords:
	.global	Basics←FillWords
Basics←FillWords:
!  Arguments:
  ! %o0	dst	word pointer to dst base
  ! %o1	count	number of words to fill
  ! %o2	value	word to fill with
!#PROLOGUE# 0
!#PROLOGUE# 1
	mov	%o2,%o3
	tst	%o1
	ble	BFout
	 andcc	%o0,4,%g0
	be	BFeven
	 nop
	dec	1,%o1
	st	%o3,[%o0]
	inc	4,%o0
BFeven:	cmp	%o1,16
	bl	BFlt16
	 nop
BFge16:	std	%o2,[%o0+0]
	std	%o2,[%o0+8]
	std	%o2,[%o0+16]
	std	%o2,[%o0+24]
	std	%o2,[%o0+32]
	std	%o2,[%o0+40]
	std	%o2,[%o0+48]
	std	%o2,[%o0+56]
	sub	%o1,16,%o1
	cmp	%o1,16
	bge	BFge16
	 inc	64,%o0
BFlt16:	andcc	%o1,8,%g0
	be	BFlt8
	 nop
	std	%o2,[%o0+0]
	std	%o2,[%o0+8]
	std	%o2,[%o0+16]
	std	%o2,[%o0+24]
	inc	32,%o0
BFlt8:	andcc	%o1,4,%g0
	be	BFlt4
	 nop
	std	%o2,[%o0+0]
	std	%o2,[%o0+8]
	inc	16,%o0
BFlt4:	andcc	%o1,2,%g0
	be	BFlt2
	 nop	
	std	%o2,[%o0+0]
	inc	8,%o0
BFlt2:	andcc	%o1,1,%g0
	be	BFout
	 nop
	st	%o2,[%o0+0]
BFout:	retl	
	nop

	.proc	12
	.global	←Basics←MoveWords
←Basics←MoveWords:
	.global	Basics←MoveWords
Basics←MoveWords:
!  Arguments:
  ! %i0	dst	word pointer to dst base
  ! %i1	src	word pointer to src base
  ! %i2	count	number of words to copy
!#PROLOGUE# 0
!#PROLOGUE# 1
	save	%sp,-64,%sp
	tst	%i2
	ble	BCout
	 sll	%i2,2,%l2	! %l2 has # of bytes
	add	%i1,%l2,%l1	! %l1 has srcLimit
	cmp	%i0,%l1		! dst >= srcLimit allows fwd transfer
	bgeu	BCfwd
	 cmp	%i0,%i1		! dst <= src allows fwd transfer
	bleu	BCfwd
	 nop

BRrev:	! sigh, at this point we have to do the move backwards
	add	%i0,%l2,%i0	! dst := dst + bytes
	add	%i1,%l2,%i1	! src := src + bytes
	andcc	%i0,4,%g0
	be	BReven
	 nop
	dec	4,%i1		! make dst double-word aligned
	ld	[%i1],%i4
	dec	1,%i2
	dec	4,%i0
	st	%i4,[%i0]
BReven:	cmp	%i2,8
	bl	BRlt8
	 andcc	%i1,4,%g0
	bne	BRge8B
	 nop
BRge8A:	! both src & dst are double-word aligned
	dec	32,%i1
	ldd	[%i1+0],%l0
	ldd	[%i1+8],%l2
	ldd	[%i1+16],%l4
	ldd	[%i1+24],%l6
	dec	32,%i0
	std	%l0,[%i0+0]
	std	%l2,[%i0+8]
	std	%l4,[%i0+16]
	std	%l6,[%i0+24]
	cmp	%i2,16
	bge	BRge8A
	 dec	8,%i2
	b	BRlt8
	 andcc	%i2,4,%g0
BRge8B:	! dst is double-word aligned, src is not
	dec	32,%i1
	ld	[%i1+0],%l0
	ld	[%i1+4],%l1
	ld	[%i1+8],%l2
	ld	[%i1+12],%l3
	ld	[%i1+16],%l4
	ld	[%i1+20],%l5
	ld	[%i1+24],%l6
	ld	[%i1+28],%l7
	dec	32,%i0
	std	%l0,[%i0+0]
	std	%l2,[%i0+8]
	std	%l4,[%i0+16]
	std	%l6,[%i0+24]
	cmp	%i2,16
	bge	BRge8B
	 dec	8,%i2
BRlt8:	andcc	%i2,4,%g0
	be	BRlt4
	 andcc	%i2,2,%g0
	dec	16,%i1
	ld	[%i1+0],%l0
	ld	[%i1+4],%l1
	ld	[%i1+8],%l2
	ld	[%i1+12],%l3
	dec	16,%i0
	std	%l0,[%i0+0]
	std	%l2,[%i0+8]
	andcc	%i2,2,%g0
BRlt4:	be	BRlt2
	 andcc	%i2,1,%g0
	dec	8,%i1
	ld	[%i1+0],%l0
	ld	[%i1+4],%l1
	dec	8,%i0
	std	%l0,[%i0+0]
	andcc	%i2,1,%g0
BRlt2:	be	BCout
	 dec	4,%i1
	ld	[%i1+0],%l0
	dec	4,%i0
	b	BCout
	 st	%l0,[%i0+0]

BCfwd:	!	At this point the transfer can go forwards (preferred)
	andcc	%i0,7,%g0
	be	BCeven
	 cmp	%i2,8
	dec	1,%i2
	ld	[%i1],%i4
	st	%i4,[%i0]
	inc	4,%i0
	inc	4,%i1
	cmp	%i2,8
BCeven:	bl	BClt8
	 andcc	%i1,7,%g0
	bne	BCge8B
	 nop
BCge8A:	! both src & dst are double-word aligned
	ldd	[%i1+0],%l0
	ldd	[%i1+8],%l2
	ldd	[%i1+16],%l4
	ldd	[%i1+24],%l6
	inc	32,%i1
	std	%l0,[%i0+0]
	std	%l2,[%i0+8]
	std	%l4,[%i0+16]
	std	%l6,[%i0+24]
	inc	32,%i0
	cmp	%i2,16
	bge	BCge8A
	 dec	8,%i2
	b	BClt8
	 nop
BCge8B:	! dst is double-word aligned, src is not
	ld	[%i1+0],%l0
	ld	[%i1+4],%l1
	ld	[%i1+8],%l2
	ld	[%i1+12],%l3
	ld	[%i1+16],%l4
	ld	[%i1+20],%l5
	ld	[%i1+24],%l6
	ld	[%i1+28],%l7
	inc	32,%i1
	std	%l0,[%i0+0]
	std	%l2,[%i0+8]
	std	%l4,[%i0+16]
	std	%l6,[%i0+24]
	inc	32,%i0
	cmp	%i2,16
	bge	BCge8B
	 dec	8,%i2
BClt8:	andcc	%i2,4,%g0
	be	BClt4
	 andcc	%i2,2,%g0
	ld	[%i1+0],%l0
	ld	[%i1+4],%l1
	ld	[%i1+8],%l2
	ld	[%i1+12],%l3
	inc	16,%i1
	std	%l0,[%i0+0]
	std	%l2,[%i0+8]
	inc	16,%i0
	andcc	%i2,2,%g0
BClt4:	be	BClt2
	 andcc	%i2,1,%g0
	ld	[%i1+0],%l0
	ld	[%i1+4],%l1
	inc	8,%i1
	std	%l0,[%i0+0]
	inc	8,%i0
	andcc	%i2,1,%g0
BClt2:	be	BCout
	 nop
	ld	[%i1+0],%l0
	st	%l0,[%i0+0]
BCout:	ret	
	 restore