JIT: Add new compare-immed-and-branch primative & drop useless clrex

This allows better use of cbz/cbnz on Thumb2 targets.  Also, removed
the clrex from the inline monitor enter code (not necessary).

Change-Id: I3bfa90bcdf34f6ef3e2447c9c6f1b49a98a89e58
diff --git a/vm/compiler/codegen/arm/CodegenDriver.c b/vm/compiler/codegen/arm/CodegenDriver.c
index 86c2e29..54d3b8e 100644
--- a/vm/compiler/codegen/arm/CodegenDriver.c
+++ b/vm/compiler/codegen/arm/CodegenDriver.c
@@ -31,8 +31,7 @@
 {
     int regCardBase = dvmCompilerAllocTemp(cUnit);
     int regCardNo = dvmCompilerAllocTemp(cUnit);
-    opRegImm(cUnit, kOpCmp, valReg, 0); /* storing null? */
-    ArmLIR *branchOver = opCondBranch(cUnit, kArmCondEq);
+    ArmLIR *branchOver = genCmpImmBranch(cUnit, kArmCondEq, valReg, 0);
     loadWordDisp(cUnit, rGLUE, offsetof(InterpState, cardTable),
                  regCardBase);
     opRegRegImm(cUnit, kOpLsr, regCardNo, tgtAddrReg, GC_CARD_SHIFT);
@@ -541,8 +540,7 @@
     LOAD_FUNC_ADDR(cUnit, r2, (int)dvmCanPutArrayElement);
 
     /* Are we storing null?  If so, avoid check */
-    opRegImm(cUnit, kOpCmp, r0, 0);
-    ArmLIR *branchOver = opCondBranch(cUnit, kArmCondEq);
+    ArmLIR *branchOver = genCmpImmBranch(cUnit, kArmCondEq, r0, 0);
 
     /* Make sure the types are compatible */
     loadWordDisp(cUnit, regArray, offsetof(Object, clazz), r1);
@@ -1175,9 +1173,7 @@
     loadWordDisp(cUnit, r7, methodIndex * 4, r0);
 
     /* Check if rechain limit is reached */
-    opRegImm(cUnit, kOpCmp, r1, 0);
-
-    ArmLIR *bypassRechaining = opCondBranch(cUnit, kArmCondGt);
+    ArmLIR *bypassRechaining = genCmpImmBranch(cUnit, kArmCondGt, r1, 0);
 
     loadWordDisp(cUnit, rGLUE, offsetof(InterpState,
                  jitToInterpEntries.dvmJitToPatchPredictedChain), r7);
@@ -1291,8 +1287,8 @@
         LOAD_FUNC_ADDR(cUnit, r2, (int)dvmUnlockObject);
         /* Do the call */
         opReg(cUnit, kOpBlx, r2);
-        opRegImm(cUnit, kOpCmp, r0, 0); /* Did we throw? */
-        ArmLIR *branchOver = opCondBranch(cUnit, kArmCondNe);
+        /* Did we throw? */
+        ArmLIR *branchOver = genCmpImmBranch(cUnit, kArmCondNe, r0, 0);
         loadConstant(cUnit, r0,
                      (int) (cUnit->method->insns + mir->offset +
                      dexGetInstrWidthAbs(gDvm.instrWidth, OP_MONITOR_EXIT)));
@@ -1606,8 +1602,7 @@
             opReg(cUnit, kOpBlx, r2);
             dvmCompilerClobberCallRegs(cUnit);
             /* generate a branch over if allocation is successful */
-            opRegImm(cUnit, kOpCmp, r0, 0); /* NULL? */
-            ArmLIR *branchOver = opCondBranch(cUnit, kArmCondNe);
+            ArmLIR *branchOver = genCmpImmBranch(cUnit, kArmCondNe, r0, 0);
             /*
              * OOM exception needs to be thrown here and cannot re-execute
              */
@@ -1648,8 +1643,9 @@
             loadConstant(cUnit, r1, (int) classPtr );
             rlSrc = dvmCompilerGetSrc(cUnit, mir, 0);
             rlSrc = loadValue(cUnit, rlSrc, kCoreReg);
-            opRegImm(cUnit, kOpCmp, rlSrc.lowReg, 0);   /* Null? */
-            ArmLIR *branch1 = opCondBranch(cUnit, kArmCondEq);
+            /* Null? */
+            ArmLIR *branch1 = genCmpImmBranch(cUnit, kArmCondEq,
+                                              rlSrc.lowReg, 0);
             /*
              *  rlSrc.lowReg now contains object->clazz.  Note that
              *  it could have been allocated r0, but we're okay so long
@@ -2253,8 +2249,7 @@
             opReg(cUnit, kOpBlx, r3);
             dvmCompilerClobberCallRegs(cUnit);
             /* generate a branch over if allocation is successful */
-            opRegImm(cUnit, kOpCmp, r0, 0); /* NULL? */
-            ArmLIR *branchOver = opCondBranch(cUnit, kArmCondNe);
+            ArmLIR *branchOver = genCmpImmBranch(cUnit, kArmCondNe, r0, 0);
             /*
              * OOM exception needs to be thrown here and cannot re-execute
              */
@@ -2293,10 +2288,8 @@
             dvmCompilerFlushAllRegs(cUnit);   /* Everything to home location */
             loadValueDirectFixed(cUnit, rlSrc, r0);  /* Ref */
             loadConstant(cUnit, r2, (int) classPtr );
-//TUNING: compare to 0 primative to allow use of CB[N]Z
-            opRegImm(cUnit, kOpCmp, r0, 0); /* NULL? */
             /* When taken r0 has NULL which can be used for store directly */
-            ArmLIR *branch1 = opCondBranch(cUnit, kArmCondEq);
+            ArmLIR *branch1 = genCmpImmBranch(cUnit, kArmCondEq, r0, 0);
             /* r1 now contains object->clazz */
             loadWordDisp(cUnit, r0, offsetof(Object, clazz), r1);
             /* r1 now contains object->clazz */
@@ -2708,8 +2701,7 @@
             opReg(cUnit, kOpBlx, r2);
             dvmCompilerClobberCallRegs(cUnit);
             /* generate a branch over if successful */
-            opRegImm(cUnit, kOpCmp, r0, 0); /* NULL? */
-            ArmLIR *branchOver = opCondBranch(cUnit, kArmCondNe);
+            ArmLIR *branchOver = genCmpImmBranch(cUnit, kArmCondNe, r0, 0);
             loadConstant(cUnit, r0,
                          (int) (cUnit->method->insns + mir->offset));
             genDispatchToHandler(cUnit, TEMPLATE_THROW_EXCEPTION_COMMON);
@@ -3055,8 +3047,7 @@
 
             dvmCompilerClobberCallRegs(cUnit);
             /* generate a branch over if the interface method is resolved */
-            opRegImm(cUnit, kOpCmp, r0, 0); /* NULL? */
-            ArmLIR *branchOver = opCondBranch(cUnit, kArmCondNe);
+            ArmLIR *branchOver = genCmpImmBranch(cUnit, kArmCondNe, r0, 0);
             /*
              * calleeMethod == NULL -> throw
              */
@@ -3072,9 +3063,8 @@
             genRegCopy(cUnit, r1, r8);
 
             /* Check if rechain limit is reached */
-            opRegImm(cUnit, kOpCmp, r1, 0);
-
-            ArmLIR *bypassRechaining = opCondBranch(cUnit, kArmCondGt);
+            ArmLIR *bypassRechaining = genCmpImmBranch(cUnit, kArmCondGt,
+                                                       r1, 0);
 
             loadWordDisp(cUnit, rGLUE, offsetof(InterpState,
                          jitToInterpEntries.dvmJitToPatchPredictedChain), r7);
@@ -3448,8 +3438,8 @@
             }
             opReg(cUnit, kOpBlx, r4PC);
             opRegImm(cUnit, kOpAdd, r13, 8);
