fcnvuf.c 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319
  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/fcnvuf.c $Revision: 1.1 $
  26. *
  27. * Purpose:
  28. * Fixed point to Floating-point Converts
  29. *
  30. * External Interfaces:
  31. * dbl_to_dbl_fcnvuf(srcptr,nullptr,dstptr,status)
  32. * dbl_to_sgl_fcnvuf(srcptr,nullptr,dstptr,status)
  33. * sgl_to_dbl_fcnvuf(srcptr,nullptr,dstptr,status)
  34. * sgl_to_sgl_fcnvuf(srcptr,nullptr,dstptr,status)
  35. *
  36. * Internal Interfaces:
  37. *
  38. * Theory:
  39. * <<please update with a overview of the operation of this file>>
  40. *
  41. * END_DESC
  42. */
  43. #include "float.h"
  44. #include "sgl_float.h"
  45. #include "dbl_float.h"
  46. #include "cnv_float.h"
  47. /************************************************************************
  48. * Fixed point to Floating-point Converts *
  49. ************************************************************************/
  50. /*
  51. * Convert Single Unsigned Fixed to Single Floating-point format
  52. */
  53. int
  54. sgl_to_sgl_fcnvuf(
  55. unsigned int *srcptr,
  56. unsigned int *nullptr,
  57. sgl_floating_point *dstptr,
  58. unsigned int *status)
  59. {
  60. register unsigned int src, result = 0;
  61. register int dst_exponent;
  62. src = *srcptr;
  63. /* Check for zero */
  64. if (src == 0) {
  65. Sgl_setzero(result);
  66. *dstptr = result;
  67. return(NOEXCEPTION);
  68. }
  69. /*
  70. * Generate exponent and normalized mantissa
  71. */
  72. dst_exponent = 16; /* initialize for normalization */
  73. /*
  74. * Check word for most significant bit set. Returns
  75. * a value in dst_exponent indicating the bit position,
  76. * between -1 and 30.
  77. */
  78. Find_ms_one_bit(src,dst_exponent);
  79. /* left justify source, with msb at bit position 0 */
  80. src <<= dst_exponent+1;
  81. Sgl_set_mantissa(result, src >> SGL_EXP_LENGTH);
  82. Sgl_set_exponent(result, 30+SGL_BIAS - dst_exponent);
  83. /* check for inexact */
  84. if (Suint_isinexact_to_sgl(src)) {
  85. switch (Rounding_mode()) {
  86. case ROUNDPLUS:
  87. Sgl_increment(result);
  88. break;
  89. case ROUNDMINUS: /* never negative */
  90. break;
  91. case ROUNDNEAREST:
  92. Sgl_roundnearest_from_suint(src,result);
  93. break;
  94. }
  95. if (Is_inexacttrap_enabled()) {
  96. *dstptr = result;
  97. return(INEXACTEXCEPTION);
  98. }
  99. else Set_inexactflag();
  100. }
  101. *dstptr = result;
  102. return(NOEXCEPTION);
  103. }
  104. /*
  105. * Single Unsigned Fixed to Double Floating-point
  106. */
  107. int
  108. sgl_to_dbl_fcnvuf(
  109. unsigned int *srcptr,
  110. unsigned int *nullptr,
  111. dbl_floating_point *dstptr,
  112. unsigned int *status)
  113. {
  114. register int dst_exponent;
  115. register unsigned int src, resultp1 = 0, resultp2 = 0;
  116. src = *srcptr;
  117. /* Check for zero */
  118. if (src == 0) {
  119. Dbl_setzero(resultp1,resultp2);
  120. Dbl_copytoptr(resultp1,resultp2,dstptr);
  121. return(NOEXCEPTION);
  122. }
  123. /*
  124. * Generate exponent and normalized mantissa
  125. */
  126. dst_exponent = 16; /* initialize for normalization */
  127. /*
  128. * Check word for most significant bit set. Returns
  129. * a value in dst_exponent indicating the bit position,
  130. * between -1 and 30.
  131. */
  132. Find_ms_one_bit(src,dst_exponent);
  133. /* left justify source, with msb at bit position 0 */
  134. src <<= dst_exponent+1;
  135. Dbl_set_mantissap1(resultp1, src >> DBL_EXP_LENGTH);
  136. Dbl_set_mantissap2(resultp2, src << (32-DBL_EXP_LENGTH));
  137. Dbl_set_exponent(resultp1, (30+DBL_BIAS) - dst_exponent);
  138. Dbl_copytoptr(resultp1,resultp2,dstptr);
  139. return(NOEXCEPTION);
  140. }
  141. /*
  142. * Double Unsigned Fixed to Single Floating-point
  143. */
  144. int
  145. dbl_to_sgl_fcnvuf(
  146. dbl_unsigned *srcptr,
  147. unsigned int *nullptr,
  148. sgl_floating_point *dstptr,
  149. unsigned int *status)
  150. {
  151. int dst_exponent;
  152. unsigned int srcp1, srcp2, result = 0;
  153. Duint_copyfromptr(srcptr,srcp1,srcp2);
  154. /* Check for zero */
  155. if (srcp1 == 0 && srcp2 == 0) {
  156. Sgl_setzero(result);
  157. *dstptr = result;
  158. return(NOEXCEPTION);
  159. }
  160. /*
  161. * Generate exponent and normalized mantissa
  162. */
  163. dst_exponent = 16; /* initialize for normalization */
  164. if (srcp1 == 0) {
  165. /*
  166. * Check word for most significant bit set. Returns
  167. * a value in dst_exponent indicating the bit position,
  168. * between -1 and 30.
  169. */
  170. Find_ms_one_bit(srcp2,dst_exponent);
  171. /* left justify source, with msb at bit position 0 */
  172. srcp1 = srcp2 << dst_exponent+1;
  173. srcp2 = 0;
  174. /*
  175. * since msb set is in second word, need to
  176. * adjust bit position count
  177. */
  178. dst_exponent += 32;
  179. }
  180. else {
  181. /*
  182. * Check word for most significant bit set. Returns
  183. * a value in dst_exponent indicating the bit position,
  184. * between -1 and 30.
  185. *
  186. */
  187. Find_ms_one_bit(srcp1,dst_exponent);
  188. /* left justify source, with msb at bit position 0 */
  189. if (dst_exponent >= 0) {
  190. Variable_shift_double(srcp1,srcp2,(31-dst_exponent),
  191. srcp1);
  192. srcp2 <<= dst_exponent+1;
  193. }
  194. }
  195. Sgl_set_mantissa(result, srcp1 >> SGL_EXP_LENGTH);
  196. Sgl_set_exponent(result, (62+SGL_BIAS) - dst_exponent);
  197. /* check for inexact */
  198. if (Duint_isinexact_to_sgl(srcp1,srcp2)) {
  199. switch (Rounding_mode()) {
  200. case ROUNDPLUS:
  201. Sgl_increment(result);
  202. break;
  203. case ROUNDMINUS: /* never negative */
  204. break;
  205. case ROUNDNEAREST:
  206. Sgl_roundnearest_from_duint(srcp1,srcp2,result);
  207. break;
  208. }
  209. if (Is_inexacttrap_enabled()) {
  210. *dstptr = result;
  211. return(INEXACTEXCEPTION);
  212. }
  213. else Set_inexactflag();
  214. }
  215. *dstptr = result;
  216. return(NOEXCEPTION);
  217. }
  218. /*
  219. * Double Unsigned Fixed to Double Floating-point
  220. */
  221. int
  222. dbl_to_dbl_fcnvuf(
  223. dbl_unsigned *srcptr,
  224. unsigned int *nullptr,
  225. dbl_floating_point *dstptr,
  226. unsigned int *status)
  227. {
  228. register int dst_exponent;
  229. register unsigned int srcp1, srcp2, resultp1 = 0, resultp2 = 0;
  230. Duint_copyfromptr(srcptr,srcp1,srcp2);
  231. /* Check for zero */
  232. if (srcp1 == 0 && srcp2 ==0) {
  233. Dbl_setzero(resultp1,resultp2);
  234. Dbl_copytoptr(resultp1,resultp2,dstptr);
  235. return(NOEXCEPTION);
  236. }
  237. /*
  238. * Generate exponent and normalized mantissa
  239. */
  240. dst_exponent = 16; /* initialize for normalization */
  241. if (srcp1 == 0) {
  242. /*
  243. * Check word for most significant bit set. Returns
  244. * a value in dst_exponent indicating the bit position,
  245. * between -1 and 30.
  246. */
  247. Find_ms_one_bit(srcp2,dst_exponent);
  248. /* left justify source, with msb at bit position 0 */
  249. srcp1 = srcp2 << dst_exponent+1;
  250. srcp2 = 0;
  251. /*
  252. * since msb set is in second word, need to
  253. * adjust bit position count
  254. */
  255. dst_exponent += 32;
  256. }
  257. else {
  258. /*
  259. * Check word for most significant bit set. Returns
  260. * a value in dst_exponent indicating the bit position,
  261. * between -1 and 30.
  262. */
  263. Find_ms_one_bit(srcp1,dst_exponent);
  264. /* left justify source, with msb at bit position 0 */
  265. if (dst_exponent >= 0) {
  266. Variable_shift_double(srcp1,srcp2,(31-dst_exponent),
  267. srcp1);
  268. srcp2 <<= dst_exponent+1;
  269. }
  270. }
  271. Dbl_set_mantissap1(resultp1, srcp1 >> DBL_EXP_LENGTH);
  272. Shiftdouble(srcp1,srcp2,DBL_EXP_LENGTH,resultp2);
  273. Dbl_set_exponent(resultp1, (62+DBL_BIAS) - dst_exponent);
  274. /* check for inexact */
  275. if (Duint_isinexact_to_dbl(srcp2)) {
  276. switch (Rounding_mode()) {
  277. case ROUNDPLUS:
  278. Dbl_increment(resultp1,resultp2);
  279. break;
  280. case ROUNDMINUS: /* never negative */
  281. break;
  282. case ROUNDNEAREST:
  283. Dbl_roundnearest_from_duint(srcp2,resultp1,
  284. resultp2);
  285. break;
  286. }
  287. if (Is_inexacttrap_enabled()) {
  288. Dbl_copytoptr(resultp1,resultp2,dstptr);
  289. return(INEXACTEXCEPTION);
  290. }
  291. else Set_inexactflag();
  292. }
  293. Dbl_copytoptr(resultp1,resultp2,dstptr);
  294. return(NOEXCEPTION);
  295. }