int64p.inc 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233
  1. {
  2. $Id$
  3. This file is part of the Free Pascal run time library.
  4. Copyright (c) 1999-2000 by the Free Pascal development team
  5. This file contains some helper routines for int64 and qword
  6. See the file COPYING.FPC, included in this distribution,
  7. for details about the copyright.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  11. **********************************************************************}
  12. {$Q- no overflow checking }
  13. {$R- no range checking }
  14. {$define FPC_SYSTEM_HAS_DIV_QWORD}
  15. function fpc_div_qword(n,z : qword) : qword;assembler;[public,alias: 'FPC_DIV_QWORD']; {$ifdef hascompilerproc} compilerproc; {$endif}
  16. var
  17. shift,lzz,lzn : longint;
  18. saveebx,saveedi : longint;
  19. asm
  20. movl %ebx,saveebx
  21. movl %edi,saveedi
  22. { the following piece of code is taken from the }
  23. { AMD Athlon Processor x86 Code Optimization manual }
  24. movl n+4,%ecx
  25. movl n,%ebx
  26. movl %ecx,%eax
  27. orl %ebx,%eax
  28. jnz .Lnodivzero
  29. pushl %ebp
  30. pushl $200
  31. call HandleErrorFrame
  32. jmp .Lexit
  33. .Lnodivzero:
  34. movl z+4,%edx
  35. movl z,%eax
  36. testl %ecx,%ecx
  37. jnz .Lqworddivbigdivisor
  38. cmpl %ebx,%edx
  39. jae .Lqworddivtwo_divs
  40. divl %ebx
  41. movl %ecx,%edx
  42. jmp .Lexit
  43. .Lqworddivtwo_divs:
  44. movl %eax,%ecx
  45. movl %edx,%eax
  46. xorl %edx,%edx
  47. divl %ebx
  48. xchgl %ecx,%eax
  49. divl %ebx
  50. movl %ecx,%edx
  51. jmp .Lexit
  52. .Lqworddivbigdivisor:
  53. movl %ecx,%edi
  54. shrl $1,%edx
  55. rcrl $1,%eax
  56. rorl $1,%edi
  57. rcrl $1,%ebx
  58. bsrl %ecx,%ecx
  59. shrdl %cl,%edi,%ebx
  60. shrdl %cl,%edx,%eax
  61. shrl %cl,%edx
  62. roll $1,%edi
  63. divl %ebx
  64. movl z,%ebx
  65. movl %eax,%ecx
  66. imull %eax,%edi
  67. mull n
  68. addl %edi,%edx
  69. subl %eax,%ebx
  70. movl %ecx,%eax
  71. movl z+4,%ecx
  72. sbbl %edx,%ecx
  73. sbbl $0,%eax
  74. xorl %edx,%edx
  75. .Lexit:
  76. movl saveebx,%ebx
  77. movl saveedi,%edi
  78. end;
  79. (*
  80. This does not work correctly
  81. {$define FPC_SYSTEM_HAS_MOD_QWORD}
  82. function fpc_mod_qword(n,z : qword) : qword;[public,alias: 'FPC_MOD_QWORD']; {$ifdef hascompilerproc} compilerproc; {$endif}
  83. var
  84. shift,lzz,lzn : longint;
  85. saveebx,saveedi : longint;
  86. asm
  87. movl %ebx,saveebx
  88. movl %edi,saveedi
  89. { the following piece of code is taken from the }
  90. { AMD Athlon Processor x86 Code Optimization manual }
  91. movl n+4,%ecx
  92. movl n,%ebx
  93. movl %ecx,%eax
  94. orl %ebx,%eax
  95. jnz .Lnodivzero
  96. pushl %ebp
  97. pushl $200
  98. call HandleErrorFrame
  99. jmp .Lexit
  100. movl z+4,%edx
  101. movl z,%eax
  102. testl %ecx,%ecx
  103. jnz .Lqwordmodr_big_divisior
  104. cmpl %ebx,%edx
  105. jae .Lqwordmodr_two_divs
  106. divl %ebx
  107. movl %edx,%eax
  108. movl %ecx,%edx
  109. jmp .Lexit
  110. .Lqwordmodr_two_divs:
  111. movl %eax,%ecx
  112. movl %edx,%eax
  113. xorl %edx,%edx
  114. divl %ebx
  115. movl %ecx,%eax
  116. divl %ebx
  117. movl %edx,%eax
  118. xorl %edx,%edx
  119. jmp .Lexit
  120. .Lqwordmodr_big_divisior:
  121. movl %ecx,%edi
  122. shrl $1,%edx
  123. rcrl $1,%eax
  124. rorl $1,%edi
  125. rcrl $1,%ebx
  126. bsrl %ecx,%ecx
  127. shrdl %cl,%edi,%ebx
  128. shrdl %cl,%edx,%eax
  129. shrl %cl,%edx
  130. rorl $1,%edi
  131. divl %ebx
  132. movl z,%ebx
  133. movl %eax,%ecx
  134. imull %eax,%edi
  135. mull n
  136. addl %edi,%edx
  137. subl %eax,%ebx
  138. movl z+4,%ecx
  139. movl n,%eax
  140. sbbl %edx,%ecx
  141. sbbl %edx,%edx
  142. andl %edx,%eax
  143. andl n+4,%edx
  144. addl %ebx,%eax
  145. adcl %ecx,%edx
  146. .Lexit:
  147. movl saveebx,%ebx
  148. movl saveedi,%edi
  149. end;
  150. *)
  151. {$define FPC_SYSTEM_HAS_MUL_QWORD}
  152. { multiplies two qwords
  153. the longbool for checkoverflow avoids a misaligned stack
  154. }
  155. function fpc_mul_qword(f1,f2 : qword;checkoverflow : longbool) : qword;[public,alias: 'FPC_MUL_QWORD']; {$ifdef hascompilerproc} compilerproc; {$endif}
  156. var
  157. _f1,bitpos : qword;
  158. l : longint;
  159. r : qword;
  160. begin
  161. if not(checkoverflow) then
  162. begin
  163. { the following piece of code is taken from the }
  164. { AMD Athlon Processor x86 Code Optimization manual }
  165. asm
  166. movl f1+4,%edx
  167. movl f2+4,%ecx
  168. orl %ecx,%edx
  169. movl f2,%edx
  170. movl f1,%eax
  171. jnz .Lqwordmultwomul
  172. mull %edx
  173. jmp .Lqwordmulready
  174. .Lqwordmultwomul:
  175. imul f1+4,%edx
  176. imul %eax,%ecx
  177. addl %edx,%ecx
  178. mull f2
  179. add %ecx,%edx
  180. .Lqwordmulready:
  181. movl %eax,r
  182. movl %edx,r+4
  183. end [ 'eax','edx','ecx' ];
  184. fpc_mul_qword:=r;
  185. end
  186. else
  187. begin
  188. fpc_mul_qword:=0;
  189. bitpos:=1;
  190. // store f1 for overflow checking
  191. _f1:=f1;
  192. for l:=0 to 63 do
  193. begin
  194. if (f2 and bitpos)<>0 then
  195. fpc_mul_qword:=fpc_mul_qword+f1;
  196. f1:=f1 shl 1;
  197. bitpos:=bitpos shl 1;
  198. end;
  199. { if one of the operands is greater than the result an }
  200. { overflow occurs }
  201. if checkoverflow and (_f1 <> 0) and (f2 <>0) and
  202. ((_f1>fpc_mul_qword) or (f2>fpc_mul_qword)) then
  203. HandleErrorFrame(215,get_frame);
  204. end;
  205. end;
  206. {
  207. $Log$
  208. Revision 1.1 2003-09-14 11:34:13 peter
  209. * moved int64 asm code to int64p.inc
  210. * save ebx,esi
  211. }