Have constant folding be more flexible.

- Have Evaluate methods take as argument(s) and return value
  instances of HConstant (instead of built-in 32- or 64-bit
  integer values), to let the evaluated instruction choose
  the type of the statically evaluated node; for instance,
  art::HEqual::Evaluate shall return a HIntConstant
  node (as implementation of a Boolean constant) whatever
  the type of its inputs (a pair of HIntConstant or a pair
  of HLongConstant).
- Split the evaluation job from the operation logic: the
  former is addressed by Evaluate methods, while the latter
  is done by a generic Compute method.
- Adress valid BinOp(int, long) and BinOp(long, int) cases.
- Add a constructor to art::HIntConstant to build an integer
  constant from a `bool` value.

Change-Id: If84b6fe8406bb94ddb1aa8b02e36628dff526db3
diff --git a/test/442-checker-constant-folding/src/Main.java b/test/442-checker-constant-folding/src/Main.java
index 4805d77..59e7282 100644
--- a/test/442-checker-constant-folding/src/Main.java
+++ b/test/442-checker-constant-folding/src/Main.java
@@ -363,6 +363,273 @@
 
 
   /**
+   * Exercise constant folding on left shift.
+   */
+
+  /// CHECK-START: int Main.ShlIntLong() constant_folding (before)
+  /// CHECK-DAG:     <<Const1:i\d+>>   IntConstant 1
+  /// CHECK-DAG:     <<Const2L:j\d+>>  LongConstant 2
+  /// CHECK-DAG:     <<TypeConv:i\d+>> TypeConversion [<<Const2L>>]
+  /// CHECK-DAG:     <<Shl:i\d+>>      Shl [<<Const1>>,<<TypeConv>>]
+  /// CHECK-DAG:                       Return [<<Shl>>]
+
+  /// CHECK-START: int Main.ShlIntLong() constant_folding (after)
+  /// CHECK-DAG:     <<Const4:i\d+>>   IntConstant 4
+  /// CHECK-DAG:                       Return [<<Const4>>]
+
+  /// CHECK-START: int Main.ShlIntLong() constant_folding (after)
+  /// CHECK-NOT:                       Shl
+
+  public static int ShlIntLong() {
+    int lhs = 1;
+    long rhs = 2;
+    return lhs << rhs;
+  }
+
+  /// CHECK-START: long Main.ShlLongInt() constant_folding (before)
+  /// CHECK-DAG:     <<Const3L:j\d+>>  LongConstant 3
+  /// CHECK-DAG:     <<Const2:i\d+>>   IntConstant 2
+  /// CHECK-DAG:     <<Shl:j\d+>>      Shl [<<Const3L>>,<<Const2>>]
+  /// CHECK-DAG:                       Return [<<Shl>>]
+
+  /// CHECK-START: long Main.ShlLongInt() constant_folding (after)
+  /// CHECK-DAG:     <<Const12L:j\d+>> LongConstant 12
+  /// CHECK-DAG:                       Return [<<Const12L>>]
+
+  /// CHECK-START: long Main.ShlLongInt() constant_folding (after)
+  /// CHECK-NOT:                       Shl
+
+  public static long ShlLongInt() {
+    long lhs = 3;
+    int rhs = 2;
+    return lhs << rhs;
+  }
+
+
+  /**
+   * Exercise constant folding on right shift.
+   */
+
+  /// CHECK-START: int Main.ShrIntLong() constant_folding (before)
+  /// CHECK-DAG:     <<Const7:i\d+>>   IntConstant 7
+  /// CHECK-DAG:     <<Const2L:j\d+>>  LongConstant 2
+  /// CHECK-DAG:     <<TypeConv:i\d+>> TypeConversion [<<Const2L>>]
+  /// CHECK-DAG:     <<Shr:i\d+>>      Shr [<<Const7>>,<<TypeConv>>]
+  /// CHECK-DAG:                       Return [<<Shr>>]
+
+  /// CHECK-START: int Main.ShrIntLong() constant_folding (after)
+  /// CHECK-DAG:     <<Const1:i\d+>>   IntConstant 1
+  /// CHECK-DAG:                       Return [<<Const1>>]
+
+  /// CHECK-START: int Main.ShrIntLong() constant_folding (after)
+  /// CHECK-NOT:                       Shr
+
+  public static int ShrIntLong() {
+    int lhs = 7;
+    long rhs = 2;
+    return lhs >> rhs;
+  }
+
+  /// CHECK-START: long Main.ShrLongInt() constant_folding (before)
+  /// CHECK-DAG:     <<Const9L:j\d+>>  LongConstant 9
+  /// CHECK-DAG:     <<Const2:i\d+>>   IntConstant 2
+  /// CHECK-DAG:     <<Shr:j\d+>>      Shr [<<Const9L>>,<<Const2>>]
+  /// CHECK-DAG:                       Return [<<Shr>>]
+
+  /// CHECK-START: long Main.ShrLongInt() constant_folding (after)
+  /// CHECK-DAG:     <<Const2L:j\d+>>  LongConstant 2
+  /// CHECK-DAG:                       Return [<<Const2L>>]
+
+  /// CHECK-START: long Main.ShrLongInt() constant_folding (after)
+  /// CHECK-NOT:                       Shr
+
+  public static long ShrLongInt() {
+    long lhs = 9;
+    int rhs = 2;
+    return lhs >> rhs;
+  }
+
+
+  /**
+   * Exercise constant folding on unsigned right shift.
+   */
+
+  /// CHECK-START: int Main.UShrIntLong() constant_folding (before)
+  /// CHECK-DAG:     <<ConstM7:i\d+>>  IntConstant -7
+  /// CHECK-DAG:     <<Const2L:j\d+>>  LongConstant 2
+  /// CHECK-DAG:     <<TypeConv:i\d+>> TypeConversion [<<Const2L>>]
+  /// CHECK-DAG:     <<UShr:i\d+>>     UShr [<<ConstM7>>,<<TypeConv>>]
+  /// CHECK-DAG:                       Return [<<UShr>>]
+
+  /// CHECK-START: int Main.UShrIntLong() constant_folding (after)
+  /// CHECK-DAG:     <<ConstRes:i\d+>> IntConstant 1073741822
+  /// CHECK-DAG:                       Return [<<ConstRes>>]
+
+  /// CHECK-START: int Main.UShrIntLong() constant_folding (after)
+  /// CHECK-NOT:                       UShr
+
+  public static int UShrIntLong() {
+    int lhs = -7;
+    long rhs = 2;
+    return lhs >>> rhs;
+  }
+
+  /// CHECK-START: long Main.UShrLongInt() constant_folding (before)
+  /// CHECK-DAG:     <<ConstM9L:j\d+>> LongConstant -9
+  /// CHECK-DAG:     <<Const2:i\d+>>   IntConstant 2
+  /// CHECK-DAG:     <<UShr:j\d+>>     UShr [<<ConstM9L>>,<<Const2>>]
+  /// CHECK-DAG:                       Return [<<UShr>>]
+
+  /// CHECK-START: long Main.UShrLongInt() constant_folding (after)
+  /// CHECK-DAG:     <<ConstRes:j\d+>> LongConstant 4611686018427387901
+  /// CHECK-DAG:                       Return [<<ConstRes>>]
+
+  /// CHECK-START: long Main.UShrLongInt() constant_folding (after)
+  /// CHECK-NOT:                       UShr
+
+  public static long UShrLongInt() {
+    long lhs = -9;
+    int rhs = 2;
+    return lhs >>> rhs;
+  }
+
+
+  /**
+   * Exercise constant folding on logical and.
+   */
+
+  /// CHECK-START: long Main.AndIntLong() constant_folding (before)
+  /// CHECK-DAG:     <<Const10:i\d+>>  IntConstant 10
+  /// CHECK-DAG:     <<Const3L:j\d+>>  LongConstant 3
+  /// CHECK-DAG:     <<TypeConv:j\d+>> TypeConversion [<<Const10>>]
+  /// CHECK-DAG:     <<And:j\d+>>      And [<<TypeConv>>,<<Const3L>>]
+  /// CHECK-DAG:                       Return [<<And>>]
+
+  /// CHECK-START: long Main.AndIntLong() constant_folding (after)
+  /// CHECK-DAG:     <<Const2:j\d+>>   LongConstant 2
+  /// CHECK-DAG:                       Return [<<Const2>>]
+
+  /// CHECK-START: long Main.AndIntLong() constant_folding (after)
+  /// CHECK-NOT:                       And
+
+  public static long AndIntLong() {
+    int lhs = 10;
+    long rhs = 3;
+    return lhs & rhs;
+  }
+
+  /// CHECK-START: long Main.AndLongInt() constant_folding (before)
+  /// CHECK-DAG:     <<Const10L:j\d+>> LongConstant 10
+  /// CHECK-DAG:     <<Const3:i\d+>>   IntConstant 3
+  /// CHECK-DAG:     <<TypeConv:j\d+>> TypeConversion [<<Const3>>]
+  /// CHECK-DAG:     <<And:j\d+>>      And [<<Const10L>>,<<TypeConv>>]
+  /// CHECK-DAG:                       Return [<<And>>]
+
+  /// CHECK-START: long Main.AndLongInt() constant_folding (after)
+  /// CHECK-DAG:     <<Const2:j\d+>>   LongConstant 2
+  /// CHECK-DAG:                       Return [<<Const2>>]
+
+  /// CHECK-START: long Main.AndLongInt() constant_folding (after)
+  /// CHECK-NOT:                       And
+
+  public static long AndLongInt() {
+    long lhs = 10;
+    int rhs = 3;
+    return lhs & rhs;
+  }
+
+
+  /**
+   * Exercise constant folding on logical or.
+   */
+
+  /// CHECK-START: long Main.OrIntLong() constant_folding (before)
+  /// CHECK-DAG:     <<Const10:i\d+>>  IntConstant 10
+  /// CHECK-DAG:     <<Const3L:j\d+>>  LongConstant 3
+  /// CHECK-DAG:     <<TypeConv:j\d+>> TypeConversion [<<Const10>>]
+  /// CHECK-DAG:     <<Or:j\d+>>       Or [<<TypeConv>>,<<Const3L>>]
+  /// CHECK-DAG:                       Return [<<Or>>]
+
+  /// CHECK-START: long Main.OrIntLong() constant_folding (after)
+  /// CHECK-DAG:     <<Const11:j\d+>>  LongConstant 11
+  /// CHECK-DAG:                       Return [<<Const11>>]
+
+  /// CHECK-START: long Main.OrIntLong() constant_folding (after)
+  /// CHECK-NOT:                       Or
+
+  public static long OrIntLong() {
+    int lhs = 10;
+    long rhs = 3;
+    return lhs | rhs;
+  }
+
+  /// CHECK-START: long Main.OrLongInt() constant_folding (before)
+  /// CHECK-DAG:     <<Const10L:j\d+>> LongConstant 10
+  /// CHECK-DAG:     <<Const3:i\d+>>   IntConstant 3
+  /// CHECK-DAG:     <<TypeConv:j\d+>> TypeConversion [<<Const3>>]
+  /// CHECK-DAG:     <<Or:j\d+>>       Or [<<Const10L>>,<<TypeConv>>]
+  /// CHECK-DAG:                       Return [<<Or>>]
+
+  /// CHECK-START: long Main.OrLongInt() constant_folding (after)
+  /// CHECK-DAG:     <<Const11:j\d+>>  LongConstant 11
+  /// CHECK-DAG:                       Return [<<Const11>>]
+
+  /// CHECK-START: long Main.OrLongInt() constant_folding (after)
+  /// CHECK-NOT:                       Or
+
+  public static long OrLongInt() {
+    long lhs = 10;
+    int rhs = 3;
+    return lhs | rhs;
+  }
+
+
+  /**
+   * Exercise constant folding on logical exclusive or.
+   */
+
+  /// CHECK-START: long Main.XorIntLong() constant_folding (before)
+  /// CHECK-DAG:     <<Const10:i\d+>>  IntConstant 10
+  /// CHECK-DAG:     <<Const3L:j\d+>>  LongConstant 3
+  /// CHECK-DAG:     <<TypeConv:j\d+>> TypeConversion [<<Const10>>]
+  /// CHECK-DAG:     <<Xor:j\d+>>      Xor [<<TypeConv>>,<<Const3L>>]
+  /// CHECK-DAG:                       Return [<<Xor>>]
+
+  /// CHECK-START: long Main.XorIntLong() constant_folding (after)
+  /// CHECK-DAG:     <<Const9:j\d+>>   LongConstant 9
+  /// CHECK-DAG:                       Return [<<Const9>>]
+
+  /// CHECK-START: long Main.XorIntLong() constant_folding (after)
+  /// CHECK-NOT:                       Xor
+
+  public static long XorIntLong() {
+    int lhs = 10;
+    long rhs = 3;
+    return lhs ^ rhs;
+  }
+
+  /// CHECK-START: long Main.XorLongInt() constant_folding (before)
+  /// CHECK-DAG:     <<Const10L:j\d+>> LongConstant 10
+  /// CHECK-DAG:     <<Const3:i\d+>>   IntConstant 3
+  /// CHECK-DAG:     <<TypeConv:j\d+>> TypeConversion [<<Const3>>]
+  /// CHECK-DAG:     <<Xor:j\d+>>      Xor [<<Const10L>>,<<TypeConv>>]
+  /// CHECK-DAG:                       Return [<<Xor>>]
+
+  /// CHECK-START: long Main.XorLongInt() constant_folding (after)
+  /// CHECK-DAG:     <<Const9:j\d+>>   LongConstant 9
+  /// CHECK-DAG:                       Return [<<Const9>>]
+
+  /// CHECK-START: long Main.XorLongInt() constant_folding (after)
+  /// CHECK-NOT:                       Xor
+
+  public static long XorLongInt() {
+    long lhs = 10;
+    int rhs = 3;
+    return lhs ^ rhs;
+  }
+
+
+  /**
    * Exercise constant folding on constant (static) condition.
    */
 
