denormal.c 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. // SPDX-License-Identifier: GPL-2.0-or-later
  2. /*
  3. * Linux/PA-RISC Project (http://www.parisc-linux.org/)
  4. *
  5. * Floating-point emulation code
  6. * Copyright (C) 2001 Hewlett-Packard (Paul Bame) <[email protected]>
  7. */
  8. /*
  9. * BEGIN_DESC
  10. *
  11. * File:
  12. * @(#) pa/fp/denormal.c $ Revision: $
  13. *
  14. * Purpose:
  15. * <<please update with a synopsis of the functionality provided by this file>>
  16. *
  17. * External Interfaces:
  18. * <<the following list was autogenerated, please review>>
  19. * dbl_denormalize(dbl_opndp1,dbl_opndp2,inexactflag,rmode)
  20. * sgl_denormalize(sgl_opnd,inexactflag,rmode)
  21. *
  22. * Internal Interfaces:
  23. * <<please update>>
  24. *
  25. * Theory:
  26. * <<please update with a overview of the operation of this file>>
  27. *
  28. * END_DESC
  29. */
  30. #include "float.h"
  31. #include "sgl_float.h"
  32. #include "dbl_float.h"
  33. #include "hppa.h"
  34. #include <linux/kernel.h>
  35. /* #include <machine/sys/mdep_private.h> */
  36. #undef Fpustatus_register
  37. #define Fpustatus_register Fpu_register[0]
  38. void
  39. sgl_denormalize(unsigned int *sgl_opnd, boolean *inexactflag, int rmode)
  40. {
  41. unsigned int opnd;
  42. int sign, exponent;
  43. boolean guardbit = FALSE, stickybit, inexact;
  44. opnd = *sgl_opnd;
  45. stickybit = *inexactflag;
  46. exponent = Sgl_exponent(opnd) - SGL_WRAP;
  47. sign = Sgl_sign(opnd);
  48. Sgl_denormalize(opnd,exponent,guardbit,stickybit,inexact);
  49. if (inexact) {
  50. switch (rmode) {
  51. case ROUNDPLUS:
  52. if (sign == 0) {
  53. Sgl_increment(opnd);
  54. }
  55. break;
  56. case ROUNDMINUS:
  57. if (sign != 0) {
  58. Sgl_increment(opnd);
  59. }
  60. break;
  61. case ROUNDNEAREST:
  62. if (guardbit && (stickybit ||
  63. Sgl_isone_lowmantissa(opnd))) {
  64. Sgl_increment(opnd);
  65. }
  66. break;
  67. }
  68. }
  69. Sgl_set_sign(opnd,sign);
  70. *sgl_opnd = opnd;
  71. *inexactflag = inexact;
  72. return;
  73. }
  74. void
  75. dbl_denormalize(unsigned int *dbl_opndp1,
  76. unsigned int * dbl_opndp2,
  77. boolean *inexactflag,
  78. int rmode)
  79. {
  80. unsigned int opndp1, opndp2;
  81. int sign, exponent;
  82. boolean guardbit = FALSE, stickybit, inexact;
  83. opndp1 = *dbl_opndp1;
  84. opndp2 = *dbl_opndp2;
  85. stickybit = *inexactflag;
  86. exponent = Dbl_exponent(opndp1) - DBL_WRAP;
  87. sign = Dbl_sign(opndp1);
  88. Dbl_denormalize(opndp1,opndp2,exponent,guardbit,stickybit,inexact);
  89. if (inexact) {
  90. switch (rmode) {
  91. case ROUNDPLUS:
  92. if (sign == 0) {
  93. Dbl_increment(opndp1,opndp2);
  94. }
  95. break;
  96. case ROUNDMINUS:
  97. if (sign != 0) {
  98. Dbl_increment(opndp1,opndp2);
  99. }
  100. break;
  101. case ROUNDNEAREST:
  102. if (guardbit && (stickybit ||
  103. Dbl_isone_lowmantissap2(opndp2))) {
  104. Dbl_increment(opndp1,opndp2);
  105. }
  106. break;
  107. }
  108. }
  109. Dbl_set_sign(opndp1,sign);
  110. *dbl_opndp1 = opndp1;
  111. *dbl_opndp2 = opndp2;
  112. *inexactflag = inexact;
  113. return;
  114. }