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

     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