[LIR] Add all constant number instructions.

Bug: b/225838009
Change-Id: Ia673b084b5c1d8bb1fc8b4c99677fc009dd41835
diff --git a/src/main/java/com/android/tools/r8/lightir/ByteUtils.java b/src/main/java/com/android/tools/r8/lightir/ByteUtils.java
index 5d34483..dc174ff 100644
--- a/src/main/java/com/android/tools/r8/lightir/ByteUtils.java
+++ b/src/main/java/com/android/tools/r8/lightir/ByteUtils.java
@@ -17,6 +17,10 @@
     return value & 0xFF;
   }
 
+  private static int truncateToU1(long value) {
+    return (int) value & 0xFF;
+  }
+
   public static int ensureU1(int value) {
     assert isU1(value);
     return truncateToU1(value);
@@ -47,6 +51,35 @@
     return value;
   }
 
+  public static int longEncodingSize(long value) {
+    return 8;
+  }
+
+  public static void writeEncodedLong(long value, ByteWriter writer) {
+    assert 8 == longEncodingSize(value);
+    writer.put(truncateToU1(value >> 56));
+    writer.put(truncateToU1(value >> 48));
+    writer.put(truncateToU1(value >> 40));
+    writer.put(truncateToU1(value >> 32));
+    writer.put(truncateToU1(value >> 24));
+    writer.put(truncateToU1(value >> 16));
+    writer.put(truncateToU1(value >> 8));
+    writer.put(truncateToU1(value));
+  }
+
+  public static long readEncodedLong(ByteIterator iterator) {
+    assert 8 == longEncodingSize(0);
+    long value = ((long) truncateToU1(iterator.nextByte())) << 56;
+    value |= ((long) truncateToU1(iterator.nextByte())) << 48;
+    value |= ((long) truncateToU1(iterator.nextByte())) << 40;
+    value |= ((long) truncateToU1(iterator.nextByte())) << 32;
+    value |= ((long) truncateToU1(iterator.nextByte())) << 24;
+    value |= ((long) truncateToU1(iterator.nextByte())) << 16;
+    value |= ((long) truncateToU1(iterator.nextByte())) << 8;
+    value |= truncateToU1(iterator.nextByte());
+    return value;
+  }
+
   public static boolean isU2(int value) {
     return (value >= 0) && (value <= 0xFFFF);
   }
diff --git a/src/main/java/com/android/tools/r8/lightir/LirBuilder.java b/src/main/java/com/android/tools/r8/lightir/LirBuilder.java
index 3edc3c2..024d6d7 100644
--- a/src/main/java/com/android/tools/r8/lightir/LirBuilder.java
+++ b/src/main/java/com/android/tools/r8/lightir/LirBuilder.java
@@ -44,6 +44,11 @@
 
 /** Builder for constructing LIR code from IR. */
 public class LirBuilder<V, EV> {
+  private static final int FLOAT_0 = Float.floatToRawIntBits(0);
+  private static final int FLOAT_1 = Float.floatToRawIntBits(1);
+  private static final int FLOAT_2 = Float.floatToRawIntBits(2);
+  private static final long DOUBLE_0 = Double.doubleToRawLongBits(0);
+  private static final long DOUBLE_1 = Double.doubleToRawLongBits(1);
 
   private final DexItemFactory factory;
   private final ByteArrayWriter byteWriter = new ByteArrayWriter();
@@ -256,6 +261,48 @@
     return this;
   }
 
