Leaked source code of windows server 2003
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.

362 lines
7.8 KiB

  1. .file "ldexpf.s"
  2. // Copyright (c) 2000, 2001, Intel Corporation
  3. // All rights reserved.
  4. //
  5. // Contributed 2/2/2000 by John Harrison, Ted Kubaska, Bob Norin, Shane Story,
  6. // and Ping Tak Peter Tang of the Computational Software Lab, Intel Corporation.
  7. //
  8. // WARRANTY DISCLAIMER
  9. //
  10. // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  11. // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  12. // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  13. // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR ITS
  14. // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
  15. // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
  16. // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
  17. // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
  18. // OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY OR TORT (INCLUDING
  19. // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  20. // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  21. //
  22. // Intel Corporation is the author of this code, and requests that all
  23. // problem reports or change requests be submitted to it directly at
  24. // http://developer.intel.com/opensource.
  25. //
  26. // History
  27. //==============================================================
  28. // 2/02/00 Initial version
  29. // 1/26/01 ldexpf completely reworked and now standalone version
  30. //
  31. // API
  32. //==============================================================
  33. // float = ldexpf (float x, int n)
  34. // input floating point f8 and int n (r33)
  35. // output floating point f8
  36. //
  37. // Returns x* 2**n using an fma and detects overflow
  38. // and underflow.
  39. //
  40. //
  41. FR_Big = f6
  42. FR_NBig = f7
  43. FR_Floating_X = f8
  44. FR_Result = f8
  45. FR_Result2 = f9
  46. FR_Result3 = f11
  47. FR_Norm_X = f12
  48. FR_Two_N = f14
  49. FR_Two_to_Big = f15
  50. GR_N_Biased = r15
  51. GR_Big = r16
  52. GR_NBig = r17
  53. GR_Scratch = r18
  54. GR_Scratch1 = r19
  55. GR_Bias = r20
  56. GR_N_as_int = r21
  57. GR_SAVE_B0 = r32
  58. GR_SAVE_GP = r33
  59. GR_SAVE_PFS = r34
  60. GR_Parameter_X = r35
  61. GR_Parameter_Y = r36
  62. GR_Parameter_RESULT = r37
  63. GR_Tag = r38
  64. .align 32
  65. .global ldexpf
  66. .section .text
  67. .proc ldexpf
  68. .align 32
  69. ldexpf:
  70. //
  71. // Is x NAN, INF, ZERO, +-?
  72. // Build the exponent Bias
  73. //
  74. { .mfi
  75. alloc r32=ar.pfs,1,2,4,0
  76. fclass.m.unc p7,p0 = FR_Floating_X, 0xe7 //@snan | @qnan | @inf | @zero
  77. addl GR_Bias = 0x0FFFF,r0
  78. }
  79. //
  80. // Sign extend input
  81. // Is N zero?
  82. // Normalize x
  83. //
  84. { .mfi
  85. cmp.eq.unc p6,p0 = r33,r0
  86. fnorm.s1 FR_Norm_X = FR_Floating_X
  87. sxt4 GR_N_as_int = r33
  88. }
  89. ;;
  90. //
  91. // Normalize x
  92. // Branch and return special values.
  93. // Create -35000
  94. // Create 35000
  95. //
  96. { .mfi
  97. addl GR_Big = 35000,r0
  98. nop.f 0
  99. add GR_N_Biased = GR_Bias,GR_N_as_int
  100. }
  101. { .mfb
  102. addl GR_NBig = -35000,r0
  103. (p7) fma.s.s0 FR_Result = FR_Floating_X,f1, f0
  104. (p7) br.ret.spnt b0
  105. };;
  106. //
  107. // Build the exponent Bias
  108. // Return x when N = 0
  109. //
  110. { .mfi
  111. setf.exp FR_Two_N = GR_N_Biased
  112. nop.f 0
  113. addl GR_Scratch1 = 0x063BF,r0
  114. }
  115. { .mfb
  116. addl GR_Scratch = 0x019C3F,r0
  117. (p6) fma.s.s0 FR_Result = FR_Floating_X,f1, f0
  118. (p6) br.ret.spnt b0
  119. };;
  120. //
  121. // Create 2*big
  122. // Create 2**-big
  123. // Is N > 35000
  124. // Is N < -35000
  125. // Raise Denormal operand flag with compare
  126. // Main path, create 2**N
  127. //
  128. { .mfi
  129. setf.exp FR_NBig = GR_Scratch1
  130. nop.f 0
  131. cmp.ge.unc p6, p0 = GR_N_as_int, GR_Big
  132. }
  133. { .mfi
  134. setf.exp FR_Big = GR_Scratch
  135. fcmp.ge.s0 p0,p11 = FR_Floating_X,f0
  136. cmp.le.unc p8, p0 = GR_N_as_int, GR_NBig
  137. };;
  138. //
  139. // Adjust 2**N if N was very small or very large
  140. //
  141. { .mfi
  142. nop.m 0
  143. (p6) fma.s1 FR_Two_N = FR_Big,f1,f0
  144. nop.i 0
  145. }
  146. { .mlx
  147. nop.m 999
  148. movl GR_Scratch = 0x000000000003007F
  149. };;
  150. { .mfi
  151. nop.m 0
  152. (p8) fma.s1 FR_Two_N = FR_NBig,f1,f0
  153. nop.i 0
  154. }
  155. { .mlx
  156. nop.m 999
  157. movl GR_Scratch1= 0x000000000001007F
  158. };;
  159. // Set up necessary status fields
  160. //
  161. // S0 user supplied status
  162. // S2 user supplied status + WRE + TD (Overflows)
  163. // S3 user supplied status + FZ + TD (Underflows)
  164. //
  165. { .mfi
  166. nop.m 999
  167. fsetc.s3 0x7F,0x41
  168. nop.i 999
  169. }
  170. { .mfi
  171. nop.m 999
  172. fsetc.s2 0x7F,0x42
  173. nop.i 999
  174. };;
  175. //
  176. // Do final operation
  177. //
  178. { .mfi
  179. setf.exp FR_NBig = GR_Scratch
  180. fma.s.s0 FR_Result = FR_Two_N,FR_Norm_X,f0
  181. nop.i 999
  182. }
  183. { .mfi
  184. nop.m 999
  185. fma.s.s3 FR_Result3 = FR_Two_N,FR_Norm_X,f0
  186. nop.i 999
  187. };;
  188. { .mfi
  189. setf.exp FR_Big = GR_Scratch1
  190. fma.s.s2 FR_Result2 = FR_Two_N,FR_Norm_X,f0
  191. nop.i 999
  192. };;
  193. // Check for overflow or underflow.
  194. // Restore s3
  195. // Restore s2
  196. //
  197. { .mfi
  198. nop.m 0
  199. fsetc.s3 0x7F,0x40
  200. nop.i 999
  201. }
  202. { .mfi
  203. nop.m 0
  204. fsetc.s2 0x7F,0x40
  205. nop.i 999
  206. };;
  207. //
  208. // Is the result zero?
  209. //
  210. { .mfi
  211. nop.m 999
  212. fclass.m.unc p6, p0 = FR_Result3, 0x007
  213. nop.i 999
  214. }
  215. { .mfi
  216. addl GR_Tag = 148, r0
  217. fcmp.ge.unc.s1 p7, p8 = FR_Result2 , FR_Big
  218. nop.i 0
  219. };;
  220. //
  221. // Detect masked underflow - Tiny + Inexact Only
  222. //
  223. { .mfi
  224. nop.m 999
  225. (p6) fcmp.neq.unc.s1 p6, p0 = FR_Result , FR_Result2
  226. nop.i 999
  227. };;
  228. //
  229. // Is result bigger the allowed range?
  230. // Branch out for underflow
  231. //
  232. { .mfb
  233. (p6) addl GR_Tag = 149, r0
  234. (p8) fcmp.le.unc.s1 p9, p10 = FR_Result2 , FR_NBig
  235. (p6) br.cond.spnt ldexpf_UNDERFLOW
  236. };;
  237. //
  238. // Branch out for overflow
  239. //
  240. { .mbb
  241. nop.m 0
  242. (p7) br.cond.spnt ldexpf_OVERFLOW
  243. (p9) br.cond.spnt ldexpf_OVERFLOW
  244. };;
  245. //
  246. // Return from main path.
  247. //
  248. { .mfb
  249. nop.m 999
  250. nop.f 0
  251. br.ret.sptk b0;;
  252. }
  253. .endp ldexpf
  254. .proc __libm_error_region
  255. __libm_error_region:
  256. ldexpf_OVERFLOW:
  257. ldexpf_UNDERFLOW:
  258. //
  259. // Get stack address of N
  260. //
  261. .prologue
  262. { .mfi
  263. add GR_Parameter_Y=-32,sp
  264. nop.f 0
  265. .save ar.pfs,GR_SAVE_PFS
  266. mov GR_SAVE_PFS=ar.pfs
  267. }
  268. //
  269. // Adjust sp
  270. //
  271. { .mfi
  272. .fframe 64
  273. add sp=-64,sp
  274. nop.f 0
  275. mov GR_SAVE_GP=gp
  276. };;
  277. //
  278. // Store N on stack in correct position
  279. // Locate the address of x on stack
  280. //
  281. { .mmi
  282. st8 [GR_Parameter_Y] = GR_N_as_int,16
  283. add GR_Parameter_X = 16,sp
  284. .save b0, GR_SAVE_B0
  285. mov GR_SAVE_B0=b0
  286. };;
  287. //
  288. // Store x on the stack.
  289. // Get address for result on stack.
  290. //
  291. .body
  292. { .mib
  293. stfs [GR_Parameter_X] = FR_Norm_X
  294. add GR_Parameter_RESULT = 0,GR_Parameter_Y
  295. nop.b 0
  296. }
  297. { .mib
  298. stfs [GR_Parameter_Y] = FR_Result
  299. add GR_Parameter_Y = -16,GR_Parameter_Y
  300. br.call.sptk b0=__libm_error_support#
  301. };;
  302. //
  303. // Get location of result on stack
  304. //
  305. { .mmi
  306. nop.m 0
  307. nop.m 0
  308. add GR_Parameter_RESULT = 48,sp
  309. };;
  310. //
  311. // Get the new result
  312. //
  313. { .mmi
  314. ldfs FR_Result = [GR_Parameter_RESULT]
  315. .restore
  316. add sp = 64,sp
  317. mov b0 = GR_SAVE_B0
  318. };;
  319. //
  320. // Restore gp, ar.pfs and return
  321. //
  322. { .mib
  323. mov gp = GR_SAVE_GP
  324. mov ar.pfs = GR_SAVE_PFS
  325. br.ret.sptk b0
  326. };;
  327. .endp __libm_error_region
  328. .type __libm_error_support#,@function
  329. .global __libm_error_support#