Refactor intrinsic CAS, prepare for 64-bit version.

Bug: 11391018
Change-Id: Ic0f740e0cd0eb47f2c915f81be02f52f7721f8a3
diff --git a/compiler/dex/quick/arm/arm_dex_file_method_inliner.cc b/compiler/dex/quick/arm/arm_dex_file_method_inliner.cc
index a8ae3cd..257b2c4 100644
--- a/compiler/dex/quick/arm/arm_dex_file_method_inliner.cc
+++ b/compiler/dex/quick/arm/arm_dex_file_method_inliner.cc
@@ -64,10 +64,12 @@
     INTRINSIC(LibcoreIoMemory, PokeLongNative, JJ_V, kIntrinsicPoke, kLong),
     INTRINSIC(LibcoreIoMemory, PokeShortNative, JS_V, kIntrinsicPoke, kSignedHalf),
 
-    INTRINSIC(SunMiscUnsafe, CompareAndSwapInt, ObjectJII_Z, kIntrinsicCas32,
-              kIntrinsicFlagDontNeedWriteBarrier),
-    INTRINSIC(SunMiscUnsafe, CompareAndSwapObject, ObjectJObjectObject_Z, kIntrinsicCas32,
-              kIntrinsicFlagNeedWriteBarrier),
+    INTRINSIC(SunMiscUnsafe, CompareAndSwapInt, ObjectJII_Z, kIntrinsicCas,
+              kIntrinsicFlagNone),
+    // INTRINSIC(SunMiscUnsafe, CompareAndSwapLong, ObjectJJJ_Z, kIntrinsicCas,
+    //           kIntrinsicFlagIsLong),
+    INTRINSIC(SunMiscUnsafe, CompareAndSwapObject, ObjectJObjectObject_Z, kIntrinsicCas,
+              kIntrinsicFlagIsObject),
 
 #define UNSAFE_GET_PUT(type, code, type_flags) \
     INTRINSIC(SunMiscUnsafe, Get ## type, ObjectJ_ ## code, kIntrinsicUnsafeGet, \
diff --git a/compiler/dex/quick/arm/codegen_arm.h b/compiler/dex/quick/arm/codegen_arm.h
index 15355be..de3223a 100644
--- a/compiler/dex/quick/arm/codegen_arm.h
+++ b/compiler/dex/quick/arm/codegen_arm.h
@@ -104,7 +104,7 @@
     void GenCmpFP(Instruction::Code opcode, RegLocation rl_dest, RegLocation rl_src1,
                   RegLocation rl_src2);
     void GenConversion(Instruction::Code opcode, RegLocation rl_dest, RegLocation rl_src);
-    bool GenInlinedCas32(CallInfo* info, bool need_write_barrier);
+    bool GenInlinedCas(CallInfo* info, bool is_long, bool is_object);
     bool GenInlinedMinMaxInt(CallInfo* info, bool is_min);
     bool GenInlinedSqrt(CallInfo* info);
     bool GenInlinedPeek(CallInfo* info, OpSize size);
diff --git a/compiler/dex/quick/arm/int_arm.cc b/compiler/dex/quick/arm/int_arm.cc
index 9f84b03..9727179 100644
--- a/compiler/dex/quick/arm/int_arm.cc
+++ b/compiler/dex/quick/arm/int_arm.cc
@@ -560,14 +560,15 @@
   LOG(FATAL) << "Unexpected use of OpTlsCmp for Arm";
 }
 
