AArch64: Fix cmp-long and method with long arguments.

1. Fix cmp-long.
2. Use single register to pass long argument.
3. Flush StackReference<ArtMethod> on arm64 the same as in common code.
3. Fix the mismatch in calculate reg offset.

Change-Id: Ie2723260fb143512e4da6ee88d4f3aded80d3d5e
diff --git a/compiler/dex/quick/arm64/int_arm64.cc b/compiler/dex/quick/arm64/int_arm64.cc
index 7ebb496..0a76b9b 100644
--- a/compiler/dex/quick/arm64/int_arm64.cc
+++ b/compiler/dex/quick/arm64/int_arm64.cc
@@ -41,8 +41,8 @@
 /*
  * 64-bit 3way compare function.
  *     cmp   xA, xB
- *     csinc wC, wzr, wzr, eq
- *     csneg wC, wC, wC, le
+ *     csinc wC, wzr, wzr, eq  // wC = (xA == xB) ? 0 : 1
+ *     csneg wC, wC, wC, ge    // wC = (xA >= xB) ? wC : -wC
  */
 void Arm64Mir2Lir::GenCmpLong(RegLocation rl_dest, RegLocation rl_src1,
                               RegLocation rl_src2) {
@@ -52,10 +52,10 @@
   rl_result = EvalLoc(rl_dest, kCoreReg, true);
 
   OpRegReg(kOpCmp, rl_src1.reg, rl_src2.reg);
-  NewLIR4(WIDE(kA64Csinc4rrrc), rl_result.reg.GetReg(), rxzr, rxzr, kArmCondEq);
-  NewLIR4(WIDE(kA64Csneg4rrrc), rl_result.reg.GetReg(), rl_result.reg.GetReg(),
-          rl_result.reg.GetReg(), kArmCondLe);
-  StoreValueWide(rl_dest, rl_result);
+  NewLIR4(kA64Csinc4rrrc, rl_result.reg.GetReg(), rwzr, rwzr, kArmCondEq);
+  NewLIR4(kA64Csneg4rrrc, rl_result.reg.GetReg(), rl_result.reg.GetReg(),
+          rl_result.reg.GetReg(), kArmCondGe);
+  StoreValue(rl_dest, rl_result);
 }
 
 void Arm64Mir2Lir::GenShiftOpLong(Instruction::Code opcode, RegLocation rl_dest,
diff --git a/compiler/dex/quick/arm64/target_arm64.cc b/compiler/dex/quick/arm64/target_arm64.cc
index 7539392..0524191 100644
--- a/compiler/dex/quick/arm64/target_arm64.cc
+++ b/compiler/dex/quick/arm64/target_arm64.cc
@@ -839,7 +839,7 @@
   int num_fpr_used = 0;
 
   /*
-   * Dummy up a RegLocation for the incoming Method*
+   * Dummy up a RegLocation for the incoming StackReference<mirror::ArtMethod>
    * It will attempt to keep kArg0 live (or copy it to home location
    * if promoted).
    */
@@ -848,14 +848,10 @@
   rl_src.reg = TargetReg(kArg0);
   rl_src.home = false;
   MarkLive(rl_src);
-
-  // rl_method might be 32-bit, but ArtMethod* on stack is 64-bit, so always flush it.
-  StoreWordDisp(TargetReg(kSp), 0, TargetReg(kArg0));
-
-  // If Method* has been promoted, load it,
-  // otherwise, rl_method is the 32-bit value on [sp], and has already been loaded.
+  StoreValue(rl_method, rl_src);
+  // If Method* has been promoted, explicitly flush
   if (rl_method.location == kLocPhysReg) {
-    StoreValue(rl_method, rl_src);
+    StoreRefDisp(TargetReg(kSp), 0, TargetReg(kArg0));
   }
 
   if (cu_->num_ins == 0) {
@@ -912,9 +908,7 @@
     RegLocation rl_arg = info->args[next_arg++];
     rl_arg = UpdateRawLoc(rl_arg);
     if (rl_arg.wide && (next_reg <= TargetReg(kArg2).GetReg())) {
-      RegStorage r_tmp(RegStorage::k64BitPair, next_reg, next_reg + 1);
-      LoadValueDirectWideFixed(rl_arg, r_tmp);
-      next_reg++;
+      LoadValueDirectWideFixed(rl_arg, RegStorage::Solo64(next_reg));
       next_arg++;
     } else {
       if (rl_arg.wide) {
diff --git a/compiler/dex/quick/gen_invoke.cc b/compiler/dex/quick/gen_invoke.cc
index 1817fd3..842533b 100644
--- a/compiler/dex/quick/gen_invoke.cc
+++ b/compiler/dex/quick/gen_invoke.cc
@@ -434,7 +434,7 @@
  */
 void Mir2Lir::FlushIns(RegLocation* ArgLocs, RegLocation rl_method) {
   /*
-   * Dummy up a RegLocation for the incoming Method*
+   * Dummy up a RegLocation for the incoming StackReference<mirror::ArtMethod>
    * It will attempt to keep kArg0 live (or copy it to home location
    * if promoted).
    */
diff --git a/runtime/stack.h b/runtime/stack.h
index fabdd4f..e1c8c80 100644
--- a/runtime/stack.h
+++ b/runtime/stack.h
@@ -599,37 +599,37 @@
    * on location in frame as long as code generator itself knows how
    * to access them.
    *
-   *     +------------------------+
-   *     | IN[ins-1]              |  {Note: resides in caller's frame}
-   *     |       .                |
-   *     | IN[0]                  |
-   *     | caller's Method*       |
-   *     +========================+  {Note: start of callee's frame}
-   *     | core callee-save spill |  {variable sized}
-   *     +------------------------+
-   *     | fp callee-save spill   |
-   *     +------------------------+
-   *     | filler word            |  {For compatibility, if V[locals-1] used as wide
-   *     +------------------------+
-   *     | V[locals-1]            |
-   *     | V[locals-2]            |
-   *     |      .                 |
-   *     |      .                 |  ... (reg == 2)
-   *     | V[1]                   |  ... (reg == 1)
-   *     | V[0]                   |  ... (reg == 0) <---- "locals_start"
-   *     +------------------------+
-   *     | Compiler temp region   |  ... (reg <= -3)
-   *     |                        |
-   *     |                        |
-   *     +------------------------+
-   *     | stack alignment padding|  {0 to (kStackAlignWords-1) of padding}
-   *     +------------------------+
-   *     | OUT[outs-1]            |
-   *     | OUT[outs-2]            |
-   *     |       .                |
-   *     | OUT[0]                 |
-   *     | curMethod*             |  ... (reg == -2) <<== sp, 16-byte aligned
-   *     +========================+
+   *     +---------------------------+
+   *     | IN[ins-1]                 |  {Note: resides in caller's frame}
+   *     |       .                   |
+   *     | IN[0]                     |
+   *     | caller's ArtMethod        |  ... StackReference<ArtMethod>
+   *     +===========================+  {Note: start of callee's frame}
+   *     | core callee-save spill    |  {variable sized}
+   *     +---------------------------+
+   *     | fp callee-save spill      |
+   *     +---------------------------+
+   *     | filler word               |  {For compatibility, if V[locals-1] used as wide
+   *     +---------------------------+
+   *     | V[locals-1]               |
+   *     | V[locals-2]               |
+   *     |      .                    |
+   *     |      .                    |  ... (reg == 2)
+   *     | V[1]                      |  ... (reg == 1)
+   *     | V[0]                      |  ... (reg == 0) <---- "locals_start"
+   *     +---------------------------+
+   *     | Compiler temp region      |  ... (reg <= -3)
+   *     |                           |
+   *     |                           |
+   *     +---------------------------+
+   *     | stack alignment padding   |  {0 to (kStackAlignWords-1) of padding}
+   *     +---------------------------+
+   *     | OUT[outs-1]               |
+   *     | OUT[outs-2]               |
+   *     |       .                   |
+   *     | OUT[0]                    |
+   *     | StackReference<ArtMethod> |  ... (reg == -2) <<== sp, 16-byte aligned
+   *     +===========================+
    */
   static int GetVRegOffset(const DexFile::CodeItem* code_item,
                            uint32_t core_spills, uint32_t fp_spills,
@@ -661,7 +661,7 @@
       return locals_start + (reg * sizeof(uint32_t));
     } else {
       // Handle ins.
-      return frame_size + ((reg - num_regs) * sizeof(uint32_t)) + GetBytesPerGprSpillLocation(isa);
+      return frame_size + ((reg - num_regs) * sizeof(uint32_t)) + sizeof(StackReference<mirror::ArtMethod>);
     }
   }