1864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// Copyright 2011 the V8 project authors. All rights reserved. 2864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// Use of this source code is governed by a BSD-style license that can be 3864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// found in the LICENSE file. 4864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 5196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/v8.h" 6864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 7864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org#if V8_TARGET_ARCH_X87 8864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 9196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/x87/lithium-codegen-x87.h" 104b0feeef5d01dbc2948080b4f69daa37e1083461machenbach@chromium.org#include "src/x87/lithium-gap-resolver-x87.h" 11864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 12864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgnamespace v8 { 13864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgnamespace internal { 14864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 15864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgLGapResolver::LGapResolver(LCodeGen* owner) 16864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org : cgen_(owner), 17864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org moves_(32, owner->zone()), 18864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org source_uses_(), 19864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org destination_uses_(), 20864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org spilled_register_(-1) {} 21864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 22864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 23864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid LGapResolver::Resolve(LParallelMove* parallel_move) { 24e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(HasBeenReset()); 25864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Build up a worklist of moves. 26864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org BuildInitialMoveList(parallel_move); 27864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 28864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org for (int i = 0; i < moves_.length(); ++i) { 29864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org LMoveOperands move = moves_[i]; 30864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Skip constants to perform them last. They don't block other moves 31864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // and skipping such moves with register destinations keeps those 32864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // registers free for the whole algorithm. 33864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (!move.IsEliminated() && !move.source()->IsConstantOperand()) { 34864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org PerformMove(i); 35864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 36864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 37864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 38864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Perform the moves with constant sources. 39864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org for (int i = 0; i < moves_.length(); ++i) { 40864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (!moves_[i].IsEliminated()) { 41e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(moves_[i].source()->IsConstantOperand()); 42864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org EmitMove(i); 43864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 44864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 45864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 46864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Finish(); 47e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(HasBeenReset()); 48864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 49864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 50864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 51864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid LGapResolver::BuildInitialMoveList(LParallelMove* parallel_move) { 52864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Perform a linear sweep of the moves to add them to the initial list of 53864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // moves to perform, ignoring any move that is redundant (the source is 54864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // the same as the destination, the destination is ignored and 55864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // unallocated, or the move was already eliminated). 56864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org const ZoneList<LMoveOperands>* moves = parallel_move->move_operands(); 57864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org for (int i = 0; i < moves->length(); ++i) { 58864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org LMoveOperands move = moves->at(i); 59864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (!move.IsRedundant()) AddMove(move); 60864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 61864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Verify(); 62864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 63864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 64864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 65864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid LGapResolver::PerformMove(int index) { 66864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Each call to this function performs a move and deletes it from the move 67864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // graph. We first recursively perform any move blocking this one. We 68864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // mark a move as "pending" on entry to PerformMove in order to detect 69864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // cycles in the move graph. We use operand swaps to resolve cycles, 70864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // which means that a call to PerformMove could change any source operand 71864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // in the move graph. 72864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 73e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(!moves_[index].IsPending()); 74e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(!moves_[index].IsRedundant()); 75864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 76864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Clear this move's destination to indicate a pending move. The actual 77864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // destination is saved on the side. 78e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(moves_[index].source() != NULL); // Or else it will look eliminated. 79864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org LOperand* destination = moves_[index].destination(); 80864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org moves_[index].set_destination(NULL); 81864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 82864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Perform a depth-first traversal of the move graph to resolve 83864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // dependencies. Any unperformed, unpending move with a source the same 84864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // as this one's destination blocks this one so recursively perform all 85864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // such moves. 86864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org for (int i = 0; i < moves_.length(); ++i) { 87864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org LMoveOperands other_move = moves_[i]; 88864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (other_move.Blocks(destination) && !other_move.IsPending()) { 89864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Though PerformMove can change any source operand in the move graph, 90864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // this call cannot create a blocking move via a swap (this loop does 91864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // not miss any). Assume there is a non-blocking move with source A 92864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // and this move is blocked on source B and there is a swap of A and 93864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // B. Then A and B must be involved in the same cycle (or they would 94864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // not be swapped). Since this move's destination is B and there is 95864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // only a single incoming edge to an operand, this move must also be 96864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // involved in the same cycle. In that case, the blocking move will 97864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // be created but will be "pending" when we return from PerformMove. 98864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org PerformMove(i); 99864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 100864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 101864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 102864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // We are about to resolve this move and don't need it marked as 103864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // pending, so restore its destination. 104864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org moves_[index].set_destination(destination); 105864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 106864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // This move's source may have changed due to swaps to resolve cycles and 107864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // so it may now be the last move in the cycle. If so remove it. 108864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (moves_[index].source()->Equals(destination)) { 109864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org RemoveMove(index); 110864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org return; 111864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 112864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 113864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // The move may be blocked on a (at most one) pending move, in which case 114864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // we have a cycle. Search for such a blocking move and perform a swap to 115864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // resolve it. 116864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org for (int i = 0; i < moves_.length(); ++i) { 117864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org LMoveOperands other_move = moves_[i]; 118864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (other_move.Blocks(destination)) { 119e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(other_move.IsPending()); 120864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org EmitSwap(index); 121864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org return; 122864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 123864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 124864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 125864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // This move is not blocked. 126864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org EmitMove(index); 127864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 128864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 129864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 130864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid LGapResolver::AddMove(LMoveOperands move) { 131864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org LOperand* source = move.source(); 132864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (source->IsRegister()) ++source_uses_[source->index()]; 133864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 134864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org LOperand* destination = move.destination(); 135864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (destination->IsRegister()) ++destination_uses_[destination->index()]; 136864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 137864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org moves_.Add(move, cgen_->zone()); 138864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 139864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 140864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 141864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid LGapResolver::RemoveMove(int index) { 142864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org LOperand* source = moves_[index].source(); 143864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (source->IsRegister()) { 144864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org --source_uses_[source->index()]; 145e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(source_uses_[source->index()] >= 0); 146864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 147864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 148864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org LOperand* destination = moves_[index].destination(); 149864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (destination->IsRegister()) { 150864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org --destination_uses_[destination->index()]; 151e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(destination_uses_[destination->index()] >= 0); 152864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 153864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 154864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org moves_[index].Eliminate(); 155864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 156864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 157864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 158864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgint LGapResolver::CountSourceUses(LOperand* operand) { 159864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int count = 0; 160864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org for (int i = 0; i < moves_.length(); ++i) { 161864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (!moves_[i].IsEliminated() && moves_[i].source()->Equals(operand)) { 162864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org ++count; 163864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 164864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 165864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org return count; 166864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 167864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 168864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 169864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgRegister LGapResolver::GetFreeRegisterNot(Register reg) { 170864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int skip_index = reg.is(no_reg) ? -1 : Register::ToAllocationIndex(reg); 171864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org for (int i = 0; i < Register::NumAllocatableRegisters(); ++i) { 172864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (source_uses_[i] == 0 && destination_uses_[i] > 0 && i != skip_index) { 173864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org return Register::FromAllocationIndex(i); 174864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 175864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 176864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org return no_reg; 177864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 178864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 179864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 180864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgbool LGapResolver::HasBeenReset() { 181864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (!moves_.is_empty()) return false; 182864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (spilled_register_ >= 0) return false; 183864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 184864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org for (int i = 0; i < Register::NumAllocatableRegisters(); ++i) { 185864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (source_uses_[i] != 0) return false; 186864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (destination_uses_[i] != 0) return false; 187864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 188864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org return true; 189864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 190864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 191864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 192864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid LGapResolver::Verify() { 193e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org#ifdef ENABLE_SLOW_DCHECKS 194864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // No operand should be the destination for more than one move. 195864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org for (int i = 0; i < moves_.length(); ++i) { 196864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org LOperand* destination = moves_[i].destination(); 197864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org for (int j = i + 1; j < moves_.length(); ++j) { 198e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org SLOW_DCHECK(!destination->Equals(moves_[j].destination())); 199864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 200864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 201864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org#endif 202864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 203864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 204864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 205864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org#define __ ACCESS_MASM(cgen_->masm()) 206864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 207864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid LGapResolver::Finish() { 208864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (spilled_register_ >= 0) { 209864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ pop(Register::FromAllocationIndex(spilled_register_)); 210864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org spilled_register_ = -1; 211864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 212864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org moves_.Rewind(0); 213864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 214864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 215864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 216864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid LGapResolver::EnsureRestored(LOperand* operand) { 217864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (operand->IsRegister() && operand->index() == spilled_register_) { 218864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ pop(Register::FromAllocationIndex(spilled_register_)); 219864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org spilled_register_ = -1; 220864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 221864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 222864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 223864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 224864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgRegister LGapResolver::EnsureTempRegister() { 225864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // 1. We may have already spilled to create a temp register. 226864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (spilled_register_ >= 0) { 227864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org return Register::FromAllocationIndex(spilled_register_); 228864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 229864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 230864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // 2. We may have a free register that we can use without spilling. 231864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register free = GetFreeRegisterNot(no_reg); 232864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (!free.is(no_reg)) return free; 233864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 234864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // 3. Prefer to spill a register that is not used in any remaining move 235864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // because it will not need to be restored until the end. 236864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org for (int i = 0; i < Register::NumAllocatableRegisters(); ++i) { 237864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (source_uses_[i] == 0 && destination_uses_[i] == 0) { 238864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register scratch = Register::FromAllocationIndex(i); 239864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ push(scratch); 240864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org spilled_register_ = i; 241864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org return scratch; 242864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 243864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 244864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 245864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // 4. Use an arbitrary register. Register 0 is as arbitrary as any other. 246864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register scratch = Register::FromAllocationIndex(0); 247864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ push(scratch); 248864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org spilled_register_ = 0; 249864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org return scratch; 250864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 251864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 252864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 253864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid LGapResolver::EmitMove(int index) { 254864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org LOperand* source = moves_[index].source(); 255864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org LOperand* destination = moves_[index].destination(); 256864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org EnsureRestored(source); 257864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org EnsureRestored(destination); 258864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 259864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Dispatch on the source and destination operand kinds. Not all 260864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // combinations are possible. 261864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (source->IsRegister()) { 262e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(destination->IsRegister() || destination->IsStackSlot()); 263864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register src = cgen_->ToRegister(source); 264864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Operand dst = cgen_->ToOperand(destination); 265864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(dst, src); 266864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 267864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else if (source->IsStackSlot()) { 268e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(destination->IsRegister() || destination->IsStackSlot()); 269864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Operand src = cgen_->ToOperand(source); 270864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (destination->IsRegister()) { 271864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register dst = cgen_->ToRegister(destination); 272864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(dst, src); 273864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else { 274864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Spill on demand to use a temporary register for memory-to-memory 275864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // moves. 276864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register tmp = EnsureTempRegister(); 277864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Operand dst = cgen_->ToOperand(destination); 278864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(tmp, src); 279864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(dst, tmp); 280864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 281864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 282864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else if (source->IsConstantOperand()) { 283864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org LConstantOperand* constant_source = LConstantOperand::cast(source); 284864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (destination->IsRegister()) { 285864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register dst = cgen_->ToRegister(destination); 286864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Representation r = cgen_->IsSmi(constant_source) 287864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org ? Representation::Smi() : Representation::Integer32(); 288864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (cgen_->IsInteger32(constant_source)) { 289864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ Move(dst, cgen_->ToImmediate(constant_source, r)); 290864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else { 291864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ LoadObject(dst, cgen_->ToHandle(constant_source)); 292864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 293864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else if (destination->IsDoubleRegister()) { 294864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org double v = cgen_->ToDouble(constant_source); 295e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org uint64_t int_val = bit_cast<uint64_t, double>(v); 296864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int32_t lower = static_cast<int32_t>(int_val); 297864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int32_t upper = static_cast<int32_t>(int_val >> kBitsPerInt); 298864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ push(Immediate(upper)); 299864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ push(Immediate(lower)); 300864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org X87Register dst = cgen_->ToX87Register(destination); 301864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org cgen_->X87Mov(dst, MemOperand(esp, 0)); 302864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ add(esp, Immediate(kDoubleSize)); 303864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else { 304e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(destination->IsStackSlot()); 305864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Operand dst = cgen_->ToOperand(destination); 306864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Representation r = cgen_->IsSmi(constant_source) 307864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org ? Representation::Smi() : Representation::Integer32(); 308864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (cgen_->IsInteger32(constant_source)) { 309864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ Move(dst, cgen_->ToImmediate(constant_source, r)); 310864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else { 311864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register tmp = EnsureTempRegister(); 312864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ LoadObject(tmp, cgen_->ToHandle(constant_source)); 313864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(dst, tmp); 314864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 315864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 316864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 317864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else if (source->IsDoubleRegister()) { 318864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // load from the register onto the stack, store in destination, which must 319864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // be a double stack slot in the non-SSE2 case. 32006b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org if (destination->IsDoubleStackSlot()) { 32106b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org Operand dst = cgen_->ToOperand(destination); 32206b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org X87Register src = cgen_->ToX87Register(source); 32306b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org cgen_->X87Mov(dst, src); 32406b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org } else { 32506b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org X87Register dst = cgen_->ToX87Register(destination); 32606b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org X87Register src = cgen_->ToX87Register(source); 32706b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org cgen_->X87Mov(dst, src); 32806b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org } 329864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else if (source->IsDoubleStackSlot()) { 330864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // load from the stack slot on top of the floating point stack, and then 331864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // store in destination. If destination is a double register, then it 332864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // represents the top of the stack and nothing needs to be done. 333864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (destination->IsDoubleStackSlot()) { 334864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register tmp = EnsureTempRegister(); 335864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Operand src0 = cgen_->ToOperand(source); 336864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Operand src1 = cgen_->HighOperand(source); 337864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Operand dst0 = cgen_->ToOperand(destination); 338864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Operand dst1 = cgen_->HighOperand(destination); 339864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(tmp, src0); // Then use tmp to copy source to destination. 340864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(dst0, tmp); 341864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(tmp, src1); 342864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(dst1, tmp); 343864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else { 344864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Operand src = cgen_->ToOperand(source); 345864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org X87Register dst = cgen_->ToX87Register(destination); 346864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org cgen_->X87Mov(dst, src); 347864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 348864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else { 349864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org UNREACHABLE(); 350864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 351864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 352864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org RemoveMove(index); 353864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 354864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 355864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 356864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid LGapResolver::EmitSwap(int index) { 357864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org LOperand* source = moves_[index].source(); 358864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org LOperand* destination = moves_[index].destination(); 359864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org EnsureRestored(source); 360864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org EnsureRestored(destination); 361864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 362864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Dispatch on the source and destination operand kinds. Not all 363864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // combinations are possible. 364864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (source->IsRegister() && destination->IsRegister()) { 365864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Register-register. 366864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register src = cgen_->ToRegister(source); 367864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register dst = cgen_->ToRegister(destination); 368864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ xchg(dst, src); 369864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 370864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else if ((source->IsRegister() && destination->IsStackSlot()) || 371864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org (source->IsStackSlot() && destination->IsRegister())) { 372864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Register-memory. Use a free register as a temp if possible. Do not 373864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // spill on demand because the simple spill implementation cannot avoid 374864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // spilling src at this point. 375864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register tmp = GetFreeRegisterNot(no_reg); 376864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register reg = 377864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org cgen_->ToRegister(source->IsRegister() ? source : destination); 378864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Operand mem = 379864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org cgen_->ToOperand(source->IsRegister() ? destination : source); 380864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (tmp.is(no_reg)) { 381864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ xor_(reg, mem); 382864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ xor_(mem, reg); 383864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ xor_(reg, mem); 384864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else { 385864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(tmp, mem); 386864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(mem, reg); 387864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(reg, tmp); 388864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 389864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 390864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else if (source->IsStackSlot() && destination->IsStackSlot()) { 391864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Memory-memory. Spill on demand to use a temporary. If there is a 392864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // free register after that, use it as a second temporary. 393864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register tmp0 = EnsureTempRegister(); 394864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register tmp1 = GetFreeRegisterNot(tmp0); 395864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Operand src = cgen_->ToOperand(source); 396864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Operand dst = cgen_->ToOperand(destination); 397864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (tmp1.is(no_reg)) { 398864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Only one temp register available to us. 399864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(tmp0, dst); 400864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ xor_(tmp0, src); 401864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ xor_(src, tmp0); 402864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ xor_(tmp0, src); 403864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(dst, tmp0); 404864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else { 405864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(tmp0, dst); 406864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(tmp1, src); 407864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(dst, tmp1); 408864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(src, tmp0); 409864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 410864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else { 411864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // No other combinations are possible. 412864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org UNREACHABLE(); 413864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 414864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 415864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // The swap of source and destination has executed a move from source to 416864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // destination. 417864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org RemoveMove(index); 418864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 419864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Any unperformed (including pending) move with a source of either 420864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // this move's source or destination needs to have their source 421864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // changed to reflect the state of affairs after the swap. 422864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org for (int i = 0; i < moves_.length(); ++i) { 423864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org LMoveOperands other_move = moves_[i]; 424864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (other_move.Blocks(source)) { 425864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org moves_[i].set_source(destination); 426864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else if (other_move.Blocks(destination)) { 427864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org moves_[i].set_source(source); 428864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 429864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 430864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 431864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // In addition to swapping the actual uses as sources, we need to update 432864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // the use counts. 433864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (source->IsRegister() && destination->IsRegister()) { 434864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int temp = source_uses_[source->index()]; 435864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org source_uses_[source->index()] = source_uses_[destination->index()]; 436864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org source_uses_[destination->index()] = temp; 437864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else if (source->IsRegister()) { 438864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // We don't have use counts for non-register operands like destination. 439864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Compute those counts now. 440864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org source_uses_[source->index()] = CountSourceUses(source); 441864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else if (destination->IsRegister()) { 442864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org source_uses_[destination->index()] = CountSourceUses(destination); 443864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 444864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 445864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 446864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org#undef __ 447864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 448864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} } // namespace v8::internal 449864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 450864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org#endif // V8_TARGET_ARCH_X87 451