-bool ArmMir2Lir::GenInlinedCas32(CallInfo* info, bool need_write_barrier) {
+bool ArmMir2Lir::GenInlinedCas(CallInfo* info, bool is_long, bool is_object) {
+  DCHECK(!is_long);  // not supported yet
   DCHECK_EQ(cu_->instruction_set, kThumb2);
   // Unused - RegLocation rl_src_unsafe = info->args[0];
-  RegLocation rl_src_obj= info->args[1];  // Object - known non-null
-  RegLocation rl_src_offset= info->args[2];  // long low
+  RegLocation rl_src_obj = info->args[1];  // Object - known non-null
+  RegLocation rl_src_offset = info->args[2];  // long low
   rl_src_offset.wide = 0;  // ignore high half in info->args[3]
-  RegLocation rl_src_expected= info->args[4];  // int or Object
-  RegLocation rl_src_new_value= info->args[5];  // int or Object
+  RegLocation rl_src_expected = info->args[4];  // int, long or Object
+  RegLocation rl_src_new_value = info->args[5];  // int, long or Object
   RegLocation rl_dest = InlineTarget(info);  // boolean place for result
 
 
@@ -577,7 +578,7 @@
   RegLocation rl_object = LoadValue(rl_src_obj, kCoreReg);
   RegLocation rl_new_value = LoadValue(rl_src_new_value, kCoreReg);
 
-  if (need_write_barrier && !mir_graph_->IsConstantNullRef(rl_new_value)) {
+  if (is_object && !mir_graph_->IsConstantNullRef(rl_new_value)) {
     // Mark card for object assuming new value is stored.
     MarkGCCard(rl_new_value.low_reg, rl_object.low_reg);
   }
diff --git a/compiler/dex/quick/dex_file_method_inliner.cc b/compiler/dex/quick/dex_file_method_inliner.cc
index 6a760fa..6c0328e 100644
--- a/compiler/dex/quick/dex_file_method_inliner.cc
+++ b/compiler/dex/quick/dex_file_method_inliner.cc
@@ -71,6 +71,7 @@
     "pokeLongNative",        // kNameCachePokeLongNative
     "pokeShortNative",       // kNameCachePokeShortNative
     "compareAndSwapInt",     // kNameCacheCompareAndSwapInt
+    "compareAndSwapLong",    // kNameCacheCompareAndSwapLong
     "compareAndSwapObject",  // kNameCacheCompareAndSwapObject
     "getInt",                // kNameCacheGetInt
     "getIntVolatile",        // kNameCacheGetIntVolatile
@@ -135,6 +136,9 @@
     // kProtoCacheObjectJII_Z
     { kClassCacheBoolean, 4, { kClassCacheJavaLangObject, kClassCacheLong,
         kClassCacheInt, kClassCacheInt } },
+    // kProtoCacheObjectJJJ_Z
+    { kClassCacheBoolean, 4, { kClassCacheJavaLangObject, kClassCacheLong,
+        kClassCacheLong, kClassCacheLong } },
     // kProtoCacheObjectJObjectObject_Z
     { kClassCacheBoolean, 4, { kClassCacheJavaLangObject, kClassCacheLong,
         kClassCacheJavaLangObject, kClassCacheJavaLangObject } },
@@ -205,8 +209,9 @@
       return backend->GenInlinedPeek(info, static_cast<OpSize>(intrinsic.data));
     case kIntrinsicPoke:
       return backend->GenInlinedPoke(info, static_cast<OpSize>(intrinsic.data));
-    case kIntrinsicCas32:
-      return backend->GenInlinedCas32(info, intrinsic.data & kIntrinsicFlagNeedWriteBarrier);
+    case kIntrinsicCas:
+      return backend->GenInlinedCas(info, intrinsic.data & kIntrinsicFlagIsLong,
+                                    intrinsic.data & kIntrinsicFlagIsObject);
     case kIntrinsicUnsafeGet:
       return backend->GenInlinedUnsafeGet(info, intrinsic.data & kIntrinsicFlagIsLong,
                                           intrinsic.data & kIntrinsicFlagIsVolatile);
diff --git a/compiler/dex/quick/dex_file_method_inliner.h b/compiler/dex/quick/dex_file_method_inliner.h
index 95b8dd3..bc00513 100644
--- a/compiler/dex/quick/dex_file_method_inliner.h
+++ b/compiler/dex/quick/dex_file_method_inliner.h
@@ -41,7 +41,7 @@
   kIntrinsicCurrentThread,
   kIntrinsicPeek,
   kIntrinsicPoke,
-  kIntrinsicCas32,
+  kIntrinsicCas,
   kIntrinsicUnsafeGet,
   kIntrinsicUnsafePut,
 };
@@ -60,15 +60,13 @@
   // kIntrinsicIndexOf
   kIntrinsicFlagBase0 = 1,
 
-  // kIntrinsicUnsafeCas32
-  kIntrinsicFlagDontNeedWriteBarrier = 0,
-  kIntrinsicFlagNeedWriteBarrier = 1,
-
-  // kIntrinsicUnsafeGet, kIntrinsicUnsafePut
+  // kIntrinsicUnsafeGet, kIntrinsicUnsafePut, kIntrinsicUnsafeCas
   kIntrinsicFlagIsLong     = 1,
+  // kIntrinsicUnsafeGet, kIntrinsicUnsafePut
   kIntrinsicFlagIsVolatile = 2,
-  // kIntrinsicUnsafePut
+  // kIntrinsicUnsafePut, kIntrinsicUnsafeCas
   kIntrinsicFlagIsObject   = 4,
+  // kIntrinsicUnsafePut
   kIntrinsicFlagIsOrdered  = 8,
 };
 
@@ -176,6 +174,7 @@
       kNameCachePokeLongNative,
       kNameCachePokeShortNative,
       kNameCacheCompareAndSwapInt,
+      kNameCacheCompareAndSwapLong,
       kNameCacheCompareAndSwapObject,
       kNameCacheGetInt,
       kNameCacheGetIntVolatile,
@@ -224,6 +223,7 @@
       kProtoCacheJJ_V,
       kProtoCacheJS_V,
       kProtoCacheObjectJII_Z,
+      kProtoCacheObjectJJJ_Z,
       kProtoCacheObjectJObjectObject_Z,
       kProtoCacheObjectJ_I,
       kProtoCacheObjectJI_V,
diff --git a/compiler/dex/quick/mips/codegen_mips.h b/compiler/dex/quick/mips/codegen_mips.h
index 88b244b..5dda445 100644
--- a/compiler/dex/quick/mips/codegen_mips.h
+++ b/compiler/dex/quick/mips/codegen_mips.h
@@ -104,7 +104,7 @@
     void GenCmpFP(Instruction::Code opcode, RegLocation rl_dest, RegLocation rl_src1,
                           RegLocation rl_src2);
     void GenConversion(Instruction::Code opcode, RegLocation rl_dest, RegLocation rl_src);
-    bool GenInlinedCas32(CallInfo* info, bool need_write_barrier);
+    bool GenInlinedCas(CallInfo* info, bool is_long, bool is_object);
     bool GenInlinedMinMaxInt(CallInfo* info, bool is_min);
     bool GenInlinedSqrt(CallInfo* info);
     bool GenInlinedPeek(CallInfo* info, OpSize size);
diff --git a/compiler/dex/quick/mips/int_mips.cc b/compiler/dex/quick/mips/int_mips.cc
index 5229429..dfff260 100644
--- a/compiler/dex/quick/mips/int_mips.cc
+++ b/compiler/dex/quick/mips/int_mips.cc
@@ -258,7 +258,7 @@
   LOG(FATAL) << "Unexpected use of OpTlsCmp for Arm";
 }
 
