This source file includes following definitions.
- poly_2xm1
1
2
3
4
5
6
7
8
9
10
11
12
13 #include "exception.h"
14 #include "reg_constant.h"
15 #include "fpu_emu.h"
16 #include "control_w.h"
17 #include "poly.h"
18
19
20 #define HIPOWER 11
21 static const unsigned long long lterms[HIPOWER] =
22 {
23 0x0000000000000000LL,
24 0xf5fdeffc162c7543LL,
25 0x1c6b08d704a0bfa6LL,
26 0x0276556df749cc21LL,
27 0x002bb0ffcf14f6b8LL,
28 0x0002861225ef751cLL,
29 0x00001ffcbfcd5422LL,
30 0x00000162c005d5f1LL,
31 0x0000000da96ccb1bLL,
32 0x0000000078d1b897LL,
33 0x000000000422b029LL
34 };
35
36 static const Xsig hiterm = MK_XSIG(0xb17217f7, 0xd1cf79ab, 0xc8a39194);
37
38
39
40
41 static const Xsig shiftterm0 = MK_XSIG(0, 0, 0);
42 static const Xsig shiftterm1 = MK_XSIG(0x9837f051, 0x8db8a96f, 0x46ad2318);
43 static const Xsig shiftterm2 = MK_XSIG(0xb504f333, 0xf9de6484, 0x597d89b3);
44 static const Xsig shiftterm3 = MK_XSIG(0xd744fcca, 0xd69d6af4, 0x39a68bb9);
45
46 static const Xsig *shiftterm[] = { &shiftterm0, &shiftterm1,
47 &shiftterm2, &shiftterm3 };
48
49
50
51
52
53 int poly_2xm1(FPU_REG const *arg, FPU_REG *result)
54 {
55 long int exponent, shift;
56 unsigned long long Xll;
57 Xsig accumulator, Denom, argSignif;
58
59
60 exponent = arg->exp - EXP_BIAS;
61
62 #ifdef PARANOID
63 if ( (exponent >= 0)
64 || (arg->tag != TW_Valid) )
65 {
66
67 EXCEPTION(EX_INTERNAL|0x127);
68 return 1;
69 }
70 #endif PARANOID
71
72 argSignif.lsw = 0;
73 XSIG_LL(argSignif) = Xll = significand(arg);
74
75 if ( exponent == -1 )
76 {
77 shift = (argSignif.msw & 0x40000000) ? 3 : 2;
78
79 exponent -= 2;
80 XSIG_LL(argSignif) <<= 2;
81 Xll <<= 2;
82 }
83 else if ( exponent == -2 )
84 {
85 shift = 1;
86
87 exponent--;
88 XSIG_LL(argSignif) <<= 1;
89 Xll <<= 1;
90 }
91 else
92 shift = 0;
93
94 if ( exponent < -2 )
95 {
96
97 if ( shrx(&Xll, -2-exponent) >= 0x80000000U )
98 Xll++;
99 }
100
101 accumulator.lsw = accumulator.midw = accumulator.msw = 0;
102 polynomial_Xsig(&accumulator, &Xll, lterms, HIPOWER-1);
103 mul_Xsig_Xsig(&accumulator, &argSignif);
104 shr_Xsig(&accumulator, 3);
105
106 mul_Xsig_Xsig(&argSignif, &hiterm);
107 add_two_Xsig(&accumulator, &argSignif, &exponent);
108
109 if ( shift )
110 {
111
112
113
114 shr_Xsig(&accumulator, - exponent);
115 accumulator.msw |= 0x80000000;
116 mul_Xsig_Xsig(&accumulator, shiftterm[shift]);
117 accumulator.msw &= 0x3fffffff;
118 exponent = 1;
119 }
120
121 if ( arg->sign != SIGN_POS )
122 {
123
124
125
126 Denom.lsw = accumulator.lsw;
127 XSIG_LL(Denom) = XSIG_LL(accumulator);
128 if ( exponent < 0 )
129 shr_Xsig(&Denom, - exponent);
130 else if ( exponent > 0 )
131 {
132
133 XSIG_LL(Denom) <<= 1;
134 if ( Denom.lsw & 0x80000000 )
135 XSIG_LL(Denom) |= 1;
136 (Denom.lsw) <<= 1;
137 }
138 Denom.msw |= 0x80000000;
139 div_Xsig(&accumulator, &Denom, &accumulator);
140 }
141
142
143 exponent += round_Xsig(&accumulator);
144
145 significand(result) = XSIG_LL(accumulator);
146 result->tag = TW_Valid;
147 result->exp = exponent + EXP_BIAS;
148 result->sign = arg->sign;
149
150 return 0;
151
152 }