Move entry spills determination to JNI compiler.

The calling convention no longer describes entry spills as
spilling is the JNI compiler's responsibility. This allows
future improvements, such as spilling registers directly to
the HandleScope or outgoing stack args.

Remove the notion of interprocedural scratch register from
calling conventions and let assemblers deal with all scratch
register uses. The remaining JNI assembler APIs that take
scratch registers are currently unused and can be removed.

Also fix a bug in disassembly comparison for tests; the
contents of two files were considered identical if the
second one just contained additional data.

This change fully preserves the generated code and adds TODO
comments where doing so results in weird or suboptimal code.

Test: m test-art-host-gtest
Test: testrunner.py --host --optimizing
Test: Prebuilt boot image is unchanged.
Test: aosp_taimen-userdebug boots.
Bug: 12189621
Change-Id: Ic26a670276920313cd907a6eda8d982cf0abfd81
diff --git a/compiler/jni/quick/x86/calling_convention_x86.cc b/compiler/jni/quick/x86/calling_convention_x86.cc
index 4e643ba..6776f12 100644
--- a/compiler/jni/quick/x86/calling_convention_x86.cc
+++ b/compiler/jni/quick/x86/calling_convention_x86.cc
@@ -26,7 +26,12 @@
 namespace art {
 namespace x86 {
 
-static_assert(kX86PointerSize == PointerSize::k32, "Unexpected x86 pointer size");
+static constexpr Register kManagedCoreArgumentRegisters[] = {
+    EAX, ECX, EDX, EBX
+};
+static constexpr size_t kManagedCoreArgumentRegistersCount =
+    arraysize(kManagedCoreArgumentRegisters);
+static constexpr size_t kManagedFpArgumentRegistersCount = 4u;
 
 static constexpr ManagedRegister kCalleeSaveRegisters[] = {
     // Core registers.
@@ -67,14 +72,6 @@
 
 // Calling convention
 
-ManagedRegister X86ManagedRuntimeCallingConvention::InterproceduralScratchRegister() const {
-  return X86ManagedRegister::FromCpuRegister(ECX);
-}
-
-ManagedRegister X86JniCallingConvention::InterproceduralScratchRegister() const {
-  return X86ManagedRegister::FromCpuRegister(ECX);
-}
-
 ManagedRegister X86JniCallingConvention::ReturnScratchRegister() const {
   return ManagedRegister::NoRegister();  // No free regs, so assembler uses push/pop
 }
@@ -113,49 +110,58 @@
   return X86ManagedRegister::FromCpuRegister(EAX);
 }
 
+void X86ManagedRuntimeCallingConvention::ResetIterator(FrameOffset displacement) {
+  ManagedRuntimeCallingConvention::ResetIterator(displacement);
+  gpr_arg_count_ = 1u;  // Skip EAX for ArtMethod*
+}
+
+void X86ManagedRuntimeCallingConvention::Next() {
+  if (!IsCurrentParamAFloatOrDouble()) {
+    gpr_arg_count_ += IsCurrentParamALong() ? 2u : 1u;
+  }
+  ManagedRuntimeCallingConvention::Next();
+}
+
 bool X86ManagedRuntimeCallingConvention::IsCurrentParamInRegister() {
-  return false;  // Everything is passed by stack
+  if (IsCurrentParamAFloatOrDouble()) {
+    return itr_float_and_doubles_ < kManagedFpArgumentRegistersCount;
+  } else {
+    // Don't split a long between the last register and the stack.
+    size_t extra_regs = IsCurrentParamALong() ? 1u : 0u;
+    return gpr_arg_count_ + extra_regs < kManagedCoreArgumentRegistersCount;
+  }
 }
 
 bool X86ManagedRuntimeCallingConvention::IsCurrentParamOnStack() {
-  // We assume all parameters are on stack, args coming via registers are spilled as entry_spills.
-  return true;
+  return !IsCurrentParamInRegister();
 }
 
 ManagedRegister X86ManagedRuntimeCallingConvention::CurrentParamRegister() {
-  ManagedRegister res = ManagedRegister::NoRegister();
-  if (!IsCurrentParamAFloatOrDouble()) {
-    switch (gpr_arg_count_) {
-      case 0:
-        res = X86ManagedRegister::FromCpuRegister(ECX);
-        break;
-      case 1:
-        res = X86ManagedRegister::FromCpuRegister(EDX);
-        break;
-      case 2:
-        // Don't split a long between the last register and the stack.
-        if (IsCurrentParamALong()) {
-          return ManagedRegister::NoRegister();
-        }
-        res = X86ManagedRegister::FromCpuRegister(EBX);
-        break;
-    }
-  } else if (itr_float_and_doubles_ < 4) {
+  DCHECK(IsCurrentParamInRegister());
+  if (IsCurrentParamAFloatOrDouble()) {
     // First four float parameters are passed via XMM0..XMM3
-    res = X86ManagedRegister::FromXmmRegister(
-                                 static_cast<XmmRegister>(XMM0 + itr_float_and_doubles_));
+    XmmRegister reg = static_cast<XmmRegister>(XMM0 + itr_float_and_doubles_);
+    return X86ManagedRegister::FromXmmRegister(reg);
+  } else {
+    if (IsCurrentParamALong()) {
+      switch (gpr_arg_count_) {
+        case 1:
+          static_assert(kManagedCoreArgumentRegisters[1] == ECX);
+          static_assert(kManagedCoreArgumentRegisters[2] == EDX);
+          return X86ManagedRegister::FromRegisterPair(ECX_EDX);
+        case 2:
+          static_assert(kManagedCoreArgumentRegisters[2] == EDX);
+          static_assert(kManagedCoreArgumentRegisters[3] == EBX);
+          return X86ManagedRegister::FromRegisterPair(EDX_EBX);
+        default:
+          LOG(FATAL) << "UNREACHABLE";
+          UNREACHABLE();
+      }
+    } else {
+      Register core_reg = kManagedCoreArgumentRegisters[gpr_arg_count_];
+      return X86ManagedRegister::FromCpuRegister(core_reg);
+    }
   }
-  return res;
-}
-
-ManagedRegister X86ManagedRuntimeCallingConvention::CurrentParamHighLongRegister() {
-  ManagedRegister res = ManagedRegister::NoRegister();
-  DCHECK(IsCurrentParamALong());
-  switch (gpr_arg_count_) {
-    case 0: res = X86ManagedRegister::FromCpuRegister(EDX); break;
-    case 1: res = X86ManagedRegister::FromCpuRegister(EBX); break;
-  }
-  return res;
 }
 
 FrameOffset X86ManagedRuntimeCallingConvention::CurrentParamStackOffset() {
@@ -164,48 +170,6 @@
                      (itr_slots_ * kFramePointerSize));  // offset into in args
 }
 
-const ManagedRegisterEntrySpills& X86ManagedRuntimeCallingConvention::EntrySpills() {
-  // We spill the argument registers on X86 to free them up for scratch use, we then assume
-  // all arguments are on the stack.
-  if (entry_spills_.size() == 0) {
-    ResetIterator(FrameOffset(0));
-    while (HasNext()) {
-      ManagedRegister in_reg = CurrentParamRegister();
-      bool is_long = IsCurrentParamALong();
-      if (!in_reg.IsNoRegister()) {
-        int32_t size = IsParamADouble(itr_args_) ? 8 : 4;
-        int32_t spill_offset = CurrentParamStackOffset().Uint32Value();
-        ManagedRegisterSpill spill(in_reg, size, spill_offset);
-        entry_spills_.push_back(spill);
-        if (is_long) {
-          // special case, as we need a second register here.
-          in_reg = CurrentParamHighLongRegister();
-          DCHECK(!in_reg.IsNoRegister());
-          // We have to spill the second half of the long.
-          ManagedRegisterSpill spill2(in_reg, size, spill_offset + 4);
-          entry_spills_.push_back(spill2);
-        }
-
-        // Keep track of the number of GPRs allocated.
-        if (!IsCurrentParamAFloatOrDouble()) {
-          if (is_long) {
-            // Long was allocated in 2 registers.
-            gpr_arg_count_ += 2;
-          } else {
-            gpr_arg_count_++;
-          }
-        }
-      } else if (is_long) {
-        // We need to skip the unused last register, which is empty.
-        // If we are already out of registers, this is harmless.
-        gpr_arg_count_ += 2;
-      }
-      Next();
-    }
-  }
-  return entry_spills_;
-}
-
 // JNI calling convention
 
 X86JniCallingConvention::X86JniCallingConvention(bool is_static,
@@ -326,7 +290,6 @@
                       [](ManagedRegister callee_save) constexpr {
                         return callee_save.Equals(X86ManagedRegister::FromCpuRegister(EAX));
                       }));
-  DCHECK(!InterproceduralScratchRegister().Equals(X86ManagedRegister::FromCpuRegister(EAX)));
   return X86ManagedRegister::FromCpuRegister(EAX);
 }