fcnvxf.c 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386
  1. /*
  2. * Linux/PA-RISC Project (http://www.parisc-linux.org/)
  3. *
  4. * Floating-point emulation code
  5. * Copyright (C) 2001 Hewlett-Packard (Paul Bame) <bame@debian.org>
  6. *
  7. * This program is free software; you can redistribute it and/or modify
  8. * it under the terms of the GNU General Public License as published by
  9. * the Free Software Foundation; either version 2, or (at your option)
  10. * any later version.
  11. *
  12. * This program is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * GNU General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU General Public License
  18. * along with this program; if not, write to the Free Software
  19. * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  20. */
  21. /*
  22. * BEGIN_DESC
  23. *
  24. * File:
  25. * @(#) pa/spmath/fcnvxf.c $Revision: 1.1 $
  26. *
  27. * Purpose:
  28. * Single Fixed-point to Single Floating-point
  29. * Single Fixed-point to Double Floating-point
  30. * Double Fixed-point to Single Floating-point
  31. * Double Fixed-point to Double Floating-point
  32. *
  33. * External Interfaces:
  34. * dbl_to_dbl_fcnvxf(srcptr,nullptr,dstptr,status)
  35. * dbl_to_sgl_fcnvxf(srcptr,nullptr,dstptr,status)
  36. * sgl_to_dbl_fcnvxf(srcptr,nullptr,dstptr,status)
  37. * sgl_to_sgl_fcnvxf(srcptr,nullptr,dstptr,status)
  38. *
  39. * Internal Interfaces:
  40. *
  41. * Theory:
  42. * <<please update with a overview of the operation of this file>>
  43. *
  44. * END_DESC
  45. */
  46. #include "float.h"
  47. #include "sgl_float.h"
  48. #include "dbl_float.h"
  49. #include "cnv_float.h"
  50. /*
  51. * Convert single fixed-point to single floating-point format
  52. */
  53. int
  54. sgl_to_sgl_fcnvxf(
  55. int *srcptr,
  56. unsigned int *nullptr,
  57. sgl_floating_point *dstptr,
  58. unsigned int *status)
  59. {
  60. register int src, dst_exponent;
  61. register unsigned int result = 0;
  62. src = *srcptr;
  63. /*
  64. * set sign bit of result and get magnitude of source
  65. */
  66. if (src < 0) {
  67. Sgl_setone_sign(result);
  68. Int_negate(src);
  69. }
  70. else {
  71. Sgl_setzero_sign(result);
  72. /* Check for zero */
  73. if (src == 0) {
  74. Sgl_setzero(result);
  75. *dstptr = result;
  76. return(NOEXCEPTION);
  77. }
  78. }
  79. /*
  80. * Generate exponent and normalized mantissa
  81. */
  82. dst_exponent = 16; /* initialize for normalization */
  83. /*
  84. * Check word for most significant bit set. Returns
  85. * a value in dst_exponent indicating the bit position,
  86. * between -1 and 30.
  87. */
  88. Find_ms_one_bit(src,dst_exponent);
  89. /* left justify source, with msb at bit position 1 */
  90. if (dst_exponent >= 0) src <<= dst_exponent;
  91. else src = 1 << 30;
  92. Sgl_set_mantissa(result, src >> (SGL_EXP_LENGTH-1));
  93. Sgl_set_exponent(result, 30+SGL_BIAS - dst_exponent);
  94. /* check for inexact */
  95. if (Int_isinexact_to_sgl(src)) {
  96. switch (Rounding_mode()) {
  97. case ROUNDPLUS:
  98. if (Sgl_iszero_sign(result))
  99. Sgl_increment(result);
  100. break;
  101. case ROUNDMINUS:
  102. if (Sgl_isone_sign(result))
  103. Sgl_increment(result);
  104. break;
  105. case ROUNDNEAREST:
  106. Sgl_roundnearest_from_int(src,result);
  107. }
  108. if (Is_inexacttrap_enabled()) {
  109. *dstptr = result;
  110. return(INEXACTEXCEPTION);
  111. }
  112. else Set_inexactflag();
  113. }
  114. *dstptr = result;
  115. return(NOEXCEPTION);
  116. }
  117. /*
  118. * Single Fixed-point to Double Floating-point
  119. */
  120. int
  121. sgl_to_dbl_fcnvxf(
  122. int *srcptr,
  123. unsigned int *nullptr,
  124. dbl_floating_point *dstptr,
  125. unsigned int *status)
  126. {
  127. register int src, dst_exponent;
  128. register unsigned int resultp1 = 0, resultp2 = 0;
  129. src = *srcptr;
  130. /*
  131. * set sign bit of result and get magnitude of source
  132. */
  133. if (src < 0) {
  134. Dbl_setone_sign(resultp1);
  135. Int_negate(src);
  136. }
  137. else {
  138. Dbl_setzero_sign(resultp1);
  139. /* Check for zero */
  140. if (src == 0) {
  141. Dbl_setzero(resultp1,resultp2);
  142. Dbl_copytoptr(resultp1,resultp2,dstptr);
  143. return(NOEXCEPTION);
  144. }
  145. }
  146. /*
  147. * Generate exponent and normalized mantissa
  148. */
  149. dst_exponent = 16; /* initialize for normalization */
  150. /*
  151. * Check word for most significant bit set. Returns
  152. * a value in dst_exponent indicating the bit position,
  153. * between -1 and 30.
  154. */
  155. Find_ms_one_bit(src,dst_exponent);
  156. /* left justify source, with msb at bit position 1 */
  157. if (dst_exponent >= 0) src <<= dst_exponent;
  158. else src = 1 << 30;
  159. Dbl_set_mantissap1(resultp1, src >> DBL_EXP_LENGTH - 1);
  160. Dbl_set_mantissap2(resultp2, src << (33-DBL_EXP_LENGTH));
  161. Dbl_set_exponent(resultp1, (30+DBL_BIAS) - dst_exponent);
  162. Dbl_copytoptr(resultp1,resultp2,dstptr);
  163. return(NOEXCEPTION);
  164. }
  165. /*
  166. * Double Fixed-point to Single Floating-point
  167. */
  168. int
  169. dbl_to_sgl_fcnvxf(
  170. dbl_integer *srcptr,
  171. unsigned int *nullptr,
  172. sgl_floating_point *dstptr,
  173. unsigned int *status)
  174. {
  175. int dst_exponent, srcp1;
  176. unsigned int result = 0, srcp2;
  177. Dint_copyfromptr(srcptr,srcp1,srcp2);
  178. /*
  179. * set sign bit of result and get magnitude of source
  180. */
  181. if (srcp1 < 0) {
  182. Sgl_setone_sign(result);
  183. Dint_negate(srcp1,srcp2);
  184. }
  185. else {
  186. Sgl_setzero_sign(result);
  187. /* Check for zero */
  188. if (srcp1 == 0 && srcp2 == 0) {
  189. Sgl_setzero(result);
  190. *dstptr = result;
  191. return(NOEXCEPTION);
  192. }
  193. }
  194. /*
  195. * Generate exponent and normalized mantissa
  196. */
  197. dst_exponent = 16; /* initialize for normalization */
  198. if (srcp1 == 0) {
  199. /*
  200. * Check word for most significant bit set. Returns
  201. * a value in dst_exponent indicating the bit position,
  202. * between -1 and 30.
  203. */
  204. Find_ms_one_bit(srcp2,dst_exponent);
  205. /* left justify source, with msb at bit position 1 */
  206. if (dst_exponent >= 0) {
  207. srcp1 = srcp2 << dst_exponent;
  208. srcp2 = 0;
  209. }
  210. else {
  211. srcp1 = srcp2 >> 1;
  212. srcp2 <<= 31;
  213. }
  214. /*
  215. * since msb set is in second word, need to
  216. * adjust bit position count
  217. */
  218. dst_exponent += 32;
  219. }
  220. else {
  221. /*
  222. * Check word for most significant bit set. Returns
  223. * a value in dst_exponent indicating the bit position,
  224. * between -1 and 30.
  225. *
  226. */
  227. Find_ms_one_bit(srcp1,dst_exponent);
  228. /* left justify source, with msb at bit position 1 */
  229. if (dst_exponent > 0) {
  230. Variable_shift_double(srcp1,srcp2,(32-dst_exponent),
  231. srcp1);
  232. srcp2 <<= dst_exponent;
  233. }
  234. /*
  235. * If dst_exponent = 0, we don't need to shift anything.
  236. * If dst_exponent = -1, src = - 2**63 so we won't need to
  237. * shift srcp2.
  238. */
  239. else srcp1 >>= -(dst_exponent);
  240. }
  241. Sgl_set_mantissa(result, srcp1 >> SGL_EXP_LENGTH - 1);
  242. Sgl_set_exponent(result, (62+SGL_BIAS) - dst_exponent);
  243. /* check for inexact */
  244. if (Dint_isinexact_to_sgl(srcp1,srcp2)) {
  245. switch (Rounding_mode()) {
  246. case ROUNDPLUS:
  247. if (Sgl_iszero_sign(result))
  248. Sgl_increment(result);
  249. break;
  250. case ROUNDMINUS:
  251. if (Sgl_isone_sign(result))
  252. Sgl_increment(result);
  253. break;
  254. case ROUNDNEAREST:
  255. Sgl_roundnearest_from_dint(srcp1,srcp2,result);
  256. }
  257. if (Is_inexacttrap_enabled()) {
  258. *dstptr = result;
  259. return(INEXACTEXCEPTION);
  260. }
  261. else Set_inexactflag();
  262. }
  263. *dstptr = result;
  264. return(NOEXCEPTION);
  265. }
  266. /*
  267. * Double Fixed-point to Double Floating-point
  268. */
  269. int
  270. dbl_to_dbl_fcnvxf(
  271. dbl_integer *srcptr,
  272. unsigned int *nullptr,
  273. dbl_floating_point *dstptr,
  274. unsigned int *status)
  275. {
  276. register int srcp1, dst_exponent;
  277. register unsigned int srcp2, resultp1 = 0, resultp2 = 0;
  278. Dint_copyfromptr(srcptr,srcp1,srcp2);
  279. /*
  280. * set sign bit of result and get magnitude of source
  281. */
  282. if (srcp1 < 0) {
  283. Dbl_setone_sign(resultp1);
  284. Dint_negate(srcp1,srcp2);
  285. }
  286. else {
  287. Dbl_setzero_sign(resultp1);
  288. /* Check for zero */
  289. if (srcp1 == 0 && srcp2 ==0) {
  290. Dbl_setzero(resultp1,resultp2);
  291. Dbl_copytoptr(resultp1,resultp2,dstptr);
  292. return(NOEXCEPTION);
  293. }
  294. }
  295. /*
  296. * Generate exponent and normalized mantissa
  297. */
  298. dst_exponent = 16; /* initialize for normalization */
  299. if (srcp1 == 0) {
  300. /*
  301. * Check word for most significant bit set. Returns
  302. * a value in dst_exponent indicating the bit position,
  303. * between -1 and 30.
  304. */
  305. Find_ms_one_bit(srcp2,dst_exponent);
  306. /* left justify source, with msb at bit position 1 */
  307. if (dst_exponent >= 0) {
  308. srcp1 = srcp2 << dst_exponent;
  309. srcp2 = 0;
  310. }
  311. else {
  312. srcp1 = srcp2 >> 1;
  313. srcp2 <<= 31;
  314. }
  315. /*
  316. * since msb set is in second word, need to
  317. * adjust bit position count
  318. */
  319. dst_exponent += 32;
  320. }
  321. else {
  322. /*
  323. * Check word for most significant bit set. Returns
  324. * a value in dst_exponent indicating the bit position,
  325. * between -1 and 30.
  326. */
  327. Find_ms_one_bit(srcp1,dst_exponent);
  328. /* left justify source, with msb at bit position 1 */
  329. if (dst_exponent > 0) {
  330. Variable_shift_double(srcp1,srcp2,(32-dst_exponent),
  331. srcp1);
  332. srcp2 <<= dst_exponent;
  333. }
  334. /*
  335. * If dst_exponent = 0, we don't need to shift anything.
  336. * If dst_exponent = -1, src = - 2**63 so we won't need to
  337. * shift srcp2.
  338. */
  339. else srcp1 >>= -(dst_exponent);
  340. }
  341. Dbl_set_mantissap1(resultp1, srcp1 >> (DBL_EXP_LENGTH-1));
  342. Shiftdouble(srcp1,srcp2,DBL_EXP_LENGTH-1,resultp2);
  343. Dbl_set_exponent(resultp1, (62+DBL_BIAS) - dst_exponent);
  344. /* check for inexact */
  345. if (Dint_isinexact_to_dbl(srcp2)) {
  346. switch (Rounding_mode()) {
  347. case ROUNDPLUS:
  348. if (Dbl_iszero_sign(resultp1)) {
  349. Dbl_increment(resultp1,resultp2);
  350. }
  351. break;
  352. case ROUNDMINUS:
  353. if (Dbl_isone_sign(resultp1)) {
  354. Dbl_increment(resultp1,resultp2);
  355. }
  356. break;
  357. case ROUNDNEAREST:
  358. Dbl_roundnearest_from_dint(srcp2,resultp1,
  359. resultp2);
  360. }
  361. if (Is_inexacttrap_enabled()) {
  362. Dbl_copytoptr(resultp1,resultp2,dstptr);
  363. return(INEXACTEXCEPTION);
  364. }
  365. else Set_inexactflag();
  366. }
  367. Dbl_copytoptr(resultp1,resultp2,dstptr);
  368. return(NOEXCEPTION);
  369. }