diff options
Diffstat (limited to 'src/compiler/codegen/compiler_codegen.h')
| -rw-r--r-- | src/compiler/codegen/compiler_codegen.h | 250 |
1 files changed, 250 insertions, 0 deletions
diff --git a/src/compiler/codegen/compiler_codegen.h b/src/compiler/codegen/compiler_codegen.h new file mode 100644 index 0000000000..45838c1465 --- /dev/null +++ b/src/compiler/codegen/compiler_codegen.h @@ -0,0 +1,250 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed 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. + */ + +#ifndef ART_SRC_COMPILER_COMPILERCODEGEN_H_ +#define ART_SRC_COMPILER_COMPILERCODEGEN_H_ + +#include "../compiler_ir.h" + +namespace art { + + +// Set to 1 to measure cost of suspend check +#define NO_SUSPEND 0 + +/* Bit flags describing the behavior of native opcodes (Arm/Mips/x86 combined) */ +enum OpFeatureFlags { + kIsBranch = 0, + kNoOperand, + kIsUnaryOp, + kIsBinaryOp, + kIsTertiaryOp, + kIsQuadOp, + kIsQuinOp, + kIsSextupleOp, + kIsIT, + kMemLoad, + kMemStore, + kPCRelFixup, // x86 FIXME: add NEEDS_FIXUP to instruction attributes + kRegDef0, + kRegDef1, + kRegDefA, + kRegDefD, + kRegDefFPCSList0, + kRegDefFPCSList2, + kRegDefList0, + kRegDefList1, + kRegDefList2, + kRegDefLR, + kRegDefSP, + kRegUse0, + kRegUse1, + kRegUse2, + kRegUse3, + kRegUse4, + kRegUseA, + kRegUseC, + kRegUseD, + kRegUseFPCSList0, + kRegUseFPCSList2, + kRegUseList0, + kRegUseList1, + kRegUseLR, + kRegUsePC, + kRegUseSP, + kSetsCCodes, + kUsesCCodes +}; + +#define IS_BINARY_OP (1ULL << kIsBinaryOp) +#define IS_BRANCH (1ULL << kIsBranch) +#define IS_IT (1ULL << kIsIT) +#define IS_LOAD (1ULL << kMemLoad) +#define IS_QUAD_OP (1ULL << kIsQuadOp) +#define IS_QUIN_OP (1ULL << kIsQuinOp) +#define IS_SEXTUPLE_OP (1ULL << kIsSextupleOp) +#define IS_STORE (1ULL << kMemStore) +#define IS_TERTIARY_OP (1ULL << kIsTertiaryOp) +#define IS_UNARY_OP (1ULL << kIsUnaryOp) +#define NEEDS_FIXUP (1ULL << kPCRelFixup) +#define NO_OPERAND (1ULL << kNoOperand) +#define REG_DEF0 (1ULL << kRegDef0) +#define REG_DEF1 (1ULL << kRegDef1) +#define REG_DEFA (1ULL << kRegDefA) +#define REG_DEFD (1ULL << kRegDefD) +#define REG_DEF_FPCS_LIST0 (1ULL << kRegDefFPCSList0) +#define REG_DEF_FPCS_LIST2 (1ULL << kRegDefFPCSList2) +#define REG_DEF_LIST0 (1ULL << kRegDefList0) +#define REG_DEF_LIST1 (1ULL << kRegDefList1) +#define REG_DEF_LR (1ULL << kRegDefLR) +#define REG_DEF_SP (1ULL << kRegDefSP) +#define REG_USE0 (1ULL << kRegUse0) +#define REG_USE1 (1ULL << kRegUse1) +#define REG_USE2 (1ULL << kRegUse2) +#define REG_USE3 (1ULL << kRegUse3) +#define REG_USE4 (1ULL << kRegUse4) +#define REG_USEA (1ULL << kRegUseA) +#define REG_USEC (1ULL << kRegUseC) +#define REG_USED (1ULL << kRegUseD) +#define REG_USE_FPCS_LIST0 (1ULL << kRegUseFPCSList0) +#define REG_USE_FPCS_LIST2 (1ULL << kRegUseFPCSList2) +#define REG_USE_LIST0 (1ULL << kRegUseList0) +#define REG_USE_LIST1 (1ULL << kRegUseList1) +#define REG_USE_LR (1ULL << kRegUseLR) +#define REG_USE_PC (1ULL << kRegUsePC) +#define REG_USE_SP (1ULL << kRegUseSP) +#define SETS_CCODES (1ULL << kSetsCCodes) +#define USES_CCODES (1ULL << kUsesCCodes) + +/* Common combo register usage patterns */ +#define REG_DEF01 (REG_DEF0 | REG_DEF1) +#define REG_DEF01_USE2 (REG_DEF0 | REG_DEF1 | REG_USE2) +#define REG_DEF0_USE01 (REG_DEF0 | REG_USE01) +#define REG_DEF0_USE0 (REG_DEF0 | REG_USE0) +#define REG_DEF0_USE12 (REG_DEF0 | REG_USE12) +#define REG_DEF0_USE1 (REG_DEF0 | REG_USE1) +#define REG_DEF0_USE2 (REG_DEF0 | REG_USE2) +#define REG_DEFAD_USEAD (REG_DEFAD_USEA | REG_USED) +#define REG_DEFAD_USEA (REG_DEFA_USEA | REG_DEFD) +#define REG_DEFA_USEA (REG_DEFA | REG_USEA) +#define REG_USE012 (REG_USE01 | REG_USE2) +#define REG_USE014 (REG_USE01 | REG_USE4) +#define REG_USE01 (REG_USE0 | REG_USE1) +#define REG_USE02 (REG_USE0 | REG_USE2) +#define REG_USE12 (REG_USE1 | REG_USE2) +#define REG_USE23 (REG_USE2 | REG_USE3) + +LIR* rawLIR(CompilationUnit* cUnit, int dalvikOffset, int opcode, int op0 = 0, + int op1 = 0, int op2 = 0, int op3 = 0, int op4 = 0, + LIR* target = NULL); + +int oatGetInsnSize(LIR* lir); + +void genFusedLongCmpBranch(CompilationUnit* cUnit, BasicBlock* bb, MIR* mir); +void genFusedFPCmpBranch(CompilationUnit* cUnit, BasicBlock* bb, MIR* mir, + bool gtBias, bool isDouble); + +CallInfo* oatNewCallInfo(CompilationUnit* cUnit, BasicBlock* bb, MIR* mir, + InvokeType type, bool isRange); + +/* Lower middle-level IR to low-level IR for the whole method */ +void oatMethodMIR2LIR(CompilationUnit* cUnit); + +/* Bitcode conversions */ +void oatMethodMIR2Bitcode(CompilationUnit* cUnit); +void oatMethodBitcode2LIR(CompilationUnit* cUnit); + +/* Lower middle-level IR to low-level IR for the simple methods */ +void oatSpecialMIR2LIR(CompilationUnit* cUnit, SpecialCaseHandler specialCase ); + +/* Assemble LIR into machine code */ +void oatAssembleLIR(CompilationUnit* cUnit); +AssemblerStatus oatAssembleInstructions(CompilationUnit* cUnit, + intptr_t startAddr); +void oatAssignOffsets(CompilationUnit* cUnit); +int oatAssignInsnOffsets(CompilationUnit* cUnit); + +/* Implemented in the codegen/<target>/ArchUtility.c */ +void oatCodegenDump(CompilationUnit* cUnit); +void oatDumpPromotionMap(CompilationUnit* cUnit); +std::string buildInsnString(const char* fmt, LIR* lir, + unsigned char* baseAddr); + + +/* Implemented in codegen/<target>/Ralloc.c */ +void oatSimpleRegAlloc(CompilationUnit* cUnit); + +/* Implemented in codegen/<target>/Thumb<version>Util.c */ +void oatInitializeRegAlloc(CompilationUnit* cUnit); + +/* Implemented in codegen/<target>/<target_variant>/ArchVariant.c */ +InstructionSet oatInstructionSet(); + +/* + * Implemented in codegen/<target>/<target_variant>/ArchVariant.c + * Architecture-specific initializations and checks + */ +bool oatArchVariantInit(void); + +/* Implemented in codegen/<target>/<target_variant>/ArchVariant.c */ +int oatTargetOptHint(int key); + +/* Implemented in codegen/<target>/<target_variant>/ArchVariant.c */ +void oatGenMemBarrier(CompilationUnit* cUnit, int barrierKind); + +LIR* genRegMemCheck(CompilationUnit* cUnit, ConditionCode cCode, + int reg1, int base, int offset, ThrowKind kind); +LIR* opThreadMem(CompilationUnit* cUnit, OpKind op, int threadOffset); +LIR* opMem(CompilationUnit* cUnit, OpKind op, int rBase, int disp); +LIR* storeBaseIndexedDisp(CompilationUnit *cUnit, + int rBase, int rIndex, int scale, int displacement, + int rSrc, int rSrcHi, OpSize size, int sReg); +LIR* opRegMem(CompilationUnit *cUnit, OpKind op, int rDest, int rBase, int offset); +LIR* opCmpBranch(CompilationUnit* cUnit, ConditionCode cond, int src1, + int src2, LIR* target); +void oatSetupRegMask(CompilationUnit* cUnit, u8* mask, int reg); +u8 oatGetRegMaskCommon(CompilationUnit* cUnit, int reg); +void setupTargetResourceMasks(CompilationUnit* cUnit, LIR* lir); +RegLocation genDivRem(CompilationUnit* cUnit, RegLocation rlDest, int regLo, int regHi, bool isDiv); +RegLocation genDivRemLit(CompilationUnit* cUnit, RegLocation rlDest, int regLo, int lit, bool isDiv); +void markGCCard(CompilationUnit* cUnit, int valReg, int tgtAddrReg); +bool genInlinedMinMaxInt(CompilationUnit *cUnit, CallInfo* info, bool isMin); +void opLea(CompilationUnit* cUnit, int rBase, int reg1, int reg2, int scale, int offset); +void opTlsCmp(CompilationUnit* cUnit, int offset, int val); +bool genInlinedSqrt(CompilationUnit* cUnit, CallInfo* info); +bool genInlinedCas32(CompilationUnit* cUnit, CallInfo* info, bool need_write_barrier); +LIR* opPcRelLoad(CompilationUnit* cUnit, int reg, LIR* target); +LIR* opVldm(CompilationUnit* cUnit, int rBase, int count); +LIR* opVstm(CompilationUnit* cUnit, int rBase, int count); +void genMultiplyByTwoBitMultiplier(CompilationUnit* cUnit, RegLocation rlSrc, + RegLocation rlResult, int lit, + int firstBit, int secondBit); +RegLocation inlineTarget(CompilationUnit* cUnit, CallInfo* info); +RegLocation inlineTargetWide(CompilationUnit* cUnit, CallInfo* info); +void genDivZeroCheck(CompilationUnit* cUnit, int regLo, int regHi); +LIR* genImmedCheck(CompilationUnit* cUnit, ConditionCode cCode, + int reg, int immVal, ThrowKind kind); +LIR* opTestSuspend(CompilationUnit* cUnit, LIR* target); +LIR* opDecAndBranch(CompilationUnit* cUnit, ConditionCode cCode, int reg, LIR* target); +LIR* opIT(CompilationUnit* cUnit, ArmConditionCode cond, const char* guide); +uint64_t getPCUseDefEncoding(); +uint64_t getRegMaskCommon(CompilationUnit* cUnit, int reg); +// TODO: clean up include files +int s2d(int lowReg, int highReg); +bool fpReg(int reg); +bool singleReg(int reg); +bool doubleReg(int reg); +uint32_t fpRegMask(); +bool sameRegType(int reg1, int reg2); +int targetReg(SpecialTargetRegister reg); +RegLocation locCReturn(); +RegLocation locCReturnWide(); +RegLocation locCReturnFloat(); +RegLocation locCReturnDouble(); +LIR* loadWordDisp(CompilationUnit* cUnit, int rBase, int displacement, int rDest); +LIR *storeWordDisp(CompilationUnit *cUnit, int rBase, + int displacement, int rSrc); +void removeRedundantBranches(CompilationUnit* cUnit); +LIR* newLIR0(CompilationUnit* cUnit, int opcode); +LIR* newLIR1(CompilationUnit* cUnit, int opcode, int dest); +LIR *opRegImm(CompilationUnit *cUnit, OpKind op, int rDestSrc1, int value); +void spillCoreRegs(CompilationUnit* cUnit); +void unSpillCoreRegs(CompilationUnit* cUnit); +void opRegThreadMem(CompilationUnit* cUnit, OpKind op, int rDest, int threadOffset); + +} // namespace art + +#endif // ART_SRC_COMPILER_COMPILERCODEGEN_H_ |