Something went wrong. Try again.
Cider Isn't Darwin Emulation, Really
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114/* * truncl.s * LibmV5 * * Created by Ian Ollmann on 9/1/05. * Copyright 2005 Apple Computer. All rights reserved. * */
#include "machine/asm.h"
#define LOCAL_STACK_SIZE 12#include "abi.h"
#if defined( __i386__ )
ENTRY(truncl) 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 // 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 } fldz // { 0, 0 } fchs // { -0, 0 } fcmovb %st(1), %st(0) fstp %st(1) ret
// |x| >= 0x1.0p63 || isnan(x) 3: fldt FRAME_SIZE(STACKP) fldz faddp ret
#elif defined( __x86_64__ )
ENTRY(truncl) fldt FRAME_SIZE( STACKP ) // { x } movzwl 8+FRAME_SIZE( STACKP ), %eax movswl %cx, %edx andl $0x7fff, %eax subl $0x3fff, %eax // push |x| < 1.0L negative cmpl $63, %eax jae 1f #if defined( __SSE3__ ) fisttpll FRAME_SIZE( STACKP ) fildll FRAME_SIZE( STACKP )#else fnstcw FRAME_SIZE( STACKP ) movw FRAME_SIZE( STACKP ), %cx movw %cx, %dx orw $0xc00, %cx movw %cx, FRAME_SIZE( STACKP ) fldcw FRAME_SIZE( STACKP ) frndint movw %dx, FRAME_SIZE( STACKP ) fldcw FRAME_SIZE( STACKP ) #endif ret
1: // |x| < 1.0L || |x| > 0x1.0p63L || isnan( x ) jge 2f
// |x| < 1.0L, return 0 of same sign fistpl FRAME_SIZE( STACKP ) // set inexact if necessary andl $0x80000000, %edx movl %edx, FRAME_SIZE( STACKP ) flds FRAME_SIZE( STACKP )
2: ret
#else #error unknown arch#endif