summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Andreas Gampe <agampe@google.com> 2015-09-11 17:50:01 +0000
committer Gerrit Code Review <noreply-gerritcodereview@google.com> 2015-09-11 17:50:01 +0000
commit2d06e08d25bbf8eff1de945736a60810009e59ad (patch)
tree27c10f4fc30a85947ac0e3189b115035107a7ff0
parente2cb7f297dfeb1a6e19c3b8d45b742427054fa56 (diff)
parent501fd635a557645ab05f893c56e1f358e21bab82 (diff)
Merge "ART: Fix Quick-style LR vs PC core spill mask bug"
-rw-r--r--compiler/dex/quick/arm/call_arm.cc21
-rw-r--r--compiler/optimizing/code_generator_arm.cc20
-rw-r--r--runtime/oat.h2
3 files changed, 22 insertions, 21 deletions
diff --git a/compiler/dex/quick/arm/call_arm.cc b/compiler/dex/quick/arm/call_arm.cc
index eb8730cf4b..868d9a43e9 100644
--- a/compiler/dex/quick/arm/call_arm.cc
+++ b/compiler/dex/quick/arm/call_arm.cc
@@ -547,27 +547,28 @@ void ArmMir2Lir::GenExitSequence() {
cfi_.RestoreMany(DwarfFpReg(0), fp_spill_mask_);
}
bool unspill_LR_to_PC = (core_spill_mask_ & (1 << rs_rARM_LR.GetRegNum())) != 0;
+ uint32_t core_unspill_mask = core_spill_mask_;
if (unspill_LR_to_PC) {
- core_spill_mask_ &= ~(1 << rs_rARM_LR.GetRegNum());
- core_spill_mask_ |= (1 << rs_rARM_PC.GetRegNum());
+ core_unspill_mask &= ~(1 << rs_rARM_LR.GetRegNum());
+ core_unspill_mask |= (1 << rs_rARM_PC.GetRegNum());
}
- if (core_spill_mask_ != 0u) {
- if ((core_spill_mask_ & ~(0xffu | (1u << rs_rARM_PC.GetRegNum()))) == 0u) {
+ if (core_unspill_mask != 0u) {
+ if ((core_unspill_mask & ~(0xffu | (1u << rs_rARM_PC.GetRegNum()))) == 0u) {
// Unspilling only low regs and/or PC, use 16-bit POP.
constexpr int pc_bit_shift = rs_rARM_PC.GetRegNum() - 8;
NewLIR1(kThumbPop,
- (core_spill_mask_ & ~(1u << rs_rARM_PC.GetRegNum())) |
- ((core_spill_mask_ & (1u << rs_rARM_PC.GetRegNum())) >> pc_bit_shift));
- } else if (IsPowerOfTwo(core_spill_mask_)) {
+ (core_unspill_mask & ~(1u << rs_rARM_PC.GetRegNum())) |
+ ((core_unspill_mask & (1u << rs_rARM_PC.GetRegNum())) >> pc_bit_shift));
+ } else if (IsPowerOfTwo(core_unspill_mask)) {
// kThumb2Pop cannot be used to unspill a single register.
- NewLIR1(kThumb2Pop1, CTZ(core_spill_mask_));
+ NewLIR1(kThumb2Pop1, CTZ(core_unspill_mask));
} else {
- NewLIR1(kThumb2Pop, core_spill_mask_);
+ NewLIR1(kThumb2Pop, core_unspill_mask);
}
// If we pop to PC, there is no further epilogue code.
if (!unspill_LR_to_PC) {
cfi_.AdjustCFAOffset(-num_core_spills_ * kArmPointerSize);
- cfi_.RestoreMany(DwarfCoreReg(0), core_spill_mask_);
+ cfi_.RestoreMany(DwarfCoreReg(0), core_unspill_mask);
DCHECK_EQ(cfi_.GetCurrentCFAOffset(), 0); // empty stack.
}
}
diff --git a/compiler/optimizing/code_generator_arm.cc b/compiler/optimizing/code_generator_arm.cc
index 438ef694bf..a4c58b095a 100644
--- a/compiler/optimizing/code_generator_arm.cc
+++ b/compiler/optimizing/code_generator_arm.cc
@@ -48,7 +48,7 @@ static constexpr Register kMethodRegisterArgument = R0;
// with baseline.
static constexpr Register kCoreSavedRegisterForBaseline = R5;
static constexpr Register kCoreCalleeSaves[] =
- { R5, R6, R7, R8, R10, R11, PC };
+ { R5, R6, R7, R8, R10, R11, LR };
static constexpr SRegister kFpuCalleeSaves[] =
{ S16, S17, S18, S19, S20, S21, S22, S23, S24, S25, S26, S27, S28, S29, S30, S31 };
@@ -409,8 +409,8 @@ CodeGeneratorARM::CodeGeneratorARM(HGraph* graph,
method_patches_(MethodReferenceComparator(), graph->GetArena()->Adapter()),
call_patches_(MethodReferenceComparator(), graph->GetArena()->Adapter()),
relative_call_patches_(graph->GetArena()->Adapter()) {
- // Save the PC register to mimic Quick.
- AddAllocatedRegister(Location::RegisterLocation(PC));
+ // Always save the LR register to mimic Quick.
+ AddAllocatedRegister(Location::RegisterLocation(LR));
}
void CodeGeneratorARM::Finalize(CodeAllocator* allocator) {
@@ -599,12 +599,9 @@ void CodeGeneratorARM::GenerateFrameEntry() {
RecordPcInfo(nullptr, 0);
}
- // PC is in the list of callee-save to mimic Quick, but we need to push
- // LR at entry instead.
- uint32_t push_mask = (core_spill_mask_ & (~(1 << PC))) | 1 << LR;
- __ PushList(push_mask);
- __ cfi().AdjustCFAOffset(kArmWordSize * POPCOUNT(push_mask));
- __ cfi().RelOffsetForMany(DWARFReg(kMethodRegisterArgument), 0, push_mask, kArmWordSize);
+ __ PushList(core_spill_mask_);
+ __ cfi().AdjustCFAOffset(kArmWordSize * POPCOUNT(core_spill_mask_));
+ __ cfi().RelOffsetForMany(DWARFReg(kMethodRegisterArgument), 0, core_spill_mask_, kArmWordSize);
if (fpu_spill_mask_ != 0) {
SRegister start_register = SRegister(LeastSignificantBit(fpu_spill_mask_));
__ vpushs(start_register, POPCOUNT(fpu_spill_mask_));
@@ -632,7 +629,10 @@ void CodeGeneratorARM::GenerateFrameExit() {
__ cfi().AdjustCFAOffset(-kArmPointerSize * POPCOUNT(fpu_spill_mask_));
__ cfi().RestoreMany(DWARFReg(SRegister(0)), fpu_spill_mask_);
}
- __ PopList(core_spill_mask_);
+ // Pop LR into PC to return.
+ DCHECK_NE(core_spill_mask_ & (1 << LR), 0U);
+ uint32_t pop_mask = (core_spill_mask_ & (~(1 << LR))) | 1 << PC;
+ __ PopList(pop_mask);
__ cfi().RestoreState();
__ cfi().DefCFAOffset(GetFrameSize());
}
diff --git a/runtime/oat.h b/runtime/oat.h
index 1520a9bb02..b8b8d30f99 100644
--- a/runtime/oat.h
+++ b/runtime/oat.h
@@ -32,7 +32,7 @@ class InstructionSetFeatures;
class PACKED(4) OatHeader {
public:
static constexpr uint8_t kOatMagic[] = { 'o', 'a', 't', '\n' };
- static constexpr uint8_t kOatVersion[] = { '0', '6', '9', '\0' };
+ static constexpr uint8_t kOatVersion[] = { '0', '7', '0', '\0' };
static constexpr const char* kImageLocationKey = "image-location";
static constexpr const char* kDex2OatCmdLineKey = "dex2oat-cmdline";