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