fenv.S 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176
  1. /*++
  2. Copyright (c) 2014 Minoca Corp.
  3. This file is licensed under the terms of the GNU General Public License
  4. version 3. Alternative licensing terms are available. Contact
  5. info@minocacorp.com for details. See the LICENSE file at the root of this
  6. project for complete licensing information.
  7. Module Name:
  8. fenv.S
  9. Abstract:
  10. This module implements functionality for manipulating the floating point
  11. environment.
  12. Author:
  13. Evan Green 18-Jul-2014
  14. Environment:
  15. User Mode C Library
  16. --*/
  17. //
  18. // ------------------------------------------------------------------- Includes
  19. //
  20. #include <minoca/kernel/x86.inc>
  21. //
  22. // ---------------------------------------------------------------- Definitions
  23. //
  24. #define FE_ALL_EXCEPT 0x3F
  25. #define FE_DFL_ENV -1
  26. //
  27. // ----------------------------------------------------------------------- Code
  28. //
  29. //
  30. // .text specifies that this code belongs in the executable section.
  31. //
  32. // .code32 specifies that this is 32-bit protected mode code.
  33. //
  34. .text
  35. .code32
  36. //
  37. // LIBC_API
  38. // int
  39. // fegetenv (
  40. // fenv_t *Environment
  41. // )
  42. //
  43. /*++
  44. Routine Description:
  45. This routine stores the current floating point machine environment into the
  46. given environment pointer.
  47. Arguments:
  48. Environment - Supplies the pointer to the environment to save the
  49. floating point context in.
  50. Return Value:
  51. 0 on success.
  52. Non-zero on failure.
  53. --*/
  54. EXPORTED_FUNCTION(fegetenv)
  55. movl 4(%esp), %eax # Get the pointer parameter.
  56. fnstenv (%eax) # Store the FP environment into the pointer.
  57. movl $0, %eax # Move a successful return status.
  58. ret # Return success.
  59. END_FUNCTION(fegetenv)
  60. //
  61. // LIBC_API
  62. // int
  63. // fesetenv (
  64. // const fenv_t *Environment
  65. // )
  66. //
  67. /*++
  68. Routine Description:
  69. This routine sets the current machine floating point environment to that of
  70. the given saved environment.
  71. Arguments:
  72. Environment - Supplies the pointer to the environment to load into the
  73. execution state.
  74. Return Value:
  75. 0 on success.
  76. Non-zero on failure.
  77. --*/
  78. EXPORTED_FUNCTION(fesetenv)
  79. movl 4(%esp), %eax # Get the pointer parameter.
  80. cmpl $FE_DFL_ENV, %eax # Compare to the "default" environment value.
  81. jne fesetenvLoad # Jump to the load portion if it's custom.
  82. finit # Load the default state.
  83. fesetenvLoad:
  84. fldenv (%eax) # Load the FP environment from the pointer.
  85. movl $0, %eax # Move a successful return status.
  86. ret # Return success.
  87. END_FUNCTION(fesetenv)
  88. //
  89. // LIBC_API
  90. // int
  91. // fegetexceptflag (
  92. // fexcept_t *Destination,
  93. // int Mask
  94. // )
  95. //
  96. /*++
  97. Routine Description:
  98. This routine stores an implementation defined representation of the
  99. exception flags indicated by the given mask into the given destination.
  100. Arguments:
  101. Destination - Supplies a pointer where the implementation-defined
  102. representation of the current flags masked with the given value.
  103. Mask - Supplies a mask of the exceptions the caller is interested in. See
  104. FE_* definitions.
  105. Return Value:
  106. 0 on success.
  107. Non-zero on failure.
  108. --*/
  109. EXPORTED_FUNCTION(fegetexceptflag)
  110. movl 4(%esp), %ecx # Get the pointer parameter.
  111. movl 8(%esp), %edx # Get the mask.
  112. xorl %eax, %eax # Zero the high part of EAX.
  113. fnstsw %ax # Get the floating point flags.
  114. andl %eax, %edx # AND them into the mask.
  115. andl $FE_ALL_EXCEPT, %edx # AND them with the valid exceptions.
  116. movw %dx, (%ecx) # Save the flags into the destination.
  117. movl $0, %eax # Move a successful return status.
  118. ret # Return success.
  119. END_FUNCTION(fegetexceptflag)