Merge "Increase use of ScopedJniThreadState." into ics-mr1-plus-art
diff --git a/src/compiler/Frontend.cc b/src/compiler/Frontend.cc
index 3d6e983..34798f9 100644
--- a/src/compiler/Frontend.cc
+++ b/src/compiler/Frontend.cc
@@ -757,8 +757,13 @@
   cUnit->numRegs = code_item->registers_size_ - cUnit->numIns;
   cUnit->numOuts = code_item->outs_size_;
 #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("HelloWorld") != std::string::npos)
+      || (PrettyMethod(method_idx, dex_file).find("count10_006") != 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("float_017") != std::string::npos)
      ) {
     cUnit->genBitcode = true;
   }
@@ -781,6 +786,8 @@
   if (cUnit->genBitcode) {
     cUnit->printMe = true;
     cUnit->enableDebug |= (1 << kDebugDumpBitcodeFile);
+    // Disable non-safe optimizations for now
+    cUnit->disableOpt |= ~(1 << kSafeOptimizations);
   }
 #endif
   if (cUnit->instructionSet == kX86) {
diff --git a/src/compiler/codegen/MethodBitcode.cc b/src/compiler/codegen/MethodBitcode.cc
index f162576..1c4fdf4 100644
--- a/src/compiler/codegen/MethodBitcode.cc
+++ b/src/compiler/codegen/MethodBitcode.cc
@@ -60,17 +60,17 @@
   llvm::Type* res = NULL;
   if (loc.wide) {
     if (loc.fp)
-        res = cUnit->irb->GetJDoubleTy();
+        res = cUnit->irb->getDoubleTy();
     else
-        res = cUnit->irb->GetJLongTy();
+        res = cUnit->irb->getInt64Ty();
   } else {
     if (loc.fp) {
-      res = cUnit->irb->GetJFloatTy();
+      res = cUnit->irb->getFloatTy();
     } else {
       if (loc.ref)
         res = cUnit->irb->GetJObjectTy();
       else
-        res = cUnit->irb->GetJIntTy();
+        res = cUnit->irb->getInt32Ty();
     }
   }
   return res;
@@ -82,9 +82,6 @@
   // NOTE: llvm takes shortcuts with c_str() - get to std::string firstt
   std::string s(val->getName().str());
   const char* valName = s.c_str();
-  if (cUnit->printMe) {
-    LOG(INFO) << "Processing llvm Value " << valName;
-  }
   SafeMap<llvm::Value*, RegLocation>::iterator it = cUnit->locMap.find(val);
   DCHECK(it == cUnit->locMap.end()) << " - already defined: " << valName;
   int baseSReg = INVALID_SREG;
@@ -94,9 +91,6 @@
     baseSReg = SSA_METHOD_BASEREG;
     subscript = 0;
   }
-  if (cUnit->printMe) {
-    LOG(INFO) << "Base: " << baseSReg << ", Sub: " << subscript;
-  }
   DCHECK_NE(baseSReg, INVALID_SREG);
   DCHECK_NE(subscript, -1);
   // TODO: redo during C++'ification
@@ -146,6 +140,14 @@
   return GET_ELEM_N(cUnit->ssaStrings, char*, ssaReg);
 }
 