+  public LirBuilder<V, EV> addConstFloat(int value) {
+    if (value == FLOAT_0) {
+      return addNoOperandInstruction(LirOpcodes.FCONST_0);
+    }
+    if (value == FLOAT_1) {
+      return addNoOperandInstruction(LirOpcodes.FCONST_1);
+    }
+    if (value == FLOAT_2) {
+      return addNoOperandInstruction(LirOpcodes.FCONST_2);
+    }
+    advanceInstructionState();
+    writer.writeInstruction(LirOpcodes.FCONST, ByteUtils.intEncodingSize(value));
+    ByteUtils.writeEncodedInt(value, writer::writeOperand);
+    return this;
+  }
+
+  public LirBuilder<V, EV> addConstLong(long value) {
+    if (value == 0) {
+      return addNoOperandInstruction(LirOpcodes.LCONST_0);
+    }
+    if (value == 1) {
+      return addNoOperandInstruction(LirOpcodes.LCONST_1);
+    }
+    advanceInstructionState();
+    writer.writeInstruction(LirOpcodes.LCONST, ByteUtils.longEncodingSize(value));
+    ByteUtils.writeEncodedLong(value, writer::writeOperand);
+    return this;
+  }
+
+  public LirBuilder<V, EV> addConstDouble(long value) {
+    if (value == DOUBLE_0) {
+      return addNoOperandInstruction(LirOpcodes.DCONST_0);
+    }
+    if (value == DOUBLE_1) {
+      return addNoOperandInstruction(LirOpcodes.DCONST_1);
+    }
+    advanceInstructionState();
+    writer.writeInstruction(LirOpcodes.DCONST, ByteUtils.longEncodingSize(value));
+    ByteUtils.writeEncodedLong(value, writer::writeOperand);
+    return this;
+  }
+
   public LirBuilder<V, EV> addConstNumber(ValueType type, long value) {
     switch (type) {
       case OBJECT:
@@ -263,8 +310,11 @@
       case INT:
         return addConstInt((int) value);
       case FLOAT:
+        return addConstFloat((int) value);
       case LONG:
+        return addConstLong(value);
       case DOUBLE:
+        return addConstDouble(value);
       default:
         throw new Unimplemented();
     }
diff --git a/src/main/java/com/android/tools/r8/lightir/LirInstructionView.java b/src/main/java/com/android/tools/r8/lightir/LirInstructionView.java
index 3eef40d..546da90 100644
--- a/src/main/java/com/android/tools/r8/lightir/LirInstructionView.java
+++ b/src/main/java/com/android/tools/r8/lightir/LirInstructionView.java
@@ -30,6 +30,9 @@
   /** Get the next operand as an encoded integer */
   int getNextIntegerOperand();
 
+  /** Get the next operand as an encoded long */
+  long getNextLongOperand();
+
   /** Get the next operand as a constant-pool index. */
   int getNextConstantOperand();
 
diff --git a/src/main/java/com/android/tools/r8/lightir/LirIterator.java b/src/main/java/com/android/tools/r8/lightir/LirIterator.java
index dd29c93..84eaee6 100644
--- a/src/main/java/com/android/tools/r8/lightir/LirIterator.java
+++ b/src/main/java/com/android/tools/r8/lightir/LirIterator.java
@@ -88,6 +88,12 @@
   }
 
   @Override
+  public long getNextLongOperand() {
+    assert hasMoreOperands();
+    return u8();
+  }
+
+  @Override
   public int getNextConstantOperand() {
     return getNextIntegerOperand();
   }
@@ -116,4 +122,9 @@
     currentByteIndex += 4;
     return ByteUtils.readEncodedInt(iterator);
   }
+
+  private long u8() {
+    currentByteIndex += 8;
+    return ByteUtils.readEncodedLong(iterator);
+  }
 }
diff --git a/src/main/java/com/android/tools/r8/lightir/LirParsedInstructionCallback.java b/src/main/java/com/android/tools/r8/lightir/LirParsedInstructionCallback.java
index 3342eed..fd7bf56 100644
--- a/src/main/java/com/android/tools/r8/lightir/LirParsedInstructionCallback.java
+++ b/src/main/java/com/android/tools/r8/lightir/LirParsedInstructionCallback.java
@@ -62,6 +62,18 @@
     onConstNumber(NumericType.INT, value);
   }
 
+  public void onConstFloat(int value) {
+    onConstNumber(NumericType.FLOAT, value);
+  }
+
+  public void onConstLong(long value) {
+    onConstNumber(NumericType.LONG, value);
+  }
+
+  public void onConstDouble(long value) {
+    onConstNumber(NumericType.DOUBLE, value);
+  }
+
   public void onConstString(DexString string) {
     onInstruction();
   }
@@ -289,6 +301,51 @@
           onConstInt(value);
           return;
         }
+      case LirOpcodes.FCONST_0:
+      case LirOpcodes.FCONST_1:
+      case LirOpcodes.FCONST_2:
+        {
+          float value = opcode - LirOpcodes.FCONST_0;
+          onConstFloat(Float.floatToRawIntBits(value));
+          return;
+        }
+      case LirOpcodes.FCONST:
+        {
+          int value = view.getNextIntegerOperand();
+          onConstFloat(value);
+          return;
+        }
+      case LirOpcodes.LCONST_0:
+        {
+          onConstLong(0);
+          return;
+        }
+      case LirOpcodes.LCONST_1:
+        {
+          onConstLong(1);
+          return;
+        }
+      case LirOpcodes.LCONST:
+        {
+          long value = view.getNextLongOperand();
+          onConstLong(value);
+          return;
+        }
+      case LirOpcodes.DCONST_0:
+        {
+          onConstDouble(Double.doubleToRawLongBits(0));
+          return;
+        }
+      case LirOpcodes.DCONST_1:
+        {
+          onConstDouble(Double.doubleToRawLongBits(1));
+        }
+      case LirOpcodes.DCONST:
+        {
+          long value = view.getNextLongOperand();
+          onConstDouble(value);
+          return;
+        }
       case LirOpcodes.IADD:
         {
           EV leftValueIndex = getNextValueOperand(view);