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