13100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// Copyright (c) 1994-2006 Sun Microsystems Inc.
23100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// All Rights Reserved.
33100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu//
43100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// Redistribution and use in source and binary forms, with or without
53100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// modification, are permitted provided that the following conditions are
63100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// met:
73100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu//
83100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// - Redistributions of source code must retain the above copyright notice,
93100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// this list of conditions and the following disclaimer.
103100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu//
113100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// - Redistribution in binary form must reproduce the above copyright
123100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// notice, this list of conditions and the following disclaimer in the
133100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// documentation and/or other materials provided with the distribution.
143100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu//
153100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// - Neither the name of Sun Microsystems or the names of contributors may
163100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// be used to endorse or promote products derived from this software without
173100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// specific prior written permission.
183100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu//
193100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
203100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
213100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
223100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
233100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
243100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
253100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
263100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
273100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
283100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
293100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
303100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu
313100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// The original source code covered by the above license above has been
323100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// modified significantly by Google Inc.
333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// Copyright 2012 the V8 project authors. All rights reserved.
343100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu
353100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu
363100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu#ifndef V8_MIPS_ASSEMBLER_MIPS_INL_H_
373100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu#define V8_MIPS_ASSEMBLER_MIPS_INL_H_
383100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu
393100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu#include "mips/assembler-mips.h"
403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
413100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu#include "cpu.h"
4244f0eee88ff00398ff7f715fab053374d808c90dSteve Block#include "debug.h"
433100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu
443100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu
453100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescunamespace v8 {
463100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescunamespace internal {
473100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu
483100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// -----------------------------------------------------------------------------
49257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch// Operand and MemOperand.
503100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu
513100271588b61cbc1dc472a3f2f105d2eed8497fAndrei PopescuOperand::Operand(int32_t immediate, RelocInfo::Mode rmode)  {
523100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  rm_ = no_reg;
533100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  imm32_ = immediate;
543100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  rmode_ = rmode;
553100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu}
563100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu
5744f0eee88ff00398ff7f715fab053374d808c90dSteve Block
583100271588b61cbc1dc472a3f2f105d2eed8497fAndrei PopescuOperand::Operand(const ExternalReference& f)  {
593100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  rm_ = no_reg;
603100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  imm32_ = reinterpret_cast<int32_t>(f.address());
613100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  rmode_ = RelocInfo::EXTERNAL_REFERENCE;
623100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu}
633100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu
643100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu
653100271588b61cbc1dc472a3f2f105d2eed8497fAndrei PopescuOperand::Operand(Smi* value) {
663100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  rm_ = no_reg;
673100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  imm32_ =  reinterpret_cast<intptr_t>(value);
683100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  rmode_ = RelocInfo::NONE;
693100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu}
703100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu
7144f0eee88ff00398ff7f715fab053374d808c90dSteve Block
723100271588b61cbc1dc472a3f2f105d2eed8497fAndrei PopescuOperand::Operand(Register rm) {
733100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  rm_ = rm;
743100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu}
753100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu
7644f0eee88ff00398ff7f715fab053374d808c90dSteve Block
773100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescubool Operand::is_reg() const {
783100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  return rm_.is_valid();
793100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu}
803100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu
813100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu
823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochint FPURegister::ToAllocationIndex(FPURegister reg) {
833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  ASSERT(reg.code() % 2 == 0);
843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  ASSERT(reg.code() / 2 < kNumAllocatableRegisters);
853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  ASSERT(reg.is_valid());
863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  ASSERT(!reg.is(kDoubleRegZero));
873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  ASSERT(!reg.is(kLithiumScratchDouble));
883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  return (reg.code() / 2);
893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
91c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch
923100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// -----------------------------------------------------------------------------
93257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch// RelocInfo.
943100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu
953100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescuvoid RelocInfo::apply(intptr_t delta) {
96589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  if (IsCodeTarget(rmode_)) {
97589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    uint32_t scope1 = (uint32_t) target_address() & ~kImm28Mask;
98589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    uint32_t scope2 = reinterpret_cast<uint32_t>(pc_) & ~kImm28Mask;
99589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch
100589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    if (scope1 != scope2) {
101589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      Assembler::JumpLabelToJumpRegister(pc_);
102589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    }
103589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  }
1043fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  if (IsInternalReference(rmode_)) {
1053fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    // Absolute code pointer inside code object moves with the code object.
1063fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    byte* p = reinterpret_cast<byte*>(pc_);
1073fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    int count = Assembler::RelocateInternalReference(p, delta);
1083fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    CPU::FlushICache(p, count * sizeof(uint32_t));
1093fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  }
1103100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu}
1113100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu
1123100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu
1133100271588b61cbc1dc472a3f2f105d2eed8497fAndrei PopescuAddress RelocInfo::target_address() {
1143100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  ASSERT(IsCodeTarget(rmode_) || rmode_ == RUNTIME_ENTRY);
1153100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  return Assembler::target_address_at(pc_);
1163100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu}
1173100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu
1183100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu
1193100271588b61cbc1dc472a3f2f105d2eed8497fAndrei PopescuAddress RelocInfo::target_address_address() {
1203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  ASSERT(IsCodeTarget(rmode_) ||
1213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch         rmode_ == RUNTIME_ENTRY ||
1223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch         rmode_ == EMBEDDED_OBJECT ||
1233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch         rmode_ == EXTERNAL_REFERENCE);
1243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Read the address of the word containing the target_address in an
1253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // instruction stream.
1263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // The only architecture-independent user of this function is the serializer.
1273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // The serializer uses it to find out how many raw bytes of instruction to
1283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // output before the next target.
1293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // For an instruction like LUI/ORI where the target bits are mixed into the
1303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // instruction bits, the size of the target will be zero, indicating that the
1313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // serializer should not step forward in memory after a target is resolved
1323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // and written. In this case the target_address_address function should
1333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // return the end of the instructions to be patched, allowing the
1343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // deserializer to deserialize the instructions as raw bytes and put them in
1353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // place, ready to be patched with the target. After jump optimization,
1363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // that is the address of the instruction that follows J/JAL/JR/JALR
1373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // instruction.
1383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  return reinterpret_cast<Address>(
1393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    pc_ + Assembler::kInstructionsFor32BitConstant * Assembler::kInstrSize);
14044f0eee88ff00398ff7f715fab053374d808c90dSteve Block}
14144f0eee88ff00398ff7f715fab053374d808c90dSteve Block
14244f0eee88ff00398ff7f715fab053374d808c90dSteve Block
14344f0eee88ff00398ff7f715fab053374d808c90dSteve Blockint RelocInfo::target_address_size() {
1443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  return Assembler::kSpecialTargetSize;
1453100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu}
1463100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu
1473100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu
1483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid RelocInfo::set_target_address(Address target, WriteBarrierMode mode) {
1493100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  ASSERT(IsCodeTarget(rmode_) || rmode_ == RUNTIME_ENTRY);
1503100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  Assembler::set_target_address_at(pc_, target);
1513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (mode == UPDATE_WRITE_BARRIER && host() != NULL && IsCodeTarget(rmode_)) {
1523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    Object* target_code = Code::GetCodeFromTargetAddress(target);
1533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    host()->GetHeap()->incremental_marking()->RecordWriteIntoCode(
1543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        host(), this, HeapObject::cast(target_code));
1553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
1563100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu}
1573100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu
1583100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu
1593100271588b61cbc1dc472a3f2f105d2eed8497fAndrei PopescuObject* RelocInfo::target_object() {
1603100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  ASSERT(IsCodeTarget(rmode_) || rmode_ == EMBEDDED_OBJECT);
1613100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  return reinterpret_cast<Object*>(Assembler::target_address_at(pc_));
1623100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu}
1633100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu
1643100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu
1653ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochHandle<Object> RelocInfo::target_object_handle(Assembler* origin) {
1663100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  ASSERT(IsCodeTarget(rmode_) || rmode_ == EMBEDDED_OBJECT);
1673100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  return Handle<Object>(reinterpret_cast<Object**>(
1683100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu      Assembler::target_address_at(pc_)));
1693100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu}
1703100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu
1713100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu
1723100271588b61cbc1dc472a3f2f105d2eed8497fAndrei PopescuObject** RelocInfo::target_object_address() {
17344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // Provide a "natural pointer" to the embedded object,
17444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // which can be de-referenced during heap iteration.
1753100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  ASSERT(IsCodeTarget(rmode_) || rmode_ == EMBEDDED_OBJECT);
176257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  reconstructed_obj_ptr_ =
177257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      reinterpret_cast<Object*>(Assembler::target_address_at(pc_));
178257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  return &reconstructed_obj_ptr_;
1793100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu}
1803100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu
1813100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu
1823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid RelocInfo::set_target_object(Object* target, WriteBarrierMode mode) {
1833100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  ASSERT(IsCodeTarget(rmode_) || rmode_ == EMBEDDED_OBJECT);
1843100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  Assembler::set_target_address_at(pc_, reinterpret_cast<Address>(target));
1853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (mode == UPDATE_WRITE_BARRIER &&
1863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      host() != NULL &&
1873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      target->IsHeapObject()) {
1883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    host()->GetHeap()->incremental_marking()->RecordWrite(
1893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        host(), &Memory::Object_at(pc_), HeapObject::cast(target));
1903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
1913100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu}
1923100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu
1933100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu
1943100271588b61cbc1dc472a3f2f105d2eed8497fAndrei PopescuAddress* RelocInfo::target_reference_address() {
1953100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  ASSERT(rmode_ == EXTERNAL_REFERENCE);
196257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  reconstructed_adr_ptr_ = Assembler::target_address_at(pc_);
197257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  return &reconstructed_adr_ptr_;
19844f0eee88ff00398ff7f715fab053374d808c90dSteve Block}
19944f0eee88ff00398ff7f715fab053374d808c90dSteve Block
20044f0eee88ff00398ff7f715fab053374d808c90dSteve Block
20144f0eee88ff00398ff7f715fab053374d808c90dSteve BlockHandle<JSGlobalPropertyCell> RelocInfo::target_cell_handle() {
20244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ASSERT(rmode_ == RelocInfo::GLOBAL_PROPERTY_CELL);
20344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  Address address = Memory::Address_at(pc_);
20444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  return Handle<JSGlobalPropertyCell>(
20544f0eee88ff00398ff7f715fab053374d808c90dSteve Block      reinterpret_cast<JSGlobalPropertyCell**>(address));
20644f0eee88ff00398ff7f715fab053374d808c90dSteve Block}
20744f0eee88ff00398ff7f715fab053374d808c90dSteve Block
20844f0eee88ff00398ff7f715fab053374d808c90dSteve Block
20944f0eee88ff00398ff7f715fab053374d808c90dSteve BlockJSGlobalPropertyCell* RelocInfo::target_cell() {
21044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ASSERT(rmode_ == RelocInfo::GLOBAL_PROPERTY_CELL);
21144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  Address address = Memory::Address_at(pc_);
21244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  Object* object = HeapObject::FromAddress(
21344f0eee88ff00398ff7f715fab053374d808c90dSteve Block      address - JSGlobalPropertyCell::kValueOffset);
21444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  return reinterpret_cast<JSGlobalPropertyCell*>(object);
21544f0eee88ff00398ff7f715fab053374d808c90dSteve Block}
21644f0eee88ff00398ff7f715fab053374d808c90dSteve Block
21744f0eee88ff00398ff7f715fab053374d808c90dSteve Block
2183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid RelocInfo::set_target_cell(JSGlobalPropertyCell* cell,
2193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                WriteBarrierMode mode) {
22044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ASSERT(rmode_ == RelocInfo::GLOBAL_PROPERTY_CELL);
22144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  Address address = cell->address() + JSGlobalPropertyCell::kValueOffset;
22244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  Memory::Address_at(pc_) = address;
2233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (mode == UPDATE_WRITE_BARRIER && host() != NULL) {
2243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    // TODO(1550) We are passing NULL as a slot because cell can never be on
2253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    // evacuation candidate.
2263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    host()->GetHeap()->incremental_marking()->RecordWrite(
2273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        host(), NULL, cell);
2283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
2293100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu}
2303100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu
2313100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu
2323100271588b61cbc1dc472a3f2f105d2eed8497fAndrei PopescuAddress RelocInfo::call_address() {
23344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ASSERT((IsJSReturn(rmode()) && IsPatchedReturnSequence()) ||
23444f0eee88ff00398ff7f715fab053374d808c90dSteve Block         (IsDebugBreakSlot(rmode()) && IsPatchedDebugBreakSlotSequence()));
23544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // The pc_ offset of 0 assumes mips patched return sequence per
23644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // debug-mips.cc BreakLocationIterator::SetDebugBreakAtReturn(), or
23744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // debug break slot per BreakLocationIterator::SetDebugBreakAtSlot().
23844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  return Assembler::target_address_at(pc_);
2393100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu}
2403100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu
2413100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu
2423100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescuvoid RelocInfo::set_call_address(Address target) {
24344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ASSERT((IsJSReturn(rmode()) && IsPatchedReturnSequence()) ||
24444f0eee88ff00398ff7f715fab053374d808c90dSteve Block         (IsDebugBreakSlot(rmode()) && IsPatchedDebugBreakSlotSequence()));
24544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // The pc_ offset of 0 assumes mips patched return sequence per
24644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // debug-mips.cc BreakLocationIterator::SetDebugBreakAtReturn(), or
24744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // debug break slot per BreakLocationIterator::SetDebugBreakAtSlot().
24844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  Assembler::set_target_address_at(pc_, target);
2493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (host() != NULL) {
2503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    Object* target_code = Code::GetCodeFromTargetAddress(target);
2513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    host()->GetHeap()->incremental_marking()->RecordWriteIntoCode(
2523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        host(), this, HeapObject::cast(target_code));
2533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
2543100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu}
2553100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu
2563100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu
2573100271588b61cbc1dc472a3f2f105d2eed8497fAndrei PopescuObject* RelocInfo::call_object() {
2583100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  return *call_object_address();
2593100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu}
2603100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu
2613100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu
2623100271588b61cbc1dc472a3f2f105d2eed8497fAndrei PopescuObject** RelocInfo::call_object_address() {
26344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ASSERT((IsJSReturn(rmode()) && IsPatchedReturnSequence()) ||
26444f0eee88ff00398ff7f715fab053374d808c90dSteve Block         (IsDebugBreakSlot(rmode()) && IsPatchedDebugBreakSlotSequence()));
2653100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  return reinterpret_cast<Object**>(pc_ + 2 * Assembler::kInstrSize);
2663100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu}
2673100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu
2683100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu
2693100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescuvoid RelocInfo::set_call_object(Object* target) {
2703100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  *call_object_address() = target;
2713100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu}
2723100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu
2733100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu
2743100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescubool RelocInfo::IsPatchedReturnSequence() {
27544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  Instr instr0 = Assembler::instr_at(pc_);
27644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  Instr instr1 = Assembler::instr_at(pc_ + 1 * Assembler::kInstrSize);
27744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  Instr instr2 = Assembler::instr_at(pc_ + 2 * Assembler::kInstrSize);
27844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  bool patched_return = ((instr0 & kOpcodeMask) == LUI &&
27944f0eee88ff00398ff7f715fab053374d808c90dSteve Block                         (instr1 & kOpcodeMask) == ORI &&
280589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch                         ((instr2 & kOpcodeMask) == JAL ||
281589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch                          ((instr2 & kOpcodeMask) == SPECIAL &&
282589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch                           (instr2 & kFunctionFieldMask) == JALR)));
28344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  return patched_return;
28444f0eee88ff00398ff7f715fab053374d808c90dSteve Block}
28544f0eee88ff00398ff7f715fab053374d808c90dSteve Block
28644f0eee88ff00398ff7f715fab053374d808c90dSteve Block
28744f0eee88ff00398ff7f715fab053374d808c90dSteve Blockbool RelocInfo::IsPatchedDebugBreakSlotSequence() {
28844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  Instr current_instr = Assembler::instr_at(pc_);
28944f0eee88ff00398ff7f715fab053374d808c90dSteve Block  return !Assembler::IsNop(current_instr, Assembler::DEBUG_BREAK_NOP);
29044f0eee88ff00398ff7f715fab053374d808c90dSteve Block}
29144f0eee88ff00398ff7f715fab053374d808c90dSteve Block
29244f0eee88ff00398ff7f715fab053374d808c90dSteve Block
29344f0eee88ff00398ff7f715fab053374d808c90dSteve Blockvoid RelocInfo::Visit(ObjectVisitor* visitor) {
29444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  RelocInfo::Mode mode = rmode();
29544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  if (mode == RelocInfo::EMBEDDED_OBJECT) {
2963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    visitor->VisitEmbeddedPointer(this);
29744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  } else if (RelocInfo::IsCodeTarget(mode)) {
29844f0eee88ff00398ff7f715fab053374d808c90dSteve Block    visitor->VisitCodeTarget(this);
299257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  } else if (mode == RelocInfo::GLOBAL_PROPERTY_CELL) {
300257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    visitor->VisitGlobalPropertyCell(this);
30144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  } else if (mode == RelocInfo::EXTERNAL_REFERENCE) {
3023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    visitor->VisitExternalReference(this);
30344f0eee88ff00398ff7f715fab053374d808c90dSteve Block#ifdef ENABLE_DEBUGGER_SUPPORT
30444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // TODO(isolates): Get a cached isolate below.
30544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  } else if (((RelocInfo::IsJSReturn(mode) &&
3063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch              IsPatchedReturnSequence()) ||
3073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch             (RelocInfo::IsDebugBreakSlot(mode) &&
3083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch             IsPatchedDebugBreakSlotSequence())) &&
30944f0eee88ff00398ff7f715fab053374d808c90dSteve Block             Isolate::Current()->debug()->has_break_points()) {
31044f0eee88ff00398ff7f715fab053374d808c90dSteve Block    visitor->VisitDebugTarget(this);
3113100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu#endif
31244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  } else if (mode == RelocInfo::RUNTIME_ENTRY) {
31344f0eee88ff00398ff7f715fab053374d808c90dSteve Block    visitor->VisitRuntimeEntry(this);
31444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  }
31544f0eee88ff00398ff7f715fab053374d808c90dSteve Block}
31644f0eee88ff00398ff7f715fab053374d808c90dSteve Block
31744f0eee88ff00398ff7f715fab053374d808c90dSteve Block
31844f0eee88ff00398ff7f715fab053374d808c90dSteve Blocktemplate<typename StaticVisitor>
31944f0eee88ff00398ff7f715fab053374d808c90dSteve Blockvoid RelocInfo::Visit(Heap* heap) {
32044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  RelocInfo::Mode mode = rmode();
32144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  if (mode == RelocInfo::EMBEDDED_OBJECT) {
3223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    StaticVisitor::VisitEmbeddedPointer(heap, this);
32344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  } else if (RelocInfo::IsCodeTarget(mode)) {
324257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    StaticVisitor::VisitCodeTarget(heap, this);
325257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  } else if (mode == RelocInfo::GLOBAL_PROPERTY_CELL) {
326257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    StaticVisitor::VisitGlobalPropertyCell(heap, this);
32744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  } else if (mode == RelocInfo::EXTERNAL_REFERENCE) {
3283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    StaticVisitor::VisitExternalReference(this);
32944f0eee88ff00398ff7f715fab053374d808c90dSteve Block#ifdef ENABLE_DEBUGGER_SUPPORT
33044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  } else if (heap->isolate()->debug()->has_break_points() &&
33144f0eee88ff00398ff7f715fab053374d808c90dSteve Block             ((RelocInfo::IsJSReturn(mode) &&
33244f0eee88ff00398ff7f715fab053374d808c90dSteve Block              IsPatchedReturnSequence()) ||
33344f0eee88ff00398ff7f715fab053374d808c90dSteve Block             (RelocInfo::IsDebugBreakSlot(mode) &&
33444f0eee88ff00398ff7f715fab053374d808c90dSteve Block              IsPatchedDebugBreakSlotSequence()))) {
335257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    StaticVisitor::VisitDebugTarget(heap, this);
33644f0eee88ff00398ff7f715fab053374d808c90dSteve Block#endif
33744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  } else if (mode == RelocInfo::RUNTIME_ENTRY) {
33844f0eee88ff00398ff7f715fab053374d808c90dSteve Block    StaticVisitor::VisitRuntimeEntry(this);
33944f0eee88ff00398ff7f715fab053374d808c90dSteve Block  }
3403100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu}
3413100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu
3423100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu
3433100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// -----------------------------------------------------------------------------
344257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch// Assembler.
3453100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu
3463100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu
3473100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescuvoid Assembler::CheckBuffer() {
3483100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  if (buffer_space() <= kGap) {
3493100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu    GrowBuffer();
3503100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  }
3513100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu}
3523100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu
3533100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu
35444f0eee88ff00398ff7f715fab053374d808c90dSteve Blockvoid Assembler::CheckTrampolinePoolQuick() {
35544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  if (pc_offset() >= next_buffer_check_) {
35644f0eee88ff00398ff7f715fab053374d808c90dSteve Block    CheckTrampolinePool();
35744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  }
35844f0eee88ff00398ff7f715fab053374d808c90dSteve Block}
35944f0eee88ff00398ff7f715fab053374d808c90dSteve Block
36044f0eee88ff00398ff7f715fab053374d808c90dSteve Block
3613100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescuvoid Assembler::emit(Instr x) {
3623fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  if (!is_buffer_growth_blocked()) {
3633fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    CheckBuffer();
3643fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  }
3653100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  *reinterpret_cast<Instr*>(pc_) = x;
3663100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  pc_ += kInstrSize;
36744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  CheckTrampolinePoolQuick();
3683100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu}
3693100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu
3703100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu
3713100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu} }  // namespace v8::internal
3723100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu
3733100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu#endif  // V8_MIPS_ASSEMBLER_MIPS_INL_H_
374