diff options
Diffstat (limited to 'vm/compiler/codegen/arm/CodegenCommon.c')
| -rw-r--r-- | vm/compiler/codegen/arm/CodegenCommon.c | 63 |
1 files changed, 50 insertions, 13 deletions
diff --git a/vm/compiler/codegen/arm/CodegenCommon.c b/vm/compiler/codegen/arm/CodegenCommon.c index f4ca95c4a..75134bf88 100644 --- a/vm/compiler/codegen/arm/CodegenCommon.c +++ b/vm/compiler/codegen/arm/CodegenCommon.c @@ -35,14 +35,12 @@ static int opcodeCoverage[kNumPackedOpcodes]; static void setMemRefType(ArmLIR *lir, bool isLoad, int memType) { u8 *maskPtr; - u8 mask; - assert( EncodingMap[lir->opcode].flags & (IS_LOAD | IS_STORE)); + u8 mask = ENCODE_MEM;; + assert(EncodingMap[lir->opcode].flags & (IS_LOAD | IS_STORE)); if (isLoad) { maskPtr = &lir->useMask; - mask = ENCODE_MEM_USE; } else { maskPtr = &lir->defMask; - mask = ENCODE_MEM_DEF; } /* Clear out the memref flags */ *maskPtr &= ~mask; @@ -50,14 +48,19 @@ static void setMemRefType(ArmLIR *lir, bool isLoad, int memType) switch(memType) { case kLiteral: assert(isLoad); - *maskPtr |= (ENCODE_LITERAL | ENCODE_LITPOOL_REF); + *maskPtr |= ENCODE_LITERAL; break; case kDalvikReg: - *maskPtr |= (ENCODE_DALVIK_REG | ENCODE_FRAME_REF); + *maskPtr |= ENCODE_DALVIK_REG; break; case kHeapRef: *maskPtr |= ENCODE_HEAP_REF; break; + case kMustNotAlias: + /* Currently only loads can be marked as kMustNotAlias */ + assert(!(EncodingMap[lir->opcode].flags & IS_STORE)); + *maskPtr |= ENCODE_MUST_NOT_ALIAS; + break; default: LOGE("Jit: invalid memref kind - %d", memType); assert(0); // Bail if debug build, set worst-case in the field @@ -138,9 +141,13 @@ static void setupResourceMasks(ArmLIR *lir) setMemRefType(lir, flags & IS_LOAD, kHeapRef); } + /* + * Conservatively assume the branch here will call out a function that in + * turn will trash everything. + */ if (flags & IS_BRANCH) { - lir->defMask |= ENCODE_REG_PC; - lir->useMask |= ENCODE_REG_PC; + lir->defMask = lir->useMask = ENCODE_ALL; + return; } if (flags & REG_DEF0) { @@ -176,11 +183,6 @@ static void setupResourceMasks(ArmLIR *lir) lir->defMask = ENCODE_ALL; } - /* Set up the mask for resources that are used */ - if (flags & IS_BRANCH) { - lir->useMask |= ENCODE_REG_PC; - } - if (flags & (REG_USE0 | REG_USE1 | REG_USE2 | REG_USE3)) { int i; @@ -225,6 +227,37 @@ static void setupResourceMasks(ArmLIR *lir) } /* + * Set up the accurate resource mask for branch instructions + */ +static void relaxBranchMasks(ArmLIR *lir) +{ + int flags = EncodingMap[lir->opcode].flags; + + /* Make sure only branch instructions are passed here */ + assert(flags & IS_BRANCH); + + lir->useMask = lir->defMask = ENCODE_REG_PC; + + if (flags & REG_DEF_LR) { + lir->defMask |= ENCODE_REG_LR; + } + + if (flags & (REG_USE0 | REG_USE1 | REG_USE2 | REG_USE3)) { + int i; + + for (i = 0; i < 4; i++) { + if (flags & (1 << (kRegUse0 + i))) { + setupRegMask(&lir->useMask, lir->operands[i]); + } + } + } + + if (flags & USES_CCODES) { + lir->useMask |= ENCODE_CCODE; + } +} + +/* * The following are building blocks to construct low-level IRs with 0 - 4 * operands. */ @@ -407,5 +440,9 @@ static ArmLIR *genCheckCommon(CompilationUnit *cUnit, int dOffset, } /* Branch to the PC reconstruction code */ branch->generic.target = (LIR *) pcrLabel; + + /* Clear the conservative flags for branches that punt to the interpreter */ + relaxBranchMasks(branch); + return pcrLabel; } |
