ART: Implement X86 hard float (Quick/JNI/Baseline)

Use XMM0-XMM3 as parameter registers for float/double on X86.  X86_64
already uses XMM0-XMM7 for parameters.

Change the 'hidden' argument register from XMM0 to XMM7 to avoid a
conflict.

Add support for FPR save/restore in runtime/arch/x86.

Minimal support for Optimizing baseline compiler.

Bump the version in runtime/oat.h because this is an ABI change.

Change-Id: Ia6fe150e8488b9e582b0178c0dda65fc81d5a8ba
Signed-off-by: Mark Mendell <mark.p.mendell@intel.com>
diff --git a/runtime/arch/x86/context_x86.h b/runtime/arch/x86/context_x86.h
index 01c8b82..d18be54 100644
--- a/runtime/arch/x86/context_x86.h
+++ b/runtime/arch/x86/context_x86.h
@@ -62,7 +62,16 @@
 
   bool SetGPR(uint32_t reg, uintptr_t value) OVERRIDE;
 
-  bool GetFPR(uint32_t reg, uintptr_t* val) OVERRIDE;
+  bool GetFPR(uint32_t reg, uintptr_t* val) OVERRIDE {
+    DCHECK_LT(reg, static_cast<uint32_t>(kNumberOfFloatRegisters));
+    if (fprs_[reg] == nullptr) {
+      return false;
+    } else {
+      DCHECK(val != nullptr);
+      *val = *fprs_[reg];
+      return true;
+    }
+  }
 
   bool SetFPR(uint32_t reg, uintptr_t value) OVERRIDE;
 
@@ -70,9 +79,22 @@
   void DoLongJump() OVERRIDE;
 
  private:
-  // Pointers to register locations, floating point registers are all caller save. Values are
-  // initialized to NULL or the special registers below.
+  // Pretend XMM registers are made of uin32_t pieces, because they are manipulated
+  // in uint32_t chunks.
+  enum {
+    XMM0_0 = 0, XMM0_1,
+    XMM1_0, XMM1_1,
+    XMM2_0, XMM2_1,
+    XMM3_0, XMM3_1,
+    XMM4_0, XMM4_1,
+    XMM5_0, XMM5_1,
+    XMM6_0, XMM6_1,
+    XMM7_0, XMM7_1,
+    kNumberOfFloatRegisters};
+
+  // Pointers to register locations. Values are initialized to NULL or the special registers below.
   uintptr_t* gprs_[kNumberOfCpuRegisters];
+  uintptr_t* fprs_[kNumberOfFloatRegisters];
   // Hold values for esp and eip if they are not located within a stack frame. EIP is somewhat
   // special in that it cannot be encoded normally as a register operand to an instruction (except
   // in 64bit addressing modes).