diff options
Diffstat (limited to 'src/compiler/codegen')
| -rw-r--r-- | src/compiler/codegen/CodegenUtil.cc | 39 | ||||
| -rw-r--r-- | src/compiler/codegen/CompilerCodegen.h | 108 | ||||
| -rw-r--r-- | src/compiler/codegen/LocalOptimizations.cc | 4 | ||||
| -rw-r--r-- | src/compiler/codegen/arm/ArchUtility.cc | 57 | ||||
| -rw-r--r-- | src/compiler/codegen/arm/ArmLIR.h | 129 | ||||
| -rw-r--r-- | src/compiler/codegen/mips/ArchUtility.cc | 41 | ||||
| -rw-r--r-- | src/compiler/codegen/mips/MipsLIR.h | 133 | ||||
| -rw-r--r-- | src/compiler/codegen/x86/ArchUtility.cc | 42 | ||||
| -rw-r--r-- | src/compiler/codegen/x86/Assemble.cc | 2 | ||||
| -rw-r--r-- | src/compiler/codegen/x86/X86/Factory.cc | 2 | ||||
| -rw-r--r-- | src/compiler/codegen/x86/X86LIR.h | 124 |
11 files changed, 274 insertions, 407 deletions
diff --git a/src/compiler/codegen/CodegenUtil.cc b/src/compiler/codegen/CodegenUtil.cc index 7ad2647f18..3041d0b427 100644 --- a/src/compiler/codegen/CodegenUtil.cc +++ b/src/compiler/codegen/CodegenUtil.cc @@ -65,36 +65,7 @@ void annotateDalvikRegAccess(LIR* lir, int regId, bool isLoad, bool is64bit) * Store the Dalvik register id in aliasInfo. Mark the MSB if it is a 64-bit * access. */ - lir->aliasInfo = regId; - if (is64bit) { - lir->aliasInfo |= 0x80000000; - } -} - -/* - * Decode the register id. - */ -inline u8 getRegMaskCommon(CompilationUnit* cUnit, int reg) -{ - u8 seed; - int shift; - int regId; - - - if (cUnit->instructionSet == kX86) { - regId = reg & 0xf; - /* Double registers in x86 are just a single FP register */ - seed = 1; - } else { - regId = reg & 0x1f; - /* Each double register is equal to a pair of single-precision FP registers */ - seed = DOUBLEREG(reg) ? 3 : 1; - } - /* FP register starts at bit position 16 */ - shift = FPREG(reg) ? kFPReg0 : 0; - /* Expand the double register id into single offset */ - shift += regId; - return (seed << shift); + lir->aliasInfo = ENCODE_ALIAS_INFO(regId, is64bit); } u8 oatGetRegMaskCommon(CompilationUnit* cUnit, int reg) @@ -161,10 +132,6 @@ void setupResourceMasks(CompilationUnit* cUnit, LIR* lir) setupRegMask(cUnit, &lir->defMask, lir->operands[1]); } - if (flags & REG_DEF_SP) { - lir->defMask |= ENCODE_REG_SP; - } - if (flags & SETS_CCODES) { lir->defMask |= ENCODE_CCODE; @@ -180,10 +147,6 @@ void setupResourceMasks(CompilationUnit* cUnit, LIR* lir) } } - if (flags & REG_USE_SP) { - lir->useMask |= ENCODE_REG_SP; - } - if (flags & USES_CCODES) { lir->useMask |= ENCODE_CCODE; } diff --git a/src/compiler/codegen/CompilerCodegen.h b/src/compiler/codegen/CompilerCodegen.h index d349412950..7584d2b8f5 100644 --- a/src/compiler/codegen/CompilerCodegen.h +++ b/src/compiler/codegen/CompilerCodegen.h @@ -21,6 +21,112 @@ 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); @@ -114,6 +220,8 @@ LIR* genImmedCheck(CompilationUnit* cUnit, ConditionCode cCode, 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); } // namespace art diff --git a/src/compiler/codegen/LocalOptimizations.cc b/src/compiler/codegen/LocalOptimizations.cc index c0e6036b7f..356f4f93e4 100644 --- a/src/compiler/codegen/LocalOptimizations.cc +++ b/src/compiler/codegen/LocalOptimizations.cc @@ -121,7 +121,7 @@ void applyLoadStoreElimination(CompilationUnit* cUnit, LIR* headLIR, * region bits since stopMask is used to check data/control * dependencies. */ - stopUseRegMask = (ENCODE_REG_PC | thisLIR->useMask) & ~ENCODE_MEM; + stopUseRegMask = (getPCUseDefEncoding() | thisLIR->useMask) & ~ENCODE_MEM; } for (checkLIR = NEXT_LIR(thisLIR); @@ -298,7 +298,7 @@ void applyLoadHoisting(CompilationUnit* cUnit, LIR* headLIR, LIR* tailLIR) * conservatively here. */ if (stopUseAllMask & ENCODE_HEAP_REF) { - stopUseAllMask |= ENCODE_REG_PC; + stopUseAllMask |= getPCUseDefEncoding(); } } diff --git a/src/compiler/codegen/arm/ArchUtility.cc b/src/compiler/codegen/arm/ArchUtility.cc index 820f64e643..8746b6866e 100644 --- a/src/compiler/codegen/arm/ArchUtility.cc +++ b/src/compiler/codegen/arm/ArchUtility.cc @@ -22,24 +22,57 @@ namespace art { +/* + * Decode the register id. + */ +u8 getRegMaskCommon(CompilationUnit* cUnit, int reg) +{ + u8 seed; + int shift; + int regId; + + + regId = reg & 0x1f; + /* Each double register is equal to a pair of single-precision FP registers */ + seed = DOUBLEREG(reg) ? 3 : 1; + /* FP register starts at bit position 16 */ + shift = FPREG(reg) ? kArmFPReg0 : 0; + /* Expand the double register id into single offset */ + shift += regId; + return (seed << shift); +} + +uint64_t getPCUseDefEncoding() +{ + return ENCODE_ARM_REG_PC; +} + void setupTargetResourceMasks(CompilationUnit* cUnit, LIR* lir) { DCHECK_EQ(cUnit->instructionSet, kThumb2); // Thumb2 specific setup - int flags = EncodingMap[lir->opcode].flags; + uint64_t flags = EncodingMap[lir->opcode].flags; int opcode = lir->opcode; + if (flags & REG_DEF_SP) { + lir->defMask |= ENCODE_ARM_REG_SP; + } + + if (flags & REG_USE_SP) { + lir->useMask |= ENCODE_ARM_REG_SP; + } + if (flags & REG_DEF_LIST0) { - lir->defMask |= ENCODE_REG_LIST(lir->operands[0]); + lir->defMask |= ENCODE_ARM_REG_LIST(lir->operands[0]); } if (flags & REG_DEF_LIST1) { - lir->defMask |= ENCODE_REG_LIST(lir->operands[1]); + lir->defMask |= ENCODE_ARM_REG_LIST(lir->operands[1]); } if (flags & REG_DEF_FPCS_LIST0) { - lir->defMask |= ENCODE_REG_FPCS_LIST(lir->operands[0]); + lir->defMask |= ENCODE_ARM_REG_FPCS_LIST(lir->operands[0]); } if (flags & REG_DEF_FPCS_LIST2) { @@ -49,7 +82,7 @@ void setupTargetResourceMasks(CompilationUnit* cUnit, LIR* lir) } if (flags & REG_USE_PC) { - lir->useMask |= ENCODE_REG_PC; + lir->useMask |= ENCODE_ARM_REG_PC; } /* Conservatively treat the IT block */ @@ -58,15 +91,15 @@ void setupTargetResourceMasks(CompilationUnit* cUnit, LIR* lir) } if (flags & REG_USE_LIST0) { - lir->useMask |= ENCODE_REG_LIST(lir->operands[0]); + lir->useMask |= ENCODE_ARM_REG_LIST(lir->operands[0]); } if (flags & REG_USE_LIST1) { - lir->useMask |= ENCODE_REG_LIST(lir->operands[1]); + lir->useMask |= ENCODE_ARM_REG_LIST(lir->operands[1]); } if (flags & REG_USE_FPCS_LIST0) { - lir->useMask |= ENCODE_REG_FPCS_LIST(lir->operands[0]); + lir->useMask |= ENCODE_ARM_REG_FPCS_LIST(lir->operands[0]); } if (flags & REG_USE_FPCS_LIST2) { @@ -79,14 +112,14 @@ void setupTargetResourceMasks(CompilationUnit* cUnit, LIR* lir) u8 r8Mask = oatGetRegMaskCommon(cUnit, r8); if ((opcode == kThumbPush) && (lir->useMask & r8Mask)) { lir->useMask &= ~r8Mask; - lir->useMask |= ENCODE_REG_LR; + lir->useMask |= ENCODE_ARM_REG_LR; } else if ((opcode == kThumbPop) && (lir->defMask & r8Mask)) { lir->defMask &= ~r8Mask; - lir->defMask |= ENCODE_REG_PC; + lir->defMask |= ENCODE_ARM_REG_PC; } } if (flags & REG_DEF_LR) { - lir->defMask |= ENCODE_REG_LR; + lir->defMask |= ENCODE_ARM_REG_LR; } } @@ -354,7 +387,7 @@ void oatDumpResourceMask(LIR* lir, u8 mask, const char* prefix) char num[8]; int i; - for (i = 0; i < kRegEnd; i++) { + for (i = 0; i < kArmRegEnd; i++) { if (mask & (1ULL << i)) { sprintf(num, "%d ", i); strcat(buf, num); diff --git a/src/compiler/codegen/arm/ArmLIR.h b/src/compiler/codegen/arm/ArmLIR.h index 407ad793c0..05082ed8d8 100644 --- a/src/compiler/codegen/arm/ArmLIR.h +++ b/src/compiler/codegen/arm/ArmLIR.h @@ -22,9 +22,6 @@ namespace art { -// Set to 1 to measure cost of suspend check -#define NO_SUSPEND 0 - /* * Runtime register usage conventions. * @@ -132,43 +129,21 @@ namespace art { #define LOC_C_RETURN_FLOAT LOC_C_RETURN #define LOC_C_RETURN_WIDE_DOUBLE LOC_C_RETURN_WIDE -enum ResourceEncodingPos { - kGPReg0 = 0, - kRegSP = 13, - kRegLR = 14, - kRegPC = 15, - kFPReg0 = 16, - kFPReg16 = 32, - kRegEnd = 48, - kCCode = kRegEnd, - kFPStatus, // FP status word - // The following four bits are for memory disambiguation - kDalvikReg, // 1 Dalvik Frame (can be fully disambiguated) - kLiteral, // 2 Literal pool (can be fully disambiguated) - kHeapRef, // 3 Somewhere on the heap (alias with any other heap) - kMustNotAlias, // 4 Guaranteed to be non-alias (eg *(r6+x)) +enum ArmResourceEncodingPos { + kArmGPReg0 = 0, + kArmRegSP = 13, + kArmRegLR = 14, + kArmRegPC = 15, + kArmFPReg0 = 16, + kArmFPReg16 = 32, + kArmRegEnd = 48, }; -#define ENCODE_REG_LIST(N) ((u8) N) -#define ENCODE_REG_SP (1ULL << kRegSP) -#define ENCODE_REG_LR (1ULL << kRegLR) -#define ENCODE_REG_PC (1ULL << kRegPC) -#define ENCODE_CCODE (1ULL << kCCode) -#define ENCODE_FP_STATUS (1ULL << kFPStatus) -#define ENCODE_REG_FPCS_LIST(N) ((u8)N << kFPReg16) - -/* Abstract memory locations */ -#define ENCODE_DALVIK_REG (1ULL << kDalvikReg) -#define ENCODE_LITERAL (1ULL << kLiteral) -#define ENCODE_HEAP_REF (1ULL << kHeapRef) -#define ENCODE_MUST_NOT_ALIAS (1ULL << kMustNotAlias) - -#define ENCODE_ALL (~0ULL) -#define ENCODE_MEM (ENCODE_DALVIK_REG | ENCODE_LITERAL | \ - ENCODE_HEAP_REF | ENCODE_MUST_NOT_ALIAS) - -#define DECODE_ALIAS_INFO_REG(X) (X & 0xffff) -#define DECODE_ALIAS_INFO_WIDE(X) ((X & 0x80000000) ? 1 : 0) +#define ENCODE_ARM_REG_LIST(N) ((u8) N) +#define ENCODE_ARM_REG_SP (1ULL << kArmRegSP) +#define ENCODE_ARM_REG_LR (1ULL << kArmRegLR) +#define ENCODE_ARM_REG_PC (1ULL << kArmRegPC) +#define ENCODE_ARM_REG_FPCS_LIST(N) ((u8)N << kArmFPReg16) /* * Annotate special-purpose core registers: @@ -606,82 +581,6 @@ enum ArmOpDmbOptions { }; /* Bit flags describing the behavior of each native opcode */ -enum ArmOpFeatureFlags { - kIsBranch = 0, - kRegDef0, - kRegDef1, - kRegDefSP, - kRegDefLR, - kRegDefList0, - kRegDefList1, - kRegDefFPCSList0, - kRegDefFPCSList2, - kRegDefList2, - kRegUse0, - kRegUse1, - kRegUse2, - kRegUse3, - kRegUseSP, - kRegUsePC, - kRegUseList0, - kRegUseList1, - kRegUseFPCSList0, - kRegUseFPCSList2, - kNoOperand, - kIsUnaryOp, - kIsBinaryOp, - kIsTertiaryOp, - kIsQuadOp, - kIsIT, - kSetsCCodes, - kUsesCCodes, - kMemLoad, - kMemStore, - kPCRelFixup, -}; - -#define IS_LOAD (1 << kMemLoad) -#define IS_STORE (1 << kMemStore) -#define IS_BRANCH (1 << kIsBranch) -#define REG_DEF0 (1 << kRegDef0) -#define REG_DEF1 (1 << kRegDef1) -#define REG_DEF_SP (1 << kRegDefSP) -#define REG_DEF_LR (1 << kRegDefLR) -#define REG_DEF_LIST0 (1 << kRegDefList0) -#define REG_DEF_LIST1 (1 << kRegDefList1) -#define REG_DEF_FPCS_LIST0 (1 << kRegDefFPCSList0) -#define REG_DEF_FPCS_LIST2 (1 << kRegDefFPCSList2) -#define REG_USE0 (1 << kRegUse0) -#define REG_USE1 (1 << kRegUse1) -#define REG_USE2 (1 << kRegUse2) -#define REG_USE3 (1 << kRegUse3) -#define REG_USE_SP (1 << kRegUseSP) -#define REG_USE_PC (1 << kRegUsePC) -#define REG_USE_LIST0 (1 << kRegUseList0) -#define REG_USE_LIST1 (1 << kRegUseList1) -#define REG_USE_FPCS_LIST0 (1 << kRegUseFPCSList0) -#define REG_USE_FPCS_LIST2 (1 << kRegUseFPCSList2) -#define NO_OPERAND (1 << kNoOperand) -#define IS_UNARY_OP (1 << kIsUnaryOp) -#define IS_BINARY_OP (1 << kIsBinaryOp) -#define IS_TERTIARY_OP (1 << kIsTertiaryOp) -#define IS_QUAD_OP (1 << kIsQuadOp) -#define IS_QUIN_OP 0 -#define IS_IT (1 << kIsIT) -#define SETS_CCODES (1 << kSetsCCodes) -#define USES_CCODES (1 << kUsesCCodes) -#define NEEDS_FIXUP (1 << kPCRelFixup) - -/* Common combo register usage patterns */ -#define REG_USE01 (REG_USE0 | REG_USE1) -#define REG_USE012 (REG_USE01 | REG_USE2) -#define REG_USE12 (REG_USE1 | REG_USE2) -#define REG_DEF0_USE0 (REG_DEF0 | REG_USE0) -#define REG_DEF0_USE1 (REG_DEF0 | REG_USE1) -#define REG_DEF0_USE01 (REG_DEF0 | REG_USE01) -#define REG_DEF0_USE12 (REG_DEF0 | REG_USE12) -#define REG_DEF01_USE2 (REG_DEF0 | REG_DEF1 | REG_USE2) - /* Instruction assembly fieldLoc kind */ enum ArmEncodingKind { kFmtUnused, @@ -710,7 +609,7 @@ struct ArmEncodingMap { int start; /* start for kFmtBitBlt, 4-bit slice end for FP regs */ } fieldLoc[4]; ArmOpcode opcode; - int flags; + uint64_t flags; const char* name; const char* fmt; int size; /* Size in bytes */ diff --git a/src/compiler/codegen/mips/ArchUtility.cc b/src/compiler/codegen/mips/ArchUtility.cc index f837c399ae..9a2b923baf 100644 --- a/src/compiler/codegen/mips/ArchUtility.cc +++ b/src/compiler/codegen/mips/ArchUtility.cc @@ -22,14 +22,49 @@ namespace art { +/* + * Decode the register id. + */ +u8 getRegMaskCommon(CompilationUnit* cUnit, int reg) +{ + u8 seed; + int shift; + int regId; + + + regId = reg & 0x1f; + /* Each double register is equal to a pair of single-precision FP registers */ + seed = DOUBLEREG(reg) ? 3 : 1; + /* FP register starts at bit position 16 */ + shift = FPREG(reg) ? kMipsFPReg0 : 0; + /* Expand the double register id into single offset */ + shift += regId; + return (seed << shift); +} + +uint64_t getPCUseDefEncoding() +{ + return ENCODE_MIPS_REG_PC; +} + + void setupTargetResourceMasks(CompilationUnit* cUnit, LIR* lir) { DCHECK_EQ(cUnit->instructionSet, kMips); // Mips-specific resource map setup here. - int flags = EncodingMap[lir->opcode].flags; + uint64_t flags = EncodingMap[lir->opcode].flags; + + if (flags & REG_DEF_SP) { + lir->defMask |= ENCODE_MIPS_REG_SP; + } + + if (flags & REG_USE_SP) { + lir->useMask |= ENCODE_MIPS_REG_SP; + } + if (flags & REG_DEF_LR) { - lir->defMask |= ENCODE_REG_LR; + lir->defMask |= ENCODE_MIPS_REG_LR; } } @@ -151,7 +186,7 @@ void oatDumpResourceMask(LIR *lir, u8 mask, const char *prefix) char num[8]; int i; - for (i = 0; i < kRegEnd; i++) { + for (i = 0; i < kMipsRegEnd; i++) { if (mask & (1ULL << i)) { sprintf(num, "%d ", i); strcat(buf, num); diff --git a/src/compiler/codegen/mips/MipsLIR.h b/src/compiler/codegen/mips/MipsLIR.h index a175706d2b..b8e5801651 100644 --- a/src/compiler/codegen/mips/MipsLIR.h +++ b/src/compiler/codegen/mips/MipsLIR.h @@ -22,9 +22,6 @@ namespace art { -// Set to 1 to measure cost of suspend check -#define NO_SUSPEND 0 - /* * Runtime register conventions. * @@ -159,44 +156,22 @@ namespace art { #define LOC_C_RETURN_WIDE_DOUBLE {kLocPhysReg, 1, 0, 0, 0, 0, 0, 0, 1, r_FRESULT0,\ r_FRESULT1, INVALID_SREG, INVALID_SREG} -enum ResourceEncodingPos { - kGPReg0 = 0, - kRegSP = 29, - kRegLR = 31, - kFPReg0 = 32, /* only 16 fp regs supported currently */ - kFPRegEnd = 48, - kRegHI = kFPRegEnd, - kRegLO, - kRegPC, - kRegEnd = 51, - kCCode = kRegEnd, - kFPStatus, // FP status word - // The following four bits are for memory disambiguation - kDalvikReg, // 1 Dalvik Frame (can be fully disambiguated) - kLiteral, // 2 Literal pool (can be fully disambiguated) - kHeapRef, // 3 Somewhere on the heap (alias with any other heap) - kMustNotAlias, // 4 Guaranteed to be non-alias (eg *(r6+x)) +enum MipsResourceEncodingPos { + kMipsGPReg0 = 0, + kMipsRegSP = 29, + kMipsRegLR = 31, + kMipsFPReg0 = 32, /* only 16 fp regs supported currently */ + kMipsFPRegEnd = 48, + kMipsRegHI = kMipsFPRegEnd, + kMipsRegLO, + kMipsRegPC, + kMipsRegEnd = 51, }; -#define ENCODE_REG_LIST(N) ((u8) N) -#define ENCODE_REG_SP (1ULL << kRegSP) -#define ENCODE_REG_LR (1ULL << kRegLR) -#define ENCODE_REG_PC (1ULL << kRegPC) -#define ENCODE_CCODE (1ULL << kCCode) -#define ENCODE_FP_STATUS (1ULL << kFPStatus) - -/* Abstract memory locations */ -#define ENCODE_DALVIK_REG (1ULL << kDalvikReg) -#define ENCODE_LITERAL (1ULL << kLiteral) -#define ENCODE_HEAP_REF (1ULL << kHeapRef) -#define ENCODE_MUST_NOT_ALIAS (1ULL << kMustNotAlias) - -#define ENCODE_ALL (~0ULL) -#define ENCODE_MEM (ENCODE_DALVIK_REG | ENCODE_LITERAL | \ - ENCODE_HEAP_REF | ENCODE_MUST_NOT_ALIAS) - -#define DECODE_ALIAS_INFO_REG(X) (X & 0xffff) -#define DECODE_ALIAS_INFO_WIDE(X) ((X & 0x80000000) ? 1 : 0) +#define ENCODE_MIPS_REG_LIST(N) ((u8) N) +#define ENCODE_MIPS_REG_SP (1ULL << kMipsRegSP) +#define ENCODE_MIPS_REG_LR (1ULL << kMipsRegLR) +#define ENCODE_MIPS_REG_PC (1ULL << kMipsRegPC) /* * Annotate special-purpose core registers: @@ -438,84 +413,6 @@ enum MipsOpCode { }; /* Bit flags describing the behavior of each native opcode */ -enum MipsOpFeatureFlags { - kIsBranch = 0, - kRegDef0, - kRegDef1, - kRegDefSP, - kRegDefLR, - kRegDefList0, - kRegDefList1, - kRegUse0, - kRegUse1, - kRegUse2, - kRegUse3, - kRegUseSP, - kRegUsePC, - kRegUseList0, - kRegUseList1, - kNoOperand, - kIsUnaryOp, - kIsBinaryOp, - kIsTertiaryOp, - kIsQuadOp, - kIsIT, - kSetsCCodes, - kUsesCCodes, - kMemLoad, - kMemStore, - kPCRelFixup, - kRegUseLR, -}; - -#define IS_LOAD (1 << kMemLoad) -#define IS_STORE (1 << kMemStore) -#define IS_BRANCH (1 << kIsBranch) -#define REG_DEF0 (1 << kRegDef0) -#define REG_DEF1 (1 << kRegDef1) -#define REG_DEF_SP (1 << kRegDefSP) -#define REG_DEF_LR (1 << kRegDefLR) -#define REG_DEF_LIST0 (1 << kRegDefList0) -#define REG_DEF_LIST1 (1 << kRegDefList1) -#define REG_USE0 (1 << kRegUse0) -#define REG_USE1 (1 << kRegUse1) -#define REG_USE2 (1 << kRegUse2) -#define REG_USE3 (1 << kRegUse3) -#define REG_USE_SP (1 << kRegUseSP) -#define REG_USE_PC (1 << kRegUsePC) -#define REG_USE_LIST0 (1 << kRegUseList0) -#define REG_USE_LIST1 (1 << kRegUseList1) -#define NO_OPERAND (1 << kNoOperand) -#define IS_UNARY_OP (1 << kIsUnaryOp) -#define IS_BINARY_OP (1 << kIsBinaryOp) -#define IS_TERTIARY_OP (1 << kIsTertiaryOp) -#define IS_QUAD_OP (1 << kIsQuadOp) -#define IS_QUIN_OP 0 -#define IS_IT (1 << kIsIT) -#define SETS_CCODES (1 << kSetsCCodes) -#define USES_CCODES (1 << kUsesCCodes) -#define NEEDS_FIXUP (1 << kPCRelFixup) -#define REG_USE_LR (1 << kRegUseLR) - -/* attributes, included for compatibility */ -#define REG_DEF_FPCS_LIST0 (0) -#define REG_DEF_FPCS_LIST2 (0) - - -/* Common combo register usage patterns */ -#define REG_USE01 (REG_USE0 | REG_USE1) -#define REG_USE02 (REG_USE0 | REG_USE2) -#define REG_USE012 (REG_USE01 | REG_USE2) -#define REG_USE12 (REG_USE1 | REG_USE2) -#define REG_USE23 (REG_USE2 | REG_USE3) -#define REG_DEF01 (REG_DEF0 | REG_DEF1) -#define REG_DEF0_USE0 (REG_DEF0 | REG_USE0) -#define REG_DEF0_USE1 (REG_DEF0 | REG_USE1) -#define REG_DEF0_USE2 (REG_DEF0 | REG_USE2) -#define REG_DEF0_USE01 (REG_DEF0 | REG_USE01) -#define REG_DEF0_USE12 (REG_DEF0 | REG_USE12) -#define REG_DEF01_USE2 (REG_DEF0 | REG_DEF1 | REG_USE2) - /* Instruction assembly fieldLoc kind */ enum MipsEncodingKind { kFmtUnused, @@ -534,7 +431,7 @@ struct MipsEncodingMap { int start; /* start for kFmtBitBlt, 4-bit slice end for FP regs */ } fieldLoc[4]; MipsOpCode opcode; - int flags; + uint64_t flags; const char *name; const char* fmt; int size; /* Size in bytes */ diff --git a/src/compiler/codegen/x86/ArchUtility.cc b/src/compiler/codegen/x86/ArchUtility.cc index 4c28b35e03..953ce4a899 100644 --- a/src/compiler/codegen/x86/ArchUtility.cc +++ b/src/compiler/codegen/x86/ArchUtility.cc @@ -22,12 +22,50 @@ namespace art { +/* + * Decode the register id. + */ +u8 getRegMaskCommon(CompilationUnit* cUnit, int reg) +{ + u8 seed; + int shift; + int regId; + + regId = reg & 0xf; + /* Double registers in x86 are just a single FP register */ + seed = 1; + /* FP register starts at bit position 16 */ + shift = FPREG(reg) ? kX86FPReg0 : 0; + /* Expand the double register id into single offset */ + shift += regId; + return (seed << shift); +} + +uint64_t getPCUseDefEncoding() +{ + /* + * FIXME: might make sense to use a virtual resource encoding bit for pc. Might be + * able to clean up some of the x86/Arm_Mips differences + */ + LOG(FATAL) << "Unexpected call to getPCUseDefEncoding for x86"; + return 0ULL; +} + void setupTargetResourceMasks(CompilationUnit* cUnit, LIR* lir) { DCHECK_EQ(cUnit->instructionSet, kX86); // X86-specific resource map setup here. - int flags = EncodingMap[lir->opcode].flags; + uint64_t flags = EncodingMap[lir->opcode].flags; + + if (flags & REG_USE_SP) { + lir->useMask |= ENCODE_X86_REG_SP; + } + + if (flags & REG_DEF_SP) { + lir->defMask |= ENCODE_X86_REG_SP; + } + if (flags & REG_DEFA) { oatSetupRegMask(cUnit, &lir->defMask, rAX); } @@ -147,7 +185,7 @@ void oatDumpResourceMask(LIR *lir, u8 mask, const char *prefix) char num[8]; int i; - for (i = 0; i < kRegEnd; i++) { + for (i = 0; i < kX86RegEnd; i++) { if (mask & (1ULL << i)) { sprintf(num, "%d ", i); strcat(buf, num); diff --git a/src/compiler/codegen/x86/Assemble.cc b/src/compiler/codegen/x86/Assemble.cc index c47711cab3..71fcdc8b38 100644 --- a/src/compiler/codegen/x86/Assemble.cc +++ b/src/compiler/codegen/x86/Assemble.cc @@ -352,7 +352,7 @@ static size_t computeSize(X86EncodingMap* entry, int displacement, bool has_sib) } if (displacement != 0) { if (entry->opcode != kX86Lea32RA) { - DCHECK_NE(entry->flags & (IS_LOAD | IS_STORE), 0) << entry->name; + DCHECK_NE(entry->flags & (IS_LOAD | IS_STORE), 0ULL) << entry->name; } size += IS_SIMM8(displacement) ? 1 : 4; } diff --git a/src/compiler/codegen/x86/X86/Factory.cc b/src/compiler/codegen/x86/X86/Factory.cc index 3da7672408..040ef17278 100644 --- a/src/compiler/codegen/x86/X86/Factory.cc +++ b/src/compiler/codegen/x86/X86/Factory.cc @@ -67,7 +67,7 @@ LIR *fpRegCopy(CompilationUnit *cUnit, int rDest, int rSrc) opcode = kX86MovdrxRR; } } - DCHECK_NE((EncodingMap[opcode].flags & IS_BINARY_OP), 0); + DCHECK_NE((EncodingMap[opcode].flags & IS_BINARY_OP), 0ULL); LIR* res = rawLIR(cUnit, cUnit->currentDalvikOffset, opcode, rDest, rSrc); if (rDest == rSrc) { res->flags.isNop = true; diff --git a/src/compiler/codegen/x86/X86LIR.h b/src/compiler/codegen/x86/X86LIR.h index 9a5d63058a..59b1859134 100644 --- a/src/compiler/codegen/x86/X86LIR.h +++ b/src/compiler/codegen/x86/X86LIR.h @@ -22,9 +22,6 @@ namespace art { -// Set to 1 to measure cost of suspend check -#define NO_SUSPEND 0 - /* * Runtime register conventions. We consider both x86, x86-64 and x32 (32bit mode x86-64), although * we currently only target x86. The ABI has different conventions and we hope to have a single @@ -143,40 +140,16 @@ namespace art { #define LOC_C_RETURN_FLOAT {kLocPhysReg, 0, 0, 0, 1, 0, 0, 0, 1, fr0, INVALID_REG, INVALID_SREG, INVALID_SREG} #define LOC_C_RETURN_WIDE_DOUBLE {kLocPhysReg, 1, 0, 0, 1, 0, 0, 0, 1, fr0, fr1, INVALID_SREG, INVALID_SREG} -enum ResourceEncodingPos { - kGPReg0 = 0, - kRegSP = 4, - kRegLR = -1, - kFPReg0 = 16, // xmm0 .. xmm7/xmm15 - kFPRegEnd = 32, - kRegEnd = kFPRegEnd, - kCCode = kRegEnd, - // The following four bits are for memory disambiguation - kDalvikReg, // 1 Dalvik Frame (can be fully disambiguated) - kLiteral, // 2 Literal pool (can be fully disambiguated) - kHeapRef, // 3 Somewhere on the heap (alias with any other heap) - kMustNotAlias, // 4 Guaranteed to be non-alias (eg *(r6+x)) +enum X86ResourceEncodingPos { + kX86GPReg0 = 0, + kX86RegSP = 4, + kX86FPReg0 = 16, // xmm0 .. xmm7/xmm15 + kX86FPRegEnd = 32, + kX86RegEnd = kX86FPRegEnd, }; -#define ENCODE_REG_LIST(N) ((u8) N) -#define ENCODE_REG_SP (1ULL << kRegSP) -#define ENCODE_CCODE (1ULL << kCCode) -#define ENCODE_FP_STATUS (1ULL << kFPStatus) - -/* Abstract memory locations */ -#define ENCODE_DALVIK_REG (1ULL << kDalvikReg) -#define ENCODE_LITERAL (1ULL << kLiteral) -#define ENCODE_HEAP_REF (1ULL << kHeapRef) -#define ENCODE_MUST_NOT_ALIAS (1ULL << kMustNotAlias) - -#define ENCODE_ALL (~0ULL) -#define ENCODE_MEM (ENCODE_DALVIK_REG | ENCODE_LITERAL | \ - ENCODE_HEAP_REF | ENCODE_MUST_NOT_ALIAS) - -#define DECODE_ALIAS_INFO_REG(X) (X & 0xffff) -#define DECODE_ALIAS_INFO_WIDE(X) ((X & 0x80000000) ? 1 : 0) -/* Not used for x86 */ -#define ENCODE_REG_PC (ENCODE_ALL) +#define ENCODE_X86_REG_LIST(N) ((u8) N) +#define ENCODE_X86_REG_SP (1ULL << kX86RegSP) /* * Annotate special-purpose core registers: @@ -444,7 +417,7 @@ enum X86EncodingKind { struct X86EncodingMap { X86OpCode opcode; // e.g. kOpAddRI X86EncodingKind kind; // Used to discriminate in the union below - int flags; + uint64_t flags; struct { uint8_t prefix1; // non-zero => a prefix byte uint8_t prefix2; // non-zero => a second prefix byte @@ -467,85 +440,6 @@ extern X86EncodingMap EncodingMap[kX86Last]; #define kSY 0 #define kST 0 -/* Bit flags describing the behavior of each native opcode */ -enum X86OpFeatureFlags { - kIsBranch = 0, - kRegDef0, - kRegDef1, - kRegDefA, - kRegDefD, - kRegDefSP, - kRegUse0, - kRegUse1, - kRegUse2, - kRegUse3, - kRegUse4, - kRegUseA, - kRegUseC, - kRegUseD, - kRegUseSP, - kNoOperand, - kIsUnaryOp, - kIsBinaryOp, - kIsTertiaryOp, - kIsQuadOp, - kIsQuinOp, - kIsSextupleOp, - kIsIT, - kSetsCCodes, - kUsesCCodes, - kMemLoad, - kMemStore, - kPCRelFixup, -// FIXME: add NEEDS_FIXUP to instruction attributes -}; - -#define IS_LOAD (1 << kMemLoad) -#define IS_STORE (1 << kMemStore) -#define IS_BRANCH (1 << kIsBranch) -#define REG_DEF0 (1 << kRegDef0) -#define REG_DEF1 (1 << kRegDef1) -#define REG_DEFA (1 << kRegDefA) -#define REG_DEFD (1 << kRegDefD) -#define REG_DEF_SP (1 << kRegDefSP) -#define REG_USE0 (1 << kRegUse0) -#define REG_USE1 (1 << kRegUse1) -#define REG_USE2 (1 << kRegUse2) -#define REG_USE3 (1 << kRegUse3) -#define REG_USE4 (1 << kRegUse4) -#define REG_USEA (1 << kRegUseA) -#define REG_USEC (1 << kRegUseC) -#define REG_USED (1 << kRegUseD) -#define REG_USE_SP (1 << kRegUseSP) -#define NO_OPERAND (1 << kNoOperand) -#define IS_UNARY_OP (1 << kIsUnaryOp) -#define IS_BINARY_OP (1 << kIsBinaryOp) -#define IS_TERTIARY_OP (1 << kIsTertiaryOp) -#define IS_QUAD_OP (1 << kIsQuadOp) -#define IS_QUIN_OP (1 << kIsQuinOp) -#define IS_SEXTUPLE_OP (1 << kIsSextupleOp) -#define IS_IT (1 << kIsIT) -#define SETS_CCODES (1 << kSetsCCodes) -#define USES_CCODES (1 << kUsesCCodes) -#define NEEDS_FIXUP (1 << kPCRelFixup) - -/* attributes, included for compatibility */ -#define REG_DEF_FPCS_LIST0 (0) -#define REG_DEF_FPCS_LIST2 (0) - - -/* Common combo register usage patterns */ -#define REG_USE01 (REG_USE0 | REG_USE1) -#define REG_USE02 (REG_USE0 | REG_USE2) -#define REG_USE012 (REG_USE01 | REG_USE2) -#define REG_USE014 (REG_USE01 | REG_USE4) -#define REG_DEF0_USE0 (REG_DEF0 | REG_USE0) -#define REG_DEF0_USE1 (REG_DEF0 | REG_USE1) -#define REG_DEF0_USE12 (REG_DEF0_USE1 | REG_USE2) -#define REG_DEFA_USEA (REG_DEFA | REG_USEA) -#define REG_DEFAD_USEA (REG_DEFA_USEA | REG_DEFD) -#define REG_DEFAD_USEAD (REG_DEFAD_USEA | REG_USED) - /* Keys for target-specific scheduling and other optimization hints */ enum X86TargetOptHints { kMaxHoistDistance, |