Quick compiler - various bug fixes

Continuing clean-up of the MIR->LLVMIR->LIR path.  With this CL,
all of run-test 003 passes except for tests which need switch
support (unimplemented) and one of the Throw tests (I'm apparently not
fully describing all of the exception-related edges in the CFG).

Change-Id: I2075357bc7c5419c873bb62d44c34fdb73424e29
diff --git a/src/compiler/Frontend.cc b/src/compiler/Frontend.cc
index d617be5..b714065 100644
--- a/src/compiler/Frontend.cc
+++ b/src/compiler/Frontend.cc
@@ -759,16 +759,10 @@
 #if defined(ART_USE_QUICK_COMPILER)
   // TODO: remove - temp for Quick compiler bring-up
   if ((PrettyMethod(method_idx, dex_file).find("fibonacci") != std::string::npos)
-      || (PrettyMethod(method_idx, dex_file).find("Array") != std::string::npos)
-      || (PrettyMethod(method_idx, dex_file).find("Monitor") != std::string::npos)
-      || (PrettyMethod(method_idx, dex_file).find("InternedString") != std::string::npos)
-      || (PrettyMethod(method_idx, dex_file).find("StaticField") != std::string::npos)
-      || (PrettyMethod(method_idx, dex_file).find("UnresClass") != std::string::npos)
       || (PrettyMethod(method_idx, dex_file).find("HelloWorld") != std::string::npos)
       || (PrettyMethod(method_idx, dex_file).find("count10_006") != std::string::npos)
       || (PrettyMethod(method_idx, dex_file).find("exceptions_007") != std::string::npos)
       || (PrettyMethod(method_idx, dex_file).find("catchAndRethrow") != std::string::npos)
-      || (PrettyMethod(method_idx, dex_file).find("throwNullPointerException") != std::string::npos)
       || (PrettyMethod(method_idx, dex_file).find("math_012") != std::string::npos)
       || (PrettyMethod(method_idx, dex_file).find("math_013") != std::string::npos)
       || (PrettyMethod(method_idx, dex_file).find("math_014") != std::string::npos)
@@ -781,6 +775,24 @@
       || (PrettyMethod(method_idx, dex_file).find("shiftTest2") != std::string::npos)
       || (PrettyMethod(method_idx, dex_file).find("unsignedShiftTest") != std::string::npos)
       || (PrettyMethod(method_idx, dex_file).find("convTest") != std::string::npos)
+      || (PrettyMethod(method_idx, dex_file).find("Array") != std::string::npos)
+      || (PrettyMethod(method_idx, dex_file).find("Classes") != std::string::npos)
+      || (PrettyMethod(method_idx, dex_file).find("Compare") != std::string::npos)
+      || (PrettyMethod(method_idx, dex_file).find("FloatMath") != std::string::npos)
+      || (PrettyMethod(method_idx, dex_file).find("Goto") != std::string::npos)
+      || (PrettyMethod(method_idx, dex_file).find("InternedString") != std::string::npos)
+   //   || (PrettyMethod(method_idx, dex_file).find("IntMath") != std::string::npos)
+      || (PrettyMethod(method_idx, dex_file).find("InstField") != std::string::npos)
+      || (PrettyMethod(method_idx, dex_file).find("MethodCall") != std::string::npos)
+      || (PrettyMethod(method_idx, dex_file).find("Monitor") != std::string::npos)
+      || (PrettyMethod(method_idx, dex_file).find("StaticField") != std::string::npos)
+   //   || (PrettyMethod(method_idx, dex_file).find("Switch") != std::string::npos)
+   //   || (PrettyMethod(method_idx, dex_file).find("Throw.rethrow") != std::string::npos)
+      || (PrettyMethod(method_idx, dex_file).find("UnresClass") != std::string::npos)
+      || (PrettyMethod(method_idx, dex_file).find("UsresClassSubclass") != std::string::npos)
+      || (PrettyMethod(method_idx, dex_file).find("UsresStuff") != std::string::npos)
+      || (PrettyMethod(method_idx, dex_file).find("UsresTest1") != std::string::npos)
+      || (PrettyMethod(method_idx, dex_file).find("UsresTest2") != std::string::npos)
      ) {
     cUnit->genBitcode = true;
   }
diff --git a/src/compiler/codegen/MethodBitcode.cc b/src/compiler/codegen/MethodBitcode.cc
index cd4e1d3..a4521bb 100644
--- a/src/compiler/codegen/MethodBitcode.cc
+++ b/src/compiler/codegen/MethodBitcode.cc
@@ -333,7 +333,6 @@
     src2 = cUnit->irb->getInt32(0);
   }
   llvm::Value* condValue = convertCompare(cUnit, cc, src1, src2);
-  condValue->setName(StringPrintf("t%d", cUnit->tempName++));
   cUnit->irb->CreateCondBr(condValue, getLLVMBlock(cUnit, bb->taken->id),
                            getLLVMBlock(cUnit, bb->fallThrough->id));
   // Don't redo the fallthrough branch in the BB driver
