! MoveAndFillWords.S
!
! Russell R Atkinson, September 24, 1992
!
!
 .seg "text"
 .proc 12
 .global �sics𡤏illWords
�sics𡤏illWords:
! 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 �sics←MoveWords
�sics←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