Revert "Revert "Refactor codegen resource masks""
This reverts commit 4b39c9f1b77ff32cf5760e6bf77c189678e2c9a6.
The problem with the original commit was failure to widen a
couple of local variables to hold the newly widenened to 64-bits
EncodingMap flag field - thus we lost some high-order resource
attributes and broke instruction scheduling for x86.
Change-Id: I04d7caf79e2cc802c39369ca04666629218ccaea
diff --git a/src/compiler/CompilerIR.h b/src/compiler/CompilerIR.h
index 4327fb6..3f855bb 100644
--- a/src/compiler/CompilerIR.h
+++ b/src/compiler/CompilerIR.h
@@ -158,6 +158,42 @@
#define NEXT_LIR(lir) (lir->next)
#define PREV_LIR(lir) (lir->prev)
+/* Defines for aliasInfo (tracks Dalvik register references) */
+#define DECODE_ALIAS_INFO_REG(X) (X & 0xffff)
+#define DECODE_ALIAS_INFO_WIDE_FLAG (0x80000000)
+#define DECODE_ALIAS_INFO_WIDE(X) ((X & DECODE_ALIAS_INFO_WIDE_FLAG) ? 1 : 0)
+#define ENCODE_ALIAS_INFO(REG, ISWIDE) (REG | (ISWIDE ? DECODE_ALIAS_INFO_WIDE_FLAG : 0))
+
+/*
+ * Def/Use encoding in 64-bit useMask/defMask. Low positions used for target-specific
+ * registers (and typically use the register number as the position). High positions
+ * reserved for common and abstract resources.
+ */
+
+enum ResourceEncodingPos {
+ kMustNotAlias = 63,
+ kHeapRef = 62, // Default memory reference type
+ kLiteral = 61, // Literal pool memory reference
+ kDalvikReg = 60, // Dalvik vReg memory reference
+ kFPStatus = 59,
+ kCCode = 58,
+ kLowestCommonResource = kCCode
+};
+
+/* Common resource macros */
+#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)
+
struct LIR {
int offset; // Offset of this instruction
int dalvikOffset; // Offset of Dalvik opcode
diff --git a/src/compiler/codegen/CodegenUtil.cc b/src/compiler/codegen/CodegenUtil.cc
index 7ad2647..2450058 100644
--- a/src/compiler/codegen/CodegenUtil.cc
+++ b/src/compiler/codegen/CodegenUtil.cc
@@ -65,36 +65,7 @@
* 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)
@@ -122,14 +93,13 @@
void setupResourceMasks(CompilationUnit* cUnit, LIR* lir)
{
int opcode = lir->opcode;
- int flags;
if (opcode <= 0) {
lir->useMask = lir->defMask = 0;
return;
}
- flags = EncodingMap[opcode].flags;
+ uint64_t flags = EncodingMap[opcode].flags;
if (flags & NEEDS_FIXUP) {
lir->flags.pcRelFixup = true;
@@ -161,10 +131,6 @@
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 +146,6 @@
}
}
- 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 d349412..7584d2b 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* 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 c0e6036..d2275aa 100644
--- a/src/compiler/codegen/LocalOptimizations.cc
+++ b/src/compiler/codegen/LocalOptimizations.cc
@@ -121,7 +121,7 @@
* 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);
@@ -232,7 +232,7 @@
if (cUnit->instructionSet == kX86) {
// Prevent stores from being sunk between ops that generate ccodes and
// ops that use them.
- int flags = EncodingMap[checkLIR->opcode].flags;
+ uint64_t flags = EncodingMap[checkLIR->opcode].flags;
if (sinkDistance > 0 && (flags & IS_BRANCH) && (flags & USES_CCODES)) {
checkLIR = PREV_LIR(checkLIR);
sinkDistance--;
@@ -298,7 +298,7 @@
* 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 820f64e..8746b68 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 @@
}
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 @@
}
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 @@
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 @@
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 407ad79..05082ed 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 @@
#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 @@
};
/* 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 @@
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 f837c39..9a2b923 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 @@
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 a175706..b8e5801 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 @@
#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 @@
};
/* 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 @@
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 4c28b35..953ce4a 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 @@
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 c47711c..71fcdc8 100644
--- a/src/compiler/codegen/x86/Assemble.cc
+++ b/src/compiler/codegen/x86/Assemble.cc
@@ -352,7 +352,7 @@
}
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 3da7672..040ef17 100644
--- a/src/compiler/codegen/x86/X86/Factory.cc
+++ b/src/compiler/codegen/x86/X86/Factory.cc
@@ -67,7 +67,7 @@
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 9a5d630..59b1859 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 @@
#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 @@
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 @@
#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,