1 /
   2 / CDDL HEADER START
   3 /
   4 / The contents of this file are subject to the terms of the
   5 / Common Development and Distribution License (the "License").
   6 / You may not use this file except in compliance with the License.
   7 /
   8 / You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9 / or http://www.opensolaris.org/os/licensing.
  10 / See the License for the specific language governing permissions
  11 / and limitations under the License.
  12 /
  13 / When distributing Covered Code,  this CDDL HEADER in each
  14 / file and  the License file at usr/src/OPENSOLARIS.LICENSE.
  15 / If applicable, add the following below this CDDL HEADER, with the
  16 / fields enclosed by brackets "[]" replaced with your own identifying
  17 / information: Portions Copyright [yyyy] [name of copyright owner]
  18 /
  19 / CDDL HEADER END
  20 /
  21 / Copyright 2011 Nexenta Systems, Inc.  All rights reserved.
  22 /
  23 / Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
  24 / Use is subject to license terms.
  25 /
  26 
  27 / Portions of this file are duplicated as GCC inline assembly in
  28 / libm_inlines.h.  Keep them in sync.
  29 
  30         .inline __ieee754_sqrt,0
  31         fldl    (%esp)
  32         fsqrt
  33         .end
  34 
  35         .inline __inline_rint,0
  36         fldl    (%esp)
  37         movl    4(%esp),%eax
  38         andl    $0x7fffffff,%eax
  39         cmpl    $0x43300000,%eax
  40         jae     1f
  41         frndint
  42 1:
  43         fwait           / in case we jumped around the frndint
  44         .end
  45 
  46         .inline __inline_sqrtf,0
  47         flds    (%esp)
  48         fsqrt
  49         .end
  50 
  51         .inline __inline_sqrt,0
  52         fldl    (%esp)
  53         fsqrt
  54         .end
  55 
  56         .inline __inline_fstsw,0
  57         fstsw   %ax
  58         .end
  59 
  60 /
  61 / 00 - 24 bits
  62 / 01 - reserved
  63 / 10 - 53 bits
  64 / 11 - 64 bits
  65 /
  66         .inline __swapRP,0
  67         subl    $4,%esp
  68         fstcw   (%esp)
  69         movw    (%esp),%ax
  70         movw    %ax,%cx
  71         andw    $0xfcff,%cx
  72         movl    4(%esp),%edx            ///
  73         andl    $0x3,%edx
  74         shlw    $8,%dx
  75         orw     %dx,%cx
  76         movl    %ecx,(%esp)
  77         fldcw   (%esp)
  78         shrw    $8,%ax
  79         andl    $0x3,%eax
  80         addl    $4,%esp
  81         .end
  82 
  83 /
  84 / 00 - Round to nearest, with even preferred
  85 / 01 - Round down
  86 / 10 - Round up
  87 / 11 - Chop
  88 /
  89         .inline __swap87RD,0
  90         subl    $4,%esp
  91         fstcw   (%esp)
  92         movw    (%esp),%ax
  93         movw    %ax,%cx
  94         andw    $0xf3ff,%cx
  95         movl    4(%esp),%edx
  96         andl    $0x3,%edx
  97         shlw    $10,%dx
  98         orw     %dx,%cx
  99         movl    %ecx,(%esp)
 100         fldcw   (%esp)
 101         shrw    $10,%ax
 102         andl    $0x3,%eax
 103         addl    $4,%esp
 104         .end
 105 
 106 /
 107 /       Convert Top-of-Stack to long
 108 /
 109         .inline __xtol,0
 110         subl    $8,%esp                 / 8 bytes of stack space
 111         fstcw   2(%esp)                 / byte[2:3] = old_cw
 112         movw    2(%esp),%ax
 113         andw    $0xf3ff,%ax
 114         orw     $0x0c00,%ax             / RD set to Chop
 115         movw    %ax,(%esp)              / byte[0:1] = new_cw
 116         fldcw   (%esp)                  / set new_cw
 117         fistpl  4(%esp)                 / byte[4:7] = converted long
 118         fstcw   (%esp)                  / restore old RD
 119         movw    (%esp),%ax
 120         andw    $0xf3ff,%ax
 121         movw    2(%esp),%dx
 122         andw    $0x0c00,%dx
 123         orw     %ax,%dx
 124         movw    %dx,2(%esp)
 125         fldcw   2(%esp)
 126         movl    4(%esp),%eax
 127         addl    $8,%esp
 128         .end
 129 
 130         .inline __ceil,0
 131         subl    $8,%esp
 132         fstcw   (%esp)
 133         fldl    8(%esp)                 ///
 134         movw    (%esp),%cx
 135         orw     $0x0c00,%cx
 136         xorw    $0x0400,%cx
 137         movw    %cx,4(%esp)
 138         fldcw   4(%esp)                 / set RD = up
 139         frndint
 140         fstcw   4(%esp)                 / restore RD
 141         movw    4(%esp),%dx
 142         andw    $0xf3ff,%dx
 143         movw    (%esp),%cx
 144         andw    $0x0c00,%cx
 145         orw     %dx,%cx
 146         movw    %cx,(%esp)
 147         fldcw   (%esp)
 148         addl    $8,%esp
 149         .end
 150 
 151         .inline __copysign,0
 152         movl    4(%esp),%eax            /// eax <-- hi_32(x)
 153         movl    12(%esp),%ecx           /// ecx <-- hi_32(y)
 154         andl    $0x7fffffff,%eax        / eax <-- hi_32(abs(x))
 155         andl    $0x80000000,%ecx        / ecx[31] <-- sign_bit(y)
 156         orl     %ecx,%eax               / eax <-- hi_32(__copysign(x,y))
 157         movl    (%esp),%ecx             /// ecx <-- lo_32(x)
 158                                         /       = lo_32(__copysign(x,y))
 159         subl    $8,%esp                 / set up loading dock for result
 160         movl    %ecx,(%esp)             / copy lo_32(result) to loading dock
 161         movl    %eax,4(%esp)            / copy hi_32(result) to loading dock
 162         fldl    (%esp)                  / load __copysign(x,y)
 163         fwait                           / in case fldl causes exception
 164         addl    $8,%esp                 / restore stack-pointer
 165         .end
 166 
 167         .inline __d_sqrt_,0
 168         movl    (%esp),%eax
 169         fldl    (%eax)
 170         fsqrt
 171         .end
 172 
 173         .inline __fabs,0
 174         fldl    (%esp)                  ///
 175         fabs
 176         .end
 177 
 178         .inline __fabsf,0
 179         flds    (%esp)
 180         fabs
 181         .end
 182 
 183         .inline __fabsl,0
 184         fldt    (%esp)
 185         fabs
 186         .end
 187 
 188 /
 189 /       branchless _finite
 190 /
 191         .inline _finite,0
 192         movl    4(%esp),%eax            /// eax <-- hi_32(x)
 193         notl    %eax                    / not(bexp) = 0 iff bexp = all 1's
 194         andl    $0x7ff00000,%eax
 195         negl    %eax
 196         shrl    $31,%eax
 197         .end
 198 
 199         .inline __floor,0
 200         subl    $8,%esp
 201         fstcw   (%esp)
 202         fldl    8(%esp)                 ///
 203         movw    (%esp),%cx
 204         orw     $0x0c00,%cx
 205         xorw    $0x0800,%cx
 206         movw    %cx,4(%esp)
 207         fldcw   4(%esp)                 / set RD = down
 208         frndint
 209         fstcw   4(%esp)                 / restore RD
 210         movw    4(%esp),%dx
 211         andw    $0xf3ff,%dx
 212         movw    (%esp),%cx
 213         andw    $0x0c00,%cx
 214         orw     %dx,%cx
 215         movw    %cx,(%esp)
 216         fldcw   (%esp)                  / restore RD
 217         addl    $8,%esp
 218         .end
 219 
 220         .inline __isnanf,0
 221         movl    (%esp),%eax
 222         andl    $0x7fffffff,%eax
 223         negl    %eax
 224         addl    $0x7f800000,%eax
 225         shrl    $31,%eax
 226         .end
 227 
 228 
 229         .inline __isnormal,0
 230                                         / TRUE iff (x is _finite, but
 231                                         /           neither subnormal nor +/-0)
 232                                         /      iff (0 < bexp(x) < 0x7ff)
 233         movl    4(%esp),%eax            / eax <-- hi_32(x)
 234         andl    $0x7ff00000,%eax        / eax[20..30]  <-- bexp(x),
 235                                         / rest_of(eax) <-- 0
 236         pushfl
 237         popl    %ecx                    / bit 6 of ecx <-- not bexp(x)
 238         subl    $0x7ff00000,%eax
 239         pushfl
 240         popl    %eax                    / bit 6 of eax <-- not bexp(x)
 241         orl     %ecx,%eax
 242         andl    $0x40,%eax
 243         xorl    $0x40,%eax
 244         shrl    $6,%eax
 245         .end
 246 
 247         .inline __issubnormal,0
 248                                         / TRUE iff (bexp(x) = 0 and
 249                                         /           frac(x) /= 0)
 250         movl    $0,%eax
 251         movl    4(%esp),%ecx            / ecx <-- hi_32(x)
 252         andl    $0x7fffffff,%ecx        / ecx <-- hi_32(abs(x))
 253         cmpl    $0x00100000,%ecx        / is bexp(x) = 0?
 254         adcl    $0,%eax                 / jump if bexp(x) = 0
 255         orl     (%esp),%ecx             / = 0 iff sgnfcnd(x) = 0
 256                                         /     iff x = +/- 0.0 here
 257         pushfl
 258         popl    %ecx
 259         andl    $0x40,%ecx
 260         xorl    $0x40,%ecx
 261         shrl    $6,%ecx
 262         andl    %ecx,%eax
 263         .end
 264 
 265         .inline __iszero,0
 266         movl    4(%esp),%eax            / eax <-- hi_32(x)
 267         andl    $0x7fffffff,%eax        / eax <-- hi_32(abs(x))
 268         orl     (%esp),%eax             / = 0 iff x = +/- 0.0
 269         pushfl
 270         popl    %eax
 271         andl    $0x40,%eax
 272         shrl    $6,%eax
 273         .end
 274 
 275         .inline __r_sqrt_,0
 276         movl    (%esp),%eax
 277         flds    (%eax)
 278         fsqrt
 279         .end
 280 
 281         .inline __rint,0
 282         fldl    (%esp)
 283         movl    4(%esp),%eax
 284         andl    $0x7fffffff,%eax
 285         cmpl    $0x43300000,%eax
 286         jae     1f
 287         frndint
 288 1:
 289         fwait                   / in case we jumped around frndint
 290         .end
 291 
 292         .inline __scalbn,0
 293         fildl   8(%esp)                 /// convert N to extended
 294         fldl    (%esp)                  /// push x
 295         fscale
 296         fstp    %st(1)
 297         .end
 298 
 299         .inline __signbit,0
 300         movl    4(%esp),%eax            /// high part of x
 301         shrl    $31,%eax
 302         .end
 303 
 304         .inline __signbitf,0
 305         movl    (%esp),%eax
 306         shrl    $31,%eax
 307         .end
 308 
 309         .inline __sqrt,0
 310         fldl    (%esp)
 311         fsqrt
 312         .end
 313 
 314         .inline __sqrtf,0
 315         flds    (%esp)
 316         fsqrt
 317         .end
 318 
 319         .inline __sqrtl,0
 320         fldt    (%esp)
 321         fsqrt
 322         .end
 323 
 324         .inline __isnanl,0
 325         movl    8(%esp),%eax            / ax <-- sign bit and __exp
 326         andl    $0x00007fff,%eax
 327         jz      1f                      / jump if __exp is all 0
 328         xorl    $0x00007fff,%eax
 329         jz      2f                      / jump if __exp is all 1
 330         testl   $0x80000000,4(%esp)
 331         jz      3f                      / jump if leading bit is 0
 332         movl    $0,%eax
 333         jmp     1f
 334 2:                                      / note that %eax = 0 from before
 335         cmpl    $0x80000000,4(%esp)     / what is first half of __significand?
 336         jnz     3f                      / jump if not equal to 0x80000000
 337         testl   $0xffffffff,(%esp)      / is second half of __significand 0?
 338         jnz     3f                      / jump if not equal to 0
 339         jmp     1f
 340 3:
 341         movl    $1,%eax
 342 1:
 343         .end
 344 
 345         .inline __f95_signf,0
 346         sub     $4,%esp
 347         mov     4(%esp),%edx
 348         mov     (%edx),%eax
 349         and     $0x7fffffff,%eax
 350         mov     8(%esp),%edx
 351         mov     (%edx),%ecx
 352         and     $0x80000000,%ecx
 353         or      %ecx,%eax
 354         mov     %eax,(%esp)
 355         flds    (%esp)
 356         add     $4,%esp
 357         .end
 358 
 359         .inline __f95_sign,0
 360         mov     (%esp),%edx
 361         fldl    (%edx)
 362         fabs
 363         mov     4(%esp),%edx
 364         mov     4(%edx),%eax
 365         test    %eax,%eax
 366         jns     1f
 367         fchs
 368 1:
 369         .end
 370