Home | History | Annotate | Download | only in gen
      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 types.
      8 
      9 (Int64Hi (Int64Make hi _)) -> hi
     10 (Int64Lo (Int64Make _ lo)) -> lo
     11 
     12 
     13 (Load <t> ptr mem) && is64BitInt(t) && !config.BigEndian && t.IsSigned() ->
     14 	(Int64Make
     15 		(Load <config.fe.TypeInt32()> (OffPtr <config.fe.TypeInt32().PtrTo()> [4] ptr) mem)
     16 		(Load <config.fe.TypeUInt32()> ptr mem))
     17 
     18 (Load <t> ptr mem) && is64BitInt(t) && !config.BigEndian && !t.IsSigned() ->
     19 	(Int64Make
     20 		(Load <config.fe.TypeUInt32()> (OffPtr <config.fe.TypeUInt32().PtrTo()> [4] ptr) mem)
     21 		(Load <config.fe.TypeUInt32()> ptr mem))
     22 
     23 (Load <t> ptr mem) && is64BitInt(t) && config.BigEndian && t.IsSigned() ->
     24 	(Int64Make
     25 		(Load <config.fe.TypeInt32()> ptr mem)
     26 		(Load <config.fe.TypeUInt32()> (OffPtr <config.fe.TypeUInt32().PtrTo()> [4] ptr) mem))
     27 
     28 (Load <t> ptr mem) && is64BitInt(t) && config.BigEndian && !t.IsSigned() ->
     29 	(Int64Make
     30 		(Load <config.fe.TypeUInt32()> ptr mem)
     31 		(Load <config.fe.TypeUInt32()> (OffPtr <config.fe.TypeUInt32().PtrTo()> [4] ptr) mem))
     32 
     33 (Store [8] dst (Int64Make hi lo) mem) && !config.BigEndian ->
     34 	(Store [4]
     35 		(OffPtr <hi.Type.PtrTo()> [4] dst)
     36 		hi
     37 		(Store [4] dst lo mem))
     38 
     39 (Store [8] dst (Int64Make hi lo) mem) && config.BigEndian ->
     40 	(Store [4]
     41 		(OffPtr <lo.Type.PtrTo()> [4] dst)
     42 		lo
     43 		(Store [4] dst hi mem))
     44 
     45 (Arg {n} [off]) && is64BitInt(v.Type) && !config.BigEndian && v.Type.IsSigned() ->
     46   (Int64Make
     47     (Arg <config.fe.TypeInt32()> {n} [off+4])
     48     (Arg <config.fe.TypeUInt32()> {n} [off]))
     49 (Arg {n} [off]) && is64BitInt(v.Type) && !config.BigEndian && !v.Type.IsSigned() ->
     50   (Int64Make
     51     (Arg <config.fe.TypeUInt32()> {n} [off+4])
     52     (Arg <config.fe.TypeUInt32()> {n} [off]))
     53 
     54 (Arg {n} [off]) && is64BitInt(v.Type) && config.BigEndian && v.Type.IsSigned() ->
     55   (Int64Make
     56     (Arg <config.fe.TypeInt32()> {n} [off])
     57     (Arg <config.fe.TypeUInt32()> {n} [off+4]))
     58 (Arg {n} [off]) && is64BitInt(v.Type) && config.BigEndian && !v.Type.IsSigned() ->
     59   (Int64Make
     60     (Arg <config.fe.TypeUInt32()> {n} [off])
     61     (Arg <config.fe.TypeUInt32()> {n} [off+4]))
     62 
     63 (Add64 x y) ->
     64 	(Int64Make
     65 		(Add32withcarry <config.fe.TypeInt32()>
     66 			(Int64Hi x)
     67 			(Int64Hi y)
     68 			(Select1 <TypeFlags> (Add32carry (Int64Lo x) (Int64Lo y))))
     69 		(Select0 <config.fe.TypeUInt32()> (Add32carry (Int64Lo x) (Int64Lo y))))
     70 
     71 (Sub64 x y) ->
     72 	(Int64Make
     73 		(Sub32withcarry <config.fe.TypeInt32()>
     74 			(Int64Hi x)
     75 			(Int64Hi y)
     76 			(Select1 <TypeFlags> (Sub32carry (Int64Lo x) (Int64Lo y))))
     77 		(Select0 <config.fe.TypeUInt32()> (Sub32carry (Int64Lo x) (Int64Lo y))))
     78 
     79 (Mul64 x y) ->
     80 	(Int64Make
     81 		(Add32 <config.fe.TypeUInt32()>
     82 			(Mul32 <config.fe.TypeUInt32()> (Int64Lo x) (Int64Hi y))
     83 			(Add32 <config.fe.TypeUInt32()>
     84 				(Mul32 <config.fe.TypeUInt32()> (Int64Hi x) (Int64Lo y))
     85 				(Select0 <config.fe.TypeUInt32()> (Mul32uhilo (Int64Lo x) (Int64Lo y)))))
     86 		(Select1 <config.fe.TypeUInt32()> (Mul32uhilo (Int64Lo x) (Int64Lo y))))
     87 
     88 (And64 x y) ->
     89 	(Int64Make
     90 		(And32 <config.fe.TypeUInt32()> (Int64Hi x) (Int64Hi y))
     91 		(And32 <config.fe.TypeUInt32()> (Int64Lo x) (Int64Lo y)))
     92 
     93 (Or64 x y) ->
     94 	(Int64Make
     95 		(Or32 <config.fe.TypeUInt32()> (Int64Hi x) (Int64Hi y))
     96 		(Or32 <config.fe.TypeUInt32()> (Int64Lo x) (Int64Lo y)))
     97 
     98 (Xor64 x y) ->
     99 	(Int64Make
    100 		(Xor32 <config.fe.TypeUInt32()> (Int64Hi x) (Int64Hi y))
    101 		(Xor32 <config.fe.TypeUInt32()> (Int64Lo x) (Int64Lo y)))
    102 
    103 (Neg64 <t> x) -> (Sub64 (Const64 <t> [0]) x)
    104 
    105 (Com64 x) ->
    106 	(Int64Make
    107 		(Com32 <config.fe.TypeUInt32()> (Int64Hi x))
    108 		(Com32 <config.fe.TypeUInt32()> (Int64Lo x)))
    109 
    110 (Ctz64 x) ->
    111 	(Int64Make
    112 		(Const32 <config.fe.TypeUInt32()> [0])
    113 		(Add32 <config.fe.TypeUInt32()>
    114 			(Ctz32 <config.fe.TypeUInt32()> (Int64Lo x))
    115 			(And32 <config.fe.TypeUInt32()>
    116 				(Com32 <config.fe.TypeUInt32()> (Zeromask (Int64Lo x)))
    117 				(Ctz32 <config.fe.TypeUInt32()> (Int64Hi x)))))
    118 
    119 (Bswap64 x) ->
    120 	(Int64Make
    121 		(Bswap32 <config.fe.TypeUInt32()> (Int64Lo x))
    122 		(Bswap32 <config.fe.TypeUInt32()> (Int64Hi x)))
    123 
    124 (SignExt32to64 x) -> (Int64Make (Signmask x) x)
    125 (SignExt16to64 x) -> (SignExt32to64 (SignExt16to32 x))
    126 (SignExt8to64 x) -> (SignExt32to64 (SignExt8to32 x))
    127 
    128 (ZeroExt32to64 x) -> (Int64Make (Const32 <config.fe.TypeUInt32()> [0]) x)
    129 (ZeroExt16to64 x) -> (ZeroExt32to64 (ZeroExt16to32 x))
    130 (ZeroExt8to64 x) -> (ZeroExt32to64 (ZeroExt8to32 x))
    131 
    132 (Trunc64to32 (Int64Make _ lo)) -> lo
    133 (Trunc64to16 (Int64Make _ lo)) -> (Trunc32to16 lo)
    134 (Trunc64to8 (Int64Make _ lo)) -> (Trunc32to8 lo)
    135 
    136 (Lsh32x64 _ (Int64Make (Const32 [c]) _)) && c != 0 -> (Const32 [0])
    137 (Rsh32x64 x (Int64Make (Const32 [c]) _)) && c != 0 -> (Signmask x)
    138 (Rsh32Ux64 _ (Int64Make (Const32 [c]) _)) && c != 0 -> (Const32 [0])
    139 (Lsh16x64 _ (Int64Make (Const32 [c]) _)) && c != 0 -> (Const32 [0])
    140 (Rsh16x64 x (Int64Make (Const32 [c]) _)) && c != 0 -> (Signmask (SignExt16to32 x))
    141 (Rsh16Ux64 _ (Int64Make (Const32 [c]) _)) && c != 0 -> (Const32 [0])
    142 (Lsh8x64 _ (Int64Make (Const32 [c]) _)) && c != 0 -> (Const32 [0])
    143 (Rsh8x64 x (Int64Make (Const32 [c]) _)) && c != 0 -> (Signmask (SignExt8to32 x))
    144 (Rsh8Ux64 _ (Int64Make (Const32 [c]) _)) && c != 0 -> (Const32 [0])
    145 
    146 (Lsh32x64 x (Int64Make (Const32 [0]) lo)) -> (Lsh32x32 x lo)
    147 (Rsh32x64 x (Int64Make (Const32 [0]) lo)) -> (Rsh32x32 x lo)
    148 (Rsh32Ux64 x (Int64Make (Const32 [0]) lo)) -> (Rsh32Ux32 x lo)
    149 (Lsh16x64 x (Int64Make (Const32 [0]) lo)) -> (Lsh16x32 x lo)
    150 (Rsh16x64 x (Int64Make (Const32 [0]) lo)) -> (Rsh16x32 x lo)
    151 (Rsh16Ux64 x (Int64Make (Const32 [0]) lo)) -> (Rsh16Ux32 x lo)
    152 (Lsh8x64 x (Int64Make (Const32 [0]) lo)) -> (Lsh8x32 x lo)
    153 (Rsh8x64 x (Int64Make (Const32 [0]) lo)) -> (Rsh8x32 x lo)
    154 (Rsh8Ux64 x (Int64Make (Const32 [0]) lo)) -> (Rsh8Ux32 x lo)
    155 
    156 (Lsh64x64 _ (Int64Make (Const32 [c]) _)) && c != 0 -> (Const64 [0])
    157 (Rsh64x64 x (Int64Make (Const32 [c]) _)) && c != 0 -> (Int64Make (Signmask (Int64Hi x)) (Signmask (Int64Hi x)))
    158 (Rsh64Ux64 _ (Int64Make (Const32 [c]) _)) && c != 0 -> (Const64 [0])
    159 
    160 (Lsh64x64 x (Int64Make (Const32 [0]) lo)) -> (Lsh64x32 x lo)
    161 (Rsh64x64 x (Int64Make (Const32 [0]) lo)) -> (Rsh64x32 x lo)
    162 (Rsh64Ux64 x (Int64Make (Const32 [0]) lo)) -> (Rsh64Ux32 x lo)
    163 
    164 // turn x64 non-constant shifts to x32 shifts
    165 // if high 32-bit of the shift is nonzero, make a huge shift
    166 (Lsh64x64 x (Int64Make hi lo)) && hi.Op != OpConst32 ->
    167 	(Lsh64x32 x (Or32 <config.fe.TypeUInt32()> (Zeromask hi) lo))
    168 (Rsh64x64 x (Int64Make hi lo)) && hi.Op != OpConst32 ->
    169 	(Rsh64x32 x (Or32 <config.fe.TypeUInt32()> (Zeromask hi) lo))
    170 (Rsh64Ux64 x (Int64Make hi lo)) && hi.Op != OpConst32 ->
    171 	(Rsh64Ux32 x (Or32 <config.fe.TypeUInt32()> (Zeromask hi) lo))
    172 (Lsh32x64 x (Int64Make hi lo)) && hi.Op != OpConst32 ->
    173 	(Lsh32x32 x (Or32 <config.fe.TypeUInt32()> (Zeromask hi) lo))
    174 (Rsh32x64 x (Int64Make hi lo)) && hi.Op != OpConst32 ->
    175 	(Rsh32x32 x (Or32 <config.fe.TypeUInt32()> (Zeromask hi) lo))
    176 (Rsh32Ux64 x (Int64Make hi lo)) && hi.Op != OpConst32 ->
    177 	(Rsh32Ux32 x (Or32 <config.fe.TypeUInt32()> (Zeromask hi) lo))
    178 (Lsh16x64 x (Int64Make hi lo)) && hi.Op != OpConst32 ->
    179 	(Lsh16x32 x (Or32 <config.fe.TypeUInt32()> (Zeromask hi) lo))
    180 (Rsh16x64 x (Int64Make hi lo)) && hi.Op != OpConst32 ->
    181 	(Rsh16x32 x (Or32 <config.fe.TypeUInt32()> (Zeromask hi) lo))
    182 (Rsh16Ux64 x (Int64Make hi lo)) && hi.Op != OpConst32 ->
    183 	(Rsh16Ux32 x (Or32 <config.fe.TypeUInt32()> (Zeromask hi) lo))
    184 (Lsh8x64 x (Int64Make hi lo)) && hi.Op != OpConst32 ->
    185 	(Lsh8x32 x (Or32 <config.fe.TypeUInt32()> (Zeromask hi) lo))
    186 (Rsh8x64 x (Int64Make hi lo)) && hi.Op != OpConst32 ->
    187 	(Rsh8x32 x (Or32 <config.fe.TypeUInt32()> (Zeromask hi) lo))
    188 (Rsh8Ux64 x (Int64Make hi lo)) && hi.Op != OpConst32 ->
    189 	(Rsh8Ux32 x (Or32 <config.fe.TypeUInt32()> (Zeromask hi) lo))
    190 
    191 // 64x left shift
    192 // result.hi = hi<<s | lo>>(32-s) | lo<<(s-32) // >> is unsigned, large shifts result 0
    193 // result.lo = lo<<s
    194 (Lsh64x32 (Int64Make hi lo) s) ->
    195 	(Int64Make
    196 		(Or32 <config.fe.TypeUInt32()>
    197 			(Or32 <config.fe.TypeUInt32()>
    198 				(Lsh32x32 <config.fe.TypeUInt32()> hi s)
    199 				(Rsh32Ux32 <config.fe.TypeUInt32()>
    200 					lo
    201 					(Sub32 <config.fe.TypeUInt32()> (Const32 <config.fe.TypeUInt32()> [32]) s)))
    202 			(Lsh32x32 <config.fe.TypeUInt32()>
    203 				lo
    204 				(Sub32 <config.fe.TypeUInt32()> s (Const32 <config.fe.TypeUInt32()> [32]))))
    205 		(Lsh32x32 <config.fe.TypeUInt32()> lo s))
    206 (Lsh64x16 (Int64Make hi lo) s) ->
    207 	(Int64Make
    208 		(Or32 <config.fe.TypeUInt32()>
    209 			(Or32 <config.fe.TypeUInt32()>
    210 				(Lsh32x16 <config.fe.TypeUInt32()> hi s)
    211 				(Rsh32Ux16 <config.fe.TypeUInt32()>
    212 					lo
    213 					(Sub16 <config.fe.TypeUInt16()> (Const16 <config.fe.TypeUInt16()> [32]) s)))
    214 			(Lsh32x16 <config.fe.TypeUInt32()>
    215 				lo
    216 				(Sub16 <config.fe.TypeUInt16()> s (Const16 <config.fe.TypeUInt16()> [32]))))
    217 		(Lsh32x16 <config.fe.TypeUInt32()> lo s))
    218 (Lsh64x8 (Int64Make hi lo) s) ->
    219 	(Int64Make
    220 		(Or32 <config.fe.TypeUInt32()>
    221 			(Or32 <config.fe.TypeUInt32()>
    222 				(Lsh32x8 <config.fe.TypeUInt32()> hi s)
    223 				(Rsh32Ux8 <config.fe.TypeUInt32()>
    224 					lo
    225 					(Sub8 <config.fe.TypeUInt8()> (Const8 <config.fe.TypeUInt8()> [32]) s)))
    226 			(Lsh32x8 <config.fe.TypeUInt32()>
    227 				lo
    228 				(Sub8 <config.fe.TypeUInt8()> s (Const8 <config.fe.TypeUInt8()> [32]))))
    229 		(Lsh32x8 <config.fe.TypeUInt32()> lo s))
    230 
    231 // 64x unsigned right shift
    232 // result.hi = hi>>s
    233 // result.lo = lo>>s | hi<<(32-s) | hi>>(s-32) // >> is unsigned, large shifts result 0
    234 (Rsh64Ux32 (Int64Make hi lo) s) ->
    235 	(Int64Make
    236 		(Rsh32Ux32 <config.fe.TypeUInt32()> hi s)
    237 		(Or32 <config.fe.TypeUInt32()>
    238 			(Or32 <config.fe.TypeUInt32()>
    239 				(Rsh32Ux32 <config.fe.TypeUInt32()> lo s)
    240 				(Lsh32x32 <config.fe.TypeUInt32()>
    241 					hi
    242 					(Sub32 <config.fe.TypeUInt32()> (Const32 <config.fe.TypeUInt32()> [32]) s)))
    243 			(Rsh32Ux32 <config.fe.TypeUInt32()>
    244 				hi
    245 				(Sub32 <config.fe.TypeUInt32()> s (Const32 <config.fe.TypeUInt32()> [32])))))
    246 (Rsh64Ux16 (Int64Make hi lo) s) ->
    247 	(Int64Make
    248 		(Rsh32Ux16 <config.fe.TypeUInt32()> hi s)
    249 		(Or32 <config.fe.TypeUInt32()>
    250 			(Or32 <config.fe.TypeUInt32()>
    251 				(Rsh32Ux16 <config.fe.TypeUInt32()> lo s)
    252 				(Lsh32x16 <config.fe.TypeUInt32()>
    253 					hi
    254 					(Sub16 <config.fe.TypeUInt16()> (Const16 <config.fe.TypeUInt16()> [32]) s)))
    255 			(Rsh32Ux16 <config.fe.TypeUInt32()>
    256 				hi
    257 				(Sub16 <config.fe.TypeUInt16()> s (Const16 <config.fe.TypeUInt16()> [32])))))
    258 (Rsh64Ux8 (Int64Make hi lo) s) ->
    259 	(Int64Make
    260 		(Rsh32Ux8 <config.fe.TypeUInt32()> hi s)
    261 		(Or32 <config.fe.TypeUInt32()>
    262 			(Or32 <config.fe.TypeUInt32()>
    263 				(Rsh32Ux8 <config.fe.TypeUInt32()> lo s)
    264 				(Lsh32x8 <config.fe.TypeUInt32()>
    265 					hi
    266 					(Sub8 <config.fe.TypeUInt8()> (Const8 <config.fe.TypeUInt8()> [32]) s)))
    267 			(Rsh32Ux8 <config.fe.TypeUInt32()>
    268 				hi
    269 				(Sub8 <config.fe.TypeUInt8()> s (Const8 <config.fe.TypeUInt8()> [32])))))
    270 
    271 // 64x signed right shift
    272 // result.hi = hi>>s
    273 // result.lo = lo>>s | hi<<(32-s) | (hi>>(s-32))&zeromask(s>>5) // hi>>(s-32) is signed, large shifts result 0/-1
    274 (Rsh64x32 (Int64Make hi lo) s) ->
    275 	(Int64Make
    276 		(Rsh32x32 <config.fe.TypeUInt32()> hi s)
    277 		(Or32 <config.fe.TypeUInt32()>
    278 			(Or32 <config.fe.TypeUInt32()>
    279 				(Rsh32Ux32 <config.fe.TypeUInt32()> lo s)
    280 				(Lsh32x32 <config.fe.TypeUInt32()>
    281 					hi
    282 					(Sub32 <config.fe.TypeUInt32()> (Const32 <config.fe.TypeUInt32()> [32]) s)))
    283 			(And32 <config.fe.TypeUInt32()>
    284 				(Rsh32x32 <config.fe.TypeUInt32()>
    285 					hi
    286 					(Sub32 <config.fe.TypeUInt32()> s (Const32 <config.fe.TypeUInt32()> [32])))
    287 				(Zeromask
    288 					(Rsh32Ux32 <config.fe.TypeUInt32()> s (Const32 <config.fe.TypeUInt32()> [5]))))))
    289 (Rsh64x16 (Int64Make hi lo) s) ->
    290 	(Int64Make
    291 		(Rsh32x16 <config.fe.TypeUInt32()> hi s)
    292 		(Or32 <config.fe.TypeUInt32()>
    293 			(Or32 <config.fe.TypeUInt32()>
    294 				(Rsh32Ux16 <config.fe.TypeUInt32()> lo s)
    295 				(Lsh32x16 <config.fe.TypeUInt32()>
    296 					hi
    297 					(Sub16 <config.fe.TypeUInt16()> (Const16 <config.fe.TypeUInt16()> [32]) s)))
    298 			(And32 <config.fe.TypeUInt32()>
    299 				(Rsh32x16 <config.fe.TypeUInt32()>
    300 					hi
    301 					(Sub16 <config.fe.TypeUInt16()> s (Const16 <config.fe.TypeUInt16()> [32])))
    302 				(Zeromask
    303 					(ZeroExt16to32
    304 						(Rsh16Ux32 <config.fe.TypeUInt16()> s (Const32 <config.fe.TypeUInt32()> [5])))))))
    305 (Rsh64x8 (Int64Make hi lo) s) ->
    306 	(Int64Make
    307 		(Rsh32x8 <config.fe.TypeUInt32()> hi s)
    308 		(Or32 <config.fe.TypeUInt32()>
    309 			(Or32 <config.fe.TypeUInt32()>
    310 				(Rsh32Ux8 <config.fe.TypeUInt32()> lo s)
    311 				(Lsh32x8 <config.fe.TypeUInt32()>
    312 					hi
    313 					(Sub8 <config.fe.TypeUInt8()> (Const8 <config.fe.TypeUInt8()> [32]) s)))
    314 			(And32 <config.fe.TypeUInt32()>
    315 				(Rsh32x8 <config.fe.TypeUInt32()>
    316 					hi
    317 					(Sub8 <config.fe.TypeUInt8()> s (Const8 <config.fe.TypeUInt8()> [32])))
    318 				(Zeromask
    319 					(ZeroExt8to32
    320 						(Rsh8Ux32 <config.fe.TypeUInt8()> s (Const32 <config.fe.TypeUInt32()> [5])))))))
    321 
    322 // 64xConst32 shifts
    323 // we probably do not need them -- lateopt may take care of them just fine
    324 //(Lsh64x32 _ (Const32 [c])) && uint32(c) >= 64 -> (Const64 [0])
    325 //(Rsh64x32 x (Const32 [c])) && uint32(c) >= 64 -> (Int64Make (Signmask (Int64Hi x)) (Signmask (Int64Hi x)))
    326 //(Rsh64Ux32 _ (Const32 [c])) && uint32(c) >= 64 -> (Const64 [0])
    327 //
    328 //(Lsh64x32 x (Const32 [c])) && c < 64 && c > 32 ->
    329 //	(Int64Make
    330 //		(Lsh32x32 <config.fe.TypeUInt32()> (Int64Lo x) (Const32 <config.fe.TypeUInt32()> [c-32]))
    331 //		(Const32 <config.fe.TypeUInt32()> [0]))
    332 //(Rsh64x32 x (Const32 [c])) && c < 64 && c > 32 ->
    333 //	(Int64Make
    334 //		(Signmask (Int64Hi x))
    335 //		(Rsh32x32 <config.fe.TypeInt32()> (Int64Hi x) (Const32 <config.fe.TypeUInt32()> [c-32])))
    336 //(Rsh64Ux32 x (Const32 [c])) && c < 64 && c > 32 ->
    337 //	(Int64Make
    338 //		(Const32 <config.fe.TypeUInt32()> [0])
    339 //		(Rsh32Ux32 <config.fe.TypeUInt32()> (Int64Hi x) (Const32 <config.fe.TypeUInt32()> [c-32])))
    340 //
    341 //(Lsh64x32 x (Const32 [32])) -> (Int64Make (Int64Lo x) (Const32 <config.fe.TypeUInt32()> [0]))
    342 //(Rsh64x32 x (Const32 [32])) -> (Int64Make (Signmask (Int64Hi x)) (Int64Hi x))
    343 //(Rsh64Ux32 x (Const32 [32])) -> (Int64Make (Const32 <config.fe.TypeUInt32()> [0]) (Int64Hi x))
    344 //
    345 //(Lsh64x32 x (Const32 [c])) && c < 32 && c > 0 ->
    346 //	(Int64Make
    347 //		(Or32 <config.fe.TypeUInt32()>
    348 //			(Lsh32x32 <config.fe.TypeUInt32()> (Int64Hi x) (Const32 <config.fe.TypeUInt32()> [c]))
    349 //			(Rsh32Ux32 <config.fe.TypeUInt32()> (Int64Lo x) (Const32 <config.fe.TypeUInt32()> [32-c])))
    350 //		(Lsh32x32 <config.fe.TypeUInt32()> (Int64Lo x) (Const32 <config.fe.TypeUInt32()> [c])))
    351 //(Rsh64x32 x (Const32 [c])) && c < 32 && c > 0 ->
    352 //	(Int64Make
    353 //		(Rsh32x32 <config.fe.TypeInt32()> (Int64Hi x) (Const32 <config.fe.TypeUInt32()> [c]))
    354 //		(Or32 <config.fe.TypeUInt32()>
    355 //			(Rsh32Ux32 <config.fe.TypeUInt32()> (Int64Lo x) (Const32 <config.fe.TypeUInt32()> [c]))
    356 //			(Lsh32x32 <config.fe.TypeUInt32()> (Int64Hi x) (Const32 <config.fe.TypeUInt32()> [32-c]))))
    357 //(Rsh64Ux32 x (Const32 [c])) && c < 32 && c > 0 ->
    358 //	(Int64Make
    359 //		(Rsh32Ux32 <config.fe.TypeUInt32()> (Int64Hi x) (Const32 <config.fe.TypeUInt32()> [c]))
    360 //		(Or32 <config.fe.TypeUInt32()>
    361 //			(Rsh32Ux32 <config.fe.TypeUInt32()> (Int64Lo x) (Const32 <config.fe.TypeUInt32()> [c]))
    362 //			(Lsh32x32 <config.fe.TypeUInt32()> (Int64Hi x) (Const32 <config.fe.TypeUInt32()> [32-c]))))
    363 //
    364 //(Lsh64x32 x (Const32 [0])) -> x
    365 //(Rsh64x32 x (Const32 [0])) -> x
    366 //(Rsh64Ux32 x (Const32 [0])) -> x
    367 
    368 (Lrot64 (Int64Make hi lo) [c]) && c <= 32 ->
    369 	(Int64Make
    370 		(Or32 <config.fe.TypeUInt32()>
    371 			(Lsh32x32 <config.fe.TypeUInt32()> hi (Const32 <config.fe.TypeUInt32()> [c]))
    372 			(Rsh32Ux32 <config.fe.TypeUInt32()> lo (Const32 <config.fe.TypeUInt32()> [32-c])))
    373 		(Or32 <config.fe.TypeUInt32()>
    374 			(Lsh32x32 <config.fe.TypeUInt32()> lo (Const32 <config.fe.TypeUInt32()> [c]))
    375 			(Rsh32Ux32 <config.fe.TypeUInt32()> hi (Const32 <config.fe.TypeUInt32()> [32-c]))))
    376 (Lrot64 (Int64Make hi lo) [c]) && c > 32 -> (Lrot64 (Int64Make lo hi) [c-32])
    377 
    378 (Const64 <t> [c]) && t.IsSigned() ->
    379 	(Int64Make (Const32 <config.fe.TypeInt32()> [c>>32]) (Const32 <config.fe.TypeUInt32()> [int64(int32(c))]))
    380 (Const64 <t> [c]) && !t.IsSigned() ->
    381 	(Int64Make (Const32 <config.fe.TypeUInt32()> [c>>32]) (Const32 <config.fe.TypeUInt32()> [int64(int32(c))]))
    382 
    383 (Eq64 x y) ->
    384 	(AndB
    385 		(Eq32 (Int64Hi x) (Int64Hi y))
    386 		(Eq32 (Int64Lo x) (Int64Lo y)))
    387 
    388 (Neq64 x y) ->
    389 	(OrB
    390 		(Neq32 (Int64Hi x) (Int64Hi y))
    391 		(Neq32 (Int64Lo x) (Int64Lo y)))
    392 
    393 (Less64U x y) ->
    394 	(OrB
    395 		(Less32U (Int64Hi x) (Int64Hi y))
    396 		(AndB
    397 			(Eq32 (Int64Hi x) (Int64Hi y))
    398 			(Less32U (Int64Lo x) (Int64Lo y))))
    399 
    400 (Leq64U x y) ->
    401 	(OrB
    402 		(Less32U (Int64Hi x) (Int64Hi y))
    403 		(AndB
    404 			(Eq32 (Int64Hi x) (Int64Hi y))
    405 			(Leq32U (Int64Lo x) (Int64Lo y))))
    406 
    407 (Greater64U x y) ->
    408 	(OrB
    409 		(Greater32U (Int64Hi x) (Int64Hi y))
    410 		(AndB
    411 			(Eq32 (Int64Hi x) (Int64Hi y))
    412 			(Greater32U (Int64Lo x) (Int64Lo y))))
    413 
    414 (Geq64U x y) ->
    415 	(OrB
    416 		(Greater32U (Int64Hi x) (Int64Hi y))
    417 		(AndB
    418 			(Eq32 (Int64Hi x) (Int64Hi y))
    419 			(Geq32U (Int64Lo x) (Int64Lo y))))
    420 
    421 (Less64 x y) ->
    422 	(OrB
    423 		(Less32 (Int64Hi x) (Int64Hi y))
    424 		(AndB
    425 			(Eq32 (Int64Hi x) (Int64Hi y))
    426 			(Less32U (Int64Lo x) (Int64Lo y))))
    427 
    428 (Leq64 x y) ->
    429 	(OrB
    430 		(Less32 (Int64Hi x) (Int64Hi y))
    431 		(AndB
    432 			(Eq32 (Int64Hi x) (Int64Hi y))
    433 			(Leq32U (Int64Lo x) (Int64Lo y))))
    434 
    435 (Greater64 x y) ->
    436 	(OrB
    437 		(Greater32 (Int64Hi x) (Int64Hi y))
    438 		(AndB
    439 			(Eq32 (Int64Hi x) (Int64Hi y))
    440 			(Greater32U (Int64Lo x) (Int64Lo y))))
    441 
    442 (Geq64 x y) ->
    443 	(OrB
    444 		(Greater32 (Int64Hi x) (Int64Hi y))
    445 		(AndB
    446 			(Eq32 (Int64Hi x) (Int64Hi y))
    447 			(Geq32U (Int64Lo x) (Int64Lo y))))
    448