2
0

math.inc 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396
  1. {
  2. $Id$
  3. This file is part of the Free Pascal run time library.
  4. Copyright (c) 1993-98 by the Free Pascal development team
  5. Implementation of mathamatical Routines (only for real)
  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. {****************************************************************************
  13. EXTENDED data type routines
  14. ****************************************************************************}
  15. {$ifndef NEWATT}
  16. {$asmmode DIRECT}
  17. {$endif}
  18. function pi : extended;assembler;[internconst:in_const_pi];
  19. asm
  20. fldpi
  21. end [];
  22. function abs(d : extended) : extended;assembler;[internconst:in_const_abs];
  23. asm
  24. fldt d
  25. fabs
  26. end [];
  27. function sqr(d : extended) : extended;assembler;[internconst:in_const_sqr];
  28. asm
  29. fldt d
  30. fldt d
  31. fmulp
  32. end [];
  33. function sqrt(d : extended) : extended;assembler;[internconst:in_const_sqrt];
  34. asm
  35. fldt d
  36. fsqrt
  37. end [];
  38. function arctan(d : extended) : extended;assembler;[internconst:in_const_arctan];
  39. asm
  40. fldt d
  41. fld1
  42. fpatan
  43. end [];
  44. function cos(d : extended) : extended;assembler;[internconst:in_const_cos];
  45. asm
  46. fldt d
  47. fcos
  48. fstsw
  49. sahf
  50. jnp .LCOS1
  51. fstp %st(0)
  52. fldt .LCOS0
  53. jmp .LCOS1
  54. .data
  55. .LCOS0:
  56. .long 0xffffffff
  57. .long 0xffffffff
  58. .long 0xffffffff
  59. .text
  60. .LCOS1:
  61. end ['EAX'];
  62. function exp(d : extended) : extended;assembler;[internconst:in_const_exp];
  63. asm
  64. // comes from DJ GPP
  65. fldt d
  66. fldl2e
  67. fmulp
  68. fstcw .LCW1
  69. fstcw .LCW2
  70. fwait
  71. andw $0xf3ff,.LCW2
  72. orw $0x0400,.LCW2
  73. fldcw .LCW2
  74. fld %st(0)
  75. frndint
  76. fldcw .LCW1
  77. fxch %st(1)
  78. fsub %st(1),%st
  79. f2xm1
  80. fld1
  81. faddp
  82. fscale
  83. fstp %st(1)
  84. jmp .LCW3
  85. // store some help data in the data segment
  86. .data
  87. .LCW1:
  88. .word 0
  89. .LCW2:
  90. .word 0
  91. .text
  92. .LCW3:
  93. end;
  94. function frac(d : extended) : extended;assembler;[internconst:in_const_frac];
  95. asm
  96. subl $16,%esp
  97. fnstcw -4(%ebp)
  98. fwait
  99. movw -4(%ebp),%cx
  100. orw $0x0c3f,%cx
  101. movw %cx,-8(%ebp)
  102. fldcw -8(%ebp)
  103. fwait
  104. fldt d
  105. frndint
  106. fldt d
  107. fsub %st(1)
  108. fstp %st(1)
  109. fclex
  110. fldcw -4(%ebp)
  111. end ['ECX'];
  112. function int(d : extended) : extended;assembler;[internconst:in_const_int];
  113. asm
  114. subl $16,%esp
  115. fnstcw -4(%ebp)
  116. fwait
  117. movw -4(%ebp),%cx
  118. orw $0x0c3f,%cx
  119. movw %cx,-8(%ebp)
  120. fldcw -8(%ebp)
  121. fwait
  122. fldt d
  123. frndint
  124. fclex
  125. fldcw -4(%ebp)
  126. end ['ECX'];
  127. function trunc(d : extended) : longint;assembler;[internconst:in_const_trunc];
  128. asm
  129. subl $16,%esp
  130. fnstcw -4(%ebp)
  131. fwait
  132. movw -4(%ebp),%cx
  133. orw $0x0c3f,%cx
  134. movw %cx,-8(%ebp)
  135. fldcw -8(%ebp)
  136. fwait
  137. fldt d
  138. fistpl -8(%ebp)
  139. movl -8(%ebp),%eax
  140. fldcw -4(%ebp)
  141. end ['EAX','ECX'];
  142. function round(d : extended) : longint;assembler;[internconst:in_const_round];
  143. asm
  144. subl $8,%esp
  145. fnstcw -4(%ebp)
  146. fwait
  147. movw $0x1372,-8(%ebp)
  148. fldcw -8(%ebp)
  149. fwait
  150. fldt d
  151. fistpl -8(%ebp)
  152. movl -8(%ebp),%eax
  153. fldcw -4(%ebp)
  154. end ['EAX','ECX'];
  155. function ln(d : extended) : extended;assembler;[internconst:in_const_ln];
  156. asm
  157. fldln2
  158. fldt d
  159. fyl2x
  160. end [];
  161. function sin(d : extended) : extended;assembler;[internconst:in_const_sin];
  162. asm
  163. fldt d
  164. fsin
  165. fstsw
  166. sahf
  167. jnp .LSIN1
  168. fstp %st(0)
  169. fldt .LSIN0
  170. jmp .LSIN1
  171. .data
  172. .LSIN0:
  173. .long 0xffffffff
  174. .long 0xffffffff
  175. .long 0xffffffff
  176. .text
  177. .LSIN1:
  178. end ['EAX'];
  179. function power(bas,expo : extended) : extended;
  180. begin
  181. power:=exp(ln(bas)*expo);
  182. end;
  183. {****************************************************************************
  184. Longint data type routines
  185. ****************************************************************************}
  186. function power(bas,expo : longint) : longint;
  187. begin
  188. power:=round(exp(ln(bas)*expo));
  189. end;
  190. {****************************************************************************
  191. Fixed data type routines
  192. ****************************************************************************}
  193. {$ifdef _SUPPORT_FIXED} { Not yet allowed }
  194. function sqrt(d : fixed) : fixed;
  195. begin
  196. asm
  197. movl d,%eax
  198. movl %eax,%ebx
  199. movl %eax,%ecx
  200. jecxz .L_kl
  201. xorl %esi,%esi
  202. .L_it:
  203. xorl %edx,%edx
  204. idivl %ebx
  205. addl %ebx,%eax
  206. shrl $1,%eax
  207. subl %eax,%esi
  208. cmpl $1,%esi
  209. jbe .L_kl
  210. movl %eax,%esi
  211. movl %eax,%ebx
  212. movl %ecx,%eax
  213. jmp .L_it
  214. .L_kl:
  215. shl $8,%eax
  216. leave
  217. ret $4
  218. end;
  219. end;
  220. function int(d : fixed) : fixed;
  221. {*****************************************************************}
  222. { Returns the integral part of d }
  223. {*****************************************************************}
  224. begin
  225. int:=d and $ffff0000; { keep only upper bits }
  226. end;
  227. function trunc(d : fixed) : longint;
  228. {*****************************************************************}
  229. { Returns the Truncated integral part of d }
  230. {*****************************************************************}
  231. begin
  232. trunc:=longint(integer(d shr 16)); { keep only upper 16 bits }
  233. end;
  234. function frac(d : fixed) : fixed;
  235. {*****************************************************************}
  236. { Returns the Fractional part of d }
  237. {*****************************************************************}
  238. begin
  239. frac:=d AND $ffff; { keep only decimal parts - lower 16 bits }
  240. end;
  241. function abs(d : fixed) : fixed;
  242. {*****************************************************************}
  243. { Returns the Absolute value of d }
  244. {*****************************************************************}
  245. begin
  246. asm
  247. movl d,%eax
  248. rol $16,%eax { Swap high & low word.}
  249. {Absolute value: Invert all bits and increment when <0 .}
  250. cwd { When ax<0, dx contains $ffff}
  251. xorw %dx,%ax { Inverts all bits when dx=$ffff.}
  252. subw %dx,%ax { Increments when dx=$ffff.}
  253. rol $16,%eax { Swap high & low word.}
  254. leave
  255. ret $4
  256. end;
  257. end;
  258. function sqr(d : fixed) : fixed;
  259. {*****************************************************************}
  260. { Returns the Absolute squared value of d }
  261. {*****************************************************************}
  262. begin
  263. {16-bit precision needed, not 32 =)}
  264. sqr := d*d;
  265. { sqr := (d SHR 8 * d) SHR 8; }
  266. end;
  267. function Round(x: fixed): longint;
  268. {*****************************************************************}
  269. { Returns the Rounded value of d as a longint }
  270. {*****************************************************************}
  271. var
  272. lowf:integer;
  273. highf:integer;
  274. begin
  275. lowf:=x and $ffff; { keep decimal part ... }
  276. highf :=integer(x shr 16);
  277. if lowf > 5 then
  278. highf:=highf+1
  279. else
  280. if lowf = 5 then
  281. begin
  282. { here we must check the sign ... }
  283. { if greater or equal to zero, then }
  284. { greater value will be found by adding }
  285. { one... }
  286. if highf >= 0 then
  287. Highf:=Highf+1;
  288. end;
  289. Round:= longint(highf);
  290. end;
  291. {$endif SUPPORT_FIXED}
  292. {$ifndef NEWATT}
  293. {$asmmode ATT}
  294. {$endif}
  295. {
  296. $Log$
  297. Revision 1.14 1999-03-01 15:40:57 peter
  298. * use external names
  299. * removed all direct assembler modes
  300. Revision 1.13 1998/12/15 22:42:56 peter
  301. * removed temp symbols
  302. Revision 1.12 1998/11/24 12:54:57 peter
  303. * removed all explicit leave;ret commands and let them generate by
  304. the compiler (needed for stack alignment)
  305. Revision 1.11 1998/11/16 14:26:03 pierre
  306. * changed fsqrtl to fsqrt (needed by as v2.9.4 for win32)
  307. Revision 1.10 1998/10/02 09:25:29 peter
  308. * more constant expression evals
  309. Revision 1.9 1998/09/11 17:38:49 pierre
  310. merge for fixes branch
  311. Revision 1.8.2.1 1998/09/11 17:37:25 pierre
  312. * correction respective to stricter as v2.9.1 syntax
  313. Revision 1.8 1998/09/01 17:36:18 peter
  314. + internconst
  315. Revision 1.7 1998/08/25 08:49:05 florian
  316. * corrected exp() function
  317. Revision 1.6 1998/08/11 21:39:04 peter
  318. * splitted default_extended from support_extended
  319. Revision 1.5 1998/08/11 00:04:50 peter
  320. * $ifdef ver0_99_5 updates
  321. Revision 1.4 1998/08/10 15:54:50 peter
  322. * removed dup power(longint)
  323. Revision 1.3 1998/08/08 12:28:09 florian
  324. * a lot small fixes to the extended data type work
  325. Revision 1.2 1998/05/31 14:15:49 peter
  326. * force to use ATT or direct parsing
  327. }