+llvm::Value* emitSget(CompilationUnit* cUnit,
+                      greenland::IntrinsicHelper::IntrinsicId id,
+                      llvm::ArrayRef<llvm::Value*> src, RegLocation Loc)
+{
+  llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
+  return cUnit->irb->CreateCall(intr, src);
+}
+
 llvm::Value* emitConst(CompilationUnit* cUnit, llvm::ArrayRef<llvm::Value*> src,
                        RegLocation loc)
 {
@@ -159,7 +161,7 @@
   } else {
     if (loc.fp) {
       id = greenland::IntrinsicHelper::ConstFloat;
-    } if (loc.ref) {
+    } else if (loc.ref) {
       id = greenland::IntrinsicHelper::ConstObj;
     } else {
       id = greenland::IntrinsicHelper::ConstInt;
@@ -191,7 +193,7 @@
   } else {
     if (loc.fp) {
       id = greenland::IntrinsicHelper::CopyFloat;
-    } if (loc.ref) {
+    } else if (loc.ref) {
       id = greenland::IntrinsicHelper::CopyObj;
     } else {
       id = greenland::IntrinsicHelper::CopyInt;
@@ -292,15 +294,16 @@
   switch(op) {
     case kOpAdd: res = cUnit->irb->CreateAdd(src1, src2); break;
     case kOpSub: res = cUnit->irb->CreateSub(src1, src2); break;
+    case kOpRsub: res = cUnit->irb->CreateSub(src2, src1); break;
     case kOpMul: res = cUnit->irb->CreateMul(src1, src2); break;
     case kOpOr: res = cUnit->irb->CreateOr(src1, src2); break;
     case kOpAnd: res = cUnit->irb->CreateAnd(src1, src2); break;
     case kOpXor: res = cUnit->irb->CreateXor(src1, src2); break;
     case kOpDiv: res = genDivModOp(cUnit, true, isLong, src1, src2); break;
     case kOpRem: res = genDivModOp(cUnit, false, isLong, src1, src2); break;
-    case kOpLsl: UNIMPLEMENTED(FATAL) << "Need Lsl"; break;
-    case kOpLsr: UNIMPLEMENTED(FATAL) << "Need Lsr"; break;
-    case kOpAsr: UNIMPLEMENTED(FATAL) << "Need Asr"; break;
+    case kOpLsl: res = cUnit->irb->CreateShl(src1, src2); break;
+    case kOpLsr: res = cUnit->irb->CreateLShr(src1, src2); break;
+    case kOpAsr: res = cUnit->irb->CreateAShr(src1, src2); break;
     default:
       LOG(FATAL) << "Invalid op " << op;
   }
@@ -313,6 +316,7 @@
   llvm::Value* src1 = getLLVMValue(cUnit, rlSrc1.origSReg);
   llvm::Value* src2 = getLLVMValue(cUnit, rlSrc2.origSReg);
   llvm::Value* res = NULL;
+LOG(INFO) << "in convertFPArithOp";
   switch(op) {
     case kOpAdd: res = cUnit->irb->CreateFAdd(src1, src2); break;
     case kOpSub: res = cUnit->irb->CreateFSub(src1, src2); break;
@@ -325,6 +329,25 @@
   defineValue(cUnit, res, rlDest.origSReg);
 }
 
+void convertShift(CompilationUnit* cUnit, OpKind op, RegLocation rlDest,
+                  RegLocation rlSrc1, RegLocation rlSrc2)
+{
+  llvm::Value* src1 = getLLVMValue(cUnit, rlSrc1.origSReg);
+  llvm::Value* src2a = getLLVMValue(cUnit, rlSrc2.origSReg);
+  llvm::Value* src2b;
+  // Limit shift counnt to 63 for long and 31 for int
+  if (rlDest.wide) {
+    // Note: creates 2 unnamed temps
+    llvm::Value* t1 = cUnit->irb->CreateAnd(src2a, 0x3f);
+    src2b = cUnit->irb->CreateZExt(t1, cUnit->irb->getInt64Ty());
+  } else {
+    // Note: creates 1 unnamed temp
+    src2b = cUnit->irb->CreateAnd(src2a, 0x1f);
+  }
+  llvm::Value* res = genArithOp(cUnit, op, rlDest.wide, src1, src2b);
+  defineValue(cUnit, res, rlDest.origSReg);
+}
+
 void convertArithOp(CompilationUnit* cUnit, OpKind op, RegLocation rlDest,
                     RegLocation rlSrc1, RegLocation rlSrc2)
 {
@@ -427,6 +450,17 @@
   defineValue(cUnit, res, rlDest.origSReg);
 }
 
+void convertNewInstance(CompilationUnit* cUnit, BasicBlock* bb,
+                        uint32_t type_idx, RegLocation rlDest)
+{
+  greenland::IntrinsicHelper::IntrinsicId id;
+  id = greenland::IntrinsicHelper::NewInstance;
+  llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
+  llvm::Value* index = cUnit->irb->getInt32(type_idx);
+  llvm::Value* res = cUnit->irb->CreateCall(intr, index);
+  defineValue(cUnit, res, rlDest.origSReg);
+}
+
 /*
  * Target-independent code generation.  Use only high-level
  * load/store utilities here, or target-dependent genXX() handlers
@@ -540,13 +574,23 @@
             cUnit->irb->GetJLong(mir->dalvikInsn.vB_wide);
         llvm::Value* res = emitConst(cUnit, immValue, rlDest);
         defineValue(cUnit, res, rlDest.origSReg);
-    }
+      }
+      break;
     case Instruction::CONST_WIDE_HIGH16: {
         int64_t imm = static_cast<int64_t>(vB) << 48;
         llvm::Constant* immValue = cUnit->irb->GetJLong(imm);
         llvm::Value* res = emitConst(cUnit, immValue, rlDest);
         defineValue(cUnit, res, rlDest.origSReg);
-    }
+      }
+      break;
+
+    case Instruction::SGET_OBJECT: {
+        llvm::Constant* fieldIdx = cUnit->irb->GetJInt(vB);
+        llvm::Value* res = emitSget(cUnit, greenland::IntrinsicHelper::SgetObj,
+                                    fieldIdx, rlDest);
+        defineValue(cUnit, res, rlDest.origSReg);
+      }
+      break;
 
     case Instruction::RETURN_WIDE:
     case Instruction::RETURN:
@@ -667,21 +711,27 @@
       break;
     case Instruction::SHL_LONG:
     case Instruction::SHL_LONG_2ADDR:
+      convertShift(cUnit, kOpLsl, rlDest, rlSrc[0], rlSrc[1]);
+      break;
     case Instruction::SHL_INT:
     case Instruction::SHL_INT_2ADDR:
-      convertArithOp(cUnit, kOpLsl, rlDest, rlSrc[0], rlSrc[1]);
+      convertShift(cUnit, kOpLsl, rlDest, rlSrc[0], rlSrc[1]);
       break;
     case Instruction::SHR_LONG:
     case Instruction::SHR_LONG_2ADDR:
+      convertShift(cUnit, kOpAsr, rlDest, rlSrc[0], rlSrc[1]);
+      break;
     case Instruction::SHR_INT:
     case Instruction::SHR_INT_2ADDR:
-      convertArithOp(cUnit, kOpAsr, rlDest, rlSrc[0], rlSrc[1]);
+      convertShift(cUnit, kOpAsr, rlDest, rlSrc[0], rlSrc[1]);
       break;
     case Instruction::USHR_LONG:
     case Instruction::USHR_LONG_2ADDR:
+      convertShift(cUnit, kOpLsr, rlDest, rlSrc[0], rlSrc[1]);
+      break;
     case Instruction::USHR_INT:
     case Instruction::USHR_INT_2ADDR:
-      convertArithOp(cUnit, kOpLsr, rlDest, rlSrc[0], rlSrc[1]);
+      convertShift(cUnit, kOpLsr, rlDest, rlSrc[0], rlSrc[1]);
       break;
 
     case Instruction::ADD_INT_LIT16:
@@ -717,13 +767,13 @@
       convertArithOpLit(cUnit, kOpXor, rlDest, rlSrc[0], vC);
       break;
     case Instruction::SHL_INT_LIT8:
-      convertArithOpLit(cUnit, kOpLsl, rlDest, rlSrc[0], vC);
+      convertArithOpLit(cUnit, kOpLsl, rlDest, rlSrc[0], vC & 0x1f);
       break;
     case Instruction::SHR_INT_LIT8:
-      convertArithOpLit(cUnit, kOpLsr, rlDest, rlSrc[0], vC);
+      convertArithOpLit(cUnit, kOpLsr, rlDest, rlSrc[0], vC & 0x1f);
       break;
     case Instruction::USHR_INT_LIT8:
-      convertArithOpLit(cUnit, kOpAsr, rlDest, rlSrc[0], vC);
+      convertArithOpLit(cUnit, kOpAsr, rlDest, rlSrc[0], vC & 0x1f);
       break;
 
     case Instruction::ADD_FLOAT:
@@ -801,6 +851,10 @@
       convertConstString(cUnit, bb, vB, rlDest);
       break;
 
+    case Instruction::NEW_INSTANCE:
+      convertNewInstance(cUnit, bb, vB, rlDest);
+      break;
+
 
 #if 0
 
@@ -850,10 +904,6 @@
       genInstanceof(cUnit, mir, rlDest, rlSrc[0]);
       break;
 
-    case Instruction::NEW_INSTANCE:
-      genNewInstance(cUnit, mir, rlDest);
-      break;
-
     case Instruction::THROW:
       genThrow(cUnit, mir, rlSrc[0]);
       break;
@@ -1423,7 +1473,7 @@
     std::string fname(PrettyMethod(cUnit->method_idx, *cUnit->dex_file));
     oatReplaceSpecialChars(fname);
     // TODO: make configurable
-    fname = StringPrintf("/tmp/%s.bc", fname.c_str());
+    fname = StringPrintf("/sdcard/Bitcode/%s.bc", fname.c_str());
 
     llvm::OwningPtr<llvm::tool_output_file> out_file(
         new llvm::tool_output_file(fname.c_str(), errmsg,
@@ -1443,7 +1493,7 @@
   DCHECK(val != NULL);
   SafeMap<llvm::Value*, RegLocation>::iterator it = cUnit->locMap.find(val);
   if (it == cUnit->locMap.end()) {
-    std::string valName(val->getName().str());
+    std::string valName = val->getName().str();
     DCHECK(!valName.empty());
     if (valName[0] == 'v') {
       int baseSReg = INVALID_SREG;
@@ -1451,8 +1501,14 @@
       res = cUnit->regLocation[baseSReg];
       cUnit->locMap.Put(val, res);
     } else {
-      UNIMPLEMENTED(WARNING) << "Need to handle llvm temps";
-      DCHECK_EQ(valName[0], 't');
+      UNIMPLEMENTED(WARNING) << "Need to handle unnamed llvm temps";
+      memset(&res, 0, sizeof(res));
+      res.location = kLocPhysReg;
+      res.lowReg = oatAllocTemp(cUnit);
+      res.home = true;
+      res.sRegLow = INVALID_SREG;
+      res.origSReg = INVALID_SREG;
+      cUnit->locMap.Put(val, res);
     }
   } else {
     res = it->second;
@@ -1512,11 +1568,57 @@
   return res;
 }
 
+Instruction::Code getDalvikFPOpcode(OpKind op, bool isConst, bool isWide)
+{
+  Instruction::Code res = Instruction::NOP;
+  if (isWide) {
+    switch(op) {
+      case kOpAdd: res = Instruction::ADD_DOUBLE; break;
+      case kOpSub: res = Instruction::SUB_DOUBLE; break;
+      case kOpMul: res = Instruction::MUL_DOUBLE; break;
+      case kOpDiv: res = Instruction::DIV_DOUBLE; break;
+      case kOpRem: res = Instruction::REM_DOUBLE; break;
+      default: LOG(FATAL) << "Unexpected OpKind " << op;
+    }
+  } else {
+    switch(op) {
+      case kOpAdd: res = Instruction::ADD_FLOAT; break;
+      case kOpSub: res = Instruction::SUB_FLOAT; break;
+      case kOpMul: res = Instruction::MUL_FLOAT; break;
+      case kOpDiv: res = Instruction::DIV_FLOAT; break;
+      case kOpRem: res = Instruction::REM_FLOAT; break;
+      default: LOG(FATAL) << "Unexpected OpKind " << op;
+    }
+  }
+  return res;
+}
+
+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);
+  } else {
+    genArithOpFloat(cUnit, dalvikOp, rlDest, rlSrc1, rlSrc2);
+  }
+}
+
 void cvtBinOp(CompilationUnit* cUnit, OpKind op, llvm::Instruction* inst)
 {
   RegLocation rlDest = getLoc(cUnit, inst);
   llvm::Value* lhs = inst->getOperand(0);
-  DCHECK(llvm::dyn_cast<llvm::ConstantInt>(lhs) == NULL);
+  // Special-case RSUB
+  llvm::ConstantInt* lhsImm = llvm::dyn_cast<llvm::ConstantInt>(lhs);
+  if ((op == kOpSub) && (lhsImm != NULL)) {
+    RegLocation rlSrc1 = getLoc(cUnit, inst->getOperand(1));
+    genArithOpIntLit(cUnit, Instruction::RSUB_INT, rlDest, rlSrc1,
+                     lhsImm->getSExtValue());
+    return;
+  }
+  DCHECK(lhsImm == NULL);
   RegLocation rlSrc1 = getLoc(cUnit, inst->getOperand(0));
   llvm::Value* rhs = inst->getOperand(1);
   if (llvm::ConstantInt* src2 = llvm::dyn_cast<llvm::ConstantInt>(rhs)) {
@@ -1566,9 +1668,12 @@
 {
   ConditionCode res = kCondAl;
   switch(llvmCond) {
-    case llvm::ICmpInst::ICMP_NE: res = kCondNe; break;
     case llvm::ICmpInst::ICMP_EQ: res = kCondEq; break;
+    case llvm::ICmpInst::ICMP_NE: res = kCondNe; break;
+    case llvm::ICmpInst::ICMP_SLT: res = kCondLt; break;
+    case llvm::ICmpInst::ICMP_SGE: res = kCondGe; break;
     case llvm::ICmpInst::ICMP_SGT: res = kCondGt; break;
+    case llvm::ICmpInst::ICMP_SLE: res = kCondLe; break;
     default: LOG(FATAL) << "Unexpected llvm condition";
   }
   return res;
@@ -1627,7 +1732,7 @@
 
 void cvtCopy(CompilationUnit* cUnit, llvm::CallInst* callInst)
 {
-  DCHECK_EQ(callInst->getNumArgOperands(), 1);
+  DCHECK_EQ(callInst->getNumArgOperands(), 1U);
   RegLocation rlSrc = getLoc(cUnit, callInst->getArgOperand(0));
   RegLocation rlDest = getLoc(cUnit, callInst);
   if (rlSrc.wide) {
@@ -1640,7 +1745,7 @@
 // Note: Immediate arg is a ConstantInt regardless of result type
 void cvtConst(CompilationUnit* cUnit, llvm::CallInst* callInst)
 {
-  DCHECK_EQ(callInst->getNumArgOperands(), 1);
+  DCHECK_EQ(callInst->getNumArgOperands(), 1U);
   llvm::ConstantInt* src =
       llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
   uint64_t immval = src->getZExtValue();
@@ -1658,7 +1763,7 @@
 
 void cvtConstString(CompilationUnit* cUnit, llvm::CallInst* callInst)
 {
-  DCHECK_EQ(callInst->getNumArgOperands(), 1);
+  DCHECK_EQ(callInst->getNumArgOperands(), 1U);
   llvm::ConstantInt* stringIdxVal =
       llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
   uint32_t stringIdx = stringIdxVal->getZExtValue();
@@ -1666,6 +1771,27 @@
   genConstString(cUnit, stringIdx, rlDest);
 }
 
+void cvtNewInstance(CompilationUnit* cUnit, llvm::CallInst* callInst)
+{
+  DCHECK(callInst->getNumArgOperands() == 1);
+  llvm::ConstantInt* typeIdxVal =
+      llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
+  uint32_t typeIdx = typeIdxVal->getZExtValue();
+  RegLocation rlDest = getLoc(cUnit, callInst);
+  genNewInstance(cUnit, typeIdx, rlDest);
+}
+
+void cvtSget(CompilationUnit* cUnit, llvm::CallInst* callInst, bool isWide,
+             bool isObject)
+{
+  DCHECK(callInst->getNumArgOperands() == 1);
+  llvm::ConstantInt* typeIdxVal =
+      llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
+  uint32_t typeIdx = typeIdxVal->getZExtValue();
+  RegLocation rlDest = getLoc(cUnit, callInst);
+  genSget(cUnit, typeIdx, rlDest, isWide, isObject);
+}
+
 void cvtInvoke(CompilationUnit* cUnit, llvm::CallInst* callInst,
                greenland::JType jtype)
 {
@@ -1700,7 +1826,7 @@
       oatNew(cUnit, sizeof(RegLocation) * info->numArgWords, false, kAllocMisc);
   // 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));
+    info->args[next] = getLoc(cUnit, callInst->getArgOperand(i++));
     if (cUnit->printMe) {
       oatDumpRegLoc(info->args[next]);
     }
@@ -1843,6 +1969,14 @@
             case greenland::IntrinsicHelper::ConstDouble:
               cvtConst(cUnit, callInst);
               break;
+            case greenland::IntrinsicHelper::DivInt:
+            case greenland::IntrinsicHelper::DivLong:
+              cvtBinOp(cUnit, kOpDiv, inst);
+              break;
+            case greenland::IntrinsicHelper::RemInt:
+            case greenland::IntrinsicHelper::RemLong:
+              cvtBinOp(cUnit, kOpRem, inst);
+              break;
             case greenland::IntrinsicHelper::MethodInfo:
               // Already dealt with - just ignore it here.
               break;
@@ -1852,12 +1986,21 @@
             case greenland::IntrinsicHelper::HLInvokeInt:
               cvtInvoke(cUnit, callInst, greenland::kInt);
               break;
+            case greenland::IntrinsicHelper::HLInvokeObj:
+              cvtInvoke(cUnit, callInst, greenland::kObject);
+              break;
             case greenland::IntrinsicHelper::HLInvokeVoid:
               cvtInvoke(cUnit, callInst, greenland::kVoid);
               break;
             case greenland::IntrinsicHelper::ConstString:
               cvtConstString(cUnit, callInst);
               break;
+            case greenland::IntrinsicHelper::NewInstance:
+              cvtNewInstance(cUnit, callInst);
+              break;
+            case greenland::IntrinsicHelper::SgetObj:
+              cvtSget(cUnit, callInst, false /* wide */, true /* Object */);
+              break;
             case greenland::IntrinsicHelper::UnknownId:
               cvtCall(cUnit, callInst, callee);
               break;
@@ -1882,13 +2025,13 @@
       case llvm::Instruction::AShr: cvtBinOp(cUnit, kOpAsr, inst); break;
       case llvm::Instruction::PHI: cvtPhi(cUnit, inst); break;
       case llvm::Instruction::Ret: cvtRet(cUnit, inst); break;
+      case llvm::Instruction::FAdd: cvtBinFPOp(cUnit, kOpAdd, inst); break;
+      case llvm::Instruction::FSub: cvtBinFPOp(cUnit, kOpSub, inst); break;
+      case llvm::Instruction::FMul: cvtBinFPOp(cUnit, kOpMul, inst); break;
+      case llvm::Instruction::FDiv: cvtBinFPOp(cUnit, kOpDiv, inst); break;
+      case llvm::Instruction::FRem: cvtBinFPOp(cUnit, kOpRem, inst); break;
 
       case llvm::Instruction::Invoke:
-      case llvm::Instruction::FAdd:
-      case llvm::Instruction::FSub:
-      case llvm::Instruction::FMul:
-      case llvm::Instruction::FDiv:
-      case llvm::Instruction::FRem:
       case llvm::Instruction::Trunc:
       case llvm::Instruction::ZExt:
       case llvm::Instruction::SExt:
@@ -1903,6 +2046,7 @@
       case llvm::Instruction::Switch:
       case llvm::Instruction::FCmp:
         UNIMPLEMENTED(FATAL) << "Unimplemented llvm opcode: " << opcode; break;
+        break;
 
       case llvm::Instruction::URem:
       case llvm::Instruction::UDiv:
diff --git a/src/greenland/intrinsic_func_list.def b/src/greenland/intrinsic_func_list.def
index d2e0a17..70f5512 100644
--- a/src/greenland/intrinsic_func_list.def
+++ b/src/greenland/intrinsic_func_list.def
@@ -127,6 +127,17 @@
                           _EXPAND_ARG1(kInt32ConstantTy))
 
 //----------------------------------------------------------------------------
+// New Instance
+//----------------------------------------------------------------------------
+
+// JavaObject* dex_lang_new_instance(uint32_t type_idx)
+_EVAL_DEF_INTRINSICS_FUNC(NewInstance,
+                          dex_lang_new_instance,
+                          kAttrNone,
+                          kJavaObjectTy,
+                          _EXPAND_ARG1(kInt32Ty))
+
+//----------------------------------------------------------------------------
 // Array
 //----------------------------------------------------------------------------
 
@@ -621,6 +632,17 @@
                           _EXPAND_ARG0())
 
 //----------------------------------------------------------------------------