@@ -429,6 +428,7 @@
 {
   llvm::Value* src1 = getLLVMValue(cUnit, rlSrc1.origSReg);
   llvm::Value* src2 = getLLVMValue(cUnit, rlSrc2.origSReg);
+  DCHECK_EQ(src1->getType(), src2->getType());
   llvm::Value* res = genArithOp(cUnit, op, rlDest.wide, src1, src2);
   defineValue(cUnit, res, rlDest.origSReg);
 }
@@ -479,13 +479,7 @@
   // Insert the optimization flags
   args.push_back(cUnit->irb->getInt32(info->optFlags));
   // Now, insert the actual arguments
-  if (cUnit->printMe) {
-    LOG(INFO) << "Building Invoke info";
-  }
   for (int i = 0; i < info->numArgWords;) {
-    if (cUnit->printMe) {
-      oatDumpRegLoc(info->args[i]);
-    }
     llvm::Value* val = getLLVMValue(cUnit, info->args[i].origSReg);
     args.push_back(val);
     i += info->args[i].wide ? 2 : 1;
@@ -1344,39 +1338,39 @@
     case Instruction::IGET:
       if (rlDest.fp) {
         convertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGetFloat,
-                    rlSrc[0], rlSrc[1], vC);
+                    rlDest, rlSrc[0], vC);
       } else {
         convertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGet,
-                    rlSrc[0], rlSrc[1], vC);
+                    rlDest, rlSrc[0], vC);
       }
       break;
     case Instruction::IGET_OBJECT:
       convertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGetObject,
-                  rlSrc[0], rlSrc[1], vC);
+                  rlDest, rlSrc[0], vC);
       break;
     case Instruction::IGET_BOOLEAN:
       convertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGetBoolean,
-                  rlSrc[0], rlSrc[1], vC);
+                  rlDest, rlSrc[0], vC);
       break;
     case Instruction::IGET_BYTE:
       convertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGetByte,
-                  rlSrc[0], rlSrc[1], vC);
+                  rlDest, rlSrc[0], vC);
       break;
     case Instruction::IGET_CHAR:
       convertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGetChar,
-                  rlSrc[0], rlSrc[1], vC);
+                  rlDest, rlSrc[0], vC);
       break;
     case Instruction::IGET_SHORT:
       convertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGetShort,
-                  rlSrc[0], rlSrc[1], vC);
+                  rlDest, rlSrc[0], vC);
       break;
     case Instruction::IGET_WIDE:
       if (rlDest.fp) {
         convertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGetDouble,
-                    rlSrc[0], rlSrc[1], vC);
+                    rlDest, rlSrc[0], vC);
       } else {
         convertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGetWide,
-                    rlSrc[0], rlSrc[1], vC);
+                    rlDest, rlSrc[0], vC);
       }
       break;
     case Instruction::IPUT:
@@ -1710,10 +1704,32 @@
   return false;
 }
 
