mirror of
				https://gitlab.com/freepascal.org/fpc/source.git
				synced 2025-11-04 08:19:36 +01: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)
 | 
						|
 | 
						|
} |