1958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// Copyright (c) 1994-2006 Sun Microsystems Inc. 2958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// All Rights Reserved. 3958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// 4958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// Redistribution and use in source and binary forms, with or without 5958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// modification, are permitted provided that the following conditions 6958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// are met: 7958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// 8958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// - Redistributions of source code must retain the above copyright notice, 9958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// this list of conditions and the following disclaimer. 10958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// 11958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// - Redistribution in binary form must reproduce the above copyright 12958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// notice, this list of conditions and the following disclaimer in the 13958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// documentation and/or other materials provided with the 14958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// distribution. 15958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// 16958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// - Neither the name of Sun Microsystems or the names of contributors may 17958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// be used to endorse or promote products derived from this software without 18958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// specific prior written permission. 19958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// 20958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 23958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 24958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 25958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 26958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 27958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 29958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 30958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 31958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// OF THE POSSIBILITY OF SUCH DAMAGE. 32958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 33958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// The original source code covered by the above license above has been modified 34958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// significantly by Google Inc. 35958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// Copyright 2014 the V8 project authors. All rights reserved. 36958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 37958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#ifndef V8_PPC_ASSEMBLER_PPC_INL_H_ 38958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#define V8_PPC_ASSEMBLER_PPC_INL_H_ 39958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 40958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#include "src/ppc/assembler-ppc.h" 41958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 42958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#include "src/assembler.h" 43014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/debug/debug.h" 4462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch#include "src/objects-inl.h" 45958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 46958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniernamespace v8 { 47958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniernamespace internal { 48958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 49958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 50958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierbool CpuFeatures::SupportsCrankshaft() { return true; } 51958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 52f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochbool CpuFeatures::SupportsSimd128() { return false; } 53958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 54014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid RelocInfo::apply(intptr_t delta) { 55014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // absolute code pointer inside code object moves with the code object. 56014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (IsInternalReference(rmode_)) { 57014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Jump table entry 58014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Address target = Memory::Address_at(pc_); 59014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Memory::Address_at(pc_) = target + delta; 60014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 61014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // mov sequence 62014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(IsInternalReferenceEncoded(rmode_)); 63014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Address target = Assembler::target_address_at(pc_, host_); 64014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Assembler::set_target_address_at(isolate_, pc_, host_, target + delta, 65014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch SKIP_ICACHE_FLUSH); 66958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 67014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 68014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 69014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 70014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochAddress RelocInfo::target_internal_reference() { 71014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (IsInternalReference(rmode_)) { 72014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Jump table entry 73014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return Memory::Address_at(pc_); 74014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 75014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // mov sequence 76014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(IsInternalReferenceEncoded(rmode_)); 77014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return Assembler::target_address_at(pc_, host_); 78014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 79014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 80014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 81014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 82014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochAddress RelocInfo::target_internal_reference_address() { 83014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(IsInternalReference(rmode_) || IsInternalReferenceEncoded(rmode_)); 84014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return reinterpret_cast<Address>(pc_); 85958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 86958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 87958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 88958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily BernierAddress RelocInfo::target_address() { 89958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(IsCodeTarget(rmode_) || IsRuntimeEntry(rmode_)); 90958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return Assembler::target_address_at(pc_, host_); 91958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 92958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 93958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily BernierAddress RelocInfo::target_address_address() { 94958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(IsCodeTarget(rmode_) || IsRuntimeEntry(rmode_) || 95958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier rmode_ == EMBEDDED_OBJECT || rmode_ == EXTERNAL_REFERENCE); 96958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 97014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (FLAG_enable_embedded_constant_pool && 98014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Assembler::IsConstantPoolLoadStart(pc_)) { 99014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // We return the PC for embedded constant pool since this function is used 100014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // by the serializer and expects the address to reside within the code 101014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // object. 102958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return reinterpret_cast<Address>(pc_); 103958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 104958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 105958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Read the address of the word containing the target_address in an 106958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // instruction stream. 107958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // The only architecture-independent user of this function is the serializer. 108958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // The serializer uses it to find out how many raw bytes of instruction to 109958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // output before the next target. 110958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // For an instruction like LIS/ORI where the target bits are mixed into the 111958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // instruction bits, the size of the target will be zero, indicating that the 112958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // serializer should not step forward in memory after a target is resolved 113958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // and written. 114958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return reinterpret_cast<Address>(pc_); 115958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 116958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 117958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 118958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily BernierAddress RelocInfo::constant_pool_entry_address() { 119014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (FLAG_enable_embedded_constant_pool) { 120014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Address constant_pool = host_->constant_pool(); 121014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(constant_pool); 122014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ConstantPoolEntry::Access access; 123014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (Assembler::IsConstantPoolLoadStart(pc_, &access)) 124014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return Assembler::target_constant_pool_address_at( 125014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch pc_, constant_pool, access, ConstantPoolEntry::INTPTR); 126014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 127958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier UNREACHABLE(); 128958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return NULL; 129958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 130958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 131958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 132958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierint RelocInfo::target_address_size() { return Assembler::kSpecialTargetSize; } 133958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 13462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen MurdochAddress Assembler::target_address_at(Address pc, Code* code) { 13562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Address constant_pool = code ? code->constant_pool() : NULL; 13662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch return target_address_at(pc, constant_pool); 13762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch} 13862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 13962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochvoid Assembler::set_target_address_at(Isolate* isolate, Address pc, Code* code, 14062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Address target, 14162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch ICacheFlushMode icache_flush_mode) { 14262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Address constant_pool = code ? code->constant_pool() : NULL; 14362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch set_target_address_at(isolate, pc, constant_pool, target, icache_flush_mode); 14462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch} 145958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 146958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily BernierAddress Assembler::target_address_from_return_address(Address pc) { 147958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// Returns the address of the call target from the return address that will 148958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// be returned to after a call. 149958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// Call sequence is : 150958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// mov ip, @ call address 151958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// mtlr ip 152958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// blrl 153958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// @ return address 154014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int len; 155014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ConstantPoolEntry::Access access; 156014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (FLAG_enable_embedded_constant_pool && 157014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch IsConstantPoolLoadEnd(pc - 3 * kInstrSize, &access)) { 158014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch len = (access == ConstantPoolEntry::OVERFLOWED) ? 2 : 1; 159014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 160014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch len = kMovInstructionsNoConstantPool; 161958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 162014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return pc - (len + 2) * kInstrSize; 163958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 164958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 165958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 166958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily BernierAddress Assembler::return_address_from_call_start(Address pc) { 167014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int len; 168014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ConstantPoolEntry::Access access; 169014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (FLAG_enable_embedded_constant_pool && 170014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch IsConstantPoolLoadStart(pc, &access)) { 171014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch len = (access == ConstantPoolEntry::OVERFLOWED) ? 2 : 1; 172014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 173014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch len = kMovInstructionsNoConstantPool; 174014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 175014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return pc + (len + 2) * kInstrSize; 176958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 177958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 178958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily BernierObject* RelocInfo::target_object() { 179958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(IsCodeTarget(rmode_) || rmode_ == EMBEDDED_OBJECT); 180958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return reinterpret_cast<Object*>(Assembler::target_address_at(pc_, host_)); 181958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 182958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 183958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 184958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily BernierHandle<Object> RelocInfo::target_object_handle(Assembler* origin) { 185958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(IsCodeTarget(rmode_) || rmode_ == EMBEDDED_OBJECT); 186958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return Handle<Object>( 187958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier reinterpret_cast<Object**>(Assembler::target_address_at(pc_, host_))); 188958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 189958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 190958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 191958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid RelocInfo::set_target_object(Object* target, 192958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier WriteBarrierMode write_barrier_mode, 193958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier ICacheFlushMode icache_flush_mode) { 194958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(IsCodeTarget(rmode_) || rmode_ == EMBEDDED_OBJECT); 195014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Assembler::set_target_address_at(isolate_, pc_, host_, 196014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch reinterpret_cast<Address>(target), 197014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch icache_flush_mode); 198958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (write_barrier_mode == UPDATE_WRITE_BARRIER && host() != NULL && 199958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier target->IsHeapObject()) { 200109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch host()->GetHeap()->incremental_marking()->RecordWriteIntoCode( 201109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch host(), this, HeapObject::cast(target)); 202f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch host()->GetHeap()->RecordWriteIntoCode(host(), this, target); 203958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 204958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 205958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 206958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 207014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochAddress RelocInfo::target_external_reference() { 208958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(rmode_ == EXTERNAL_REFERENCE); 209958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return Assembler::target_address_at(pc_, host_); 210958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 211958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 212958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 213958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily BernierAddress RelocInfo::target_runtime_entry(Assembler* origin) { 214958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(IsRuntimeEntry(rmode_)); 215958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return target_address(); 216958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 217958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 218958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 219958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid RelocInfo::set_target_runtime_entry(Address target, 220958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier WriteBarrierMode write_barrier_mode, 221958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier ICacheFlushMode icache_flush_mode) { 222958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(IsRuntimeEntry(rmode_)); 223958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (target_address() != target) 224958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier set_target_address(target, write_barrier_mode, icache_flush_mode); 225958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 226958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 227958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 228958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily BernierHandle<Cell> RelocInfo::target_cell_handle() { 229958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(rmode_ == RelocInfo::CELL); 230958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Address address = Memory::Address_at(pc_); 231958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return Handle<Cell>(reinterpret_cast<Cell**>(address)); 232958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 233958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 234958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 235958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily BernierCell* RelocInfo::target_cell() { 236958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(rmode_ == RelocInfo::CELL); 237958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return Cell::FromValueAddress(Memory::Address_at(pc_)); 238958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 239958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 240958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 241958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid RelocInfo::set_target_cell(Cell* cell, WriteBarrierMode write_barrier_mode, 242958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier ICacheFlushMode icache_flush_mode) { 243958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(rmode_ == RelocInfo::CELL); 244958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Address address = cell->address() + Cell::kValueOffset; 245958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Memory::Address_at(pc_) = address; 246958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (write_barrier_mode == UPDATE_WRITE_BARRIER && host() != NULL) { 247109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch host()->GetHeap()->incremental_marking()->RecordWriteIntoCode(host(), this, 248109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch cell); 249958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 250958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 251958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 252958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 253014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochstatic const int kNoCodeAgeInstructions = 254014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch FLAG_enable_embedded_constant_pool ? 7 : 6; 255958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierstatic const int kCodeAgingInstructions = 256958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Assembler::kMovInstructionsNoConstantPool + 3; 257958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierstatic const int kNoCodeAgeSequenceInstructions = 258958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier ((kNoCodeAgeInstructions >= kCodeAgingInstructions) 259958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier ? kNoCodeAgeInstructions 260958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier : kCodeAgingInstructions); 261958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierstatic const int kNoCodeAgeSequenceNops = 262958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier (kNoCodeAgeSequenceInstructions - kNoCodeAgeInstructions); 263958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierstatic const int kCodeAgingSequenceNops = 264958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier (kNoCodeAgeSequenceInstructions - kCodeAgingInstructions); 265958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierstatic const int kCodeAgingTargetDelta = 1 * Assembler::kInstrSize; 266958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierstatic const int kNoCodeAgeSequenceLength = 267958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier (kNoCodeAgeSequenceInstructions * Assembler::kInstrSize); 268958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 269958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 270958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily BernierHandle<Object> RelocInfo::code_age_stub_handle(Assembler* origin) { 271958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier UNREACHABLE(); // This should never be reached on PPC. 272958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return Handle<Object>(); 273958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 274958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 275958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 276958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily BernierCode* RelocInfo::code_age_stub() { 277958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(rmode_ == RelocInfo::CODE_AGE_SEQUENCE); 278958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return Code::GetCodeFromTargetAddress( 279958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Assembler::target_address_at(pc_ + kCodeAgingTargetDelta, host_)); 280958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 281958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 282958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 283958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid RelocInfo::set_code_age_stub(Code* stub, 284958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier ICacheFlushMode icache_flush_mode) { 285958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(rmode_ == RelocInfo::CODE_AGE_SEQUENCE); 286014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Assembler::set_target_address_at(isolate_, pc_ + kCodeAgingTargetDelta, host_, 287958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier stub->instruction_start(), 288958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier icache_flush_mode); 289958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 290958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 291958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 292014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochAddress RelocInfo::debug_call_address() { 293014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(IsDebugBreakSlot(rmode()) && IsPatchedDebugBreakSlotSequence()); 294958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return Assembler::target_address_at(pc_, host_); 295958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 296958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 297958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 298014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid RelocInfo::set_debug_call_address(Address target) { 299014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(IsDebugBreakSlot(rmode()) && IsPatchedDebugBreakSlotSequence()); 300014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Assembler::set_target_address_at(isolate_, pc_, host_, target); 301958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (host() != NULL) { 302958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Object* target_code = Code::GetCodeFromTargetAddress(target); 303958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier host()->GetHeap()->incremental_marking()->RecordWriteIntoCode( 304958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier host(), this, HeapObject::cast(target_code)); 305958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 306958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 307958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 308958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 309958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid RelocInfo::WipeOut() { 310958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(IsEmbeddedObject(rmode_) || IsCodeTarget(rmode_) || 311014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch IsRuntimeEntry(rmode_) || IsExternalReference(rmode_) || 312014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch IsInternalReference(rmode_) || IsInternalReferenceEncoded(rmode_)); 313014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (IsInternalReference(rmode_)) { 314014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Jump table entry 315014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Memory::Address_at(pc_) = NULL; 316014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else if (IsInternalReferenceEncoded(rmode_)) { 317014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // mov sequence 318014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Currently used only by deserializer, no need to flush. 319014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Assembler::set_target_address_at(isolate_, pc_, host_, NULL, 320014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch SKIP_ICACHE_FLUSH); 321014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 322014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Assembler::set_target_address_at(isolate_, pc_, host_, NULL); 323014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 324958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 325958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 326bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdochtemplate <typename ObjectVisitor> 327958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid RelocInfo::Visit(Isolate* isolate, ObjectVisitor* visitor) { 328958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier RelocInfo::Mode mode = rmode(); 329958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (mode == RelocInfo::EMBEDDED_OBJECT) { 330958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier visitor->VisitEmbeddedPointer(this); 331958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else if (RelocInfo::IsCodeTarget(mode)) { 332958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier visitor->VisitCodeTarget(this); 333958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else if (mode == RelocInfo::CELL) { 334958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier visitor->VisitCell(this); 335958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else if (mode == RelocInfo::EXTERNAL_REFERENCE) { 336958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier visitor->VisitExternalReference(this); 337014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else if (mode == RelocInfo::INTERNAL_REFERENCE || 338014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch mode == RelocInfo::INTERNAL_REFERENCE_ENCODED) { 339014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch visitor->VisitInternalReference(this); 340958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else if (RelocInfo::IsCodeAgeSequence(mode)) { 341958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier visitor->VisitCodeAgeSequence(this); 342014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else if (RelocInfo::IsDebugBreakSlot(mode) && 343014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch IsPatchedDebugBreakSlotSequence()) { 344958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier visitor->VisitDebugTarget(this); 345958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else if (IsRuntimeEntry(mode)) { 346958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier visitor->VisitRuntimeEntry(this); 347958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 348958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 349958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 350958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 351958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniertemplate <typename StaticVisitor> 352958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid RelocInfo::Visit(Heap* heap) { 353958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier RelocInfo::Mode mode = rmode(); 354958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (mode == RelocInfo::EMBEDDED_OBJECT) { 355958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier StaticVisitor::VisitEmbeddedPointer(heap, this); 356958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else if (RelocInfo::IsCodeTarget(mode)) { 357958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier StaticVisitor::VisitCodeTarget(heap, this); 358958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else if (mode == RelocInfo::CELL) { 359958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier StaticVisitor::VisitCell(heap, this); 360958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else if (mode == RelocInfo::EXTERNAL_REFERENCE) { 361958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier StaticVisitor::VisitExternalReference(this); 362014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else if (mode == RelocInfo::INTERNAL_REFERENCE || 363014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch mode == RelocInfo::INTERNAL_REFERENCE_ENCODED) { 364014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch StaticVisitor::VisitInternalReference(this); 365958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else if (RelocInfo::IsCodeAgeSequence(mode)) { 366958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier StaticVisitor::VisitCodeAgeSequence(heap, this); 367014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else if (RelocInfo::IsDebugBreakSlot(mode) && 368014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch IsPatchedDebugBreakSlotSequence()) { 369958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier StaticVisitor::VisitDebugTarget(heap, this); 370958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else if (IsRuntimeEntry(mode)) { 371958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier StaticVisitor::VisitRuntimeEntry(this); 372958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 373958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 374958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 375958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily BernierOperand::Operand(intptr_t immediate, RelocInfo::Mode rmode) { 376958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier rm_ = no_reg; 377958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier imm_ = immediate; 378958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier rmode_ = rmode; 379958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 380958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 381958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily BernierOperand::Operand(const ExternalReference& f) { 382958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier rm_ = no_reg; 383958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier imm_ = reinterpret_cast<intptr_t>(f.address()); 384958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier rmode_ = RelocInfo::EXTERNAL_REFERENCE; 385958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 386958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 387958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily BernierOperand::Operand(Smi* value) { 388958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier rm_ = no_reg; 389958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier imm_ = reinterpret_cast<intptr_t>(value); 390958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier rmode_ = kRelocInfo_NONEPTR; 391958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 392958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 393958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily BernierOperand::Operand(Register rm) { 394958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier rm_ = rm; 395958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier rmode_ = kRelocInfo_NONEPTR; // PPC -why doesn't ARM do this? 396958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 397958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 398958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid Assembler::CheckBuffer() { 399958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (buffer_space() <= kGap) { 400958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier GrowBuffer(); 401958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 402958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 403958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 404014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Assembler::TrackBranch() { 405014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(!trampoline_emitted_); 406014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int count = tracked_branch_count_++; 407014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (count == 0) { 408014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // We leave space (kMaxBlockTrampolineSectionSize) 409014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // for BlockTrampolinePoolScope buffer. 410014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch next_trampoline_check_ = 411014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch pc_offset() + kMaxCondBranchReach - kMaxBlockTrampolineSectionSize; 412014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 413014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch next_trampoline_check_ -= kTrampolineSlotsSize; 414014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 415014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 416014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 417014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Assembler::UntrackBranch() { 418014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(!trampoline_emitted_); 419014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(tracked_branch_count_ > 0); 420014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int count = --tracked_branch_count_; 421014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (count == 0) { 422014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Reset 423014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch next_trampoline_check_ = kMaxInt; 424014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 425014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch next_trampoline_check_ += kTrampolineSlotsSize; 426014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 427014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 428014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 429958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid Assembler::CheckTrampolinePoolQuick() { 430014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (pc_offset() >= next_trampoline_check_) { 431958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier CheckTrampolinePool(); 432958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 433958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 434958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 435958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid Assembler::emit(Instr x) { 436958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier CheckBuffer(); 437958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier *reinterpret_cast<Instr*>(pc_) = x; 438958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier pc_ += kInstrSize; 439958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier CheckTrampolinePoolQuick(); 440958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 441958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 442958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierbool Operand::is_reg() const { return rm_.is_valid(); } 443958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 444958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 445958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// Fetch the 32bit value from the FIXED_SEQUENCE lis/ori 446014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochAddress Assembler::target_address_at(Address pc, Address constant_pool) { 447014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (FLAG_enable_embedded_constant_pool && constant_pool) { 448014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ConstantPoolEntry::Access access; 449014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (IsConstantPoolLoadStart(pc, &access)) 450014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return Memory::Address_at(target_constant_pool_address_at( 451014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch pc, constant_pool, access, ConstantPoolEntry::INTPTR)); 452014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 453014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 454958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Instr instr1 = instr_at(pc); 455958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Instr instr2 = instr_at(pc + kInstrSize); 456958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Interpret 2 instructions generated by lis/ori 457958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (IsLis(instr1) && IsOri(instr2)) { 458958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#if V8_TARGET_ARCH_PPC64 459958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Instr instr4 = instr_at(pc + (3 * kInstrSize)); 460958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Instr instr5 = instr_at(pc + (4 * kInstrSize)); 461958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Assemble the 64 bit value. 462958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier uint64_t hi = (static_cast<uint32_t>((instr1 & kImm16Mask) << 16) | 463958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier static_cast<uint32_t>(instr2 & kImm16Mask)); 464958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier uint64_t lo = (static_cast<uint32_t>((instr4 & kImm16Mask) << 16) | 465958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier static_cast<uint32_t>(instr5 & kImm16Mask)); 466958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return reinterpret_cast<Address>((hi << 32) | lo); 467958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#else 468958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Assemble the 32 bit value. 469958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return reinterpret_cast<Address>(((instr1 & kImm16Mask) << 16) | 470958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier (instr2 & kImm16Mask)); 471958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#endif 472958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 473014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 474014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch UNREACHABLE(); 475014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return NULL; 476958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 477958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 478958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 479958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#if V8_TARGET_ARCH_PPC64 48062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochconst uint32_t kLoadIntptrOpcode = LD; 481014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#else 48262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochconst uint32_t kLoadIntptrOpcode = LWZ; 483958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#endif 484958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 485014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// Constant pool load sequence detection: 486014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// 1) REGULAR access: 487014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// load <dst>, kConstantPoolRegister + <offset> 488014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// 489014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// 2) OVERFLOWED access: 490014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// addis <scratch>, kConstantPoolRegister, <offset_high> 491014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// load <dst>, <scratch> + <offset_low> 492014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochbool Assembler::IsConstantPoolLoadStart(Address pc, 493014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ConstantPoolEntry::Access* access) { 494014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Instr instr = instr_at(pc); 49562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch uint32_t opcode = instr & kOpcodeMask; 496014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (!GetRA(instr).is(kConstantPoolRegister)) return false; 497014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bool overflowed = (opcode == ADDIS); 498014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#ifdef DEBUG 499014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (overflowed) { 500014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch opcode = instr_at(pc + kInstrSize) & kOpcodeMask; 501014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 502014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(opcode == kLoadIntptrOpcode || opcode == LFD); 503958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#endif 504014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (access) { 505014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch *access = (overflowed ? ConstantPoolEntry::OVERFLOWED 506014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch : ConstantPoolEntry::REGULAR); 507014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 508014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return true; 509958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 510958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 511958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 512014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochbool Assembler::IsConstantPoolLoadEnd(Address pc, 513014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ConstantPoolEntry::Access* access) { 514958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Instr instr = instr_at(pc); 51562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch uint32_t opcode = instr & kOpcodeMask; 516014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bool overflowed = false; 517014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (!(opcode == kLoadIntptrOpcode || opcode == LFD)) return false; 518014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (!GetRA(instr).is(kConstantPoolRegister)) { 519014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch instr = instr_at(pc - kInstrSize); 520014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch opcode = instr & kOpcodeMask; 521014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if ((opcode != ADDIS) || !GetRA(instr).is(kConstantPoolRegister)) { 522014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return false; 523014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 524014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch overflowed = true; 525014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 526014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (access) { 527014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch *access = (overflowed ? ConstantPoolEntry::OVERFLOWED 528014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch : ConstantPoolEntry::REGULAR); 529014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 530014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return true; 531014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 532014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 533014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 534014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochint Assembler::GetConstantPoolOffset(Address pc, 535014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ConstantPoolEntry::Access access, 536014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ConstantPoolEntry::Type type) { 537014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bool overflowed = (access == ConstantPoolEntry::OVERFLOWED); 538014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#ifdef DEBUG 539014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ConstantPoolEntry::Access access_check = 540014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static_cast<ConstantPoolEntry::Access>(-1); 541014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(IsConstantPoolLoadStart(pc, &access_check)); 542014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(access_check == access); 543014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#endif 544014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int offset; 545014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (overflowed) { 546014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch offset = (instr_at(pc) & kImm16Mask) << 16; 547014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch offset += SIGN_EXT_IMM16(instr_at(pc + kInstrSize) & kImm16Mask); 548014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(!is_int16(offset)); 549014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 550014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch offset = SIGN_EXT_IMM16((instr_at(pc) & kImm16Mask)); 551014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 552958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return offset; 553958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 554958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 555958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 556014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Assembler::PatchConstantPoolAccessInstruction( 557014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int pc_offset, int offset, ConstantPoolEntry::Access access, 558014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ConstantPoolEntry::Type type) { 559014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Address pc = buffer_ + pc_offset; 560014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bool overflowed = (access == ConstantPoolEntry::OVERFLOWED); 561014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CHECK(overflowed != is_int16(offset)); 562014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#ifdef DEBUG 563014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ConstantPoolEntry::Access access_check = 564014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static_cast<ConstantPoolEntry::Access>(-1); 565014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(IsConstantPoolLoadStart(pc, &access_check)); 566014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(access_check == access); 567014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#endif 568014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (overflowed) { 569014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int hi_word = static_cast<int>(offset >> 16); 570014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int lo_word = static_cast<int>(offset & 0xffff); 571014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (lo_word & 0x8000) hi_word++; 572014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 573014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Instr instr1 = instr_at(pc); 574014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Instr instr2 = instr_at(pc + kInstrSize); 575014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch instr1 &= ~kImm16Mask; 576014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch instr1 |= (hi_word & kImm16Mask); 577014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch instr2 &= ~kImm16Mask; 578014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch instr2 |= (lo_word & kImm16Mask); 579014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch instr_at_put(pc, instr1); 580014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch instr_at_put(pc + kInstrSize, instr2); 581014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 582014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Instr instr = instr_at(pc); 583014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch instr &= ~kImm16Mask; 584014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch instr |= (offset & kImm16Mask); 585014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch instr_at_put(pc, instr); 586014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 587958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 588958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 589958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 590958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily BernierAddress Assembler::target_constant_pool_address_at( 591014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Address pc, Address constant_pool, ConstantPoolEntry::Access access, 592014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ConstantPoolEntry::Type type) { 593014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Address addr = constant_pool; 594958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(addr); 595014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch addr += GetConstantPoolOffset(pc, access, type); 596958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return addr; 597958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 598958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 599958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 600958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// This sets the branch destination (which gets loaded at the call address). 601958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// This is for calls and branches within generated code. The serializer 602958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// has already deserialized the mov instructions etc. 603958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// There is a FIXED_SEQUENCE assumption here 604958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid Assembler::deserialization_set_special_target_at( 605014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Isolate* isolate, Address instruction_payload, Code* code, Address target) { 606014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch set_target_address_at(isolate, instruction_payload, code, target); 607014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 608014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 609014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 610014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Assembler::deserialization_set_target_internal_reference_at( 611014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Isolate* isolate, Address pc, Address target, RelocInfo::Mode mode) { 612014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (RelocInfo::IsInternalReferenceEncoded(mode)) { 613014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Code* code = NULL; 614014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch set_target_address_at(isolate, pc, code, target, SKIP_ICACHE_FLUSH); 615014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 616014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Memory::Address_at(pc) = target; 617014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 618958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 619958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 620014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 621958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// This code assumes the FIXED_SEQUENCE of lis/ori 622014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Assembler::set_target_address_at(Isolate* isolate, Address pc, 623014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Address constant_pool, Address target, 624958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier ICacheFlushMode icache_flush_mode) { 625014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (FLAG_enable_embedded_constant_pool && constant_pool) { 626014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ConstantPoolEntry::Access access; 627014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (IsConstantPoolLoadStart(pc, &access)) { 628014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Memory::Address_at(target_constant_pool_address_at( 629014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch pc, constant_pool, access, ConstantPoolEntry::INTPTR)) = target; 630014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return; 631014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 632014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 633014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 634958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Instr instr1 = instr_at(pc); 635958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Instr instr2 = instr_at(pc + kInstrSize); 636958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Interpret 2 instructions generated by lis/ori 637958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (IsLis(instr1) && IsOri(instr2)) { 638958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#if V8_TARGET_ARCH_PPC64 639958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Instr instr4 = instr_at(pc + (3 * kInstrSize)); 640958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Instr instr5 = instr_at(pc + (4 * kInstrSize)); 641958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Needs to be fixed up when mov changes to handle 64-bit values. 642958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier uint32_t* p = reinterpret_cast<uint32_t*>(pc); 643958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier uintptr_t itarget = reinterpret_cast<uintptr_t>(target); 644958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 645958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier instr5 &= ~kImm16Mask; 646958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier instr5 |= itarget & kImm16Mask; 647958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier itarget = itarget >> 16; 648958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 649958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier instr4 &= ~kImm16Mask; 650958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier instr4 |= itarget & kImm16Mask; 651958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier itarget = itarget >> 16; 652958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 653958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier instr2 &= ~kImm16Mask; 654958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier instr2 |= itarget & kImm16Mask; 655958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier itarget = itarget >> 16; 656958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 657958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier instr1 &= ~kImm16Mask; 658958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier instr1 |= itarget & kImm16Mask; 659958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier itarget = itarget >> 16; 660958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 661958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier *p = instr1; 662958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier *(p + 1) = instr2; 663958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier *(p + 3) = instr4; 664958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier *(p + 4) = instr5; 665958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (icache_flush_mode != SKIP_ICACHE_FLUSH) { 666014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Assembler::FlushICache(isolate, p, 5 * kInstrSize); 667958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 668958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#else 669958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier uint32_t* p = reinterpret_cast<uint32_t*>(pc); 670958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier uint32_t itarget = reinterpret_cast<uint32_t>(target); 671958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int lo_word = itarget & kImm16Mask; 672958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int hi_word = itarget >> 16; 673958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier instr1 &= ~kImm16Mask; 674958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier instr1 |= hi_word; 675958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier instr2 &= ~kImm16Mask; 676958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier instr2 |= lo_word; 677958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 678958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier *p = instr1; 679958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier *(p + 1) = instr2; 680958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (icache_flush_mode != SKIP_ICACHE_FLUSH) { 681014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Assembler::FlushICache(isolate, p, 2 * kInstrSize); 682958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 683958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#endif 684014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return; 685958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 686014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch UNREACHABLE(); 687958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 688014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} // namespace internal 689014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} // namespace v8 690958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 691958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#endif // V8_PPC_ASSEMBLER_PPC_INL_H_ 692