powerpc.inc 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189
  1. {
  2. $Id$
  3. This file is part of the Free Pascal run time library.
  4. Copyright (c) 1999 by the Free Pascal development team.
  5. Portions Copyright (c) 2000 by Casey Duncan ([email protected])
  6. Processor dependent implementation for the system unit for
  7. PowerPC
  8. See the file COPYING.FPC, included in this distribution,
  9. for details about the copyright.
  10. This program is distributed in the hope that it will be useful,
  11. but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  13. **********************************************************************}
  14. {****************************************************************************
  15. Move / Fill
  16. ****************************************************************************}
  17. {$define FPC_SYSTEM_HAS_MOVE}
  18. procedure Move(var source;var dest;count:longint);
  19. begin
  20. { register usage:
  21. r3 source
  22. r4 dest
  23. r5 count
  24. r13 ptr to end of source
  25. r14 ptr to end of dest
  26. r15 counter 1
  27. r16 counter 2
  28. r17 addr increment
  29. r18 ptr to current source block
  30. r19 ptr to current dest block
  31. r20-24 buffer
  32. f1-4 buffer
  33. ctr Loop counter
  34. notes:
  35. Move uses FPRs for increased bandwidth
  36. }
  37. asm
  38. { do some param checking, initialization }
  39. cmplwi cr2,r3,0
  40. cmplwi cr3,r4,0
  41. cmplw cr4,r3,r4
  42. add r13,r3,r5
  43. add r14,r4,r5
  44. bt cr2,.MoveEnd //end if source=nil
  45. bt cr3,.MoveEnd //end if dest=nil
  46. bt cr4,.MoveEnd //end if source=dest
  47. { see if source and dest overlap }
  48. cmplw cr2,r13,r4
  49. cmplw cr3,r4,r3
  50. srawi. r15,r5,$5 //r15 := count div 32
  51. andi r16,r5,$1F //r16 := count mod 32
  52. crand cr3,cr2,cr3
  53. mtctr r15 //Load loop counter
  54. bgt cr3,.MoveRL //dest overlaps source on right
  55. li r17,$8 //Offset 8 bytes per doubleword copy
  56. sub r18,r17,r3 //calculate the starting source
  57. sub r19,r17,r4 // and dest ptrs
  58. beq .MoveByByte //If count<32 skip 32 byte block copy
  59. srawi. r15,r16,$2 //r15 := r16 div 4
  60. andi r16,r15,$3 //r16 := r15 mod 4
  61. cmpwi cr2,r16,0 //r16 = 0 ?
  62. crand cr3,cr2,cr0 //r15 = 0 AND r16 = 0 ?
  63. .MoveBlockLoop: //32 Byte block copy (fully optimized)
  64. lfdux f1,r18,r17
  65. lfdux f2,r18,r17
  66. lfdux f3,r18,r17
  67. lfdux f4,r18,r17
  68. stfdux f1,r19,r17
  69. stfdux f2,r19,r17
  70. stfdux f3,r19,r17
  71. stfdux f4,r19,r17
  72. bdnz .MoveBlockLoop
  73. bt cr3,MoveEnd //Nothing left to do...
  74. mtspr 1,r16 //XER := r16
  75. beq .MoveBytes //There are fewer than 4 bytes left
  76. mtctr r15 //load counter
  77. andi r15,r15,$3 //r15 := r15 mod 4
  78. srawi r17,$1 //Offset := Offset div 2
  79. .MoveWordLoop: //4 byte copy
  80. lwzux r20,r18,r17
  81. stwux r20,r19,r17
  82. bdnz .WordCopyLoop
  83. bt cr2,MoveEnd //Nothing left to do...
  84. .MoveBytes: //Copy remaining stragglers
  85. lswx r20,r0,r18
  86. stswx r20,r0,r19
  87. .MoveEnd:
  88. End;
  89. End;
  90. {$define FPC_SYSTEM_HAS_FILLCHAR}
  91. Procedure FillChar(var x;count:longint;value:byte);
  92. begin
  93. asm
  94. { Register Usage:
  95. r3 x
  96. r4 count
  97. r5 value
  98. r13 value.value.value.value
  99. r14 ptr to current dest char
  100. r15 byte increment, Scratch
  101. r16 Block count
  102. r17 misalignment byte count
  103. }
  104. cmpwi cr2,r4,12
  105. mr r14,r3
  106. andi. r17,r3,3
  107. sub r14,r3,r17 //32 bit align
  108. blt cr2,.FillBytes //if count<12 then fill byte by byte
  109. sub r16,r4,r17
  110. andi r17,r16,3
  111. cmpwi cr2,r17,0
  112. srwi r16,r16,2 //r16:=count div 4
  113. subi r16,r16,2
  114. mtctr r16 //counter:=r16
  115. mr r13,r5 //insert
  116. insrwi r13,r5,8,16 // value into all four bytes
  117. insrwi r13,r13,16,0 // of r13
  118. li r15,4
  119. stw r13,0(r3) //fill first few bytes
  120. .FillWordLoop:
  121. stwux r13,r14,r15
  122. bdnz .FillWordLoop
  123. beq cr2,FillEnd //No trailing bytes, so exit
  124. add r14,r3,r4
  125. stw r13,-4(r14) //fill last few bytes
  126. b .FillEnd
  127. .FillBytes:
  128. mtctr r4 //counter:=count
  129. li r15,1
  130. subi r14,r3,1
  131. .FillByteLoop:
  132. stbux r13,r14,r15
  133. bdnz .FillByteLoop
  134. .FillEnd:
  135. end [r13,r14,r15,r16,r17,ctr];
  136. end;
  137. {$define FPC_SYSTEM_HAS_FILLWORD}
  138. procedure fillword(var x;count : longint;value : word);
  139. begin
  140. { registers:
  141. r3 x
  142. r4 count
  143. r5 value
  144. r13 value.value
  145. r14 ptr to dest word
  146. r15 increment 1
  147. r16 increment 2
  148. r17 scratch
  149. r18 scratch
  150. f1 value.value.value.value
  151. }
  152. asm
  153. cmpwi cr0,r3,0
  154. andi r17,r4,$3
  155. srwi r18,r4,1 //r18:=count div 2
  156. mr r13,r3
  157. li r14,4
  158. ble .FillWordEnd //if count<=0 Then Exit
  159. .FillWordLoop:
  160. stwux r5,r13,r14
  161. bdnz .FillWordLoop
  162. .FillWordEnd:
  163. end [r13,r14,ctr]
  164. end;
  165. {
  166. $Log$
  167. Revision 1.1 2000-07-27 07:32:12 jonas
  168. + initial version by Casey Duncan (not yet thoroughly debugged or complete)
  169. }