Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/arch/parisc/math-emu/denormal.c
26288 views
1
// SPDX-License-Identifier: GPL-2.0-or-later
2
/*
3
* Linux/PA-RISC Project (http://www.parisc-linux.org/)
4
*
5
* Floating-point emulation code
6
* Copyright (C) 2001 Hewlett-Packard (Paul Bame) <[email protected]>
7
*/
8
/*
9
* BEGIN_DESC
10
*
11
* File:
12
* @(#) pa/fp/denormal.c $ Revision: $
13
*
14
* Purpose:
15
* <<please update with a synopsis of the functionality provided by this file>>
16
*
17
* External Interfaces:
18
* <<the following list was autogenerated, please review>>
19
* dbl_denormalize(dbl_opndp1,dbl_opndp2,inexactflag,rmode)
20
* sgl_denormalize(sgl_opnd,inexactflag,rmode)
21
*
22
* Internal Interfaces:
23
* <<please update>>
24
*
25
* Theory:
26
* <<please update with a overview of the operation of this file>>
27
*
28
* END_DESC
29
*/
30
31
32
33
#include "float.h"
34
#include "sgl_float.h"
35
#include "dbl_float.h"
36
#include "hppa.h"
37
#include <linux/kernel.h>
38
/* #include <machine/sys/mdep_private.h> */
39
40
#undef Fpustatus_register
41
#define Fpustatus_register Fpu_register[0]
42
43
void
44
sgl_denormalize(unsigned int *sgl_opnd, boolean *inexactflag, int rmode)
45
{
46
unsigned int opnd;
47
int sign, exponent;
48
boolean guardbit = FALSE, stickybit, inexact;
49
50
opnd = *sgl_opnd;
51
stickybit = *inexactflag;
52
exponent = Sgl_exponent(opnd) - SGL_WRAP;
53
sign = Sgl_sign(opnd);
54
Sgl_denormalize(opnd,exponent,guardbit,stickybit,inexact);
55
if (inexact) {
56
switch (rmode) {
57
case ROUNDPLUS:
58
if (sign == 0) {
59
Sgl_increment(opnd);
60
}
61
break;
62
case ROUNDMINUS:
63
if (sign != 0) {
64
Sgl_increment(opnd);
65
}
66
break;
67
case ROUNDNEAREST:
68
if (guardbit && (stickybit ||
69
Sgl_isone_lowmantissa(opnd))) {
70
Sgl_increment(opnd);
71
}
72
break;
73
}
74
}
75
Sgl_set_sign(opnd,sign);
76
*sgl_opnd = opnd;
77
*inexactflag = inexact;
78
return;
79
}
80
81
void
82
dbl_denormalize(unsigned int *dbl_opndp1,
83
unsigned int * dbl_opndp2,
84
boolean *inexactflag,
85
int rmode)
86
{
87
unsigned int opndp1, opndp2;
88
int sign, exponent;
89
boolean guardbit = FALSE, stickybit, inexact;
90
91
opndp1 = *dbl_opndp1;
92
opndp2 = *dbl_opndp2;
93
stickybit = *inexactflag;
94
exponent = Dbl_exponent(opndp1) - DBL_WRAP;
95
sign = Dbl_sign(opndp1);
96
Dbl_denormalize(opndp1,opndp2,exponent,guardbit,stickybit,inexact);
97
if (inexact) {
98
switch (rmode) {
99
case ROUNDPLUS:
100
if (sign == 0) {
101
Dbl_increment(opndp1,opndp2);
102
}
103
break;
104
case ROUNDMINUS:
105
if (sign != 0) {
106
Dbl_increment(opndp1,opndp2);
107
}
108
break;
109
case ROUNDNEAREST:
110
if (guardbit && (stickybit ||
111
Dbl_isone_lowmantissap2(opndp2))) {
112
Dbl_increment(opndp1,opndp2);
113
}
114
break;
115
}
116
}
117
Dbl_set_sign(opndp1,sign);
118
*dbl_opndp1 = opndp1;
119
*dbl_opndp2 = opndp2;
120
*inexactflag = inexact;
121
return;
122
}
123
124