Use LIRSlowPath for throwing NPE.

Get rid of launchpads for throwing NPE and use LIRSlowPath instead.
Also clean up some code of using LIRSlowPath for checking div
by zero.

Bug: 13170824

Change-Id: I0c20a49c39feff3eb1f147755e557d9bc0ff15bb
diff --git a/compiler/dex/quick/gen_common.cc b/compiler/dex/quick/gen_common.cc
index 4522379..0d938d9 100644
--- a/compiler/dex/quick/gen_common.cc
+++ b/compiler/dex/quick/gen_common.cc
@@ -58,18 +58,18 @@
   return branch;
 }
 
-void Mir2Lir::AddDivZeroSlowPath(ConditionCode c_code) {
+void Mir2Lir::GenDivZeroException() {
+  LIR* branch = OpUnconditionalBranch(nullptr);
+  AddDivZeroCheckSlowPath(branch);
+}
+
+void Mir2Lir::GenDivZeroCheck(ConditionCode c_code) {
   LIR* branch = OpCondBranch(c_code, nullptr);
   AddDivZeroCheckSlowPath(branch);
 }
 
-void Mir2Lir::AddDivZeroSlowPath(ConditionCode c_code, RegStorage reg, int imm_val) {
-  LIR* branch;
-  if (c_code == kCondAl) {
-    branch = OpUnconditionalBranch(nullptr);
-  } else {
-    branch = OpCmpImmBranch(c_code, reg, imm_val, nullptr);
-  }
+void Mir2Lir::GenDivZeroCheck(RegStorage reg) {
+  LIR* branch = OpCmpImmBranch(kCondEq, reg, 0, nullptr);
   AddDivZeroCheckSlowPath(branch);
 }
 
@@ -80,7 +80,7 @@
         : LIRSlowPath(m2l, m2l->GetCurrentDexPc(), branch) {
     }
 
-    void Compile() {
+    void Compile() OVERRIDE {
       m2l_->ResetRegPool();
       m2l_->ResetDefTracking();
       GenerateTargetLabel();
@@ -91,6 +91,26 @@
   AddSlowPath(new (arena_) DivZeroCheckSlowPath(this, branch));
 }
 
+LIR* Mir2Lir::GenNullCheck(RegStorage reg) {
+  class NullCheckSlowPath : public Mir2Lir::LIRSlowPath {
+   public:
+    NullCheckSlowPath(Mir2Lir* m2l, LIR* branch)
+        : LIRSlowPath(m2l, m2l->GetCurrentDexPc(), branch) {
+    }
+
+    void Compile() OVERRIDE {
+      m2l_->ResetRegPool();
+      m2l_->ResetDefTracking();
+      GenerateTargetLabel();
+      m2l_->CallRuntimeHelper(QUICK_ENTRYPOINT_OFFSET(4, pThrowNullPointer), true);
+    }
+  };
+
+  LIR* branch = OpCmpImmBranch(kCondEq, reg, 0, nullptr);
+  AddSlowPath(new (arena_) NullCheckSlowPath(this, branch));
+  return branch;
+}
+
 /* Perform null-check on a register.  */
 LIR* Mir2Lir::GenNullCheck(RegStorage m_reg, int opt_flags) {
   if (Runtime::Current()->ExplicitNullChecks()) {
@@ -104,7 +124,7 @@
   if (!(cu_->disable_opt & (1 << kNullCheckElimination)) && (opt_flags & MIR_IGNORE_NULL_CHECK)) {
     return NULL;
   }
-  return GenImmedCheck(kCondEq, m_reg, 0, kThrowNullPointer);
+  return GenNullCheck(m_reg);
 }
 
 void Mir2Lir::MarkPossibleNullPointerException(int opt_flags) {
@@ -658,9 +678,6 @@
     int v2 = lab->operands[3];
     const bool target_x86 = cu_->instruction_set == kX86 || cu_->instruction_set == kX86_64;
     switch (lab->operands[0]) {
-      case kThrowNullPointer:
-        func_offset = QUICK_ENTRYPOINT_OFFSET(4, pThrowNullPointer);
-        break;
       case kThrowConstantArrayBounds:  // v1 is length reg (for Arm/Mips), v2 constant index
         // v1 holds the constant array index.  Mips/Arm uses v2 for length, x86 reloads.
         if (target_x86) {
@@ -1551,7 +1568,7 @@
       rl_src1 = LoadValue(rl_src1, kCoreReg);
       rl_src2 = LoadValue(rl_src2, kCoreReg);
       if (check_zero) {
-          AddDivZeroSlowPath(kCondEq, rl_src2.reg, 0);
+          GenDivZeroCheck(rl_src2.reg);
       }
       rl_result = GenDivRem(rl_dest, rl_src1.reg, rl_src2.reg, op == kOpDiv);
       done = true;
@@ -1562,7 +1579,7 @@
         rl_src1 = LoadValue(rl_src1, kCoreReg);
         rl_src2 = LoadValue(rl_src2, kCoreReg);
         if (check_zero) {
-            AddDivZeroSlowPath(kCondEq, rl_src2.reg, 0);
+            GenDivZeroCheck(rl_src2.reg);
         }
         rl_result = GenDivRem(rl_dest, rl_src1.reg, rl_src2.reg, op == kOpDiv);
         done = true;
@@ -1577,7 +1594,7 @@
       RegStorage r_tgt = CallHelperSetup(func_offset);
       LoadValueDirectFixed(rl_src1, TargetReg(kArg0));
       if (check_zero) {
-        AddDivZeroSlowPath(kCondEq, TargetReg(kArg1), 0);
+        GenDivZeroCheck(TargetReg(kArg1));
       }
       // NOTE: callout here is not a safepoint.
       CallHelper(r_tgt, func_offset, false /* not a safepoint */);
@@ -1802,7 +1819,7 @@
     case Instruction::REM_INT_LIT8:
     case Instruction::REM_INT_LIT16: {
       if (lit == 0) {
-        AddDivZeroSlowPath(kCondAl, RegStorage::InvalidReg(), 0);
+        GenDivZeroException();
         return;
       }
       if ((opcode == Instruction::DIV_INT) ||
@@ -1976,7 +1993,7 @@
       RegStorage r_tmp2 = RegStorage::MakeRegPair(TargetReg(kArg2), TargetReg(kArg3));
       LoadValueDirectWideFixed(rl_src2, r_tmp2);
       RegStorage r_tgt = CallHelperSetup(func_offset);
-      GenDivZeroCheck(RegStorage::MakeRegPair(TargetReg(kArg2), TargetReg(kArg3)));
+      GenDivZeroCheckWide(RegStorage::MakeRegPair(TargetReg(kArg2), TargetReg(kArg3)));
       LoadValueDirectWideFixed(rl_src1, r_tmp1);
       // NOTE: callout here is not a safepoint
       CallHelper(r_tgt, func_offset, false /* not safepoint */);