+// sget intrinsics to assist MIR to Greenland_ir conversion.
+//----------------------------------------------------------------------------
+
+// object* sget_obj(int field_idx)
+_EVAL_DEF_INTRINSICS_FUNC(SgetObj,
+                          dex_lang_sget_obj,
+                          kAttrReadOnly | kAttrNoThrow,
+                          kJavaObjectTy,
+                          _EXPAND_ARG1(kInt32Ty))
+
+//----------------------------------------------------------------------------
 // Shadow Frame
 //----------------------------------------------------------------------------
 
@@ -684,7 +706,7 @@
                           kFloatTy,
                           _EXPAND_ARG1(kInt32Ty))
 
-// int copy_double(long)
+// int const_double(long)
 _EVAL_DEF_INTRINSICS_FUNC(ConstDouble,
                           dex_lang_const_Double,
                           kAttrReadOnly | kAttrNoThrow,
diff --git a/test/006-count10/src/Main.java b/test/006-count10/src/Main.java
index 650d053..8fd2947 100644
--- a/test/006-count10/src/Main.java
+++ b/test/006-count10/src/Main.java
@@ -18,9 +18,12 @@
  * Simple loop-and-print
  */
 public class Main {
-    public static void main(String args[]) {
+    public static void count10_006() {
         for (int i = 0; i < 10; i++) {
             System.out.println(i);
         }
     }
+    public static void main(String args[]) {
+        count10_006();
+    }
 }
diff --git a/test/012-math/src/Main.java b/test/012-math/src/Main.java
index 87ea40b..a4a8c71 100644
--- a/test/012-math/src/Main.java
+++ b/test/012-math/src/Main.java
@@ -18,7 +18,7 @@
  * test simple math opers
  */
 public class Main {
-    public static void main(String args[]) {
+    public static void math_012() {
         int pad0, pad1, pad2, pad3, pad4, pad5, pad6, pad7;
         int pad8, pad9, pad10, pad11, pad12, pad13, pad14, pad15;
         int a, b, res;
@@ -99,4 +99,7 @@
         f %= g;
         System.out.println("f:" +f);
     }
+    public static void main(String args[]) {
+      math_012();
+    }
 }
diff --git a/test/013-math2/src/Main.java b/test/013-math2/src/Main.java
index 819571d..2c80c31 100644
--- a/test/013-math2/src/Main.java
+++ b/test/013-math2/src/Main.java
@@ -18,7 +18,7 @@
  * test add by a 16-bit constant
  */
 public class Main {
-    public static void main(String args[]) {
+    public static void math_013() {
         int a, b, res;
 
         a = 3;
@@ -28,4 +28,7 @@
         a += 32000;
         System.out.println("a:" +a);
     }
+    public static void main(String args[]) {
+        math_013();
+    }
 }
diff --git a/test/017-float/src/Main.java b/test/017-float/src/Main.java
index a5dbe1e..83fa2ee 100644
--- a/test/017-float/src/Main.java
+++ b/test/017-float/src/Main.java
@@ -18,7 +18,7 @@
  * I dont know what this test does.
  */
 public class Main {
-    public static void main(String args[]) {
+    public static void float_017() {
         float f = 3.1415926535f;
         double d = 3.1415926535;
         //float fd = (float) d;
@@ -30,4 +30,7 @@
         //System.out.println("object values: off="
         //    + off.floatValue() + " ofd=" + ofd.floatValue());
     }
+    public static void main(String args[]) {
+        float_017();
+    }
 }