@@ -15,195 +15,9 @@ namespace Internal.Runtime.CompilerHelpers
15
15
[ StackTraceHidden ]
16
16
internal static partial class MathHelpers
17
17
{
18
- private const double Int32MaxValueOffset = ( double ) int . MaxValue + 1 ;
19
- private const double UInt32MaxValueOffset = ( double ) uint . MaxValue + 1 ;
20
-
21
- [ RuntimeExport ( "Dbl2IntOvf" ) ]
22
- public static int Dbl2IntOvf ( double value )
23
- {
24
- // Note that this expression also works properly for val = NaN case
25
- if ( value is > - Int32MaxValueOffset - 1 and < Int32MaxValueOffset )
26
- {
27
- return ( int ) value ;
28
- }
29
-
30
- ThrowHelper . ThrowOverflowException ( ) ;
31
- return 0 ;
32
- }
33
-
34
- [ RuntimeExport ( "Dbl2UIntOvf" ) ]
35
- public static uint Dbl2UIntOvf ( double value )
36
- {
37
- // Note that this expression also works properly for val = NaN case
38
- if ( value is > - 1.0 and < UInt32MaxValueOffset )
39
- {
40
- return ( uint ) value ;
41
- }
42
-
43
- ThrowHelper . ThrowOverflowException ( ) ;
44
- return 0 ;
45
- }
46
-
47
- [ RuntimeExport ( "Dbl2LngOvf" ) ]
48
- public static long Dbl2LngOvf ( double value )
49
- {
50
- const double two63 = Int32MaxValueOffset * UInt32MaxValueOffset ;
51
-
52
- // Note that this expression also works properly for val = NaN case
53
- // We need to compare with the very next double to two63. 0x402 is epsilon to get us there.
54
- if ( value is > - two63 - 0x402 and < two63 )
55
- {
56
- return ( long ) value ;
57
- }
58
-
59
- ThrowHelper . ThrowOverflowException ( ) ;
60
- return 0 ;
61
- }
62
-
63
- [ RuntimeExport ( "Dbl2ULngOvf" ) ]
64
- public static ulong Dbl2ULngOvf ( double value )
65
- {
66
- const double two64 = UInt32MaxValueOffset * UInt32MaxValueOffset ;
67
- // Note that this expression also works properly for val = NaN case
68
- if ( value is > - 1.0 and < two64 )
69
- {
70
- return ( ulong ) value ;
71
- }
72
-
73
- ThrowHelper . ThrowOverflowException ( ) ;
74
- return 0 ;
75
- }
76
-
77
18
#if ! TARGET_64BIT
78
- //
79
- // 64-bit checked multiplication for 32-bit platforms
80
- //
81
-
82
19
private const string RuntimeLibrary = "*" ;
83
20
84
- [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
85
- private static uint High32Bits ( ulong a )
86
- {
87
- return ( uint ) ( a >> 32 ) ;
88
- }
89
-
90
- [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
91
- private static ulong BigMul ( uint left , uint right )
92
- {
93
- return ( ulong ) left * right ;
94
- }
95
-
96
- [ RuntimeExport ( "LMulOvf" ) ]
97
- public static long LMulOvf ( long left , long right )
98
- {
99
- #if DEBUG
100
- long result = left * right ;
101
- #endif
102
-
103
- // Remember the sign of the result
104
- int sign = ( int ) ( High32Bits ( ( ulong ) left ) ^ High32Bits ( ( ulong ) right ) ) ;
105
-
106
- // Convert to unsigned multiplication
107
- if ( left < 0 )
108
- left = - left ;
109
- if ( right < 0 )
110
- right = - right ;
111
-
112
- // Get the upper 32 bits of the numbers
113
- uint val1High = High32Bits ( ( ulong ) left ) ;
114
- uint val2High = High32Bits ( ( ulong ) right ) ;
115
-
116
- ulong valMid ;
117
-
118
- if ( val1High == 0 )
119
- {
120
- // Compute the 'middle' bits of the long multiplication
121
- valMid = BigMul ( val2High , ( uint ) left ) ;
122
- }
123
- else
124
- {
125
- if ( val2High != 0 )
126
- goto Overflow ;
127
- // Compute the 'middle' bits of the long multiplication
128
- valMid = BigMul ( val1High , ( uint ) right ) ;
129
- }
130
-
131
- // See if any bits after bit 32 are set
132
- if ( High32Bits ( valMid ) != 0 )
133
- goto Overflow ;
134
-
135
- long ret = ( long ) ( BigMul ( ( uint ) left , ( uint ) right ) + ( valMid << 32 ) ) ;
136
-
137
- // check for overflow
138
- if ( High32Bits ( ( ulong ) ret ) < ( uint ) valMid )
139
- goto Overflow ;
140
-
141
- if ( sign >= 0 )
142
- {
143
- // have we spilled into the sign bit?
144
- if ( ret < 0 )
145
- goto Overflow ;
146
- }
147
- else
148
- {
149
- ret = - ret ;
150
- // have we spilled into the sign bit?
151
- if ( ret > 0 )
152
- goto Overflow ;
153
- }
154
-
155
- #if DEBUG
156
- Debug . Assert ( ret == result , $ "Multiply overflow got: { ret } , expected: { result } ") ;
157
- #endif
158
- return ret ;
159
-
160
- Overflow :
161
- ThrowHelper . ThrowOverflowException ( ) ;
162
- return 0 ;
163
- }
164
-
165
- [ RuntimeExport ( "ULMulOvf" ) ]
166
- public static ulong ULMulOvf ( ulong left , ulong right )
167
- {
168
- // Get the upper 32 bits of the numbers
169
- uint val1High = High32Bits ( left ) ;
170
- uint val2High = High32Bits ( right ) ;
171
-
172
- ulong valMid ;
173
-
174
- if ( val1High == 0 )
175
- {
176
- if ( val2High == 0 )
177
- return ( ulong ) ( uint ) left * ( uint ) right ;
178
- // Compute the 'middle' bits of the long multiplication
179
- valMid = BigMul ( val2High , ( uint ) left ) ;
180
- }
181
- else
182
- {
183
- if ( val2High != 0 )
184
- goto Overflow ;
185
- // Compute the 'middle' bits of the long multiplication
186
- valMid = BigMul ( val1High , ( uint ) right ) ;
187
- }
188
-
189
- // See if any bits after bit 32 are set
190
- if ( High32Bits ( valMid ) != 0 )
191
- goto Overflow ;
192
-
193
- ulong ret = BigMul ( ( uint ) left , ( uint ) right ) + ( valMid << 32 ) ;
194
-
195
- // check for overflow
196
- if ( High32Bits ( ret ) < ( uint ) valMid )
197
- goto Overflow ;
198
-
199
- Debug . Assert ( ret == left * right , $ "Multiply overflow got: { ret } , expected: { left * right } ") ;
200
- return ret ;
201
-
202
- Overflow :
203
- ThrowHelper . ThrowOverflowException ( ) ;
204
- return 0 ;
205
- }
206
-
207
21
[ LibraryImport ( RuntimeLibrary ) ]
208
22
[ SuppressGCTransition ]
209
23
private static partial ulong RhpULMod ( ulong dividend , ulong divisor ) ;
0 commit comments