summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorbuzbee <buzbee@google.com>2012-06-27 15:44:52 -0700
committerbuzbee <buzbee@google.com>2012-06-27 15:44:52 -0700
commit8fa0fda8e1b6aa0a759990b3d32b78bb08065e0f (patch)
tree4e87b99f5afdc564ee27eb3902e48d52c8795720
parent6613de3585d726a246b5ee2597ddaef8b3c3a621 (diff)
downloadart-8fa0fda8e1b6aa0a759990b3d32b78bb08065e0f.zip
art-8fa0fda8e1b6aa0a759990b3d32b78bb08065e0f.tar.gz
art-8fa0fda8e1b6aa0a759990b3d32b78bb08065e0f.tar.bz2
Quick compiler: support for arrays, misc.
Continuing to flesh out support in the Quick compiler. Mostly array-related. Also, added runtest 028-array-write to the set of passing tests. Change-Id: I3c8eaf4bb14e9327e4f5fc48de73c85a5d3efb54
-rw-r--r--src/compiler/Frontend.cc4
-rw-r--r--src/compiler/codegen/MethodBitcode.cc576
-rw-r--r--src/greenland/intrinsic_func_list.def278
-rw-r--r--test/028-array-write/src/Main.java11
4 files changed, 714 insertions, 155 deletions
diff --git a/src/compiler/Frontend.cc b/src/compiler/Frontend.cc
index 9e4b857..ba8d0d8 100644
--- a/src/compiler/Frontend.cc
+++ b/src/compiler/Frontend.cc
@@ -768,6 +768,10 @@ CompiledMethod* oatCompileMethod(Compiler& compiler,
|| (PrettyMethod(method_idx, dex_file).find("math_013") != std::string::npos)
|| (PrettyMethod(method_idx, dex_file).find("math_014") != std::string::npos)
|| (PrettyMethod(method_idx, dex_file).find("float_017") != std::string::npos)
+ || (PrettyMethod(method_idx, dex_file).find("array_028") != std::string::npos)
+ || (PrettyMethod(method_idx, dex_file).find("writeArray") != std::string::npos)
+ || (PrettyMethod(method_idx, dex_file).find("writeTest") != std::string::npos)
+ || (PrettyMethod(method_idx, dex_file).find("copyTest") != std::string::npos)
) {
cUnit->genBitcode = true;
}
diff --git a/src/compiler/codegen/MethodBitcode.cc b/src/compiler/codegen/MethodBitcode.cc
index cf990ec..690f022 100644
--- a/src/compiler/codegen/MethodBitcode.cc
+++ b/src/compiler/codegen/MethodBitcode.cc
@@ -140,12 +140,25 @@ 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)
+void convertSget(CompilationUnit* cUnit, int32_t fieldIndex,
+ greenland::IntrinsicHelper::IntrinsicId id,
+ RegLocation rlDest)
{
+ llvm::Constant* fieldIdx = cUnit->irb->getInt32(fieldIndex);
llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
- return cUnit->irb->CreateCall(intr, src);
+ llvm::Value* res = cUnit->irb->CreateCall(intr, fieldIdx);
+ defineValue(cUnit, res, rlDest.origSReg);
+}
+
+void convertSput(CompilationUnit* cUnit, int32_t fieldIndex,
+ greenland::IntrinsicHelper::IntrinsicId id,
+ RegLocation rlSrc)
+{
+ llvm::SmallVector<llvm::Value*, 2> args;
+ args.push_back(cUnit->irb->getInt32(fieldIndex));
+ args.push_back(getLLVMValue(cUnit, rlSrc.origSReg));
+ llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
+ cUnit->irb->CreateCall(intr, args);
}
llvm::Value* emitConst(CompilationUnit* cUnit, llvm::ArrayRef<llvm::Value*> src,
@@ -178,8 +191,6 @@ void emitPopShadowFrame(CompilationUnit* cUnit)
cUnit->irb->CreateCall(intr);
}
-
-
llvm::Value* emitCopy(CompilationUnit* cUnit, llvm::ArrayRef<llvm::Value*> src,
RegLocation loc)
{
@@ -220,6 +231,27 @@ void convertThrow(CompilationUnit* cUnit, RegLocation rlSrc)
cUnit->irb->CreateUnreachable();
}
+void convertMonitorEnterExit(CompilationUnit* cUnit, int optFlags,
+ greenland::IntrinsicHelper::IntrinsicId id,
+ 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(id);
+ cUnit->irb->CreateCall(func, args);
+}
+
+void convertArrayLength(CompilationUnit* cUnit, int optFlags, 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);
+}
+
void convertThrowVerificationError(CompilationUnit* cUnit, int info1, int info2)
{
llvm::Function* func = cUnit->intrinsic_helper->GetIntrinsicFunction(
@@ -450,7 +482,7 @@ void convertInvoke(CompilationUnit* cUnit, BasicBlock* bb, MIR* mir,
if (info->result.fp) {
id = greenland::IntrinsicHelper::HLInvokeDouble;
} else {
- id = greenland::IntrinsicHelper::HLInvokeFloat;
+ id = greenland::IntrinsicHelper::HLInvokeLong;
}
} else if (info->result.ref) {
id = greenland::IntrinsicHelper::HLInvokeObj;
@@ -478,8 +510,8 @@ void convertConstString(CompilationUnit* cUnit, BasicBlock* bb,
defineValue(cUnit, res, rlDest.origSReg);
}
-void convertNewInstance(CompilationUnit* cUnit, BasicBlock* bb,
- uint32_t type_idx, RegLocation rlDest)
+void convertNewInstance(CompilationUnit* cUnit, uint32_t type_idx,
+ RegLocation rlDest)
{
greenland::IntrinsicHelper::IntrinsicId id;
id = greenland::IntrinsicHelper::NewInstance;
@@ -489,6 +521,58 @@ void convertNewInstance(CompilationUnit* cUnit, BasicBlock* bb,
defineValue(cUnit, res, rlDest.origSReg);
}
+void convertNewArray(CompilationUnit* cUnit, uint32_t type_idx,
+ RegLocation rlDest, RegLocation rlSrc)
+{
+ greenland::IntrinsicHelper::IntrinsicId id;
+ id = greenland::IntrinsicHelper::NewArray;
+ llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
+ llvm::SmallVector<llvm::Value*, 2> args;
+ args.push_back(cUnit->irb->getInt32(type_idx));
+ args.push_back(getLLVMValue(cUnit, rlSrc.origSReg));
+ llvm::Value* res = cUnit->irb->CreateCall(intr, args);
+ defineValue(cUnit, res, rlDest.origSReg);
+}
+
+void convertAget(CompilationUnit* cUnit, int optFlags,
+ greenland::IntrinsicHelper::IntrinsicId id,
+ RegLocation rlDest, RegLocation rlArray, RegLocation rlIndex)
+{
+ llvm::SmallVector<llvm::Value*, 3> args;
+ args.push_back(cUnit->irb->getInt32(optFlags));
+ args.push_back(getLLVMValue(cUnit, rlArray.origSReg));
+ args.push_back(getLLVMValue(cUnit, rlIndex.origSReg));
+ llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
+ llvm::Value* res = cUnit->irb->CreateCall(intr, args);
+ defineValue(cUnit, res, rlDest.origSReg);
+}
+
+void convertAput(CompilationUnit* cUnit, int optFlags,
+ greenland::IntrinsicHelper::IntrinsicId id,
+ RegLocation rlSrc, RegLocation rlArray, RegLocation rlIndex)
+{
+ llvm::SmallVector<llvm::Value*, 4> args;
+ args.push_back(cUnit->irb->getInt32(optFlags));
+ args.push_back(getLLVMValue(cUnit, rlSrc.origSReg));
+ args.push_back(getLLVMValue(cUnit, rlArray.origSReg));
+ args.push_back(getLLVMValue(cUnit, rlIndex.origSReg));
+ llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
+ cUnit->irb->CreateCall(intr, args);
+}
+
+void convertInstanceOf(CompilationUnit* cUnit, uint32_t type_idx,
+ RegLocation rlDest, RegLocation rlSrc)
+{
+ greenland::IntrinsicHelper::IntrinsicId id;
+ id = greenland::IntrinsicHelper::InstanceOf;
+ llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
+ llvm::SmallVector<llvm::Value*, 2> args;
+ args.push_back(cUnit->irb->getInt32(type_idx));
+ args.push_back(getLLVMValue(cUnit, rlSrc.origSReg));
+ llvm::Value* res = cUnit->irb->CreateCall(intr, args);
+ defineValue(cUnit, res, rlDest.origSReg);
+}
+
/*
* Target-independent code generation. Use only high-level
* load/store utilities here, or target-dependent genXX() handlers
@@ -505,6 +589,7 @@ bool convertMIRNode(CompilationUnit* cUnit, MIR* mir, BasicBlock* bb,
uint32_t vA = mir->dalvikInsn.vA;
uint32_t vB = mir->dalvikInsn.vB;
uint32_t vC = mir->dalvikInsn.vC;
+ int optFlags = mir->optimizationFlags;
bool objectDefinition = false;
@@ -613,11 +698,69 @@ bool convertMIRNode(CompilationUnit* cUnit, MIR* mir, BasicBlock* bb,
}
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);
+ case Instruction::SPUT_OBJECT:
+ convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSputObject,
+ rlSrc[0]);
+ break;
+ case Instruction::SPUT:
+ if (rlSrc[0].fp) {
+ convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSputFloat,
+ rlSrc[0]);
+ } else {
+ convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSput, rlSrc[0]);
+ }
+ break;
+ case Instruction::SPUT_BOOLEAN:
+ convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSputBoolean,
+ rlSrc[0]);
+ break;
+ case Instruction::SPUT_BYTE:
+ convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSputByte, rlSrc[0]);
+ break;
+ case Instruction::SPUT_CHAR:
+ convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSputChar, rlSrc[0]);
+ break;
+ case Instruction::SPUT_SHORT:
+ convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSputShort, rlSrc[0]);
+ break;
+ case Instruction::SPUT_WIDE:
+ if (rlSrc[0].fp) {
+ convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSputDouble,
+ rlSrc[0]);
+ } else {
+ convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSputWide,
+ rlSrc[0]);
+ }
+ break;
+
+ case Instruction::SGET_OBJECT:
+ convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSgetObject, rlDest);
+ break;
+ case Instruction::SGET:
+ if (rlDest.fp) {
+ convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSgetFloat, rlDest);
+ } else {
+ convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSget, rlDest);
+ }
+ break;
+ case Instruction::SGET_BOOLEAN:
+ convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSgetBoolean, rlDest);
+ break;
+ case Instruction::SGET_BYTE:
+ convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSgetByte, rlDest);
+ break;
+ case Instruction::SGET_CHAR:
+ convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSgetChar, rlDest);
+ break;
+ case Instruction::SGET_SHORT:
+ convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSgetShort, rlDest);
+ break;
+ case Instruction::SGET_WIDE:
+ if (rlDest.fp) {
+ convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSgetDouble,
+ rlDest);
+ } else {
+ convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSgetWide, rlDest);
}
break;
@@ -881,7 +1024,7 @@ bool convertMIRNode(CompilationUnit* cUnit, MIR* mir, BasicBlock* bb,
break;
case Instruction::NEW_INSTANCE:
- convertNewInstance(cUnit, bb, vB, rlDest);
+ convertNewInstance(cUnit, vB, rlDest);
break;
case Instruction::MOVE_EXCEPTION:
@@ -896,70 +1039,124 @@ bool convertMIRNode(CompilationUnit* cUnit, MIR* mir, BasicBlock* bb,
convertThrowVerificationError(cUnit, vA, vB);
break;
-#if 0
-
- case Instruction::MOVE_EXCEPTION: {
- int exOffset = Thread::ExceptionOffset().Int32Value();
- rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true);
-#if defined(TARGET_X86)
- newLIR2(cUnit, kX86Mov32RT, rlResult.lowReg, exOffset);
- newLIR2(cUnit, kX86Mov32TI, exOffset, 0);
-#else
- int resetReg = oatAllocTemp(cUnit);
- loadWordDisp(cUnit, rSELF, exOffset, rlResult.lowReg);
- loadConstant(cUnit, resetReg, 0);
- storeWordDisp(cUnit, rSELF, exOffset, resetReg);
- storeValue(cUnit, rlDest, rlResult);
- oatFreeTemp(cUnit, resetReg);
-#endif
- break;
- }
-
case Instruction::MOVE_RESULT_WIDE:
- if (mir->optimizationFlags & MIR_INLINED)
- break; // Nop - combined w/ previous invoke
- storeValueWide(cUnit, rlDest, oatGetReturnWide(cUnit, rlDest.fp));
- break;
-
case Instruction::MOVE_RESULT:
case Instruction::MOVE_RESULT_OBJECT:
- if (mir->optimizationFlags & MIR_INLINED)
- break; // Nop - combined w/ previous invoke
- storeValue(cUnit, rlDest, oatGetReturn(cUnit, rlDest.fp));
+ CHECK(false) << "Unexpected MOVE_RESULT";
break;
case Instruction::MONITOR_ENTER:
- genMonitorEnter(cUnit, mir, rlSrc[0]);
+ convertMonitorEnterExit(cUnit, optFlags,
+ greenland::IntrinsicHelper::MonitorEnter,
+ rlSrc[0]);
break;
case Instruction::MONITOR_EXIT:
- genMonitorExit(cUnit, mir, rlSrc[0]);
+ convertMonitorEnterExit(cUnit, optFlags,
+ greenland::IntrinsicHelper::MonitorExit,
+ rlSrc[0]);
break;
- case Instruction::CHECK_CAST:
- genCheckCast(cUnit, mir, rlSrc[0]);
+ case Instruction::ARRAY_LENGTH:
+ convertArrayLength(cUnit, optFlags, rlSrc[0]);
+ break;
+
+ case Instruction::NEW_ARRAY:
+ convertNewArray(cUnit, vC, rlDest, rlSrc[0]);
break;
case Instruction::INSTANCE_OF:
- genInstanceof(cUnit, mir, rlDest, rlSrc[0]);
+ convertInstanceOf(cUnit, vC, rlDest, rlSrc[0]);
break;
- case Instruction::THROW:
- genThrow(cUnit, mir, rlSrc[0]);
+ case Instruction::AGET:
+ if (rlDest.fp) {
+ convertAget(cUnit, optFlags,
+ greenland::IntrinsicHelper::HLArrayGetFloat,
+ rlDest, rlSrc[0], rlSrc[1]);
+ } else {
+ convertAget(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayGet,
+ rlDest, rlSrc[0], rlSrc[1]);
+ }
+ break;
+ case Instruction::AGET_OBJECT:
+ convertAget(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayGetObject,
+ rlDest, rlSrc[0], rlSrc[1]);
+ break;
+ case Instruction::AGET_BOOLEAN:
+ convertAget(cUnit, optFlags,
+ greenland::IntrinsicHelper::HLArrayGetBoolean,
+ rlDest, rlSrc[0], rlSrc[1]);
+ break;
+ case Instruction::AGET_BYTE:
+ convertAget(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayGetByte,
+ rlDest, rlSrc[0], rlSrc[1]);
+ break;
+ case Instruction::AGET_CHAR:
+ convertAget(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayGetChar,
+ rlDest, rlSrc[0], rlSrc[1]);
+ break;
+ case Instruction::AGET_SHORT:
+ convertAget(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayGetShort,
+ rlDest, rlSrc[0], rlSrc[1]);
+ break;
+ case Instruction::AGET_WIDE:
+ if (rlDest.fp) {
+ convertAget(cUnit, optFlags,
+ greenland::IntrinsicHelper::HLArrayGetDouble,
+ rlDest, rlSrc[0], rlSrc[1]);
+ } else {
+ convertAget(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayGetWide,
+ rlDest, rlSrc[0], rlSrc[1]);
+ }
break;
- case Instruction::THROW_VERIFICATION_ERROR:
- genThrowVerificationError(cUnit, mir);
+ case Instruction::APUT:
+ if (rlSrc[0].fp) {
+ convertAput(cUnit, optFlags,
+ greenland::IntrinsicHelper::HLArrayPutFloat,
+ rlSrc[0], rlSrc[1], rlSrc[2]);
+ } else {
+ convertAput(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayPut,
+ rlSrc[0], rlSrc[1], rlSrc[2]);
+ }
+ break;
+ case Instruction::APUT_OBJECT:
+ convertAput(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayPutObject,
+ rlSrc[0], rlSrc[1], rlSrc[2]);
+ break;
+ case Instruction::APUT_BOOLEAN:
+ convertAput(cUnit, optFlags,
+ greenland::IntrinsicHelper::HLArrayPutBoolean,
+ rlSrc[0], rlSrc[1], rlSrc[2]);
+ break;
+ case Instruction::APUT_BYTE:
+ convertAput(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayPutByte,
+ rlSrc[0], rlSrc[1], rlSrc[2]);
+ break;
+ case Instruction::APUT_CHAR:
+ convertAput(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayPutChar,
+ rlSrc[0], rlSrc[1], rlSrc[2]);
+ break;
+ case Instruction::APUT_SHORT:
+ convertAput(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayPutShort,
+ rlSrc[0], rlSrc[1], rlSrc[2]);
+ break;
+ case Instruction::APUT_WIDE:
+ if (rlSrc[0].fp) {
+ convertAput(cUnit, optFlags,
+ greenland::IntrinsicHelper::HLArrayPutDouble,
+ rlSrc[0], rlSrc[1], rlSrc[2]);
+ } else {
+ convertAput(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayPutWide,
+ rlSrc[0], rlSrc[1], rlSrc[2]);
+ }
break;
- case Instruction::ARRAY_LENGTH:
- int lenOffset;
- lenOffset = Array::LengthOffset().Int32Value();
- rlSrc[0] = loadValue(cUnit, rlSrc[0], kCoreReg);
- genNullCheck(cUnit, rlSrc[0].sRegLow, rlSrc[0].lowReg, mir);
- rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true);
- loadWordDisp(cUnit, rlSrc[0].lowReg, lenOffset, rlResult.lowReg);
- storeValue(cUnit, rlDest, rlResult);
+#if 0
+
+ case Instruction::CHECK_CAST:
+ genCheckCast(cUnit, mir, rlSrc[0]);
break;
case Instruction::CONST_CLASS:
@@ -970,18 +1167,10 @@ bool convertMIRNode(CompilationUnit* cUnit, MIR* mir, BasicBlock* bb,
genFillArrayData(cUnit, mir, rlSrc[0]);
break;
- case Instruction::FILLED_NEW_ARRAY:
- genFilledNewArray(cUnit, mir, false /* not range */);
- break;
-
case Instruction::FILLED_NEW_ARRAY_RANGE:
genFilledNewArray(cUnit, mir, true /* range */);
break;
- case Instruction::NEW_ARRAY:
- genNewArray(cUnit, mir, rlDest, rlSrc[0]);
- break;
-
case Instruction::PACKED_SWITCH:
genPackedSwitch(cUnit, mir, rlSrc[0]);
break;
@@ -1001,44 +1190,6 @@ bool convertMIRNode(CompilationUnit* cUnit, MIR* mir, BasicBlock* bb,
genCmpLong(cUnit, mir, rlDest, rlSrc[0], rlSrc[1]);
break;
- case Instruction::AGET_WIDE:
- genArrayGet(cUnit, mir, kLong, rlSrc[0], rlSrc[1], rlDest, 3);
- break;
- case Instruction::AGET:
- case Instruction::AGET_OBJECT:
- genArrayGet(cUnit, mir, kWord, rlSrc[0], rlSrc[1], rlDest, 2);
- break;
- case Instruction::AGET_BOOLEAN:
- genArrayGet(cUnit, mir, kUnsignedByte, rlSrc[0], rlSrc[1], rlDest, 0);
- break;
- case Instruction::AGET_BYTE:
- genArrayGet(cUnit, mir, kSignedByte, rlSrc[0], rlSrc[1], rlDest, 0);
- break;
- case Instruction::AGET_CHAR:
- genArrayGet(cUnit, mir, kUnsignedHalf, rlSrc[0], rlSrc[1], rlDest, 1);
- break;
- case Instruction::AGET_SHORT:
- genArrayGet(cUnit, mir, kSignedHalf, rlSrc[0], rlSrc[1], rlDest, 1);
- break;
- case Instruction::APUT_WIDE:
- genArrayPut(cUnit, mir, kLong, rlSrc[1], rlSrc[2], rlSrc[0], 3);
- break;
- case Instruction::APUT:
- genArrayPut(cUnit, mir, kWord, rlSrc[1], rlSrc[2], rlSrc[0], 2);
- break;
- case Instruction::APUT_OBJECT:
- genArrayObjPut(cUnit, mir, rlSrc[1], rlSrc[2], rlSrc[0], 2);
- break;
- case Instruction::APUT_SHORT:
- case Instruction::APUT_CHAR:
- genArrayPut(cUnit, mir, kUnsignedHalf, rlSrc[1], rlSrc[2], rlSrc[0], 1);
- break;
- case Instruction::APUT_BYTE:
- case Instruction::APUT_BOOLEAN:
- genArrayPut(cUnit, mir, kUnsignedByte, rlSrc[1], rlSrc[2],
- rlSrc[0], 0);
- break;
-
case Instruction::IGET_OBJECT:
//case Instruction::IGET_OBJECT_VOLATILE:
genIGet(cUnit, mir, kWord, rlDest, rlSrc[0], false, true);
@@ -1095,37 +1246,6 @@ bool convertMIRNode(CompilationUnit* cUnit, MIR* mir, BasicBlock* bb,
genIPut(cUnit, mir, kSignedHalf, rlSrc[0], rlSrc[1], false, false);
break;
- case Instruction::SGET_OBJECT:
- genSget(cUnit, mir, rlDest, false, true);
- break;
- case Instruction::SGET:
- case Instruction::SGET_BOOLEAN:
- case Instruction::SGET_BYTE:
- case Instruction::SGET_CHAR:
- case Instruction::SGET_SHORT:
- genSget(cUnit, mir, rlDest, false, false);
- break;
-
- case Instruction::SGET_WIDE:
- genSget(cUnit, mir, rlDest, true, false);
- break;
-
- case Instruction::SPUT_OBJECT:
- genSput(cUnit, mir, rlSrc[0], false, true);
- break;
-
- case Instruction::SPUT:
- case Instruction::SPUT_BOOLEAN:
- case Instruction::SPUT_BYTE:
- case Instruction::SPUT_CHAR:
- case Instruction::SPUT_SHORT:
- genSput(cUnit, mir, rlSrc[0], false, false);
- break;
-
- case Instruction::SPUT_WIDE:
- genSput(cUnit, mir, rlSrc[0], true, false);
- break;
-
case Instruction::NEG_INT:
case Instruction::NOT_INT:
res = genArithOpInt(cUnit, mir, rlDest, rlSrc[0], rlSrc[0]);
@@ -1822,6 +1942,30 @@ void cvtNewInstance(CompilationUnit* cUnit, llvm::CallInst* callInst)
genNewInstance(cUnit, typeIdx, rlDest);
}
+void cvtNewArray(CompilationUnit* cUnit, llvm::CallInst* callInst)
+{
+ DCHECK_EQ(callInst->getNumArgOperands(), 2U);
+ llvm::ConstantInt* typeIdxVal =
+ llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
+ uint32_t typeIdx = typeIdxVal->getZExtValue();
+ llvm::Value* len = callInst->getArgOperand(1);
+ RegLocation rlLen = getLoc(cUnit, len);
+ RegLocation rlDest = getLoc(cUnit, callInst);
+ genNewArray(cUnit, typeIdx, rlDest, rlLen);
+}
+
+void cvtInstanceOf(CompilationUnit* cUnit, llvm::CallInst* callInst)
+{
+ DCHECK_EQ(callInst->getNumArgOperands(), 2U);
+ llvm::ConstantInt* typeIdxVal =
+ llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
+ uint32_t typeIdx = typeIdxVal->getZExtValue();
+ llvm::Value* src = callInst->getArgOperand(1);
+ RegLocation rlSrc = getLoc(cUnit, src);
+ RegLocation rlDest = getLoc(cUnit, callInst);
+ genInstanceof(cUnit, typeIdx, rlDest, rlSrc);
+}
+
void cvtThrowVerificationError(CompilationUnit* cUnit, llvm::CallInst* callInst)
{
DCHECK_EQ(callInst->getNumArgOperands(), 2U);
@@ -1840,6 +1984,37 @@ void cvtThrow(CompilationUnit* cUnit, llvm::CallInst* callInst)
genThrow(cUnit, rlSrc);
}
+void cvtMonitorEnterExit(CompilationUnit* cUnit, bool isEnter,
+ llvm::CallInst* callInst)
+{
+ DCHECK_EQ(callInst->getNumArgOperands(), 2U);
+ llvm::ConstantInt* optFlags =
+ llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
+ llvm::Value* src = callInst->getArgOperand(1);
+ RegLocation rlSrc = getLoc(cUnit, src);
+ if (isEnter) {
+ genMonitorEnter(cUnit, optFlags->getZExtValue(), rlSrc);
+ } else {
+ genMonitorExit(cUnit, optFlags->getZExtValue(), rlSrc);
+ }
+}
+
+void cvtMonitorArrayLength(CompilationUnit* cUnit, llvm::CallInst* callInst)
+{
+ DCHECK_EQ(callInst->getNumArgOperands(), 2U);
+ llvm::ConstantInt* optFlags =
+ llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
+ llvm::Value* src = callInst->getArgOperand(1);
+ RegLocation rlSrc = getLoc(cUnit, src);
+ rlSrc = loadValue(cUnit, rlSrc, kCoreReg);
+ genNullCheck(cUnit, rlSrc.sRegLow, rlSrc.lowReg, optFlags->getZExtValue());
+ RegLocation rlDest = getLoc(cUnit, callInst);
+ RegLocation rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true);
+ int lenOffset = Array::LengthOffset().Int32Value();
+ loadWordDisp(cUnit, rlSrc.lowReg, lenOffset, rlResult.lowReg);
+ storeValue(cUnit, rlDest, rlResult);
+}
+
void cvtMoveException(CompilationUnit* cUnit, llvm::CallInst* callInst)
{
DCHECK_EQ(callInst->getNumArgOperands(), 0U);
@@ -1870,12 +2045,50 @@ void cvtSget(CompilationUnit* cUnit, llvm::CallInst* callInst, bool isWide,
genSget(cUnit, typeIdx, rlDest, isWide, isObject);
}
+void cvtSput(CompilationUnit* cUnit, llvm::CallInst* callInst, bool isWide,
+ bool isObject)
+{
+ DCHECK_EQ(callInst->getNumArgOperands(), 2U);
+ llvm::ConstantInt* typeIdxVal =
+ llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
+ uint32_t typeIdx = typeIdxVal->getZExtValue();
+ llvm::Value* src = callInst->getArgOperand(1);
+ RegLocation rlSrc = getLoc(cUnit, src);
+ genSput(cUnit, typeIdx, rlSrc, isWide, isObject);
+}
+
+void cvtAget(CompilationUnit* cUnit, llvm::CallInst* callInst, OpSize size,
+ int scale)
+{
+ DCHECK_EQ(callInst->getNumArgOperands(), 3U);
+ llvm::ConstantInt* optFlags =
+ llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
+ RegLocation rlArray = getLoc(cUnit, callInst->getArgOperand(1));
+ RegLocation rlIndex = getLoc(cUnit, callInst->getArgOperand(2));
+ RegLocation rlDest = getLoc(cUnit, callInst);
+ genArrayGet(cUnit, optFlags->getZExtValue(), size, rlArray, rlIndex,
+ rlDest, scale);
+}
+
+void cvtAput(CompilationUnit* cUnit, llvm::CallInst* callInst, OpSize size,
+ int scale)
+{
+ DCHECK_EQ(callInst->getNumArgOperands(), 4U);
+ llvm::ConstantInt* optFlags =
+ llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
+ RegLocation rlSrc = getLoc(cUnit, callInst->getArgOperand(1));
+ RegLocation rlArray = getLoc(cUnit, callInst->getArgOperand(2));
+ RegLocation rlIndex = getLoc(cUnit, callInst->getArgOperand(3));
+ genArrayPut(cUnit, optFlags->getZExtValue(), size, rlArray, rlIndex,
+ rlSrc, scale);
+}
+
void cvtInvoke(CompilationUnit* cUnit, llvm::CallInst* callInst,
- greenland::JType jtype)
+ bool isVoid)
{
CallInfo* info = (CallInfo*)oatNew(cUnit, sizeof(CallInfo), true,
kAllocMisc);
- if (jtype == greenland::kVoid) {
+ if (isVoid) {
info->result.location = kLocInvalid;
} else {
info->result = getLoc(cUnit, callInst);
@@ -2061,14 +2274,15 @@ bool methodBitcodeBlockCodeGen(CompilationUnit* cUnit, llvm::BasicBlock* bb)
case greenland::IntrinsicHelper::CheckSuspend:
genSuspendTest(cUnit, 0 /* optFlags already applied */);
break;
- case greenland::IntrinsicHelper::HLInvokeInt:
- cvtInvoke(cUnit, callInst, greenland::kInt);
- break;
case greenland::IntrinsicHelper::HLInvokeObj:
- cvtInvoke(cUnit, callInst, greenland::kObject);
+ case greenland::IntrinsicHelper::HLInvokeFloat:
+ case greenland::IntrinsicHelper::HLInvokeDouble:
+ case greenland::IntrinsicHelper::HLInvokeLong:
+ case greenland::IntrinsicHelper::HLInvokeInt:
+ cvtInvoke(cUnit, callInst, false /* isVoid */);
break;
case greenland::IntrinsicHelper::HLInvokeVoid:
- cvtInvoke(cUnit, callInst, greenland::kVoid);
+ cvtInvoke(cUnit, callInst, true /* isVoid */);
break;
case greenland::IntrinsicHelper::ConstString:
cvtConstString(cUnit, callInst);
@@ -2076,9 +2290,21 @@ bool methodBitcodeBlockCodeGen(CompilationUnit* cUnit, llvm::BasicBlock* bb)
case greenland::IntrinsicHelper::NewInstance:
cvtNewInstance(cUnit, callInst);
break;
- case greenland::IntrinsicHelper::SgetObj:
+ case greenland::IntrinsicHelper::HLSgetObject:
cvtSget(cUnit, callInst, false /* wide */, true /* Object */);
break;
+ case greenland::IntrinsicHelper::HLSget:
+ case greenland::IntrinsicHelper::HLSgetFloat:
+ case greenland::IntrinsicHelper::HLSgetBoolean:
+ case greenland::IntrinsicHelper::HLSgetByte:
+ case greenland::IntrinsicHelper::HLSgetChar:
+ case greenland::IntrinsicHelper::HLSgetShort:
+ cvtSget(cUnit, callInst, false /* wide */, false /* Object */);
+ break;
+ case greenland::IntrinsicHelper::HLSgetWide:
+ case greenland::IntrinsicHelper::HLSgetDouble:
+ cvtSget(cUnit, callInst, true /* wide */, false /* Object */);
+ break;
case greenland::IntrinsicHelper::GetException:
cvtMoveException(cUnit, callInst);
break;
@@ -2086,8 +2312,68 @@ bool methodBitcodeBlockCodeGen(CompilationUnit* cUnit, llvm::BasicBlock* bb)
cvtThrow(cUnit, callInst);
break;
case greenland::IntrinsicHelper::ThrowVerificationError:
- cvtThrow(cUnit, callInst);
+ cvtThrowVerificationError(cUnit, callInst);
+ break;
+ case greenland::IntrinsicHelper::MonitorEnter:
+ cvtMonitorEnterExit(cUnit, true /* isEnter */, callInst);
+ break;
+ case greenland::IntrinsicHelper::MonitorExit:
+ cvtMonitorEnterExit(cUnit, false /* isEnter */, callInst);
+ break;
+ case greenland::IntrinsicHelper::ArrayLength:
+ cvtMonitorArrayLength(cUnit, callInst);
break;
+ case greenland::IntrinsicHelper::NewArray:
+ cvtNewArray(cUnit, callInst);
+ break;
+ case greenland::IntrinsicHelper::InstanceOf:
+ cvtInstanceOf(cUnit, callInst);
+ break;
+
+ case greenland::IntrinsicHelper::HLArrayGet:
+ case greenland::IntrinsicHelper::HLArrayGetObject:
+ case greenland::IntrinsicHelper::HLArrayGetFloat:
+ cvtAget(cUnit, callInst, kWord, 2);
+ break;
+ case greenland::IntrinsicHelper::HLArrayGetWide:
+ case greenland::IntrinsicHelper::HLArrayGetDouble:
+ cvtAget(cUnit, callInst, kLong, 3);
+ break;
+ case greenland::IntrinsicHelper::HLArrayGetBoolean:
+ cvtAget(cUnit, callInst, kUnsignedByte, 0);
+ break;
+ case greenland::IntrinsicHelper::HLArrayGetByte:
+ cvtAget(cUnit, callInst, kSignedByte, 0);
+ break;
+ case greenland::IntrinsicHelper::HLArrayGetChar:
+ cvtAget(cUnit, callInst, kUnsignedHalf, 1);
+ break;
+ case greenland::IntrinsicHelper::HLArrayGetShort:
+ cvtAget(cUnit, callInst, kSignedHalf, 1);
+ break;
+
+ case greenland::IntrinsicHelper::HLArrayPut:
+ case greenland::IntrinsicHelper::HLArrayPutObject:
+ case greenland::IntrinsicHelper::HLArrayPutFloat:
+ cvtAput(cUnit, callInst, kWord, 2);
+ break;
+ case greenland::IntrinsicHelper::HLArrayPutWide:
+ case greenland::IntrinsicHelper::HLArrayPutDouble:
+ cvtAput(cUnit, callInst, kLong, 3);
+ break;
+ case greenland::IntrinsicHelper::HLArrayPutBoolean:
+ cvtAput(cUnit, callInst, kUnsignedByte, 0);
+ break;
+ case greenland::IntrinsicHelper::HLArrayPutByte:
+ cvtAput(cUnit, callInst, kSignedByte, 0);
+ break;
+ case greenland::IntrinsicHelper::HLArrayPutChar:
+ cvtAput(cUnit, callInst, kUnsignedHalf, 1);
+ break;
+ case greenland::IntrinsicHelper::HLArrayPutShort:
+ cvtAput(cUnit, callInst, kSignedHalf, 1);
+ break;
+
case greenland::IntrinsicHelper::UnknownId:
cvtCall(cUnit, callInst, callee);
break;
diff --git a/src/greenland/intrinsic_func_list.def b/src/greenland/intrinsic_func_list.def
index e2a5557..5c8da89 100644
--- a/src/greenland/intrinsic_func_list.def
+++ b/src/greenland/intrinsic_func_list.def
@@ -141,7 +141,7 @@ _EVAL_DEF_INTRINSICS_FUNC(ConstStringFast,
_EXPAND_ARG1(kInt32ConstantTy))
//----------------------------------------------------------------------------
-// New Instance
+// Instance
//----------------------------------------------------------------------------
// JavaObject* dex_lang_new_instance(uint32_t type_idx)
@@ -151,16 +151,23 @@ _EVAL_DEF_INTRINSICS_FUNC(NewInstance,
kJavaObjectTy,
_EXPAND_ARG1(kInt32Ty))
+// bool dex_lang_instance_of(uint32_t type_idx, JavaObject* ref)
+_EVAL_DEF_INTRINSICS_FUNC(InstanceOf,
+ dex_lang_instance_of,
+ kAttrNone,
+ kInt1Ty,
+ _EXPAND_ARG2(kInt32Ty, kJavaObjectTy))
+
//----------------------------------------------------------------------------
// Array
//----------------------------------------------------------------------------
-// uint32_t dex_lang_array_length(JavaObject* array)
+// uint32_t dex_lang_array_length(int32_t opt_flags, JavaObject* array)
_EVAL_DEF_INTRINSICS_FUNC(ArrayLength,
dex_lang_array_length,
kAttrReadOnly | kAttrNoThrow,
kInt32Ty,
- _EXPAND_ARG1(kJavaObjectTy))
+ _EXPAND_ARG2(kInt32Ty, kJavaObjectTy))
// JavaObject* dex_lang_new_array(uint32_t type_idx, uint32_t array_size)
_EVAL_DEF_INTRINSICS_FUNC(NewArray,
@@ -474,6 +481,123 @@ _EVAL_DEF_INTRINSICS_FUNC(InitializeAndLoadClassSSB,
_EXPAND_ARG3(kInt32ConstantTy, kJavaMethodTy, kJavaThreadTy))
//----------------------------------------------------------------------------
+// High-level Array get/put
+//
+// Similar to dex_lang_aget/aput_xxx, but checks not yet performed.
+// OptFlags contain info describing whether frontend has determined that
+// null check and/or array bounds check may be skipped.
+//
+// [type] void dex_lang_hl_aget_[type](int optFlags, JavaObject* array, uint32_t index)
+_EVAL_DEF_INTRINSICS_FUNC(HLArrayGet,
+ dex_lang_hl_aget,
+ kAttrReadOnly | kAttrNoThrow,
+ kInt32Ty,
+ _EXPAND_ARG3(kInt32Ty, kJavaObjectTy, kInt32Ty))
+
+_EVAL_DEF_INTRINSICS_FUNC(HLArrayGetFloat,
+ dex_lang_hl_aget_float,
+ kAttrReadOnly | kAttrNoThrow,
+ kFloatTy,
+ _EXPAND_ARG3(kInt32Ty, kJavaObjectTy, kInt32Ty))
+
+_EVAL_DEF_INTRINSICS_FUNC(HLArrayGetWide,
+ dex_lang_hl_aget_wide,
+ kAttrReadOnly | kAttrNoThrow,
+ kInt64Ty,
+ _EXPAND_ARG3(kInt32Ty, kJavaObjectTy, kInt32Ty))
+
+_EVAL_DEF_INTRINSICS_FUNC(HLArrayGetDouble,
+ dex_lang_hl_aget_double,
+ kAttrReadOnly | kAttrNoThrow,
+ kDoubleTy,
+ _EXPAND_ARG3(kInt32Ty, kJavaObjectTy, kInt32Ty))
+
+_EVAL_DEF_INTRINSICS_FUNC(HLArrayGetObject,
+ dex_lang_hl_aget_object,
+ kAttrReadOnly | kAttrNoThrow,
+ kJavaObjectTy,
+ _EXPAND_ARG3(kInt32Ty, kJavaObjectTy, kInt32Ty))
+
+_EVAL_DEF_INTRINSICS_FUNC(HLArrayGetBoolean,
+ dex_lang_hl_aget_boolean,
+ kAttrReadOnly | kAttrNoThrow,
+ kInt1Ty,
+ _EXPAND_ARG3(kInt32Ty, kJavaObjectTy, kInt32Ty))
+
+_EVAL_DEF_INTRINSICS_FUNC(HLArrayGetByte,
+ dex_lang_hl_aget_byte,
+ kAttrReadOnly | kAttrNoThrow,
+ kInt8Ty,
+ _EXPAND_ARG3(kInt32Ty, kJavaObjectTy, kInt32Ty))
+
+_EVAL_DEF_INTRINSICS_FUNC(HLArrayGetChar,
+ dex_lang_hl_aget_char,
+ kAttrReadOnly | kAttrNoThrow,
+ kInt16Ty,
+ _EXPAND_ARG3(kInt32Ty, kJavaObjectTy, kInt32Ty))
+
+_EVAL_DEF_INTRINSICS_FUNC(HLArrayGetShort,
+ dex_lang_hl_aget_short,
+ kAttrReadOnly | kAttrNoThrow,
+ kInt16Ty,
+ _EXPAND_ARG3(kInt32Ty, kJavaObjectTy, kInt32Ty))
+
+// void dex_lang_aput_[type](int optFlags, [type] value, JavaObject* array, uint32_t index)
+_EVAL_DEF_INTRINSICS_FUNC(HLArrayPut,
+ dex_lang_hl_aput,
+ kAttrNoThrow,
+ kVoidTy,
+ _EXPAND_ARG4(kInt32Ty, kInt32Ty, kJavaObjectTy, kInt32Ty))
+
+_EVAL_DEF_INTRINSICS_FUNC(HLArrayPutFloat,
+ dex_lang_hl_aput_float,
+ kAttrNoThrow,
+ kVoidTy,
+ _EXPAND_ARG4(kInt32Ty, kFloatTy, kJavaObjectTy, kInt32Ty))
+
+_EVAL_DEF_INTRINSICS_FUNC(HLArrayPutWide,
+ dex_lang_hl_aput_wide,
+ kAttrNoThrow,
+ kVoidTy,
+ _EXPAND_ARG4(kInt32Ty, kInt64Ty, kJavaObjectTy, kInt32Ty))
+
+_EVAL_DEF_INTRINSICS_FUNC(HLArrayPutDouble,
+ dex_lang_hl_aput_double,
+ kAttrNoThrow,
+ kVoidTy,
+ _EXPAND_ARG4(kInt32Ty, kDoubleTy, kJavaObjectTy, kInt32Ty))
+
+_EVAL_DEF_INTRINSICS_FUNC(HLArrayPutObject,
+ dex_lang_hl_aput_object,
+ kAttrNoThrow,
+ kVoidTy,
+ _EXPAND_ARG4(kInt32Ty, kJavaObjectTy, kJavaObjectTy, kInt32Ty))
+
+_EVAL_DEF_INTRINSICS_FUNC(HLArrayPutBoolean,
+ dex_lang_hl_aput_boolean,
+ kAttrNoThrow,
+ kVoidTy,
+ _EXPAND_ARG4(kInt32Ty, kInt1Ty, kJavaObjectTy, kInt32Ty))
+
+_EVAL_DEF_INTRINSICS_FUNC(HLArrayPutByte,
+ dex_lang_hl_aput_byte,
+ kAttrNoThrow,
+ kVoidTy,
+ _EXPAND_ARG4(kInt32Ty, kInt8Ty, kJavaObjectTy, kInt32Ty))
+
+_EVAL_DEF_INTRINSICS_FUNC(HLArrayPutChar,
+ dex_lang_hl_aput_char,
+ kAttrNoThrow,
+ kVoidTy,
+ _EXPAND_ARG4(kInt32Ty, kInt16Ty, kJavaObjectTy, kInt32Ty))
+
+_EVAL_DEF_INTRINSICS_FUNC(HLArrayPutShort,
+ dex_lang_hl_aput_short,
+ kAttrNoThrow,
+ kVoidTy,
+ _EXPAND_ARG4(kInt32Ty, kInt16Ty, kJavaObjectTy, kInt32Ty))
+
+//----------------------------------------------------------------------------
// High-level Invokes (fast-path determination not yet performed)
//
// NOTE: We expect these intrinsics to be temporary. Once calling conventions are
@@ -644,18 +768,160 @@ _EVAL_DEF_INTRINSICS_FUNC(CheckSuspend,
kAttrNoThrow,
kVoidTy,
_EXPAND_ARG0())
+//----------------------------------------------------------------------------
+// sput intrinsics to assist MIR to Greenland_ir conversion.
+// "HL" versions - will be deprecated when fast/slow path handling done
+// in the common frontend.
+//----------------------------------------------------------------------------
+
+// void sput_hl(int field_idx, int val)
+_EVAL_DEF_INTRINSICS_FUNC(HLSput,
+ dex_lang_hl_sput,
+ kAttrReadOnly | kAttrNoThrow,
+ kVoidTy,
+ _EXPAND_ARG2(kInt32Ty, kInt32Ty))
+
+// void sput_hl_object(int field_idx, object* val)
+_EVAL_DEF_INTRINSICS_FUNC(HLSputObject,
+ dex_lang_hl_sput_object,
+ kAttrReadOnly | kAttrNoThrow,
+ kVoidTy,
+ _EXPAND_ARG2(kInt32Ty, kJavaObjectTy))
+
+// void sput_hl_boolean(int field_idx, kInt1Ty)
+_EVAL_DEF_INTRINSICS_FUNC(HLSputBoolean,
+ dex_lang_hl_sput_boolean,
+ kAttrReadOnly | kAttrNoThrow,
+ kVoidTy,
+ _EXPAND_ARG2(kInt32Ty, kInt1Ty))
+
+// 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))
+
+// 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))
+
+// 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))
+
+// void sput_hl_wide(int field_idx, long val)
+_EVAL_DEF_INTRINSICS_FUNC(HLSputWide,
+ dex_lang_hl_sput_wide,
+ kAttrReadOnly | kAttrNoThrow,
+ kVoidTy,
+ _EXPAND_ARG2(kInt32Ty, kInt64Ty))
+
+// void sput_hl_double(int field_idx, double val)
+_EVAL_DEF_INTRINSICS_FUNC(HLSputDouble,
+ dex_lang_hl_sput_double,
+ kAttrReadOnly | kAttrNoThrow,
+ kVoidTy,
+ _EXPAND_ARG2(kInt32Ty, kDoubleTy))
+
+// void sput_hl_float(int field_idx, float val)
+_EVAL_DEF_INTRINSICS_FUNC(HLSputFloat,
+ dex_lang_hl_sput_float,
+ kAttrReadOnly | kAttrNoThrow,
+ kVoidTy,
+ _EXPAND_ARG2(kInt32Ty, kFloatTy))
//----------------------------------------------------------------------------
// sget intrinsics to assist MIR to Greenland_ir conversion.
+// "HL" versions - will be deprecated when fast/slow path handling done
+// in the common frontend.
//----------------------------------------------------------------------------
-// object* sget_obj(int field_idx)
-_EVAL_DEF_INTRINSICS_FUNC(SgetObj,
- dex_lang_sget_obj,
+// int sget_hl(int field_idx)
+_EVAL_DEF_INTRINSICS_FUNC(HLSget,
+ dex_lang_hl_sget,
+ kAttrReadOnly | kAttrNoThrow,
+ kInt32Ty,
+ _EXPAND_ARG1(kInt32Ty))
+
+// object* sget_hl_object(int field_idx)
+_EVAL_DEF_INTRINSICS_FUNC(HLSgetObject,
+ dex_lang_hl_sget_object,
kAttrReadOnly | kAttrNoThrow,
kJavaObjectTy,
_EXPAND_ARG1(kInt32Ty))
+// boolean sget_hl_boolean(int field_idx)
+_EVAL_DEF_INTRINSICS_FUNC(HLSgetBoolean,
+ dex_lang_hl_sget_boolean,
+ kAttrReadOnly | kAttrNoThrow,
+ kInt1Ty,
+ _EXPAND_ARG1(kInt32Ty))
+
+// byte sget_hl_byte(int field_idx)
+_EVAL_DEF_INTRINSICS_FUNC(HLSgetByte,
+ dex_lang_hl_sget_byte,
+ kAttrReadOnly | kAttrNoThrow,
+ kInt8Ty,
+ _EXPAND_ARG1(kInt32Ty))
+
+// char sget_hl_char(int field_idx)
+_EVAL_DEF_INTRINSICS_FUNC(HLSgetChar,
+ dex_lang_hl_sget_char,
+ kAttrReadOnly | kAttrNoThrow,
+ kInt16Ty,
+ _EXPAND_ARG1(kInt32Ty))
+
+// char sget_hl_short(int field_idx)
+_EVAL_DEF_INTRINSICS_FUNC(HLSgetShort,
+ dex_lang_hl_sget_short,
+ kAttrReadOnly | kAttrNoThrow,
+ kInt16Ty,
+ _EXPAND_ARG1(kInt32Ty))
+
+// char sget_hl_wide(int field_idx)
+_EVAL_DEF_INTRINSICS_FUNC(HLSgetWide,
+ dex_lang_hl_sget_wide,
+ kAttrReadOnly | kAttrNoThrow,
+ kInt64Ty,
+ _EXPAND_ARG1(kInt32Ty))
+
+// char sget_hl_double(int field_idx)
+_EVAL_DEF_INTRINSICS_FUNC(HLSgetDouble,
+ dex_lang_hl_sget_double,
+ kAttrReadOnly | kAttrNoThrow,
+ kDoubleTy,
+ _EXPAND_ARG1(kInt32Ty))
+
+// char sget_hl_float(int field_idx)
+_EVAL_DEF_INTRINSICS_FUNC(HLSgetFloat,
+ dex_lang_hl_sget_float,
+ kAttrReadOnly | kAttrNoThrow,
+ kFloatTy,
+ _EXPAND_ARG1(kInt32Ty))
+//----------------------------------------------------------------------------
+// Monitor enter/exit
+//----------------------------------------------------------------------------
+// uint32_t dex_lang_monitor_enter(JavaObject* obj)
+_EVAL_DEF_INTRINSICS_FUNC(MonitorEnter,
+ dex_lang_monitor_enter,
+ kAttrReadOnly | kAttrNoThrow,
+ kVoidTy,
+ _EXPAND_ARG1(kJavaObjectTy))
+
+// uint32_t dex_lang_monitor_exit(JavaObject* obj)
+_EVAL_DEF_INTRINSICS_FUNC(MonitorExit,
+ dex_lang_monitor_exit,
+ kAttrReadOnly | kAttrNoThrow,
+ kVoidTy,
+ _EXPAND_ARG1(kJavaObjectTy))
+
//----------------------------------------------------------------------------
// Shadow Frame
//----------------------------------------------------------------------------
diff --git a/test/028-array-write/src/Main.java b/test/028-array-write/src/Main.java
index 9e2826e..2618ff8 100644
--- a/test/028-array-write/src/Main.java
+++ b/test/028-array-write/src/Main.java
@@ -70,13 +70,16 @@ public class Main {
report(start, end);
}
+ public static void array_028() {
+ writeTest();
+ copyTest();
+ System.out.println("Done!");
+ }
+
public static void main(String[] args) {
if ((args.length >= 1) && args[0].equals("--timing")) {
timing = true;
}
-
- writeTest();
- copyTest();
- System.out.println("Done!");
+ array_028();
}
}