-            opRegImm(cUnit, kOpCmp, r0, 0); /* NULL? */
-            ArmLIR *branchOver = opCondBranch(cUnit, kArmCondNe);
+            /* NULL? */
+            ArmLIR *branchOver = genCmpImmBranch(cUnit, kArmCondNe, r0, 0);
             loadConstant(cUnit, r0,
                          (int) (cUnit->method->insns + mir->offset));
             genDispatchToHandler(cUnit, TEMPLATE_THROW_EXCEPTION_COMMON);
diff --git a/vm/compiler/codegen/arm/CodegenFactory.c b/vm/compiler/codegen/arm/CodegenFactory.c
index 157bd1f..1de9f90 100644
--- a/vm/compiler/codegen/arm/CodegenFactory.c
+++ b/vm/compiler/codegen/arm/CodegenFactory.c
@@ -257,6 +257,20 @@
         }
     }
 }
+
+/*
+ * Perform a "reg cmp imm" operation and jump to the PCR region if condition
+ * satisfies.
+ */
+static ArmLIR *genRegImmCheck(CompilationUnit *cUnit,
+                              ArmConditionCode cond, int reg,
+                              int checkValue, int dOffset,
+                              ArmLIR *pcrLabel)
+{
+    ArmLIR *branch = genCmpImmBranch(cUnit, cond, reg, checkValue);
+    return genCheckCommon(cUnit, dOffset, branch, pcrLabel);
+}
+
 /*
  * Perform null-check on a register. sReg is the ssa register being checked,
  * and mReg is the machine register holding the actual value. If internal state
diff --git a/vm/compiler/codegen/arm/Thumb/Factory.c b/vm/compiler/codegen/arm/Thumb/Factory.c
index 85f612e..e18aa75 100644
--- a/vm/compiler/codegen/arm/Thumb/Factory.c
+++ b/vm/compiler/codegen/arm/Thumb/Factory.c
@@ -859,21 +859,18 @@
     }
 }
 
-static inline ArmLIR *genRegImmCheck(CompilationUnit *cUnit,
+static ArmLIR *genCmpImmBranch(CompilationUnit *cUnit,
                                      ArmConditionCode cond, int reg,
-                                     int checkValue, int dOffset,
-                                     ArmLIR *pcrLabel)
+                                     int checkValue)
 {
-    int tReg;
-    ArmLIR *res;
     if ((checkValue & 0xff) != checkValue) {
-        tReg = dvmCompilerAllocTemp(cUnit);
+        int tReg = dvmCompilerAllocTemp(cUnit);
         loadConstant(cUnit, tReg, checkValue);
-        res = genRegRegCheck(cUnit, cond, reg, tReg, dOffset, pcrLabel);
+        newLIR2(cUnit, kThumbCmpRR, reg, tReg);
         dvmCompilerFreeTemp(cUnit, tReg);
-        return res;
+    } else {
+        newLIR2(cUnit, kThumbCmpRI8, reg, checkValue);
     }
-    newLIR2(cUnit, kThumbCmpRI8, reg, checkValue);
     ArmLIR *branch = newLIR2(cUnit, kThumbBCond, 0, cond);
-    return genCheckCommon(cUnit, dOffset, branch, pcrLabel);
+    return branch;
 }
diff --git a/vm/compiler/codegen/arm/Thumb2/Factory.c b/vm/compiler/codegen/arm/Thumb2/Factory.c
index 2bf2940..5074e42 100644
--- a/vm/compiler/codegen/arm/Thumb2/Factory.c
+++ b/vm/compiler/codegen/arm/Thumb2/Factory.c
@@ -1088,15 +1088,13 @@
     loadBaseDispWide(cUnit, NULL, base, 0, lowReg, highReg, INVALID_SREG);
 }
 
-
 /*
- * Perform a "reg cmp imm" operation and jump to the PCR region if condition
- * satisfies.
+ * Generate a register comparison to an immediate and branch.  Caller
+ * is responsible for setting branch target field.
  */
