...
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))))
View as plain text