| /* |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with |
| * this work for additional information regarding copyright ownership. |
| * The ASF licenses this file to You under the Apache License, Version 2.0 |
| * (the "License"); you may not use this file except in compliance with |
| * the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| /** |
| * @author Intel, Vyacheslav P. Shakin |
| * |
| */ |
| |
| #ifndef _CODEGENINTFC_H_ |
| #define _CODEGENINTFC_H_ |
| |
| #include "open/types.h" |
| #include "Type.h" |
| #include "Jitrino.h" |
| #include "VMInterface.h" |
| #include "Stl.h" |
| |
| |
| |
| namespace Jitrino |
| { |
| |
| // struct ::JitFrameContext; |
| class CG_OpndHandle { |
| }; |
| |
| |
| // "_Ovf" types are used to support CLI's overflow semantics. CLI supports |
| // overflow arithmetic. If an overflow type is used below, generated code must |
| // test for and throw an exception if an overflow occurs. |
| |
| class ArithmeticOp { |
| public: |
| enum Types { |
| I4, I4_Ovf, U4_Ovf, |
| I8, I8_Ovf, U8_Ovf, |
| I, I_Ovf, U_Ovf, |
| F, S, D |
| }; |
| }; |
| |
| class RefArithmeticOp { |
| public: |
| enum Types { |
| I4, I, U4_Ovf, U_Ovf |
| }; |
| }; |
| |
| class IntegerOp { |
| public: |
| enum Types { |
| I4, |
| I8, |
| I |
| }; |
| }; |
| |
| class DivOp { |
| public: |
| enum Types { |
| I4, U4, |
| I8, U8, |
| I, U, |
| F, S, D |
| }; |
| }; |
| |
| class MulHiOp { |
| public: |
| enum Types { |
| I4, U4, I8, U8, I, U |
| }; |
| }; |
| |
| class NegOp { |
| public: |
| enum Types { |
| I4, |
| I8, |
| I, |
| F, S, D |
| }; |
| }; |
| |
| class CompareOp { |
| public: |
| enum Types { |
| I4, |
| I8, |
| I, |
| F, S, D, |
| Ref, |
| CompRef |
| }; |
| enum Operators { |
| Eq, // equal |
| Ne, // int: not equal; |
| // fp: not equal or unordered |
| Gt, // greater than |
| Gtu, // int: greater than unsigned; |
| // fp: greater than or unordered |
| Ge, // greater than or equal |
| Geu // int: greater than or equal unsigned; |
| // fp: greater than or equal or unordered |
| }; |
| }; |
| |
| class CompareZeroOp { |
| public: |
| enum Types { |
| I4, |
| I8, |
| I, |
| Ref, |
| CompRef |
| }; |
| }; |
| |
| class ConvertToIntOp { |
| public: |
| enum Types { |
| I1, I2, I4, I8, I |
| }; |
| enum OverflowMod { |
| NoOvf, |
| SignedOvf, |
| UnsignedOvf |
| }; |
| }; |
| |
| class ConvertToFpOp { |
| public: |
| enum Types { |
| Single, |
| Double, |
| FloatFromUnsigned |
| }; |
| }; |
| |
| class JitHelperCallOp { |
| public: |
| enum Id { |
| Prefetch, |
| Memset0, |
| InitializeArray, |
| FillArrayWithConst, |
| SaveThisState, |
| ReadThisState, |
| LockedCompareAndExchange, |
| AddValueProfileValue, |
| ArrayCopyDirect, |
| ArrayCopyReverse, |
| StringCompareTo, |
| StringRegionMatches, |
| StringIndexOf |
| }; |
| }; |
| |
| class InstructionCallback { |
| public: |
| virtual ~InstructionCallback() {} |
| virtual void opndMaybeGlobal(CG_OpndHandle* opnd) = 0; |
| |
| // tau generating instructions |
| virtual CG_OpndHandle* tauPoint() = 0; // depends on all preceding branches |
| virtual CG_OpndHandle* tauEdge() = 0; // tied to incoming edge |
| virtual CG_OpndHandle* tauAnd(U_32 numArgs, CG_OpndHandle** args) = 0; |
| virtual CG_OpndHandle* tauUnsafe() = 0; // have lost dependence info, don't move uses |
| virtual CG_OpndHandle* tauSafe() = 0; // operation is always safe |
| |
| virtual CG_OpndHandle* add(ArithmeticOp::Types,CG_OpndHandle* src1,CG_OpndHandle* src2) = 0; |
| virtual CG_OpndHandle* addRef(RefArithmeticOp::Types,CG_OpndHandle* refSrc,CG_OpndHandle* intSrc) = 0; |
| virtual CG_OpndHandle* sub(ArithmeticOp::Types,CG_OpndHandle* src1,CG_OpndHandle* src2) = 0; |
| virtual CG_OpndHandle* subRef(RefArithmeticOp::Types,CG_OpndHandle* refSrc, CG_OpndHandle* intSrc) = 0; |
| virtual CG_OpndHandle* diffRef(bool ovf, CG_OpndHandle* ref1,CG_OpndHandle* ref2) = 0; |
| virtual CG_OpndHandle* mul(ArithmeticOp::Types,CG_OpndHandle* src1,CG_OpndHandle* src2) = 0; |
| virtual CG_OpndHandle* tau_div(DivOp::Types,CG_OpndHandle* src1,CG_OpndHandle* src2, |
| CG_OpndHandle *tauSrc1NonZero) = 0; |
| virtual CG_OpndHandle* tau_rem(DivOp::Types,CG_OpndHandle* src1,CG_OpndHandle* src2, |
| CG_OpndHandle *tauSrc2NonZero) = 0; |
| virtual CG_OpndHandle* neg(NegOp::Types,CG_OpndHandle* src) = 0; |
| virtual CG_OpndHandle* mulhi(MulHiOp::Types,CG_OpndHandle* src1,CG_OpndHandle* src2) = 0; |
| virtual CG_OpndHandle* min_op(NegOp::Types,CG_OpndHandle* src1,CG_OpndHandle* src2) = 0; |
| virtual CG_OpndHandle* max_op(NegOp::Types,CG_OpndHandle* src1,CG_OpndHandle* src2) = 0; |
| virtual CG_OpndHandle* abs_op(NegOp::Types,CG_OpndHandle* src1) = 0; |
| virtual CG_OpndHandle* tau_ckfinite(CG_OpndHandle* src) = 0; |
| virtual CG_OpndHandle* and_(IntegerOp::Types,CG_OpndHandle* src1,CG_OpndHandle* src2) = 0; |
| virtual CG_OpndHandle* or_(IntegerOp::Types,CG_OpndHandle* src1,CG_OpndHandle* src2) = 0; |
| virtual CG_OpndHandle* xor_(IntegerOp::Types,CG_OpndHandle* src1,CG_OpndHandle* src2) = 0; |
| virtual CG_OpndHandle* not_(IntegerOp::Types,CG_OpndHandle* src) = 0; |
| virtual CG_OpndHandle* shladd(IntegerOp::Types,CG_OpndHandle* value, |
| U_32 shiftamount, |
| CG_OpndHandle* addto) = 0; |
| virtual CG_OpndHandle* shl(IntegerOp::Types,CG_OpndHandle* value,CG_OpndHandle* shiftAmount) = 0; |
| virtual CG_OpndHandle* shr(IntegerOp::Types,CG_OpndHandle* value,CG_OpndHandle* shiftAmount) = 0; |
| virtual CG_OpndHandle* shru(IntegerOp::Types,CG_OpndHandle* value,CG_OpndHandle* shiftAmount) = 0; |
| virtual CG_OpndHandle* select(CompareOp::Types,CG_OpndHandle* src1,CG_OpndHandle* src2, |
| CG_OpndHandle* src3) = 0; |
| // BEGIN PRED DEPRECATED |
| virtual CG_OpndHandle* cmp(CompareOp::Operators,CompareOp::Types, CG_OpndHandle* src1,CG_OpndHandle* src2,int ifNaNResult=0) = 0; |
| virtual CG_OpndHandle* cmp3(CompareOp::Operators,CompareOp::Types,CG_OpndHandle* src1,CG_OpndHandle* src2) { return 0; }; |
| virtual CG_OpndHandle* czero(CompareZeroOp::Types,CG_OpndHandle* src) = 0; |
| virtual CG_OpndHandle* cnzero(CompareZeroOp::Types,CG_OpndHandle* src) = 0; |
| // END PRED DEPRECATED |
| |
| // result is a predicate |
| virtual CG_OpndHandle* pred_czero(CompareZeroOp::Types,CG_OpndHandle* src) = 0; |
| virtual CG_OpndHandle* pred_cnzero(CompareZeroOp::Types,CG_OpndHandle* src) = 0; |
| |
| // BEGIN PRED DEPRECATED |
| virtual void branch(CompareOp::Operators,CompareOp::Types,CG_OpndHandle* src1,CG_OpndHandle* src2) = 0; |
| virtual void bzero(CompareZeroOp::Types,CG_OpndHandle* src) = 0; |
| virtual void bnzero(CompareZeroOp::Types,CG_OpndHandle* src) = 0; |
| // END PRED DEPRECATED |
| |
| virtual void jump() = 0; |
| virtual void tableSwitch(CG_OpndHandle* src, U_32 nTargets) = 0; |
| virtual void throwException(CG_OpndHandle* exceptionObj, bool createStackTrace) = 0; |
| virtual void throwSystemException(CompilationInterface::SystemExceptionId) = 0; |
| virtual void throwLinkingException(Class_Handle encClass, U_32 cp_ndx, U_32 opcode) = 0; |
| |
| /// convert unmanaged pointer to object. Boxing |
| virtual CG_OpndHandle* convUPtrToObject(ObjectType * dstType, CG_OpndHandle* val) = 0; |
| /// convert object or integer to unmanaged pointer. Unboxing |
| virtual CG_OpndHandle* convToUPtr(PtrType * dstType, CG_OpndHandle* op) = 0; |
| |
| virtual CG_OpndHandle* convToInt(ConvertToIntOp::Types, bool isSigned, bool isZeroExtend, |
| ConvertToIntOp::OverflowMod, |
| Type* dstType, CG_OpndHandle* src) = 0; |
| virtual CG_OpndHandle* convToFp(ConvertToFpOp::Types, Type* dstType, CG_OpndHandle* src) = 0; |
| |
| virtual CG_OpndHandle* ldFunAddr(Type* dstType, MethodDesc *desc) = 0; |
| virtual CG_OpndHandle* tau_ldVirtFunAddr(Type* dstType, CG_OpndHandle* vtableAddr, |
| MethodDesc *desc, |
| CG_OpndHandle *tauVtableHasDesc) = 0; |
| virtual CG_OpndHandle* tau_ldVTableAddr(Type *dstType, CG_OpndHandle* base, |
| CG_OpndHandle *tauBaseNonNull) = 0; |
| virtual CG_OpndHandle* getVTableAddr(Type *dstType, ObjectType *base) = 0; |
| virtual CG_OpndHandle* getClassObj(Type *dstType, ObjectType *base) = 0; |
| virtual CG_OpndHandle* tau_ldIntfTableAddr(Type *dstType, CG_OpndHandle* base, |
| NamedType* vtableType) = 0; |
| virtual CG_OpndHandle* call(U_32 numArgs, CG_OpndHandle** args, Type* retType, |
| MethodDesc *desc) = 0; |
| virtual CG_OpndHandle* tau_call(U_32 numArgs, CG_OpndHandle** args, Type* retType, |
| MethodDesc *desc, |
| CG_OpndHandle *tauNullChecked, |
| CG_OpndHandle *tauTypesChecked) = 0; |
| // for callvirt this reference is in args[0] |
| virtual CG_OpndHandle* tau_callvirt(U_32 numArgs, CG_OpndHandle** args, Type* retType, |
| MethodDesc *desc, CG_OpndHandle* tauNullChecked, |
| CG_OpndHandle* tauTypesChecked) = 0; |
| virtual CG_OpndHandle* tau_calli(U_32 numArgs,CG_OpndHandle** args, Type* retType, |
| CG_OpndHandle* methodPtr, |
| CG_OpndHandle* tauNullChecked, |
| CG_OpndHandle* tauTypesChecked) = 0; |
| virtual CG_OpndHandle* callhelper(U_32 numArgs, CG_OpndHandle** args, Type* retType, |
| JitHelperCallOp::Id callId) = 0; |
| virtual CG_OpndHandle* callvmhelper(U_32 numArgs, CG_OpndHandle** args, Type* retType, |
| VM_RT_SUPPORT callId) = 0; |
| |
| virtual CG_OpndHandle* ldc_i4(I_32 val) = 0; |
| virtual CG_OpndHandle* ldc_i8(int64 val) = 0; |
| virtual CG_OpndHandle* ldc_s(float val) = 0; |
| virtual CG_OpndHandle* ldc_d(double val) = 0; |
| virtual CG_OpndHandle* ldnull(bool compressed) = 0; |
| |
| // result of each of these is now a tau |
| // if a negative result is needed, use a tau_point() on the exception handler |
| virtual CG_OpndHandle* tau_checkNull(CG_OpndHandle* base, bool checksThisForInlinedMethod) = 0; |
| virtual CG_OpndHandle* tau_checkBounds(CG_OpndHandle* arrayLen, CG_OpndHandle *index) = 0; |
| virtual CG_OpndHandle* tau_checkLowerBound(CG_OpndHandle* a, CG_OpndHandle *b) = 0; // throw if (a > b), unsigned if pointer |
| virtual CG_OpndHandle* tau_checkUpperBound(CG_OpndHandle* a, CG_OpndHandle *b) = 0; // throw if (a >= b) |
| virtual CG_OpndHandle* tau_checkElemType(CG_OpndHandle* array, CG_OpndHandle *src, |
| CG_OpndHandle* tauNullChecked, |
| CG_OpndHandle* tauIsArray) = 0; |
| virtual CG_OpndHandle* tau_checkZero(CG_OpndHandle* src) = 0; |
| virtual CG_OpndHandle* tau_checkDivOpnds(CG_OpndHandle* src1, CG_OpndHandle *src2) = 0; |
| |
| virtual CG_OpndHandle* tau_checkCast(ObjectType *toType, CG_OpndHandle* obj, |
| CG_OpndHandle* tauCheckedNull) = 0; // for lowered cast |
| |
| // *** begin 32-bit pointers: |
| virtual CG_OpndHandle* uncompressRef(CG_OpndHandle *compref) = 0; |
| virtual CG_OpndHandle* compressRef(CG_OpndHandle *ref) = 0; |
| |
| // yields an Offset |
| virtual CG_OpndHandle* ldFieldOffset(FieldDesc *desc) = 0; |
| // yields an OffsetPlusHeapbase |
| virtual CG_OpndHandle* ldFieldOffsetPlusHeapbase(FieldDesc *desc) = 0; |
| |
| // yields an Offset |
| virtual CG_OpndHandle* ldArrayBaseOffset(Type *elemType) = 0; |
| // yields an Offset |
| virtual CG_OpndHandle* ldArrayLenOffset(Type *elemType) = 0; |
| // yields an OffsetPlusHeapbase |
| virtual CG_OpndHandle* ldArrayBaseOffsetPlusHeapbase(Type *elemType) = 0; |
| // yields an OffsetPlusHeapbase |
| virtual CG_OpndHandle* ldArrayLenOffsetPlusHeapbase(Type *elemType) = 0; |
| |
| // takes an uncompressed reference ref and an Offset fieldOffset, |
| // yields a managed pointer of type fieldRefType: |
| virtual CG_OpndHandle* addOffset(Type *pointerType, CG_OpndHandle* ref, |
| CG_OpndHandle* fieldOffset) = 0; |
| // takes a compressed reference compRef and an OffsetPlusHeapbase, |
| // yields a managed pointer of type fieldRefType: |
| virtual CG_OpndHandle* addOffsetPlusHeapbase(Type *pointerType, |
| CG_OpndHandle* compRef, |
| CG_OpndHandle* fieldOffsetPlusHeapbase) = 0; |
| |
| // *** end 32-bit pointers |
| |
| // COMPRESSED_PTR note: if we are using compressed references, and |
| // field is a reference, then result type should be |
| // Ptr<CompressedRef>; otherwise, it is Ptr<Ref>. |
| virtual CG_OpndHandle* ldFieldAddr(Type* fieldRefType,CG_OpndHandle* base,FieldDesc *desc) = 0; |
| virtual CG_OpndHandle* ldStaticAddr(Type* fieldRefType,FieldDesc *desc) = 0; |
| virtual CG_OpndHandle* ldElemBaseAddr(CG_OpndHandle* array) = 0; |
| virtual CG_OpndHandle* addElemIndex(Type*, CG_OpndHandle *elemBase,CG_OpndHandle* index) = 0; |
| virtual CG_OpndHandle* addElemIndexWithLEA(Type*, CG_OpndHandle *elemBase,CG_OpndHandle* index) = 0; |
| virtual CG_OpndHandle* ldElemAddr(CG_OpndHandle* array,CG_OpndHandle* index) = 0; |
| // COMPRESSED_PTR note: |
| // if we are using compressed references, and ptr is Ptr<CompressedRef>, then |
| // if autoUncompressRef, then result is uncompressed by CG and is of type Ref |
| // otherwise, result is of type CompressedRef and optimizer will handle it |
| // TAU note: |
| // tau_addressInRange = (for array reference) tau_isarray && tau_inbounds |
| // (for field reference) tau_hastype |
| // (for static reference) special AlwaysTrueTau |
| // (for speculative reference) special AlwaysFalseTau |
| // (for array length) chknull tau |
| virtual CG_OpndHandle* tau_ldInd(Type* dstType, CG_OpndHandle* ptr, Type::Tag memType, |
| bool autoUncompressRef, bool speculate, |
| CG_OpndHandle* tauBaseNonNull, |
| CG_OpndHandle* tauaddressInRange) = 0; |
| // COMPRESSED_PTR note: similar here, except field type determines behavior |
| virtual CG_OpndHandle* ldStatic(Type *dstType, FieldDesc *desc, Type::Tag fieldType, |
| bool autoUncompressRef) = 0; |
| virtual CG_OpndHandle* tau_ldField(Type *dstType, CG_OpndHandle* base, Type::Tag fieldType, |
| FieldDesc *desc, bool autoUncompressRef, |
| CG_OpndHandle* tauBaseNonNull, |
| CG_OpndHandle* tauBaseTypeHasField) = 0; |
| virtual CG_OpndHandle* tau_ldElem(Type *dstType, CG_OpndHandle* array, CG_OpndHandle* index, |
| bool autoUncompressRef, |
| CG_OpndHandle* tauBaseNonNull, |
| CG_OpndHandle* tauIdxIsInBounds) = 0; |
| // COMPRESSED_PTR note: var is already uncompressed, so compression doesn't affect these: |
| virtual CG_OpndHandle* ldVarAddr(U_32 varId) = 0; |
| virtual CG_OpndHandle* ldVar(Type* dstType, U_32 varId) = 0; |
| virtual CG_OpndHandle* tau_arrayLen(Type* dstType, ArrayType* arrayType, Type* lenType, |
| CG_OpndHandle* array, |
| CG_OpndHandle* tauArrayNonNull, |
| CG_OpndHandle* tauIsArray) = 0; |
| |
| // COMPRESSED_PTR note: If we are using compressed references, and |
| // ptr is Ptr<Compressed Ref>, then |
| // (1) if autoCompressRef, then src should be Ref and CG will compress |
| // it on store; type is uncompressedRef type |
| // (2) if !autoCompressRef, then src should be CompressedRef; type is |
| // compressedRef type |
| virtual void tau_stInd(CG_OpndHandle* src, CG_OpndHandle* ptr, Type::Tag memType, |
| bool autoCompressRef, |
| CG_OpndHandle* tauBaseNonNull, |
| CG_OpndHandle* tauAddressInRange, |
| CG_OpndHandle* tauElemTypeChecked) = 0; |
| // COMPRESSED_PTR note: similar here |
| virtual void tau_stStatic(CG_OpndHandle* src, FieldDesc *desc, Type::Tag fieldType, |
| bool autoCompressRef, |
| CG_OpndHandle* tauFieldTypeChecked) = 0; |
| virtual void tau_stField(CG_OpndHandle* src, CG_OpndHandle* base, Type::Tag fieldType, |
| FieldDesc *desc, bool autoCompress, |
| CG_OpndHandle* tauBaseNonNull, |
| CG_OpndHandle* tauBaseTypeHasField, |
| CG_OpndHandle* tauFieldTypeChecked) = 0; |
| virtual void tau_stElem(CG_OpndHandle* src, CG_OpndHandle* array, |
| CG_OpndHandle* index, |
| bool autoCompress, |
| CG_OpndHandle* tauBaseNonNull, |
| CG_OpndHandle* tauAddressInRange, |
| CG_OpndHandle* tauElemTypeChecked) = 0; |
| virtual void tau_stRef(CG_OpndHandle* src, CG_OpndHandle* ptr, CG_OpndHandle* base, Type::Tag memType, |
| bool autoCompressRef, |
| CG_OpndHandle* tauBaseNonNull, |
| CG_OpndHandle* tauAddressInRange, |
| CG_OpndHandle* tauElemTypeChecked) = 0; |
| // COMPRESSED_PTR note: var is already uncompressed, so compression doesn't affect it |
| virtual void stVar(CG_OpndHandle* src, U_32 varId) = 0; |
| |
| virtual CG_OpndHandle* newObj(ObjectType* objType) = 0; |
| virtual CG_OpndHandle* newArray(ArrayType* arrayType, CG_OpndHandle* numElems) = 0; |
| virtual CG_OpndHandle* newMultiArray(ArrayType* arrayType, U_32 numDims, CG_OpndHandle** dims) = 0; |
| virtual CG_OpndHandle* ldRef(Type* type,MethodDesc* enclosingMethod,U_32 stringToken, bool autouncompress) = 0; |
| virtual void incCounter(Type *counterType,U_32 counter) = 0; |
| |
| virtual void ret() = 0; |
| virtual void ret(CG_OpndHandle* returnValue) = 0; |
| virtual CG_OpndHandle* defArg(U_32 position,Type *type) = 0; |
| |
| virtual void tau_monitorEnter(CG_OpndHandle* obj, |
| CG_OpndHandle* tauIsNonNull) = 0; |
| virtual void tau_monitorExit(CG_OpndHandle* obj, |
| CG_OpndHandle* tauIsNonNull) = 0; |
| virtual CG_OpndHandle* ldLockAddr(CG_OpndHandle* obj) = 0; |
| virtual CG_OpndHandle* tau_balancedMonitorEnter(CG_OpndHandle* obj, CG_OpndHandle* lockAddr, |
| CG_OpndHandle* tauIsNonNull) = 0; |
| // null-check dependence is threaded through oldLock from tau_balancedMonitorEnter |
| virtual void balancedMonitorExit(CG_OpndHandle* obj, CG_OpndHandle* lockAddr, |
| CG_OpndHandle* oldLoc) = 0; |
| virtual CG_OpndHandle* tau_optimisticBalancedMonitorEnter(CG_OpndHandle* obj, |
| CG_OpndHandle* lockAddr, |
| CG_OpndHandle* tauIsNonNull) = 0; |
| // null-check dependence is threaded through oldLock from tau_optimisticBalancedMonitorEnter |
| virtual void optimisticBalancedMonitorExit(CG_OpndHandle* obj, |
| CG_OpndHandle* lockAddr, |
| CG_OpndHandle* oldLoc) = 0; |
| // null-check dependence is threaded through oldLock from tau_optimisticBalancedMonitorEnter |
| virtual void incRecursionCount(CG_OpndHandle* obj, CG_OpndHandle* oldLock) = 0; |
| virtual void monitorEnterFence(CG_OpndHandle* obj) = 0; |
| virtual void monitorExitFence(CG_OpndHandle* obj) = 0; |
| virtual void typeMonitorEnter(NamedType *type) = 0; |
| virtual void typeMonitorExit(NamedType *type) = 0; |
| |
| virtual CG_OpndHandle* tau_staticCast(ObjectType *toType, CG_OpndHandle* obj, |
| CG_OpndHandle* tauIsType) = 0; |
| virtual CG_OpndHandle* tau_cast(ObjectType *toType, CG_OpndHandle* obj, |
| CG_OpndHandle* tauCheckedNull) = 0; |
| virtual CG_OpndHandle* tau_asType(ObjectType* type, CG_OpndHandle* obj, |
| CG_OpndHandle* tauCheckedNull) = 0; |
| virtual CG_OpndHandle* tau_instanceOf(ObjectType *type, CG_OpndHandle* obj, |
| CG_OpndHandle* tauCheckedNull) = 0; |
| virtual void initType(Type* type) = 0; |
| virtual CG_OpndHandle* box(ObjectType * dstType, CG_OpndHandle* val) = 0; |
| virtual CG_OpndHandle* unbox(Type * dstType, CG_OpndHandle* obj) = 0; |
| virtual CG_OpndHandle* ldValueObj(Type* objType, CG_OpndHandle *srcAddr) = 0; |
| virtual void stValueObj(CG_OpndHandle *dstAddr, CG_OpndHandle *src) = 0; |
| virtual void initValueObj(Type* objType, CG_OpndHandle *objAddr) = 0; |
| virtual void copyValueObj(Type* objType, CG_OpndHandle *dstAddr, CG_OpndHandle *srcAddr) = 0; |
| virtual CG_OpndHandle* copy(CG_OpndHandle *src) = 0; |
| virtual CG_OpndHandle* catchException(Type * exceptionType) = 0; |
| virtual void prefetch(CG_OpndHandle *addr) = 0; |
| |
| virtual void pseudoInst() = 0; |
| |
| virtual void methodEntry(MethodDesc* mDesc) = 0; |
| virtual void methodEnd(MethodDesc* mDesc, CG_OpndHandle* retVallue = NULL) = 0; |
| |
| // Set the current persistent instruction id associated with any subsequently generated instructions. |
| virtual void setCurrentPersistentId(PersistentInstructionId persistentId) = 0; |
| |
| // Clear the current persistent instruction id. |
| // Any subsequently generated instructions have no associated ID. |
| virtual void clearCurrentPersistentId() = 0; |
| // Set current HIR instruction bytecode offset |
| virtual void setCurrentHIRInstBCOffset(uint16 val) = 0; |
| virtual uint16 getCurrentHIRInstBCOffset() const = 0; |
| private: |
| }; |
| |
| // |
| // interface for generating code for a variable |
| // |
| class VarCodeSelector { |
| public: |
| virtual ~VarCodeSelector() {} |
| class Callback { |
| public: |
| virtual ~Callback() {} |
| virtual U_32 defVar(Type* varType,bool isAddressTaken,bool isPinned) = 0; |
| virtual void setManagedPointerBase(U_32 managedPtrVarNum, U_32 baseVarNum) = 0; |
| }; |
| virtual void genCode(Callback&) = 0; |
| }; |
| |
| // |
| // interface for generating code for a basic block |
| // |
| class BlockCodeSelector { |
| public: |
| virtual ~BlockCodeSelector() {} |
| virtual void genCode(InstructionCallback&) = 0; |
| }; |
| |
| // |
| // interface for generating code for a control-flow graph |
| // |
| class CFGCodeSelector { |
| public: |
| virtual ~CFGCodeSelector() {} |
| class Callback { |
| public: |
| enum BlockKind {Prolog, InnerBlock, Epilog}; |
| virtual ~Callback() {} |
| virtual U_32 genDispatchNode(U_32 numInEdges,U_32 numOutEdges, const StlVector<MethodDesc*>& inlineEndMarkers, double cnt) = 0; |
| virtual U_32 genBlock(U_32 numInEdges,U_32 numOutEdges, BlockKind blockKind, |
| BlockCodeSelector&, double cnt) = 0; |
| virtual U_32 genUnwindNode(U_32 numInEdges, U_32 numOutEdges,double cnt) = 0; |
| virtual U_32 genExitNode(U_32 numInEdges, double cnt) = 0; |
| virtual void genUnconditionalEdge(U_32 tailNodeId,U_32 headNodeId,double prob) = 0; |
| virtual void genTrueEdge(U_32 tailNodeId,U_32 headNodeId,double prob) = 0; |
| virtual void genFalseEdge(U_32 tailNodeId,U_32 headNodeId, double prob) = 0; |
| virtual void genSwitchEdges(U_32 tailNodeId, U_32 numTargets, |
| U_32 *targets, double *probs, U_32 defaultTarget) = 0; |
| virtual void genExceptionEdge(U_32 tailNodeId, U_32 headNodeId, double prob) = 0; |
| virtual void genCatchEdge(U_32 tailNodeId,U_32 headNodeId, |
| U_32 priority,Type* exceptionType, double prob) = 0; |
| |
| // Set the persistent block ID for a given block. |
| virtual void setPersistentId(U_32 nodeId, U_32 persistentId) = 0; |
| }; |
| virtual void genCode(Callback&) = 0; |
| }; |
| // |
| // interface for generating code for a method |
| // |
| class MethodCodeSelector { |
| public: |
| MethodCodeSelector() {} |
| virtual ~MethodCodeSelector() {} |
| class Callback { |
| public: |
| virtual void genVars(U_32 numLocals,VarCodeSelector&) = 0; |
| virtual void setMethodDesc(MethodDesc * desc) = 0; |
| virtual void genCFG(U_32 numNodes,CFGCodeSelector&,bool useProfile) = 0; |
| virtual ~Callback() {} |
| }; |
| virtual void selectCode(Callback&) = 0; |
| }; |
| |
| class SessionAction; |
| class CodeGenerator { |
| public: |
| virtual ~CodeGenerator() {} |
| virtual void genCode(SessionAction* sa, MethodCodeSelector&) = 0; |
| }; |
| |
| class CodeGeneratorFactory { |
| public: |
| virtual ~CodeGeneratorFactory() {} |
| virtual CodeGenerator* getCodeGenerator(MemoryManager &mm, |
| CompilationInterface& compInterface) = 0; |
| }; |
| |
| } |
| #endif // _CODEGENINTFC_H_ |