fcnvuf.c
上传用户:jlfgdled
上传日期:2013-04-10
资源大小:33168k
文件大小:8k
源码类别:

Linux/Unix编程

开发平台:

Unix_Linux

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