1a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Copyright (c) 1994-2006 Sun Microsystems Inc.
2a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// All Rights Reserved.
3a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//
4a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Redistribution and use in source and binary forms, with or without
5a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// modification, are permitted provided that the following conditions
6a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// are met:
7a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//
8a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// - Redistributions of source code must retain the above copyright notice,
9a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// this list of conditions and the following disclaimer.
10a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//
11a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// - Redistribution in binary form must reproduce the above copyright
12a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// notice, this list of conditions and the following disclaimer in the
13a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// documentation and/or other materials provided with the
14a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// distribution.
15a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//
16a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// - Neither the name of Sun Microsystems or the names of contributors may
17a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// be used to endorse or promote products derived from this software without
18a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// specific prior written permission.
19a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//
20a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
23a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
24a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
25a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
26a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
27a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
29a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
31a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// OF THE POSSIBILITY OF SUCH DAMAGE.
32a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
33a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// The original source code covered by the above license above has been modified
34a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// significantly by Google Inc.
35692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch// Copyright 2012 the V8 project authors. All rights reserved.
36a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
37a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifndef V8_ARM_ASSEMBLER_ARM_INL_H_
38a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define V8_ARM_ASSEMBLER_ARM_INL_H_
39a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
40b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/arm/assembler-arm.h"
413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
42b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/assembler.h"
43014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/debug/debug.h"
4462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch#include "src/objects-inl.h"
45a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
46a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocknamespace v8 {
47a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocknamespace internal {
48a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
49f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochbool CpuFeatures::SupportsCrankshaft() { return true; }
50b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochbool CpuFeatures::SupportsSimd128() { return true; }
52b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
53014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochint DoubleRegister::NumRegisters() {
54b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return CpuFeatures::IsSupported(VFP32DREGS) ? 32 : 16;
55b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
56b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
57b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
58014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid RelocInfo::apply(intptr_t delta) {
59a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (RelocInfo::IsInternalReference(rmode_)) {
60a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // absolute code pointer inside code object moves with the code object.
61a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    int32_t* p = reinterpret_cast<int32_t*>(pc_);
62a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    *p += delta;  // relocate entry
63a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
64a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // We do not use pc relative addressing on ARM, so there is
65a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // nothing else to do.
66a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
67a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
68a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
69a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockAddress RelocInfo::target_address() {
70b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(IsCodeTarget(rmode_) || IsRuntimeEntry(rmode_));
71b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return Assembler::target_address_at(pc_, host_);
72a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
73a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
74a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockAddress RelocInfo::target_address_address() {
75b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(IsCodeTarget(rmode_) || IsRuntimeEntry(rmode_)
763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                              || rmode_ == EMBEDDED_OBJECT
773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                              || rmode_ == EXTERNAL_REFERENCE);
78014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (FLAG_enable_embedded_constant_pool ||
79b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      Assembler::IsMovW(Memory::int32_at(pc_))) {
80014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // We return the PC for embedded constant pool since this function is used
81014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // by the serializer and expects the address to reside within the code
82014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // object.
83b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return reinterpret_cast<Address>(pc_);
84b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {
85b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(Assembler::IsLdrPcImmediateOffset(Memory::int32_at(pc_)));
86b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return constant_pool_entry_address();
87b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
88b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
89b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
90b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
91b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochAddress RelocInfo::constant_pool_entry_address() {
92b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(IsInConstantPool());
93b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return Assembler::constant_pool_entry_address(pc_, host_->constant_pool());
94a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
95a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
96a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
97f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarkeint RelocInfo::target_address_size() {
983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  return kPointerSize;
99f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke}
100f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke
101f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke
102a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockObject* RelocInfo::target_object() {
103b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(IsCodeTarget(rmode_) || rmode_ == EMBEDDED_OBJECT);
104b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return reinterpret_cast<Object*>(Assembler::target_address_at(pc_, host_));
1053ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block}
1063ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block
1073ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block
108d0582a6c46733687d045e4188a1bcd0123c758a1Steve BlockHandle<Object> RelocInfo::target_object_handle(Assembler* origin) {
109b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(IsCodeTarget(rmode_) || rmode_ == EMBEDDED_OBJECT);
110b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return Handle<Object>(reinterpret_cast<Object**>(
111b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      Assembler::target_address_at(pc_, host_)));
112a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
113a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
114a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
115b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid RelocInfo::set_target_object(Object* target,
116b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                  WriteBarrierMode write_barrier_mode,
117b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                  ICacheFlushMode icache_flush_mode) {
118b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(IsCodeTarget(rmode_) || rmode_ == EMBEDDED_OBJECT);
119014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Assembler::set_target_address_at(isolate_, pc_, host_,
120b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                   reinterpret_cast<Address>(target),
121b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                   icache_flush_mode);
122b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (write_barrier_mode == UPDATE_WRITE_BARRIER &&
1233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      host() != NULL &&
1243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      target->IsHeapObject()) {
125109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    host()->GetHeap()->incremental_marking()->RecordWriteIntoCode(
126109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        host(), this, HeapObject::cast(target));
127f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    host()->GetHeap()->RecordWriteIntoCode(host(), this, target);
1283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
129a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
130a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
131a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
132014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochAddress RelocInfo::target_external_reference() {
133b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(rmode_ == EXTERNAL_REFERENCE);
134b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return Assembler::target_address_at(pc_, host_);
135a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
136a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
137a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
138014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochAddress RelocInfo::target_internal_reference() {
139014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(rmode_ == INTERNAL_REFERENCE);
140014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return Memory::Address_at(pc_);
141014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
142014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
143014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
144014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochAddress RelocInfo::target_internal_reference_address() {
145014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(rmode_ == INTERNAL_REFERENCE);
146014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return reinterpret_cast<Address>(pc_);
147014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
148014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
149014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
150b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochAddress RelocInfo::target_runtime_entry(Assembler* origin) {
151b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(IsRuntimeEntry(rmode_));
152b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return target_address();
153b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
154b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
155b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
156b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid RelocInfo::set_target_runtime_entry(Address target,
157b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                         WriteBarrierMode write_barrier_mode,
158b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                         ICacheFlushMode icache_flush_mode) {
159b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(IsRuntimeEntry(rmode_));
160b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (target_address() != target)
161b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    set_target_address(target, write_barrier_mode, icache_flush_mode);
162b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}
163b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
164b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
165b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHandle<Cell> RelocInfo::target_cell_handle() {
166b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(rmode_ == RelocInfo::CELL);
167b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  Address address = Memory::Address_at(pc_);
168b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return Handle<Cell>(reinterpret_cast<Cell**>(address));
169b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}
170b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
171b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
172b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochCell* RelocInfo::target_cell() {
173b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(rmode_ == RelocInfo::CELL);
174b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return Cell::FromValueAddress(Memory::Address_at(pc_));
175b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
176b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
177b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
178b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid RelocInfo::set_target_cell(Cell* cell,
179b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                WriteBarrierMode write_barrier_mode,
180b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                ICacheFlushMode icache_flush_mode) {
181b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(rmode_ == RelocInfo::CELL);
182b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Address address = cell->address() + Cell::kValueOffset;
183b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  Memory::Address_at(pc_) = address;
184b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (write_barrier_mode == UPDATE_WRITE_BARRIER && host() != NULL) {
185109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    host()->GetHeap()->incremental_marking()->RecordWriteIntoCode(host(), this,
186109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch                                                                  cell);
1873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
188b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}
189b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
190b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
191b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic const int kNoCodeAgeSequenceLength = 3 * Assembler::kInstrSize;
192b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
193b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
194b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHandle<Object> RelocInfo::code_age_stub_handle(Assembler* origin) {
195b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  UNREACHABLE();  // This should never be reached on Arm.
196b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return Handle<Object>();
197b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
198b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
199b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
200b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochCode* RelocInfo::code_age_stub() {
201b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(rmode_ == RelocInfo::CODE_AGE_SEQUENCE);
202b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return Code::GetCodeFromTargetAddress(
203b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      Memory::Address_at(pc_ +
204b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                         (kNoCodeAgeSequenceLength - Assembler::kInstrSize)));
205b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
206b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
207b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
208b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid RelocInfo::set_code_age_stub(Code* stub,
209b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                  ICacheFlushMode icache_flush_mode) {
210b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(rmode_ == RelocInfo::CODE_AGE_SEQUENCE);
211b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Memory::Address_at(pc_ +
212b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                     (kNoCodeAgeSequenceLength - Assembler::kInstrSize)) =
213b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      stub->instruction_start();
214b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
215b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
216b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
217014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochAddress RelocInfo::debug_call_address() {
2187f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  // The 2 instructions offset assumes patched debug break slot or return
2197f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  // sequence.
220014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(IsDebugBreakSlot(rmode()) && IsPatchedDebugBreakSlotSequence());
221014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return Memory::Address_at(pc_ + Assembler::kPatchDebugBreakSlotAddressOffset);
222a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
223a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
224a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
225014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid RelocInfo::set_debug_call_address(Address target) {
226014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(IsDebugBreakSlot(rmode()) && IsPatchedDebugBreakSlotSequence());
227014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Memory::Address_at(pc_ + Assembler::kPatchDebugBreakSlotAddressOffset) =
228014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      target;
2293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (host() != NULL) {
2303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    Object* target_code = Code::GetCodeFromTargetAddress(target);
2313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    host()->GetHeap()->incremental_marking()->RecordWriteIntoCode(
2323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        host(), this, HeapObject::cast(target_code));
2333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
234a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
235a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
236a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
237b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid RelocInfo::WipeOut() {
238014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(IsEmbeddedObject(rmode_) || IsCodeTarget(rmode_) ||
239014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch         IsRuntimeEntry(rmode_) || IsExternalReference(rmode_) ||
240014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch         IsInternalReference(rmode_));
241014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (IsInternalReference(rmode_)) {
242014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Memory::Address_at(pc_) = NULL;
243014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else {
244014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Assembler::set_target_address_at(isolate_, pc_, host_, NULL);
245014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
246b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
247b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
248bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdochtemplate <typename ObjectVisitor>
249b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid RelocInfo::Visit(Isolate* isolate, ObjectVisitor* visitor) {
250f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  RelocInfo::Mode mode = rmode();
251f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  if (mode == RelocInfo::EMBEDDED_OBJECT) {
2523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    visitor->VisitEmbeddedPointer(this);
253f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  } else if (RelocInfo::IsCodeTarget(mode)) {
254f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke    visitor->VisitCodeTarget(this);
255b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else if (mode == RelocInfo::CELL) {
256b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    visitor->VisitCell(this);
257f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  } else if (mode == RelocInfo::EXTERNAL_REFERENCE) {
2583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    visitor->VisitExternalReference(this);
259014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else if (mode == RelocInfo::INTERNAL_REFERENCE) {
260014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    visitor->VisitInternalReference(this);
261b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else if (RelocInfo::IsCodeAgeSequence(mode)) {
262b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    visitor->VisitCodeAgeSequence(this);
263014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else if (RelocInfo::IsDebugBreakSlot(mode) &&
264014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch             IsPatchedDebugBreakSlotSequence()) {
265f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke    visitor->VisitDebugTarget(this);
266b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else if (RelocInfo::IsRuntimeEntry(mode)) {
267f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke    visitor->VisitRuntimeEntry(this);
268f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  }
269a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
270a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
271a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
272756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merricktemplate<typename StaticVisitor>
27344f0eee88ff00398ff7f715fab053374d808c90dSteve Blockvoid RelocInfo::Visit(Heap* heap) {
274756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick  RelocInfo::Mode mode = rmode();
275756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick  if (mode == RelocInfo::EMBEDDED_OBJECT) {
2763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    StaticVisitor::VisitEmbeddedPointer(heap, this);
277756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick  } else if (RelocInfo::IsCodeTarget(mode)) {
2788b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    StaticVisitor::VisitCodeTarget(heap, this);
279b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else if (mode == RelocInfo::CELL) {
280b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    StaticVisitor::VisitCell(heap, this);
281756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick  } else if (mode == RelocInfo::EXTERNAL_REFERENCE) {
2823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    StaticVisitor::VisitExternalReference(this);
283014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else if (mode == RelocInfo::INTERNAL_REFERENCE) {
284014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    StaticVisitor::VisitInternalReference(this);
285b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else if (RelocInfo::IsCodeAgeSequence(mode)) {
286b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    StaticVisitor::VisitCodeAgeSequence(heap, this);
287014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else if (RelocInfo::IsDebugBreakSlot(mode) &&
288014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch             IsPatchedDebugBreakSlotSequence()) {
2898b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    StaticVisitor::VisitDebugTarget(heap, this);
290b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else if (RelocInfo::IsRuntimeEntry(mode)) {
291756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick    StaticVisitor::VisitRuntimeEntry(this);
292756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick  }
293756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick}
294756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick
295756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick
296f7060e27768c550ace7ec48ad8c093466db52dfaLeon ClarkeOperand::Operand(int32_t immediate, RelocInfo::Mode rmode)  {
297a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  rm_ = no_reg;
298f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  imm32_ = immediate;
299f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  rmode_ = rmode;
300a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
301a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
302a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
303a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockOperand::Operand(const ExternalReference& f)  {
304a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  rm_ = no_reg;
305a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  imm32_ = reinterpret_cast<int32_t>(f.address());
306a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  rmode_ = RelocInfo::EXTERNAL_REFERENCE;
307a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
308a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
309a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
310a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockOperand::Operand(Smi* value) {
311a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  rm_ = no_reg;
312a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  imm32_ =  reinterpret_cast<intptr_t>(value);
313b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  rmode_ = RelocInfo::NONE32;
314a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
315a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
316a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
317a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockOperand::Operand(Register rm) {
318a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  rm_ = rm;
319a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  rs_ = no_reg;
320a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  shift_op_ = LSL;
321a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  shift_imm_ = 0;
322a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
323a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
324a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
325a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockbool Operand::is_reg() const {
326a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return rm_.is_valid() &&
327a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block         rs_.is(no_reg) &&
328a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block         shift_op_ == LSL &&
329a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block         shift_imm_ == 0;
330a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
331a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
332a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
333a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::CheckBuffer() {
334a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (buffer_space() <= kGap) {
335a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    GrowBuffer();
336a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
337014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  MaybeCheckConstPool();
338a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
339a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
340a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
341a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::emit(Instr x) {
342a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  CheckBuffer();
343a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  *reinterpret_cast<Instr*>(pc_) = x;
344a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  pc_ += kInstrSize;
345a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
346a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
347a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
348b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochAddress Assembler::target_address_from_return_address(Address pc) {
349b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Returns the address of the call target from the return address that will
350b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // be returned to after a call.
351b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Call sequence on V7 or later is:
352b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  //  movw  ip, #... @ call address low 16
353b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  //  movt  ip, #... @ call address high 16
354b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  //  blx   ip
355b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  //                      @ return address
356b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // For V6 when the constant pool is unavailable, it is:
357b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  //  mov  ip, #...     @ call address low 8
358b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  //  orr  ip, ip, #... @ call address 2nd 8
359b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  //  orr  ip, ip, #... @ call address 3rd 8
360b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  //  orr  ip, ip, #... @ call address high 8
361b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  //  blx   ip
362b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  //                      @ return address
363b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // In cases that need frequent patching, the address is in the
364b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // constant pool.  It could be a small constant pool load:
365b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  //  ldr   ip, [pc / pp, #...] @ call address
366b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  //  blx   ip
367b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  //                      @ return address
368b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Or an extended constant pool load (ARMv7):
369b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  //  movw  ip, #...
370b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  //  movt  ip, #...
371b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  //  ldr   ip, [pc, ip]  @ call address
372b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  //  blx   ip
373b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  //                      @ return address
374b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Or an extended constant pool load (ARMv6):
375b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  //  mov  ip, #...
376b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  //  orr  ip, ip, #...
377b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  //  orr  ip, ip, #...
378b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  //  orr  ip, ip, #...
379b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  //  ldr   ip, [pc, ip]  @ call address
380b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  //  blx   ip
381b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  //                      @ return address
382b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Address candidate = pc - 2 * Assembler::kInstrSize;
383b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Instr candidate_instr(Memory::int32_at(candidate));
384b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (IsLdrPcImmediateOffset(candidate_instr) |
385b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      IsLdrPpImmediateOffset(candidate_instr)) {
386b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return candidate;
387b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {
388b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (IsLdrPpRegOffset(candidate_instr)) {
389b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      candidate -= Assembler::kInstrSize;
390b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
391b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (CpuFeatures::IsSupported(ARMv7)) {
392b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      candidate -= 1 * Assembler::kInstrSize;
393b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      DCHECK(IsMovW(Memory::int32_at(candidate)) &&
394b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch             IsMovT(Memory::int32_at(candidate + Assembler::kInstrSize)));
395b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    } else {
396b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      candidate -= 3 * Assembler::kInstrSize;
397b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      DCHECK(
398b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          IsMovImmed(Memory::int32_at(candidate)) &&
399b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          IsOrrImmed(Memory::int32_at(candidate + Assembler::kInstrSize)) &&
400b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          IsOrrImmed(Memory::int32_at(candidate + 2 * Assembler::kInstrSize)) &&
401b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          IsOrrImmed(Memory::int32_at(candidate + 3 * Assembler::kInstrSize)));
402b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
403b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return candidate;
404e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  }
405b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
4066ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
407b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
408b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochAddress Assembler::return_address_from_call_start(Address pc) {
409b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (IsLdrPcImmediateOffset(Memory::int32_at(pc)) |
410b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      IsLdrPpImmediateOffset(Memory::int32_at(pc))) {
411b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Load from constant pool, small section.
412b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return pc + kInstrSize * 2;
413b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {
414b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (CpuFeatures::IsSupported(ARMv7)) {
415b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      DCHECK(IsMovW(Memory::int32_at(pc)));
416b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      DCHECK(IsMovT(Memory::int32_at(pc + kInstrSize)));
417b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if (IsLdrPpRegOffset(Memory::int32_at(pc + 2 * kInstrSize))) {
418b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        // Load from constant pool, extended section.
419b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        return pc + kInstrSize * 4;
420b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      } else {
421b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        // A movw / movt load immediate.
422b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        return pc + kInstrSize * 3;
423b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
424b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    } else {
425b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      DCHECK(IsMovImmed(Memory::int32_at(pc)));
426b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      DCHECK(IsOrrImmed(Memory::int32_at(pc + kInstrSize)));
427b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      DCHECK(IsOrrImmed(Memory::int32_at(pc + 2 * kInstrSize)));
428b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      DCHECK(IsOrrImmed(Memory::int32_at(pc + 3 * kInstrSize)));
429b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if (IsLdrPpRegOffset(Memory::int32_at(pc + 4 * kInstrSize))) {
430b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        // Load from constant pool, extended section.
431b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        return pc + kInstrSize * 6;
432b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      } else {
433b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        // A mov / orr load immediate.
434b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        return pc + kInstrSize * 5;
435b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
436b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
4376ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  }
438b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
4396ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
440b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
441b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::deserialization_set_special_target_at(
442014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Isolate* isolate, Address constant_pool_entry, Code* code, Address target) {
443014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (FLAG_enable_embedded_constant_pool) {
444014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    set_target_address_at(isolate, constant_pool_entry, code, target);
445b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {
446b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Memory::Address_at(constant_pool_entry) = target;
447b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
448a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
449a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
450a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
451014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Assembler::deserialization_set_target_internal_reference_at(
452014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Isolate* isolate, Address pc, Address target, RelocInfo::Mode mode) {
453014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Memory::Address_at(pc) = target;
454014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
455014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
456014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
457b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool Assembler::is_constant_pool_load(Address pc) {
458b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (CpuFeatures::IsSupported(ARMv7)) {
459b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return !Assembler::IsMovW(Memory::int32_at(pc)) ||
460014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch           (FLAG_enable_embedded_constant_pool &&
461b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch            Assembler::IsLdrPpRegOffset(
462b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                Memory::int32_at(pc + 2 * Assembler::kInstrSize)));
463b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {
464b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return !Assembler::IsMovImmed(Memory::int32_at(pc)) ||
465014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch           (FLAG_enable_embedded_constant_pool &&
466b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch            Assembler::IsLdrPpRegOffset(
467b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                Memory::int32_at(pc + 4 * Assembler::kInstrSize)));
468b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
469a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
470a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
471a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
472014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochAddress Assembler::constant_pool_entry_address(Address pc,
473014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                               Address constant_pool) {
474014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (FLAG_enable_embedded_constant_pool) {
475b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(constant_pool != NULL);
476b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    int cp_offset;
477b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (!CpuFeatures::IsSupported(ARMv7) && IsMovImmed(Memory::int32_at(pc))) {
478b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      DCHECK(IsOrrImmed(Memory::int32_at(pc + kInstrSize)) &&
479b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch             IsOrrImmed(Memory::int32_at(pc + 2 * kInstrSize)) &&
480b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch             IsOrrImmed(Memory::int32_at(pc + 3 * kInstrSize)) &&
481b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch             IsLdrPpRegOffset(Memory::int32_at(pc + 4 * kInstrSize)));
482b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      // This is an extended constant pool lookup (ARMv6).
483b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      Instr mov_instr = instr_at(pc);
484b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      Instr orr_instr_1 = instr_at(pc + kInstrSize);
485b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      Instr orr_instr_2 = instr_at(pc + 2 * kInstrSize);
486b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      Instr orr_instr_3 = instr_at(pc + 3 * kInstrSize);
487b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      cp_offset = DecodeShiftImm(mov_instr) | DecodeShiftImm(orr_instr_1) |
488b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                  DecodeShiftImm(orr_instr_2) | DecodeShiftImm(orr_instr_3);
489b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    } else if (IsMovW(Memory::int32_at(pc))) {
490b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      DCHECK(IsMovT(Memory::int32_at(pc + kInstrSize)) &&
491b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch             IsLdrPpRegOffset(Memory::int32_at(pc + 2 * kInstrSize)));
492b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      // This is an extended constant pool lookup (ARMv7).
493b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      Instruction* movw_instr = Instruction::At(pc);
494b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      Instruction* movt_instr = Instruction::At(pc + kInstrSize);
495b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      cp_offset = (movt_instr->ImmedMovwMovtValue() << 16) |
496b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                  movw_instr->ImmedMovwMovtValue();
497b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    } else {
498b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      // This is a small constant pool lookup.
499b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      DCHECK(Assembler::IsLdrPpImmediateOffset(Memory::int32_at(pc)));
500b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      cp_offset = GetLdrRegisterImmediateOffset(Memory::int32_at(pc));
501b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
502014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return constant_pool + cp_offset;
503b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {
504b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(Assembler::IsLdrPcImmediateOffset(Memory::int32_at(pc)));
505b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Instr instr = Memory::int32_at(pc);
506b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return pc + GetLdrRegisterImmediateOffset(instr) + kPcLoadDelta;
507b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
5083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
5093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
5103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
511014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochAddress Assembler::target_address_at(Address pc, Address constant_pool) {
512b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (is_constant_pool_load(pc)) {
513b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // This is a constant pool lookup. Return the value in the constant pool.
514b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return Memory::Address_at(constant_pool_entry_address(pc, constant_pool));
515b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else if (CpuFeatures::IsSupported(ARMv7)) {
516b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // This is an movw / movt immediate load. Return the immediate.
517b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(IsMovW(Memory::int32_at(pc)) &&
518b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch           IsMovT(Memory::int32_at(pc + kInstrSize)));
519b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Instruction* movw_instr = Instruction::At(pc);
520b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Instruction* movt_instr = Instruction::At(pc + kInstrSize);
521b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return reinterpret_cast<Address>(
522b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        (movt_instr->ImmedMovwMovtValue() << 16) |
523b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch         movw_instr->ImmedMovwMovtValue());
524b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {
525b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // This is an mov / orr immediate load. Return the immediate.
526b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(IsMovImmed(Memory::int32_at(pc)) &&
527b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch           IsOrrImmed(Memory::int32_at(pc + kInstrSize)) &&
528b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch           IsOrrImmed(Memory::int32_at(pc + 2 * kInstrSize)) &&
529b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch           IsOrrImmed(Memory::int32_at(pc + 3 * kInstrSize)));
530b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Instr mov_instr = instr_at(pc);
531b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Instr orr_instr_1 = instr_at(pc + kInstrSize);
532b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Instr orr_instr_2 = instr_at(pc + 2 * kInstrSize);
533b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Instr orr_instr_3 = instr_at(pc + 3 * kInstrSize);
534b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Address ret = reinterpret_cast<Address>(
535b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        DecodeShiftImm(mov_instr) | DecodeShiftImm(orr_instr_1) |
536b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        DecodeShiftImm(orr_instr_2) | DecodeShiftImm(orr_instr_3));
537b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return ret;
538b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
539d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block}
540d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
541d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
542014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Assembler::set_target_address_at(Isolate* isolate, Address pc,
543014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                      Address constant_pool, Address target,
544b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                      ICacheFlushMode icache_flush_mode) {
545b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (is_constant_pool_load(pc)) {
546b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // This is a constant pool lookup. Update the entry in the constant pool.
547b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Memory::Address_at(constant_pool_entry_address(pc, constant_pool)) = target;
548b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Intuitively, we would think it is necessary to always flush the
549b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // instruction cache after patching a target address in the code as follows:
550014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    //   Assembler::FlushICache(isolate, pc, sizeof(target));
551b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // However, on ARM, no instruction is actually patched in the case
552b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // of embedded constants of the form:
553b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // ldr   ip, [pp, #...]
554b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // since the instruction accessing this address in the constant pool remains
555b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // unchanged.
556b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else if (CpuFeatures::IsSupported(ARMv7)) {
557b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // This is an movw / movt immediate load. Patch the immediate embedded in
558b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // the instructions.
559b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(IsMovW(Memory::int32_at(pc)));
560b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(IsMovT(Memory::int32_at(pc + kInstrSize)));
561b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    uint32_t* instr_ptr = reinterpret_cast<uint32_t*>(pc);
562b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    uint32_t immediate = reinterpret_cast<uint32_t>(target);
563b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    instr_ptr[0] = PatchMovwImmediate(instr_ptr[0], immediate & 0xFFFF);
564b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    instr_ptr[1] = PatchMovwImmediate(instr_ptr[1], immediate >> 16);
565b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(IsMovW(Memory::int32_at(pc)));
566b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(IsMovT(Memory::int32_at(pc + kInstrSize)));
567b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (icache_flush_mode != SKIP_ICACHE_FLUSH) {
568014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Assembler::FlushICache(isolate, pc, 2 * kInstrSize);
569b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
570b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {
571b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // This is an mov / orr immediate load. Patch the immediate embedded in
572b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // the instructions.
573b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(IsMovImmed(Memory::int32_at(pc)) &&
574b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch           IsOrrImmed(Memory::int32_at(pc + kInstrSize)) &&
575b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch           IsOrrImmed(Memory::int32_at(pc + 2 * kInstrSize)) &&
576b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch           IsOrrImmed(Memory::int32_at(pc + 3 * kInstrSize)));
577b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    uint32_t* instr_ptr = reinterpret_cast<uint32_t*>(pc);
578b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    uint32_t immediate = reinterpret_cast<uint32_t>(target);
579b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    instr_ptr[0] = PatchShiftImm(instr_ptr[0], immediate & kImm8Mask);
580b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    instr_ptr[1] = PatchShiftImm(instr_ptr[1], immediate & (kImm8Mask << 8));
581b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    instr_ptr[2] = PatchShiftImm(instr_ptr[2], immediate & (kImm8Mask << 16));
582b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    instr_ptr[3] = PatchShiftImm(instr_ptr[3], immediate & (kImm8Mask << 24));
583b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(IsMovImmed(Memory::int32_at(pc)) &&
584b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch           IsOrrImmed(Memory::int32_at(pc + kInstrSize)) &&
585b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch           IsOrrImmed(Memory::int32_at(pc + 2 * kInstrSize)) &&
586b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch           IsOrrImmed(Memory::int32_at(pc + 3 * kInstrSize)));
587b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (icache_flush_mode != SKIP_ICACHE_FLUSH) {
588014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Assembler::FlushICache(isolate, pc, 4 * kInstrSize);
589b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
590b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
591a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
592a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
59362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen MurdochAddress Assembler::target_address_at(Address pc, Code* code) {
59462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Address constant_pool = code ? code->constant_pool() : NULL;
59562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  return target_address_at(pc, constant_pool);
59662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch}
59762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
59862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochvoid Assembler::set_target_address_at(Isolate* isolate, Address pc, Code* code,
59962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                      Address target,
60062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                      ICacheFlushMode icache_flush_mode) {
60162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Address constant_pool = code ? code->constant_pool() : NULL;
60262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  set_target_address_at(isolate, pc, constant_pool, target, icache_flush_mode);
60362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch}
604b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
605014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}  // namespace internal
606014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}  // namespace v8
607a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
608a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif  // V8_ARM_ASSEMBLER_ARM_INL_H_
609