diff options
author | buzbee <buzbee@google.com> | 2012-06-27 15:44:52 -0700 |
---|---|---|
committer | buzbee <buzbee@google.com> | 2012-06-27 15:44:52 -0700 |
commit | 8fa0fda8e1b6aa0a759990b3d32b78bb08065e0f (patch) | |
tree | 4e87b99f5afdc564ee27eb3902e48d52c8795720 | |
parent | 6613de3585d726a246b5ee2597ddaef8b3c3a621 (diff) | |
download | art-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.cc | 4 | ||||
-rw-r--r-- | src/compiler/codegen/MethodBitcode.cc | 576 | ||||
-rw-r--r-- | src/greenland/intrinsic_func_list.def | 278 | ||||
-rw-r--r-- | test/028-array-write/src/Main.java | 11 |
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(); } } |