1 // Copyright 2016 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
4
5 // This file contains rules to decompose [u]int64 types on 32-bit
6 // architectures. These rules work together with the decomposeBuiltin
7 // pass which handles phis of these typ.
8
9 (Last ___) => v.Args[len(v.Args)-1]
10
11 (Int64Hi (Int64Make hi _)) => hi
12 (Int64Lo (Int64Make _ lo)) => lo
13 (Select0 (MakeTuple x y)) => x
14 (Select1 (MakeTuple x y)) => y
15
16 (Load <t> ptr mem) && is64BitInt(t) && !config.BigEndian && t.IsSigned() =>
17 (Int64Make
18 (Load <typ.Int32> (OffPtr <typ.Int32Ptr> [4] ptr) mem)
19 (Load <typ.UInt32> ptr mem))
20
21 (Load <t> ptr mem) && is64BitInt(t) && !config.BigEndian && !t.IsSigned() =>
22 (Int64Make
23 (Load <typ.UInt32> (OffPtr <typ.UInt32Ptr> [4] ptr) mem)
24 (Load <typ.UInt32> ptr mem))
25
26 (Load <t> ptr mem) && is64BitInt(t) && config.BigEndian && t.IsSigned() =>
27 (Int64Make
28 (Load <typ.Int32> ptr mem)
29 (Load <typ.UInt32> (OffPtr <typ.UInt32Ptr> [4] ptr) mem))
30
31 (Load <t> ptr mem) && is64BitInt(t) && config.BigEndian && !t.IsSigned() =>
32 (Int64Make
33 (Load <typ.UInt32> ptr mem)
34 (Load <typ.UInt32> (OffPtr <typ.UInt32Ptr> [4] ptr) mem))
35
36 (Store {t} dst (Int64Make hi lo) mem) && t.Size() == 8 && !config.BigEndian =>
37 (Store {hi.Type}
38 (OffPtr <hi.Type.PtrTo()> [4] dst)
39 hi
40 (Store {lo.Type} dst lo mem))
41
42 (Store {t} dst (Int64Make hi lo) mem) && t.Size() == 8 && config.BigEndian =>
43 (Store {lo.Type}
44 (OffPtr <lo.Type.PtrTo()> [4] dst)
45 lo
46 (Store {hi.Type} dst hi mem))
47
48 // These are not enabled during decomposeBuiltin if late call expansion, but they are always enabled for softFloat
49 (Arg {n} [off]) && is64BitInt(v.Type) && !config.BigEndian && v.Type.IsSigned() && !(b.Func.pass.name == "decompose builtin") =>
50 (Int64Make
51 (Arg <typ.Int32> {n} [off+4])
52 (Arg <typ.UInt32> {n} [off]))
53 (Arg {n} [off]) && is64BitInt(v.Type) && !config.BigEndian && !v.Type.IsSigned() && !(b.Func.pass.name == "decompose builtin") =>
54 (Int64Make
55 (Arg <typ.UInt32> {n} [off+4])
56 (Arg <typ.UInt32> {n} [off]))
57
58 (Arg {n} [off]) && is64BitInt(v.Type) && config.BigEndian && v.Type.IsSigned() && !(b.Func.pass.name == "decompose builtin") =>
59 (Int64Make
60 (Arg <typ.Int32> {n} [off])
61 (Arg <typ.UInt32> {n} [off+4]))
62 (Arg {n} [off]) && is64BitInt(v.Type) && config.BigEndian && !v.Type.IsSigned() && !(b.Func.pass.name == "decompose builtin") =>
63 (Int64Make
64 (Arg <typ.UInt32> {n} [off])
65 (Arg <typ.UInt32> {n} [off+4]))
66
67 (Add64 <t> x y) =>
68 (Last <t>
69 x0: (Int64Lo x)
70 x1: (Int64Hi x)
71 y0: (Int64Lo y)
72 y1: (Int64Hi y)
73 add: (Add32carry x0 y0)
74 (Int64Make
75 (Add32withcarry <typ.UInt32> x1 y1 (Select1 <types.TypeFlags> add))
76 (Select0 <typ.UInt32> add)))
77
78 (Sub64 <t> x y) =>
79 (Last <t>
80 x0: (Int64Lo x)
81 x1: (Int64Hi x)
82 y0: (Int64Lo y)
83 y1: (Int64Hi y)
84 sub: (Sub32carry x0 y0)
85 (Int64Make
86 (Sub32withcarry <typ.UInt32> x1 y1 (Select1 <types.TypeFlags> sub))
87 (Select0 <typ.UInt32> sub)))
88
89 (Mul64 <t> x y) =>
90 (Last <t>
91 x0: (Int64Lo x)
92 x1: (Int64Hi x)
93 y0: (Int64Lo y)
94 y1: (Int64Hi y)
95 x0y0: (Mul32uhilo x0 y0)
96 x0y0Hi: (Select0 <typ.UInt32> x0y0)
97 x0y0Lo: (Select1 <typ.UInt32> x0y0)
98 (Int64Make
99 (Add32 <typ.UInt32> x0y0Hi
100 (Add32 <typ.UInt32>
101 (Mul32 <typ.UInt32> x0 y1)
102 (Mul32 <typ.UInt32> x1 y0)))
103 x0y0Lo))
104
105 (Mul64uhilo <t> x y) =>
106 (Last <t>
107 x0: (Int64Lo x)
108 x1: (Int64Hi x)
109 y0: (Int64Lo y)
110 y1: (Int64Hi y)
111 x0y0: (Mul32uhilo x0 y0)
112 x0y1: (Mul32uhilo x0 y1)
113 x1y0: (Mul32uhilo x1 y0)
114 x1y1: (Mul32uhilo x1 y1)
115 x0y0Hi: (Select0 <typ.UInt32> x0y0)
116 x0y0Lo: (Select1 <typ.UInt32> x0y0)
117 x0y1Hi: (Select0 <typ.UInt32> x0y1)
118 x0y1Lo: (Select1 <typ.UInt32> x0y1)
119 x1y0Hi: (Select0 <typ.UInt32> x1y0)
120 x1y0Lo: (Select1 <typ.UInt32> x1y0)
121 x1y1Hi: (Select0 <typ.UInt32> x1y1)
122 x1y1Lo: (Select1 <typ.UInt32> x1y1)
123 w1a: (Add32carry x0y0Hi x0y1Lo)
124 w2a: (Add32carrywithcarry x0y1Hi x1y0Hi (Select1 <types.TypeFlags> w1a))
125 w3a: (Add32withcarry <typ.UInt32> x1y1Hi (Const32 <typ.UInt32> [0]) (Select1 <types.TypeFlags> w2a))
126 w1b: (Add32carry x1y0Lo (Select0 <typ.UInt32> w1a))
127 w2b: (Add32carrywithcarry x1y1Lo (Select0 <typ.UInt32> w2a) (Select1 <types.TypeFlags> w1b))
128 w3b: (Add32withcarry <typ.UInt32> w3a (Const32 <typ.UInt32> [0]) (Select1 <types.TypeFlags> w2b))
129 (MakeTuple <types.NewTuple(typ.UInt64,typ.UInt64)>
130 (Int64Make w3b (Select0 <typ.UInt32> w2b))
131 (Int64Make (Select0 <typ.UInt32> w1b) x0y0Lo)))
132
133 (Hmul64u x y) => (Select0 (Mul64uhilo x y))
134
135 // Hacker's Delight p. 175: signed hmul = unsigned hmul - (x<0)&y - (y<0)&x.
136 (Hmul64 x y) =>
137 (Last
138 p: (Hmul64u <typ.UInt64> x y)
139 xSign: (Int64Make xs:(Rsh32x32 <typ.UInt32> (Int64Hi x) (Const32 <typ.UInt32> [31])) xs)
140 ySign: (Int64Make ys:(Rsh32x32 <typ.UInt32> (Int64Hi y) (Const32 <typ.UInt32> [31])) ys)
141 (Sub64 <typ.Int64> (Sub64 <typ.Int64> p (And64 <typ.Int64> xSign y)) (And64 <typ.Int64> ySign x)))
142
143 // (x+y)/2 => (x-y)/2 + y
144 (Avg64u <t> x y) => (Add64 (Rsh64Ux32 <t> (Sub64 <t> x y) (Const32 <typ.UInt32> [1])) y)
145
146
147 (And64 x y) =>
148 (Int64Make
149 (And32 <typ.UInt32> (Int64Hi x) (Int64Hi y))
150 (And32 <typ.UInt32> (Int64Lo x) (Int64Lo y)))
151
152 (Or64 x y) =>
153 (Int64Make
154 (Or32 <typ.UInt32> (Int64Hi x) (Int64Hi y))
155 (Or32 <typ.UInt32> (Int64Lo x) (Int64Lo y)))
156
157 (Xor64 x y) =>
158 (Int64Make
159 (Xor32 <typ.UInt32> (Int64Hi x) (Int64Hi y))
160 (Xor32 <typ.UInt32> (Int64Lo x) (Int64Lo y)))
161
162 (Neg64 <t> x) => (Sub64 (Const64 <t> [0]) x)
163
164 (Com64 x) =>
165 (Int64Make
166 (Com32 <typ.UInt32> (Int64Hi x))
167 (Com32 <typ.UInt32> (Int64Lo x)))
168
169 // Sadly, just because we know that x is non-zero,
170 // we don't know whether either component is,
171 // so just treat Ctz64NonZero the same as Ctz64.
172 (Ctz64NonZero ...) => (Ctz64 ...)
173
174 (Ctz64 x) =>
175 (Add32 <typ.UInt32>
176 (Ctz32 <typ.UInt32> (Int64Lo x))
177 (And32 <typ.UInt32>
178 (Com32 <typ.UInt32> (Zeromask (Int64Lo x)))
179 (Ctz32 <typ.UInt32> (Int64Hi x))))
180
181 (BitLen64 x) =>
182 (Add32 <typ.Int>
183 (BitLen32 <typ.Int> (Int64Hi x))
184 (BitLen32 <typ.Int>
185 (Or32 <typ.UInt32>
186 (Int64Lo x)
187 (Zeromask (Int64Hi x)))))
188
189 (Bswap64 x) =>
190 (Int64Make
191 (Bswap32 <typ.UInt32> (Int64Lo x))
192 (Bswap32 <typ.UInt32> (Int64Hi x)))
193
194 (SignExt32to64 x) => (Int64Make (Signmask x) x)
195 (SignExt16to64 x) => (SignExt32to64 (SignExt16to32 x))
196 (SignExt8to64 x) => (SignExt32to64 (SignExt8to32 x))
197
198 (ZeroExt32to64 x) => (Int64Make (Const32 <typ.UInt32> [0]) x)
199 (ZeroExt16to64 x) => (ZeroExt32to64 (ZeroExt16to32 x))
200 (ZeroExt8to64 x) => (ZeroExt32to64 (ZeroExt8to32 x))
201
202 (Trunc64to32 (Int64Make _ lo)) => lo
203 (Trunc64to16 (Int64Make _ lo)) => (Trunc32to16 lo)
204 (Trunc64to8 (Int64Make _ lo)) => (Trunc32to8 lo)
205 // Most general
206 (Trunc64to32 x) => (Int64Lo x)
207 (Trunc64to16 x) => (Trunc32to16 (Int64Lo x))
208 (Trunc64to8 x) => (Trunc32to8 (Int64Lo x))
209
210 (Lsh32x64 _ (Int64Make (Const32 [c]) _)) && c != 0 => (Const32 [0])
211 (Rsh32x64 x (Int64Make (Const32 [c]) _)) && c != 0 => (Signmask x)
212 (Rsh32Ux64 _ (Int64Make (Const32 [c]) _)) && c != 0 => (Const32 [0])
213 (Lsh16x64 _ (Int64Make (Const32 [c]) _)) && c != 0 => (Const32 [0])
214 (Rsh16x64 x (Int64Make (Const32 [c]) _)) && c != 0 => (Signmask (SignExt16to32 x))
215 (Rsh16Ux64 _ (Int64Make (Const32 [c]) _)) && c != 0 => (Const32 [0])
216 (Lsh8x64 _ (Int64Make (Const32 [c]) _)) && c != 0 => (Const32 [0])
217 (Rsh8x64 x (Int64Make (Const32 [c]) _)) && c != 0 => (Signmask (SignExt8to32 x))
218 (Rsh8Ux64 _ (Int64Make (Const32 [c]) _)) && c != 0 => (Const32 [0])
219
220 (Lsh32x64 [c] x (Int64Make (Const32 [0]) lo)) => (Lsh32x32 [c] x lo)
221 (Rsh32x64 [c] x (Int64Make (Const32 [0]) lo)) => (Rsh32x32 [c] x lo)
222 (Rsh32Ux64 [c] x (Int64Make (Const32 [0]) lo)) => (Rsh32Ux32 [c] x lo)
223 (Lsh16x64 [c] x (Int64Make (Const32 [0]) lo)) => (Lsh16x32 [c] x lo)
224 (Rsh16x64 [c] x (Int64Make (Const32 [0]) lo)) => (Rsh16x32 [c] x lo)
225 (Rsh16Ux64 [c] x (Int64Make (Const32 [0]) lo)) => (Rsh16Ux32 [c] x lo)
226 (Lsh8x64 [c] x (Int64Make (Const32 [0]) lo)) => (Lsh8x32 [c] x lo)
227 (Rsh8x64 [c] x (Int64Make (Const32 [0]) lo)) => (Rsh8x32 [c] x lo)
228 (Rsh8Ux64 [c] x (Int64Make (Const32 [0]) lo)) => (Rsh8Ux32 [c] x lo)
229
230 (Lsh64x64 _ (Int64Make (Const32 [c]) _)) && c != 0 => (Const64 [0])
231 (Rsh64x64 x (Int64Make (Const32 [c]) _)) && c != 0 => (Int64Make (Signmask (Int64Hi x)) (Signmask (Int64Hi x)))
232 (Rsh64Ux64 _ (Int64Make (Const32 [c]) _)) && c != 0 => (Const64 [0])
233
234 (Lsh64x64 [c] x (Int64Make (Const32 [0]) lo)) => (Lsh64x32 [c] x lo)
235 (Rsh64x64 [c] x (Int64Make (Const32 [0]) lo)) => (Rsh64x32 [c] x lo)
236 (Rsh64Ux64 [c] x (Int64Make (Const32 [0]) lo)) => (Rsh64Ux32 [c] x lo)
237
238 // turn x64 non-constant shifts to x32 shifts
239 // if high 32-bit of the shift is nonzero, make a huge shift
240 (Lsh64x64 x (Int64Make hi lo)) && hi.Op != OpConst32 =>
241 (Lsh64x32 x (Or32 <typ.UInt32> (Zeromask hi) lo))
242 (Rsh64x64 x (Int64Make hi lo)) && hi.Op != OpConst32 =>
243 (Rsh64x32 x (Or32 <typ.UInt32> (Zeromask hi) lo))
244 (Rsh64Ux64 x (Int64Make hi lo)) && hi.Op != OpConst32 =>
245 (Rsh64Ux32 x (Or32 <typ.UInt32> (Zeromask hi) lo))
246 (Lsh32x64 x (Int64Make hi lo)) && hi.Op != OpConst32 =>
247 (Lsh32x32 x (Or32 <typ.UInt32> (Zeromask hi) lo))
248 (Rsh32x64 x (Int64Make hi lo)) && hi.Op != OpConst32 =>
249 (Rsh32x32 x (Or32 <typ.UInt32> (Zeromask hi) lo))
250 (Rsh32Ux64 x (Int64Make hi lo)) && hi.Op != OpConst32 =>
251 (Rsh32Ux32 x (Or32 <typ.UInt32> (Zeromask hi) lo))
252 (Lsh16x64 x (Int64Make hi lo)) && hi.Op != OpConst32 =>
253 (Lsh16x32 x (Or32 <typ.UInt32> (Zeromask hi) lo))
254 (Rsh16x64 x (Int64Make hi lo)) && hi.Op != OpConst32 =>
255 (Rsh16x32 x (Or32 <typ.UInt32> (Zeromask hi) lo))
256 (Rsh16Ux64 x (Int64Make hi lo)) && hi.Op != OpConst32 =>
257 (Rsh16Ux32 x (Or32 <typ.UInt32> (Zeromask hi) lo))
258 (Lsh8x64 x (Int64Make hi lo)) && hi.Op != OpConst32 =>
259 (Lsh8x32 x (Or32 <typ.UInt32> (Zeromask hi) lo))
260 (Rsh8x64 x (Int64Make hi lo)) && hi.Op != OpConst32 =>
261 (Rsh8x32 x (Or32 <typ.UInt32> (Zeromask hi) lo))
262 (Rsh8Ux64 x (Int64Make hi lo)) && hi.Op != OpConst32 =>
263 (Rsh8Ux32 x (Or32 <typ.UInt32> (Zeromask hi) lo))
264
265 // Most general
266 (Lsh64x64 x y) => (Lsh64x32 x (Or32 <typ.UInt32> (Zeromask (Int64Hi y)) (Int64Lo y)))
267 (Rsh64x64 x y) => (Rsh64x32 x (Or32 <typ.UInt32> (Zeromask (Int64Hi y)) (Int64Lo y)))
268 (Rsh64Ux64 x y) => (Rsh64Ux32 x (Or32 <typ.UInt32> (Zeromask (Int64Hi y)) (Int64Lo y)))
269 (Lsh32x64 x y) => (Lsh32x32 x (Or32 <typ.UInt32> (Zeromask (Int64Hi y)) (Int64Lo y)))
270 (Rsh32x64 x y) => (Rsh32x32 x (Or32 <typ.UInt32> (Zeromask (Int64Hi y)) (Int64Lo y)))
271 (Rsh32Ux64 x y) => (Rsh32Ux32 x (Or32 <typ.UInt32> (Zeromask (Int64Hi y)) (Int64Lo y)))
272 (Lsh16x64 x y) => (Lsh16x32 x (Or32 <typ.UInt32> (Zeromask (Int64Hi y)) (Int64Lo y)))
273 (Rsh16x64 x y) => (Rsh16x32 x (Or32 <typ.UInt32> (Zeromask (Int64Hi y)) (Int64Lo y)))
274 (Rsh16Ux64 x y) => (Rsh16Ux32 x (Or32 <typ.UInt32> (Zeromask (Int64Hi y)) (Int64Lo y)))
275 (Lsh8x64 x y) => (Lsh8x32 x (Or32 <typ.UInt32> (Zeromask (Int64Hi y)) (Int64Lo y)))
276 (Rsh8x64 x y) => (Rsh8x32 x (Or32 <typ.UInt32> (Zeromask (Int64Hi y)) (Int64Lo y)))
277 (Rsh8Ux64 x y) => (Rsh8Ux32 x (Or32 <typ.UInt32> (Zeromask (Int64Hi y)) (Int64Lo y)))
278
279
280 (RotateLeft64 x (Int64Make hi lo)) => (RotateLeft64 x lo)
281 (RotateLeft32 x (Int64Make hi lo)) => (RotateLeft32 x lo)
282 (RotateLeft16 x (Int64Make hi lo)) => (RotateLeft16 x lo)
283 (RotateLeft8 x (Int64Make hi lo)) => (RotateLeft8 x lo)
284
285 // RotateLeft64 by constant, for use in divmod.
286 (RotateLeft64 <t> x (Const(64|32|16|8) [c])) && c&63 == 0 => x
287 (RotateLeft64 <t> x (Const(64|32|16|8) [c])) && c&63 == 32 => (Int64Make <t> (Int64Lo x) (Int64Hi x))
288 (RotateLeft64 <t> x (Const(64|32|16|8) [c])) && 0 < c&63 && c&63 < 32 =>
289 (Int64Make <t>
290 (Or32 <typ.UInt32>
291 (Lsh32x32 <typ.UInt32> (Int64Hi x) (Const32 <typ.UInt32> [int32(c&31)]))
292 (Rsh32Ux32 <typ.UInt32> (Int64Lo x) (Const32 <typ.UInt32> [int32(32-c&31)])))
293 (Or32 <typ.UInt32>
294 (Lsh32x32 <typ.UInt32> (Int64Lo x) (Const32 <typ.UInt32> [int32(c&31)]))
295 (Rsh32Ux32 <typ.UInt32> (Int64Hi x) (Const32 <typ.UInt32> [int32(32-c&31)]))))
296 (RotateLeft64 <t> x (Const(64|32|16|8) [c])) && 32 < c&63 && c&63 < 64 =>
297 (Int64Make <t>
298 (Or32 <typ.UInt32>
299 (Lsh32x32 <typ.UInt32> (Int64Lo x) (Const32 <typ.UInt32> [int32(c&31)]))
300 (Rsh32Ux32 <typ.UInt32> (Int64Hi x) (Const32 <typ.UInt32> [int32(32-c&31)])))
301 (Or32 <typ.UInt32>
302 (Lsh32x32 <typ.UInt32> (Int64Hi x) (Const32 <typ.UInt32> [int32(c&31)]))
303 (Rsh32Ux32 <typ.UInt32> (Int64Lo x) (Const32 <typ.UInt32> [int32(32-c&31)]))))
304
305 // Clean up constants a little
306 (Or32 <typ.UInt32> (Zeromask (Const32 [c])) y) && c == 0 => y
307 (Or32 <typ.UInt32> (Zeromask (Const32 [c])) y) && c != 0 => (Const32 <typ.UInt32> [-1])
308
309 // 64x left shift
310 // result.hi = hi<<s | lo>>(32-s) | lo<<(s-32) // >> is unsigned, large shifts result 0
311 // result.lo = lo<<s
312 (Lsh64x32 x s) =>
313 (Int64Make
314 (Or32 <typ.UInt32>
315 (Or32 <typ.UInt32>
316 (Lsh32x32 <typ.UInt32> (Int64Hi x) s)
317 (Rsh32Ux32 <typ.UInt32>
318 (Int64Lo x)
319 (Sub32 <typ.UInt32> (Const32 <typ.UInt32> [32]) s)))
320 (Lsh32x32 <typ.UInt32>
321 (Int64Lo x)
322 (Sub32 <typ.UInt32> s (Const32 <typ.UInt32> [32]))))
323 (Lsh32x32 <typ.UInt32> (Int64Lo x) s))
324 (Lsh64x16 x s) =>
325 (Int64Make
326 (Or32 <typ.UInt32>
327 (Or32 <typ.UInt32>
328 (Lsh32x16 <typ.UInt32> (Int64Hi x) s)
329 (Rsh32Ux16 <typ.UInt32>
330 (Int64Lo x)
331 (Sub16 <typ.UInt16> (Const16 <typ.UInt16> [32]) s)))
332 (Lsh32x16 <typ.UInt32>
333 (Int64Lo x)
334 (Sub16 <typ.UInt16> s (Const16 <typ.UInt16> [32]))))
335 (Lsh32x16 <typ.UInt32> (Int64Lo x) s))
336 (Lsh64x8 x s) =>
337 (Int64Make
338 (Or32 <typ.UInt32>
339 (Or32 <typ.UInt32>
340 (Lsh32x8 <typ.UInt32> (Int64Hi x) s)
341 (Rsh32Ux8 <typ.UInt32>
342 (Int64Lo x)
343 (Sub8 <typ.UInt8> (Const8 <typ.UInt8> [32]) s)))
344 (Lsh32x8 <typ.UInt32>
345 (Int64Lo x)
346 (Sub8 <typ.UInt8> s (Const8 <typ.UInt8> [32]))))
347 (Lsh32x8 <typ.UInt32> (Int64Lo x) s))
348
349 // 64x unsigned right shift
350 // result.hi = hi>>s
351 // result.lo = lo>>s | hi<<(32-s) | hi>>(s-32) // >> is unsigned, large shifts result 0
352 (Rsh64Ux32 x s) =>
353 (Int64Make
354 (Rsh32Ux32 <typ.UInt32> (Int64Hi x) s)
355 (Or32 <typ.UInt32>
356 (Or32 <typ.UInt32>
357 (Rsh32Ux32 <typ.UInt32> (Int64Lo x) s)
358 (Lsh32x32 <typ.UInt32>
359 (Int64Hi x)
360 (Sub32 <typ.UInt32> (Const32 <typ.UInt32> [32]) s)))
361 (Rsh32Ux32 <typ.UInt32>
362 (Int64Hi x)
363 (Sub32 <typ.UInt32> s (Const32 <typ.UInt32> [32])))))
364 (Rsh64Ux16 x s) =>
365 (Int64Make
366 (Rsh32Ux16 <typ.UInt32> (Int64Hi x) s)
367 (Or32 <typ.UInt32>
368 (Or32 <typ.UInt32>
369 (Rsh32Ux16 <typ.UInt32> (Int64Lo x) s)
370 (Lsh32x16 <typ.UInt32>
371 (Int64Hi x)
372 (Sub16 <typ.UInt16> (Const16 <typ.UInt16> [32]) s)))
373 (Rsh32Ux16 <typ.UInt32>
374 (Int64Hi x)
375 (Sub16 <typ.UInt16> s (Const16 <typ.UInt16> [32])))))
376 (Rsh64Ux8 x s) =>
377 (Int64Make
378 (Rsh32Ux8 <typ.UInt32> (Int64Hi x) s)
379 (Or32 <typ.UInt32>
380 (Or32 <typ.UInt32>
381 (Rsh32Ux8 <typ.UInt32> (Int64Lo x) s)
382 (Lsh32x8 <typ.UInt32>
383 (Int64Hi x)
384 (Sub8 <typ.UInt8> (Const8 <typ.UInt8> [32]) s)))
385 (Rsh32Ux8 <typ.UInt32>
386 (Int64Hi x)
387 (Sub8 <typ.UInt8> s (Const8 <typ.UInt8> [32])))))
388
389 // 64x signed right shift
390 // result.hi = hi>>s
391 // result.lo = lo>>s | hi<<(32-s) | (hi>>(s-32))&zeromask(s>>5) // hi>>(s-32) is signed, large shifts result 0/-1
392 (Rsh64x32 x s) =>
393 (Int64Make
394 (Rsh32x32 <typ.UInt32> (Int64Hi x) s)
395 (Or32 <typ.UInt32>
396 (Or32 <typ.UInt32>
397 (Rsh32Ux32 <typ.UInt32> (Int64Lo x) s)
398 (Lsh32x32 <typ.UInt32>
399 (Int64Hi x)
400 (Sub32 <typ.UInt32> (Const32 <typ.UInt32> [32]) s)))
401 (And32 <typ.UInt32>
402 (Rsh32x32 <typ.UInt32>
403 (Int64Hi x)
404 (Sub32 <typ.UInt32> s (Const32 <typ.UInt32> [32])))
405 (Zeromask
406 (Rsh32Ux32 <typ.UInt32> s (Const32 <typ.UInt32> [5]))))))
407 (Rsh64x16 x s) =>
408 (Int64Make
409 (Rsh32x16 <typ.UInt32> (Int64Hi x) s)
410 (Or32 <typ.UInt32>
411 (Or32 <typ.UInt32>
412 (Rsh32Ux16 <typ.UInt32> (Int64Lo x) s)
413 (Lsh32x16 <typ.UInt32>
414 (Int64Hi x)
415 (Sub16 <typ.UInt16> (Const16 <typ.UInt16> [32]) s)))
416 (And32 <typ.UInt32>
417 (Rsh32x16 <typ.UInt32>
418 (Int64Hi x)
419 (Sub16 <typ.UInt16> s (Const16 <typ.UInt16> [32])))
420 (Zeromask
421 (ZeroExt16to32
422 (Rsh16Ux32 <typ.UInt16> s (Const32 <typ.UInt32> [5])))))))
423 (Rsh64x8 x s) =>
424 (Int64Make
425 (Rsh32x8 <typ.UInt32> (Int64Hi x) s)
426 (Or32 <typ.UInt32>
427 (Or32 <typ.UInt32>
428 (Rsh32Ux8 <typ.UInt32> (Int64Lo x) s)
429 (Lsh32x8 <typ.UInt32>
430 (Int64Hi x)
431 (Sub8 <typ.UInt8> (Const8 <typ.UInt8> [32]) s)))
432 (And32 <typ.UInt32>
433 (Rsh32x8 <typ.UInt32>
434 (Int64Hi x)
435 (Sub8 <typ.UInt8> s (Const8 <typ.UInt8> [32])))
436 (Zeromask
437 (ZeroExt8to32
438 (Rsh8Ux32 <typ.UInt8> s (Const32 <typ.UInt32> [5])))))))
439
440 (Const64 <t> [c]) && t.IsSigned() =>
441 (Int64Make (Const32 <typ.Int32> [int32(c>>32)]) (Const32 <typ.UInt32> [int32(c)]))
442 (Const64 <t> [c]) && !t.IsSigned() =>
443 (Int64Make (Const32 <typ.UInt32> [int32(c>>32)]) (Const32 <typ.UInt32> [int32(c)]))
444
445 (Eq64 x y) =>
446 (AndB
447 (Eq32 (Int64Hi x) (Int64Hi y))
448 (Eq32 (Int64Lo x) (Int64Lo y)))
449
450 (Neq64 x y) =>
451 (OrB
452 (Neq32 (Int64Hi x) (Int64Hi y))
453 (Neq32 (Int64Lo x) (Int64Lo y)))
454
455 (Less64U x y) =>
456 (OrB
457 (Less32U (Int64Hi x) (Int64Hi y))
458 (AndB
459 (Eq32 (Int64Hi x) (Int64Hi y))
460 (Less32U (Int64Lo x) (Int64Lo y))))
461
462 (Leq64U x y) =>
463 (OrB
464 (Less32U (Int64Hi x) (Int64Hi y))
465 (AndB
466 (Eq32 (Int64Hi x) (Int64Hi y))
467 (Leq32U (Int64Lo x) (Int64Lo y))))
468
469 (Less64 x y) =>
470 (OrB
471 (Less32 (Int64Hi x) (Int64Hi y))
472 (AndB
473 (Eq32 (Int64Hi x) (Int64Hi y))
474 (Less32U (Int64Lo x) (Int64Lo y))))
475
476 (Leq64 x y) =>
477 (OrB
478 (Less32 (Int64Hi x) (Int64Hi y))
479 (AndB
480 (Eq32 (Int64Hi x) (Int64Hi y))
481 (Leq32U (Int64Lo x) (Int64Lo y))))
482
View as plain text