Opt compiler: ARM64: Use ldp/stp on arm64 for slow paths.

It should be a bit faster than load/store single registers and reduce
the code size.

Change-Id: I67b8302adf6174b7bb728f7c2afd2c237e34ffde
diff --git a/compiler/optimizing/common_arm64.h b/compiler/optimizing/common_arm64.h
index 53f1f3c..246fff9 100644
--- a/compiler/optimizing/common_arm64.h
+++ b/compiler/optimizing/common_arm64.h
@@ -218,6 +218,28 @@
   return Location::RequiresRegister();
 }
 
+// Check if registers in art register set have the same register code in vixl. If the register
+// codes are same, we can initialize vixl register list simply by the register masks. Currently,
+// only SP/WSP and ZXR/WZR codes are different between art and vixl.
+// Note: This function is only used for debug checks.
+static inline bool ArtVixlRegCodeCoherentForRegSet(uint32_t art_core_registers,
+                                                   size_t num_core,
+                                                   uint32_t art_fpu_registers,
+                                                   size_t num_fpu) {
+  // The register masks won't work if the number of register is larger than 32.
+  DCHECK_GE(sizeof(art_core_registers) * 8, num_core);
+  DCHECK_GE(sizeof(art_fpu_registers) * 8, num_fpu);
+  for (size_t art_reg_code = 0;  art_reg_code < num_core; ++art_reg_code) {
+    if (RegisterSet::Contains(art_core_registers, art_reg_code)) {
+      if (art_reg_code != static_cast<size_t>(VIXLRegCodeFromART(art_reg_code))) {
+        return false;
+      }
+    }
+  }
+  // There is no register code translation for float registers.
+  return true;
+}
+
 }  // namespace helpers
 }  // namespace arm64
 }  // namespace art