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