-bool MipsMir2Lir::GenInlinedCas32(CallInfo* info, bool need_write_barrier) {
+bool MipsMir2Lir::GenInlinedCas(CallInfo* info, bool is_long, bool is_object) {
   DCHECK_NE(cu_->instruction_set, kThumb2);
   return false;
 }
diff --git a/compiler/dex/quick/mips/mips_dex_file_method_inliner.cc b/compiler/dex/quick/mips/mips_dex_file_method_inliner.cc
index e5345ec..05d8ac8 100644
--- a/compiler/dex/quick/mips/mips_dex_file_method_inliner.cc
+++ b/compiler/dex/quick/mips/mips_dex_file_method_inliner.cc
@@ -64,10 +64,12 @@
     // INTRINSIC(LibcoreIoMemory, PokeLongNative, JJ_V, kIntrinsicPoke, kLong),
     // INTRINSIC(LibcoreIoMemory, PokeShortNative, JS_V, kIntrinsicPoke, kSignedHalf),
 
-    // INTRINSIC(SunMiscUnsafe, CompareAndSwapInt, ObjectJII_Z, kIntrinsicCas32,
-    //           kIntrinsicFlagDontNeedWriteBarrier),
-    // INTRINSIC(SunMiscUnsafe, CompareAndSwapObject, ObjectJObjectObject_Z, kIntrinsicCas32,
-    //           kIntrinsicFlagNeedWriteBarrier),
+    // INTRINSIC(SunMiscUnsafe, CompareAndSwapInt, ObjectJII_Z, kIntrinsicCas,
+    //           kIntrinsicFlagNone),
+    // INTRINSIC(SunMiscUnsafe, CompareAndSwapLong, ObjectJJJ_Z, kIntrinsicCas,
+    //           kIntrinsicFlagIsLong),
+    // INTRINSIC(SunMiscUnsafe, CompareAndSwapObject, ObjectJObjectObject_Z, kIntrinsicCas,
+    //           kIntrinsicFlagIsObject),
 
 #define UNSAFE_GET_PUT(type, code, type_flags) \
     INTRINSIC(SunMiscUnsafe, Get ## type, ObjectJ_ ## code, kIntrinsicUnsafeGet, \
diff --git a/compiler/dex/quick/mir_to_lir.h b/compiler/dex/quick/mir_to_lir.h
index 58a77c7..ad9b0de 100644
--- a/compiler/dex/quick/mir_to_lir.h
+++ b/compiler/dex/quick/mir_to_lir.h
@@ -661,7 +661,7 @@
                           RegLocation rl_src1, RegLocation rl_src2) = 0;
     virtual void GenConversion(Instruction::Code opcode, RegLocation rl_dest,
                                RegLocation rl_src) = 0;
-    virtual bool GenInlinedCas32(CallInfo* info, bool need_write_barrier) = 0;
+    virtual bool GenInlinedCas(CallInfo* info, bool is_long, bool is_object) = 0;
     virtual bool GenInlinedMinMaxInt(CallInfo* info, bool is_min) = 0;
     virtual bool GenInlinedSqrt(CallInfo* info) = 0;
     virtual bool GenInlinedPeek(CallInfo* info, OpSize size) = 0;
diff --git a/compiler/dex/quick/x86/codegen_x86.h b/compiler/dex/quick/x86/codegen_x86.h
index 1d6509e..ffe2d67 100644
--- a/compiler/dex/quick/x86/codegen_x86.h
+++ b/compiler/dex/quick/x86/codegen_x86.h
@@ -104,7 +104,7 @@
     void GenCmpFP(Instruction::Code opcode, RegLocation rl_dest, RegLocation rl_src1,
                           RegLocation rl_src2);
     void GenConversion(Instruction::Code opcode, RegLocation rl_dest, RegLocation rl_src);
-    bool GenInlinedCas32(CallInfo* info, bool need_write_barrier);
+    bool GenInlinedCas(CallInfo* info, bool is_long, bool is_object);
     bool GenInlinedMinMaxInt(CallInfo* info, bool is_min);
     bool GenInlinedSqrt(CallInfo* info);
     bool GenInlinedPeek(CallInfo* info, OpSize size);
diff --git a/compiler/dex/quick/x86/int_x86.cc b/compiler/dex/quick/x86/int_x86.cc
index 499547b..01d5c17 100644
--- a/compiler/dex/quick/x86/int_x86.cc
+++ b/compiler/dex/quick/x86/int_x86.cc
@@ -281,7 +281,7 @@
   NewLIR2(kX86Cmp16TI8, offset.Int32Value(), val);
 }
 
