rint.s   [plain text]


//  double rint(double x)
//
//  returns the argument rounded to an integral value using the prevailing
//  rounding mode.  rintf is allowed to raise the "inexact" flag if the result
//  differs from the argument (C99 7.12.9.4).
//
//  -- Stephen Canon, January 2010

.globl _rint

#if defined __i386__

.text
.align 4
_rint:
    fldl        4(%esp)
    frndint
    ret
    
#elif defined __x86_64__

.literal8
absmask:    .quad 0x7fffffffffffffff
twop52:     .quad 0x4330000000000000

.text
.align 4
_rint:
    movd        %xmm0,          %rcx
    mov         %rcx,           %rdx
    and         absmask(%rip),  %rcx    // |x|
    xor         %rcx,           %rdx    // signbit(x)
    movd        %rdx,           %xmm1
    cmp         twop52(%rip),   %rcx    // if |x| >= 0x1.0p52 or isnan(x)
    jae         L_xIsIntegral           //    just return x
    
    cvtsd2si    %xmm0,          %rax
    cvtsi2sd    %rax,           %xmm0
    orpd        %xmm1,          %xmm0   // restore signbit
L_xIsIntegral:
    ret

#else
    #error "this implementation only supports 32- and 64-bit intel."
#endif