ARM: don't use r9 anymore for gap resolution

BUG=
R=bmeurer@chromium.org, ulan@chromium.org

Review URL: https://codereview.chromium.org/255883002

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@21008 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 9aaa5367
...@@ -33,11 +33,22 @@ ...@@ -33,11 +33,22 @@
namespace v8 { namespace v8 {
namespace internal { namespace internal {
static const Register kSavedValueRegister = { 9 }; // We use the root register to spill a value while breaking a cycle in parallel
// moves. We don't need access to roots while resolving the move list and using
// the root register has two advantages:
// - It is not in crankshaft allocatable registers list, so it can't interfere
// with any of the moves we are resolving.
// - We don't need to push it on the stack, as we can reload it with its value
// once we have resolved a cycle.
#define kSavedValueRegister kRootRegister
LGapResolver::LGapResolver(LCodeGen* owner) LGapResolver::LGapResolver(LCodeGen* owner)
: cgen_(owner), moves_(32, owner->zone()), root_index_(0), in_cycle_(false), : cgen_(owner), moves_(32, owner->zone()), root_index_(0), in_cycle_(false),
saved_destination_(NULL) { } saved_destination_(NULL), need_to_restore_root_(false) { }
#define __ ACCESS_MASM(cgen_->masm())
void LGapResolver::Resolve(LParallelMove* parallel_move) { void LGapResolver::Resolve(LParallelMove* parallel_move) {
...@@ -67,6 +78,12 @@ void LGapResolver::Resolve(LParallelMove* parallel_move) { ...@@ -67,6 +78,12 @@ void LGapResolver::Resolve(LParallelMove* parallel_move) {
} }
} }
if (need_to_restore_root_) {
ASSERT(kSavedValueRegister.is(kRootRegister));
__ InitializeRootRegister();
need_to_restore_root_ = false;
}
moves_.Rewind(0); moves_.Rewind(0);
} }
...@@ -155,20 +172,21 @@ void LGapResolver::Verify() { ...@@ -155,20 +172,21 @@ void LGapResolver::Verify() {
#endif #endif
} }
#define __ ACCESS_MASM(cgen_->masm())
void LGapResolver::BreakCycle(int index) { void LGapResolver::BreakCycle(int index) {
// We save in a register the value that should end up in the source of // We save in a register the source of that move and we remember its
// moves_[root_index]. After performing all moves in the tree rooted // destination. Then we mark this move as resolved so the cycle is
// in that move, we save the value to that source. // broken and we can perform the other moves.
ASSERT(moves_[index].destination()->Equals(moves_[root_index_].source())); ASSERT(moves_[index].destination()->Equals(moves_[root_index_].source()));
ASSERT(!in_cycle_); ASSERT(!in_cycle_);
in_cycle_ = true; in_cycle_ = true;
LOperand* source = moves_[index].source(); LOperand* source = moves_[index].source();
saved_destination_ = moves_[index].destination(); saved_destination_ = moves_[index].destination();
if (source->IsRegister()) { if (source->IsRegister()) {
need_to_restore_root_ = true;
__ mov(kSavedValueRegister, cgen_->ToRegister(source)); __ mov(kSavedValueRegister, cgen_->ToRegister(source));
} else if (source->IsStackSlot()) { } else if (source->IsStackSlot()) {
need_to_restore_root_ = true;
__ ldr(kSavedValueRegister, cgen_->ToMemOperand(source)); __ ldr(kSavedValueRegister, cgen_->ToMemOperand(source));
} else if (source->IsDoubleRegister()) { } else if (source->IsDoubleRegister()) {
__ vmov(kScratchDoubleReg, cgen_->ToDoubleRegister(source)); __ vmov(kScratchDoubleReg, cgen_->ToDoubleRegister(source));
...@@ -186,7 +204,6 @@ void LGapResolver::RestoreValue() { ...@@ -186,7 +204,6 @@ void LGapResolver::RestoreValue() {
ASSERT(in_cycle_); ASSERT(in_cycle_);
ASSERT(saved_destination_ != NULL); ASSERT(saved_destination_ != NULL);
// Spilled value is in kSavedValueRegister or kSavedDoubleValueRegister.
if (saved_destination_->IsRegister()) { if (saved_destination_->IsRegister()) {
__ mov(cgen_->ToRegister(saved_destination_), kSavedValueRegister); __ mov(cgen_->ToRegister(saved_destination_), kSavedValueRegister);
} else if (saved_destination_->IsStackSlot()) { } else if (saved_destination_->IsStackSlot()) {
...@@ -226,7 +243,6 @@ void LGapResolver::EmitMove(int index) { ...@@ -226,7 +243,6 @@ void LGapResolver::EmitMove(int index) {
} else { } else {
ASSERT(destination->IsStackSlot()); ASSERT(destination->IsStackSlot());
MemOperand destination_operand = cgen_->ToMemOperand(destination); MemOperand destination_operand = cgen_->ToMemOperand(destination);
if (in_cycle_) {
if (!destination_operand.OffsetIsUint12Encodable()) { if (!destination_operand.OffsetIsUint12Encodable()) {
// ip is overwritten while saving the value to the destination. // ip is overwritten while saving the value to the destination.
// Therefore we can't use ip. It is OK if the read from the source // Therefore we can't use ip. It is OK if the read from the source
...@@ -237,10 +253,6 @@ void LGapResolver::EmitMove(int index) { ...@@ -237,10 +253,6 @@ void LGapResolver::EmitMove(int index) {
__ ldr(ip, source_operand); __ ldr(ip, source_operand);
__ str(ip, destination_operand); __ str(ip, destination_operand);
} }
} else {
__ ldr(kSavedValueRegister, source_operand);
__ str(kSavedValueRegister, destination_operand);
}
} }
} else if (source->IsConstantOperand()) { } else if (source->IsConstantOperand()) {
...@@ -261,14 +273,14 @@ void LGapResolver::EmitMove(int index) { ...@@ -261,14 +273,14 @@ void LGapResolver::EmitMove(int index) {
} else { } else {
ASSERT(destination->IsStackSlot()); ASSERT(destination->IsStackSlot());
ASSERT(!in_cycle_); // Constant moves happen after all cycles are gone. ASSERT(!in_cycle_); // Constant moves happen after all cycles are gone.
need_to_restore_root_ = true;
Representation r = cgen_->IsSmi(constant_source) Representation r = cgen_->IsSmi(constant_source)
? Representation::Smi() : Representation::Integer32(); ? Representation::Smi() : Representation::Integer32();
if (cgen_->IsInteger32(constant_source)) { if (cgen_->IsInteger32(constant_source)) {
__ mov(kSavedValueRegister, __ mov(kSavedValueRegister,
Operand(cgen_->ToRepresentation(constant_source, r))); Operand(cgen_->ToRepresentation(constant_source, r)));
} else { } else {
__ Move(kSavedValueRegister, __ Move(kSavedValueRegister, cgen_->ToHandle(constant_source));
cgen_->ToHandle(constant_source));
} }
__ str(kSavedValueRegister, cgen_->ToMemOperand(destination)); __ str(kSavedValueRegister, cgen_->ToMemOperand(destination));
} }
...@@ -290,16 +302,11 @@ void LGapResolver::EmitMove(int index) { ...@@ -290,16 +302,11 @@ void LGapResolver::EmitMove(int index) {
ASSERT(destination->IsDoubleStackSlot()); ASSERT(destination->IsDoubleStackSlot());
MemOperand destination_operand = cgen_->ToMemOperand(destination); MemOperand destination_operand = cgen_->ToMemOperand(destination);
if (in_cycle_) { if (in_cycle_) {
// kSavedDoubleValueRegister was used to break the cycle, // kScratchDoubleReg was used to break the cycle.
// but kSavedValueRegister is free. __ vstm(db_w, sp, kScratchDoubleReg, kScratchDoubleReg);
MemOperand source_high_operand = __ vldr(kScratchDoubleReg, source_operand);
cgen_->ToHighMemOperand(source); __ vstr(kScratchDoubleReg, destination_operand);
MemOperand destination_high_operand = __ vldm(ia_w, sp, kScratchDoubleReg, kScratchDoubleReg);
cgen_->ToHighMemOperand(destination);
__ ldr(kSavedValueRegister, source_operand);
__ str(kSavedValueRegister, destination_operand);
__ ldr(kSavedValueRegister, source_high_operand);
__ str(kSavedValueRegister, destination_high_operand);
} else { } else {
__ vldr(kScratchDoubleReg, source_operand); __ vldr(kScratchDoubleReg, source_operand);
__ vstr(kScratchDoubleReg, destination_operand); __ vstr(kScratchDoubleReg, destination_operand);
......
...@@ -76,6 +76,10 @@ class LGapResolver V8_FINAL BASE_EMBEDDED { ...@@ -76,6 +76,10 @@ class LGapResolver V8_FINAL BASE_EMBEDDED {
int root_index_; int root_index_;
bool in_cycle_; bool in_cycle_;
LOperand* saved_destination_; LOperand* saved_destination_;
// We use the root register as a scratch in a few places. When that happens,
// this flag is set to indicate that it needs to be restored.
bool need_to_restore_root_;
}; };
} } // namespace v8::internal } } // namespace v8::internal
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment