FPU.ob07 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460
  1. (*
  2. BSD 2-Clause License
  3. Copyright (c) 2020-2021, Anton Krotov
  4. All rights reserved.
  5. *)
  6. MODULE FPU;
  7. CONST
  8. INF = 07F800000H;
  9. NINF = 0FF800000H;
  10. NAN = 07FC00000H;
  11. PROCEDURE div2 (b, a: INTEGER): INTEGER;
  12. VAR
  13. n, e, r, s: INTEGER;
  14. BEGIN
  15. s := ORD(BITS(a) / BITS(b) - {0..30});
  16. e := (a DIV 800000H) MOD 256 - (b DIV 800000H) MOD 256 + 127;
  17. a := a MOD 800000H + 800000H;
  18. b := b MOD 800000H + 800000H;
  19. n := 800000H;
  20. r := 0;
  21. IF a < b THEN
  22. a := a * 2;
  23. DEC(e)
  24. END;
  25. WHILE (a > 0) & (n > 0) DO
  26. IF a >= b THEN
  27. INC(r, n);
  28. DEC(a, b)
  29. END;
  30. a := a * 2;
  31. n := n DIV 2
  32. END;
  33. IF e <= 0 THEN
  34. e := 0;
  35. r := 800000H;
  36. s := 0
  37. ELSIF e >= 255 THEN
  38. e := 255;
  39. r := 800000H
  40. END
  41. RETURN (r - 800000H) + e * 800000H + s
  42. END div2;
  43. PROCEDURE mul2 (b, a: INTEGER): INTEGER;
  44. VAR
  45. e, r, s: INTEGER;
  46. BEGIN
  47. s := ORD(BITS(a) / BITS(b) - {0..30});
  48. e := (a DIV 800000H) MOD 256 + (b DIV 800000H) MOD 256 - 127;
  49. a := a MOD 800000H + 800000H;
  50. b := b MOD 800000H + 800000H;
  51. r := a * (b MOD 256);
  52. b := b DIV 256;
  53. r := LSR(r, 8);
  54. INC(r, a * (b MOD 256));
  55. b := b DIV 256;
  56. r := LSR(r, 8);
  57. INC(r, a * (b MOD 256));
  58. r := LSR(r, 7);
  59. IF r >= 1000000H THEN
  60. r := r DIV 2;
  61. INC(e)
  62. END;
  63. IF e <= 0 THEN
  64. e := 0;
  65. r := 800000H;
  66. s := 0
  67. ELSIF e >= 255 THEN
  68. e := 255;
  69. r := 800000H
  70. END
  71. RETURN (r - 800000H) + e * 800000H + s
  72. END mul2;
  73. PROCEDURE add2 (b, a: INTEGER): INTEGER;
  74. VAR
  75. t, e, d: INTEGER;
  76. BEGIN
  77. e := (a DIV 800000H) MOD 256;
  78. t := (b DIV 800000H) MOD 256;
  79. d := e - t;
  80. a := a MOD 800000H + 800000H;
  81. b := b MOD 800000H + 800000H;
  82. IF d > 0 THEN
  83. IF d < 24 THEN
  84. b := LSR(b, d)
  85. ELSE
  86. b := 0
  87. END
  88. ELSIF d < 0 THEN
  89. IF d > -24 THEN
  90. a := LSR(a, -d)
  91. ELSE
  92. a := 0
  93. END;
  94. e := t
  95. END;
  96. INC(a, b);
  97. IF a >= 1000000H THEN
  98. a := a DIV 2;
  99. INC(e)
  100. END;
  101. IF e >= 255 THEN
  102. e := 255;
  103. a := 800000H
  104. END
  105. RETURN (a - 800000H) + e * 800000H
  106. END add2;
  107. PROCEDURE sub2 (b, a: INTEGER): INTEGER;
  108. VAR
  109. t, e, d, s: INTEGER;
  110. BEGIN
  111. e := (a DIV 800000H) MOD 256;
  112. t := (b DIV 800000H) MOD 256;
  113. a := a MOD 800000H + 800000H;
  114. b := b MOD 800000H + 800000H;
  115. d := e - t;
  116. IF (d > 0) OR (d = 0) & (a >= b) THEN
  117. s := 0
  118. ELSE
  119. e := t;
  120. d := -d;
  121. t := a;
  122. a := b;
  123. b := t;
  124. s := 80000000H
  125. END;
  126. IF d > 0 THEN
  127. IF d < 24 THEN
  128. b := LSR(b, d)
  129. ELSE
  130. b := 0
  131. END
  132. END;
  133. DEC(a, b);
  134. IF a = 0 THEN
  135. e := 0;
  136. a := 800000H;
  137. s := 0
  138. ELSE
  139. WHILE a < 800000H DO
  140. a := a * 2;
  141. DEC(e)
  142. END
  143. END;
  144. IF e <= 0 THEN
  145. e := 0;
  146. a := 800000H;
  147. s := 0
  148. END
  149. RETURN (a - 800000H) + e * 800000H + s
  150. END sub2;
  151. PROCEDURE zero (VAR x: INTEGER);
  152. BEGIN
  153. IF LSR(LSL(x, 1), 24) = 0 THEN
  154. x := 0
  155. END
  156. END zero;
  157. PROCEDURE isNaN (a: INTEGER): BOOLEAN;
  158. RETURN (a > INF) OR (a < 0) & (a > NINF)
  159. END isNaN;
  160. PROCEDURE isInf (a: INTEGER): BOOLEAN;
  161. RETURN LSL(a, 1) = 0FF000000H
  162. END isInf;
  163. PROCEDURE isNormal (a, b: INTEGER): BOOLEAN;
  164. RETURN (LSR(LSL(a, 1), 24) # 255) & (LSR(LSL(a, 1), 24) # 0) &
  165. (LSR(LSL(b, 1), 24) # 255) & (LSR(LSL(b, 1), 24) # 0)
  166. END isNormal;
  167. PROCEDURE add* (b, a: INTEGER): INTEGER;
  168. VAR
  169. r: INTEGER;
  170. BEGIN
  171. zero(a); zero(b);
  172. IF isNormal(a, b) THEN
  173. IF a > 0 THEN
  174. IF b > 0 THEN
  175. r := add2(b, a)
  176. ELSE
  177. r := sub2(b, a)
  178. END
  179. ELSE
  180. IF b > 0 THEN
  181. r := sub2(a, b)
  182. ELSE
  183. r := add2(b, a) + 80000000H
  184. END
  185. END
  186. ELSIF isNaN(a) OR isNaN(b) THEN
  187. r := NAN
  188. ELSIF isInf(a) & isInf(b) THEN
  189. IF a = b THEN
  190. r := a
  191. ELSE
  192. r := NAN
  193. END
  194. ELSIF isInf(a) THEN
  195. r := a
  196. ELSIF isInf(b) THEN
  197. r := b
  198. ELSIF a = 0 THEN
  199. r := b
  200. ELSIF b = 0 THEN
  201. r := a
  202. END
  203. RETURN r
  204. END add;
  205. PROCEDURE sub* (b, a: INTEGER): INTEGER;
  206. VAR
  207. r: INTEGER;
  208. BEGIN
  209. zero(a); zero(b);
  210. IF isNormal(a, b) THEN
  211. IF a > 0 THEN
  212. IF b > 0 THEN
  213. r := sub2(b, a)
  214. ELSE
  215. r := add2(b, a)
  216. END
  217. ELSE
  218. IF b > 0 THEN
  219. r := add2(b, a) + 80000000H
  220. ELSE
  221. r := sub2(a, b)
  222. END
  223. END
  224. ELSIF isNaN(a) OR isNaN(b) THEN
  225. r := NAN
  226. ELSIF isInf(a) & isInf(b) THEN
  227. IF a # b THEN
  228. r := a
  229. ELSE
  230. r := NAN
  231. END
  232. ELSIF isInf(a) THEN
  233. r := a
  234. ELSIF isInf(b) THEN
  235. r := INF + ORD(BITS(b) / {31} - {0..30})
  236. ELSIF (a = 0) & (b = 0) THEN
  237. r := 0
  238. ELSIF a = 0 THEN
  239. r := ORD(BITS(b) / {31})
  240. ELSIF b = 0 THEN
  241. r := a
  242. END
  243. RETURN r
  244. END sub;
  245. PROCEDURE mul* (b, a: INTEGER): INTEGER;
  246. VAR
  247. r: INTEGER;
  248. BEGIN
  249. zero(a); zero(b);
  250. IF isNormal(a, b) THEN
  251. r := mul2(b, a)
  252. ELSIF isNaN(a) OR isNaN(b) OR (isInf(a) & (b = 0)) OR (isInf(b) & (a = 0)) THEN
  253. r := NAN
  254. ELSIF isInf(a) OR isInf(b) THEN
  255. r := INF + ORD(BITS(a) / BITS(b) - {0..30})
  256. ELSIF (a = 0) OR (b = 0) THEN
  257. r := 0
  258. END
  259. RETURN r
  260. END mul;
  261. PROCEDURE _div* (b, a: INTEGER): INTEGER;
  262. VAR
  263. r: INTEGER;
  264. BEGIN
  265. zero(a); zero(b);
  266. IF isNormal(a, b) THEN
  267. r := div2(b, a)
  268. ELSIF isNaN(a) OR isNaN(b) OR isInf(a) & isInf(b) THEN
  269. r := NAN
  270. ELSIF isInf(a) THEN
  271. r := INF + ORD(BITS(a) / BITS(b) - {0..30})
  272. ELSIF isInf(b) THEN
  273. r := 0
  274. ELSIF a = 0 THEN
  275. IF b = 0 THEN
  276. r := NAN
  277. ELSE
  278. r := 0
  279. END
  280. ELSIF b = 0 THEN
  281. IF a > 0 THEN
  282. r := INF
  283. ELSE
  284. r := NINF
  285. END
  286. END
  287. RETURN r
  288. END _div;
  289. PROCEDURE cmp* (op, b, a: INTEGER): BOOLEAN;
  290. VAR
  291. res: BOOLEAN;
  292. BEGIN
  293. zero(a); zero(b);
  294. IF isNaN(a) OR isNaN(b) THEN
  295. res := op = 1
  296. ELSE
  297. IF (a < 0) & (b < 0) THEN
  298. INC(op, 6)
  299. END;
  300. CASE op OF
  301. |0, 6: res := a = b
  302. |1, 7: res := a # b
  303. |2, 10: res := a < b
  304. |3, 11: res := a <= b
  305. |4, 8: res := a > b
  306. |5, 9: res := a >= b
  307. END
  308. END
  309. RETURN res
  310. END cmp;
  311. PROCEDURE flt* (x: INTEGER): INTEGER;
  312. VAR
  313. n, y, s: INTEGER;
  314. BEGIN
  315. IF x = 0 THEN
  316. s := 0;
  317. x := 800000H;
  318. n := -126
  319. ELSIF x = 80000000H THEN
  320. s := 80000000H;
  321. x := 800000H;
  322. n := 32
  323. ELSE
  324. IF x < 0 THEN
  325. s := 80000000H;
  326. x := -x
  327. ELSE
  328. s := 0
  329. END;
  330. n := 0;
  331. y := x;
  332. WHILE y > 0 DO
  333. y := y DIV 2;
  334. INC(n)
  335. END;
  336. IF n > 24 THEN
  337. x := LSR(x, n - 24)
  338. ELSE
  339. x := LSL(x, 24 - n)
  340. END
  341. END
  342. RETURN (x - 800000H) + (n + 126) * 800000H + s
  343. END flt;
  344. PROCEDURE floor* (x: INTEGER): INTEGER;
  345. VAR
  346. r, e: INTEGER;
  347. BEGIN
  348. zero(x);
  349. e := (x DIV 800000H) MOD 256 - 127;
  350. r := x MOD 800000H + 800000H;
  351. IF (0 <= e) & (e <= 22) THEN
  352. r := LSR(r, 23 - e) + ORD((x < 0) & (LSL(r, e + 9) # 0))
  353. ELSIF (23 <= e) & (e <= 54) THEN
  354. r := LSL(r, e - 23)
  355. ELSIF (e < 0) & (x < 0) THEN
  356. r := 1
  357. ELSE
  358. r := 0
  359. END;
  360. IF x < 0 THEN
  361. r := -r
  362. END
  363. RETURN r
  364. END floor;
  365. END FPU.