floatmgr.pp 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940
  1. {$MACRO ON}
  2. (******************************************************************************
  3. *
  4. * Copyright (c) 1996-2000 Palm, Inc. or its subsidiaries.
  5. * All rights reserved.
  6. *
  7. * File: FloatMgr.h
  8. *
  9. * Release: Palm OS SDK 4.0 (63220)
  10. *
  11. * Description:
  12. * New Floating point routines, provided by new IEEE arithmetic
  13. * 68K software floating point emulator (sfpe) code.
  14. *
  15. * History:
  16. * 9/23/96 - Created by SCL
  17. * 11/15/96 - First build of NewFloatMgr.lib
  18. * 11/26/96 - Added FlpCorrectedAdd and FlpCorrectedSub routines
  19. * 12/30/96 - Added FlpVersion routine
  20. * 2/ 4/97 - Fixed FlpDoubleBits definition - sign & exp now Int32s
  21. * so total size of FlpCompDouble is 64 bits, not 96.
  22. * 2/ 5/97 - Added note about FlpBase10Info reporting "negative" zero.
  23. * 7/21/99 - Renamed NewFloatMgr.h to FloatMgr.h.
  24. *
  25. *****************************************************************************)
  26. unit floatmgr;
  27. interface
  28. uses palmos, coretraps, errorbase;
  29. (************************************************************************
  30. * Differences between FloatMgr (PalmOS v1.0) and (this) NewFloatMgr
  31. ***********************************************************************)
  32. //
  33. // FloatMgr (PalmOS v1.0) NewFloatMgr
  34. // ---------------------- ---------------------------------------------
  35. // FloatType (64-bits) use FlpFloat (32-bits) or FlpDouble (64-bits)
  36. //
  37. // fplErrOutOfRange use _fp_get_fpscr() to retrieve errors
  38. //
  39. // FplInit() not necessary
  40. // FplFree() not necessary
  41. //
  42. // FplFToA() use FlpFToA()
  43. // FplAToF() use FlpAToF()
  44. // FplBase10Info() use FlpBase10Info() [*signP returns sign BIT: 1 if negative]
  45. //
  46. // FplLongToFloat() use _f_itof() or _d_itod()
  47. // FplFloatToLong() use _f_ftoi() or _d_dtoi()
  48. // FplFloatToULong() use _f_ftou() or _d_dtou()
  49. //
  50. // FplMul() use _f_mul() or _d_mul()
  51. // FplAdd() use _f_add() or _d_add()
  52. // FplSub() use _f_sub() or _d_sub()
  53. // FplDiv() use _f_div() or _d_div()
  54. (************************************************************************
  55. * New Floating point manager constants
  56. ***********************************************************************)
  57. const
  58. flpVersion_ = $02008000; // first version of NewFloatMgr (PalmOS 2.0)
  59. (*
  60. * These constants are passed to and received from the _fp_round routine.
  61. *)
  62. flpToNearest = 0;
  63. flpTowardZero = 1;
  64. flpUpward = 3;
  65. flpDownward = 2;
  66. flpModeMask = $00000030;
  67. flpModeShift = 4;
  68. (*
  69. * These masks define the fpscr bits supported by the sfpe (software floating point emulator).
  70. * These constants are used with the _fp_get_fpscr and _fp_set_fpscr routines.
  71. *)
  72. flpInvalid = $00008000;
  73. flpOverflow = $00004000;
  74. flpUnderflow = $00002000;
  75. flpDivByZero = $00001000;
  76. flpInexact = $00000800;
  77. (*
  78. * These constants are returned by _d_cmp, _d_cmpe, _f_cmp, and _f_cmpe:
  79. *)
  80. flpEqual = 0;
  81. flpLess = 1;
  82. flpGreater = 2;
  83. flpUnordered = 3;
  84. (************************************************************************
  85. * New Floating point manager types (private)
  86. ***********************************************************************)
  87. type
  88. _sfpe_64_bits = record // for internal use only
  89. high: Int32;
  90. low: Int32;
  91. end;
  92. sfpe_long_long = _sfpe_64_bits; // for internal use only
  93. sfpe_unsigned_long_long = _sfpe_64_bits; // for internal use only
  94. (************************************************************************
  95. * New Floating point manager types (public)
  96. ***********************************************************************)
  97. FlpFloat = Single; //Int32;
  98. FlpDouble = Double; //_sfpe_64_bits;
  99. FlpLongDouble = _sfpe_64_bits;
  100. (*
  101. * A double value comprises the fields:
  102. * 0x80000000 0x00000000 -- sign bit (1 for negative)
  103. * 0x7ff00000 0x00000000 -- exponent, biased by 0x3ff == 1023
  104. * 0x000fffff 0xffffffff -- significand == the fraction after an implicit "1."
  105. * So a double has the mathematical form:
  106. * (-1)^sign_bit * 2^(exponent - bias) * 1.significand
  107. * What follows are some structures (and macros) useful for decomposing numbers.
  108. *)
  109. FlpDoubleBits = record // for accessing specific fields
  110. Bits1: UInt32;
  111. {
  112. UInt32 sign: 1;
  113. Int32 exp : 11;
  114. UInt32 manH: 20;
  115. }
  116. ManL: UInt32;
  117. end;
  118. (*!!!
  119. typedef union {
  120. double d; // for easy assignment of values
  121. FlpDouble fd; // for calling New Floating point manager routines
  122. UInt32 ul[2]; // for accessing upper and lower longs
  123. FlpDoubleBits fdb; // for accessing specific fields
  124. } FlpCompDouble;
  125. typedef union {
  126. float f; // for easy assignment of values
  127. FlpFloat ff; // for calling New Floating point manager routines
  128. UInt32 ul; // for accessing bits of the float
  129. } FlpCompFloat;
  130. !!!*)
  131. (************************************************************************
  132. * Useful macros...
  133. ***********************************************************************)
  134. {
  135. #define BIG_ENDIAN 1
  136. #define __FIRST32(x) *((UInt32 *) &x)
  137. #define __SECOND32(x) *((UInt32 *) &x + 1)
  138. #define __ALL32(x) *((UInt32 *) &x)
  139. #ifdef LITTLE_ENDIAN
  140. #define __LO32(x) *((UInt32 *) &x)
  141. #define __HI32(x) *((UInt32 *) &x + 1)
  142. #define __HIX 1
  143. #define __LOX 0
  144. #else
  145. #define __HI32(x) *((UInt32 *) &x)
  146. #define __LO32(x) *((UInt32 *) &x + 1)
  147. #define __HIX 0
  148. #define __LOX 1
  149. #endif
  150. #define FlpGetSign(x) ((__HI32(x) & 0x80000000) != 0)
  151. #define FlpIsZero(x) ( ((__HI32(x) & 0x7fffffff) | (__LO32(x))) == 0)
  152. #define FlpGetExponent(x) (((__HI32(x) & 0x7ff00000) >> 20) - 1023)
  153. #define FlpNegate(x) (((FlpCompDouble *)&x)->ul[__HIX] ^= 0x80000000)
  154. #define FlpSetNegative(x) (((FlpCompDouble *)&x)->ul[__HIX] |= 0x80000000)
  155. #define FlpSetPositive(x) (((FlpCompDouble *)&x)->ul[__HIX] &= ~0x80000000)
  156. }
  157. (*******************************************************************
  158. * New Floating point manager errors
  159. * The constant fplErrorClass is defined in SystemMgr.h
  160. *******************************************************************)
  161. const
  162. flpErrOutOfRange = flpErrorClass or 1;
  163. (************************************************************
  164. * New Floating point manager trap macros
  165. *************************************************************)
  166. (************************************************************
  167. * New Floating point manager selectors
  168. *************************************************************)
  169. type
  170. sysFloatSelector = Enum; // The order of this enum *MUST* match the
  171. // corresponding table in NewFloatDispatch.c
  172. const
  173. sysFloatBase10Info = 0; // 0
  174. sysFloatFToA = Succ(sysFloatBase10Info); // 1
  175. sysFloatAToF = Succ(sysFloatFToA); // 2
  176. sysFloatCorrectedAdd = Succ(sysFloatAToF); // 3
  177. sysFloatCorrectedSub = Succ(sysFloatCorrectedAdd); // 4
  178. sysFloatVersion = Succ(sysFloatCorrectedSub); // 5
  179. flpMaxFloatSelector = sysFloatVersion; // used by NewFloatDispatch.c
  180. type
  181. sysFloatEmSelector = Enum; // The order of this enum *MUST* match the
  182. // sysFloatSelector table in NewFloatDispatch.c
  183. const
  184. sysFloatEm_fp_round = 0; // 0
  185. sysFloatEm_fp_get_fpscr = Succ(sysFloatEm_fp_round); // 1
  186. sysFloatEm_fp_set_fpscr = Succ(sysFloatEm_fp_get_fpscr); // 2
  187. sysFloatEm_f_utof = Succ(sysFloatEm_fp_set_fpscr); // 3
  188. sysFloatEm_f_itof = Succ(sysFloatEm_f_utof); // 4
  189. sysFloatEm_f_ulltof = Succ(sysFloatEm_f_itof); // 5
  190. sysFloatEm_f_lltof = Succ(sysFloatEm_f_ulltof); // 6
  191. sysFloatEm_d_utod = Succ(sysFloatEm_f_lltof); // 7
  192. sysFloatEm_d_itod = Succ(sysFloatEm_d_utod); // 8
  193. sysFloatEm_d_ulltod = Succ(sysFloatEm_d_itod); // 9
  194. sysFloatEm_d_lltod = Succ(sysFloatEm_d_ulltod); // 10
  195. sysFloatEm_f_ftod = Succ(sysFloatEm_d_lltod); // 11
  196. sysFloatEm_d_dtof = Succ(sysFloatEm_f_ftod); // 12
  197. sysFloatEm_f_ftoq = Succ(sysFloatEm_d_dtof); // 13
  198. sysFloatEm_f_qtof = Succ(sysFloatEm_f_ftoq); // 14
  199. sysFloatEm_d_dtoq = Succ(sysFloatEm_f_qtof); // 15
  200. sysFloatEm_d_qtod = Succ(sysFloatEm_d_dtoq); // 16
  201. sysFloatEm_f_ftou = Succ(sysFloatEm_d_qtod); // 17
  202. sysFloatEm_f_ftoi = Succ(sysFloatEm_f_ftou); // 18
  203. sysFloatEm_f_ftoull = Succ(sysFloatEm_f_ftoi); // 19
  204. sysFloatEm_f_ftoll = Succ(sysFloatEm_f_ftoull); // 20
  205. sysFloatEm_d_dtou = Succ(sysFloatEm_f_ftoll); // 21
  206. sysFloatEm_d_dtoi = Succ(sysFloatEm_d_dtou); // 22
  207. sysFloatEm_d_dtoull = Succ(sysFloatEm_d_dtoi); // 23
  208. sysFloatEm_d_dtoll = Succ(sysFloatEm_d_dtoull); // 24
  209. sysFloatEm_f_cmp = Succ(sysFloatEm_d_dtoll); // 25
  210. sysFloatEm_f_cmpe = Succ(sysFloatEm_f_cmp); // 26
  211. sysFloatEm_f_feq = Succ(sysFloatEm_f_cmpe); // 27
  212. sysFloatEm_f_fne = Succ(sysFloatEm_f_feq); // 28
  213. sysFloatEm_f_flt = Succ(sysFloatEm_f_fne); // 29
  214. sysFloatEm_f_fle = Succ(sysFloatEm_f_flt); // 30
  215. sysFloatEm_f_fgt = Succ(sysFloatEm_f_fle); // 31
  216. sysFloatEm_f_fge = Succ(sysFloatEm_f_fgt); // 32
  217. sysFloatEm_f_fun = Succ(sysFloatEm_f_fge); // 33
  218. sysFloatEm_f_for = Succ(sysFloatEm_f_fun); // 34
  219. sysFloatEm_d_cmp = Succ(sysFloatEm_f_for); // 35
  220. sysFloatEm_d_cmpe = Succ(sysFloatEm_d_cmp); // 36
  221. sysFloatEm_d_feq = Succ(sysFloatEm_d_cmpe); // 37
  222. sysFloatEm_d_fne = Succ(sysFloatEm_d_feq); // 38
  223. sysFloatEm_d_flt = Succ(sysFloatEm_d_fne); // 39
  224. sysFloatEm_d_fle = Succ(sysFloatEm_d_flt); // 40
  225. sysFloatEm_d_fgt = Succ(sysFloatEm_d_fle); // 41
  226. sysFloatEm_d_fge = Succ(sysFloatEm_d_fgt); // 42
  227. sysFloatEm_d_fun = Succ(sysFloatEm_d_fge); // 43
  228. sysFloatEm_d_for = Succ(sysFloatEm_d_fun); // 44
  229. sysFloatEm_f_neg = Succ(sysFloatEm_d_for); // 45
  230. sysFloatEm_f_add = Succ(sysFloatEm_f_neg); // 46
  231. sysFloatEm_f_mul = Succ(sysFloatEm_f_add); // 47
  232. sysFloatEm_f_sub = Succ(sysFloatEm_f_mul); // 48
  233. sysFloatEm_f_div = Succ(sysFloatEm_f_sub); // 49
  234. sysFloatEm_d_neg = Succ(sysFloatEm_f_div); // 50
  235. sysFloatEm_d_add = Succ(sysFloatEm_d_neg); // 51
  236. sysFloatEm_d_mul = Succ(sysFloatEm_d_add); // 52
  237. sysFloatEm_d_sub = Succ(sysFloatEm_d_mul); // 53
  238. sysFloatEm_d_div = Succ(sysFloatEm_d_sub); // 54
  239. (************************************************************
  240. * New Floating point manager routines
  241. *************************************************************)
  242. // Note: FlpBase10Info returns the actual sign bit in *signP (1 if negative)
  243. // Note: FlpBase10Info reports that zero is "negative".
  244. // A workaround is to check (*signP && *mantissaP) instead of just *signP.
  245. function FlpBase10Info(a: FlpDouble; var mantissaP: UInt32; var exponentP, signP: Int16): Err;
  246. function FlpFToA(a: FlpDouble; s: PChar): Err;
  247. function FlpAToF(const s: PChar): FlpDouble;
  248. function FlpCorrectedAdd(firstOperand, secondOperand: FlpDouble; howAccurate: Int16): FlpDouble;
  249. function FlpCorrectedSub(firstOperand, secondOperand: FlpDouble; howAccurate: Int16): FlpDouble;
  250. // These next three functions correspond to the previous three above.
  251. // The signatures are different, but in fact with CodeWarrior for Palm OS
  252. // the structure return values above are implemented via a hidden pointer
  253. // parameter, so corresponding functions are binary compatible. Programs
  254. // using CodeWarrior to target m68k Palm OS can use either function
  255. // interchangeably.
  256. //
  257. // However, a description of the handling of structure return values is
  258. // missing from the defined Palm OS ABI, and m68k-palmos-gcc does it
  259. // differently. So programs compiled with GCC using the standard functions
  260. // above are likely to crash: GCC users must use the FlpBuffer* forms of
  261. // these functions.
  262. //
  263. // The FlpBuffer* functions are not available on the Simulator, so you need
  264. // to use the standard versions above if you want Simulator compatibility.
  265. //
  266. // Many of the _d_* functions further below suffer from the same problem.
  267. // This is not an issue, because programs targeting Palm OS devices can use
  268. // operators (+ - * / etc) instead of calling these functions directly.
  269. // (GCC users may wish to use -lnfm -- see the documentation for details.)
  270. //
  271. // See the SDK's SampleCalc example for further discussion.
  272. procedure FlpBufferAToF(var result: FlpDouble; const s: PChar);
  273. procedure FlpBufferCorrectedAdd(var result: FlpDouble; firstOperand, secondOperand: FlpDouble; howAccurate: Int16);
  274. procedure FlpBufferCorrectedSub(var result: FlpDouble; firstOperand, secondOperand: FlpDouble; howAccurate: Int16);
  275. function FlpVersion: UInt32;
  276. //procedure FlpSelectorErrPrv(flpSelector: UInt16); // used only by NewFloatDispatch.c
  277. // The following macros could be useful but are left undefined due to the
  278. // confusion they might cause. What was called a "float" in PalmOS v1.0 was
  279. // really a 64-bit; in v2.0 "float" is only 32-bits and "double" is 64-bits.
  280. // However, if a v1.0 program is converted to use the NewFloatMgr, these
  281. // macros could be re-defined, or the native _d_ routines could be called.
  282. //#define FlpLongToFloat(x) _d_itod(x) // similar to 1.0 call, but returns double
  283. //#define FlpFloatToLong(f) _d_dtoi(f) // similar to 1.0 call, but takes a double
  284. //#define FlpFloatToULong(f) _d_dtou(f) // similar to 1.0 call, but takes a double
  285. (************************************************************
  286. * New Floating point emulator functions
  287. *************************************************************)
  288. (*
  289. * These three functions define the interface to the (software) fpscr
  290. * of the sfpe. _fp_round not only sets the rounding mode according
  291. * the low two bits of its argument, but it also returns those masked
  292. * two bits. This provides some hope of compatibility with less capable
  293. * emulators, which support only rounding to nearest. A programmer
  294. * concerned about getting the rounding mode requested can test the
  295. * return value from _fp_round; it will indicate what the current mode is.
  296. *
  297. * Constants passed to and received from _fp_round are:
  298. * flpToNearest, flpTowardZero, flpUpward, or flpDownward
  299. *)
  300. function _fp_round(Value: Int32): Int32;
  301. (*
  302. * Constants passed to _fp_set_fpscr and received from _fp_get_fpscr are:
  303. * flpInvalid, flpOverflow, flpUnderflow, flpDivByZero, or flpInexact
  304. *)
  305. function _fp_get_fpscr: Int32;
  306. procedure _fp_set_fpscr(Value: Int32);
  307. (*
  308. * The shorthand here can be determined from the context:
  309. * i --> long (Int32)
  310. * u --> UInt32 (UInt32)
  311. * ll --> long long int
  312. * ull --> UInt32 long int
  313. * f --> float
  314. * d --> double
  315. * q --> long double (defaults to double in this implementaton)
  316. * XtoY--> map of type X to a value of type Y
  317. *)
  318. function _f_utof(Value: UInt32): FlpFloat;
  319. function _f_itof(Value: Int32): FlpFloat;
  320. //!!!function _f_ulltof(Value: sfpe_unsigned_long_long): FlpFloat; syscall sysTrapFlpEmDispatch, sysFloatEm_f_ulltof;
  321. //!!!function _f_lltof(Value: sfpe_long_long): FlpFloat; syscall sysTrapFlpEmDispatch, sysFloatEm_f_lltof;
  322. function _d_utod(Value: UInt32): FlpDouble;
  323. function _d_itod(Value: Int32): FlpDouble;
  324. //!!!function _d_ulltod(Value: sfpe_unsigned_long_long): FlpDouble; syscall sysTrapFlpEmDispatch, sysFloatEm_d_ulltod;
  325. //!!!function _d_lltod(Value: sfpe_long_long): FlpDouble; syscall sysTrapFlpEmDispatch, sysFloatEm_d_lltod;
  326. function _f_ftod(Value: FlpFloat): FlpDouble;
  327. function _d_dtof(Value: FlpDouble): FlpFloat;
  328. //!!!function _f_ftoq(Value: FlpFloat): FlpLongDouble; syscall sysTrapFlpEmDispatch, sysFloatEm_f_ftoq;
  329. function _f_qtof(var Value: FlpLongDouble): FlpFloat;
  330. //!!!function _d_dtoq(Value: FlpDouble): FlpLongDouble; syscall sysTrapFlpEmDispatch, sysFloatEm_d_dtoq;
  331. //!!!function _d_qtod(var Value: FlpLongDouble): FlpDouble; syscall sysTrapFlpEmDispatch, sysFloatEm_d_qtod;
  332. function _f_ftou(Value: FlpFloat): UInt32;
  333. function _f_ftoi(Value: FlpFloat): Int32;
  334. //!!!function _f_ftoull(Value: FlpFloat): sfpe_unsigned_long_long; syscall sysTrapFlpEmDispatch, sysFloatEm_f_ftoull;
  335. //!!!function _f_ftoll(Value: FlpFloat): sfpe_long_long; syscall sysTrapFlpEmDispatch, sysFloatEm_f_ftoll;
  336. function _d_dtou(Value: FlpDouble): UInt32;
  337. function _d_dtoi(Value: FlpDouble): Int32;
  338. //!!!function _d_dtoull(Value: FlpDouble): sfpe_unsigned_long_long; syscall sysTrapFlpEmDispatch, sysFloatEm_d_dtoull;
  339. //!!!function _d_dtoll(Value: FlpDouble): sfpe_long_long; syscall sysTrapFlpEmDispatch, sysFloatEm_d_dtoll;
  340. (*
  341. * The comparison functions _T_Tcmp[e] compare their two arguments,
  342. * of type T, and return one of the four values defined below.
  343. * The functions _d_dcmpe and _f_fcmpe, in addition to returning
  344. * the comparison code, also set the invalid flag in the fpscr if
  345. * the operands are unordered. Two floating point values are unordered
  346. * when they enjoy no numerical relationship, as is the case when one
  347. * or both are NaNs.
  348. *
  349. * Return values for _d_cmp, _d_cmpe, _f_cmp, and _f_cmpe are:
  350. * flpEqual, flpLess, flpGreater, or flpUnordered
  351. *
  352. * The function shorthand is:
  353. * eq --> equal
  354. * ne --> not equal
  355. * lt --> less than
  356. * le --> less than or equal to
  357. * gt --> greater than
  358. * ge --> greater than or equal to
  359. * un --> unordered with
  360. * or --> ordered with (i.e. less than, equal to, or greater than)
  361. *)
  362. function _f_cmp(Left: FlpFloat; Right: FlpFloat): Int32;
  363. function _f_cmpe(Left: FlpFloat; Right: FlpFloat): Int32;
  364. function _f_feq(Left: FlpFloat; Right: FlpFloat): Int32;
  365. function _f_fne(Left: FlpFloat; Right: FlpFloat): Int32;
  366. function _f_flt(Left: FlpFloat; Right: FlpFloat): Int32;
  367. function _f_fle(Left: FlpFloat; Right: FlpFloat): Int32;
  368. function _f_fgt(Left: FlpFloat; Right: FlpFloat): Int32;
  369. function _f_fge(Left: FlpFloat; Right: FlpFloat): Int32;
  370. function _f_fun(Left: FlpFloat; Right: FlpFloat): Int32;
  371. function _f_for(Left: FlpFloat; Right: FlpFloat): Int32;
  372. function _d_cmp(Left: FlpDouble; Right: FlpDouble): Int32;
  373. function _d_cmpe(Left: FlpDouble; Right: FlpDouble): Int32;
  374. function _d_feq(Left: FlpDouble; Right: FlpDouble): Int32;
  375. function _d_fne(Left: FlpDouble; Right: FlpDouble): Int32;
  376. function _d_flt(Left: FlpDouble; Right: FlpDouble): Int32;
  377. function _d_fle(Left: FlpDouble; Right: FlpDouble): Int32;
  378. function _d_fgt(Left: FlpDouble; Right: FlpDouble): Int32;
  379. function _d_fge(Left: FlpDouble; Right: FlpDouble): Int32;
  380. function _d_fun(Left: FlpDouble; Right: FlpDouble): Int32;
  381. function _d_for(Left: FlpDouble; Right: FlpDouble): Int32;
  382. function _f_neg(Value: FlpFloat): FlpFloat;
  383. function _f_add(Left: FlpFloat; Right: FlpFloat): FlpFloat;
  384. function _f_mul(Left: FlpFloat; Right: FlpFloat): FlpFloat;
  385. function _f_sub(Left: FlpFloat; Right: FlpFloat): FlpFloat;
  386. function _f_div(Left: FlpFloat; Right: FlpFloat): FlpFloat;
  387. function _d_neg(Value: FlpDouble): FlpDouble;
  388. function _d_add(Left: FlpDouble; Right: FlpDouble): FlpDouble;
  389. function _d_mul(Left: FlpDouble; Right: FlpDouble): FlpDouble;
  390. function _d_sub(Left: FlpDouble; Right: FlpDouble): FlpDouble;
  391. function _d_div(Left: FlpDouble; Right: FlpDouble): FlpDouble;
  392. implementation
  393. function __FlpBase10Info(a: FlpDouble; var mantissaP: UInt32; var exponentP, signP: Int16): Err; syscall sysTrapFlpDispatch;
  394. function __FlpFToA(a: FlpDouble; s: PChar): Err; syscall sysTrapFlpDispatch;
  395. function __FlpAToF(const s: PChar): FlpDouble; syscall sysTrapFlpDispatch;
  396. function __FlpCorrectedAdd(firstOperand, secondOperand: FlpDouble; howAccurate: Int16): FlpDouble; syscall sysTrapFlpDispatch;
  397. function __FlpCorrectedSub(firstOperand, secondOperand: FlpDouble; howAccurate: Int16): FlpDouble; syscall sysTrapFlpDispatch;
  398. procedure __FlpBufferAToF(var result: FlpDouble; const s: PChar); syscall sysTrapFlpDispatch;
  399. procedure __FlpBufferCorrectedAdd(var result: FlpDouble; firstOperand, secondOperand: FlpDouble; howAccurate: Int16); syscall sysTrapFlpDispatch;
  400. procedure __FlpBufferCorrectedSub(var result: FlpDouble; firstOperand, secondOperand: FlpDouble; howAccurate: Int16); syscall sysTrapFlpDispatch;
  401. function __FlpVersion: UInt32; syscall sysTrapFlpDispatch;
  402. function ___fp_round(Value: Int32): Int32; syscall sysTrapFlpEmDispatch;
  403. function ___fp_get_fpscr: Int32; syscall sysTrapFlpEmDispatch;
  404. procedure ___fp_set_fpscr(Value: Int32); syscall sysTrapFlpEmDispatch;
  405. function ___f_utof(Value: UInt32): FlpFloat; syscall sysTrapFlpEmDispatch;
  406. function ___f_itof(Value: Int32): FlpFloat; syscall sysTrapFlpEmDispatch;
  407. function ___d_utod(Value: UInt32): FlpDouble; syscall sysTrapFlpEmDispatch;
  408. function ___d_itod(Value: Int32): FlpDouble; syscall sysTrapFlpEmDispatch;
  409. function ___f_ftod(Value: FlpFloat): FlpDouble; syscall sysTrapFlpEmDispatch;
  410. function ___d_dtof(Value: FlpDouble): FlpFloat; syscall sysTrapFlpEmDispatch;
  411. function ___f_qtof(var Value: FlpLongDouble): FlpFloat; syscall sysTrapFlpEmDispatch;
  412. function ___f_ftou(Value: FlpFloat): UInt32; syscall sysTrapFlpEmDispatch;
  413. function ___f_ftoi(Value: FlpFloat): Int32; syscall sysTrapFlpEmDispatch;
  414. function ___d_dtou(Value: FlpDouble): UInt32; syscall sysTrapFlpEmDispatch;
  415. function ___d_dtoi(Value: FlpDouble): Int32; syscall sysTrapFlpEmDispatch;
  416. function FlpBase10Info(a: FlpDouble; var mantissaP: UInt32; var exponentP, signP: Int16): Err;
  417. begin
  418. asm
  419. move.l #$sysFloatBase10Info, D2;
  420. end;
  421. FlpBase10Info := __FlpBase10Info(a, mantissaP, exponentP, signP);
  422. end;
  423. function FlpFToA(a: FlpDouble; s: PChar): Err;
  424. begin
  425. asm
  426. move.l #$sysFloatFToA, D2;
  427. end;
  428. FlpFToA := __FlpFToA(a, s);
  429. end;
  430. function FlpAToF(const s: PChar): FlpDouble;
  431. begin
  432. asm
  433. move.l #$sysFloatAToF, D2
  434. end;
  435. FlpAToF := __FlpAToF(s);
  436. end;
  437. function FlpCorrectedAdd(firstOperand, secondOperand: FlpDouble; howAccurate: Int16): FlpDouble;
  438. begin
  439. asm
  440. move.l #$sysFloatCorrectedAdd, D2
  441. end;
  442. FlpCorrectedAdd := __FlpCorrectedAdd(firstOperand, secondOperand, howAccurate);
  443. end;
  444. function FlpCorrectedSub(firstOperand, secondOperand: FlpDouble; howAccurate: Int16): FlpDouble;
  445. begin
  446. asm
  447. move.l #$sysFloatCorrectedSub, D2;
  448. end;
  449. FlpCorrectedSub := __FlpCorrectedSub(firstOperand, secondOperand, howAccurate);
  450. end;
  451. procedure FlpBufferAToF(var result: FlpDouble; const s: PChar);
  452. begin
  453. asm
  454. move.l #$sysFloatAToF, D2;
  455. end;
  456. __FlpBufferAToF(result, s);
  457. end;
  458. procedure FlpBufferCorrectedAdd(var result: FlpDouble; firstOperand, secondOperand: FlpDouble; howAccurate: Int16);
  459. begin
  460. asm
  461. move.l #$sysFloatCorrectedAdd, D2;
  462. end;
  463. __FlpBufferCorrectedAdd(result, firstOperand, secondOperand, howAccurate);
  464. end;
  465. procedure FlpBufferCorrectedSub(var result: FlpDouble; firstOperand, secondOperand: FlpDouble; howAccurate: Int16);
  466. begin
  467. asm
  468. move.l #$sysFloatCorrectedSub, D2
  469. end;
  470. __FlpBufferCorrectedSub(result, firstOperand, secondOperand, howAccurate);
  471. end;
  472. function FlpVersion: UInt32;
  473. begin
  474. asm
  475. move.l #$sysFloatVersion, D2;
  476. end;
  477. FlpVersion := __FlpVersion;
  478. end;
  479. function _fp_round(Value: Int32): Int32;
  480. begin
  481. asm
  482. move.l #$sysFloatEm_fp_round, D2;
  483. end;
  484. _fp_round := ___fp_round(Value);
  485. end;
  486. function _fp_get_fpscr: Int32;
  487. begin
  488. asm
  489. move.l #$sysFloatEm_fp_get_fpscr, D2;
  490. end;
  491. _fp_get_fpscr := ___fp_get_fpscr;
  492. end;
  493. procedure _fp_set_fpscr(Value: Int32);
  494. begin
  495. asm
  496. move.l #$sysFloatEm_fp_set_fpscr, D2;
  497. end;
  498. ___fp_set_fpscr(Value);
  499. end;
  500. function _f_utof(Value: UInt32): FlpFloat;
  501. begin
  502. asm
  503. move.l #$sysFloatEm_f_utof, D2;
  504. end;
  505. _f_utof := ___f_utof(Value);
  506. end;
  507. function _f_itof(Value: Int32): FlpFloat;
  508. begin
  509. asm
  510. move.l #$sysFloatEm_f_itof, D2;
  511. end;
  512. _f_itof := ___f_itof(Value);
  513. end;
  514. function _d_utod(Value: UInt32): FlpDouble;
  515. begin
  516. asm
  517. move.l #$sysFloatEm_d_utod, D2;
  518. end;
  519. _d_utod := ___d_utod(Value);
  520. end;
  521. function _d_itod(Value: Int32): FlpDouble;
  522. begin
  523. asm
  524. move.l #$sysFloatEm_d_itod, D2;
  525. end;
  526. _d_itod := ___d_itod(Value);
  527. end;
  528. function _f_ftod(Value: FlpFloat): FlpDouble;
  529. begin
  530. asm
  531. move.l #$sysFloatEm_f_ftod, D2;
  532. end;
  533. _f_ftod := ___f_ftod(Value);
  534. end;
  535. function _d_dtof(Value: FlpDouble): FlpFloat;
  536. begin
  537. asm
  538. move.l #$sysFloatEm_d_dtof, D2;
  539. end;
  540. _d_dtof := ___d_dtof(Value);
  541. end;
  542. function _f_qtof(var Value: FlpLongDouble): FlpFloat;
  543. begin
  544. asm
  545. move.l #$sysFloatEm_f_qtof, D2;
  546. end;
  547. _f_qtof := ___f_qtof(Value);
  548. end;
  549. function _f_ftou(Value: FlpFloat): UInt32;
  550. begin
  551. asm
  552. move.l #$sysFloatEm_f_ftou, D2;
  553. end;
  554. _f_ftou := ___f_ftou(Value);
  555. end;
  556. function _f_ftoi(Value: FlpFloat): Int32;
  557. begin
  558. asm
  559. move.l #$sysFloatEm_f_ftoi, D2;
  560. end;
  561. _f_ftoi := ___f_ftoi(Value);
  562. end;
  563. function _d_dtou(Value: FlpDouble): UInt32;
  564. begin
  565. asm
  566. move.l #$sysFloatEm_d_dtou, D2;
  567. end;
  568. _d_dtou := ___d_dtou(Value);
  569. end;
  570. function _d_dtoi(Value: FlpDouble): Int32;
  571. begin
  572. asm
  573. move.l #$sysFloatEm_d_dtoi, D2;
  574. end;
  575. _d_dtoi := ___d_dtoi(Value);
  576. end;
  577. function ___f_cmp(Left: FlpFloat; Right: FlpFloat): Int32; syscall sysTrapFlpEmDispatch;
  578. function ___f_cmpe(Left: FlpFloat; Right: FlpFloat): Int32; syscall sysTrapFlpEmDispatch;
  579. function ___f_feq(Left: FlpFloat; Right: FlpFloat): Int32; syscall sysTrapFlpEmDispatch;
  580. function ___f_fne(Left: FlpFloat; Right: FlpFloat): Int32; syscall sysTrapFlpEmDispatch;
  581. function ___f_flt(Left: FlpFloat; Right: FlpFloat): Int32; syscall sysTrapFlpEmDispatch;
  582. function ___f_fle(Left: FlpFloat; Right: FlpFloat): Int32; syscall sysTrapFlpEmDispatch;
  583. function ___f_fgt(Left: FlpFloat; Right: FlpFloat): Int32; syscall sysTrapFlpEmDispatch;
  584. function ___f_fge(Left: FlpFloat; Right: FlpFloat): Int32; syscall sysTrapFlpEmDispatch;
  585. function ___f_fun(Left: FlpFloat; Right: FlpFloat): Int32; syscall sysTrapFlpEmDispatch;
  586. function ___f_for(Left: FlpFloat; Right: FlpFloat): Int32; syscall sysTrapFlpEmDispatch;
  587. function ___d_cmp(Left: FlpDouble; Right: FlpDouble): Int32; syscall sysTrapFlpEmDispatch;
  588. function ___d_cmpe(Left: FlpDouble; Right: FlpDouble): Int32; syscall sysTrapFlpEmDispatch;
  589. function ___d_feq(Left: FlpDouble; Right: FlpDouble): Int32; syscall sysTrapFlpEmDispatch;
  590. function ___d_fne(Left: FlpDouble; Right: FlpDouble): Int32; syscall sysTrapFlpEmDispatch;
  591. function ___d_flt(Left: FlpDouble; Right: FlpDouble): Int32; syscall sysTrapFlpEmDispatch;
  592. function ___d_fle(Left: FlpDouble; Right: FlpDouble): Int32; syscall sysTrapFlpEmDispatch;
  593. function ___d_fgt(Left: FlpDouble; Right: FlpDouble): Int32; syscall sysTrapFlpEmDispatch;
  594. function ___d_fge(Left: FlpDouble; Right: FlpDouble): Int32; syscall sysTrapFlpEmDispatch;
  595. function ___d_fun(Left: FlpDouble; Right: FlpDouble): Int32; syscall sysTrapFlpEmDispatch;
  596. function ___d_for(Left: FlpDouble; Right: FlpDouble): Int32; syscall sysTrapFlpEmDispatch;
  597. function ___f_neg(Value: FlpFloat): FlpFloat; syscall sysTrapFlpEmDispatch;
  598. function ___f_add(Left: FlpFloat; Right: FlpFloat): FlpFloat; syscall sysTrapFlpEmDispatch;
  599. function ___f_mul(Left: FlpFloat; Right: FlpFloat): FlpFloat; syscall sysTrapFlpEmDispatch;
  600. function ___f_sub(Left: FlpFloat; Right: FlpFloat): FlpFloat; syscall sysTrapFlpEmDispatch;
  601. function ___f_div(Left: FlpFloat; Right: FlpFloat): FlpFloat; syscall sysTrapFlpEmDispatch;
  602. function ___d_neg(Value: FlpDouble): FlpDouble; syscall sysTrapFlpEmDispatch;
  603. function ___d_add(Left: FlpDouble; Right: FlpDouble): FlpDouble; syscall sysTrapFlpEmDispatch;
  604. function ___d_mul(Left: FlpDouble; Right: FlpDouble): FlpDouble; syscall sysTrapFlpEmDispatch;
  605. function ___d_sub(Left: FlpDouble; Right: FlpDouble): FlpDouble; syscall sysTrapFlpEmDispatch;
  606. function ___d_div(Left: FlpDouble; Right: FlpDouble): FlpDouble; syscall sysTrapFlpEmDispatch;
  607. function _f_cmp(Left: FlpFloat; Right: FlpFloat): Int32;
  608. begin
  609. asm
  610. move.l #$sysFloatEm_f_cmp , D2
  611. end;
  612. _f_cmp := ___f_cmp(Left, Right);
  613. end;
  614. function _f_cmpe(Left: FlpFloat; Right: FlpFloat): Int32;
  615. begin
  616. asm
  617. move.l #$sysFloatEm_f_cmpe , D2
  618. end;
  619. _f_cmpe := ___f_cmpe(Left, Right);
  620. end;
  621. function _f_feq(Left: FlpFloat; Right: FlpFloat): Int32;
  622. begin
  623. asm
  624. move.l #$sysFloatEm_f_feq , D2
  625. end;
  626. _f_feq := ___f_feq(Left, Right);
  627. end;
  628. function _f_fne(Left: FlpFloat; Right: FlpFloat): Int32;
  629. begin
  630. asm
  631. move.l #$sysFloatEm_f_fne , D2
  632. end;
  633. _f_fne := ___f_fne(Left, Right);
  634. end;
  635. function _f_flt(Left: FlpFloat; Right: FlpFloat): Int32;
  636. begin
  637. asm
  638. move.l #$sysFloatEm_f_flt, D2;
  639. end;
  640. _f_flt := ___f_flt(Left, Right);
  641. end;
  642. function _f_fle(Left: FlpFloat; Right: FlpFloat): Int32;
  643. begin
  644. asm
  645. move.l #$sysFloatEm_f_fle, D2;
  646. end;
  647. _f_fle := ___f_fle(Left, Right);
  648. end;
  649. function _f_fgt(Left: FlpFloat; Right: FlpFloat): Int32;
  650. begin
  651. asm
  652. move.l #$sysFloatEm_f_fgt, D2;
  653. end;
  654. _f_fgt := ___f_fgt(Left, Right);
  655. end;
  656. function _f_fge(Left: FlpFloat; Right: FlpFloat): Int32;
  657. begin
  658. asm
  659. move.l #$sysFloatEm_f_fge, D2;
  660. end;
  661. _f_fge := ___f_fge(Left, Right);
  662. end;
  663. function _f_fun(Left: FlpFloat; Right: FlpFloat): Int32;
  664. begin
  665. asm
  666. move.l #$sysFloatEm_f_fun, D2;
  667. end;
  668. _f_fun := ___f_fun(Left, Right);
  669. end;
  670. function _f_for(Left: FlpFloat; Right: FlpFloat): Int32;
  671. begin
  672. asm
  673. move.l #$sysFloatEm_f_for, D2
  674. end;
  675. _f_for := ___f_for(Left, Right);
  676. end;
  677. function _d_cmp(Left: FlpDouble; Right: FlpDouble): Int32;
  678. begin
  679. asm
  680. move.l #$sysFloatEm_d_cmp, D2
  681. end;
  682. _d_cmp := ___d_cmp(Left, Right);
  683. end;
  684. function _d_cmpe(Left: FlpDouble; Right: FlpDouble): Int32;
  685. begin
  686. asm
  687. move.l #$sysFloatEm_d_cmpe, D2;
  688. end;
  689. _d_cmpe := ___d_cmpe(Left, Right);
  690. end;
  691. function _d_feq(Left: FlpDouble; Right: FlpDouble): Int32;
  692. begin
  693. asm
  694. move.l #$sysFloatEm_d_feq, D2;
  695. end;
  696. _d_feq := ___d_feq(Left, Right);
  697. end;
  698. function _d_fne(Left: FlpDouble; Right: FlpDouble): Int32;
  699. begin
  700. asm
  701. move.l #$sysFloatEm_d_fne, D2;
  702. end;
  703. _d_fne := ___d_fne(Left, Right);
  704. end;
  705. function _d_flt(Left: FlpDouble; Right: FlpDouble): Int32;
  706. begin
  707. asm
  708. move.l #$sysFloatEm_d_flt, D2;
  709. end;
  710. _d_flt := ___d_flt(Left, Right);
  711. end;
  712. function _d_fle(Left: FlpDouble; Right: FlpDouble): Int32;
  713. begin
  714. asm
  715. move.l #$sysFloatEm_d_fle, D2
  716. end;
  717. _d_fle := ___d_fle(Left, Right);
  718. end;
  719. function _d_fgt(Left: FlpDouble; Right: FlpDouble): Int32;
  720. begin
  721. asm
  722. move.l #$sysFloatEm_d_fgt, D2;
  723. end;
  724. _d_fgt := ___d_fgt(Left, Right);
  725. end;
  726. function _d_fge(Left: FlpDouble; Right: FlpDouble): Int32;
  727. begin
  728. asm
  729. move.l #$sysFloatEm_d_fge, D2;
  730. end;
  731. _d_fge := ___d_fge(Left, Right);
  732. end;
  733. function _d_fun(Left: FlpDouble; Right: FlpDouble): Int32;
  734. begin
  735. asm
  736. move.l #$sysFloatEm_d_fun, D2
  737. end;
  738. _d_fun := ___d_fun(Left, Right);
  739. end;
  740. function _d_for(Left: FlpDouble; Right: FlpDouble): Int32;
  741. begin
  742. asm
  743. move.l #$sysFloatEm_d_for, D2
  744. end;
  745. _d_for := ___d_for(Left, Right);
  746. end;
  747. function _f_neg(Value: FlpFloat): FlpFloat;
  748. begin
  749. asm
  750. move.l #$sysFloatEm_f_neg, D2;
  751. end;
  752. _f_neg := ___f_neg(Value);
  753. end;
  754. function _f_add(Left: FlpFloat; Right: FlpFloat): FlpFloat;
  755. begin
  756. asm
  757. move.l #$sysFloatEm_f_add, D2;
  758. end;
  759. _f_add := ___f_add(Left, Right);
  760. end;
  761. function _f_mul(Left: FlpFloat; Right: FlpFloat): FlpFloat;
  762. begin
  763. asm
  764. move.l #$sysFloatEm_f_mul, D2;
  765. end;
  766. _f_mul := ___f_mul(Left, Right);
  767. end;
  768. function _f_sub(Left: FlpFloat; Right: FlpFloat): FlpFloat;
  769. begin
  770. asm
  771. move.l #$sysFloatEm_f_sub, D2;
  772. end;
  773. _f_sub := ___f_sub(Left, Right);
  774. end;
  775. function _f_div(Left: FlpFloat; Right: FlpFloat): FlpFloat;
  776. begin
  777. asm
  778. move.l #$sysFloatEm_f_div, D2
  779. end;
  780. _f_div := ___f_div(Left, Right);
  781. end;
  782. function _d_neg(Value: FlpDouble): FlpDouble;
  783. begin
  784. asm
  785. move.l #$sysFloatEm_d_neg, D2;
  786. end;
  787. _d_neg := ___d_neg(Value);
  788. end;
  789. function _d_add(Left: FlpDouble; Right: FlpDouble): FlpDouble;
  790. begin
  791. asm
  792. move.l #$sysFloatEm_d_add, D2;
  793. end;
  794. _d_add := ___d_add(Left, Right);
  795. end;
  796. function _d_mul(Left: FlpDouble; Right: FlpDouble): FlpDouble;
  797. begin
  798. asm
  799. move.l #$sysFloatEm_d_mul, D2;
  800. end;
  801. _d_mul := ___d_mul(Left, Right);
  802. end;
  803. function _d_sub(Left: FlpDouble; Right: FlpDouble): FlpDouble;
  804. begin
  805. asm
  806. move.l #$sysFloatEm_d_sub, D2;
  807. end;
  808. _d_sub := ___d_sub(Left, Right);
  809. end;
  810. function _d_div(Left: FlpDouble; Right: FlpDouble): FlpDouble;
  811. begin
  812. asm
  813. move.l #$sysFloatEm_d_div, D2;
  814. end;
  815. _d_div := ___d_div(Left, Right);
  816. end;
  817. end.