Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/arch/parisc/math-emu/denormal.c
10817 views
1
/*
2
* Linux/PA-RISC Project (http://www.parisc-linux.org/)
3
*
4
* Floating-point emulation code
5
* Copyright (C) 2001 Hewlett-Packard (Paul Bame) <[email protected]>
6
*
7
* This program is free software; you can redistribute it and/or modify
8
* it under the terms of the GNU General Public License as published by
9
* the Free Software Foundation; either version 2, or (at your option)
10
* any later version.
11
*
12
* This program is distributed in the hope that it will be useful,
13
* but WITHOUT ANY WARRANTY; without even the implied warranty of
14
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
* GNU General Public License for more details.
16
*
17
* You should have received a copy of the GNU General Public License
18
* along with this program; if not, write to the Free Software
19
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20
*/
21
/*
22
* BEGIN_DESC
23
*
24
* File:
25
* @(#) pa/fp/denormal.c $ Revision: $
26
*
27
* Purpose:
28
* <<please update with a synopsis of the functionality provided by this file>>
29
*
30
* External Interfaces:
31
* <<the following list was autogenerated, please review>>
32
* dbl_denormalize(dbl_opndp1,dbl_opndp2,inexactflag,rmode)
33
* sgl_denormalize(sgl_opnd,inexactflag,rmode)
34
*
35
* Internal Interfaces:
36
* <<please update>>
37
*
38
* Theory:
39
* <<please update with a overview of the operation of this file>>
40
*
41
* END_DESC
42
*/
43
44
45
46
#include "float.h"
47
#include "sgl_float.h"
48
#include "dbl_float.h"
49
#include "hppa.h"
50
#include <linux/kernel.h>
51
/* #include <machine/sys/mdep_private.h> */
52
53
#undef Fpustatus_register
54
#define Fpustatus_register Fpu_register[0]
55
56
void
57
sgl_denormalize(unsigned int *sgl_opnd, boolean *inexactflag, int rmode)
58
{
59
unsigned int opnd;
60
int sign, exponent;
61
boolean guardbit = FALSE, stickybit, inexact;
62
63
opnd = *sgl_opnd;
64
stickybit = *inexactflag;
65
exponent = Sgl_exponent(opnd) - SGL_WRAP;
66
sign = Sgl_sign(opnd);
67
Sgl_denormalize(opnd,exponent,guardbit,stickybit,inexact);
68
if (inexact) {
69
switch (rmode) {
70
case ROUNDPLUS:
71
if (sign == 0) {
72
Sgl_increment(opnd);
73
}
74
break;
75
case ROUNDMINUS:
76
if (sign != 0) {
77
Sgl_increment(opnd);
78
}
79
break;
80
case ROUNDNEAREST:
81
if (guardbit && (stickybit ||
82
Sgl_isone_lowmantissa(opnd))) {
83
Sgl_increment(opnd);
84
}
85
break;
86
}
87
}
88
Sgl_set_sign(opnd,sign);
89
*sgl_opnd = opnd;
90
*inexactflag = inexact;
91
return;
92
}
93
94
void
95
dbl_denormalize(unsigned int *dbl_opndp1,
96
unsigned int * dbl_opndp2,
97
boolean *inexactflag,
98
int rmode)
99
{
100
unsigned int opndp1, opndp2;
101
int sign, exponent;
102
boolean guardbit = FALSE, stickybit, inexact;
103
104
opndp1 = *dbl_opndp1;
105
opndp2 = *dbl_opndp2;
106
stickybit = *inexactflag;
107
exponent = Dbl_exponent(opndp1) - DBL_WRAP;
108
sign = Dbl_sign(opndp1);
109
Dbl_denormalize(opndp1,opndp2,exponent,guardbit,stickybit,inexact);
110
if (inexact) {
111
switch (rmode) {
112
case ROUNDPLUS:
113
if (sign == 0) {
114
Dbl_increment(opndp1,opndp2);
115
}
116
break;
117
case ROUNDMINUS:
118
if (sign != 0) {
119
Dbl_increment(opndp1,opndp2);
120
}
121
break;
122
case ROUNDNEAREST:
123
if (guardbit && (stickybit ||
124
Dbl_isone_lowmantissap2(opndp2))) {
125
Dbl_increment(opndp1,opndp2);
126
}
127
break;
128
}
129
}
130
Dbl_set_sign(opndp1,sign);
131
*dbl_opndp1 = opndp1;
132
*dbl_opndp2 = opndp2;
133
*inexactflag = inexact;
134
return;
135
}
136
137