-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathfp-add32.c
122 lines (114 loc) · 2.48 KB
/
fp-add32.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
/* Add 2 32 bits floating point numbers without multiplier
*/
#include <strings.h>
#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <assert.h>
#include "fp-soft-variable.h"
int isZero (int Exp, __int64_t Mant)
{
if ((0 == Exp) && (0 == (Mant & MANTISSA32_MASK)))
return 1;
else
return 0;
}
__uint64_t fpaddparts(__uint64_t a, __uint64_t b)
{
int precision, aSign, bSign, rSign, aExp, bExp, rExp, diffExp, absDiffExp;
__int64_t rMant, aMant, bMant, mMant;
aSign = SIGN32(a); aExp = EXP32(a); aMant = MANT32(a);
bSign = SIGN32(b); bExp = EXP32(b); bMant = MANT32(b);
diffExp = aExp - bExp;
absDiffExp = abs (diffExp);
#if 0
printf ("a: %X %7X %8lX\n", (aSign >> 31)&1, aExp, aMant);
printf ("b: %X %7X %8lX\n", (bSign >> 31)&1, bExp, bMant);
printf ("diff Exp: %d\n", diffExp);
printFPBinMantissa(aMant);
printFPBinMantissa(bMant);
#endif
if (isZero (aExp, aMant))
return b;
if (isZero (bExp, bMant))
return a;
if (diffExp > 0)
{
bExp += absDiffExp;
LSHIFT(bMant, absDiffExp);
}
else if (diffExp < 0)
{
aExp += absDiffExp;
LSHIFT(aMant, absDiffExp);
}
#if 0
printFPBinMantissa(aMant);
printFPBinMantissa(bMant);
assert (aExp == bExp);
#endif
if (aSign == bSign)
{
rSign = aSign;
rExp = aExp;
rMant = aMant + bMant;
}
else // Differents signs
{
if (aSign) // Negative A
{
rMant = -aMant + bMant;
}
else // Negative B
{
rMant = aMant - bMant;
}
rExp = aExp;
rSign = (rMant >= 0)?0:1;
if (rMant < 0)
{
rMant = -rMant;
}
while (rMant < IMPLICIT32_1 && rMant)
{
rMant <<= 1;
rExp--;
}
}
#if 0
printFPBinMantissa(rMant);
#endif
if (rMant >= (1 << (23+1)))
{
LSHIFT(rMant,1);
rExp++;
}
if (0 == rMant)
{
rExp = 0;
}
#if 0
printFPBinMantissa(rMant);
printf ("r: %X %7X %8lX\n", (rSign >> 31)&1, rExp, rMant);
#endif
precision = fpGetPrecision();
/* Precision emulation */
mMant = ((1 << (precision + 1)) - 1) << (23 - precision);
rMant = rMant & mMant;
return PACK32(rSign, rExp, rMant);
}
__uint64_t addsf3_classical(__uint64_t a, __uint64_t b)
{
__uint64_t result;
fpIncadd();
result = fpaddparts(a, b);
return result;
}
float __addsf3(float a, float b)
{
float_cast af, bf, cf;
af.f = a;
bf.f = b;
cf.i = addsf3_classical(af.i, bf.i);
return cf.f;
}