Support hard float on arm in optimizing compiler.

Also bump oat version, needed after latest hard float switch.

Change-Id: Idf5acfb36c07e74acff00edab998419a3c6b2965
diff --git a/compiler/optimizing/locations.h b/compiler/optimizing/locations.h
index 11bcd78..de8c78d 100644
--- a/compiler/optimizing/locations.h
+++ b/compiler/optimizing/locations.h
@@ -47,24 +47,26 @@
     // We do not use the value 5 because it conflicts with kLocationConstantMask.
     kDoNotUse5 = 5,
 
-    kFpuRegister = 6,  // Floating point processor.
+    kFpuRegister = 6,  // Float register.
 
-    kRegisterPair = 7,
+    kRegisterPair = 7,  // Long register.
+
+    kFpuRegisterPair = 8,  // Double register.
+
+    // We do not use the value 9 because it conflicts with kLocationConstantMask.
+    kDoNotUse9 = 9,
 
     // On 32bits architectures, quick can pass a long where the
     // low bits are in the last parameter register, and the high
     // bits are in a stack slot. The kQuickParameter kind is for
     // handling this special case.
-    kQuickParameter = 8,
-
-    // We do not use the value 9 because it conflicts with kLocationConstantMask.
-    kDoNotUse9 = 9,
+    kQuickParameter = 10,
 
     // Unallocated location represents a location that is not fixed and can be
     // allocated by a register allocator.  Each unallocated location has
     // a policy that specifies what kind of location is suitable. Payload
     // contains register allocation policy.
-    kUnallocated = 10,
+    kUnallocated = 11,
   };
 
   Location() : value_(kInvalid) {
@@ -77,6 +79,7 @@
     COMPILE_ASSERT((kQuickParameter & kLocationConstantMask) != kConstant, TagError);
     COMPILE_ASSERT((kFpuRegister & kLocationConstantMask) != kConstant, TagError);
     COMPILE_ASSERT((kRegisterPair & kLocationConstantMask) != kConstant, TagError);
+    COMPILE_ASSERT((kFpuRegisterPair & kLocationConstantMask) != kConstant, TagError);
     COMPILE_ASSERT((kConstant & kLocationConstantMask) == kConstant, TagError);
 
     DCHECK(!IsValid());
@@ -129,6 +132,10 @@
     return Location(kRegisterPair, low << 16 | high);
   }
 
+  static Location FpuRegisterPairLocation(int low, int high) {
+    return Location(kFpuRegisterPair, low << 16 | high);
+  }
+
   bool IsRegister() const {
     return GetKind() == kRegister;
   }
@@ -141,6 +148,10 @@
     return GetKind() == kRegisterPair;
   }
 
+  bool IsFpuRegisterPair() const {
+    return GetKind() == kFpuRegisterPair;
+  }
+
   int reg() const {
     DCHECK(IsRegister() || IsFpuRegister());
     return GetPayload();
@@ -163,6 +174,18 @@
     return static_cast<T>(GetPayload() & 0xFFFF);
   }
 
+  template <typename T>
+  T AsFpuRegisterPairLow() const {
+    DCHECK(IsFpuRegisterPair());
+    return static_cast<T>(GetPayload() >> 16);
+  }
+
+  template <typename T>
+  T AsFpuRegisterPairHigh() const {
+    DCHECK(IsFpuRegisterPair());
+    return static_cast<T>(GetPayload() & 0xFFFF);
+  }
+
   static uintptr_t EncodeStackIndex(intptr_t stack_index) {
     DCHECK(-kStackIndexBias <= stack_index);
     DCHECK(stack_index < kStackIndexBias);
@@ -237,6 +260,7 @@
       case kConstant: return "C";
       case kFpuRegister: return "F";
       case kRegisterPair: return "RP";
+      case kFpuRegisterPair: return "FP";
       case kDoNotUse5:  // fall-through
       case kDoNotUse9:
         LOG(FATAL) << "Should not use this location kind";