this repo has no description
1/*
2 * truncl.s
3 * LibmV5
4 *
5 * Created by Ian Ollmann on 9/1/05.
6 * Copyright 2005 Apple Computer. All rights reserved.
7 *
8 */
9
10#include "machine/asm.h"
11
12#define LOCAL_STACK_SIZE 12
13#include "abi.h"
14
15#if defined( __i386__ )
16
17ENTRY(truncl)
18 movswl 8+FRAME_SIZE( STACKP ), %eax // load signed exponent
19 movl %eax, %edx // sign + exponent
20 andl $0x7fff, %eax // exponent
21 subl $0x3fff, %eax // remove bias
22 cmpl $63, %eax // if( |x| >= 0x1.0p63 || |x| < 1.0 || isnan(x) )
23 jae 2f // goto 2
24
25 movl $63, %ecx
26 movq FRAME_SIZE( STACKP ), %xmm0 // significand
27 subl %eax, %ecx // 63 - exponent
28 pcmpeqb %xmm1, %xmm1 // -1LL
29 movd %ecx, %xmm7 // 63-exponent
30 pxor %xmm2, %xmm2 // 0
31 psubq %xmm1, %xmm2 // 1
32 movdqa %xmm2, %xmm1 // 1
33 psllq %xmm7, %xmm2 // one's bit
34 psubq %xmm1, %xmm2 // fract mask
35 pandn %xmm0, %xmm2
36 movq %xmm2, FRAME_SIZE( STACKP )
37 pcmpeqd %xmm2, %xmm0
38 pmovmskb %xmm0, %eax
39 cmp $0xffff, %eax
40 fldt FRAME_SIZE( STACKP ) // result
41 je 1f
42
43 // set inexact
44 fldpi
45 fmul %st(0), %st(0)
46 fstp %st(0)
47
481: ret
49
50// |x| >= 0x1.0p63 || |x| < 1.0 || isnan(x)
512: jge 3f
52
53// |x| < 1.0
54 fldt FRAME_SIZE( STACKP ) // { x }
55 fldz // { 0, x }
56 fucomip %st(1), %st(0) // { x }
57 je 1b
58
59 fistpl FRAME_SIZE( STACKP )
60 fldz // { 0 }
61 fldz // { 0, 0 }
62 fchs // { -0, 0 }
63 fcmovb %st(1), %st(0)
64 fstp %st(1)
65 ret
66
67// |x| >= 0x1.0p63 || isnan(x)
683: fldt FRAME_SIZE(STACKP)
69 fldz
70 faddp
71 ret
72
73#elif defined( __x86_64__ )
74
75ENTRY(truncl)
76 fldt FRAME_SIZE( STACKP ) // { x }
77 movzwl 8+FRAME_SIZE( STACKP ), %eax
78 movswl %cx, %edx
79 andl $0x7fff, %eax
80 subl $0x3fff, %eax // push |x| < 1.0L negative
81 cmpl $63, %eax
82 jae 1f
83
84#if defined( __SSE3__ )
85 fisttpll FRAME_SIZE( STACKP )
86 fildll FRAME_SIZE( STACKP )
87#else
88 fnstcw FRAME_SIZE( STACKP )
89 movw FRAME_SIZE( STACKP ), %cx
90 movw %cx, %dx
91 orw $0xc00, %cx
92 movw %cx, FRAME_SIZE( STACKP )
93 fldcw FRAME_SIZE( STACKP )
94 frndint
95 movw %dx, FRAME_SIZE( STACKP )
96 fldcw FRAME_SIZE( STACKP )
97#endif
98 ret
99
1001: // |x| < 1.0L || |x| > 0x1.0p63L || isnan( x )
101 jge 2f
102
103 // |x| < 1.0L, return 0 of same sign
104 fistpl FRAME_SIZE( STACKP ) // set inexact if necessary
105 andl $0x80000000, %edx
106 movl %edx, FRAME_SIZE( STACKP )
107 flds FRAME_SIZE( STACKP )
108
1092: ret
110
111#else
112 #error unknown arch
113#endif