* fixed small bug in move

This commit is contained in:
Jonas Maebe 2001-03-03 13:53:36 +00:00
parent af38291233
commit 33bd4a1769

View File

@ -24,7 +24,7 @@
{$define FPC_SYSTEM_HAS_MOVE}
procedure Move(var sou{}rce;var dest;count:longint);assembler;
procedure Move(var source;var dest;count:longint);assembler;
asm
{ count <= 0 ? }
cmpwi cr0,r5,0
@ -32,19 +32,19 @@ asm
sub r30,r4,r3
{ carry := boolean(dest-source < count) = boolean(overlap) }
subc r30,r30,r5
{ count < 11 ? (to decide whether we will move dwords or bytes }
cmpwi cr1,r5,11
{ if overlap, then r30 := -1 else r30 := 0 }
subfe r30,r30,r30
{ count < 39 ? (32 + max. alignment (7) }
cmpwi cr7,r5,39
{ if count <= 0, stop }
ble cr0,LMoveDone
{ if overlap, then r29 := count else r29 := 0 }
and r29,r5,r30
{ if overlap, then point source and dest to the end }
@ -85,12 +85,17 @@ LMove4ByteAlignLoop:
{ if 11 <= count < 39, copy using dwords }
blt cr7,LMoveDWords
{ multiply the update count with 4 }
slwi r30,r30,2
beq cr0,L8BytesAligned
{ count >= 39 -> align to 8 byte boundary and then use the FPU }
{ since we're already at 4 byte alignment, use dword store }
lwzux r29,r3,r30
stwux r29,r4,r30
lwz r29,0(r3)
add r3,r3,r30,
stw r29,0(r4)
add r4,r4,r30,
L8BytesAligned:
{ count div 32 ( >= 1, since count was >=39 }
srwi r29,r5,5
@ -99,13 +104,13 @@ L8BytesAligned:
{ to decide if we will do some dword stores afterwards or not }
cmpwi cr1,r5,11
mtctr r29
{ r29 := count div 4, will be moved to ctr when copying dwords }
srwi r29,r5,2
{ adjust the update count: it will now be 8 or -8 depending on overlap }
slwi r30,r30,3
slwi r30,r30,1
{ adjust source and dest pointers: because of the above loop, dest is now }
{ aligned to 8 bytes. So if we substract r30 we will still have an 8 bytes }
{ aligned address) }
@ -127,8 +132,8 @@ LMove32ByteLoop:
beq cr0,LMoveDone
{ make r30 again -1 or 1, but first adjust source/dest pointers }
add r3,r3,r30
add r4,r4,r30
add r3,r3,r30
add r4,r4,r30
srawi r30,r30,3
sub r3,r3,r30
sub r4,r4,r30
@ -143,8 +148,8 @@ LMoveDWords:
andi. r5,r5,3
{ r30 * 4 }
slwi r30,r30,2
sub r3,r3,r30
sub r4,r4,r30
sub r3,r3,r30
sub r4,r4,r30
LMoveDWordsLoop:
lwzux r29,r3,r30
@ -153,8 +158,8 @@ LMoveDWordsLoop:
beq cr0,LMoveDone
{ make r30 again -1 or 1 }
add r3,r3,r30
add r4,r4,r30
add r3,r3,r30
add r4,r4,r30
srawi r30,r30,2
sub r3,r3,r30
sub r4,r4,r30
@ -433,7 +438,7 @@ asm
subme r3,r3,r3 { if r3 >= r4 then r3' := 0 else r3' := -1 }
and r3,r29,r3 { if r3 >= r4 then r3' := 0 else r3' := r3-r30 }
add r3,r3,r30 { if r3 >= r4 then r3' := r30 else r3' := r3 }
cmpli r3,0
{ put length in ctr }
mtctr r3
@ -448,7 +453,10 @@ end ['r3','r4','r5','r29','r30','cr0','ctr'];
{
$Log$
Revision 1.3 2001-03-02 13:24:10 jonas
Revision 1.4 2001-03-03 13:53:36 jonas
* fixed small bug in move
Revision 1.3 2001/03/02 13:24:10 jonas
+ new, complete implementation of move procedure (including support for
overlapping regions)