math.inc 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417
  1. {
  2. $Id$
  3. This file is part of the Free Pascal run time library.
  4. Copyright (c) 1993,97 by the Free Pascal development team
  5. See the file COPYING.FPC, included in this distribution,
  6. for details about the copyright.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  10. **********************************************************************}
  11. { Implementation of mathamatical Routines (only for real) }
  12. function abs(d : real) : real;
  13. begin
  14. asm
  15. fldl 8(%ebp)
  16. fabs
  17. leave
  18. ret $8
  19. end [];
  20. end;
  21. function sqr(d : real) : real;
  22. begin
  23. asm
  24. fldl 8(%ebp)
  25. fldl 8(%ebp)
  26. fmulp
  27. leave
  28. ret $8
  29. end [];
  30. end;
  31. function sqrt(d : real) : real;
  32. begin
  33. asm
  34. fldl 8(%ebp)
  35. fsqrtl
  36. leave
  37. ret $8
  38. end [];
  39. end;
  40. function arctan(d : real) : real;
  41. begin
  42. asm
  43. fldl 8(%ebp)
  44. fld1
  45. fpatan
  46. leave
  47. ret $8
  48. end [];
  49. end;
  50. function cos(d : real) : real;
  51. begin
  52. asm
  53. fldl 8(%ebp)
  54. fcos
  55. fstsw
  56. sahf
  57. jnp .LCOS1
  58. fstp %st(0)
  59. fldl .LCOS0
  60. .LCOS1:
  61. leave
  62. ret $8
  63. .LCOS0:
  64. .quad 0xffffffffffffffff
  65. end ['EAX'];
  66. end;
  67. function exp(d : real) : real;
  68. begin
  69. asm
  70. // comes from DJ GPP
  71. fldl 8(%ebp)
  72. fldl2e
  73. fmulp
  74. fstcww .LCW1
  75. fstcww .LCW2
  76. fwait
  77. andw $0xf3ff,.LCW2
  78. orw $0x0400,.LCW2
  79. fldcww .LCW2
  80. fldl %st(0)
  81. frndint
  82. fldcww .LCW1
  83. fxch %st(1)
  84. fsub %st(1),%st
  85. f2xm1
  86. faddl .LC0
  87. fscale
  88. fstp %st(1)
  89. leave
  90. ret $8
  91. // store some help data in the data segment
  92. .data
  93. .LCW1:
  94. .word 0
  95. .LCW2:
  96. .word 0
  97. .LC0:
  98. .double 0d1.0e+00
  99. // do not forget to switch back to text
  100. .text
  101. end;
  102. end;
  103. function frac(d : real) : real;
  104. begin
  105. asm
  106. subl $16,%esp
  107. fnstcw -4(%ebp)
  108. fwait
  109. movw -4(%ebp),%cx
  110. orw $0x0c3f,%cx
  111. movw %cx,-8(%ebp)
  112. fldcw -8(%ebp)
  113. fwait
  114. fldl 8(%ebp)
  115. frndint
  116. fldl 8(%ebp)
  117. fsub %st(1)
  118. fstp %st(1)
  119. fclex
  120. fldcw -4(%ebp)
  121. leave
  122. ret $8
  123. end ['ECX'];
  124. end;
  125. function int(d : real) : real;
  126. begin
  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. frndint
  138. fclex
  139. fldcw -4(%ebp)
  140. leave
  141. ret $8
  142. end ['ECX'];
  143. end;
  144. function trunc(d : real) : longint;
  145. begin
  146. asm
  147. subl $16,%esp
  148. fnstcw -4(%ebp)
  149. fwait
  150. movw -4(%ebp),%cx
  151. orw $0x0c3f,%cx
  152. movw %cx,-8(%ebp)
  153. fldcw -8(%ebp)
  154. fwait
  155. fldl 8(%ebp)
  156. fistpl -8(%ebp)
  157. movl -8(%ebp),%eax
  158. fldcw -4(%ebp)
  159. leave
  160. ret $8
  161. end ['EAX','ECX'];
  162. end;
  163. function round(d : real) : longint;
  164. begin
  165. asm
  166. subl $8,%esp
  167. fnstcw -4(%ebp)
  168. fwait
  169. movw $0x1372,-8(%ebp)
  170. fldcw -8(%ebp)
  171. fwait
  172. fldl 8(%ebp)
  173. fistpl -8(%ebp)
  174. movl -8(%ebp),%eax
  175. fldcw -4(%ebp)
  176. leave
  177. ret $8
  178. end ['EAX','ECX'];
  179. end;
  180. function ln(d : real) : real;
  181. begin
  182. asm
  183. fldln2
  184. fldl 8(%ebp)
  185. fyl2x
  186. leave
  187. ret $8
  188. end [];
  189. end;
  190. function pi : real;
  191. begin
  192. asm
  193. fldpi
  194. leave
  195. ret
  196. end [];
  197. end;
  198. function sin(d : real) : real;
  199. begin
  200. asm
  201. fldl 8(%ebp)
  202. fsin
  203. fstsw
  204. sahf
  205. jnp .LSIN1
  206. fstp %st(0)
  207. fldl .LSIN0
  208. .LSIN1:
  209. leave
  210. ret $8
  211. .LSIN0:
  212. .quad 0xffffffffffffffff
  213. end ['EAX'];
  214. end;
  215. function power(bas,expo : real) : real;
  216. begin
  217. power:=exp(ln(bas)*expo);
  218. end;
  219. function power(bas,expo : longint) : longint;
  220. begin
  221. power:=round(exp(ln(bas)*expo));
  222. end;
  223. {$ifdef fixed}
  224. function sqrt(d : fixed) : fixed;
  225. begin
  226. asm
  227. movl d,%eax
  228. movl %eax,%ebx
  229. movl %eax,%ecx
  230. jecxz .L_kl
  231. xorl %esi,%esi
  232. .L_it:
  233. xorl %edx,%edx
  234. idivl %ebx
  235. addl %ebx,%eax
  236. shrl $1,%eax
  237. subl %eax,%esi
  238. cmpl $1,%esi
  239. jbe .L_kl
  240. movl %eax,%esi
  241. movl %eax,%ebx
  242. movl %ecx,%eax
  243. jmp .L_it
  244. .L_kl:
  245. shl $8,%eax
  246. leave
  247. ret $4
  248. end;
  249. end;
  250. function int(d : fixed) : fixed;
  251. {*****************************************************************}
  252. { Returns the integral part of d }
  253. {*****************************************************************}
  254. begin
  255. int:=d and $ffff0000; { keep only upper bits }
  256. end;
  257. function trunc(d : fixed) : longint;
  258. {*****************************************************************}
  259. { Returns the Truncated integral part of d }
  260. {*****************************************************************}
  261. begin
  262. trunc:=longint(integer(d shr 16)); { keep only upper 16 bits }
  263. end;
  264. function frac(d : fixed) : fixed;
  265. {*****************************************************************}
  266. { Returns the Fractional part of d }
  267. {*****************************************************************}
  268. begin
  269. frac:=d AND $ffff; { keep only decimal parts - lower 16 bits }
  270. end;
  271. function abs(d : fixed) : fixed;
  272. {*****************************************************************}
  273. { Returns the Absolute value of d }
  274. {*****************************************************************}
  275. begin
  276. asm
  277. movl d,%eax
  278. rol $16,%eax { Swap high & low word.}
  279. {Absolute value: Invert all bits and increment when <0 .}
  280. cwd { When ax<0, dx contains $ffff}
  281. xorw %dx,%ax { Inverts all bits when dx=$ffff.}
  282. subw %dx,%ax { Increments when dx=$ffff.}
  283. rol $16,%eax { Swap high & low word.}
  284. leave
  285. ret $4
  286. end;
  287. end;
  288. function sqr(d : fixed) : fixed;
  289. {*****************************************************************}
  290. { Returns the Absolute squared value of d }
  291. {*****************************************************************}
  292. begin
  293. {16-bit precision needed, not 32 =)}
  294. sqr := d*d;
  295. { sqr := (d SHR 8 * d) SHR 8; }
  296. end;
  297. function Round(x: fixed): longint;
  298. {*****************************************************************}
  299. { Returns the Rounded value of d as a longint }
  300. {*****************************************************************}
  301. var
  302. lowf:integer;
  303. highf:integer;
  304. begin
  305. lowf:=x and $ffff; { keep decimal part ... }
  306. highf :=integer(x shr 16);
  307. if lowf > 5 then
  308. highf:=highf+1
  309. else
  310. if lowf = 5 then
  311. begin
  312. { here we must check the sign ... }
  313. { if greater or equal to zero, then }
  314. { greater value will be found by adding }
  315. { one... }
  316. if highf >= 0 then
  317. Highf:=Highf+1;
  318. end;
  319. Round:= longint(highf);
  320. end;
  321. {$endif}
  322. {
  323. $Log$
  324. Revision 1.1 1998-03-25 11:18:42 root
  325. Initial revision
  326. Revision 1.9 1998/02/04 14:40:31 daniel
  327. * Translated abs for fixed to assembler.
  328. Revision 1.8 1998/01/27 12:44:48 peter
  329. * removed comment level 2 warning
  330. Revision 1.7 1998/01/26 11:59:04 michael
  331. + Added log at the end
  332. Working file: rtl/i386/math.inc
  333. description:
  334. ----------------------------
  335. revision 1.6
  336. date: 1998/01/20 15:12:27; author: peter; state: Exp; lines: +4 -3
  337. * fixes bug 65
  338. ----------------------------
  339. revision 1.5
  340. date: 1997/12/01 12:34:37; author: michael; state: Exp; lines: +11 -4
  341. + added copyright reference in header.
  342. ----------------------------
  343. revision 1.4
  344. date: 1997/11/28 23:26:44; author: florian; state: Exp; lines: +34 -33
  345. $ifdef fixed added
  346. ----------------------------
  347. revision 1.3
  348. date: 1997/11/28 19:46:11; author: pierre; state: Exp; lines: +360 -358
  349. + fixed math in define (does not compile yet)
  350. ----------------------------
  351. revision 1.2
  352. date: 1997/11/28 16:50:04; author: carl; state: Exp; lines: +358 -278
  353. + added fixes point routines.
  354. ----------------------------
  355. revision 1.1
  356. date: 1997/11/27 08:33:48; author: michael; state: Exp;
  357. Initial revision
  358. ----------------------------
  359. revision 1.1.1.1
  360. date: 1997/11/27 08:33:48; author: michael; state: Exp; lines: +0 -0
  361. FPC RTL CVS start
  362. =============================================================================
  363. }