Quick compiler: conversions, bug fixes
Added support for the remaining conversions, misc. bugs fixed. Still
left is switch support, rework of type handling and lots of bug
fixes.
Change-Id: Ib370a4176555d628f222e35776e0b3f0be8de0c4
diff --git a/src/compiler/Frontend.cc b/src/compiler/Frontend.cc
index 140f681..d617be5 100644
--- a/src/compiler/Frontend.cc
+++ b/src/compiler/Frontend.cc
@@ -759,6 +759,11 @@
#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)
@@ -775,6 +780,7 @@
|| (PrettyMethod(method_idx, dex_file).find("shiftTest1") != std::string::npos)
|| (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)
) {
cUnit->genBitcode = true;
}
diff --git a/src/compiler/codegen/MethodBitcode.cc b/src/compiler/codegen/MethodBitcode.cc
index 92cc6cc..cd4e1d3 100644
--- a/src/compiler/codegen/MethodBitcode.cc
+++ b/src/compiler/codegen/MethodBitcode.cc
@@ -254,14 +254,16 @@
cUnit->irb->CreateCall(func, args);
}
-void convertArrayLength(CompilationUnit* cUnit, int optFlags, RegLocation rlSrc)
+void convertArrayLength(CompilationUnit* cUnit, int optFlags,
+ RegLocation rlDest, RegLocation rlSrc)
{
llvm::SmallVector<llvm::Value*, 2> args;
args.push_back(cUnit->irb->getInt32(optFlags));
args.push_back(getLLVMValue(cUnit, rlSrc.origSReg));
llvm::Function* func = cUnit->intrinsic_helper->GetIntrinsicFunction(
greenland::IntrinsicHelper::ArrayLength);
- cUnit->irb->CreateCall(func, args);
+ llvm::Value* res = cUnit->irb->CreateCall(func, args);
+ defineValue(cUnit, res, rlDest.origSReg);
}
void convertThrowVerificationError(CompilationUnit* cUnit, int info1, int info2)
@@ -287,6 +289,7 @@
llvm::Value* src1, llvm::Value* src2)
{
llvm::Value* res = NULL;
+ DCHECK_EQ(src1->getType(), src2->getType());
switch(cc) {
case kCondEq: res = cUnit->irb->CreateICmpEQ(src1, src2); break;
case kCondNe: res = cUnit->irb->CreateICmpNE(src1, src2); break;
@@ -465,7 +468,7 @@
* The requirements are similar.
*/
void convertInvoke(CompilationUnit* cUnit, BasicBlock* bb, MIR* mir,
- InvokeType invokeType, bool isRange, bool isNewArray)
+ InvokeType invokeType, bool isRange, bool isFilledNewArray)
{
CallInfo* info = oatNewCallInfo(cUnit, bb, mir, invokeType, isRange);
llvm::SmallVector<llvm::Value*, 10> args;
@@ -493,8 +496,8 @@
* is not used, we'll treat this as a void invoke.
*/
greenland::IntrinsicHelper::IntrinsicId id;
- if (isNewArray) {
- id = greenland::IntrinsicHelper::NewArray;
+ if (isFilledNewArray) {
+ id = greenland::IntrinsicHelper::FilledNewArray;
} else if (info->result.location == kLocInvalid) {
id = greenland::IntrinsicHelper::HLInvokeVoid;
} else {
@@ -638,13 +641,92 @@
defineValue(cUnit, res, rlDest.origSReg);
}
+void convertLongToInt(CompilationUnit* cUnit, RegLocation rlDest,
+ RegLocation rlSrc)
+{
+ llvm::Value* src = getLLVMValue(cUnit, rlSrc.origSReg);
+ llvm::Value* res = cUnit->irb->CreateTrunc(src, cUnit->irb->getInt32Ty());
+ defineValue(cUnit, res, rlDest.origSReg);
+}
+
+void convertFloatToDouble(CompilationUnit* cUnit, RegLocation rlDest,
+ RegLocation rlSrc)
+{
+ llvm::Value* src = getLLVMValue(cUnit, rlSrc.origSReg);
+ llvm::Value* res = cUnit->irb->CreateFPExt(src, cUnit->irb->getDoubleTy());
+ defineValue(cUnit, res, rlDest.origSReg);
+}
+
+void convertDoubleToFloat(CompilationUnit* cUnit, RegLocation rlDest,
+ RegLocation rlSrc)
+{
+ llvm::Value* src = getLLVMValue(cUnit, rlSrc.origSReg);
+ llvm::Value* res = cUnit->irb->CreateFPTrunc(src, cUnit->irb->getFloatTy());
+ defineValue(cUnit, res, rlDest.origSReg);
+}
+
+void convertWideComparison(CompilationUnit* cUnit,
+ greenland::IntrinsicHelper::IntrinsicId id,
+ RegLocation rlDest, RegLocation rlSrc1,
+ RegLocation rlSrc2)
+{
+ DCHECK_EQ(rlSrc1.fp, rlSrc2.fp);
+ DCHECK_EQ(rlSrc1.wide, rlSrc2.wide);
+ llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
+ llvm::SmallVector<llvm::Value*, 2> args;
+ args.push_back(getLLVMValue(cUnit, rlSrc1.origSReg));
+ args.push_back(getLLVMValue(cUnit, rlSrc2.origSReg));
+ llvm::Value* res = cUnit->irb->CreateCall(intr, args);
+ defineValue(cUnit, res, rlDest.origSReg);
+}
+
void convertIntNarrowing(CompilationUnit* cUnit, RegLocation rlDest,
RegLocation rlSrc,
greenland::IntrinsicHelper::IntrinsicId id)
{
llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
- llvm::Value* res = cUnit->irb->CreateCall(intr,
- getLLVMValue(cUnit, rlSrc.origSReg));
+ llvm::Value* res =
+ cUnit->irb->CreateCall(intr, getLLVMValue(cUnit, rlSrc.origSReg));
+ defineValue(cUnit, res, rlDest.origSReg);
+}
+
+void convertNeg(CompilationUnit* cUnit, RegLocation rlDest,
+ RegLocation rlSrc)
+{
+ llvm::Value* res = cUnit->irb->CreateNeg(getLLVMValue(cUnit, rlSrc.origSReg));
+ defineValue(cUnit, res, rlDest.origSReg);
+}
+
+void convertIntToFP(CompilationUnit* cUnit, llvm::Type* ty, RegLocation rlDest,
+ RegLocation rlSrc)
+{
+ llvm::Value* res =
+ cUnit->irb->CreateSIToFP(getLLVMValue(cUnit, rlSrc.origSReg), ty);
+ defineValue(cUnit, res, rlDest.origSReg);
+}
+
+void convertFPToInt(CompilationUnit* cUnit, llvm::Type* ty, RegLocation rlDest,
+ RegLocation rlSrc)
+{
+ llvm::Value* res =
+ cUnit->irb->CreateFPToSI(getLLVMValue(cUnit, rlSrc.origSReg), ty);
+ defineValue(cUnit, res, rlDest.origSReg);
+}
+
+
+void convertNegFP(CompilationUnit* cUnit, RegLocation rlDest,
+ RegLocation rlSrc)
+{
+ llvm::Value* res =
+ cUnit->irb->CreateFNeg(getLLVMValue(cUnit, rlSrc.origSReg));
+ defineValue(cUnit, res, rlDest.origSReg);
+}
+
+void convertNot(CompilationUnit* cUnit, RegLocation rlDest,
+ RegLocation rlSrc)
+{
+ llvm::Value* src = getLLVMValue(cUnit, rlSrc.origSReg);
+ llvm::Value* res = cUnit->irb->CreateXor(src, static_cast<uint64_t>(-1));
defineValue(cUnit, res, rlDest.origSReg);
}
@@ -717,6 +799,7 @@
case Instruction::MOVE_OBJECT:
case Instruction::MOVE_16:
case Instruction::MOVE_OBJECT_16:
+ case Instruction::MOVE_OBJECT_FROM16:
case Instruction::MOVE_FROM16:
case Instruction::MOVE_WIDE:
case Instruction::MOVE_WIDE_16:
@@ -745,7 +828,9 @@
case Instruction::CONST_WIDE_16:
case Instruction::CONST_WIDE_32: {
- llvm::Constant* immValue = cUnit->irb->GetJLong(vB);
+ // Sign extend to 64 bits
+ int64_t imm = static_cast<int32_t>(vB);
+ llvm::Constant* immValue = cUnit->irb->GetJLong(imm);
llvm::Value* res = emitConst(cUnit, immValue, rlDest);
defineValue(cUnit, res, rlDest.origSReg);
}
@@ -774,36 +859,36 @@
break;
case Instruction::SPUT_OBJECT:
- convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSputObject,
+ convertSput(cUnit, vB, greenland::IntrinsicHelper::HLSputObject,
rlSrc[0]);
break;
case Instruction::SPUT:
if (rlSrc[0].fp) {
- convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSputFloat,
+ convertSput(cUnit, vB, greenland::IntrinsicHelper::HLSputFloat,
rlSrc[0]);
} else {
- convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSput, rlSrc[0]);
+ convertSput(cUnit, vB, greenland::IntrinsicHelper::HLSput, rlSrc[0]);
}
break;
case Instruction::SPUT_BOOLEAN:
- convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSputBoolean,
+ convertSput(cUnit, vB, greenland::IntrinsicHelper::HLSputBoolean,
rlSrc[0]);
break;
case Instruction::SPUT_BYTE:
- convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSputByte, rlSrc[0]);
+ convertSput(cUnit, vB, greenland::IntrinsicHelper::HLSputByte, rlSrc[0]);
break;
case Instruction::SPUT_CHAR:
- convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSputChar, rlSrc[0]);
+ convertSput(cUnit, vB, greenland::IntrinsicHelper::HLSputChar, rlSrc[0]);
break;
case Instruction::SPUT_SHORT:
- convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSputShort, rlSrc[0]);
+ convertSput(cUnit, vB, greenland::IntrinsicHelper::HLSputShort, rlSrc[0]);
break;
case Instruction::SPUT_WIDE:
if (rlSrc[0].fp) {
- convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSputDouble,
+ convertSput(cUnit, vB, greenland::IntrinsicHelper::HLSputDouble,
rlSrc[0]);
} else {
- convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSputWide,
+ convertSput(cUnit, vB, greenland::IntrinsicHelper::HLSputWide,
rlSrc[0]);
}
break;
@@ -1161,7 +1246,7 @@
break;
case Instruction::ARRAY_LENGTH:
- convertArrayLength(cUnit, optFlags, rlSrc[0]);
+ convertArrayLength(cUnit, optFlags, rlDest, rlSrc[0]);
break;
case Instruction::NEW_ARRAY:
@@ -1337,6 +1422,10 @@
convertFillArrayData(cUnit, vB, rlSrc[0]);
break;
+ case Instruction::LONG_TO_INT:
+ convertLongToInt(cUnit, rlDest, rlSrc[0]);
+ break;
+
case Instruction::INT_TO_LONG:
convertIntToLong(cUnit, rlDest, rlSrc[0]);
break;
@@ -1354,64 +1443,78 @@
greenland::IntrinsicHelper::IntToShort);
break;
-#if 0
-
- case Instruction::PACKED_SWITCH:
- genPackedSwitch(cUnit, mir, rlSrc[0]);
+ case Instruction::INT_TO_FLOAT:
+ case Instruction::LONG_TO_FLOAT:
+ convertIntToFP(cUnit, cUnit->irb->getFloatTy(), rlDest, rlSrc[0]);
break;
- case Instruction::SPARSE_SWITCH:
- genSparseSwitch(cUnit, mir, rlSrc[0], labelList);
+ case Instruction::INT_TO_DOUBLE:
+ case Instruction::LONG_TO_DOUBLE:
+ convertIntToFP(cUnit, cUnit->irb->getDoubleTy(), rlDest, rlSrc[0]);
break;
- case Instruction::CMPL_FLOAT:
- case Instruction::CMPG_FLOAT:
- case Instruction::CMPL_DOUBLE:
- case Instruction::CMPG_DOUBLE:
- res = genCmpFP(cUnit, mir, rlDest, rlSrc[0], rlSrc[1]);
+ case Instruction::FLOAT_TO_DOUBLE:
+ convertFloatToDouble(cUnit, rlDest, rlSrc[0]);
break;
- case Instruction::CMP_LONG:
- genCmpLong(cUnit, mir, rlDest, rlSrc[0], rlSrc[1]);
- break;
-
- case Instruction::NEG_INT:
- case Instruction::NOT_INT:
- res = genArithOpInt(cUnit, mir, rlDest, rlSrc[0], rlSrc[0]);
+ case Instruction::DOUBLE_TO_FLOAT:
+ convertDoubleToFloat(cUnit, rlDest, rlSrc[0]);
break;
case Instruction::NEG_LONG:
- case Instruction::NOT_LONG:
- res = genArithOpLong(cUnit, mir, rlDest, rlSrc[0], rlSrc[0]);
+ case Instruction::NEG_INT:
+ convertNeg(cUnit, rlDest, rlSrc[0]);
break;
case Instruction::NEG_FLOAT:
- res = genArithOpFloat(cUnit, mir, rlDest, rlSrc[0], rlSrc[0]);
- break;
-
case Instruction::NEG_DOUBLE:
- res = genArithOpDouble(cUnit, mir, rlDest, rlSrc[0], rlSrc[0]);
+ convertNegFP(cUnit, rlDest, rlSrc[0]);
break;
- case Instruction::LONG_TO_INT:
- rlSrc[0] = oatUpdateLocWide(cUnit, rlSrc[0]);
- rlSrc[0] = oatWideToNarrow(cUnit, rlSrc[0]);
- storeValue(cUnit, rlDest, rlSrc[0]);
+ case Instruction::NOT_LONG:
+ case Instruction::NOT_INT:
+ convertNot(cUnit, rlDest, rlSrc[0]);
break;
- case Instruction::INT_TO_FLOAT:
- case Instruction::INT_TO_DOUBLE:
- case Instruction::LONG_TO_FLOAT:
- case Instruction::LONG_TO_DOUBLE:
case Instruction::FLOAT_TO_INT:
- case Instruction::FLOAT_TO_LONG:
- case Instruction::FLOAT_TO_DOUBLE:
case Instruction::DOUBLE_TO_INT:
- case Instruction::DOUBLE_TO_LONG:
- case Instruction::DOUBLE_TO_FLOAT:
- genConversion(cUnit, mir);
+ convertFPToInt(cUnit, cUnit->irb->getInt32Ty(), rlDest, rlSrc[0]);
break;
+ case Instruction::FLOAT_TO_LONG:
+ case Instruction::DOUBLE_TO_LONG:
+ convertFPToInt(cUnit, cUnit->irb->getInt64Ty(), rlDest, rlSrc[0]);
+ break;
+
+ case Instruction::CMPL_FLOAT:
+ convertWideComparison(cUnit, greenland::IntrinsicHelper::CmplFloat,
+ rlDest, rlSrc[0], rlSrc[1]);
+ break;
+ case Instruction::CMPG_FLOAT:
+ convertWideComparison(cUnit, greenland::IntrinsicHelper::CmpgFloat,
+ rlDest, rlSrc[0], rlSrc[1]);
+ break;
+ case Instruction::CMPL_DOUBLE:
+ convertWideComparison(cUnit, greenland::IntrinsicHelper::CmplDouble,
+ rlDest, rlSrc[0], rlSrc[1]);
+ break;
+ case Instruction::CMPG_DOUBLE:
+ convertWideComparison(cUnit, greenland::IntrinsicHelper::CmpgDouble,
+ rlDest, rlSrc[0], rlSrc[1]);
+ break;
+ case Instruction::CMP_LONG:
+ convertWideComparison(cUnit, greenland::IntrinsicHelper::CmpLong,
+ rlDest, rlSrc[0], rlSrc[1]);
+ break;
+
+#if 0
+ case Instruction::PACKED_SWITCH:
+ genPackedSwitch(cUnit, vB, rlSrc[0]);
+ break;
+
+ case Instruction::SPARSE_SWITCH:
+ genSparseSwitch(cUnit, vB, rlSrc[0], labelList);
+ break;
#endif
default:
@@ -1480,7 +1583,7 @@
void setDexOffset(CompilationUnit* cUnit, int32_t offset)
{
cUnit->currentDalvikOffset = offset;
- llvm::SmallVector<llvm::Value*, 1>arrayRef;
+ llvm::SmallVector<llvm::Value*, 1> arrayRef;
arrayRef.push_back(cUnit->irb->getInt32(offset));
llvm::MDNode* node = llvm::MDNode::get(*cUnit->context, arrayRef);
cUnit->irb->SetDexOffset(node);
@@ -1902,6 +2005,72 @@
genIntNarrowing(cUnit, opcode, rlDest, rlSrc);
}
+void cvtIntToFP(CompilationUnit* cUnit, llvm::Instruction* inst)
+{
+ RegLocation rlDest = getLoc(cUnit, inst);
+ RegLocation rlSrc = getLoc(cUnit, inst->getOperand(0));
+ Instruction::Code opcode;
+ if (rlDest.wide) {
+ if (rlSrc.wide) {
+ opcode = Instruction::LONG_TO_DOUBLE;
+ } else {
+ opcode = Instruction::INT_TO_DOUBLE;
+ }
+ } else {
+ if (rlSrc.wide) {
+ opcode = Instruction::LONG_TO_FLOAT;
+ } else {
+ opcode = Instruction::INT_TO_FLOAT;
+ }
+ }
+ genConversion(cUnit, opcode, rlDest, rlSrc);
+}
+
+void cvtFPToInt(CompilationUnit* cUnit, llvm::Instruction* inst)
+{
+ RegLocation rlDest = getLoc(cUnit, inst);
+ RegLocation rlSrc = getLoc(cUnit, inst->getOperand(0));
+ Instruction::Code opcode;
+ if (rlDest.wide) {
+ if (rlSrc.wide) {
+ opcode = Instruction::DOUBLE_TO_LONG;
+ } else {
+ opcode = Instruction::FLOAT_TO_LONG;
+ }
+ } else {
+ if (rlSrc.wide) {
+ opcode = Instruction::DOUBLE_TO_INT;
+ } else {
+ opcode = Instruction::FLOAT_TO_INT;
+ }
+ }
+ genConversion(cUnit, opcode, rlDest, rlSrc);
+}
+
+void cvtFloatToDouble(CompilationUnit* cUnit, llvm::Instruction* inst)
+{
+ RegLocation rlDest = getLoc(cUnit, inst);
+ RegLocation rlSrc = getLoc(cUnit, inst->getOperand(0));
+ genConversion(cUnit, Instruction::FLOAT_TO_DOUBLE, rlDest, rlSrc);
+}
+
+void cvtTrunc(CompilationUnit* cUnit, llvm::Instruction* inst)
+{
+ RegLocation rlDest = getLoc(cUnit, inst);
+ RegLocation rlSrc = getLoc(cUnit, inst->getOperand(0));
+ rlSrc = oatUpdateLocWide(cUnit, rlSrc);
+ rlSrc = oatWideToNarrow(cUnit, rlSrc);
+ storeValue(cUnit, rlDest, rlSrc);
+}
+
+void cvtDoubleToFloat(CompilationUnit* cUnit, llvm::Instruction* inst)
+{
+ RegLocation rlDest = getLoc(cUnit, inst);
+ RegLocation rlSrc = getLoc(cUnit, inst->getOperand(0));
+ genConversion(cUnit, Instruction::DOUBLE_TO_FLOAT, rlDest, rlSrc);
+}
+
+
void cvtIntExt(CompilationUnit* cUnit, llvm::Instruction* inst, bool isSigned)
{
// TODO: evaluate src/tgt types and add general support for more than int to long
@@ -2094,6 +2263,8 @@
DCHECK_EQ(callInst->getNumArgOperands(), 1U);
RegLocation rlSrc = getLoc(cUnit, callInst->getArgOperand(0));
RegLocation rlDest = getLoc(cUnit, callInst);
+ DCHECK_EQ(rlSrc.wide, rlDest.wide);
+ DCHECK_EQ(rlSrc.fp, rlDest.fp);
if (rlSrc.wide) {
storeValueWide(cUnit, rlDest, rlSrc);
} else {
@@ -2211,7 +2382,7 @@
}
}
-void cvtMonitorArrayLength(CompilationUnit* cUnit, llvm::CallInst* callInst)
+void cvtArrayLength(CompilationUnit* cUnit, llvm::CallInst* callInst)
{
DCHECK_EQ(callInst->getNumArgOperands(), 2U);
llvm::ConstantInt* optFlags =
@@ -2332,8 +2503,25 @@
genCheckCast(cUnit, typeIdx->getZExtValue(), rlSrc);
}
+void cvtFPCompare(CompilationUnit* cUnit, llvm::CallInst* callInst,
+ Instruction::Code opcode)
+{
+ RegLocation rlSrc1 = getLoc(cUnit, callInst->getArgOperand(0));
+ RegLocation rlSrc2 = getLoc(cUnit, callInst->getArgOperand(1));
+ RegLocation rlDest = getLoc(cUnit, callInst);
+ genCmpFP(cUnit, opcode, rlDest, rlSrc1, rlSrc2);
+}
+
+void cvtLongCompare(CompilationUnit* cUnit, llvm::CallInst* callInst)
+{
+ RegLocation rlSrc1 = getLoc(cUnit, callInst->getArgOperand(0));
+ RegLocation rlSrc2 = getLoc(cUnit, callInst->getArgOperand(1));
+ RegLocation rlDest = getLoc(cUnit, callInst);
+ genCmpLong(cUnit, rlDest, rlSrc1, rlSrc2);
+}
+
void cvtInvoke(CompilationUnit* cUnit, llvm::CallInst* callInst,
- bool isVoid, bool isNewArray)
+ bool isVoid, bool isFilledNewArray)
{
CallInfo* info = (CallInfo*)oatNew(cUnit, sizeof(CallInfo), true,
kAllocMisc);
@@ -2378,7 +2566,7 @@
}
next++;
}
- if (isNewArray) {
+ if (isFilledNewArray) {
genFilledNewArray(cUnit, info);
} else {
genInvoke(cUnit, info);
@@ -2570,6 +2758,18 @@
case greenland::IntrinsicHelper::HLSgetDouble:
cvtSget(cUnit, callInst, true /* wide */, false /* Object */);
break;
+ case greenland::IntrinsicHelper::HLSput:
+ case greenland::IntrinsicHelper::HLSputFloat:
+ case greenland::IntrinsicHelper::HLSputBoolean:
+ case greenland::IntrinsicHelper::HLSputByte:
+ case greenland::IntrinsicHelper::HLSputChar:
+ case greenland::IntrinsicHelper::HLSputShort:
+ cvtSput(cUnit, callInst, false /* wide */, false /* Object */);
+ break;
+ case greenland::IntrinsicHelper::HLSputWide:
+ case greenland::IntrinsicHelper::HLSputDouble:
+ cvtSput(cUnit, callInst, true /* wide */, false /* Object */);
+ break;
case greenland::IntrinsicHelper::GetException:
cvtMoveException(cUnit, callInst);
break;
@@ -2586,7 +2786,7 @@
cvtMonitorEnterExit(cUnit, false /* isEnter */, callInst);
break;
case greenland::IntrinsicHelper::ArrayLength:
- cvtMonitorArrayLength(cUnit, callInst);
+ cvtArrayLength(cUnit, callInst);
break;
case greenland::IntrinsicHelper::NewArray:
cvtNewArray(cUnit, callInst);
@@ -2705,6 +2905,23 @@
cvtIntNarrowing(cUnit, callInst, Instruction::INT_TO_BYTE);
break;
+ case greenland::IntrinsicHelper::CmplFloat:
+ cvtFPCompare(cUnit, callInst, Instruction::CMPL_FLOAT);
+ break;
+ case greenland::IntrinsicHelper::CmpgFloat:
+ cvtFPCompare(cUnit, callInst, Instruction::CMPG_FLOAT);
+ break;
+ case greenland::IntrinsicHelper::CmplDouble:
+ cvtFPCompare(cUnit, callInst, Instruction::CMPL_DOUBLE);
+ break;
+ case greenland::IntrinsicHelper::CmpgDouble:
+ cvtFPCompare(cUnit, callInst, Instruction::CMPG_DOUBLE);
+ break;
+
+ case greenland::IntrinsicHelper::CmpLong:
+ cvtLongCompare(cUnit, callInst);
+ break;
+
case greenland::IntrinsicHelper::UnknownId:
cvtCall(cUnit, callInst, callee);
break;
@@ -2734,6 +2951,11 @@
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::SIToFP: cvtIntToFP(cUnit, inst); break;
+ case llvm::Instruction::FPToSI: cvtFPToInt(cUnit, inst); break;
+ case llvm::Instruction::FPTrunc: cvtDoubleToFloat(cUnit, inst); break;
+ case llvm::Instruction::FPExt: cvtFloatToDouble(cUnit, inst); break;
+ case llvm::Instruction::Trunc: cvtTrunc(cUnit, inst); break;
case llvm::Instruction::ZExt: cvtIntExt(cUnit, inst, false /* signed */);
break;
@@ -2744,20 +2966,12 @@
break; // FIXME: can we really ignore these?
case llvm::Instruction::Invoke:
- case llvm::Instruction::Trunc:
case llvm::Instruction::FPToUI:
- case llvm::Instruction::FPToSI:
case llvm::Instruction::UIToFP:
- case llvm::Instruction::SIToFP:
- case llvm::Instruction::FPTrunc:
- case llvm::Instruction::FPExt:
case llvm::Instruction::PtrToInt:
case llvm::Instruction::IntToPtr:
case llvm::Instruction::Switch:
case llvm::Instruction::FCmp:
- UNIMPLEMENTED(FATAL) << "Unimplemented llvm opcode: " << opcode;
- break;
-
case llvm::Instruction::URem:
case llvm::Instruction::UDiv:
case llvm::Instruction::Resume:
diff --git a/src/greenland/intrinsic_func_list.def b/src/greenland/intrinsic_func_list.def
index 89ec4c4..084d09c 100644
--- a/src/greenland/intrinsic_func_list.def
+++ b/src/greenland/intrinsic_func_list.def
@@ -548,25 +548,25 @@
_EVAL_DEF_INTRINSICS_FUNC(HLArrayGetBoolean,
dex_lang_hl_aget_boolean,
kAttrReadOnly | kAttrNoThrow,
- kInt1Ty,
+ kInt32Ty,
_EXPAND_ARG3(kInt32Ty, kJavaObjectTy, kInt32Ty))
_EVAL_DEF_INTRINSICS_FUNC(HLArrayGetByte,
dex_lang_hl_aget_byte,
kAttrReadOnly | kAttrNoThrow,
- kInt8Ty,
+ kInt32Ty,
_EXPAND_ARG3(kInt32Ty, kJavaObjectTy, kInt32Ty))
_EVAL_DEF_INTRINSICS_FUNC(HLArrayGetChar,
dex_lang_hl_aget_char,
kAttrReadOnly | kAttrNoThrow,
- kInt16Ty,
+ kInt32Ty,
_EXPAND_ARG3(kInt32Ty, kJavaObjectTy, kInt32Ty))
_EVAL_DEF_INTRINSICS_FUNC(HLArrayGetShort,
dex_lang_hl_aget_short,
kAttrReadOnly | kAttrNoThrow,
- kInt16Ty,
+ kInt32Ty,
_EXPAND_ARG3(kInt32Ty, kJavaObjectTy, kInt32Ty))
// void dex_lang_aput_[type](int optFlags, [type] value, JavaObject* array, uint32_t index)
@@ -604,25 +604,25 @@
dex_lang_hl_aput_boolean,
kAttrNoThrow,
kVoidTy,
- _EXPAND_ARG4(kInt32Ty, kInt1Ty, kJavaObjectTy, kInt32Ty))
+ _EXPAND_ARG4(kInt32Ty, kInt32Ty, kJavaObjectTy, kInt32Ty))
_EVAL_DEF_INTRINSICS_FUNC(HLArrayPutByte,
dex_lang_hl_aput_byte,
kAttrNoThrow,
kVoidTy,
- _EXPAND_ARG4(kInt32Ty, kInt8Ty, kJavaObjectTy, kInt32Ty))
+ _EXPAND_ARG4(kInt32Ty, kInt32Ty, kJavaObjectTy, kInt32Ty))
_EVAL_DEF_INTRINSICS_FUNC(HLArrayPutChar,
dex_lang_hl_aput_char,
kAttrNoThrow,
kVoidTy,
- _EXPAND_ARG4(kInt32Ty, kInt16Ty, kJavaObjectTy, kInt32Ty))
+ _EXPAND_ARG4(kInt32Ty, kInt32Ty, kJavaObjectTy, kInt32Ty))
_EVAL_DEF_INTRINSICS_FUNC(HLArrayPutShort,
dex_lang_hl_aput_short,
kAttrNoThrow,
kVoidTy,
- _EXPAND_ARG4(kInt32Ty, kInt16Ty, kJavaObjectTy, kInt32Ty))
+ _EXPAND_ARG4(kInt32Ty, kInt32Ty, kJavaObjectTy, kInt32Ty))
//----------------------------------------------------------------------------
// High-level Instance get/put
@@ -665,25 +665,25 @@
_EVAL_DEF_INTRINSICS_FUNC(HLIGetBoolean,
dex_lang_hl_iget_boolean,
kAttrReadOnly | kAttrNoThrow,
- kInt1Ty,
+ kInt32Ty,
_EXPAND_ARG3(kInt32Ty, kJavaObjectTy, kInt32Ty))
_EVAL_DEF_INTRINSICS_FUNC(HLIGetByte,
dex_lang_hl_iget_byte,
kAttrReadOnly | kAttrNoThrow,
- kInt8Ty,
+ kInt32Ty,
_EXPAND_ARG3(kInt32Ty, kJavaObjectTy, kInt32Ty))
_EVAL_DEF_INTRINSICS_FUNC(HLIGetChar,
dex_lang_hl_iget_char,
kAttrReadOnly | kAttrNoThrow,
- kInt16Ty,
+ kInt32Ty,
_EXPAND_ARG3(kInt32Ty, kJavaObjectTy, kInt32Ty))
_EVAL_DEF_INTRINSICS_FUNC(HLIGetShort,
dex_lang_hl_iget_short,
kAttrReadOnly | kAttrNoThrow,
- kInt16Ty,
+ kInt32Ty,
_EXPAND_ARG3(kInt32Ty, kJavaObjectTy, kInt32Ty))
// void dex_lang_iput_[type](int optFlags, [type] value, JavaObject* ojb, uint32_t field_idx)
@@ -721,25 +721,25 @@
dex_lang_hl_iput_boolean,
kAttrNoThrow,
kVoidTy,
- _EXPAND_ARG4(kInt32Ty, kInt1Ty, kJavaObjectTy, kInt32Ty))
+ _EXPAND_ARG4(kInt32Ty, kInt32Ty, kJavaObjectTy, kInt32Ty))
_EVAL_DEF_INTRINSICS_FUNC(HLIPutByte,
dex_lang_hl_iput_byte,
kAttrNoThrow,
kVoidTy,
- _EXPAND_ARG4(kInt32Ty, kInt8Ty, kJavaObjectTy, kInt32Ty))
+ _EXPAND_ARG4(kInt32Ty, kInt32Ty, kJavaObjectTy, kInt32Ty))
_EVAL_DEF_INTRINSICS_FUNC(HLIPutChar,
dex_lang_hl_iput_char,
kAttrNoThrow,
kVoidTy,
- _EXPAND_ARG4(kInt32Ty, kInt16Ty, kJavaObjectTy, kInt32Ty))
+ _EXPAND_ARG4(kInt32Ty, kInt32Ty, kJavaObjectTy, kInt32Ty))
_EVAL_DEF_INTRINSICS_FUNC(HLIPutShort,
dex_lang_hl_iput_short,
kAttrNoThrow,
kVoidTy,
- _EXPAND_ARG4(kInt32Ty, kInt16Ty, kJavaObjectTy, kInt32Ty))
+ _EXPAND_ARG4(kInt32Ty, kInt32Ty, kJavaObjectTy, kInt32Ty))
//----------------------------------------------------------------------------
// High-level Invokes (fast-path determination not yet performed)
@@ -944,28 +944,28 @@
dex_lang_hl_sput_boolean,
kAttrReadOnly | kAttrNoThrow,
kVoidTy,
- _EXPAND_ARG2(kInt32Ty, kInt1Ty))
+ _EXPAND_ARG2(kInt32Ty, kInt32Ty))
// void sput_hl_byte(int field_idx, int val)
_EVAL_DEF_INTRINSICS_FUNC(HLSputByte,
dex_lang_hl_sput_byte,
kAttrReadOnly | kAttrNoThrow,
kVoidTy,
- _EXPAND_ARG2(kInt32Ty, kInt8Ty))
+ _EXPAND_ARG2(kInt32Ty, kInt32Ty))
// void sput_hl_char(int field_idx, kInt16Ty val)
_EVAL_DEF_INTRINSICS_FUNC(HLSputChar,
dex_lang_hl_sput_char,
kAttrReadOnly | kAttrNoThrow,
kVoidTy,
- _EXPAND_ARG2(kInt32Ty, kInt16Ty))
+ _EXPAND_ARG2(kInt32Ty, kInt32Ty))
// void sput_hl_short(int field_idx, int val)
_EVAL_DEF_INTRINSICS_FUNC(HLSputShort,
dex_lang_hl_sput_short,
kAttrReadOnly | kAttrNoThrow,
kVoidTy,
- _EXPAND_ARG2(kInt32Ty, kInt16Ty))
+ _EXPAND_ARG2(kInt32Ty, kInt32Ty))
// void sput_hl_wide(int field_idx, long val)
_EVAL_DEF_INTRINSICS_FUNC(HLSputWide,
@@ -1012,28 +1012,28 @@
_EVAL_DEF_INTRINSICS_FUNC(HLSgetBoolean,
dex_lang_hl_sget_boolean,
kAttrReadOnly | kAttrNoThrow,
- kInt1Ty,
+ kInt32Ty,
_EXPAND_ARG1(kInt32Ty))
// byte sget_hl_byte(int field_idx)
_EVAL_DEF_INTRINSICS_FUNC(HLSgetByte,
dex_lang_hl_sget_byte,
kAttrReadOnly | kAttrNoThrow,
- kInt8Ty,
+ kInt32Ty,
_EXPAND_ARG1(kInt32Ty))
// char sget_hl_char(int field_idx)
_EVAL_DEF_INTRINSICS_FUNC(HLSgetChar,
dex_lang_hl_sget_char,
kAttrReadOnly | kAttrNoThrow,
- kInt16Ty,
+ kInt32Ty,
_EXPAND_ARG1(kInt32Ty))
// char sget_hl_short(int field_idx)
_EVAL_DEF_INTRINSICS_FUNC(HLSgetShort,
dex_lang_hl_sget_short,
kAttrReadOnly | kAttrNoThrow,
- kInt16Ty,
+ kInt32Ty,
_EXPAND_ARG1(kInt32Ty))
// char sget_hl_wide(int field_idx)
@@ -1059,19 +1059,19 @@
//----------------------------------------------------------------------------
// Monitor enter/exit
//----------------------------------------------------------------------------
-// uint32_t dex_lang_monitor_enter(JavaObject* obj)
+// uint32_t dex_lang_monitor_enter(int optFlags, JavaObject* obj)
_EVAL_DEF_INTRINSICS_FUNC(MonitorEnter,
dex_lang_monitor_enter,
kAttrReadOnly | kAttrNoThrow,
kVoidTy,
- _EXPAND_ARG1(kJavaObjectTy))
+ _EXPAND_ARG2(kInt32Ty, kJavaObjectTy))
-// uint32_t dex_lang_monitor_exit(JavaObject* obj)
+// uint32_t dex_lang_monitor_exit(int optFlags, JavaObject* obj)
_EVAL_DEF_INTRINSICS_FUNC(MonitorExit,
dex_lang_monitor_exit,
kAttrReadOnly | kAttrNoThrow,
kVoidTy,
- _EXPAND_ARG1(kJavaObjectTy))
+ _EXPAND_ARG2(kInt32Ty, kJavaObjectTy))
//----------------------------------------------------------------------------
// Shadow Frame
@@ -1106,6 +1106,64 @@
_EXPAND_ARG1(kInt32ConstantTy))
//----------------------------------------------------------------------------
+// FP Comparison
+//----------------------------------------------------------------------------
+// int cmpl_float(float, float)
+_EVAL_DEF_INTRINSICS_FUNC(CmplFloat,
+ dex_lang_cmpl_float,
+ kAttrReadOnly | kAttrNoThrow,
+ kInt32Ty,
+ _EXPAND_ARG2(kFloatTy, kFloatTy))
+
+// int cmpg_float(float, float)
+_EVAL_DEF_INTRINSICS_FUNC(CmpgFloat,
+ dex_lang_cmpg_float,
+ kAttrReadOnly | kAttrNoThrow,
+ kInt32Ty,
+ _EXPAND_ARG2(kFloatTy, kFloatTy))
+
+// int cmpl_double(double, double)
+_EVAL_DEF_INTRINSICS_FUNC(CmplDouble,
+ dex_lang_cmpl_double,
+ kAttrReadOnly | kAttrNoThrow,
+ kInt32Ty,
+ _EXPAND_ARG2(kDoubleTy, kDoubleTy))
+
+// int cmpg_double(double, double)
+_EVAL_DEF_INTRINSICS_FUNC(CmpgDouble,
+ dex_lang_cmpg_double,
+ kAttrReadOnly | kAttrNoThrow,
+ kInt32Ty,
+ _EXPAND_ARG2(kDoubleTy, kDoubleTy))
+
+//----------------------------------------------------------------------------
+// Long Comparison
+//----------------------------------------------------------------------------
+// int cmp_long(long, long)
+_EVAL_DEF_INTRINSICS_FUNC(CmpLong,
+ dex_lang_cmp_long,
+ kAttrReadOnly | kAttrNoThrow,
+ kInt32Ty,
+ _EXPAND_ARG2(kInt64Ty, kInt64Ty))
+
+//----------------------------------------------------------------------------
+// Switch
+//----------------------------------------------------------------------------
+// void sparse_switch(int, int)
+_EVAL_DEF_INTRINSICS_FUNC(SparseSwitch,
+ dex_lang_sparse_switch,
+ kAttrReadOnly | kAttrNoThrow,
+ kVoidTy,
+ _EXPAND_ARG2(kInt32Ty, kInt32Ty))
+
+// void packed_switch(int, int)
+_EVAL_DEF_INTRINSICS_FUNC(PackedSwitch,
+ dex_lang_packed_switch,
+ kAttrReadOnly | kAttrNoThrow,
+ kVoidTy,
+ _EXPAND_ARG2(kInt32Ty, kInt32Ty))
+
+//----------------------------------------------------------------------------
// Const intrinsics to assist MIR to Greenland_ir conversion. Should not materialize
// For simplicity, all use integer input
//----------------------------------------------------------------------------