Complete compiler portion of exception handling

Will still need much testing once the runtime portions are in place.

Change-Id: I90fc7c1fd89bfae89dfd19a6e422024b6b5454ec
diff --git a/src/compiler/codegen/arm/ArchFactory.cc b/src/compiler/codegen/arm/ArchFactory.cc
index 574bb57..66eaf54 100644
--- a/src/compiler/codegen/arm/ArchFactory.cc
+++ b/src/compiler/codegen/arm/ArchFactory.cc
@@ -22,6 +22,10 @@
  *
  */
 
+static ArmLIR* genUnconditionalBranch(CompilationUnit*, ArmLIR*);
+static ArmLIR* genConditionalBranch(CompilationUnit*, ArmConditionCode,
+                                    ArmLIR*);
+
 /*
  * Utiltiy to load the current Method*.  Broken out
  * to allow easy change between placing the current Method* in a
@@ -47,26 +51,23 @@
 #endif
 }
 
-/*
- * Perform a "reg cmp imm" operation and jump to the PCR region if condition
- * satisfies.
- */
-static TGT_LIR* genRegImmCheck(CompilationUnit* cUnit,
-                               ArmConditionCode cond, int reg,
-                               int checkValue, int dOffset,
-                               TGT_LIR* pcrLabel)
+static ArmLIR* genImmedCheck(CompilationUnit* cUnit, ArmConditionCode cCode,
+                             int reg, int immVal, MIR* mir, ArmThrowKind kind)
 {
-    TGT_LIR* branch = genCmpImmBranch(cUnit, cond, reg, checkValue);
-    BasicBlock* bb = cUnit->curBlock;
-    if (bb->taken) {
-        ArmLIR  *exceptionLabel = (ArmLIR* ) cUnit->blockLabelList;
-        exceptionLabel += bb->taken->id;
-        branch->generic.target = (LIR* ) exceptionLabel;
-        return exceptionLabel;
+    ArmLIR* tgt = (ArmLIR*)oatNew(sizeof(ArmLIR), true);
+    tgt->opcode = kArmPseudoThrowTarget;
+    tgt->operands[0] = kind;
+    tgt->operands[1] = mir->offset;
+    ArmLIR* branch;
+    if (cCode == kArmCondAl) {
+        branch = genUnconditionalBranch(cUnit, tgt);
     } else {
-        LOG(FATAL) << "Catch blocks not handled yet";
-        return NULL; // quiet gcc
+        branch = genCmpImmBranch(cUnit, kArmCondEq, reg, 0);
+        branch->generic.target = (LIR*)tgt;
     }
+    // Remember branch target - will process later
+    oatInsertGrowableList(&cUnit->throwLaunchpads, (intptr_t)tgt);
+    return branch;
 }
 
 /*
@@ -74,42 +75,30 @@
  * and mReg is the machine register holding the actual value. If internal state
  * indicates that sReg has been checked before the check request is ignored.
  */
-static TGT_LIR* genNullCheck(CompilationUnit* cUnit, int sReg, int mReg,
-                             int dOffset, TGT_LIR* pcrLabel)
+static ArmLIR* genNullCheck(CompilationUnit* cUnit, int sReg, int mReg,
+                             MIR* mir)
 {
-    /* This particular Dalvik register has been null-checked */
-#if 0
-    // Yes, I know.  Please be quiet.
-    UNIMPLEMENTED(WARNING) << "Need null check & throw support";
-#endif
-    return pcrLabel;
     if (oatIsBitSet(cUnit->regPool->nullCheckedRegs, sReg)) {
-        return pcrLabel;
+        /* This particular Dalvik register has been null-checked */
+        return NULL;
     }
     oatSetBit(cUnit->regPool->nullCheckedRegs, sReg);
-    return genRegImmCheck(cUnit, kArmCondEq, mReg, 0, dOffset, pcrLabel);
-}
-
-/*
- * Perform a "reg cmp reg" operation and jump to the PCR region if condition
- * satisfies.
- */
-static TGT_LIR* genRegRegCheck(CompilationUnit* cUnit,
-                               ArmConditionCode cond,
-                               int reg1, int reg2, int dOffset,
-                               TGT_LIR* pcrLabel)
-{
-    TGT_LIR* res;
-    res = opRegReg(cUnit, kOpCmp, reg1, reg2);
-    TGT_LIR* branch = opCondBranch(cUnit, cond);
-    genCheckCommon(cUnit, dOffset, branch, pcrLabel);
-    return res;
+    return genImmedCheck(cUnit, kArmCondEq, mReg, 0, mir, kArmThrowNullPointer);
 }
 
 /* Perform bound check on two registers */
 static TGT_LIR* genBoundsCheck(CompilationUnit* cUnit, int rIndex,
-                               int rBound, int dOffset, TGT_LIR* pcrLabel)
+                               int rBound, MIR* mir, ArmThrowKind kind)
 {
-    return genRegRegCheck(cUnit, kArmCondCs, rIndex, rBound, dOffset,
-                          pcrLabel);
+    ArmLIR* tgt = (ArmLIR*)oatNew(sizeof(ArmLIR), true);
+    tgt->opcode = kArmPseudoThrowTarget;
+    tgt->operands[0] = kind;
+    tgt->operands[1] = mir->offset;
+    tgt->operands[2] = rIndex;
+    tgt->operands[3] = rBound;
+    opRegReg(cUnit, kOpCmp, rIndex, rBound);
+    ArmLIR* branch = genConditionalBranch(cUnit, kArmCondCs, tgt);
+    // Remember branch target - will process later
+    oatInsertGrowableList(&cUnit->throwLaunchpads, (intptr_t)tgt);
+    return branch;
 }