Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

371 lines
8.7 KiB

  1. // TITLE("Floating Point Control")
  2. //++
  3. //
  4. // Copyright (c) 1992 Digital Equipment Corporation
  5. //
  6. // Module Name:
  7. //
  8. // fpctrl.s
  9. //
  10. // Abstract:
  11. //
  12. // This module implements routines that control floating point
  13. // operations.
  14. //
  15. // Author:
  16. //
  17. // Thomas Van Baak (tvb) 31-Aug-1992
  18. //
  19. // Environment:
  20. //
  21. // Any mode.
  22. //
  23. // Revision History:
  24. //
  25. //--
  26. #include "ksalpha.h"
  27. //
  28. // Define call frame used to exchange a floating point and integer register.
  29. //
  30. .struct 0
  31. FpCr: .space 8 // fpcr value
  32. .space 8 // ensure 16-byte stack alignment
  33. FpFrameLength: // length of stack frame
  34. SBTTL("Get Hardware Floating Point Control Register")
  35. //++
  36. //
  37. // ULONGLONG
  38. // _get_fpcr (
  39. // VOID
  40. // )
  41. //
  42. // Routine Description:
  43. //
  44. // This function obtains the current FPCR value.
  45. //
  46. // Arguments:
  47. //
  48. // None.
  49. //
  50. // Return Value:
  51. //
  52. // The current value of the FPCR is returned as the function value.
  53. //
  54. //--
  55. NESTED_ENTRY(_get_fpcr, FpFrameLength, ra)
  56. lda sp, -FpFrameLength(sp) // allocate stack frame
  57. PROLOGUE_END
  58. excb // wait for all pending traps
  59. mf_fpcr f0, f0, f0 // get current fpcr
  60. excb // block against new traps
  61. stt f0, FpCr(sp) // store floating register in order to
  62. ldq v0, FpCr(sp) // load integer register with fpcr
  63. lda sp, FpFrameLength(sp) // deallocate stack frame
  64. ret zero, (ra) // return
  65. .end _get_fpcr
  66. SBTTL("Set Hardware Floating Point Control Register")
  67. //++
  68. //
  69. // VOID
  70. // _set_fpcr (
  71. // ULONGLONG FpcrValue
  72. // )
  73. //
  74. // Routine Description:
  75. //
  76. // This function sets a new value in the FPCR.
  77. //
  78. // Arguments:
  79. //
  80. // FpcrValue (a0) - Supplies the new value for the FPCR.
  81. //
  82. // Return Value:
  83. //
  84. // None.
  85. //
  86. //--
  87. NESTED_ENTRY(_set_fpcr, FpFrameLength, ra)
  88. lda sp, -FpFrameLength(sp) // allocate stack frame
  89. PROLOGUE_END
  90. stq a0, FpCr(sp) // store integer register in order to
  91. ldt f0, FpCr(sp) // load floating register with fpcr
  92. excb // wait for all pending traps
  93. mt_fpcr f0, f0, f0 // set new fpcr
  94. excb // block against new traps
  95. lda sp, FpFrameLength(sp) // deallocate stack frame
  96. ret zero, (ra) // return
  97. .end _set_fpcr
  98. SBTTL("Get Software Floating Point Control and Status Register")
  99. //++
  100. //
  101. // ULONG
  102. // _get_softfpcr (
  103. // VOID
  104. // )
  105. //
  106. // Routine Description:
  107. //
  108. // This function obtains the current software FPCR value.
  109. //
  110. // Arguments:
  111. //
  112. // None.
  113. //
  114. // Return Value:
  115. //
  116. // The current value of the software FPCR is returned as the function value.
  117. //
  118. //--
  119. LEAF_ENTRY(_get_softfpcr)
  120. GET_THREAD_ENVIRONMENT_BLOCK // get Teb address in v0
  121. ldl v0, TeSoftFpcr(v0) // get current software fpcr value
  122. ret zero, (ra) // return
  123. .end _get_softfpcr
  124. SBTTL("Set Software Floating Point Control and Status Register")
  125. //++
  126. //
  127. // VOID
  128. // _set_softfpcr (
  129. // ULONG SoftFpcrValue
  130. // )
  131. //
  132. // Routine Description:
  133. //
  134. // This function sets a new value in the software FPCR.
  135. //
  136. // Arguments:
  137. //
  138. // SoftFpcrValue (a0) - Supplies the new value for the software FPCR.
  139. //
  140. // Return Value:
  141. //
  142. // None.
  143. //
  144. //--
  145. LEAF_ENTRY(_set_softfpcr)
  146. GET_THREAD_ENVIRONMENT_BLOCK // get Teb address in v0
  147. stl a0, TeSoftFpcr(v0) // store new software fpcr value
  148. ret zero, (ra) // return
  149. .end _set_softfpcr
  150. SBTTL("Set New Floating Control Register Value")
  151. //++
  152. //
  153. // ULONG
  154. // _ctrlfp (
  155. // IN ULONG newctrl,
  156. // IN ULONG mask
  157. // )
  158. //
  159. // Routine Description:
  160. //
  161. // For Alpha AXP this function sets nothing. It returns the current
  162. // rounding mode and the current IEEE exception disable mask in the
  163. // fp32 internal control word format.
  164. //
  165. // Arguments:
  166. //
  167. // newctrl (a0) - Supplies the new control bits to be set.
  168. //
  169. // mask (a1) - Supplies the mask of bits to be set.
  170. //
  171. // Return Value:
  172. //
  173. // oldctrl (v0) - Returns the old value of the control bits.
  174. //
  175. //
  176. //--
  177. NESTED_ENTRY(_ctrlfp, FpFrameLength, ra)
  178. lda sp, -FpFrameLength(sp) // allocate stack frame
  179. PROLOGUE_END
  180. //
  181. // Get the dynamic rounding mode from the FPCR.
  182. //
  183. excb // wait for all pending traps
  184. mf_fpcr f0, f0, f0 // get current fpcr
  185. excb // block against new traps
  186. stt f0, FpCr(sp) // store floating register in order to
  187. ldq t0, FpCr(sp) // load integer register with fpcr
  188. srl t0, 58, t0 // shift rounding mode to low end
  189. and t0, 0x3, t0 // isolate rounding mode bits
  190. sll t0, 58 - 32, t0 // shift to internal cw format
  191. //
  192. // Get the IEEE exception mask bits and status bits from the software FPCR.
  193. //
  194. GET_THREAD_ENVIRONMENT_BLOCK // get Teb address in v0
  195. ldl v0, TeSoftFpcr(v0) // get current software fpcr value
  196. xor v0, 0x3e, v0 // convert enable bits to disable bits
  197. or v0, t0, v0 // merge with current rounding mode
  198. lda sp, FpFrameLength(sp) // deallocate stack frame
  199. ret zero, (ra) // return
  200. .end _ctrlfp
  201. SBTTL("Get IEEE Sticky Status Bits")
  202. //++
  203. //
  204. // ULONG
  205. // _statfp (
  206. // VOID
  207. // )
  208. //
  209. // Routine Description:
  210. //
  211. // This function gets the IEEE sticky status bits from the software FPCR.
  212. //
  213. // Arguments:
  214. //
  215. // None.
  216. //
  217. // Return Value:
  218. //
  219. // The current value of the status word is returned as the function value.
  220. //
  221. //--
  222. LEAF_ENTRY(_statfp)
  223. GET_THREAD_ENVIRONMENT_BLOCK // get Teb address in v0
  224. ldl v0, TeSoftFpcr(v0) // get current software fpcr value
  225. ret zero, (ra) // return
  226. .end _statfp
  227. SBTTL("Clear IEEE Sticky Status Bits")
  228. //++
  229. //
  230. // ULONG
  231. // _clrfp (
  232. // VOID
  233. // )
  234. //
  235. // Routine Description:
  236. //
  237. // This function clears the IEEE sticky status bits in the software FPCR.
  238. //
  239. // Arguments:
  240. //
  241. // None.
  242. //
  243. // Return Value:
  244. //
  245. // The previous value of the status word is returned as the function value.
  246. //
  247. //--
  248. LEAF_ENTRY(_clrfp)
  249. GET_THREAD_ENVIRONMENT_BLOCK // get Teb address in v0
  250. ldl t0, TeSoftFpcr(v0) // get current software fpcr value
  251. bic t0, 0x3e0000, t1 // clear status bits
  252. stl t1, TeSoftFpcr(v0) // store new software fpcr value
  253. mov t0, v0 // get previous value
  254. ret zero, (ra) // return
  255. .end _clrfp
  256. SBTTL("Set IEEE Sticky Status Bits")
  257. //++
  258. //
  259. // VOID
  260. // _set_statfp (
  261. // IN ULONG sw
  262. // )
  263. //
  264. // Routine Description:
  265. //
  266. // This function sets a IEEE sticky status bit in the software FPCR.
  267. //
  268. // Arguments:
  269. //
  270. // sw (a0) - Supplies the status bits to be set.
  271. //
  272. // Return Value:
  273. //
  274. // None.
  275. //
  276. //--
  277. LEAF_ENTRY(_set_statfp)
  278. GET_THREAD_ENVIRONMENT_BLOCK // get Teb address in v0
  279. ldl t0, TeSoftFpcr(v0) // get current software fpcr value
  280. or t0, a0, t0 // set status bit(s)
  281. stl t0, TeSoftFpcr(v0) // store new software fpcr value
  282. ret zero, (ra) // return
  283. .end _set_statfp
  284. SBTTL("Convert Signal NaN to Quiet NaN")
  285. //++
  286. //
  287. // double
  288. // _nan2qnan (
  289. // IN double x
  290. // )
  291. //
  292. // Routine Description:
  293. //
  294. // This function converts a signaling NaN to a quiet NaN without causing
  295. // a hardware trap.
  296. //
  297. // Arguments:
  298. //
  299. // x (f16) - Supplies the signal NaN value to be converted.
  300. //
  301. // Return Value:
  302. //
  303. // The quiet NaN value is returned as the function value.
  304. //
  305. //--
  306. NESTED_ENTRY(_nan2qnan, FpFrameLength, ra)
  307. lda sp, -FpFrameLength(sp) // allocate stack frame
  308. PROLOGUE_END
  309. stt f16, FpCr(sp) // store floating register in order to
  310. ldq t0, FpCr(sp) // load integer register
  311. ldiq t1, (1 << 51) // get NaN bit
  312. or t0, t1, t0 // convert NaN to QNaN
  313. stq t0, FpCr(sp) // store integer register in order to
  314. ldt f0, FpCr(sp) // load floating register
  315. lda sp, FpFrameLength(sp) // deallocate stack frame
  316. ret zero, (ra) // return
  317. .end _nan2qnan