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