diff options
author | 2012-06-22 13:52:12 -0700 | |
---|---|---|
committer | 2012-06-26 11:27:36 -0700 | |
commit | 4f1181fe061d3529f72e1237e7662bf9bc73c6e2 (patch) | |
tree | ea4044920632370d170a8b1c37ec4729ceb859f4 /src/compiler/codegen/MethodBitcode.cc | |
parent | 147440427984816b6ed5235a9b1fb2cbf99496d0 (diff) |
Quick compiler: support for 006, 012, 013, 017
Continued fleshing out of the Quick compiler. With this CL,
we're passing run-tests 006, 012, 013 and 017. Note minor
changes to the tests to allow for easy identification of methods
we want to run through the Quick path. Also, set up by default
now to dump bitcode file to /sdcard/Bitcode/
Change-Id: I77ec73a87a21064273567802ddb44c4fdf71f9fd
Diffstat (limited to 'src/compiler/codegen/MethodBitcode.cc')
-rw-r--r-- | src/compiler/codegen/MethodBitcode.cc | 228 |
1 files changed, 186 insertions, 42 deletions
diff --git a/src/compiler/codegen/MethodBitcode.cc b/src/compiler/codegen/MethodBitcode.cc index f162576ac4..1c4fdf4640 100644 --- a/src/compiler/codegen/MethodBitcode.cc +++ b/src/compiler/codegen/MethodBitcode.cc @@ -60,17 +60,17 @@ llvm::Type* llvmTypeFromLocRec(CompilationUnit* cUnit, RegLocation loc) 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 @@ void createLocFromValue(CompilationUnit* cUnit, llvm::Value* val) // 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 @@ void createLocFromValue(CompilationUnit* cUnit, llvm::Value* val) 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 @@ const char* llvmSSAName(CompilationUnit* cUnit, int ssaReg) { 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 @@ llvm::Value* emitConst(CompilationUnit* cUnit, llvm::ArrayRef<llvm::Value*> src, } 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 @@ llvm::Value* emitCopy(CompilationUnit* cUnit, llvm::ArrayRef<llvm::Value*> src, } 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 @@ llvm::Value* genArithOp(CompilationUnit* cUnit, OpKind op, bool isLong, 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 @@ void convertFPArithOp(CompilationUnit* cUnit, OpKind op, RegLocation rlDest, 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 @@ void convertFPArithOp(CompilationUnit* cUnit, OpKind op, RegLocation rlDest, 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 @@ void convertConstString(CompilationUnit* cUnit, BasicBlock* bb, 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 @@ bool convertMIRNode(CompilationUnit* cUnit, MIR* mir, BasicBlock* bb, 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 @@ bool convertMIRNode(CompilationUnit* cUnit, MIR* mir, BasicBlock* bb, 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 @@ bool convertMIRNode(CompilationUnit* cUnit, MIR* mir, BasicBlock* bb, 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 @@ bool convertMIRNode(CompilationUnit* cUnit, MIR* mir, BasicBlock* bb, convertConstString(cUnit, bb, vB, rlDest); break; + case Instruction::NEW_INSTANCE: + convertNewInstance(cUnit, bb, vB, rlDest); + break; + #if 0 @@ -850,10 +904,6 @@ bool convertMIRNode(CompilationUnit* cUnit, MIR* mir, BasicBlock* bb, 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 @@ void oatMethodMIR2Bitcode(CompilationUnit* cUnit) 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 @@ RegLocation getLoc(CompilationUnit* cUnit, llvm::Value* val) { 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 @@ RegLocation getLoc(CompilationUnit* cUnit, llvm::Value* val) { 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 @@ Instruction::Code getDalvikOpcode(OpKind op, bool isConst, bool isWide) 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 getCond(llvm::ICmpInst::Predicate llvmCond) { 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 cvtCall(CompilationUnit* cUnit, llvm::CallInst* callInst, 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 @@ void cvtCopy(CompilationUnit* cUnit, llvm::CallInst* callInst) // 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 cvtConst(CompilationUnit* cUnit, llvm::CallInst* callInst) 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 @@ void cvtConstString(CompilationUnit* cUnit, llvm::CallInst* callInst) 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 @@ void cvtInvoke(CompilationUnit* cUnit, llvm::CallInst* callInst, 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 @@ bool methodBitcodeBlockCodeGen(CompilationUnit* cUnit, llvm::BasicBlock* bb) 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 @@ bool methodBitcodeBlockCodeGen(CompilationUnit* cUnit, llvm::BasicBlock* bb) 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 @@ bool methodBitcodeBlockCodeGen(CompilationUnit* cUnit, llvm::BasicBlock* bb) 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 @@ bool methodBitcodeBlockCodeGen(CompilationUnit* cUnit, llvm::BasicBlock* bb) case llvm::Instruction::Switch: case llvm::Instruction::FCmp: UNIMPLEMENTED(FATAL) << "Unimplemented llvm opcode: " << opcode; break; + break; case llvm::Instruction::URem: case llvm::Instruction::UDiv: |