fcnvfxt.c 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328
  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/fcnvfxt.c $Revision: 1.1 $
  26. *
  27. * Purpose:
  28. * Single Floating-point to Single Fixed-point /w truncated result
  29. * Single Floating-point to Double Fixed-point /w truncated result
  30. * Double Floating-point to Single Fixed-point /w truncated result
  31. * Double Floating-point to Double Fixed-point /w truncated result
  32. *
  33. * External Interfaces:
  34. * dbl_to_dbl_fcnvfxt(srcptr,nullptr,dstptr,status)
  35. * dbl_to_sgl_fcnvfxt(srcptr,nullptr,dstptr,status)
  36. * sgl_to_dbl_fcnvfxt(srcptr,nullptr,dstptr,status)
  37. * sgl_to_sgl_fcnvfxt(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 floating-point to single fixed-point format
  52. * with truncated result
  53. */
  54. /*ARGSUSED*/
  55. int
  56. sgl_to_sgl_fcnvfxt(
  57. sgl_floating_point *srcptr,
  58. unsigned int *nullptr,
  59. int *dstptr,
  60. unsigned int *status)
  61. {
  62. register unsigned int src, temp;
  63. register int src_exponent, result;
  64. src = *srcptr;
  65. src_exponent = Sgl_exponent(src) - SGL_BIAS;
  66. /*
  67. * Test for overflow
  68. */
  69. if (src_exponent > SGL_FX_MAX_EXP) {
  70. /* check for MININT */
  71. if ((src_exponent > SGL_FX_MAX_EXP + 1) ||
  72. Sgl_isnotzero_mantissa(src) || Sgl_iszero_sign(src)) {
  73. if (Sgl_iszero_sign(src)) result = 0x7fffffff;
  74. else result = 0x80000000;
  75. if (Is_invalidtrap_enabled()) {
  76. return(INVALIDEXCEPTION);
  77. }
  78. Set_invalidflag();
  79. *dstptr = result;
  80. return(NOEXCEPTION);
  81. }
  82. }
  83. /*
  84. * Generate result
  85. */
  86. if (src_exponent >= 0) {
  87. temp = src;
  88. Sgl_clear_signexponent_set_hidden(temp);
  89. Int_from_sgl_mantissa(temp,src_exponent);
  90. if (Sgl_isone_sign(src)) result = -Sgl_all(temp);
  91. else result = Sgl_all(temp);
  92. *dstptr = result;
  93. /* check for inexact */
  94. if (Sgl_isinexact_to_fix(src,src_exponent)) {
  95. if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION);
  96. else Set_inexactflag();
  97. }
  98. }
  99. else {
  100. *dstptr = 0;
  101. /* check for inexact */
  102. if (Sgl_isnotzero_exponentmantissa(src)) {
  103. if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION);
  104. else Set_inexactflag();
  105. }
  106. }
  107. return(NOEXCEPTION);
  108. }
  109. /*
  110. * Single Floating-point to Double Fixed-point
  111. */
  112. /*ARGSUSED*/
  113. int
  114. sgl_to_dbl_fcnvfxt(
  115. sgl_floating_point *srcptr,
  116. unsigned int *nullptr,
  117. dbl_integer *dstptr,
  118. unsigned int *status)
  119. {
  120. register int src_exponent, resultp1;
  121. register unsigned int src, temp, resultp2;
  122. src = *srcptr;
  123. src_exponent = Sgl_exponent(src) - SGL_BIAS;
  124. /*
  125. * Test for overflow
  126. */
  127. if (src_exponent > DBL_FX_MAX_EXP) {
  128. /* check for MININT */
  129. if ((src_exponent > DBL_FX_MAX_EXP + 1) ||
  130. Sgl_isnotzero_mantissa(src) || Sgl_iszero_sign(src)) {
  131. if (Sgl_iszero_sign(src)) {
  132. resultp1 = 0x7fffffff;
  133. resultp2 = 0xffffffff;
  134. }
  135. else {
  136. resultp1 = 0x80000000;
  137. resultp2 = 0;
  138. }
  139. if (Is_invalidtrap_enabled()) {
  140. return(INVALIDEXCEPTION);
  141. }
  142. Set_invalidflag();
  143. Dint_copytoptr(resultp1,resultp2,dstptr);
  144. return(NOEXCEPTION);
  145. }
  146. Dint_set_minint(resultp1,resultp2);
  147. Dint_copytoptr(resultp1,resultp2,dstptr);
  148. return(NOEXCEPTION);
  149. }
  150. /*
  151. * Generate result
  152. */
  153. if (src_exponent >= 0) {
  154. temp = src;
  155. Sgl_clear_signexponent_set_hidden(temp);
  156. Dint_from_sgl_mantissa(temp,src_exponent,resultp1,resultp2);
  157. if (Sgl_isone_sign(src)) {
  158. Dint_setone_sign(resultp1,resultp2);
  159. }
  160. Dint_copytoptr(resultp1,resultp2,dstptr);
  161. /* check for inexact */
  162. if (Sgl_isinexact_to_fix(src,src_exponent)) {
  163. if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION);
  164. else Set_inexactflag();
  165. }
  166. }
  167. else {
  168. Dint_setzero(resultp1,resultp2);
  169. Dint_copytoptr(resultp1,resultp2,dstptr);
  170. /* check for inexact */
  171. if (Sgl_isnotzero_exponentmantissa(src)) {
  172. if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION);
  173. else Set_inexactflag();
  174. }
  175. }
  176. return(NOEXCEPTION);
  177. }
  178. /*
  179. * Double Floating-point to Single Fixed-point
  180. */
  181. /*ARGSUSED*/
  182. int
  183. dbl_to_sgl_fcnvfxt(
  184. dbl_floating_point *srcptr,
  185. unsigned int *nullptr,
  186. int *dstptr,
  187. unsigned int *status)
  188. {
  189. register unsigned int srcp1, srcp2, tempp1, tempp2;
  190. register int src_exponent, result;
  191. Dbl_copyfromptr(srcptr,srcp1,srcp2);
  192. src_exponent = Dbl_exponent(srcp1) - DBL_BIAS;
  193. /*
  194. * Test for overflow
  195. */
  196. if (src_exponent > SGL_FX_MAX_EXP) {
  197. /* check for MININT */
  198. if (Dbl_isoverflow_to_int(src_exponent,srcp1,srcp2)) {
  199. if (Dbl_iszero_sign(srcp1)) result = 0x7fffffff;
  200. else result = 0x80000000;
  201. if (Is_invalidtrap_enabled()) {
  202. return(INVALIDEXCEPTION);
  203. }
  204. Set_invalidflag();
  205. *dstptr = result;
  206. return(NOEXCEPTION);
  207. }
  208. }
  209. /*
  210. * Generate result
  211. */
  212. if (src_exponent >= 0) {
  213. tempp1 = srcp1;
  214. tempp2 = srcp2;
  215. Dbl_clear_signexponent_set_hidden(tempp1);
  216. Int_from_dbl_mantissa(tempp1,tempp2,src_exponent);
  217. if (Dbl_isone_sign(srcp1) && (src_exponent <= SGL_FX_MAX_EXP))
  218. result = -Dbl_allp1(tempp1);
  219. else result = Dbl_allp1(tempp1);
  220. *dstptr = result;
  221. /* check for inexact */
  222. if (Dbl_isinexact_to_fix(srcp1,srcp2,src_exponent)) {
  223. if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION);
  224. else Set_inexactflag();
  225. }
  226. }
  227. else {
  228. *dstptr = 0;
  229. /* check for inexact */
  230. if (Dbl_isnotzero_exponentmantissa(srcp1,srcp2)) {
  231. if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION);
  232. else Set_inexactflag();
  233. }
  234. }
  235. return(NOEXCEPTION);
  236. }
  237. /*
  238. * Double Floating-point to Double Fixed-point
  239. */
  240. /*ARGSUSED*/
  241. int
  242. dbl_to_dbl_fcnvfxt(
  243. dbl_floating_point *srcptr,
  244. unsigned int *nullptr,
  245. dbl_integer *dstptr,
  246. unsigned int *status)
  247. {
  248. register int src_exponent, resultp1;
  249. register unsigned int srcp1, srcp2, tempp1, tempp2, resultp2;
  250. Dbl_copyfromptr(srcptr,srcp1,srcp2);
  251. src_exponent = Dbl_exponent(srcp1) - DBL_BIAS;
  252. /*
  253. * Test for overflow
  254. */
  255. if (src_exponent > DBL_FX_MAX_EXP) {
  256. /* check for MININT */
  257. if ((src_exponent > DBL_FX_MAX_EXP + 1) ||
  258. Dbl_isnotzero_mantissa(srcp1,srcp2) || Dbl_iszero_sign(srcp1)) {
  259. if (Dbl_iszero_sign(srcp1)) {
  260. resultp1 = 0x7fffffff;
  261. resultp2 = 0xffffffff;
  262. }
  263. else {
  264. resultp1 = 0x80000000;
  265. resultp2 = 0;
  266. }
  267. if (Is_invalidtrap_enabled()) {
  268. return(INVALIDEXCEPTION);
  269. }
  270. Set_invalidflag();
  271. Dint_copytoptr(resultp1,resultp2,dstptr);
  272. return(NOEXCEPTION);
  273. }
  274. }
  275. /*
  276. * Generate result
  277. */
  278. if (src_exponent >= 0) {
  279. tempp1 = srcp1;
  280. tempp2 = srcp2;
  281. Dbl_clear_signexponent_set_hidden(tempp1);
  282. Dint_from_dbl_mantissa(tempp1,tempp2,src_exponent,
  283. resultp1,resultp2);
  284. if (Dbl_isone_sign(srcp1)) {
  285. Dint_setone_sign(resultp1,resultp2);
  286. }
  287. Dint_copytoptr(resultp1,resultp2,dstptr);
  288. /* check for inexact */
  289. if (Dbl_isinexact_to_fix(srcp1,srcp2,src_exponent)) {
  290. if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION);
  291. else Set_inexactflag();
  292. }
  293. }
  294. else {
  295. Dint_setzero(resultp1,resultp2);
  296. Dint_copytoptr(resultp1,resultp2,dstptr);
  297. /* check for inexact */
  298. if (Dbl_isnotzero_exponentmantissa(srcp1,srcp2)) {
  299. if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION);
  300. else Set_inexactflag();
  301. }
  302. }
  303. return(NOEXCEPTION);
  304. }