@@ -558,6 +825,25 @@
     return 0 << arg;
   }
 
+  /// CHECK-START: long Main.ShlLong0WithInt(int) constant_folding (before)
+  /// CHECK-DAG:     <<Arg:i\d+>>      ParameterValue
+  /// CHECK-DAG:     <<Const0L:j\d+>>  LongConstant 0
+  /// CHECK-DAG:     <<Shl:j\d+>>      Shl [<<Const0L>>,<<Arg>>]
+  /// CHECK-DAG:                       Return [<<Shl>>]
+
+  /// CHECK-START: long Main.ShlLong0WithInt(int) constant_folding (after)
+  /// CHECK-DAG:     <<Arg:i\d+>>      ParameterValue
+  /// CHECK-DAG:     <<Const0L:j\d+>>  LongConstant 0
+  /// CHECK-DAG:                       Return [<<Const0L>>]
+
+  /// CHECK-START: long Main.ShlLong0WithInt(int) constant_folding (after)
+  /// CHECK-NOT:                       Shl
+
+  public static long ShlLong0WithInt(int arg) {
+    long long_zero = 0;
+    return long_zero << arg;
+  }
+
   /// CHECK-START: long Main.Shr0(int) constant_folding (before)
   /// CHECK-DAG:     <<Arg:i\d+>>      ParameterValue
   /// CHECK-DAG:     <<Const0:j\d+>>   LongConstant 0