+char remapShorty(char shortyType) {
+  /*
+   * TODO: might want to revisit this.  Dalvik registers are 32-bits wide,
+   * and longs/doubles are represented as a pair of registers.  When sub-word
+   * arguments (and method results) are passed, they are extended to Dalvik
+   * virtual register containers.  Because llvm is picky about type consistency,
+   * we must either cast the "real" type to 32-bit container multiple Dalvik
+   * register types, or always use the expanded values.
+   * Here, we're doing the latter.  We map the shorty signature to container
+   * types (which is valid so long as we always do a real expansion of passed
+   * arguments and field loads).
+   */
+  switch(shortyType) {
+    case 'Z' : shortyType = 'I'; break;
+    case 'B' : shortyType = 'I'; break;
+    case 'S' : shortyType = 'I'; break;
+    case 'C' : shortyType = 'I'; break;
+    default: break;
+  }
+  return shortyType;
+}
+
 llvm::FunctionType* getFunctionType(CompilationUnit* cUnit) {
 
   // Get return type
-  llvm::Type* ret_type = cUnit->irb->GetJType(cUnit->shorty[0],
+  llvm::Type* ret_type = cUnit->irb->GetJType(remapShorty(cUnit->shorty[0]),
                                               greenland::kAccurate);
 
   // Get argument type
@@ -1728,7 +1744,7 @@
   }
 
   for (uint32_t i = 1; i < strlen(cUnit->shorty); ++i) {
-    args_type.push_back(cUnit->irb->GetJType(cUnit->shorty[i],
+    args_type.push_back(cUnit->irb->GetJType(remapShorty(cUnit->shorty[i]),
                                              greenland::kAccurate));
   }
 
@@ -1839,6 +1855,11 @@
       // Recover previously-created argument values
       llvm::Value* argVal = arg_iter++;
       oatInsertGrowableList(cUnit, &cUnit->llvmValues, (intptr_t)argVal);
+      if (cUnit->regLocation[i].wide) {
+        // Skip high half of wide values.
+        oatInsertGrowableList(cUnit, &cUnit->llvmValues, 0);
+        i++;
+      }
     }
   }
   cUnit->irb->CreateBr(cUnit->placeholderBB);
@@ -1987,13 +2008,32 @@
 void cvtBinFPOp(CompilationUnit* cUnit, OpKind op, llvm::Instruction* inst)
 {
   RegLocation rlDest = getLoc(cUnit, inst);
-  RegLocation rlSrc1 = getLoc(cUnit, inst->getOperand(0));
-  RegLocation rlSrc2 = getLoc(cUnit, inst->getOperand(1));
-  Instruction::Code dalvikOp = getDalvikFPOpcode(op, false, rlDest.wide);
-  if (rlDest.wide) {
-    genArithOpDouble(cUnit, dalvikOp, rlDest, rlSrc1, rlSrc2);
+  /*
+   * Normally, we won't ever generate an FP operation with an immediate
+   * operand (not supported in Dex instruction set).  However, the IR builder
+   * may insert them - in particular for createNegFP.  Recognize this case
+   * and deal with it.
+   */
+  llvm::ConstantFP* op1C = llvm::dyn_cast<llvm::ConstantFP>(inst->getOperand(0));
+  llvm::ConstantFP* op2C = llvm::dyn_cast<llvm::ConstantFP>(inst->getOperand(1));
+  DCHECK(op2C == NULL);
+  if ((op1C != NULL) && (op == kOpSub)) {
+    RegLocation rlSrc = getLoc(cUnit, inst->getOperand(1));
+    if (rlDest.wide) {
+      genArithOpDouble(cUnit, Instruction::NEG_DOUBLE, rlDest, rlSrc, rlSrc);
+    } else {
+      genArithOpFloat(cUnit, Instruction::NEG_FLOAT, rlDest, rlSrc, rlSrc);
+    }
   } else {
-    genArithOpFloat(cUnit, dalvikOp, rlDest, rlSrc1, rlSrc2);
+    DCHECK(op1C == NULL);
+    RegLocation rlSrc1 = getLoc(cUnit, inst->getOperand(0));
+    RegLocation rlSrc2 = getLoc(cUnit, inst->getOperand(1));
+    Instruction::Code dalvikOp = getDalvikFPOpcode(op, false, rlDest.wide);
+    if (rlDest.wide) {
+      genArithOpDouble(cUnit, dalvikOp, rlDest, rlSrc1, rlSrc2);
+    } else {
+      genArithOpFloat(cUnit, dalvikOp, rlDest, rlSrc1, rlSrc2);
+    }
   }
 }
 
@@ -2489,7 +2529,7 @@
   RegLocation rlSrc = getLoc(cUnit, callInst->getArgOperand(1));
   RegLocation rlObj = getLoc(cUnit, callInst->getArgOperand(2));
   llvm::ConstantInt* fieldIdx =
-      llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(2));
+      llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(3));
   genIPut(cUnit, fieldIdx->getZExtValue(), optFlags->getZExtValue(),
           size, rlSrc, rlObj, isWide, isObj);
 }
@@ -2541,9 +2581,6 @@
   info->optFlags = optFlagsVal->getZExtValue();
   info->offset = cUnit->currentDalvikOffset;
 
-  // FIXME - rework such that we no longer need isRange
-  info->isRange = false;
-
   // Count the argument words, and then build argument array.
   info->numArgWords = 0;
   for (unsigned int i = 3; i < callInst->getNumArgOperands(); i++) {
@@ -2555,9 +2592,6 @@
   // Now, fill in the location records, synthesizing high loc of wide vals
   for (int i = 3, next = 0; next < info->numArgWords;) {
     info->args[next] = getLoc(cUnit, callInst->getArgOperand(i++));
-    if (cUnit->printMe) {
-      oatDumpRegLoc(info->args[next]);
-    }
     if (info->args[next].wide) {
       next++;
       // TODO: Might make sense to mark this as an invalid loc
@@ -2566,6 +2600,9 @@
     }
     next++;
   }
+  // TODO - rework such that we no longer need isRange
+  info->isRange = (info->numArgWords > 5);
+
   if (isFilledNewArray) {
     genFilledNewArray(cUnit, info);
   } else {
diff --git a/src/greenland/intrinsic_func_list.def b/src/greenland/intrinsic_func_list.def
index 084d09c..608e760 100644
--- a/src/greenland/intrinsic_func_list.def
+++ b/src/greenland/intrinsic_func_list.def
@@ -175,7 +175,7 @@
 _EVAL_DEF_INTRINSICS_FUNC(InstanceOf,
                           dex_lang_instance_of,
                           kAttrNone,
-                          kInt1Ty,
+                          kInt32Ty,
                           _EXPAND_ARG2(kInt32Ty, kJavaObjectTy))
 
 //----------------------------------------------------------------------------
@@ -686,7 +686,7 @@
                           kInt32Ty,
                           _EXPAND_ARG3(kInt32Ty, kJavaObjectTy, kInt32Ty))
 
-// void dex_lang_iput_[type](int optFlags, [type] value, JavaObject* ojb, uint32_t field_idx)
+// void dex_lang_iput_[type](int optFlags, [type] value, JavaObject* obj, uint32_t field_idx)
 _EVAL_DEF_INTRINSICS_FUNC(HLIPut,
                           dex_lang_hl_iput,
                           kAttrNoThrow,