this repo has no description
1
2/*
3 * lrintl.s
4 *
5 * by Ian Ollmann
6 *
7 * Copyright Apple Inc. 2007.
8 *
9 * C99 implementation of lrintl and llrintl
10 */
11
12#include <machine/asm.h>
13#include "abi.h"
14
15#if ! defined( __LP64__ )
16
17ENTRY( lrintl )
18 fldt FRAME_SIZE( STACKP ) // { x }
19 movswl 8+FRAME_SIZE( STACKP), %eax // Load signed exponent
20 movl %eax, %ecx // set aside sign
21 andl $0x7fff, %eax // remove sign
22 cmpl $0x401d, %eax // if( |x| > 0x1.0p30 || isnan(x) )
23 jae 2f // goto 2
24
25 // |x| < 0x1.0p30 || isnan(x)
26 fistpl FRAME_SIZE( STACKP )
271: movl FRAME_SIZE( STACKP ), %eax // load result
28 ret
29
30 //|x| >= 0x1.0p30 || isnan(x)
312: fistl FRAME_SIZE( STACKP )
32 fucomip %st(0), %st(0) // if( isnan(x) )
33 jp 1b // goto 1
34
35 // |x| >= 0x1.0p30. If sign != old sign, xor with -1
36 movl FRAME_SIZE( STACKP ), %eax // load result
37 xorl %eax, %ecx // check to see if the sign changed
38 sarl $31, %ecx // sign changed ? -1 : 0
39 xorl %ecx, %eax // if the sign changed, xor with -1 (flips 0x80000000 to 0x7fffffff)
40 ret
41
42#define MOVSW movswl
43
44#else
45#define MOVSW movswq
46
47ENTRY( lrintl )
48#endif
49ENTRY( llrintl )
50 MOVSW 8+FRAME_SIZE( STACKP), AX_P // load signed exponent
51 fldt FRAME_SIZE( STACKP ) // { x }
52 mov AX_P, CX_P // signed exponent
53 and $0x7fff, AX_P // remove sign
54 cmp $0x403d, AX_P // if( exponent + bias >= 16383+62 )
55 jae 2f // goto 1
56
57 // |x| < 0x1.0p62. Nothing can go wrong. Return the long long.
581: fistpll FRAME_SIZE( STACKP ) // store out x as 64-bit int with appropriate rounding
59
60#if defined( __LP64__ )
61 movq FRAME_SIZE( STACKP ), %rax
62#else
63 movl FRAME_SIZE( STACKP ), %eax
64 movl 4+FRAME_SIZE( STACKP ), %edx
65#endif
66 ret
67
68 // |x| >= 2**62 || isnan(x) -- might be invalid
692: fucomi %st(0), %st(0) // if( x != x )
70 jp 1b
71
72 fistpll FRAME_SIZE( STACKP ) // store out x as 64-bit int with appropriate rounding
73
74 // Load data in. If the sign changed, xor with -1
75#if defined( __LP64__ )
76 movq FRAME_SIZE( STACKP ), %rax
77 xorq %rax, %rcx
78 sarq $63, %rcx
79 xorq %rcx, %rax
80#else
81 movl FRAME_SIZE( STACKP ), %eax
82 movl 4+FRAME_SIZE( STACKP ), %edx
83 xorl %edx, %ecx
84 sarl $31, %ecx
85 xorl %ecx, %eax
86 xorl %ecx, %edx
87#endif
88 ret
89
90
91