12efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org// Copyright 2012 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. 4c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 5196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/v8.h" 6c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 7196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/mips/lithium-codegen-mips.h" 84b0feeef5d01dbc2948080b4f69daa37e1083461machenbach@chromium.org#include "src/mips/lithium-gap-resolver-mips.h" 9c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 10c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgnamespace v8 { 11c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgnamespace internal { 12c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 13c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgLGapResolver::LGapResolver(LCodeGen* owner) 14c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org : cgen_(owner), 157028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org moves_(32, owner->zone()), 16c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org root_index_(0), 17c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org in_cycle_(false), 18c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org saved_destination_(NULL) {} 19c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 20c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 21c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LGapResolver::Resolve(LParallelMove* parallel_move) { 22e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(moves_.is_empty()); 23c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // Build up a worklist of moves. 24c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org BuildInitialMoveList(parallel_move); 25c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 26c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org for (int i = 0; i < moves_.length(); ++i) { 27c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org LMoveOperands move = moves_[i]; 28c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // Skip constants to perform them last. They don't block other moves 29c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // and skipping such moves with register destinations keeps those 30c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // registers free for the whole algorithm. 31c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org if (!move.IsEliminated() && !move.source()->IsConstantOperand()) { 32c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org root_index_ = i; // Any cycle is found when by reaching this move again. 33c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org PerformMove(i); 34c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org if (in_cycle_) { 35c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org RestoreValue(); 36c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } 37c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } 38c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } 39c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 40c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // Perform the moves with constant sources. 41c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org for (int i = 0; i < moves_.length(); ++i) { 42c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org if (!moves_[i].IsEliminated()) { 43e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(moves_[i].source()->IsConstantOperand()); 44c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org EmitMove(i); 45c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } 46c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } 47c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 48c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org moves_.Rewind(0); 49c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org} 50c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 51c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 52c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LGapResolver::BuildInitialMoveList(LParallelMove* parallel_move) { 53c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // Perform a linear sweep of the moves to add them to the initial list of 54c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // moves to perform, ignoring any move that is redundant (the source is 55c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // the same as the destination, the destination is ignored and 56c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // unallocated, or the move was already eliminated). 57c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org const ZoneList<LMoveOperands>* moves = parallel_move->move_operands(); 58c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org for (int i = 0; i < moves->length(); ++i) { 59c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org LMoveOperands move = moves->at(i); 607028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org if (!move.IsRedundant()) moves_.Add(move, cgen_->zone()); 61c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } 62c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Verify(); 63c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org} 64c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 65c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 66c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LGapResolver::PerformMove(int index) { 67c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // Each call to this function performs a move and deletes it from the move 68c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // graph. We first recursively perform any move blocking this one. We 69c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // mark a move as "pending" on entry to PerformMove in order to detect 70c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // cycles in the move graph. 71c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 72c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // We can only find a cycle, when doing a depth-first traversal of moves, 73c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // be encountering the starting move again. So by spilling the source of 74c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // the starting move, we break the cycle. All moves are then unblocked, 75c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // and the starting move is completed by writing the spilled value to 76c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // its destination. All other moves from the spilled source have been 77c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // completed prior to breaking the cycle. 78c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // An additional complication is that moves to MemOperands with large 79c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // offsets (more than 1K or 4K) require us to spill this spilled value to 80c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // the stack, to free up the register. 81e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(!moves_[index].IsPending()); 82e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(!moves_[index].IsRedundant()); 83c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 84c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // Clear this move's destination to indicate a pending move. The actual 85c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // destination is saved in a stack allocated local. Multiple moves can 86c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // be pending because this function is recursive. 87e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(moves_[index].source() != NULL); // Or else it will look eliminated. 88c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org LOperand* destination = moves_[index].destination(); 89c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org moves_[index].set_destination(NULL); 90c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 91c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // Perform a depth-first traversal of the move graph to resolve 92c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // dependencies. Any unperformed, unpending move with a source the same 93c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // as this one's destination blocks this one so recursively perform all 94c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // such moves. 95c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org for (int i = 0; i < moves_.length(); ++i) { 96c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org LMoveOperands other_move = moves_[i]; 97c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org if (other_move.Blocks(destination) && !other_move.IsPending()) { 98c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org PerformMove(i); 99c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // If there is a blocking, pending move it must be moves_[root_index_] 100c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // and all other moves with the same source as moves_[root_index_] are 101c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // sucessfully executed (because they are cycle-free) by this loop. 102c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } 103c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } 104c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 105c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // We are about to resolve this move and don't need it marked as 106c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // pending, so restore its destination. 107c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org moves_[index].set_destination(destination); 108c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 109c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // The move may be blocked on a pending move, which must be the starting move. 110c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // In this case, we have a cycle, and we save the source of this move to 111c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // a scratch register to break it. 112c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org LMoveOperands other_move = moves_[root_index_]; 113c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org if (other_move.Blocks(destination)) { 114e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(other_move.IsPending()); 115c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org BreakCycle(index); 116c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org return; 117c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } 118c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 119c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // This move is no longer blocked. 120c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org EmitMove(index); 121c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org} 122c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 123c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 124c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LGapResolver::Verify() { 125e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org#ifdef ENABLE_SLOW_DCHECKS 126c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // No operand should be the destination for more than one move. 127c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org for (int i = 0; i < moves_.length(); ++i) { 128c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org LOperand* destination = moves_[i].destination(); 129c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org for (int j = i + 1; j < moves_.length(); ++j) { 130e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org SLOW_DCHECK(!destination->Equals(moves_[j].destination())); 131c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } 132c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } 133c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org#endif 134c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org} 135c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 136c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org#define __ ACCESS_MASM(cgen_->masm()) 137c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 138c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LGapResolver::BreakCycle(int index) { 139c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // We save in a register the value that should end up in the source of 140c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // moves_[root_index]. After performing all moves in the tree rooted 141c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // in that move, we save the value to that source. 142e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(moves_[index].destination()->Equals(moves_[root_index_].source())); 143e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(!in_cycle_); 144c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org in_cycle_ = true; 145c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org LOperand* source = moves_[index].source(); 146c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org saved_destination_ = moves_[index].destination(); 147c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org if (source->IsRegister()) { 1487d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.org __ mov(kLithiumScratchReg, cgen_->ToRegister(source)); 149c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } else if (source->IsStackSlot()) { 1507d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.org __ lw(kLithiumScratchReg, cgen_->ToMemOperand(source)); 151c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } else if (source->IsDoubleRegister()) { 1522efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org __ mov_d(kLithiumScratchDouble, cgen_->ToDoubleRegister(source)); 153c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } else if (source->IsDoubleStackSlot()) { 1542efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org __ ldc1(kLithiumScratchDouble, cgen_->ToMemOperand(source)); 155c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } else { 156c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org UNREACHABLE(); 157c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } 158c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // This move will be done by restoring the saved value to the destination. 159c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org moves_[index].Eliminate(); 160c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org} 161c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 162c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 163c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LGapResolver::RestoreValue() { 164e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(in_cycle_); 165e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(saved_destination_ != NULL); 166c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 1677d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.org // Spilled value is in kLithiumScratchReg or kLithiumScratchDouble. 168c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org if (saved_destination_->IsRegister()) { 1697d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.org __ mov(cgen_->ToRegister(saved_destination_), kLithiumScratchReg); 170c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } else if (saved_destination_->IsStackSlot()) { 1717d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.org __ sw(kLithiumScratchReg, cgen_->ToMemOperand(saved_destination_)); 172c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } else if (saved_destination_->IsDoubleRegister()) { 173c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ mov_d(cgen_->ToDoubleRegister(saved_destination_), 1742efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org kLithiumScratchDouble); 175c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } else if (saved_destination_->IsDoubleStackSlot()) { 1762efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org __ sdc1(kLithiumScratchDouble, 177c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org cgen_->ToMemOperand(saved_destination_)); 178c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } else { 179c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org UNREACHABLE(); 180c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } 181c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 182c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org in_cycle_ = false; 183c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org saved_destination_ = NULL; 184c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org} 185c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 186c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 187c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LGapResolver::EmitMove(int index) { 188c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org LOperand* source = moves_[index].source(); 189c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org LOperand* destination = moves_[index].destination(); 190c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 191c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // Dispatch on the source and destination operand kinds. Not all 192c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // combinations are possible. 193c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 194c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org if (source->IsRegister()) { 195c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Register source_register = cgen_->ToRegister(source); 196c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org if (destination->IsRegister()) { 197c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ mov(cgen_->ToRegister(destination), source_register); 198c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } else { 199e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(destination->IsStackSlot()); 200c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ sw(source_register, cgen_->ToMemOperand(destination)); 201c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } 202c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } else if (source->IsStackSlot()) { 203c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org MemOperand source_operand = cgen_->ToMemOperand(source); 204c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org if (destination->IsRegister()) { 205c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ lw(cgen_->ToRegister(destination), source_operand); 206c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } else { 207e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(destination->IsStackSlot()); 208c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org MemOperand destination_operand = cgen_->ToMemOperand(destination); 209c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org if (in_cycle_) { 210c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org if (!destination_operand.OffsetIsInt16Encodable()) { 211c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // 'at' is overwritten while saving the value to the destination. 212c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // Therefore we can't use 'at'. It is OK if the read from the source 213c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // destroys 'at', since that happens before the value is read. 214c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // This uses only a single reg of the double reg-pair. 2152efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org __ lwc1(kLithiumScratchDouble, source_operand); 2162efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org __ swc1(kLithiumScratchDouble, destination_operand); 217c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } else { 218c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ lw(at, source_operand); 219c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ sw(at, destination_operand); 220c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } 221c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } else { 2227d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.org __ lw(kLithiumScratchReg, source_operand); 2237d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.org __ sw(kLithiumScratchReg, destination_operand); 224c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } 225c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } 226c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 227c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } else if (source->IsConstantOperand()) { 228fab1498f2f42726c7de46c3ed560d56dd072a8b3rossberg@chromium.org LConstantOperand* constant_source = LConstantOperand::cast(source); 229c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org if (destination->IsRegister()) { 230fab1498f2f42726c7de46c3ed560d56dd072a8b3rossberg@chromium.org Register dst = cgen_->ToRegister(destination); 231fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org Representation r = cgen_->IsSmi(constant_source) 232fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org ? Representation::Smi() : Representation::Integer32(); 233fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org if (cgen_->IsInteger32(constant_source)) { 234fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org __ li(dst, Operand(cgen_->ToRepresentation(constant_source, r))); 235fab1498f2f42726c7de46c3ed560d56dd072a8b3rossberg@chromium.org } else { 236057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org __ li(dst, cgen_->ToHandle(constant_source)); 237fab1498f2f42726c7de46c3ed560d56dd072a8b3rossberg@chromium.org } 238594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org } else if (destination->IsDoubleRegister()) { 239e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org DoubleRegister result = cgen_->ToDoubleRegister(destination); 240e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org double v = cgen_->ToDouble(constant_source); 241e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org __ Move(result, v); 242c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } else { 243e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(destination->IsStackSlot()); 244e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(!in_cycle_); // Constant moves happen after all cycles are gone. 245fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org Representation r = cgen_->IsSmi(constant_source) 246fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org ? Representation::Smi() : Representation::Integer32(); 247fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org if (cgen_->IsInteger32(constant_source)) { 2487d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.org __ li(kLithiumScratchReg, 249fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org Operand(cgen_->ToRepresentation(constant_source, r))); 250fab1498f2f42726c7de46c3ed560d56dd072a8b3rossberg@chromium.org } else { 251057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org __ li(kLithiumScratchReg, cgen_->ToHandle(constant_source)); 252fab1498f2f42726c7de46c3ed560d56dd072a8b3rossberg@chromium.org } 2537d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.org __ sw(kLithiumScratchReg, cgen_->ToMemOperand(destination)); 254c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } 255c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 256c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } else if (source->IsDoubleRegister()) { 257c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org DoubleRegister source_register = cgen_->ToDoubleRegister(source); 258c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org if (destination->IsDoubleRegister()) { 259c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ mov_d(cgen_->ToDoubleRegister(destination), source_register); 260c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } else { 261e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(destination->IsDoubleStackSlot()); 262c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org MemOperand destination_operand = cgen_->ToMemOperand(destination); 263c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ sdc1(source_register, destination_operand); 264c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } 265c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 266c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } else if (source->IsDoubleStackSlot()) { 267c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org MemOperand source_operand = cgen_->ToMemOperand(source); 268c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org if (destination->IsDoubleRegister()) { 269c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ ldc1(cgen_->ToDoubleRegister(destination), source_operand); 270c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } else { 271e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(destination->IsDoubleStackSlot()); 272c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org MemOperand destination_operand = cgen_->ToMemOperand(destination); 273c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org if (in_cycle_) { 2742efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org // kLithiumScratchDouble was used to break the cycle, 2757d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.org // but kLithiumScratchReg is free. 276c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org MemOperand source_high_operand = 277c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org cgen_->ToHighMemOperand(source); 278c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org MemOperand destination_high_operand = 279c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org cgen_->ToHighMemOperand(destination); 2807d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.org __ lw(kLithiumScratchReg, source_operand); 2817d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.org __ sw(kLithiumScratchReg, destination_operand); 2827d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.org __ lw(kLithiumScratchReg, source_high_operand); 2837d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.org __ sw(kLithiumScratchReg, destination_high_operand); 284c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } else { 2852efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org __ ldc1(kLithiumScratchDouble, source_operand); 2862efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org __ sdc1(kLithiumScratchDouble, destination_operand); 287c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } 288c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } 289c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } else { 290c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org UNREACHABLE(); 291c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } 292c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 293c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org moves_[index].Eliminate(); 294c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org} 295c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 296c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 297c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org#undef __ 298c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 299c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org} } // namespace v8::internal 300