fenv.S 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. /*++
  2. Copyright (c) 2015 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-Jan-2015
  14. Environment:
  15. User Mode C Library
  16. --*/
  17. //
  18. // ------------------------------------------------------------------- Includes
  19. //
  20. #include <minoca/kernel/x64.inc>
  21. //
  22. // ---------------------------------------------------------------- Definitions
  23. //
  24. #define FE_ALL_EXCEPT 0x3F
  25. #define FE_DFL_ENV -1
  26. //
  27. // ----------------------------------------------------------------------- Code
  28. //
  29. ASSEMBLY_FILE_HEADER
  30. //
  31. // LIBC_API
  32. // int
  33. // fegetenv (
  34. // fenv_t *Environment
  35. // )
  36. //
  37. /*++
  38. Routine Description:
  39. This routine stores the current floating point machine environment into the
  40. given environment pointer.
  41. Arguments:
  42. Environment - Supplies the pointer to the environment to save the
  43. floating point context in.
  44. Return Value:
  45. 0 on success.
  46. Non-zero on failure.
  47. --*/
  48. EXPORTED_FUNCTION(fegetenv)
  49. fnstenv (%rdi) # Store the FP environment into the pointer.
  50. xorq %rax, %rax # Zero out rax.
  51. ret # Return success.
  52. END_FUNCTION(fegetenv)
  53. //
  54. // LIBC_API
  55. // int
  56. // fesetenv (
  57. // const fenv_t *Environment
  58. // )
  59. //
  60. /*++
  61. Routine Description:
  62. This routine sets the current machine floating point environment to that of
  63. the given saved environment.
  64. Arguments:
  65. Environment - Supplies the pointer to the environment to load into the
  66. execution state.
  67. Return Value:
  68. 0 on success.
  69. Non-zero on failure.
  70. --*/
  71. EXPORTED_FUNCTION(fesetenv)
  72. cmpq $FE_DFL_ENV, %rdi # Compare to the "default" environment value.
  73. jne fesetenvLoad # Jump to the load portion if it's custom.
  74. finit # Load the default state.
  75. fesetenvLoad:
  76. fldenv (%rdi) # Load the FP environment from the pointer.
  77. xorq %rax, %rax # Zero out rax.
  78. ret # Return success.
  79. END_FUNCTION(fesetenv)
  80. //
  81. // LIBC_API
  82. // int
  83. // fegetexceptflag (
  84. // fexcept_t *Destination,
  85. // int Mask
  86. // )
  87. //
  88. /*++
  89. Routine Description:
  90. This routine stores an implementation defined representation of the
  91. exception flags indicated by the given mask into the given destination.
  92. Arguments:
  93. Destination - Supplies a pointer where the implementation-defined
  94. representation of the current flags masked with the given value.
  95. Mask - Supplies a mask of the exceptions the caller is interested in. See
  96. FE_* definitions.
  97. Return Value:
  98. 0 on success.
  99. Non-zero on failure.
  100. --*/
  101. EXPORTED_FUNCTION(fegetexceptflag)
  102. xorq %rax, %rax # Zero out rax.
  103. fnstsw %ax # Get the floating point flags.
  104. andq %rax, %rsi # AND them with the mask.
  105. andq $FE_ALL_EXCEPT, %rsi # AND in the valid exceptions.
  106. movw %dx, (%rdi) # Save the flags into the destination.
  107. xorq %rax, %rax # Zero out rax return value.
  108. ret # return success.
  109. END_FUNCTION(fegetexceptflag)