1b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Copyright 2013 the V8 project authors. All rights reserved. 2b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Use of this source code is governed by a BSD-style license that can be 3b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// found in the LICENSE file. 4b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/crankshaft/arm64/delayed-masm-arm64-inl.h" 6014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/crankshaft/arm64/lithium-codegen-arm64.h" 7014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/crankshaft/arm64/lithium-gap-resolver-arm64.h" 8b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 9b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochnamespace v8 { 10b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochnamespace internal { 11b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 12b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define __ ACCESS_MASM((&masm_)) 13b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 14b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 15b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid DelayedGapMasm::EndDelayedUse() { 16b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DelayedMasm::EndDelayedUse(); 17b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (scratch_register_used()) { 18b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(ScratchRegister().Is(root)); 19b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!pending()); 20b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch InitializeRootRegister(); 21b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch reset_scratch_register_used(); 22b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 23b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 24b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 25b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 26b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochLGapResolver::LGapResolver(LCodeGen* owner) 27b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch : cgen_(owner), masm_(owner, owner->masm()), moves_(32, owner->zone()), 28b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch root_index_(0), in_cycle_(false), saved_destination_(NULL) { 29b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 30b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 31b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 32b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid LGapResolver::Resolve(LParallelMove* parallel_move) { 33b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(moves_.is_empty()); 34b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!masm_.pending()); 35b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 36b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Build up a worklist of moves. 37b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BuildInitialMoveList(parallel_move); 38b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 39b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int i = 0; i < moves_.length(); ++i) { 40b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LMoveOperands move = moves_[i]; 41b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 42b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Skip constants to perform them last. They don't block other moves 43b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // and skipping such moves with register destinations keeps those 44b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // registers free for the whole algorithm. 45b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!move.IsEliminated() && !move.source()->IsConstantOperand()) { 46b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch root_index_ = i; // Any cycle is found when we reach this move again. 47b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PerformMove(i); 48b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (in_cycle_) RestoreValue(); 49b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 50b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 51b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 52b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Perform the moves with constant sources. 53b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int i = 0; i < moves_.length(); ++i) { 54b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LMoveOperands move = moves_[i]; 55b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 56b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!move.IsEliminated()) { 57b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(move.source()->IsConstantOperand()); 58b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch EmitMove(i); 59b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 60b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 61b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 62b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ EndDelayedUse(); 63b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 64b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch moves_.Rewind(0); 65b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 66b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 67b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 68b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid LGapResolver::BuildInitialMoveList(LParallelMove* parallel_move) { 69b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Perform a linear sweep of the moves to add them to the initial list of 70b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // moves to perform, ignoring any move that is redundant (the source is 71b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // the same as the destination, the destination is ignored and 72b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // unallocated, or the move was already eliminated). 73b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const ZoneList<LMoveOperands>* moves = parallel_move->move_operands(); 74b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int i = 0; i < moves->length(); ++i) { 75b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LMoveOperands move = moves->at(i); 76b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!move.IsRedundant()) moves_.Add(move, cgen_->zone()); 77b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 78b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Verify(); 79b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 80b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 81b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 82b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid LGapResolver::PerformMove(int index) { 83b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Each call to this function performs a move and deletes it from the move 84b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // graph. We first recursively perform any move blocking this one. We 85b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // mark a move as "pending" on entry to PerformMove in order to detect 86b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // cycles in the move graph. 87b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LMoveOperands& current_move = moves_[index]; 88b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 89b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!current_move.IsPending()); 90b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!current_move.IsRedundant()); 91b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 92b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Clear this move's destination to indicate a pending move. The actual 93b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // destination is saved in a stack allocated local. Multiple moves can 94b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // be pending because this function is recursive. 95b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(current_move.source() != NULL); // Otherwise it will look eliminated. 96b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LOperand* destination = current_move.destination(); 97b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch current_move.set_destination(NULL); 98b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 99b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Perform a depth-first traversal of the move graph to resolve 100b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // dependencies. Any unperformed, unpending move with a source the same 101b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // as this one's destination blocks this one so recursively perform all 102b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // such moves. 103b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int i = 0; i < moves_.length(); ++i) { 104b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LMoveOperands other_move = moves_[i]; 105b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (other_move.Blocks(destination) && !other_move.IsPending()) { 106b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PerformMove(i); 107b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // If there is a blocking, pending move it must be moves_[root_index_] 108b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // and all other moves with the same source as moves_[root_index_] are 109b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // sucessfully executed (because they are cycle-free) by this loop. 110b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 111b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 112b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 113b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // We are about to resolve this move and don't need it marked as 114b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // pending, so restore its destination. 115b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch current_move.set_destination(destination); 116b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 117b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // The move may be blocked on a pending move, which must be the starting move. 118b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // In this case, we have a cycle, and we save the source of this move to 119b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // a scratch register to break it. 120b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LMoveOperands other_move = moves_[root_index_]; 121b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (other_move.Blocks(destination)) { 122b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(other_move.IsPending()); 123b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BreakCycle(index); 124b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return; 125b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 126b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 127b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // This move is no longer blocked. 128b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch EmitMove(index); 129b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 130b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 131b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 132b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid LGapResolver::Verify() { 133b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifdef ENABLE_SLOW_DCHECKS 134b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // No operand should be the destination for more than one move. 135b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int i = 0; i < moves_.length(); ++i) { 136b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LOperand* destination = moves_[i].destination(); 137b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int j = i + 1; j < moves_.length(); ++j) { 138b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SLOW_DCHECK(!destination->Equals(moves_[j].destination())); 139b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 140b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 141b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif 142b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 143b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 144b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 145b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid LGapResolver::BreakCycle(int index) { 146b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(moves_[index].destination()->Equals(moves_[root_index_].source())); 147b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!in_cycle_); 148b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 149b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // We save in a register the source of that move and we remember its 150b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // destination. Then we mark this move as resolved so the cycle is 151b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // broken and we can perform the other moves. 152b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch in_cycle_ = true; 153b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LOperand* source = moves_[index].source(); 154b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch saved_destination_ = moves_[index].destination(); 155b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 156b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (source->IsRegister()) { 157b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AcquireSavedValueRegister(); 158b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ Mov(SavedValueRegister(), cgen_->ToRegister(source)); 159b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else if (source->IsStackSlot()) { 160b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AcquireSavedValueRegister(); 161b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ Load(SavedValueRegister(), cgen_->ToMemOperand(source)); 162b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else if (source->IsDoubleRegister()) { 163b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ Fmov(SavedFPValueRegister(), cgen_->ToDoubleRegister(source)); 164b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else if (source->IsDoubleStackSlot()) { 165b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ Load(SavedFPValueRegister(), cgen_->ToMemOperand(source)); 166b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 167b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch UNREACHABLE(); 168b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 169b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 170b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Mark this move as resolved. 171b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // This move will be actually performed by moving the saved value to this 172b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // move's destination in LGapResolver::RestoreValue(). 173b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch moves_[index].Eliminate(); 174b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 175b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 176b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 177b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid LGapResolver::RestoreValue() { 178b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(in_cycle_); 179b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(saved_destination_ != NULL); 180b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 181b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (saved_destination_->IsRegister()) { 182b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ Mov(cgen_->ToRegister(saved_destination_), SavedValueRegister()); 183b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ReleaseSavedValueRegister(); 184b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else if (saved_destination_->IsStackSlot()) { 185b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ Store(SavedValueRegister(), cgen_->ToMemOperand(saved_destination_)); 186b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ReleaseSavedValueRegister(); 187b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else if (saved_destination_->IsDoubleRegister()) { 188b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ Fmov(cgen_->ToDoubleRegister(saved_destination_), 189b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SavedFPValueRegister()); 190b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else if (saved_destination_->IsDoubleStackSlot()) { 191b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ Store(SavedFPValueRegister(), cgen_->ToMemOperand(saved_destination_)); 192b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 193b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch UNREACHABLE(); 194b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 195b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 196b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch in_cycle_ = false; 197b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch saved_destination_ = NULL; 198b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 199b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 200b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 201b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid LGapResolver::EmitMove(int index) { 202b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LOperand* source = moves_[index].source(); 203b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LOperand* destination = moves_[index].destination(); 204b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 205b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Dispatch on the source and destination operand kinds. Not all 206b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // combinations are possible. 207b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 208b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (source->IsRegister()) { 209b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register source_register = cgen_->ToRegister(source); 210b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (destination->IsRegister()) { 211b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ Mov(cgen_->ToRegister(destination), source_register); 212b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 213b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(destination->IsStackSlot()); 214b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ Store(source_register, cgen_->ToMemOperand(destination)); 215b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 216b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 217b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else if (source->IsStackSlot()) { 218b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch MemOperand source_operand = cgen_->ToMemOperand(source); 219b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (destination->IsRegister()) { 220b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ Load(cgen_->ToRegister(destination), source_operand); 221b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 222b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(destination->IsStackSlot()); 223b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch EmitStackSlotMove(index); 224b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 225b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 226b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else if (source->IsConstantOperand()) { 227b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LConstantOperand* constant_source = LConstantOperand::cast(source); 228b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (destination->IsRegister()) { 229b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register dst = cgen_->ToRegister(destination); 230b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (cgen_->IsSmi(constant_source)) { 231b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ Mov(dst, cgen_->ToSmi(constant_source)); 232b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else if (cgen_->IsInteger32Constant(constant_source)) { 233b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ Mov(dst, cgen_->ToInteger32(constant_source)); 234b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 235b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ LoadObject(dst, cgen_->ToHandle(constant_source)); 236b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 237b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else if (destination->IsDoubleRegister()) { 238b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DoubleRegister result = cgen_->ToDoubleRegister(destination); 239b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ Fmov(result, cgen_->ToDouble(constant_source)); 240b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 241b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(destination->IsStackSlot()); 242b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!in_cycle_); // Constant moves happen after all cycles are gone. 243b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (cgen_->IsSmi(constant_source)) { 244b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Smi* smi = cgen_->ToSmi(constant_source); 245b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ StoreConstant(reinterpret_cast<intptr_t>(smi), 246b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cgen_->ToMemOperand(destination)); 247b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else if (cgen_->IsInteger32Constant(constant_source)) { 248b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ StoreConstant(cgen_->ToInteger32(constant_source), 249b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cgen_->ToMemOperand(destination)); 250b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 251b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Object> handle = cgen_->ToHandle(constant_source); 252b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AllowDeferredHandleDereference smi_object_check; 253b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (handle->IsSmi()) { 254b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Object* obj = *handle; 255b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!obj->IsHeapObject()); 256b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ StoreConstant(reinterpret_cast<intptr_t>(obj), 257b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cgen_->ToMemOperand(destination)); 258b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 259b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AcquireSavedValueRegister(); 260b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ LoadObject(SavedValueRegister(), handle); 261b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ Store(SavedValueRegister(), cgen_->ToMemOperand(destination)); 262b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ReleaseSavedValueRegister(); 263b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 264b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 265b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 266b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 267b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else if (source->IsDoubleRegister()) { 268b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DoubleRegister src = cgen_->ToDoubleRegister(source); 269b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (destination->IsDoubleRegister()) { 270b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ Fmov(cgen_->ToDoubleRegister(destination), src); 271b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 272b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(destination->IsDoubleStackSlot()); 273b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ Store(src, cgen_->ToMemOperand(destination)); 274b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 275b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 276b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else if (source->IsDoubleStackSlot()) { 277b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch MemOperand src = cgen_->ToMemOperand(source); 278b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (destination->IsDoubleRegister()) { 279b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ Load(cgen_->ToDoubleRegister(destination), src); 280b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 281b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(destination->IsDoubleStackSlot()); 282b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch EmitStackSlotMove(index); 283b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 284b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 285b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 286b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch UNREACHABLE(); 287b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 288b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 289b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // The move has been emitted, we can eliminate it. 290b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch moves_[index].Eliminate(); 291b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 292b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 293014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} // namespace internal 294014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} // namespace v8 295