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 421: 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 2881: 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 3342: / 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 3403: 341 movl $1,%eax 3421: 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 3681: 369 .end 370 371