math.inc 15 KB

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