math.inc 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586
  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. {$ASMMODE DIRECT}
  13. {$ifndef DEFAULT_EXTENDED}
  14. {****************************************************************************
  15. Real/Double data type routines
  16. ****************************************************************************}
  17. function pi : real;assembler;
  18. asm
  19. fldpi
  20. leave
  21. ret
  22. end [];
  23. function abs(d : real) : real;assembler;
  24. asm
  25. fldl 8(%ebp)
  26. fabs
  27. end [];
  28. function sqr(d : real) : real;assembler;
  29. asm
  30. fldl 8(%ebp)
  31. fldl 8(%ebp)
  32. fmulp
  33. end [];
  34. function sqrt(d : real) : real;assembler;
  35. asm
  36. fldl 8(%ebp)
  37. fsqrt
  38. leave
  39. ret $8
  40. end [];
  41. function arctan(d : real) : real;assembler;
  42. asm
  43. fldl 8(%ebp)
  44. fld1
  45. fpatan
  46. end [];
  47. function cos(d : real) : real;assembler;
  48. asm
  49. fldl 8(%ebp)
  50. fcos
  51. fstsw
  52. sahf
  53. jnp .LCOS1
  54. fstp %st(0)
  55. fldl .LCOS0
  56. jmp .LCOS1
  57. .LCOS0:
  58. .quad 0xffffffffffffffff
  59. .LCOS1:
  60. end ['EAX'];
  61. function exp(d : real) : real;assembler;
  62. asm
  63. // comes from DJ GPP
  64. fldl 8(%ebp)
  65. fldl2e
  66. fmulp
  67. fstcw .LCW1
  68. fstcw .LCW2
  69. fwait
  70. andw $0xf3ff,.LCW2
  71. orw $0x0400,.LCW2
  72. fldcw .LCW2
  73. fldl %st(0)
  74. frndint
  75. fldcw .LCW1
  76. fxch %st(1)
  77. fsub %st(1),%st
  78. f2xm1
  79. fld1
  80. faddp
  81. fscale
  82. fstp %st(1)
  83. jmp .LCW3
  84. // store some help data in the data segment
  85. .data
  86. .LCW1:
  87. .word 0
  88. .LCW2:
  89. .word 0
  90. .text
  91. .LCW3:
  92. end;
  93. function frac(d : real) : real;assembler;
  94. asm
  95. subl $16,%esp
  96. fnstcw -4(%ebp)
  97. fwait
  98. movw -4(%ebp),%cx
  99. orw $0x0c3f,%cx
  100. movw %cx,-8(%ebp)
  101. fldcw -8(%ebp)
  102. fwait
  103. fldl 8(%ebp)
  104. frndint
  105. fldl 8(%ebp)
  106. fsub %st(1)
  107. fstp %st(1)
  108. fclex
  109. fldcw -4(%ebp)
  110. end ['ECX'];
  111. function int(d : real) : real;assembler;
  112. asm
  113. subl $16,%esp
  114. fnstcw -4(%ebp)
  115. fwait
  116. movw -4(%ebp),%cx
  117. orw $0x0c3f,%cx
  118. movw %cx,-8(%ebp)
  119. fldcw -8(%ebp)
  120. fwait
  121. fldl 8(%ebp)
  122. frndint
  123. fclex
  124. fldcw -4(%ebp)
  125. end ['ECX'];
  126. function trunc(d : real) : longint;assembler;
  127. asm
  128. subl $16,%esp
  129. fnstcw -4(%ebp)
  130. fwait
  131. movw -4(%ebp),%cx
  132. orw $0x0c3f,%cx
  133. movw %cx,-8(%ebp)
  134. fldcw -8(%ebp)
  135. fwait
  136. fldl 8(%ebp)
  137. fistpl -8(%ebp)
  138. movl -8(%ebp),%eax
  139. fldcw -4(%ebp)
  140. end ['EAX','ECX'];
  141. function round(d : real) : longint;assembler;
  142. asm
  143. subl $8,%esp
  144. fnstcw -4(%ebp)
  145. fwait
  146. movw $0x1372,-8(%ebp)
  147. fldcw -8(%ebp)
  148. fwait
  149. fldl 8(%ebp)
  150. fistpl -8(%ebp)
  151. movl -8(%ebp),%eax
  152. fldcw -4(%ebp)
  153. end ['EAX','ECX'];
  154. function ln(d : real) : real;assembler;
  155. asm
  156. fldln2
  157. fldl 8(%ebp)
  158. fyl2x
  159. end [];
  160. function sin(d : real) : real;assembler;
  161. asm
  162. fldl 8(%ebp)
  163. fsin
  164. fstsw
  165. sahf
  166. jnp .LSIN1
  167. fstp %st(0)
  168. fldl .LSIN0
  169. jmp .LSIN1
  170. .LSIN0:
  171. .quad 0xffffffffffffffff
  172. .LSIN1:
  173. end ['EAX'];
  174. function power(bas,expo : real) : real;
  175. begin
  176. power:=exp(ln(bas)*expo);
  177. end;
  178. {$else DEFAULT_EXTENDED}
  179. {****************************************************************************
  180. EXTENDED data type routines
  181. ****************************************************************************}
  182. function pi : extended;assembler;[internconst:in_const_pi];
  183. asm
  184. fldpi
  185. end [];
  186. function abs(d : extended) : extended;assembler;[internconst:in_const_abs];
  187. asm
  188. fldt d
  189. fabs
  190. end [];
  191. function sqr(d : extended) : extended;assembler;[internconst:in_const_sqr];
  192. asm
  193. fldt d
  194. fldt d
  195. fmulp
  196. end [];
  197. function sqrt(d : extended) : extended;assembler;[internconst:in_const_sqrt];
  198. asm
  199. fldt d
  200. fsqrt
  201. end [];
  202. function arctan(d : extended) : extended;assembler;[internconst:in_const_arctan];
  203. asm
  204. fldt d
  205. fld1
  206. fpatan
  207. end [];
  208. function cos(d : extended) : extended;assembler;[internconst:in_const_cos];
  209. asm
  210. fldt d
  211. fcos
  212. fstsw
  213. sahf
  214. jnp .LCOS1
  215. fstp %st(0)
  216. fldt .LCOS0
  217. jmp .LCOS1
  218. .data
  219. .LCOS0:
  220. .long 0xffffffff
  221. .long 0xffffffff
  222. .long 0xffffffff
  223. .text
  224. .LCOS1:
  225. end ['EAX'];
  226. function exp(d : extended) : extended;assembler;[internconst:in_const_exp];
  227. asm
  228. // comes from DJ GPP
  229. fldt d
  230. fldl2e
  231. fmulp
  232. fstcw .LCW1
  233. fstcw .LCW2
  234. fwait
  235. andw $0xf3ff,.LCW2
  236. orw $0x0400,.LCW2
  237. fldcw .LCW2
  238. fld %st(0)
  239. frndint
  240. fldcw .LCW1
  241. fxch %st(1)
  242. fsub %st(1),%st
  243. f2xm1
  244. fld1
  245. faddp
  246. fscale
  247. fstp %st(1)
  248. jmp .LCW3
  249. // store some help data in the data segment
  250. .data
  251. .LCW1:
  252. .word 0
  253. .LCW2:
  254. .word 0
  255. .text
  256. .LCW3:
  257. end;
  258. function frac(d : extended) : extended;assembler;[internconst:in_const_frac];
  259. asm
  260. subl $16,%esp
  261. fnstcw -4(%ebp)
  262. fwait
  263. movw -4(%ebp),%cx
  264. orw $0x0c3f,%cx
  265. movw %cx,-8(%ebp)
  266. fldcw -8(%ebp)
  267. fwait
  268. fldt d
  269. frndint
  270. fldt d
  271. fsub %st(1)
  272. fstp %st(1)
  273. fclex
  274. fldcw -4(%ebp)
  275. end ['ECX'];
  276. function int(d : extended) : extended;assembler;[internconst:in_const_int];
  277. asm
  278. subl $16,%esp
  279. fnstcw -4(%ebp)
  280. fwait
  281. movw -4(%ebp),%cx
  282. orw $0x0c3f,%cx
  283. movw %cx,-8(%ebp)
  284. fldcw -8(%ebp)
  285. fwait
  286. fldt d
  287. frndint
  288. fclex
  289. fldcw -4(%ebp)
  290. end ['ECX'];
  291. function trunc(d : extended) : longint;assembler;[internconst:in_const_trunc];
  292. asm
  293. subl $16,%esp
  294. fnstcw -4(%ebp)
  295. fwait
  296. movw -4(%ebp),%cx
  297. orw $0x0c3f,%cx
  298. movw %cx,-8(%ebp)
  299. fldcw -8(%ebp)
  300. fwait
  301. fldt d
  302. fistpl -8(%ebp)
  303. movl -8(%ebp),%eax
  304. fldcw -4(%ebp)
  305. end ['EAX','ECX'];
  306. function round(d : extended) : longint;assembler;[internconst:in_const_round];
  307. asm
  308. subl $8,%esp
  309. fnstcw -4(%ebp)
  310. fwait
  311. movw $0x1372,-8(%ebp)
  312. fldcw -8(%ebp)
  313. fwait
  314. fldt d
  315. fistpl -8(%ebp)
  316. movl -8(%ebp),%eax
  317. fldcw -4(%ebp)
  318. end ['EAX','ECX'];
  319. function ln(d : extended) : extended;assembler;[internconst:in_const_ln];
  320. asm
  321. fldln2
  322. fldt d
  323. fyl2x
  324. end [];
  325. function sin(d : extended) : extended;assembler;[internconst:in_const_sin];
  326. asm
  327. fldt d
  328. fsin
  329. fstsw
  330. sahf
  331. jnp .LSIN1
  332. fstp %st(0)
  333. fldt .LSIN0
  334. jmp .LSIN1
  335. .data
  336. .LSIN0:
  337. .long 0xffffffff
  338. .long 0xffffffff
  339. .long 0xffffffff
  340. .text
  341. .LSIN1:
  342. end ['EAX'];
  343. function power(bas,expo : extended) : extended;
  344. begin
  345. power:=exp(ln(bas)*expo);
  346. end;
  347. {$endif DEFAULT_EXTENDED}
  348. {****************************************************************************
  349. Longint data type routines
  350. ****************************************************************************}
  351. function power(bas,expo : longint) : longint;
  352. begin
  353. power:=round(exp(ln(bas)*expo));
  354. end;
  355. {****************************************************************************
  356. Fixed data type routines
  357. ****************************************************************************}
  358. {$ifdef _SUPPORT_FIXED} { Not yet allowed }
  359. function sqrt(d : fixed) : fixed;
  360. begin
  361. asm
  362. movl d,%eax
  363. movl %eax,%ebx
  364. movl %eax,%ecx
  365. jecxz .L_kl
  366. xorl %esi,%esi
  367. .L_it:
  368. xorl %edx,%edx
  369. idivl %ebx
  370. addl %ebx,%eax
  371. shrl $1,%eax
  372. subl %eax,%esi
  373. cmpl $1,%esi
  374. jbe .L_kl
  375. movl %eax,%esi
  376. movl %eax,%ebx
  377. movl %ecx,%eax
  378. jmp .L_it
  379. .L_kl:
  380. shl $8,%eax
  381. leave
  382. ret $4
  383. end;
  384. end;
  385. function int(d : fixed) : fixed;
  386. {*****************************************************************}
  387. { Returns the integral part of d }
  388. {*****************************************************************}
  389. begin
  390. int:=d and $ffff0000; { keep only upper bits }
  391. end;
  392. function trunc(d : fixed) : longint;
  393. {*****************************************************************}
  394. { Returns the Truncated integral part of d }
  395. {*****************************************************************}
  396. begin
  397. trunc:=longint(integer(d shr 16)); { keep only upper 16 bits }
  398. end;
  399. function frac(d : fixed) : fixed;
  400. {*****************************************************************}
  401. { Returns the Fractional part of d }
  402. {*****************************************************************}
  403. begin
  404. frac:=d AND $ffff; { keep only decimal parts - lower 16 bits }
  405. end;
  406. function abs(d : fixed) : fixed;
  407. {*****************************************************************}
  408. { Returns the Absolute value of d }
  409. {*****************************************************************}
  410. begin
  411. asm
  412. movl d,%eax
  413. rol $16,%eax { Swap high & low word.}
  414. {Absolute value: Invert all bits and increment when <0 .}
  415. cwd { When ax<0, dx contains $ffff}
  416. xorw %dx,%ax { Inverts all bits when dx=$ffff.}
  417. subw %dx,%ax { Increments when dx=$ffff.}
  418. rol $16,%eax { Swap high & low word.}
  419. leave
  420. ret $4
  421. end;
  422. end;
  423. function sqr(d : fixed) : fixed;
  424. {*****************************************************************}
  425. { Returns the Absolute squared value of d }
  426. {*****************************************************************}
  427. begin
  428. {16-bit precision needed, not 32 =)}
  429. sqr := d*d;
  430. { sqr := (d SHR 8 * d) SHR 8; }
  431. end;
  432. function Round(x: fixed): longint;
  433. {*****************************************************************}
  434. { Returns the Rounded value of d as a longint }
  435. {*****************************************************************}
  436. var
  437. lowf:integer;
  438. highf:integer;
  439. begin
  440. lowf:=x and $ffff; { keep decimal part ... }
  441. highf :=integer(x shr 16);
  442. if lowf > 5 then
  443. highf:=highf+1
  444. else
  445. if lowf = 5 then
  446. begin
  447. { here we must check the sign ... }
  448. { if greater or equal to zero, then }
  449. { greater value will be found by adding }
  450. { one... }
  451. if highf >= 0 then
  452. Highf:=Highf+1;
  453. end;
  454. Round:= longint(highf);
  455. end;
  456. {$endif SUPPORT_FIXED}
  457. {$ASMMODE ATT}
  458. {
  459. $Log$
  460. Revision 1.13 1998-12-15 22:42:56 peter
  461. * removed temp symbols
  462. Revision 1.12 1998/11/24 12:54:57 peter
  463. * removed all explicit leave;ret commands and let them generate by
  464. the compiler (needed for stack alignment)
  465. Revision 1.11 1998/11/16 14:26:03 pierre
  466. * changed fsqrtl to fsqrt (needed by as v2.9.4 for win32)
  467. Revision 1.10 1998/10/02 09:25:29 peter
  468. * more constant expression evals
  469. Revision 1.9 1998/09/11 17:38:49 pierre
  470. merge for fixes branch
  471. Revision 1.8.2.1 1998/09/11 17:37:25 pierre
  472. * correction respective to stricter as v2.9.1 syntax
  473. Revision 1.8 1998/09/01 17:36:18 peter
  474. + internconst
  475. Revision 1.7 1998/08/25 08:49:05 florian
  476. * corrected exp() function
  477. Revision 1.6 1998/08/11 21:39:04 peter
  478. * splitted default_extended from support_extended
  479. Revision 1.5 1998/08/11 00:04:50 peter
  480. * $ifdef ver0_99_5 updates
  481. Revision 1.4 1998/08/10 15:54:50 peter
  482. * removed dup power(longint)
  483. Revision 1.3 1998/08/08 12:28:09 florian
  484. * a lot small fixes to the extended data type work
  485. Revision 1.2 1998/05/31 14:15:49 peter
  486. * force to use ATT or direct parsing
  487. }