1b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Copyright (c) 1994-2006 Sun Microsystems Inc.
2b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// All Rights Reserved.
3b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch//
4b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Redistribution and use in source and binary forms, with or without
5b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// modification, are permitted provided that the following conditions are
6b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// met:
7b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch//
8b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// - Redistributions of source code must retain the above copyright notice,
9b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// this list of conditions and the following disclaimer.
10b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch//
11b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// - Redistribution in binary form must reproduce the above copyright
12b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// notice, this list of conditions and the following disclaimer in the
13b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// documentation and/or other materials provided with the distribution.
14b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch//
15b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// - Neither the name of Sun Microsystems or the names of contributors may
16b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// be used to endorse or promote products derived from this software without
17b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// specific prior written permission.
18b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch//
19b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
20b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
21b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
23b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
24b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
25b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
26b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
27b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
28b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
29b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
31b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// The original source code covered by the above license above has been
32b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// modified significantly by Google Inc.
33b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Copyright 2012 the V8 project authors. All rights reserved.
34b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
35b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// A light-weight IA32 Assembler.
36b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
37b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifndef V8_X87_ASSEMBLER_X87_INL_H_
38b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define V8_X87_ASSEMBLER_X87_INL_H_
39b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
40b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/x87/assembler-x87.h"
41b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
42b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/assembler.h"
43014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/debug/debug.h"
44b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
45b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochnamespace v8 {
46b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochnamespace internal {
47b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
48b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool CpuFeatures::SupportsCrankshaft() { return true; }
49b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
50f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochbool CpuFeatures::SupportsSimd128() { return false; }
51b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
52b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic const byte kCallOpcode = 0xE8;
53b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic const int kNoCodeAgeSequenceLength = 5;
54b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
55b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
56b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// The modes possibly affected by apply must be in kApplyMask.
57014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid RelocInfo::apply(intptr_t delta) {
58b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (IsRuntimeEntry(rmode_) || IsCodeTarget(rmode_)) {
59b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    int32_t* p = reinterpret_cast<int32_t*>(pc_);
60b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    *p -= delta;  // Relocate entry.
61014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else if (IsCodeAgeSequence(rmode_)) {
62b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (*pc_ == kCallOpcode) {
63b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      int32_t* p = reinterpret_cast<int32_t*>(pc_ + 1);
64b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      *p -= delta;  // Relocate entry.
65b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
66014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else if (IsDebugBreakSlot(rmode_) && IsPatchedDebugBreakSlotSequence()) {
67b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Special handling of a debug break slot when a break point is set (call
68b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // instruction has been inserted).
69014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    int32_t* p = reinterpret_cast<int32_t*>(
70014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        pc_ + Assembler::kPatchDebugBreakSlotAddressOffset);
71b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    *p -= delta;  // Relocate entry.
72b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else if (IsInternalReference(rmode_)) {
73b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // absolute code pointer inside code object moves with the code object.
74b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    int32_t* p = reinterpret_cast<int32_t*>(pc_);
75b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    *p += delta;  // Relocate entry.
76b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
77b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
78b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
79b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
80b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochAddress RelocInfo::target_address() {
81b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(IsCodeTarget(rmode_) || IsRuntimeEntry(rmode_));
82b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return Assembler::target_address_at(pc_, host_);
83b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
84b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
85b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochAddress RelocInfo::target_address_address() {
86b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(IsCodeTarget(rmode_) || IsRuntimeEntry(rmode_)
87b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                              || rmode_ == EMBEDDED_OBJECT
88b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                              || rmode_ == EXTERNAL_REFERENCE);
89b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return reinterpret_cast<Address>(pc_);
90b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
91b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
92b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
93b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochAddress RelocInfo::constant_pool_entry_address() {
94b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  UNREACHABLE();
95b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return NULL;
96b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
97b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
98b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
99b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochint RelocInfo::target_address_size() {
100b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return Assembler::kSpecialTargetSize;
101b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
102b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
103b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
104b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochObject* RelocInfo::target_object() {
105b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(IsCodeTarget(rmode_) || rmode_ == EMBEDDED_OBJECT);
106b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return Memory::Object_at(pc_);
107b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
108b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
109b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
110b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHandle<Object> RelocInfo::target_object_handle(Assembler* origin) {
111b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(IsCodeTarget(rmode_) || rmode_ == EMBEDDED_OBJECT);
112b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return Memory::Object_Handle_at(pc_);
113b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
114b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
115b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
116b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid RelocInfo::set_target_object(Object* target,
117b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                  WriteBarrierMode write_barrier_mode,
118b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                  ICacheFlushMode icache_flush_mode) {
119b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(IsCodeTarget(rmode_) || rmode_ == EMBEDDED_OBJECT);
120b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Memory::Object_at(pc_) = target;
121b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (icache_flush_mode != SKIP_ICACHE_FLUSH) {
122014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Assembler::FlushICache(isolate_, pc_, sizeof(Address));
123b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
124b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (write_barrier_mode == UPDATE_WRITE_BARRIER &&
125b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      host() != NULL &&
126b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      target->IsHeapObject()) {
127f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    host()->GetHeap()->RecordWriteIntoCode(host(), this, target);
1283b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    host()->GetHeap()->incremental_marking()->RecordWriteIntoCode(
1293b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        host(), this, HeapObject::cast(target));
130b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
131b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
132b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
133b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
134014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochAddress RelocInfo::target_external_reference() {
135b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(rmode_ == RelocInfo::EXTERNAL_REFERENCE);
136b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return Memory::Address_at(pc_);
137b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
138b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
139b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
140014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochAddress RelocInfo::target_internal_reference() {
141014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(rmode_ == INTERNAL_REFERENCE);
142014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return Memory::Address_at(pc_);
143014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
144014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
145014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
146014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochAddress RelocInfo::target_internal_reference_address() {
147014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(rmode_ == INTERNAL_REFERENCE);
148014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return reinterpret_cast<Address>(pc_);
149014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
150014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
151014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
152b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochAddress RelocInfo::target_runtime_entry(Assembler* origin) {
153b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(IsRuntimeEntry(rmode_));
154b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return reinterpret_cast<Address>(*reinterpret_cast<int32_t*>(pc_));
155b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
156b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
157b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
158b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid RelocInfo::set_target_runtime_entry(Address target,
159b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                         WriteBarrierMode write_barrier_mode,
160b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                         ICacheFlushMode icache_flush_mode) {
161b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(IsRuntimeEntry(rmode_));
162b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (target_address() != target) {
163b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    set_target_address(target, write_barrier_mode, icache_flush_mode);
164b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
165b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
166b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
167b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
168b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHandle<Cell> RelocInfo::target_cell_handle() {
169b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(rmode_ == RelocInfo::CELL);
170b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Address address = Memory::Address_at(pc_);
171b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return Handle<Cell>(reinterpret_cast<Cell**>(address));
172b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
173b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
174b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
175b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochCell* RelocInfo::target_cell() {
176b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(rmode_ == RelocInfo::CELL);
177b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return Cell::FromValueAddress(Memory::Address_at(pc_));
178b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
179b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
180b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
181b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid RelocInfo::set_target_cell(Cell* cell,
182b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                WriteBarrierMode write_barrier_mode,
183b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                ICacheFlushMode icache_flush_mode) {
184014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(cell->IsCell());
185b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(rmode_ == RelocInfo::CELL);
186b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Address address = cell->address() + Cell::kValueOffset;
187b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Memory::Address_at(pc_) = address;
188b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (icache_flush_mode != SKIP_ICACHE_FLUSH) {
189014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Assembler::FlushICache(isolate_, pc_, sizeof(Address));
190b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
191b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (write_barrier_mode == UPDATE_WRITE_BARRIER && host() != NULL) {
192109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    host()->GetHeap()->incremental_marking()->RecordWriteIntoCode(host(), this,
193109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch                                                                  cell);
194b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
195b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
196b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
197b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
198b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHandle<Object> RelocInfo::code_age_stub_handle(Assembler* origin) {
199b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(rmode_ == RelocInfo::CODE_AGE_SEQUENCE);
200b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(*pc_ == kCallOpcode);
201b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return Memory::Object_Handle_at(pc_ + 1);
202b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
203b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
204b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
205b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochCode* RelocInfo::code_age_stub() {
206b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(rmode_ == RelocInfo::CODE_AGE_SEQUENCE);
207b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(*pc_ == kCallOpcode);
208b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return Code::GetCodeFromTargetAddress(
209b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      Assembler::target_address_at(pc_ + 1, host_));
210b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
211b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
212b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
213b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid RelocInfo::set_code_age_stub(Code* stub,
214b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                  ICacheFlushMode icache_flush_mode) {
215b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(*pc_ == kCallOpcode);
216b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(rmode_ == RelocInfo::CODE_AGE_SEQUENCE);
217014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Assembler::set_target_address_at(
218014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      isolate_, pc_ + 1, host_, stub->instruction_start(), icache_flush_mode);
219b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
220b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
221b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
222014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochAddress RelocInfo::debug_call_address() {
223014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(IsDebugBreakSlot(rmode()) && IsPatchedDebugBreakSlotSequence());
224014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Address location = pc_ + Assembler::kPatchDebugBreakSlotAddressOffset;
225014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return Assembler::target_address_at(location, host_);
226b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
227b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
228b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
229014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid RelocInfo::set_debug_call_address(Address target) {
230014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(IsDebugBreakSlot(rmode()) && IsPatchedDebugBreakSlotSequence());
231014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Address location = pc_ + Assembler::kPatchDebugBreakSlotAddressOffset;
232014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Assembler::set_target_address_at(isolate_, location, host_, target);
233b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (host() != NULL) {
234b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Object* target_code = Code::GetCodeFromTargetAddress(target);
235b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    host()->GetHeap()->incremental_marking()->RecordWriteIntoCode(
236b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        host(), this, HeapObject::cast(target_code));
237b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
238b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
239b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
240b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
241b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid RelocInfo::WipeOut() {
242014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (IsEmbeddedObject(rmode_) || IsExternalReference(rmode_) ||
243014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      IsInternalReference(rmode_)) {
244b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Memory::Address_at(pc_) = NULL;
245b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else if (IsCodeTarget(rmode_) || IsRuntimeEntry(rmode_)) {
246b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Effectively write zero into the relocation.
247014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Assembler::set_target_address_at(isolate_, pc_, host_,
248014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                     pc_ + sizeof(int32_t));
249b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {
250b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    UNREACHABLE();
251b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
252b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
253b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
254bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdochtemplate <typename ObjectVisitor>
255b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid RelocInfo::Visit(Isolate* isolate, ObjectVisitor* visitor) {
256b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  RelocInfo::Mode mode = rmode();
257b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (mode == RelocInfo::EMBEDDED_OBJECT) {
258b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    visitor->VisitEmbeddedPointer(this);
259014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Assembler::FlushICache(isolate, pc_, sizeof(Address));
260b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else if (RelocInfo::IsCodeTarget(mode)) {
261b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    visitor->VisitCodeTarget(this);
262b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else if (mode == RelocInfo::CELL) {
263b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    visitor->VisitCell(this);
264b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else if (mode == RelocInfo::EXTERNAL_REFERENCE) {
265b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    visitor->VisitExternalReference(this);
266014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else if (mode == RelocInfo::INTERNAL_REFERENCE) {
267014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    visitor->VisitInternalReference(this);
268b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else if (RelocInfo::IsCodeAgeSequence(mode)) {
269b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    visitor->VisitCodeAgeSequence(this);
270014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else if (RelocInfo::IsDebugBreakSlot(mode) &&
271014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch             IsPatchedDebugBreakSlotSequence()) {
272b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    visitor->VisitDebugTarget(this);
273b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else if (IsRuntimeEntry(mode)) {
274b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    visitor->VisitRuntimeEntry(this);
275b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
276b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
277b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
278b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
279b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochtemplate<typename StaticVisitor>
280b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid RelocInfo::Visit(Heap* heap) {
281b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  RelocInfo::Mode mode = rmode();
282b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (mode == RelocInfo::EMBEDDED_OBJECT) {
283b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    StaticVisitor::VisitEmbeddedPointer(heap, this);
284014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Assembler::FlushICache(heap->isolate(), pc_, sizeof(Address));
285b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else if (RelocInfo::IsCodeTarget(mode)) {
286b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    StaticVisitor::VisitCodeTarget(heap, this);
287b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else if (mode == RelocInfo::CELL) {
288b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    StaticVisitor::VisitCell(heap, this);
289b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else if (mode == RelocInfo::EXTERNAL_REFERENCE) {
290b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    StaticVisitor::VisitExternalReference(this);
291014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else if (mode == RelocInfo::INTERNAL_REFERENCE) {
292014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    StaticVisitor::VisitInternalReference(this);
293b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else if (RelocInfo::IsCodeAgeSequence(mode)) {
294b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    StaticVisitor::VisitCodeAgeSequence(heap, this);
295014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else if (RelocInfo::IsDebugBreakSlot(mode) &&
296014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch             IsPatchedDebugBreakSlotSequence()) {
297b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    StaticVisitor::VisitDebugTarget(heap, this);
298b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else if (IsRuntimeEntry(mode)) {
299b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    StaticVisitor::VisitRuntimeEntry(this);
300b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
301b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
302b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
303b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
304b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
305b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochImmediate::Immediate(int x)  {
306b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  x_ = x;
307b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  rmode_ = RelocInfo::NONE32;
308b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
309b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3103b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben MurdochImmediate::Immediate(Address x, RelocInfo::Mode rmode) {
3113b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  x_ = reinterpret_cast<int32_t>(x);
3123b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  rmode_ = rmode;
3133b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch}
314b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
315b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochImmediate::Immediate(const ExternalReference& ext) {
316b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  x_ = reinterpret_cast<int32_t>(ext.address());
317b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  rmode_ = RelocInfo::EXTERNAL_REFERENCE;
318b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
319b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
320b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
321b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochImmediate::Immediate(Label* internal_offset) {
322b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  x_ = reinterpret_cast<int32_t>(internal_offset);
323b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  rmode_ = RelocInfo::INTERNAL_REFERENCE;
324b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
325b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
326b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
327b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochImmediate::Immediate(Handle<Object> handle) {
328b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  AllowDeferredHandleDereference using_raw_address;
329b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Verify all Objects referred by code are NOT in new space.
330b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Object* obj = *handle;
331b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (obj->IsHeapObject()) {
332b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    x_ = reinterpret_cast<intptr_t>(handle.location());
333b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    rmode_ = RelocInfo::EMBEDDED_OBJECT;
334b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {
335b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // no relocation needed
336b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    x_ =  reinterpret_cast<intptr_t>(obj);
337b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    rmode_ = RelocInfo::NONE32;
338b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
339b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
340b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
341b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
342b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochImmediate::Immediate(Smi* value) {
343b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  x_ = reinterpret_cast<intptr_t>(value);
344b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  rmode_ = RelocInfo::NONE32;
345b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
346b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
347b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
348b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochImmediate::Immediate(Address addr) {
349b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  x_ = reinterpret_cast<int32_t>(addr);
350b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  rmode_ = RelocInfo::NONE32;
351b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
352b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
353b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
354b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::emit(uint32_t x) {
355b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  *reinterpret_cast<uint32_t*>(pc_) = x;
356b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  pc_ += sizeof(uint32_t);
357b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
358b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
359b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
360014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Assembler::emit_q(uint64_t x) {
361014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  *reinterpret_cast<uint64_t*>(pc_) = x;
362014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  pc_ += sizeof(uint64_t);
363014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
364014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
365014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
366b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::emit(Handle<Object> handle) {
367b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  AllowDeferredHandleDereference heap_object_check;
368b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Verify all Objects referred by code are NOT in new space.
369b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Object* obj = *handle;
370b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (obj->IsHeapObject()) {
371b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    emit(reinterpret_cast<intptr_t>(handle.location()),
372b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch         RelocInfo::EMBEDDED_OBJECT);
373b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {
374b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // no relocation needed
375b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    emit(reinterpret_cast<intptr_t>(obj));
376b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
377b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
378b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
379b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
380b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::emit(uint32_t x, RelocInfo::Mode rmode, TypeFeedbackId id) {
381b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (rmode == RelocInfo::CODE_TARGET && !id.IsNone()) {
382b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    RecordRelocInfo(RelocInfo::CODE_TARGET_WITH_ID, id.ToInt());
383b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else if (!RelocInfo::IsNone(rmode)
384b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      && rmode != RelocInfo::CODE_AGE_SEQUENCE) {
385b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    RecordRelocInfo(rmode);
386b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
387b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  emit(x);
388b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
389b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
390b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
391b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::emit(Handle<Code> code,
392b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                     RelocInfo::Mode rmode,
393b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                     TypeFeedbackId id) {
394b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  AllowDeferredHandleDereference embedding_raw_address;
395b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  emit(reinterpret_cast<intptr_t>(code.location()), rmode, id);
396b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
397b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
398b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
399b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::emit(const Immediate& x) {
400b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (x.rmode_ == RelocInfo::INTERNAL_REFERENCE) {
401b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Label* label = reinterpret_cast<Label*>(x.x_);
402b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    emit_code_relative_offset(label);
403b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return;
404b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
405b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (!RelocInfo::IsNone(x.rmode_)) RecordRelocInfo(x.rmode_);
406b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  emit(x.x_);
407b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
408b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
409b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
410b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::emit_code_relative_offset(Label* label) {
411b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (label->is_bound()) {
412b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    int32_t pos;
413b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    pos = label->pos() + Code::kHeaderSize - kHeapObjectTag;
414b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    emit(pos);
415b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {
416b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    emit_disp(label, Displacement::CODE_RELATIVE);
417b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
418b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
419b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4203b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdochvoid Assembler::emit_b(Immediate x) {
4213b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  DCHECK(x.is_int8() || x.is_uint8());
4223b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  uint8_t value = static_cast<uint8_t>(x.x_);
4233b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  *pc_++ = value;
4243b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch}
425b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
426b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::emit_w(const Immediate& x) {
427b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(RelocInfo::IsNone(x.rmode_));
428b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  uint16_t value = static_cast<uint16_t>(x.x_);
429b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  reinterpret_cast<uint16_t*>(pc_)[0] = value;
430b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  pc_ += sizeof(uint16_t);
431b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
432b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
433b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
434014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochAddress Assembler::target_address_at(Address pc, Address constant_pool) {
435b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return pc + sizeof(int32_t) + *reinterpret_cast<int32_t*>(pc);
436b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
437b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
438b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
439014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Assembler::set_target_address_at(Isolate* isolate, Address pc,
440014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                      Address constant_pool, Address target,
441b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                      ICacheFlushMode icache_flush_mode) {
442b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int32_t* p = reinterpret_cast<int32_t*>(pc);
443b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  *p = target - (pc + sizeof(int32_t));
444b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (icache_flush_mode != SKIP_ICACHE_FLUSH) {
445014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Assembler::FlushICache(isolate, p, sizeof(int32_t));
446b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
447b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
448b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
449b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
450b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochAddress Assembler::target_address_from_return_address(Address pc) {
451b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return pc - kCallTargetAddressOffset;
452b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
453b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
454b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
455b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochDisplacement Assembler::disp_at(Label* L) {
456b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return Displacement(long_at(L->pos()));
457b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
458b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
459b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
460b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::disp_at_put(Label* L, Displacement disp) {
461b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  long_at_put(L->pos(), disp.data());
462b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
463b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
464b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
465b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::emit_disp(Label* L, Displacement::Type type) {
466b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Displacement disp(L, type);
467b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  L->link_to(pc_offset());
468b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  emit(static_cast<int>(disp.data()));
469b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
470b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
471b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
472b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::emit_near_disp(Label* L) {
473b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  byte disp = 0x00;
474b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (L->is_near_linked()) {
475b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    int offset = L->near_link_pos() - pc_offset();
476b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(is_int8(offset));
477b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    disp = static_cast<byte>(offset & 0xFF);
478b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
479b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  L->link_to(pc_offset(), Label::kNear);
480b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  *pc_++ = disp;
481b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
482b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
483b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
484014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Assembler::deserialization_set_target_internal_reference_at(
485014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Isolate* isolate, Address pc, Address target, RelocInfo::Mode mode) {
486014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Memory::Address_at(pc) = target;
487014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
488014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
489014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
490b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Operand::set_modrm(int mod, Register rm) {
491b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK((mod & -4) == 0);
492b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  buf_[0] = mod << 6 | rm.code();
493b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  len_ = 1;
494b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
495b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
496b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
497b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Operand::set_sib(ScaleFactor scale, Register index, Register base) {
498b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(len_ == 1);
499b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK((scale & -4) == 0);
500b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Use SIB with no index register only for base esp.
501b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(!index.is(esp) || base.is(esp));
502b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  buf_[1] = scale << 6 | index.code() << 3 | base.code();
503b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  len_ = 2;
504b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
505b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
506b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
507b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Operand::set_disp8(int8_t disp) {
508b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(len_ == 1 || len_ == 2);
509b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  *reinterpret_cast<int8_t*>(&buf_[len_++]) = disp;
510b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
511b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
512b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
513b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Operand::set_dispr(int32_t disp, RelocInfo::Mode rmode) {
514b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(len_ == 1 || len_ == 2);
515b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int32_t* p = reinterpret_cast<int32_t*>(&buf_[len_]);
516b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  *p = disp;
517b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  len_ += sizeof(int32_t);
518b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  rmode_ = rmode;
519b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
520b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
521b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochOperand::Operand(Register reg) {
522b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // reg
523b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  set_modrm(3, reg);
524b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
525b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
526b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
527b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochOperand::Operand(int32_t disp, RelocInfo::Mode rmode) {
528b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // [disp/r]
529b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  set_modrm(0, ebp);
530b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  set_dispr(disp, rmode);
531b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
532b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
533b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
534b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochOperand::Operand(Immediate imm) {
535b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // [disp/r]
536b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  set_modrm(0, ebp);
537b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  set_dispr(imm.x_, imm.rmode_);
538b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
539014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}  // namespace internal
540014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}  // namespace v8
541b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
542b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif  // V8_X87_ASSEMBLER_X87_INL_H_
543