Linux Kernel
3.7.1
Main Page
Related Pages
Modules
Namespaces
Data Structures
Files
File List
Globals
All
Data Structures
Namespaces
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Macros
Groups
Pages
arch
mips
math-emu
dp_tlong.c
Go to the documentation of this file.
1
/* IEEE754 floating point arithmetic
2
* double precision: common utilities
3
*/
4
/*
5
* MIPS floating point support
6
* Copyright (C) 1994-2000 Algorithmics Ltd.
7
*
8
* ########################################################################
9
*
10
* This program is free software; you can distribute it and/or modify it
11
* under the terms of the GNU General Public License (Version 2) as
12
* published by the Free Software Foundation.
13
*
14
* This program is distributed in the hope it will be useful, but WITHOUT
15
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
16
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
17
* for more details.
18
*
19
* You should have received a copy of the GNU General Public License along
20
* with this program; if not, write to the Free Software Foundation, Inc.,
21
* 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
22
*
23
* ########################################################################
24
*/
25
26
27
#include "
ieee754dp.h
"
28
29
s64
ieee754dp_tlong
(ieee754dp
x
)
30
{
31
COMPXDP
;
32
33
CLEARCX
;
34
35
EXPLODEXDP
;
36
FLUSHXDP
;
37
38
switch
(
xc
) {
39
case
IEEE754_CLASS_SNAN
:
40
case
IEEE754_CLASS_QNAN
:
41
case
IEEE754_CLASS_INF
:
42
SETCX
(
IEEE754_INVALID_OPERATION
);
43
return
ieee754di_xcpt
(
ieee754di_indef
(),
"dp_tlong"
, x);
44
case
IEEE754_CLASS_ZERO
:
45
return
0;
46
case
IEEE754_CLASS_DNORM
:
47
case
IEEE754_CLASS_NORM
:
48
break
;
49
}
50
if
(
xe
>= 63) {
51
/* look for valid corner case */
52
if
(
xe
== 63 &&
xs
&& xm ==
DP_HIDDEN_BIT
)
53
return
-0x8000000000000000
LL
;
54
/* Set invalid. We will only use overflow for floating
55
point overflow */
56
SETCX
(
IEEE754_INVALID_OPERATION
);
57
return
ieee754di_xcpt
(
ieee754di_indef
(),
"dp_tlong"
, x);
58
}
59
/* oh gawd */
60
if
(
xe
>
DP_MBITS
) {
61
xm <<=
xe
-
DP_MBITS
;
62
}
else
if
(
xe
<
DP_MBITS
) {
63
u64
residue;
64
int
round;
65
int
sticky;
66
int
odd;
67
68
if
(
xe
< -1) {
69
residue = xm;
70
round = 0;
71
sticky = residue != 0;
72
xm = 0;
73
}
else
{
74
/* Shifting a u64 64 times does not work,
75
* so we do it in two steps. Be aware that xe
76
* may be -1 */
77
residue = xm << (
xe
+ 1);
78
residue <<= 63 -
DP_MBITS
;
79
round = (residue >> 63) != 0;
80
sticky = (residue << 1) != 0;
81
xm >>=
DP_MBITS
-
xe
;
82
}
83
odd = (xm & 0x1) != 0x0;
84
switch
(
ieee754_csr
.rm) {
85
case
IEEE754_RN
:
86
if
(round && (sticky || odd))
87
xm++;
88
break
;
89
case
IEEE754_RZ
:
90
break
;
91
case
IEEE754_RU
:
/* toward +Infinity */
92
if
((round || sticky) && !
xs
)
93
xm++;
94
break
;
95
case
IEEE754_RD
:
/* toward -Infinity */
96
if
((round || sticky) &&
xs
)
97
xm++;
98
break
;
99
}
100
if
((xm >> 63) != 0) {
101
/* This can happen after rounding */
102
SETCX
(
IEEE754_INVALID_OPERATION
);
103
return
ieee754di_xcpt
(
ieee754di_indef
(),
"dp_tlong"
, x);
104
}
105
if
(round || sticky)
106
SETCX
(
IEEE754_INEXACT
);
107
}
108
if
(
xs
)
109
return
-xm;
110
else
111
return
xm;
112
}
113
114
115
u64
ieee754dp_tulong
(ieee754dp
x
)
116
{
117
ieee754dp hb =
ieee754dp_1e63
();
118
119
/* what if x < 0 ?? */
120
if
(ieee754dp_lt(x, hb))
121
return
(
u64
)
ieee754dp_tlong
(x);
122
123
return
(
u64
)
ieee754dp_tlong
(
ieee754dp_sub
(x, hb)) |
124
(1ULL << 63);
125
}
Generated on Thu Jan 10 2013 13:11:39 for Linux Kernel by
1.8.2