Support Java conversions from char to long in opt. compiler.

These char to long conversions generate int-to-long Dex
instructions.

Change-Id: I6a8e71b57870cf5e8d5bc638fabce0fc7593f0b2
diff --git a/compiler/optimizing/code_generator_arm.cc b/compiler/optimizing/code_generator_arm.cc
index 6218fc9..467c2a6 100644
--- a/compiler/optimizing/code_generator_arm.cc
+++ b/compiler/optimizing/code_generator_arm.cc
@@ -1338,6 +1338,7 @@
         case Primitive::kPrimByte:
         case Primitive::kPrimShort:
         case Primitive::kPrimInt:
+        case Primitive::kPrimChar:
           // int-to-long conversion.
           locations->SetInAt(0, Location::RequiresRegister());
           locations->SetOut(Location::RequiresRegister(), Location::kNoOutputOverlap);
@@ -1380,6 +1381,7 @@
         case Primitive::kPrimByte:
         case Primitive::kPrimShort:
         case Primitive::kPrimInt:
+        case Primitive::kPrimChar:
           // int-to-long conversion.
           DCHECK(out.IsRegisterPair());
           DCHECK(in.IsRegister());
diff --git a/compiler/optimizing/code_generator_x86.cc b/compiler/optimizing/code_generator_x86.cc
index 82591b0..d66180b 100644
--- a/compiler/optimizing/code_generator_x86.cc
+++ b/compiler/optimizing/code_generator_x86.cc
@@ -1266,6 +1266,7 @@
         case Primitive::kPrimByte:
         case Primitive::kPrimShort:
         case Primitive::kPrimInt:
+        case Primitive::kPrimChar:
           // int-to-long conversion.
           locations->SetInAt(0, Location::RegisterLocation(EAX));
           locations->SetOut(Location::RegisterPairLocation(EAX, EDX));
@@ -1308,6 +1309,7 @@
         case Primitive::kPrimByte:
         case Primitive::kPrimShort:
         case Primitive::kPrimInt:
+        case Primitive::kPrimChar:
           // int-to-long conversion.
           DCHECK_EQ(out.AsRegisterPairLow<Register>(), EAX);
           DCHECK_EQ(out.AsRegisterPairHigh<Register>(), EDX);
diff --git a/compiler/optimizing/code_generator_x86_64.cc b/compiler/optimizing/code_generator_x86_64.cc
index d2730a5..e09b6ca 100644
--- a/compiler/optimizing/code_generator_x86_64.cc
+++ b/compiler/optimizing/code_generator_x86_64.cc
@@ -1264,6 +1264,7 @@
         case Primitive::kPrimByte:
         case Primitive::kPrimShort:
         case Primitive::kPrimInt:
+        case Primitive::kPrimChar:
           // int-to-long conversion.
           // TODO: We would benefit from a (to-be-implemented)
           // Location::RegisterOrStackSlot requirement for this input.
@@ -1309,6 +1310,7 @@
         case Primitive::kPrimByte:
         case Primitive::kPrimShort:
         case Primitive::kPrimInt:
+        case Primitive::kPrimChar:
           // int-to-long conversion.
           DCHECK(in.IsRegister());
           __ movsxd(out.As<CpuRegister>(), in.As<CpuRegister>());
diff --git a/test/422-type-conversion/src/Main.java b/test/422-type-conversion/src/Main.java
index d2ffc5b..d61f255 100644
--- a/test/422-type-conversion/src/Main.java
+++ b/test/422-type-conversion/src/Main.java
@@ -26,6 +26,7 @@
 
   public static void main(String[] args) {
     byteToLong();
+    charToLong();
     shortToLong();
     intToLong();
   }
@@ -63,18 +64,25 @@
     assertEquals(-2147483648L, $opt$IntToLong(-2147483648));  // -(2^31)
   }
 
-  static long $opt$ByteToLong(byte a) {
-    // Translates to an int-to-long Dex instruction.
-    return a;
+  private static void charToLong() {
+    assertEquals(1L, $opt$CharToLong((char)1));
+    assertEquals(0L, $opt$CharToLong((char)0));
+    assertEquals(51L, $opt$CharToLong((char)51));
+    assertEquals(32767L, $opt$CharToLong((char)32767));  // (2^15) - 1
+    assertEquals(65535L, $opt$CharToLong((char)65535));  // (2^16) - 1
+
+    assertEquals(0L, $opt$CharToLong('\u0000'));
+    assertEquals(65535L, $opt$CharToLong('\uFFFF'));  // (2^16) - 1
+
+    assertEquals(65535L, $opt$CharToLong((char)-1));
+    assertEquals(65485L, $opt$CharToLong((char)-51));
+    assertEquals(32769L, $opt$CharToLong((char)-32767));  // -(2^15) - 1
+    assertEquals(32768L, $opt$CharToLong((char)-32768));  // -(2^15)
   }
 
-  static long $opt$ShortToLong(short a) {
-    // Translates to an int-to-long Dex instruction.
-    return a;
-  }
-
-  static long $opt$IntToLong(int a) {
-    // Translates to an int-to-long Dex instruction.
-    return a;
-  }
+  // All these methods produce an int-to-long Dex instruction.
+  static long $opt$ByteToLong(byte a) { return a; }
+  static long $opt$ShortToLong(short a) { return a; }
+  static long $opt$IntToLong(int a) { return a; }
+  static long $opt$CharToLong(int a) { return a; }
 }