...

Text file src/cmd/compile/internal/ssa/_gen/dec64.rules

Documentation: cmd/compile/internal/ssa/_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 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