Fix a MOV instruction in Optimizing's x86-64 code generator.

Use `movl' instead of `movw' to store a 32-bit immediate
(integer or reference) into a field.

Also fix art::Location::RegisterOrInt32LongConstant to
properly handle non-long constants.

Change-Id: I34c6ec8eaa1632822a31969f87c9c2d6c5b96326
diff --git a/compiler/optimizing/code_generator_x86_64.cc b/compiler/optimizing/code_generator_x86_64.cc
index 22f5d96..afffbe2 100644
--- a/compiler/optimizing/code_generator_x86_64.cc
+++ b/compiler/optimizing/code_generator_x86_64.cc
@@ -3337,7 +3337,7 @@
     case Primitive::kPrimNot: {
       if (value.IsConstant()) {
         int32_t v = CodeGenerator::GetInt32ValueOf(value.GetConstant());
-        __ movw(Address(base, offset), Immediate(v));
+        __ movl(Address(base, offset), Immediate(v));
       } else {
         __ movl(Address(base, offset), value.AsRegister<CpuRegister>());
       }
diff --git a/compiler/optimizing/locations.cc b/compiler/optimizing/locations.cc
index 42aba04..d14dfc1 100644
--- a/compiler/optimizing/locations.cc
+++ b/compiler/optimizing/locations.cc
@@ -51,16 +51,17 @@
 }
 
 Location Location::RegisterOrInt32LongConstant(HInstruction* instruction) {
-  if (!instruction->IsConstant() || !instruction->AsConstant()->IsLongConstant()) {
+  if (instruction->IsIntConstant() || instruction->IsNullConstant()) {
+    return Location::ConstantLocation(instruction->AsConstant());
+  } else if (instruction->IsLongConstant()) {
+    // Does the long constant fit in a 32 bit int?
+    int64_t value = instruction->AsLongConstant()->GetValue();
+    return IsInt<32>(value)
+        ? Location::ConstantLocation(instruction->AsConstant())
+        : Location::RequiresRegister();
+  } else {
     return Location::RequiresRegister();
   }
-
-  // Does the long constant fit in a 32 bit int?
-  int64_t value = instruction->AsConstant()->AsLongConstant()->GetValue();
-
-  return IsInt<32>(value)
-      ? Location::ConstantLocation(instruction->AsConstant())
-      : Location::RequiresRegister();
 }
 
 Location Location::ByteRegisterOrConstant(int reg, HInstruction* instruction) {
diff --git a/test/521-regression-integer-field-set/expected.txt b/test/521-regression-integer-field-set/expected.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/521-regression-integer-field-set/expected.txt
diff --git a/test/521-regression-integer-field-set/info.txt b/test/521-regression-integer-field-set/info.txt
new file mode 100644
index 0000000..62f7e3d
--- /dev/null
+++ b/test/521-regression-integer-field-set/info.txt
@@ -0,0 +1,3 @@
+Regression test for Optimizing's x86-64 code generator, where moving a
+32-bit immediate (integer or reference) into a field used to generate
+a `movw` instruction instead of a `movl` instruction.
diff --git a/test/521-regression-integer-field-set/src/Main.java b/test/521-regression-integer-field-set/src/Main.java
new file mode 100644
index 0000000..9924e09
--- /dev/null
+++ b/test/521-regression-integer-field-set/src/Main.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+class Main {
+  public static void assertIntEquals(int expected, int result) {
+    if (expected != result) {
+      throw new Error("Expected: " + expected + ", found: " + result);
+    }
+  }
+
+  public static void main(String[] args) {
+    Main m = new Main();
+
+    m.$noinline$SetInstanceField();
+    assertIntEquals(123456, m.i);
+
+    $noinline$SetStaticField();
+    assertIntEquals(456789, s);
+  }
+
+  private static boolean doThrow = false;
+
+  private void $noinline$SetInstanceField() {
+    if (doThrow) {
+      // Try defeating inlining.
+      throw new Error();
+    }
+
+    // Set a value than does not fit in a 16-bit (signed) integer.
+    i = 123456;
+  }
+
+  private static void $noinline$SetStaticField() {
+    if (doThrow) {
+      // Try defeating inlining.
+      throw new Error();
+    }
+
+    // Set a value than does not fit in a 16-bit (signed) integer.
+    s = 456789;
+  }
+
+  private int i = 0;
+  private static int s = 0;
+}