Something went wrong. Try again.
Cider Isn't Darwin Emulation, Really
Something went wrong. Try again.
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677/* * floorl.s * * by Ian Ollmann * * Copyright (c) Apple Inc. 2007. All Rights Reserved. * * C99 implementation of floorl for __i386__ and __x86_64__. */ #include <machine/asm.h>#include "abi.h"
ENTRY( floorl ) movswl 8+FRAME_SIZE( STACKP ), %eax // load signed exponent movl %eax, %edx // sign + exponent andl $0x7fff, %eax // exponent subl $0x3fff, %eax // remove bias cmpl $63, %eax // if( |x| >= 0x1.0p63 || |x| < 1.0 || isnan(x) ) jae 2f // goto 2 movl $63, %ecx movq FRAME_SIZE( STACKP ), %xmm0 // significand subl %eax, %ecx // 63 - exponent pcmpeqb %xmm1, %xmm1 // -1LL movd %ecx, %xmm7 // 63-exponent pxor %xmm2, %xmm2 // 0 psubq %xmm1, %xmm2 // 1 movdqa %xmm2, %xmm1 // 1 psllq %xmm7, %xmm2 // one's bit psubq %xmm1, %xmm2 // fract mask pandn %xmm0, %xmm2 movq %xmm2, FRAME_SIZE( STACKP ) pcmpeqd %xmm2, %xmm0 pmovmskb %xmm0, %eax cmp $0xffff, %eax fldt FRAME_SIZE( STACKP ) // result je 1f //need to set the inexact flag and correct rounding sarl $31, %edx andl $0xbf800000, %edx movl %edx, FRAME_SIZE(STACKP) fadds FRAME_SIZE( STACKP ) // correct rounding
// set inexact fldpi fmul %st(0), %st(0) fstp %st(0) 1: ret
// |x| >= 0x1.0p63 || |x| < 1.0 || isnan(x) 2: jge 3f // |x| < 1.0 fldt FRAME_SIZE( STACKP ) // { x } fldz // { 0, x } fucomip %st(1), %st(0) // { x } je 1b
fistpl FRAME_SIZE( STACKP ) fldz // { 0 } fld1 // { 1, 0 } fchs // { -1, 0 } fcmovb %st(1), %st(0) fstp %st(1) ret
// |x| >= 0x1.0p63 || isnan(x) 3: fldt FRAME_SIZE(STACKP) fldz faddp ret