mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-04-29 06:23:43 +02:00
189 lines
4.7 KiB
PHP
189 lines
4.7 KiB
PHP
{
|
|
$Id$
|
|
This file is part of the Free Pascal run time library.
|
|
Copyright (c) 1999 by the Free Pascal development team.
|
|
|
|
Portions Copyright (c) 2000 by Casey Duncan (casey.duncan@state.co.us)
|
|
|
|
Processor dependent implementation for the system unit for
|
|
PowerPC
|
|
|
|
See the file COPYING.FPC, included in this distribution,
|
|
for details about the copyright.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
|
|
**********************************************************************}
|
|
|
|
|
|
{****************************************************************************
|
|
Move / Fill
|
|
****************************************************************************}
|
|
|
|
{$define FPC_SYSTEM_HAS_MOVE}
|
|
|
|
procedure Move(var source;var dest;count:longint);
|
|
begin
|
|
{ register usage:
|
|
r3 source
|
|
r4 dest
|
|
r5 count
|
|
r13 ptr to end of source
|
|
r14 ptr to end of dest
|
|
r15 counter 1
|
|
r16 counter 2
|
|
r17 addr increment
|
|
r18 ptr to current source block
|
|
r19 ptr to current dest block
|
|
r20-24 buffer
|
|
f1-4 buffer
|
|
ctr Loop counter
|
|
notes:
|
|
Move uses FPRs for increased bandwidth
|
|
}
|
|
asm
|
|
{ do some param checking, initialization }
|
|
cmplwi cr2,r3,0
|
|
cmplwi cr3,r4,0
|
|
cmplw cr4,r3,r4
|
|
add r13,r3,r5
|
|
add r14,r4,r5
|
|
bt cr2,.MoveEnd //end if source=nil
|
|
bt cr3,.MoveEnd //end if dest=nil
|
|
bt cr4,.MoveEnd //end if source=dest
|
|
{ see if source and dest overlap }
|
|
cmplw cr2,r13,r4
|
|
cmplw cr3,r4,r3
|
|
srawi. r15,r5,$5 //r15 := count div 32
|
|
andi r16,r5,$1F //r16 := count mod 32
|
|
crand cr3,cr2,cr3
|
|
mtctr r15 //Load loop counter
|
|
bgt cr3,.MoveRL //dest overlaps source on right
|
|
li r17,$8 //Offset 8 bytes per doubleword copy
|
|
sub r18,r17,r3 //calculate the starting source
|
|
sub r19,r17,r4 // and dest ptrs
|
|
beq .MoveByByte //If count<32 skip 32 byte block copy
|
|
srawi. r15,r16,$2 //r15 := r16 div 4
|
|
andi r16,r15,$3 //r16 := r15 mod 4
|
|
cmpwi cr2,r16,0 //r16 = 0 ?
|
|
crand cr3,cr2,cr0 //r15 = 0 AND r16 = 0 ?
|
|
.MoveBlockLoop: //32 Byte block copy (fully optimized)
|
|
lfdux f1,r18,r17
|
|
lfdux f2,r18,r17
|
|
lfdux f3,r18,r17
|
|
lfdux f4,r18,r17
|
|
stfdux f1,r19,r17
|
|
stfdux f2,r19,r17
|
|
stfdux f3,r19,r17
|
|
stfdux f4,r19,r17
|
|
bdnz .MoveBlockLoop
|
|
|
|
bt cr3,MoveEnd //Nothing left to do...
|
|
mtspr 1,r16 //XER := r16
|
|
beq .MoveBytes //There are fewer than 4 bytes left
|
|
mtctr r15 //load counter
|
|
andi r15,r15,$3 //r15 := r15 mod 4
|
|
srawi r17,$1 //Offset := Offset div 2
|
|
.MoveWordLoop: //4 byte copy
|
|
lwzux r20,r18,r17
|
|
stwux r20,r19,r17
|
|
bdnz .WordCopyLoop
|
|
|
|
bt cr2,MoveEnd //Nothing left to do...
|
|
.MoveBytes: //Copy remaining stragglers
|
|
lswx r20,r0,r18
|
|
stswx r20,r0,r19
|
|
.MoveEnd:
|
|
End;
|
|
End;
|
|
|
|
|
|
{$define FPC_SYSTEM_HAS_FILLCHAR}
|
|
|
|
Procedure FillChar(var x;count:longint;value:byte);
|
|
begin
|
|
asm
|
|
{ Register Usage:
|
|
r3 x
|
|
r4 count
|
|
r5 value
|
|
r13 value.value.value.value
|
|
r14 ptr to current dest char
|
|
r15 byte increment, Scratch
|
|
r16 Block count
|
|
r17 misalignment byte count
|
|
}
|
|
cmpwi cr2,r4,12
|
|
mr r14,r3
|
|
andi. r17,r3,3
|
|
sub r14,r3,r17 //32 bit align
|
|
blt cr2,.FillBytes //if count<12 then fill byte by byte
|
|
sub r16,r4,r17
|
|
andi r17,r16,3
|
|
cmpwi cr2,r17,0
|
|
srwi r16,r16,2 //r16:=count div 4
|
|
subi r16,r16,2
|
|
mtctr r16 //counter:=r16
|
|
mr r13,r5 //insert
|
|
insrwi r13,r5,8,16 // value into all four bytes
|
|
insrwi r13,r13,16,0 // of r13
|
|
li r15,4
|
|
stw r13,0(r3) //fill first few bytes
|
|
.FillWordLoop:
|
|
stwux r13,r14,r15
|
|
bdnz .FillWordLoop
|
|
beq cr2,FillEnd //No trailing bytes, so exit
|
|
add r14,r3,r4
|
|
stw r13,-4(r14) //fill last few bytes
|
|
b .FillEnd
|
|
|
|
.FillBytes:
|
|
mtctr r4 //counter:=count
|
|
li r15,1
|
|
subi r14,r3,1
|
|
.FillByteLoop:
|
|
stbux r13,r14,r15
|
|
bdnz .FillByteLoop
|
|
.FillEnd:
|
|
end [r13,r14,r15,r16,r17,ctr];
|
|
end;
|
|
|
|
|
|
{$define FPC_SYSTEM_HAS_FILLWORD}
|
|
|
|
procedure fillword(var x;count : longint;value : word);
|
|
begin
|
|
{ registers:
|
|
r3 x
|
|
r4 count
|
|
r5 value
|
|
r13 value.value
|
|
r14 ptr to dest word
|
|
r15 increment 1
|
|
r16 increment 2
|
|
r17 scratch
|
|
r18 scratch
|
|
f1 value.value.value.value
|
|
}
|
|
asm
|
|
cmpwi cr0,r3,0
|
|
andi r17,r4,$3
|
|
srwi r18,r4,1 //r18:=count div 2
|
|
mr r13,r3
|
|
li r14,4
|
|
ble .FillWordEnd //if count<=0 Then Exit
|
|
.FillWordLoop:
|
|
stwux r5,r13,r14
|
|
bdnz .FillWordLoop
|
|
.FillWordEnd:
|
|
end [r13,r14,ctr]
|
|
end;
|
|
|
|
{
|
|
$Log$
|
|
Revision 1.1 2000-07-27 07:32:12 jonas
|
|
+ initial version by Casey Duncan (not yet thoroughly debugged or complete)
|
|
|
|
} |