...
Source file
src/runtime/vlrt.go
Documentation: runtime
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 package runtime
29
30 import "unsafe"
31
32 const (
33 sign32 = 1 << (32 - 1)
34 sign64 = 1 << (64 - 1)
35 )
36
37 func float64toint64(d float64) (y uint64) {
38 _d2v(&y, d)
39 return
40 }
41
42 func float64touint64(d float64) (y uint64) {
43 _d2v(&y, d)
44 return
45 }
46
47 func int64tofloat64(y int64) float64 {
48 if y < 0 {
49 return -uint64tofloat64(-uint64(y))
50 }
51 return uint64tofloat64(uint64(y))
52 }
53
54 func uint64tofloat64(y uint64) float64 {
55 hi := float64(uint32(y >> 32))
56 lo := float64(uint32(y))
57 d := hi*(1<<32) + lo
58 return d
59 }
60
61 func int64tofloat32(y int64) float32 {
62 if y < 0 {
63 return -uint64tofloat32(-uint64(y))
64 }
65 return uint64tofloat32(uint64(y))
66 }
67
68 func uint64tofloat32(y uint64) float32 {
69
70
71 top := uint32(y >> 46)
72 mid := uint32(y >> 23 & (1<<23 - 1))
73 bot := uint32(y & (1<<23 - 1))
74 if top == 0 {
75 return float32(mid)*(1<<23) + float32(bot)
76 }
77 if bot != 0 {
78
79
80
81
82
83
84
85
86 mid |= 1
87 }
88 return float32(top)*(1<<46) + float32(mid)*(1<<23)
89 }
90
91 func _d2v(y *uint64, d float64) {
92 x := *(*uint64)(unsafe.Pointer(&d))
93
94 xhi := uint32(x>>32)&0xfffff | 0x100000
95 xlo := uint32(x)
96 sh := 1075 - int32(uint32(x>>52)&0x7ff)
97
98 var ylo, yhi uint32
99 if sh >= 0 {
100 sh := uint32(sh)
101
102 if sh < 32 {
103 if sh == 0 {
104 ylo = xlo
105 yhi = xhi
106 } else {
107 ylo = xlo>>sh | xhi<<(32-sh)
108 yhi = xhi >> sh
109 }
110 } else {
111 if sh == 32 {
112 ylo = xhi
113 } else if sh < 64 {
114 ylo = xhi >> (sh - 32)
115 }
116 }
117 } else {
118
119 sh := uint32(-sh)
120 if sh <= 11 {
121 ylo = xlo << sh
122 yhi = xhi<<sh | xlo>>(32-sh)
123 } else {
124
125 yhi = uint32(d)
126 }
127 }
128 if x&sign64 != 0 {
129 if ylo != 0 {
130 ylo = -ylo
131 yhi = ^yhi
132 } else {
133 yhi = -yhi
134 }
135 }
136
137 *y = uint64(yhi)<<32 | uint64(ylo)
138 }
139 func uint64div(n, d uint64) uint64 {
140
141 if uint32(n>>32) == 0 && uint32(d>>32) == 0 {
142 if uint32(d) == 0 {
143 panicdivide()
144 }
145 return uint64(uint32(n) / uint32(d))
146 }
147 q, _ := dodiv(n, d)
148 return q
149 }
150
151 func uint64mod(n, d uint64) uint64 {
152
153 if uint32(n>>32) == 0 && uint32(d>>32) == 0 {
154 if uint32(d) == 0 {
155 panicdivide()
156 }
157 return uint64(uint32(n) % uint32(d))
158 }
159 _, r := dodiv(n, d)
160 return r
161 }
162
163 func int64div(n, d int64) int64 {
164
165 if int64(int32(n)) == n && int64(int32(d)) == d {
166 if int32(n) == -0x80000000 && int32(d) == -1 {
167
168
169 return 0x80000000
170 }
171 if int32(d) == 0 {
172 panicdivide()
173 }
174 return int64(int32(n) / int32(d))
175 }
176
177 nneg := n < 0
178 dneg := d < 0
179 if nneg {
180 n = -n
181 }
182 if dneg {
183 d = -d
184 }
185 uq, _ := dodiv(uint64(n), uint64(d))
186 q := int64(uq)
187 if nneg != dneg {
188 q = -q
189 }
190 return q
191 }
192
193
194 func int64mod(n, d int64) int64 {
195
196 if int64(int32(n)) == n && int64(int32(d)) == d {
197 if int32(d) == 0 {
198 panicdivide()
199 }
200 return int64(int32(n) % int32(d))
201 }
202
203 nneg := n < 0
204 if nneg {
205 n = -n
206 }
207 if d < 0 {
208 d = -d
209 }
210 _, ur := dodiv(uint64(n), uint64(d))
211 r := int64(ur)
212 if nneg {
213 r = -r
214 }
215 return r
216 }
217
218
219 func _mul64by32(lo64 *uint64, a uint64, b uint32) (hi32 uint32)
220
221
222 func _div64by32(a uint64, b uint32, r *uint32) (q uint32)
223
224
225 func dodiv(n, d uint64) (q, r uint64) {
226 if GOARCH == "arm" {
227
228
229 return slowdodiv(n, d)
230 }
231
232 if GOARCH == "mips" || GOARCH == "mipsle" {
233
234 return slowdodiv(n, d)
235 }
236
237 if d > n {
238 return 0, n
239 }
240
241 if uint32(d>>32) != 0 {
242 t := uint32(n>>32) / uint32(d>>32)
243 var lo64 uint64
244 hi32 := _mul64by32(&lo64, d, t)
245 if hi32 != 0 || lo64 > n {
246 return slowdodiv(n, d)
247 }
248 return uint64(t), n - lo64
249 }
250
251
252 var qhi uint32
253 if uint32(n>>32) >= uint32(d) {
254 if uint32(d) == 0 {
255 panicdivide()
256 }
257 qhi = uint32(n>>32) / uint32(d)
258 n -= uint64(uint32(d)*qhi) << 32
259 } else {
260 qhi = 0
261 }
262
263 var rlo uint32
264 qlo := _div64by32(n, uint32(d), &rlo)
265 return uint64(qhi)<<32 + uint64(qlo), uint64(rlo)
266 }
267
268
269 func slowdodiv(n, d uint64) (q, r uint64) {
270 if d == 0 {
271 panicdivide()
272 }
273
274
275 capn := n
276 if n >= sign64 {
277 capn = sign64
278 }
279 i := 0
280 for d < capn {
281 d <<= 1
282 i++
283 }
284
285 for ; i >= 0; i-- {
286 q <<= 1
287 if n >= d {
288 n -= d
289 q |= 1
290 }
291 d >>= 1
292 }
293 return q, n
294 }
295
296
297
298
299
300
301
302
303
304
305
306
307 var (
308 controlWord64 uint16 = 0x3f + 2<<8 + 0<<10
309 controlWord64trunc uint16 = 0x3f + 2<<8 + 3<<10
310 )
311
View as plain text