Jni compiler should zero extend boolean and char return values.

This mostly fixes the emulator. It seems like there's some final issues
in browser.

Change-Id: I9a82db3c243a0994465106bf21ac6596af5bdf5a
diff --git a/src/oat/jni/jni_compiler.cc b/src/oat/jni/jni_compiler.cc
index 42d2166..625580c 100644
--- a/src/oat/jni/jni_compiler.cc
+++ b/src/oat/jni/jni_compiler.cc
@@ -543,9 +543,14 @@
 
     __ DecreaseFrameSize(out_arg_size);
     jni_conv->ResetIterator(FrameOffset(0));
-  } else if (instruction_set == kX86 && (jni_conv->GetReturnType() == Primitive::kPrimByte ||
-                                         jni_conv->GetReturnType() == Primitive::kPrimShort)) {
-    __ SignExtend(jni_conv->ReturnRegister(), Primitive::ComponentSize(jni_conv->GetReturnType()));
+  } else if (instruction_set == kX86) {
+    if (jni_conv->GetReturnType() == Primitive::kPrimByte ||
+        jni_conv->GetReturnType() == Primitive::kPrimShort) {
+      __ SignExtend(jni_conv->ReturnRegister(), Primitive::ComponentSize(jni_conv->GetReturnType()));
+    } else if (jni_conv->GetReturnType() == Primitive::kPrimBoolean ||
+               jni_conv->GetReturnType() == Primitive::kPrimChar) {
+      __ ZeroExtend(jni_conv->ReturnRegister(), Primitive::ComponentSize(jni_conv->GetReturnType()));
+    }
   }
   DCHECK_EQ(mr_conv->SizeOfReturnValue(), jni_conv->SizeOfReturnValue());
   __ Move(mr_conv->ReturnRegister(), jni_conv->ReturnRegister(), mr_conv->SizeOfReturnValue());
diff --git a/src/oat/utils/arm/assembler_arm.cc b/src/oat/utils/arm/assembler_arm.cc
index e248d5f..55b6187 100644
--- a/src/oat/utils/arm/assembler_arm.cc
+++ b/src/oat/utils/arm/assembler_arm.cc
@@ -1651,6 +1651,10 @@
   UNIMPLEMENTED(FATAL) << "no sign extension necessary for arm";
 }
 
+void ArmAssembler::ZeroExtend(ManagedRegister /*mreg*/, size_t /*size*/) {
+  UNIMPLEMENTED(FATAL) << "no zero extension necessary for arm";
+}
+
 void ArmAssembler::Move(ManagedRegister m_dst, ManagedRegister m_src, size_t /*size*/) {
   ArmManagedRegister dst = m_dst.AsArm();
   ArmManagedRegister src = m_src.AsArm();
diff --git a/src/oat/utils/arm/assembler_arm.h b/src/oat/utils/arm/assembler_arm.h
index ae7bfb4..31c3ab0 100644
--- a/src/oat/utils/arm/assembler_arm.h
+++ b/src/oat/utils/arm/assembler_arm.h
@@ -519,6 +519,9 @@
   // Sign extension
   virtual void SignExtend(ManagedRegister mreg, size_t size);
 
+  // Zero extension
+  virtual void ZeroExtend(ManagedRegister mreg, size_t size);
+
   // Exploit fast access in managed code to Thread::Current()
   virtual void GetCurrentThread(ManagedRegister tr);
   virtual void GetCurrentThread(FrameOffset dest_offset,
diff --git a/src/oat/utils/assembler.h b/src/oat/utils/assembler.h
index 71f32c0..dabd321 100644
--- a/src/oat/utils/assembler.h
+++ b/src/oat/utils/assembler.h
@@ -401,6 +401,9 @@
   // Sign extension
   virtual void SignExtend(ManagedRegister mreg, size_t size) = 0;
 
+  // Zero extension
+  virtual void ZeroExtend(ManagedRegister mreg, size_t size) = 0;
+
   // Exploit fast access in managed code to Thread::Current()
   virtual void GetCurrentThread(ManagedRegister tr) = 0;
   virtual void GetCurrentThread(FrameOffset dest_offset,
diff --git a/src/oat/utils/x86/assembler_x86.cc b/src/oat/utils/x86/assembler_x86.cc
index 52535fd..28b17f5 100644
--- a/src/oat/utils/x86/assembler_x86.cc
+++ b/src/oat/utils/x86/assembler_x86.cc
@@ -1608,6 +1608,17 @@
   }
 }
 
+void X86Assembler::ZeroExtend(ManagedRegister mreg, size_t size) {
+  X86ManagedRegister reg = mreg.AsX86();
+  CHECK(size == 1 || size == 2) << size;
+  CHECK(reg.IsCpuRegister()) << reg;
+  if (size == 1) {
+    movzxb(reg.AsCpuRegister(), reg.AsByteRegister());
+  } else {
+    movzxw(reg.AsCpuRegister(), reg.AsCpuRegister());
+  }
+}
+
 void X86Assembler::Move(ManagedRegister mdest, ManagedRegister msrc, size_t size) {
   X86ManagedRegister dest = mdest.AsX86();
   X86ManagedRegister src = msrc.AsX86();
diff --git a/src/oat/utils/x86/assembler_x86.h b/src/oat/utils/x86/assembler_x86.h
index d3600b0..d4356b6 100644
--- a/src/oat/utils/x86/assembler_x86.h
+++ b/src/oat/utils/x86/assembler_x86.h
@@ -553,6 +553,9 @@
   // Sign extension
   virtual void SignExtend(ManagedRegister mreg, size_t size);
 
+  // Zero extension
+  virtual void ZeroExtend(ManagedRegister mreg, size_t size);
+
   // Exploit fast access in managed code to Thread::Current()
   virtual void GetCurrentThread(ManagedRegister tr);
   virtual void GetCurrentThread(FrameOffset dest_offset,