-bool X86Mir2Lir::GenInlinedCas32(CallInfo* info, bool need_write_barrier) {
+bool X86Mir2Lir::GenInlinedCas(CallInfo* info, bool is_long, bool is_object) {
   DCHECK_NE(cu_->instruction_set, kThumb2);
   return false;
 }
diff --git a/compiler/dex/quick/x86/x86_dex_file_method_inliner.cc b/compiler/dex/quick/x86/x86_dex_file_method_inliner.cc
index 87f881a..b788c3c 100644
--- a/compiler/dex/quick/x86/x86_dex_file_method_inliner.cc
+++ b/compiler/dex/quick/x86/x86_dex_file_method_inliner.cc
@@ -64,10 +64,12 @@
     INTRINSIC(LibcoreIoMemory, PokeLongNative, JJ_V, kIntrinsicPoke, kLong),
     INTRINSIC(LibcoreIoMemory, PokeShortNative, JS_V, kIntrinsicPoke, kSignedHalf),
 
-    // INTRINSIC(SunMiscUnsafe, CompareAndSwapInt, ObjectJII_Z, kIntrinsicCas32,
-    //           kIntrinsicFlagDontNeedWriteBarrier),
-    // INTRINSIC(SunMiscUnsafe, CompareAndSwapObject, ObjectJObjectObject_Z, kIntrinsicCas32,
-    //           kIntrinsicFlagNeedWriteBarrier),
+    // INTRINSIC(SunMiscUnsafe, CompareAndSwapInt, ObjectJII_Z, kIntrinsicCas,
+    //           kIntrinsicFlagNone),
+    // INTRINSIC(SunMiscUnsafe, CompareAndSwapLong, ObjectJJJ_Z, kIntrinsicCas,
+    //           kIntrinsicFlagIsLong),
+    // INTRINSIC(SunMiscUnsafe, CompareAndSwapObject, ObjectJObjectObject_Z, kIntrinsicCas,
+    //           kIntrinsicFlagIsObject),
 
 #define UNSAFE_GET_PUT(type, code, type_flags) \
     INTRINSIC(SunMiscUnsafe, Get ## type, ObjectJ_ ## code, kIntrinsicUnsafeGet, \