Something went wrong. Try again.
Cider Isn't Darwin Emulation, Really
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596/* Single-precision roundf, reimplemented using integer operations * for improved performance, especially on in-order machines. * * Steve Canon, March 2009. */
#if defined __i386__
.text.align 4.globl _roundf_roundf: mov 4(%esp), %eax // load the input, x movss 4(%esp), %xmm0 and $0x7f800000, %eax // |x| mov $23, %ecx mov $0x1, %edx sar %cl, %eax // exponent(x) + 1 sub $0x7e, %eax // if |x| < 1.0f. goto 2 jbe 2f sub %eax, %ecx // 23 - exponent(x) - 1 js 1f // return x if |x| >= 0x1.0p23 shl %cl, %edx mov $0xfffffffe, %eax shl %cl, %eax add %edx, 4(%esp) // add 0.5 (ish -- non-integral bits are garbage) and %eax, 4(%esp) // truncate cvttps2dq %xmm0, %xmm0 // raise inexact1: flds 4(%esp) ret.align 42: je 3f // if |x| >= 0.5f, goto 3 andl $0x80000000, 4(%esp) // copysign(0.0, x) cvttps2dq %xmm0, %xmm0 // raise inexact flds 4(%esp) ret.align 43: addl $0x00800000, 4(%esp) andl $0xff800000, 4(%esp) // copysign(1.0, x) cvttps2dq %xmm0, %xmm0 // raise inexact flds 4(%esp) ret #elif defined __x86_64__
.const.align 4mzero: .long 0x80000000.align 4expbit: .long 0x00800000.align 4expmask:.long 0xff800000
.text.align 4.globl _roundf_roundf: movd %xmm0, %eax and $0x7f800000, %eax // |x| mov $23, %ecx mov $0x1, %edx sar %cl, %eax // exponent(x) + 1 sub $0x7e, %eax // if |x| < 1.0f. goto 2 jbe 2f sub %eax, %ecx // 23 - exponent(x) - 1 js 1f // return x if |x| >= 0x1.0p23 shl %cl, %edx mov $0xfffffffe, %eax shl %cl, %eax movd %edx, %xmm2 movd %eax, %xmm3 cvttps2dq %xmm0, %xmm1 // raise inexact paddd %xmm2, %xmm0 // add 0.5 (ish -- non-integral bits are garbage) pand %xmm3, %xmm0 // truncate1: ret.align 42: je 3f // if |x| >= 0.5f, goto 3 cvttps2dq %xmm0, %xmm1 // raise inexact andps mzero(%rip), %xmm0 // copysign(0.0, x) ret.align 43: cvttps2dq %xmm0, %xmm1 // raise inexact paddd expbit(%rip), %xmm0 pand expmask(%rip), %xmm0 // copysign(1.0, x) ret
#else #error unknown arch#endif