123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189 |
- {
- $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 ([email protected])
- 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)
- }
|