-static ArmLIR *genRegImmCheck(CompilationUnit *cUnit,
+static ArmLIR *genCmpImmBranch(CompilationUnit *cUnit,
                               ArmConditionCode cond, int reg,
-                              int checkValue, int dOffset,
-                              ArmLIR *pcrLabel)
+                              int checkValue)
 {
     ArmLIR *branch;
     int modImm;
@@ -1118,7 +1116,7 @@
         }
         branch = newLIR2(cUnit, kThumbBCond, 0, cond);
     }
-    return genCheckCommon(cUnit, dOffset, branch, pcrLabel);
+    return branch;
 }
 
 static ArmLIR *fpRegCopy(CompilationUnit *cUnit, int rDest, int rSrc)
diff --git a/vm/compiler/codegen/arm/Thumb2/Gen.c b/vm/compiler/codegen/arm/Thumb2/Gen.c
index 3632388..8858bb0 100644
--- a/vm/compiler/codegen/arm/Thumb2/Gen.c
+++ b/vm/compiler/codegen/arm/Thumb2/Gen.c
@@ -220,11 +220,6 @@
     hopTarget->defMask = ENCODE_ALL;
     hopBranch->generic.target = (LIR *)hopTarget;
 
-    // Clear the lock
-    ArmLIR *inst = newLIR0(cUnit, kThumb2Clrex);
-    // ...and make it a scheduling barrier
-    inst->defMask = ENCODE_ALL;
-
     // Export PC (part 1)
     loadConstant(cUnit, r3, (int) (cUnit->method->insns + mir->offset));
 
@@ -290,8 +285,8 @@
             sizeof(StackSaveArea) -
             offsetof(StackSaveArea, xtra.currentPc));
     opReg(cUnit, kOpBlx, r7);
-    opRegImm(cUnit, kOpCmp, r0, 0); /* Did we throw? */
-    ArmLIR *branchOver = opCondBranch(cUnit, kArmCondNe);
+    /* Did we throw? */
+    ArmLIR *branchOver = genCmpImmBranch(cUnit, kArmCondNe, r0, 0);
     loadConstant(cUnit, r0,
                  (int) (cUnit->method->insns + mir->offset +
                  dexGetInstrWidthAbs(gDvm.instrWidth, OP_MONITOR_EXIT)));