ARM64: Use the zero register for field and array set operations.

Test: Run ART test suite on host and Nexus 9.
Change-Id: I4e2a81570ecc57530249672df704eb0bb780acce
diff --git a/compiler/optimizing/common_arm64.h b/compiler/optimizing/common_arm64.h
index cc949c5..cea4a7e 100644
--- a/compiler/optimizing/common_arm64.h
+++ b/compiler/optimizing/common_arm64.h
@@ -124,6 +124,18 @@
       : static_cast<vixl::aarch64::CPURegister>(InputRegisterAt(instr, index));
 }
 
+static inline vixl::aarch64::CPURegister InputCPURegisterOrZeroRegAt(HInstruction* instr,
+                                                                     int index) {
+  HInstruction* input = instr->InputAt(index);
+  Primitive::Type input_type = input->GetType();
+  if (input->IsConstant() && input->AsConstant()->IsZeroBitPattern()) {
+    return (Primitive::ComponentSize(input_type) >= vixl::aarch64::kXRegSizeInBytes)
+        ?  vixl::aarch64::xzr
+        : vixl::aarch64::wzr;
+  }
+  return InputCPURegisterAt(instr, index);
+}
+
 static inline int64_t Int64ConstantFrom(Location location) {
   HConstant* instr = location.GetConstant();
   if (instr->IsIntConstant()) {
@@ -339,6 +351,10 @@
   return instruction->IsAdd() || instruction->IsSub();
 }
 
+static inline bool IsConstantZeroBitPattern(const HInstruction* instruction) {
+  return instruction->IsConstant() && instruction->AsConstant()->IsZeroBitPattern();
+}
+
 }  // namespace helpers
 }  // namespace arm64
 }  // namespace art