@@ -903,6 +1189,24 @@
     assertIntEquals(2, IntRemainder());
     assertLongEquals(2L, LongRemainder());
 
+    assertIntEquals(4, ShlIntLong());
+    assertLongEquals(12L, ShlLongInt());
+
+    assertIntEquals(1, ShrIntLong());
+    assertLongEquals(2L, ShrLongInt());
+
+    assertIntEquals(1073741822, UShrIntLong());
+    assertLongEquals(4611686018427387901L, UShrLongInt());
+
+    assertLongEquals(2, AndIntLong());
+    assertLongEquals(2, AndLongInt());
+
+    assertLongEquals(11, OrIntLong());
+    assertLongEquals(11, OrLongInt());
+
+    assertLongEquals(9, XorIntLong());
+    assertLongEquals(9, XorLongInt());
+
     assertIntEquals(5, StaticCondition());
 
     assertIntEquals(7, JumpsAndConditionals(true));
@@ -917,6 +1221,7 @@
     assertIntEquals(0, Rem1(arbitrary));
     assertLongEquals(0, RemN1(arbitrary));
     assertIntEquals(0, Shl0(arbitrary));
+    assertLongEquals(0, ShlLong0WithInt(arbitrary));
     assertLongEquals(0, Shr0(arbitrary));
     assertLongEquals(0, SubSameLong(arbitrary));
     assertIntEquals(0, UShr0(arbitrary));